Release v1.0.0 #56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [ "main" ] | |
| paths-ignore: | |
| - 'js/**' | |
| - '**/*.md' | |
| - 'LICENSE' | |
| - '.gitignore' | |
| pull_request: | |
| branches: [ "main" ] | |
| paths-ignore: | |
| - 'js/**' | |
| - '**/*.md' | |
| - 'LICENSE' | |
| - '.gitignore' | |
| env: | |
| NOIR_VERSION: v1.0.0-beta.18 | |
| SUNSPOT_REPO: reilabs/sunspot | |
| SUNSPOT_REF: main | |
| jobs: | |
| # ----------------------------------------------------------- | |
| # JOB 1 — NOIR COMPILE + EXECUTE | |
| # Iterates every package under `tests/noir_projects/` and | |
| # emits ACIR JSON + witness `.gz`. Each project is discovered | |
| # by globbing for `Nargo.toml`, so adding a new circuit only | |
| # requires dropping it under `tests/noir_projects/<name>/`. | |
| # ----------------------------------------------------------- | |
| noir: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Restore noir output cache | |
| id: noir-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: tests/noir_projects/*/target | |
| key: noir-${{ runner.os }}-${{ env.NOIR_VERSION }}-${{ hashFiles('tests/noir_projects/**/Nargo.toml', 'tests/noir_projects/**/Prover.toml', 'tests/noir_projects/**/src/**') }} | |
| - uses: noir-lang/noirup@v0.1.2 | |
| if: steps.noir-cache.outputs.cache-hit != 'true' | |
| with: | |
| toolchain: ${{ env.NOIR_VERSION }} | |
| - name: Compile & execute circuits | |
| if: steps.noir-cache.outputs.cache-hit != 'true' | |
| run: | | |
| set -euxo pipefail | |
| shopt -s nullglob | |
| for nargo_toml in tests/noir_projects/*/Nargo.toml; do | |
| project_dir="$(dirname "$nargo_toml")" | |
| name="$(basename "$project_dir")" | |
| echo "::group::Noir: $name" | |
| ( | |
| cd "$project_dir" | |
| nargo compile | |
| if [ -f Prover.toml ]; then nargo execute; fi | |
| ) | |
| echo "::endgroup::" | |
| done | |
| - name: Upload noir output | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: noir-output | |
| path: tests/noir_projects/*/target | |
| retention-days: 1 | |
| # ----------------------------------------------------------- | |
| # JOB 2 — SUNSPOT BINARY BUILD | |
| # Builds the Go `sunspot` CLI from the sibling reilabs/sunspot | |
| # repo. Result is cached by the upstream commit SHA, so we | |
| # only rebuild when SUNSPOT_REF points at a new commit (or | |
| # when the Go version / runner OS changes). | |
| # ----------------------------------------------------------- | |
| sunspot-build: | |
| runs-on: ubuntu-latest | |
| env: | |
| GO_VERSION: '1.24.2' | |
| outputs: | |
| sha: ${{ steps.sunspot-sha.outputs.sha }} | |
| steps: | |
| - name: Resolve sunspot SHA | |
| id: sunspot-sha | |
| run: | | |
| set -euo pipefail | |
| SHA=$(git ls-remote "https://github.com/${SUNSPOT_REPO}.git" "$SUNSPOT_REF" | awk 'NR==1 {print $1}') | |
| # If the ref didn't resolve, assume it's already a commit SHA. | |
| if [ -z "$SHA" ]; then SHA="$SUNSPOT_REF"; fi | |
| echo "Resolved $SUNSPOT_REPO@$SUNSPOT_REF -> $SHA" | |
| echo "sha=$SHA" >> "$GITHUB_OUTPUT" | |
| - name: Restore sunspot binary cache | |
| id: sunspot-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: sunspot-bin/sunspot | |
| key: sunspot-${{ runner.os }}-go${{ env.GO_VERSION }}-${{ steps.sunspot-sha.outputs.sha }} | |
| - uses: actions/checkout@v4 | |
| if: steps.sunspot-cache.outputs.cache-hit != 'true' | |
| with: | |
| repository: ${{ env.SUNSPOT_REPO }} | |
| ref: ${{ steps.sunspot-sha.outputs.sha }} | |
| path: sunspot | |
| - uses: actions/setup-go@v4 | |
| if: steps.sunspot-cache.outputs.cache-hit != 'true' | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Build sunspot | |
| if: steps.sunspot-cache.outputs.cache-hit != 'true' | |
| working-directory: sunspot/go | |
| run: | | |
| set -euxo pipefail | |
| go mod tidy | |
| go build -o sunspot -v . | |
| mkdir -p "$GITHUB_WORKSPACE/sunspot-bin" | |
| mv sunspot "$GITHUB_WORKSPACE/sunspot-bin/sunspot" | |
| - name: Upload sunspot binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sunspot-bin | |
| path: sunspot-bin/sunspot | |
| retention-days: 7 | |
| # ----------------------------------------------------------- | |
| # JOB 3 — FIXTURES | |
| # Combines the Noir outputs with the sunspot binary to | |
| # produce the full artifact set (.json, .gz, .ccs, .pk, .vk) | |
| # under `tests/noir_projects/<name>/target/`, which is the | |
| # layout `tests/mod.rs` loads from at test time. | |
| # ----------------------------------------------------------- | |
| fixtures: | |
| runs-on: ubuntu-latest | |
| needs: [noir, sunspot-build] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Restore fixtures cache | |
| id: fixtures-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: tests/noir_projects/*/target | |
| key: fixtures-${{ runner.os }}-${{ env.NOIR_VERSION }}-${{ needs.sunspot-build.outputs.sha }}-${{ hashFiles('tests/noir_projects/**/Nargo.toml', 'tests/noir_projects/**/Prover.toml', 'tests/noir_projects/**/src/**') }} | |
| - name: Download noir output | |
| if: steps.fixtures-cache.outputs.cache-hit != 'true' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: noir-output | |
| path: tests/noir_projects | |
| - name: Download sunspot binary | |
| if: steps.fixtures-cache.outputs.cache-hit != 'true' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: sunspot-bin | |
| path: bin | |
| - name: Install sunspot on PATH | |
| if: steps.fixtures-cache.outputs.cache-hit != 'true' | |
| run: | | |
| chmod +x bin/sunspot | |
| sudo mv bin/sunspot /usr/local/bin/sunspot | |
| sunspot --help > /dev/null | |
| - name: Run sunspot compile + setup | |
| if: steps.fixtures-cache.outputs.cache-hit != 'true' | |
| run: | | |
| set -euxo pipefail | |
| shopt -s nullglob | |
| for nargo_toml in tests/noir_projects/*/Nargo.toml; do | |
| project_dir="$(dirname "$nargo_toml")" | |
| name="$(basename "$project_dir")" | |
| echo "::group::Fixture: $name" | |
| ( | |
| cd "$project_dir" | |
| sunspot compile "target/${name}.json" | |
| sunspot setup "target/${name}.ccs" | |
| ) | |
| echo "::endgroup::" | |
| done | |
| - name: Upload fixtures | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fixtures | |
| path: tests/noir_projects/*/target | |
| retention-days: 1 | |
| # ----------------------------------------------------------- | |
| # JOB 4 — RUST BUILD + TEST | |
| # Pure Rust stage: only needs the rustup toolchain. The | |
| # integration tests in `tests/mod.rs` consume the pre-built | |
| # `.json/.gz/.ccs/.pk` files; no nargo or sunspot on PATH. | |
| # ----------------------------------------------------------- | |
| rust: | |
| runs-on: ubuntu-latest | |
| needs: [fixtures] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: actions-rust-lang/setup-rust-toolchain@v1 | |
| - name: Download fixtures | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: fixtures | |
| path: tests/noir_projects | |
| - run: cargo fmt --all -- --check | |
| - run: cargo clippy --all-targets -- -D warnings | |
| - run: cargo build --all-targets | |
| - run: cargo test --all --release -- --nocapture | |
| # ----------------------------------------------------------- | |
| # JOB 5 — WASM BENCH | |
| # Builds the PR HEAD *and* the base branch's wasm with the | |
| # `bench` feature, drives the bench harness via Playwright | |
| # Chromium against both, and posts a markdown diff to the PR. | |
| # ----------------------------------------------------------- | |
| bench: | |
| runs-on: ubuntu-latest | |
| needs: [fixtures] | |
| if: github.event_name == 'pull_request' | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| env: | |
| BENCH_ITERS: '10' | |
| BENCH_FOLD_N: '4096' | |
| BENCH_PROJECTS: 'poseidon2' | |
| steps: | |
| - name: Checkout PR head | |
| uses: actions/checkout@v4 | |
| with: | |
| path: pr | |
| - name: Checkout base branch | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ github.repository }} | |
| ref: ${{ github.event.pull_request.base.ref }} | |
| path: base | |
| - name: Install Rust (wasm target) | |
| uses: actions-rust-lang/setup-rust-toolchain@v1 | |
| with: | |
| rustflags: "" | |
| - name: Cache cargo build artifacts | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: | | |
| pr -> target | |
| base -> target | |
| - name: Install wasm-pack | |
| run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh | |
| - name: Build PR wasm (--features bench) | |
| working-directory: pr | |
| env: | |
| CARGO_UNSTABLE_BUILD_STD: panic_abort,std | |
| run: wasm-pack build --release --target web --features bench | |
| - name: Build base wasm (--features bench) | |
| id: base_build | |
| continue-on-error: true | |
| working-directory: base | |
| env: | |
| CARGO_UNSTABLE_BUILD_STD: panic_abort,std | |
| run: wasm-pack build --release --target web --features bench | |
| - name: Download fixtures | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: fixtures | |
| path: pr/tests/noir_projects | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: playwright-${{ runner.os }}-${{ hashFiles('pr/bench/package.json') }} | |
| - name: Install bench deps | |
| working-directory: pr/bench | |
| run: npm install --no-audit --no-fund | |
| - name: Install Playwright Chromium | |
| working-directory: pr/bench | |
| run: npx playwright install --with-deps chromium | |
| - name: Bench PR HEAD | |
| working-directory: pr | |
| run: | | |
| node bench/runner.mjs \ | |
| --pkg ./pkg \ | |
| --root . \ | |
| --out ../head.json \ | |
| --projects "$BENCH_PROJECTS" \ | |
| --iters "$BENCH_ITERS" \ | |
| --foldN "$BENCH_FOLD_N" \ | |
| --label "${{ github.event.pull_request.head.sha }}" | |
| - name: Bench base branch | |
| if: steps.base_build.outcome == 'success' | |
| working-directory: pr | |
| run: | | |
| node bench/runner.mjs \ | |
| --pkg ../base/pkg \ | |
| --root . \ | |
| --out ../base.json \ | |
| --projects "$BENCH_PROJECTS" \ | |
| --iters "$BENCH_ITERS" \ | |
| --foldN "$BENCH_FOLD_N" \ | |
| --label "${{ github.event.pull_request.base.sha }}" | |
| - name: Render comparison | |
| working-directory: pr | |
| run: | | |
| baseline_arg="" | |
| if [ -f ../base.json ]; then baseline_arg="--baseline ../base.json"; fi | |
| node bench/compare.mjs \ | |
| --current ../head.json \ | |
| $baseline_arg \ | |
| --out ../bench-comment.md | |
| cat ../bench-comment.md | |
| - name: Upload bench JSON | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bench-results | |
| path: | | |
| head.json | |
| base.json | |
| bench-comment.md | |
| if-no-files-found: warn | |
| retention-days: 14 | |
| - name: Post comment on PR | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const body = fs.readFileSync('bench-comment.md', 'utf-8'); | |
| const marker = '## sunspot_wasm bench'; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existing = comments.find( | |
| c => c.user?.type === 'Bot' && c.body?.startsWith(marker), | |
| ); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body, | |
| }); | |
| } |