Failures (entire visual-test job)
Run: https://github.com/OpenStaticFish/ZigCraft/actions/runs/31080801035
Head SHA: 8d205ff0b27a951ac7136cb72796ecd8e2e91ed4 (the only commit on
dev: the nix flake → devenv migration, PR #951)
The visual-test workflow aborted before the game was ever built or run. No
build-output.log and no screenshot.png were produced. The workspace
contains only weston.log (weston startup at 07:28:36 followed by
[07:28:39.397] caught signal 15 from the Stop headless Wayland compositor step). The only failing step is the preflight that bootstraps
the issue labels.
Step table (run #31080801035, jobs API)
| # |
Step |
Status |
Conclusion |
| 1-7 |
Set up job → Load visual diagnosis prompt |
completed |
success |
| 8 |
Ensure visual-test label exists |
completed |
failure |
| 9 |
Setup Lavapipe Vulkan |
completed |
skipped |
| 10 |
Run menu screenshot capture |
completed |
skipped |
| 11 |
Check screenshot exists |
completed |
success (screenshot_exists=false) |
| 12 |
Compare against golden image |
completed |
skipped |
| 13 |
Upload screenshot artifact |
completed |
skipped |
| 14 |
Check build log exists |
completed |
success (file absent) |
| 15 |
Upload build log artifact |
completed |
skipped |
| 16 |
Stop headless Wayland compositor |
completed |
success |
| 17 |
Run opencode visual verification |
completed |
skipped |
| 18 |
Run opencode failure diagnosis |
in_progress |
— |
Exact failure
The failing step is Ensure visual-test label exists at
.github/workflows/visual-test.yml:55-66. It runs:
if ! gh label list --json name --jq '.[].name' | grep -q '^visual-test$'; then
gh label create "visual-test" \
--description "Issues from automated visual regression tests" \
--color "E06C75"
fi
if ! gh label list --json name --jq '.[].name' | grep -q '^run-visual-test$'; then
gh label create "run-visual-test" \
--description "Run deterministic visual regression workflow on a PR" \
--color "E06C75"
fi
gh label list returns the GitHub default 30 labels per page. This
repository currently has 41 labels (verified locally with
gh label list --repo OpenStaticFish/ZigCraft --limit 100 --json name).
visual-test is at index 20 (visible on page 1), but run-visual-test
is at index 40 (only on page 2). The precheck at visual-test.yml:62
therefore reports run-visual-test as missing even though it exists. The
subsequent gh label create then fails with:
label with name "run-visual-test" already exists; use `--force` to update its color and description
Because the step uses set -euo pipefail (the gh CLI exits non-zero
on a duplicate create), the step exits 1. Subsequent steps
(Setup Lavapipe Vulkan, Run menu screenshot capture, the screenshot
existence check, the golden-image diff, and the artifact uploads) are
skipped. Only the Stop headless Wayland compositor step runs
(if: always()), and it kills the weston process with SIGTERM — which
is the signal recorded in weston.log:62.
Why there is no Vulkan, swapchain, or screenshot error
VulkanSwapchain.createSwapchain at
modules/engine-graphics/src/vulkan_swapchain.zig:127, the headless
color-attachment image setup at the same file lines 128-174,
screenshot-mode init at src/game/app.zig:268-276, HomeScreen.init at
modules/game-ui/src/screens/home.zig:33-40, and
screenshot.requestCapture at
modules/engine-graphics/src/vulkan/screenshot.zig:24-44 were never
executed. The Zig binary was never launched; only the YAML pipeline ran.
Root cause
- File:
.github/workflows/visual-test.yml
- Function/step:
Ensure visual-test label exists at lines 55-66
- The precheck at line 62
(gh label list --json name --jq '.[].name' | grep -q '^run-visual-test$')
silently truncates to 30 labels and treats the existing run-visual-test
label as absent.
- The unconditional-on-miss create at lines 63-65 then fails with a
non-zero exit, surviving set -euo pipefail.
Recurring regression
This is the same root cause that has been filed repeatedly against
unmodified visual-test.yml since the devenv migration commit
8d205ff (the only commit on dev). Open duplicates of this exact
bug include (newest first):
None of those proposed fixes have been merged into dev. The
Ensure visual-test label exists step has not been modified since the
devenv migration, so the regression re-fires on every nightly schedule
run.
Suggested fix
Make the bootstrap idempotent without relying on paginated list output.
Apply in .github/workflows/visual-test.yml at lines 55-68:
- name: Ensure visual-test labels exist
run: |
gh label create "visual-test" \
--description "Issues from automated visual regression tests" \
--color "E06C75" \
--force
gh label create "run-visual-test" \
--description "Run deterministic visual regression workflow on a PR" \
--color "E06C75" \
--force
env:
GH_TOKEN: ${{ secrets.OPENCODE_PAT }}
--force makes gh label create succeed on existing labels (updating
color/description in place) and eliminates the paginated precheck
entirely.
Alternatives if a precheck is preferred:
- Query each exact label through
gh api repos/$GITHUB_REPOSITORY/labels/<name>
(single-resource GET, no pagination), or
- Pass
--limit 100 to the existing gh label list call.
--limit 100 masks the immediate bug but reintroduces a hidden
threshold as the label catalog grows, so --force is the more robust
fix.
Side observations (not blocking)
- The diagnosis prompt is stale:
.github/prompts/visual-test-diagnose.md:7 still says
screenshot.ppm, while the actual command at
.github/workflows/visual-test.yml:81 uses the supported
screenshot.png. The current encoder would still reject .ppm at
modules/engine-graphics/src/vulkan/screenshot.zig:39
(detectScreenshotFormat only accepts .png, .jpg, .jpeg,
.gif, .webp) if a future run ever reverted to .ppm. The prompt
also references src/game/screens/home.zig, but the HomeScreen now
lives at modules/game-ui/src/screens/home.zig.
Failures (entire visual-test job)
Run: https://github.com/OpenStaticFish/ZigCraft/actions/runs/31080801035
Head SHA:
8d205ff0b27a951ac7136cb72796ecd8e2e91ed4(the only commit ondev: the nix flake → devenv migration, PR #951)The visual-test workflow aborted before the game was ever built or run. No
build-output.logand noscreenshot.pngwere produced. The workspacecontains only
weston.log(weston startup at 07:28:36 followed by[07:28:39.397] caught signal 15from theStop headless Wayland compositorstep). The only failing step is the preflight that bootstrapsthe issue labels.
Step table (run #31080801035, jobs API)
screenshot_exists=false)Exact failure
The failing step is
Ensure visual-test label existsat.github/workflows/visual-test.yml:55-66. It runs:gh label listreturns the GitHub default 30 labels per page. Thisrepository currently has 41 labels (verified locally with
gh label list --repo OpenStaticFish/ZigCraft --limit 100 --json name).visual-testis at index 20 (visible on page 1), butrun-visual-testis at index 40 (only on page 2). The precheck at
visual-test.yml:62therefore reports
run-visual-testas missing even though it exists. Thesubsequent
gh label createthen fails with:Because the step uses
set -euo pipefail(theghCLI exits non-zeroon a duplicate create), the step exits 1. Subsequent steps
(
Setup Lavapipe Vulkan,Run menu screenshot capture, the screenshotexistence check, the golden-image diff, and the artifact uploads) are
skipped. Only the
Stop headless Wayland compositorstep runs(
if: always()), and it kills the weston process with SIGTERM — whichis the signal recorded in
weston.log:62.Why there is no Vulkan, swapchain, or screenshot error
VulkanSwapchain.createSwapchainatmodules/engine-graphics/src/vulkan_swapchain.zig:127, the headlesscolor-attachment image setup at the same file lines 128-174,
screenshot-mode init at
src/game/app.zig:268-276,HomeScreen.initatmodules/game-ui/src/screens/home.zig:33-40, andscreenshot.requestCaptureatmodules/engine-graphics/src/vulkan/screenshot.zig:24-44were neverexecuted. The Zig binary was never launched; only the YAML pipeline ran.
Root cause
.github/workflows/visual-test.ymlEnsure visual-test label existsat lines 55-66(
gh label list --json name --jq '.[].name' | grep -q '^run-visual-test$')silently truncates to 30 labels and treats the existing
run-visual-testlabel as absent.
non-zero exit, surviving
set -euo pipefail.Recurring regression
This is the same root cause that has been filed repeatedly against
unmodified
visual-test.ymlsince the devenv migration commit8d205ff(the only commit ondev). Open duplicates of this exactbug include (newest first):
None of those proposed fixes have been merged into
dev. TheEnsure visual-test label existsstep has not been modified since thedevenv migration, so the regression re-fires on every nightly schedule
run.
Suggested fix
Make the bootstrap idempotent without relying on paginated list output.
Apply in
.github/workflows/visual-test.ymlat lines 55-68:--forcemakesgh label createsucceed on existing labels (updatingcolor/description in place) and eliminates the paginated precheck
entirely.
Alternatives if a precheck is preferred:
gh api repos/$GITHUB_REPOSITORY/labels/<name>(single-resource GET, no pagination), or
--limit 100to the existinggh label listcall.--limit 100masks the immediate bug but reintroduces a hiddenthreshold as the label catalog grows, so
--forceis the more robustfix.
Side observations (not blocking)
.github/prompts/visual-test-diagnose.md:7still saysscreenshot.ppm, while the actual command at.github/workflows/visual-test.yml:81uses the supportedscreenshot.png. The current encoder would still reject.ppmatmodules/engine-graphics/src/vulkan/screenshot.zig:39(
detectScreenshotFormatonly accepts.png,.jpg,.jpeg,.gif,.webp) if a future run ever reverted to.ppm. The promptalso references
src/game/screens/home.zig, but the HomeScreen nowlives at
modules/game-ui/src/screens/home.zig.