Skip to content

Release v1.0.0

Release v1.0.0 #56

Workflow file for this run

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,
});
}