fix(ci): skip release instead of erroring when both fixtures are cached - #2036
Conversation
…ed (#2034) map(select(.build)) yields an empty include list when both the iOS and Android fingerprints already have a trusted artifact, and GitHub Actions rejects an empty strategy.matrix at the workflow level -- so release was never created and the run was marked failure on every push since #1996 merged. Publish has-work alongside matrix and gate release on it, so the both-cached steady state now completes with release skipped instead of erroring the whole workflow.
Size Report
npm unpacked components
Startup median (7 runs, lower is better):
Top changed chunks:
Top changed packed files
|
Reviewer feedback on #2036: the standalone four-case test duplicated the harness above it and only two states are meaningful for this regression. Reuse the same parsed workflow, temp dir, resolver stub, and Node stub; keep neither-cached (both platforms, has-work=true) and both-cached (empty matrix, has-work=false, release gated). Drops the single-cache permutations, which exercise #1996's unchanged filtering rather than this fix.
|
Re-reviewed |
Reduced coverage to 0-cached and 2-cached, leaving the 1-cached cardinality unchecked -- a mistaken \`length > 1\` in the has-work check would pass while wrongly suppressing a valid single-platform build. Generalize the Node stub to report caching per artifact-name suffix and add the iOS-cached case to the same reused harness.
|
Added exactly one single-cache case to the reused harness in 🤖 Addressed by Claude Code |
|
Re-review at |
…lines Thermo-nuclear review: matrix was already parsed out of its GITHUB_OUTPUT line (prefix stripped, JSON-parsed), but hasWork returned the raw "has-work=true" line, so assertions compared against a redundant 'has-work=true' string instead of the actual value. Slice the prefix the same way matrix does.
|
Delta re-review at |
|
Current-head CI is now complete: all 19 non-skipped checks passed, and the sole skipped matrix.name is the intended no-work release path. The prior clean code verdict is now merge-ready. |
|
Summary
Fixes #2034.
Test App Build Cachehas failed on every run since 2026-08-24 14:42 UTC, including onmain.#1996 changed the release matrix builder to filter to only entries that will actually build:
That's correct when at least one fixture needs building, but when both are already cached,
map(select(.build))yieldsinclude: []. GitHub Actions rejects an emptystrategy.matrixat the workflow level, so thereleasejob is never created and the whole run is markedfailure. Both-cached is the steady state, which is why this fails on nearly every run rather than intermittently.fingerprintnow also publishes ahas-workoutput (jq -r '.include | length > 0'over the matrix).releasegetsif: needs.fingerprint.outputs.has-work == 'true', so a both-cached run skipsreleaseinstead of erroring.I checked whether a skipped
releasebreaks anything downstream thatneeds:it: nothing does — consumers (setup-fixture-app/trusted-artifact.mjs) pollclassifyProducerState, which reads the workflow run's overallstatus/conclusion, not individual job state. A workflow with a skipped job (and no failed jobs) reportssuccess, so consumers correctly see the producer as done rather than failed.Test plan
test/ci/trusted-fixture-artifact.test.mjs) that executes the real fingerprint jq/shell step across all four cache combinations (both-cached, iOS-only, Android-only, neither), pinning that both-cached producesinclude: []+has-work=false, and every other combination produceshas-work=true. This is the combination that shipped broken and had no prior coverage.has-work=output line in$GITHUB_OUTPUT.pnpm run test:fixture-cache— all 12 tests pass.actionlint .github/workflows/test-app-build-cache.yml— clean.oxlinton the modified test file — clean.After merge, a push to
mainwith no native change should showTest App Build Cachegreen withreleaseskipped rather than errored; a run where a fingerprint actually changed should still build and publish as before.