Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
pull-requests: read
steps:
- name: Require one pre-existing issue
uses: actions/github-script@v7
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
script: |
const pull = context.payload.pull_request;
Expand Down Expand Up @@ -49,9 +49,9 @@ jobs:
name: Cargo check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: swatinem/rust-cache@v2
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: swatinem/rust-cache@42dc69e1aa15d09112580998cf2ef0119e2e91ae # v2
- name: Check formatting
run: cargo fmt --all -- --check
- name: Check compilation
Expand Down
51 changes: 30 additions & 21 deletions .github/workflows/release.yml → .github/workflows/v-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ on:
pull_request:
push:
tags:
- '**[0-9]+.[0-9]+.[0-9]+*'
- 'v**[0-9]+.[0-9]+.[0-9]+*'

jobs:
# Run 'dist plan' (or host) to determine what tasks we need to do
Expand All @@ -56,7 +56,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
with:
persist-credentials: false
submodules: recursive
Expand All @@ -66,7 +66,7 @@ jobs:
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.31.0/cargo-dist-installer.sh | sh"
- name: Cache dist
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
name: cargo-dist-cache
path: ~/.cargo/bin/dist
Expand All @@ -82,7 +82,7 @@ jobs:
cat plan-dist-manifest.json
echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
name: artifacts-plan-dist-manifest
path: plan-dist-manifest.json
Expand Down Expand Up @@ -116,7 +116,7 @@ jobs:
- name: enable windows longpaths
run: |
git config --global core.longpaths true
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
with:
persist-credentials: false
submodules: recursive
Expand All @@ -131,7 +131,7 @@ jobs:
run: ${{ matrix.install_dist.run }}
# Get the dist-manifest
- name: Fetch local artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
pattern: artifacts-*
path: target/distrib/
Expand All @@ -158,7 +158,7 @@ jobs:

cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
name: artifacts-build-local-${{ join(matrix.targets, '_') }}
path: |
Expand All @@ -175,19 +175,19 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
- name: Fetch local artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
pattern: artifacts-*
path: target/distrib/
Expand All @@ -205,7 +205,7 @@ jobs:

cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
name: artifacts-build-global
path: |
Expand All @@ -224,20 +224,24 @@ jobs:
runs-on: "ubuntu-22.04"
outputs:
val: ${{ steps.host.outputs.manifest }}
permissions:
"attestations": "write"
"contents": "write"
"id-token": "write"
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
pattern: artifacts-*
path: target/distrib/
Expand All @@ -250,14 +254,14 @@ jobs:
cat dist-manifest.json
echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
# Overwrite the previous copy
name: artifacts-dist-manifest
path: dist-manifest.json
# Create a GitHub Release while uploading all files to it
- name: "Download GitHub Artifacts"
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
pattern: artifacts-*
path: artifacts
Expand All @@ -266,6 +270,11 @@ jobs:
run: |
# Remove the granular manifests
rm -f artifacts/*-dist-manifest.json
- name: Attest
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a
with:
subject-path: |
artifacts/*
- name: Create GitHub Release
env:
PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}"
Expand All @@ -290,14 +299,14 @@ jobs:
GITHUB_EMAIL: "admin+bot@axo.dev"
if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
with:
persist-credentials: true
repository: "shayyz-code/homebrew-tap"
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
# So we have access to the formula
- name: Fetch homebrew formulae
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
pattern: artifacts-*
path: Formula/
Expand Down Expand Up @@ -335,12 +344,12 @@ jobs:
if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}
steps:
- name: Fetch npm packages
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
pattern: artifacts-*
path: npm/
merge-multiple: true
- uses: actions/setup-node@v6
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'
Expand All @@ -366,7 +375,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
with:
persist-credentials: false
submodules: recursive
10 changes: 5 additions & 5 deletions .github/workflows/web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ jobs:
runs-on: ubuntu-latest
steps:
# Setup
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- uses: swatinem/rust-cache@v2
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: swatinem/rust-cache@42dc69e1aa15d09112580998cf2ef0119e2e91ae # v2

# If you use any mdbook plugins, here's the place to install them!

Expand All @@ -76,7 +76,7 @@ jobs:
run: mkdir -p /tmp/link-check/poolang && cp -R public/* /tmp/link-check/poolang/ && cp CONTRIBUTING.md /tmp/link-check/poolang/ && cp LICENSE /tmp/link-check/poolang/

- name: Check HTML for broken internal links
uses: untitaker/hyperlink@0.1.29
uses: untitaker/hyperlink@273ec52f34b7cbf039908d52985010c7f3f35160 # 0.1.29
with:
args: /tmp/link-check/

Expand All @@ -88,7 +88,7 @@ jobs:
# go into repo's settings > pages and set "deploy from branch: gh-pages".
# The other defaults work fine.
- name: Deploy to Github Pages
uses: JamesIves/github-pages-deploy-action@v4.4.1
uses: JamesIves/github-pages-deploy-action@ba1486788b0490a235422264426c45848eac35c6 # v4.4.1
# ONLY if we're on main (so no PRs or feature branches allowed!)
if: ${{ github.ref == 'refs/heads/main' }}
with:
Expand Down
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Edit documentation sources under `docs/src/` and navigation in `docs/src/SUMMARY
- `cargo fmt --all -- --check` checks formatting; `cargo fmt --all` applies it.
- `cargo clippy --all-targets --all-features -- -D warnings` runs strict linting.
- `mdbook build docs` is the canonical documentation build; `mdbook test docs` tests its Rust examples.
- `dist generate --check` verifies that the generated release workflow matches its configuration.

All established formatting, compilation, test, and lint checks must pass before review.

Expand All @@ -24,6 +25,10 @@ Use rustfmt defaults and idiomatic Rust names: `snake_case` for functions and mo

Follow TDD for features and fixes. Add focused cases to `tests/language_specs.rs`, named `spec_<component>_<behavior>`, and cover success plus relevant failure paths.

## Release Automation

Treat `dist-workspace.toml` as the source of truth for releases. Never edit `.github/workflows/v-release.yml` directly; run `dist generate --mode=ci` after a configuration change and commit the result. Follow `RELEASING.md` for release checks, tag format, credential handling, and artifact verification. Do not create a release tag as part of an unrelated change.

## Issue, Commit & Pull Request Rules

Every change starts with an existing GitHub issue. Create a branch from `main` and keep the PR limited to one issue and one reviewable concern. The PR body must contain exactly one closing reference such as `Closes #123`, describe verification, and note documentation or screenshot impact.
Expand Down
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ Pull requests are squash-merged only. Do not use merge commits or rebase merges.

`mdbook build docs` is the canonical documentation build command. Before review, run all applicable commands above plus `cargo fmt --all -- --check` and `cargo clippy --all-targets --all-features -- -D warnings`; all established checks must pass.

## Release Changes

Configure releases in `dist-workspace.toml`; `.github/workflows/v-release.yml` is generated and must not be edited by hand. Run `dist generate --mode=ci` after changing release configuration and `dist generate --check` before review. Maintainers must follow `RELEASING.md`; release tags are reserved for reviewed release commits on `main`.

## Architectural Overview

- **Lexer (`src/lexer.rs`)**: Converts source text into a stream of tokens.
Expand Down
29 changes: 29 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Releasing PooLang

Releases are generated by cargo-dist 0.31.0 from `dist-workspace.toml`. Treat that file as the source of truth: never edit `.github/workflows/v-release.yml` by hand. After changing release configuration, run `dist generate --mode=ci` and commit the generated result.

## Release Checklist

Release version changes must first land on `main` through the normal issue and pull-request workflow. From a clean, synchronized checkout of that reviewed commit:

1. Confirm `Cargo.toml` contains the intended version and that no tracked files are modified.
2. Run `dist generate --check` and `dist plan --output-format=json --no-local-paths`.
3. Run `cargo fmt --all -- --check`, `cargo check --all-targets`, `cargo clippy --all-targets --all-features -- -D warnings`, `cargo test`, `mdbook build docs`, `mdbook test docs`, and `oranda build`.
4. Create one annotated tag matching the package version: `git tag -a vX.Y.Z -m "Release vX.Y.Z"`.
5. Push only that tag: `git push origin vX.Y.Z`.
6. Monitor the **Release** workflow. Verify the GitHub release assets and SHA256 files, the npm package, the Homebrew formula, and the subsequent **Web** deployment.
7. Download an artifact and verify its provenance with `gh attestation verify <artifact> -R shayyz-code/poolang`.

Do not reuse, move, force-push, or delete a published version tag.

## Supported Distribution

Releases target Apple Silicon macOS, Intel macOS, Apple Silicon Linux, Intel Linux, and x86_64 Windows. cargo-dist produces shell, PowerShell, npm, Homebrew, and MSI installers; stable releases publish to `@shayyz-code/poo` and `shayyz-code/homebrew-tap`.

## Credentials and Security

- `NPM_TOKEN` must be a short-lived granular token with read/write access only to `@shayyz-code/poo`. Rotate it regularly. Migrate to npm trusted publishing for `v-release.yml`, then revoke and remove this token.
- `HOMEBREW_TAP_TOKEN` must be a fine-grained token limited to `shayyz-code/homebrew-tap` with Contents write access. Replace or rotate it when its scope or age cannot be confirmed.
- Never place secret values in repository files, issue text, pull-request text, command output, or workflow logs.

All workflow actions are pinned to immutable commits. The generated workflow still declares top-level Contents write permission so cargo-dist can host releases; pull requests receive no repository secrets. Platform code signing is not yet configured, so binaries and MSI packages remain unsigned even though release artifacts receive GitHub provenance attestations.
7 changes: 6 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Snapshot: 2026-07-29.
- The crate exposes checked file/source execution APIs and typed I/O, parse, and runtime error categories.
- Checked parsing reports malformed literals, comments, non-ASCII identifiers, and unexpected EOF without panicking or hanging.
- Lexer, parser, interpreter, type-inference, examples, mdBook documentation, and cargo-dist release assets exist.
- cargo-dist 0.31.0 generates five platform targets and shell, PowerShell, npm, Homebrew, and MSI installers from reviewed configuration.
- Release actions use immutable commit pins, version tags are protected, and future release artifacts receive GitHub provenance attestations.

### Quality gaps

Expand Down Expand Up @@ -78,8 +80,11 @@ Snapshot: 2026-07-29.
- [x] Separate generated mdBook output from sources and define one reproducible documentation build command.
- [x] Reconcile README commands, branch names, CI claims, supported features, and examples with executable behavior.
- [x] Add focused lexer/parser error tests for malformed strings, comments, UTF-8 input, and unexpected EOF.
- [ ] Audit release workflow actions, permissions, secrets, installers, and generated cargo-dist configuration.
- [x] Audit release workflow actions, permissions, secrets, installers, and generated cargo-dist configuration.
- [ ] Add dependency, license, and supply-chain checks appropriate to Rust and future native runtime dependencies.
- [ ] Migrate npm publishing to trusted publishing for `v-release.yml`, then revoke and remove `NPM_TOKEN`.
- [ ] Replace or rotate the Homebrew credential with a fine-grained, tap-only Contents-write token.
- [ ] Add platform code signing before the production v0.2 release.

## Phase 2 — Normative v0.2 Language Specification

Expand Down
15 changes: 15 additions & 0 deletions dist-workspace.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ members = ["cargo:."]
cargo-dist-version = "0.31.0"
# CI backends to support
ci = "github"
# Only v-prefixed semantic-version tags trigger release automation
tag-namespace = "v"
# Produce GitHub artifact attestations after all artifacts are assembled
github-attestations = true
github-attestations-phase = "host"
github-release = "host"
# The installers to generate for each app
installers = ["shell", "powershell", "npm", "homebrew", "msi"]
# A GitHub repo to push Homebrew formulas to
Expand All @@ -21,3 +27,12 @@ install-path = "CARGO_HOME"
publish-jobs = ["homebrew", "npm"]
# Whether to install an updater program
install-updater = false

# Pin generated GitHub Actions to immutable commits. Update these through a
# reviewed cargo-dist configuration change, then regenerate the workflow.
[dist.github-action-commits]
"actions/checkout" = "d23441a48e516b6c34aea4fa41551a30e30af803"
"actions/upload-artifact" = "b7c566a772e6b6bfb58ed0dc250532a479d7789f"
"actions/download-artifact" = "37930b1c2abaa49bbe596cd826c3c89aef350131"
"actions/setup-node" = "249970729cb0ef3589644e2896645e5dc5ba9c38"
"actions/attest-build-provenance" = "977bb373ede98d70efdf65b84cb5f73e068dcc2a"
Loading