Skip to content

[Visual Test] Workflow fails before game runs: 'Ensure visual-test label exists' step rejected by duplicate label #947

Description

@MichaelFisher1997

Summary

The visual-test schedule run is failing before the game ever starts. The failure happens in the workflow's Ensure visual-test label exists preflight step, not in the Vulkan/SDL/screenshot pipeline the diagnose prompt describes. There is no build-output.log for this run because the game command at .github/workflows/visual-test.yml:81 was skipped.

Workflow run: https://github.com/OpenStaticFish/ZigCraft/actions/runs/29809988559 (also reproduced on the previous scheduled run 29725595085, which used the same head SHA 8945da9).

Error output from the failing step

Step name in the Actions UI: Ensure visual-test label exists.

Observed step outcome:

Process completed with exit code 1.

Observed step state (from the run page):

Ensure visual-test label exists     failure
Setup Lavapipe Vulkan               skipped
Run menu screenshot capture         skipped
Upload build log artifact           skipped
Stop headless Wayland compositor    skipped
Run opencode failure diagnosis      failure

Weston itself started cleanly at 1280x720 and was terminated by the cleanup step after the preflight failure; weston.log contains no compositor error.

Diagnosis

The failure originates in .github/workflows/visual-test.yml:55-68, specifically the second guard and create at .github/workflows/visual-test.yml:62-65:

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 at most 30 labels by default. The repository currently has 41 labels (curl https://api.github.com/repos/OpenStaticFish/ZigCraft/labels?per_page=100). With the default ordering, visual-test is at position 38 and run-visual-test is at position 35 — both outside the first-page window, so neither guard sees them, both gh label create calls fire, and GitHub rejects the second one because run-visual-test already exists. That duplicate-create rejection is what produces exit code 1.

This is purely a workflow-side preflight failure. None of the rendering paths referenced in the diagnose prompt were reached:

  • initContext in modules/engine-graphics/src/rhi_vulkan.zig
  • headless createSwapchain path in modules/engine-graphics/src/vulkan_swapchain.zig:127-174
  • menu selection in src/game/app.zig:268-276
  • HomeScreen.init in modules/game-ui/src/screens/home.zig:33-41
  • captureFrame in modules/engine-graphics/src/rhi_vulkan.zig:415-420
  • requestCapture / recordCapture / completeCapture in modules/engine-graphics/src/vulkan/screenshot.zig

Therefore the Vulkan instance/device, swapchain, shader, HomeScreen, and screenshot readback code paths have not been exercised by these failures; they remain unverified until the workflow actually reaches the game step.

Side note on the diagnose prompt

The current visual-test.yml invokes zig build run -Dscreenshot-path=screenshot.png -Dskip-present=true (line 81), not -Dscreenshot-path=screenshot.ppm as .github/prompts/visual-test-diagnose.md describes. PNG is supported by detectScreenshotFormat in modules/engine-graphics/src/vulkan/screenshot.zig:262-267; PPM is not. If the workflow is ever changed to write a .ppm, requestCapture would log screenshot: unsupported image path 'screenshot.ppm' (use .png, .jpg, .jpeg, .gif, or .webp) and the game would never capture a frame. Either keep the workflow on .png, add a PPM encoder to screenshot.zig, or update the diagnose prompt to match the actual command.

Failure origin

  • File: .github/workflows/visual-test.yml
  • Step: Ensure visual-test label exists
  • Failing command: gh label create "run-visual-test" at .github/workflows/visual-test.yml:63
  • Trigger: unpaginated gh label list guard at .github/workflows/visual-test.yml:62 (and the symmetric guard for visual-test at lines 57-61)
  • Head SHA: 8945da9ecb9944048dd94f70a88b63733dcc1a9e (feat: ship high-detail live world map (#943))

Suggested fix

Make the label setup idempotent without depending on a paginated gh label list query. Either pass --force to gh label create, or check each label with gh label view first. Increasing the --limit is fragile because the label count will keep growing.

- 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 }}

After the fix, please re-run visual-test on dev so we can finally exercise the headless Lavapipe + screenshot path and confirm the actual rendering pipeline (which this issue has not been able to validate).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghotfixquestionFurther information is requestedvisual-testIssues from automated visual regression tests

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions