ReviewOS

also looking at this

craft-native/craft

ci: pin the first-party Zig dependencies to commits

#39
Merged glennmichael123 wants to merge ci/pin-first-party-zig-deps into main
2 files +62 -15
11 days ago

The immediate breakage is already fixed upstream (zig-utils/zig-js#625, merged). This is so it cannot happen again from a repository nobody here pushed to.

What went wrong

build.zig.zon reaches zig-js and its zig-regex / zig-gc by relative path, so Zig's package manager has no .url + hash to verify and nothing recorded which revision a build used. This action cloned each default branch — which hands the question of whether craft's CI is green to whoever last pushed to another repo.

That is not hypothetical. zig-js sized a SIMD loop by @sizeOf(@Vector(8, u8)), which is 8 on aarch64 and 16 on x86_64. Every Linux job here failed to compile for three days over a change nobody made in this repo — and because macOS stayed green, it read as a platform problem rather than a dependency one.

The action's own comment already conceded the point ("an unrelated push to zig-js can turn a craft build red") and deferred it to a future .url + hash dependency. That still needs zig-js to publish its own dependencies the same way, and this is cheap in the meantime.

What this does

Revisions live in pins.env next to the action:

# fix(lexer): size the SIMD identifier scan by lane count, not byte size (#625)
zig_js=eba3f7cfb8b32d6d84099b10f0e063fa0e0c53c7

Bumping one becomes a commit that says which revision changed and why, with CI proving it before it lands. "Whatever main happened to be at 13:32" said neither.

Two details that matter:

  • The fetch takes the pinned commit, not the branch tip. A pin may point at something that is no longer the tip, and --depth 1 on a branch would not reach it.
  • A checkout already at the pin is left alone; one at any other revision is replaced. Several jobs call this action and some run it more than once, so a stale tree must not quietly win.

Local development is untouched: developers still build against their own sibling checkouts, and pins.env is read only by this CI action.

Verification

I ran the action's script directly against a simulated workspace rather than only reading it:

caseresult
fresh workspaceall three fetched by SHA in ~8s; the checked-out lexer.zig has const lanes = @typeInfo(Block).vector.len
run again unchangedzig-js already at eba3f7c… — no refetch
checkout moved to HEAD~1zig-js pinned at eba3f7c…, and rev-parse HEAD confirms it moved back

This PR's own Linux jobs are the real test: they exercise the new action on every leg.

2 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.