Skip to content

feat: circuits distribution#1243

Merged
hmzakhalid merged 5 commits into
mainfrom
feat/circuits-distribution
Feb 4, 2026
Merged

feat: circuits distribution#1243
hmzakhalid merged 5 commits into
mainfrom
feat/circuits-distribution

Conversation

@ctrlc03

@ctrlc03 ctrlc03 commented Jan 30, 2026

Copy link
Copy Markdown
Collaborator

fix #1235

Summary by CodeRabbit

  • New Features

    • Circuit artifacts are detected, packaged, and attached to releases; release notes include a Noir Circuits section with a source hash.
    • New CLI workflows and npm scripts to build, hash, and publish circuit artifacts.
  • Documentation

    • Added Circuit Builder documentation with usage, examples, and operational details.
  • Chores

    • Root ignore list updated to exclude built distribution artifacts.

@vercel

vercel Bot commented Jan 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
crisp Ready Ready Preview, Comment Feb 4, 2026 10:57am
enclave-docs Ready Ready Preview, Comment Feb 4, 2026 10:57am

Request Review

@coderabbitai

coderabbitai Bot commented Jan 30, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@ctrlc03 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 27 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Adds Noir circuit build and artifact management: TypeScript CLI to compile/package circuits, a git-backed push/pull script, npm scripts and docs, root .gitignore update, and a GitHub Actions download-circuits job that fetches artifacts and exposes found and source_hash for release notes and assets.

Changes

Cohort / File(s) Summary
GitHub Actions
.github/workflows/releases.yml
Adds download-circuits job to fetch circuit artifacts from a dedicated branch, compute/source_hash, upload noir-circuits artifact, and wires create-github-release to depend on it; release notes updated to conditionally include Noir Circuits section.
Circuit Build & Artifact Tooling
scripts/build-circuits.ts, scripts/circuit-artifacts.ts
Adds NoirCircuitBuilder CLI (compile via nargo, optional VK gen, checksums, manifest, source hashing, packaging) and a circuit-artifacts.ts script to push/pull dist to/from a git branch.
Package & Docs
package.json, scripts/README.md
Adds build:circuits and store:circuits npm scripts and documents the circuit builder usage (README contains a duplicated subsection).
Ignore Rules
.gitignore
Adds dist to root .gitignore.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant CLI as NoirCircuitBuilder (scripts/build-circuits.ts)
    participant ArtifRepo as Git Remote (circuit-artifacts branch)
    participant GHA as GitHub Actions (download-circuits)
    participant Release as create-github-release

    Dev->>CLI: npm run build:circuits (build artifacts, compute source hash)
    CLI->>CLI: compile circuits, generate checksums & manifest
    Dev->>ArtifRepo: npm run store:circuits push (commit dist + SOURCE_HASH)
    ArtifRepo->>ArtifRepo: store artifacts on circuits branch

    Note over GHA,ArtifRepo: On release workflow
    GHA->>ArtifRepo: fetch/arcive origin/circuit-artifacts
    ArtifRepo-->>GHA: archive + SOURCE_HASH (or not found)
    GHA->>Release: set outputs found / source_hash
    Release->>Release: include noir-circuits asset and Source hash in final release notes if found
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • cedoor
  • 0xjei

Poem

🐰 I scurried through nargo, checksums in paw,
I bundled each circuit and left no flaw,
I hopped to a branch where artifacts sleep,
Now releases wake with hashes to keep,
A tiny rabbit cheers — soft thump, then a leap.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: circuits distribution' clearly and concisely describes the main change: adding circuit distribution functionality to the release workflow.
Linked Issues check ✅ Passed The PR fully implements issue #1235 requirements: provides download links for compiled circuits via GitHub Actions artifacts and includes checksums (SHA256SUMS and checksums.json) for integrity verification.
Out of Scope Changes check ✅ Passed All changes are directly related to circuits distribution: GitHub Actions workflow updates, build scripts, artifact management, and documentation are all within scope of the linked objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/circuits-distribution

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.github/workflows/release-test.yml:
- Around line 84-91: The workflow is reading github.event.inputs.version which
is undefined for push triggers; replace uses of github.event.inputs.version with
the pre-defined env.VERSION (or assign VERSION=${{ env.VERSION }}) wherever
VERSION is set or consumed (the shell assignment VERSION=..., the release notes
generation, and the release action fields tag_name and name) so the script and
the release action use env.VERSION consistently instead of
github.event.inputs.version.

In `@scripts/circuit-artifacts.ts`:
- Around line 55-68: The pull() function should (1) quote the DIST variable in
the git archive/tar shell invocation used by runV to safely handle paths with
spaces (reference DIST and runV in pull()), and (2) stop assuming every git
fetch failure means the branch is missing—capture the thrown error in the catch
block (reference run and BRANCH in pull()), log or include the actual error
message and exit with a generic "failed to fetch" message, or inspect the error
text to only treat explicit "branch not found" as that case (mirror the more
robust handling used in push()).
- Around line 44-50: The catch around the git operations (calls to run and runV
that perform `git commit`/`git push`) incorrectly conflates all failures as "No
changes"; update the catch in the try block that wraps run(`git commit...`) and
runV(...) to inspect the thrown error (or its message/exit code) and only treat
it as "no changes" when it clearly indicates nothing to commit (e.g., contains
"nothing to commit" / "no changes added to commit" or equivalent); for any other
error (git config/permissions/network), log the full error (including
error.message) with context (hash, BRANCH) and rethrow or exit non-zero so real
failures aren't masked. Ensure references to run, runV, hash, BRANCH and tmp are
preserved when adding the more specific handling and logging.
🧹 Nitpick comments (3)
.gitignore (1)

10-10: Trailing whitespace on dist entry.

There's a trailing space after dist which, while harmless for gitignore functionality, is inconsistent with the other entries.

Suggested fix
-dist 
+dist
scripts/circuit-artifacts.ts (1)

16-16: Functions are marked async but don't use await.

Both push() and pull() are declared as async but use synchronous execSync calls exclusively. The CLI dispatch doesn't await them either. This works because the functions are actually synchronous, but it's misleading.

Suggested fix: Remove async keywords
-async function push() {
+function push() {
-async function pull() {
+function pull() {

Also applies to: 55-55, 70-73

scripts/build-circuits.ts (1)

342-342: No validation for --env argument values.

The --env argument splits by comma and casts directly to Environment[] without validating that the values are actually valid environments (insecure or production). Invalid values like --env foo,bar would be silently accepted, resulting in no circuits being discovered.

Suggested fix: Validate environment values
-    else if (arg === '--env') options.environments = args[++i]?.split(',') as Environment[]
+    else if (arg === '--env') {
+      const envs = args[++i]?.split(',')
+      const valid = Object.values(ENVIRONMENTS) as string[]
+      const invalid = envs?.filter(e => !valid.includes(e))
+      if (invalid?.length) {
+        console.error(`❌ Invalid environment(s): ${invalid.join(', ')}. Valid: ${valid.join(', ')}`)
+        process.exit(1)
+      }
+      options.environments = envs as Environment[]
+    }

Comment thread .github/workflows/release-test.yml Outdated
Comment thread scripts/circuit-artifacts.ts
Comment thread scripts/circuit-artifacts.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In @.github/workflows/releases.yml:
- Around line 333-345: The Pull circuit artifacts step sets found=true
prematurely; update the step (the "Pull circuit artifacts" run block) to
validate the extracted dist/circuits layout and SOURCE_HASH before echoing
"found=true": after git archive extracts into dist/circuits, check for required
files/directories (e.g., expected circuit files or index manifest produced by
scripts/build-circuits.ts), compute or read the artifact hash from the extracted
artifacts and compare it to SOURCE_HASH, and only echo "found=true" to
GITHUB_OUTPUT if layout and hash match; otherwise echo "found=false" (and
optionally fail with a clear error) so downstream steps don't run on
malformed/mismatched artifacts.

In `@scripts/build-circuits.ts`:
- Around line 336-338: The --verbose flag is parsed into options.verbose but
never used; either remove its parsing/documentation or wire it to actual verbose
behavior. Locate the options object and where CLI flags are handled (references:
options.verbose and the argument-parsing block in build-circuits.ts) and
implement one of two fixes: 1) Remove the '-v'/'--verbose' branch and any
user-facing docs mentioning verbose, or 2) Use options.verbose to enable more
detailed logging (e.g., pass it into logging/helpers or conditionally increase
log level in functions that call build circuits or checksum routines) so the
flag has an effect across the script.
- Around line 305-321: The manifest currently builds artifact paths using
directory/name assumptions in generateManifest; instead, look up each circuit's
real artifact names from the discovered circuit metadata (e.g., use properties
on each circuit object such as packageName or artifacts produced by
discoverCircuits()) and construct artifacts.json as
`${environment}/${packageName}/${packageName}.json`; also respect the skip-vk
flag by omitting the vk entry when this.options.skipVk (or the equivalent
option) is true, otherwise include vk as
`${environment}/${packageName}/${packageName}.vk`; update generateManifest to
map circuits to use those real names and conditional vk inclusion.
- Around line 272-290: computeSourceHash/hashDir currently only updates the hash
with file names and contents, so renaming directories can leave the hash
unchanged; update hashDir to include directory names (or the file's relative
path) when iterating entries—e.g., before recursing into a directory or hashing
a file, call hash.update with the entry's relative path (or the joined relative
path from the circuit root) so directory structure is incorporated into the
final hash returned by computeSourceHash.
- Around line 143-188: The build currently treats a missing ${packageName}.json
as a warning; change buildCircuit so it fails loudly instead of returning an
incomplete CompiledCircuit: when jsonFile or targetDir is not found after
checking targetDirs, throw an Error (include circuit.environment and
circuit.name in the message) rather than logging and returning result; keep the
existing successful-path behavior (setting result.artifacts.json, checksums,
generating VK via generateVk when !this.options.skipVk) and ensure callers of
buildCircuit will observe the thrown error so CI fails.
- Around line 190-204: In generateVk, don't swallow errors silently: change the
empty catch to catch (err) and log the failure (including jsonFile and
packageName) and the error details (e.g., console.error(`Failed to generate VK
for ${jsonFile} (${packageName}):`, err)); optionally rethrow if you want the
build to fail instead of returning null; ensure the catch references the
generateVk function so you can find and update it.

In `@scripts/circuit-artifacts.ts`:
- Around line 40-41: The cpSync call is copying the DIST directory itself into
tmp (creating tmp/circuits/...), causing nested paths; change the copy to copy
DIST's contents into tmp instead. Locate the cpSync(DIST, tmp, { recursive: true
}) invocation and replace it so the copy operation targets the contents of DIST
(e.g., copy join(DIST, '.') or iterate DIST's entries and cpSync each into tmp)
so that files land directly under tmp (preserving the expected dist/circuits/...
layout) and keep the subsequent writeFileSync(join(tmp, 'SOURCE_HASH'), hash)
unchanged.

Comment thread .github/workflows/releases.yml
Comment thread scripts/build-circuits.ts
Comment thread scripts/build-circuits.ts
Comment thread scripts/build-circuits.ts
Comment thread scripts/build-circuits.ts Outdated
Comment thread scripts/build-circuits.ts
Comment thread scripts/circuit-artifacts.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.gitignore:
- Around line 9-10: The .gitignore entry "dist␠" has a trailing space so it
won't match the directory; remove the trailing space from the "dist" line (or
replace it with "dist/") to ensure the build output directory is actually
ignored and verify there is no trailing whitespace on that line.
🧹 Nitpick comments (4)
scripts/README.md (2)

195-196: Documentation shows only two groups but code defines three.

The --group option documentation lists only dkg,threshold, but build-circuits.ts also defines AGGREGATION: 'recursive_aggregation' as a valid group. Consider updating the documentation to include all available groups.

 Options:
-  --group <groups>    Circuit groups (comma-separated: dkg,threshold)
+  --group <groups>    Circuit groups (comma-separated: dkg,threshold,recursive_aggregation)

233-238: Inconsistent command usage between sections.

Line 237 uses pnpm tsx scripts/circuit-artifacts.ts push directly, while lines 218-219 use the npm script alias pnpm store:circuits push. For consistency and maintainability, prefer the npm script alias throughout.

 1. **Local**: Build circuits and push to branch

 ```bash
    pnpm build:circuits
-   pnpm tsx scripts/circuit-artifacts.ts push
+   pnpm store:circuits push

</blockquote></details>
<details>
<summary>scripts/build-circuits.ts (2)</summary><blockquote>

`329-331`: **CLI argument parsing can access undefined array index.**

When `--group`, `--circuit`, or `-o`/`--output` is the last argument without a value, `args[++i]` returns `undefined`. This silently sets invalid options rather than erroring.

<details>
<summary>🛡️ Proposed defensive fix</summary>

```diff
-    else if (arg === '--group') options.groups = args[++i]?.split(',') as CircuitGroup[]
-    else if (arg === '--circuit') (options.circuits ??= []).push(args[++i])
-    else if (arg === '-o' || arg === '--output') options.outputDir = resolve(args[++i])
+    else if (arg === '--group') {
+      const val = args[++i]
+      if (!val) { console.error('--group requires a value'); process.exit(1) }
+      options.groups = val.split(',') as CircuitGroup[]
+    }
+    else if (arg === '--circuit') {
+      const val = args[++i]
+      if (!val) { console.error('--circuit requires a value'); process.exit(1) }
+      (options.circuits ??= []).push(val)
+    }
+    else if (arg === '-o' || arg === '--output') {
+      const val = args[++i]
+      if (!val) { console.error('--output requires a value'); process.exit(1) }
+      options.outputDir = resolve(val)
+    }

222-232: Path sanitization regex may not cover all path separators consistently.

The regex uses [/\\] for separators but the replacement uses hardcoded forward slashes. On Windows, mixed separators in the output could occur. Also, silently ignoring errors here could hide issues during debugging.

Consider at minimum logging a warning when sanitization fails:

     } catch {
-      // Ignore errors
+      // Sanitization is best-effort; file may be read-only or malformed
     }

Comment thread .gitignore Outdated
@hmzakhalid hmzakhalid merged commit a77f9d4 into main Feb 4, 2026
25 checks passed
@github-actions github-actions Bot deleted the feat/circuits-distribution branch February 12, 2026 03:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release compiled circuits when publishing a new release on GH

2 participants