From 3b9cde71b89eeeb3b8cde3ed59683d3d906a8a6b Mon Sep 17 00:00:00 2001 From: Anton Velichko <631906+tonyvelichko@users.noreply.github.com> Date: Thu, 1 Oct 2026 15:36:47 +0400 Subject: [PATCH] ci(packs): a release that refreezes nothing keeps the last library's packs The release-time freeze minted the crate's version into the library, so a release changing no circuit (v0.8.3: the crate on crates.io) failed the packs job's clean-tree check and left its release a draft. When the manifest's library version isn't the tag's, the circuits are that library's, whose packs are already published: the job skips building them and points the notes there. --- .github/workflows/ci.yml | 48 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd0a577..5173809 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -505,38 +505,66 @@ jobs: - uses: actions/checkout@v5 with: ref: ${{ needs.tag.outputs.tag || needs.resolve.outputs.release_tag }} + # The circuits are frozen as a library version (rust/eid-circuits/circuits/manifest.toml), set by + # the refreeze that precedes a circuit release. A release that changes no circuit (a + # dependency, the crate) keeps the last frozen library: its packs are that release's, already + # published, so this job only points the notes at them. + - name: Did this release refreeze the circuits? + id: frozen + env: + TAG: ${{ needs.tag.outputs.tag || needs.resolve.outputs.release_tag }} + run: | + set -euo pipefail + library="$(awk '/^\[library\]/{f=1} f && /^version/{gsub(/"/,"",$3); print $3; exit}' rust/eid-circuits/circuits/manifest.toml)" + echo "library=$library" >> "$GITHUB_OUTPUT" + if [ "v$library" = "$TAG" ]; then + echo "refrozen=true" >> "$GITHUB_OUTPUT" + else + echo "refrozen=false" >> "$GITHUB_OUTPUT" + echo "circuits unchanged since v$library: its packs stand" + fi - uses: actions-rust-lang/setup-rust-toolchain@v1 + if: steps.frozen.outputs.refrozen == 'true' with: rust-src-dir: rust # noir-zk links bb's static library against libc++. - name: Install libc++ + if: steps.frozen.outputs.refrozen == 'true' run: sudo apt-get update -q && sudo apt-get install -yq libc++-dev libc++abi-dev - uses: jdx/mise-action@v4 + if: steps.frozen.outputs.refrozen == 'true' - name: Install nargo, bb and the noir-zk CLI + if: steps.frozen.outputs.refrozen == 'true' run: mise run install:zk-toolchain install:noir-zk # noir-zk derives keys against a pinned SRS (2^20+1 BN254, 2^15 Grumpkin # points in ~/.bb-crs) and never downloads it itself: provision it once # (mise run srs) and keep it, keyed by the pins. - uses: actions/cache@v4 + if: steps.frozen.outputs.refrozen == 'true' with: path: ~/.bb-crs key: noir-zk-srs-0f238856e557-72b8cdad9da8 - name: Provision the SRS noir-zk pins + if: steps.frozen.outputs.refrozen == 'true' run: mise run srs - name: Compile every circuit + if: steps.frozen.outputs.refrozen == 'true' run: mise run compile - name: Check the compiled circuits against their pins + if: steps.frozen.outputs.refrozen == 'true' run: mise run freeze -- --check - name: Write the release assets and packs + if: steps.frozen.outputs.refrozen == 'true' run: | set -euo pipefail mise run freeze git diff --exit-code -- rust/eid-circuits mise run packs - name: Upload to the release + if: steps.frozen.outputs.refrozen == 'true' run: mise run packs:publish - name: Upload to the circuits R2 bucket - if: vars.R2_CIRCUITS_BUCKET != '' + if: steps.frozen.outputs.refrozen == 'true' && (vars.R2_CIRCUITS_BUCKET != '') env: R2_CIRCUITS_TOKEN: ${{ secrets.R2_CIRCUITS_TOKEN }} R2_CIRCUITS_BUCKET: ${{ vars.R2_CIRCUITS_BUCKET }} @@ -546,6 +574,7 @@ jobs: # check every file is an asset of the draft (packs:publish-r2 checks the # bucket's copies itself). - name: Check the published downloads + if: steps.frozen.outputs.refrozen == 'true' env: TAG: ${{ needs.tag.outputs.tag || needs.resolve.outputs.release_tag }} run: | @@ -556,6 +585,7 @@ jobs: grep -qxF "$name" <<<"$have" || { echo "::error::$name is not an asset of $TAG"; exit 1; } done - name: Add the downloads to the release notes + if: steps.frozen.outputs.refrozen == 'true' env: TAG: ${{ needs.tag.outputs.tag || needs.resolve.outputs.release_tag }} BASE: ${{ vars.R2_CIRCUITS_BUCKET != '' && 'https://circuits.zk-eid.dev' || '' }} @@ -580,6 +610,22 @@ jobs: echo "Every bytecode and verification key is pinned in the \`eid-circuits\` crate (\`BYTECODE_SHA256\`, \`VK_SHA256\`): check an unpacked pack with \`noir_zk_backend::frozen::verify_dir(eid_circuits::circuits::REGISTRY, dir)\`. The hosts are mirrors, not trust anchors." } > notes.md gh release edit "$TAG" --notes-file notes.md + - name: Point the release notes at the frozen library's packs + if: steps.frozen.outputs.refrozen == 'false' + env: + TAG: ${{ needs.tag.outputs.tag || needs.resolve.outputs.release_tag }} + LIBRARY: ${{ steps.frozen.outputs.library }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + { + gh release view "$TAG" --json body -q .body + echo + echo "## Circuit packs" + echo + echo "No circuit changed in this release: the circuits are still frozen as \`eid-circuits@$LIBRARY\`, and their packs are [v$LIBRARY's](https://github.com/${GITHUB_REPOSITORY}/releases/tag/v$LIBRARY) (\`catalog@$LIBRARY.json\` on the CDN)." + } > notes.md + gh release edit "$TAG" --notes-file notes.md # Last: the draft becomes the public release once the packs and the crate are published. release: