Skip to content

fix(build): pin XcodeGen for CI and local builds, stabilize test failure reporting#88

Open
gly11 wants to merge 5 commits into
mrmidi:mainfrom
gly11:codex/ci-stabilize-test-workflow
Open

fix(build): pin XcodeGen for CI and local builds, stabilize test failure reporting#88
gly11 wants to merge 5 commits into
mrmidi:mainfrom
gly11:codex/ci-stabilize-test-workflow

Conversation

@gly11

@gly11 gly11 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • pin the XcodeGen release and SHA-256 used to verify the committed project
  • share that pin with build.sh through .xcodegen-version so CI and local
    builds cannot disagree
  • refuse to regenerate the project when the pin is missing, unreadable, or
    undefined, instead of silently falling back to an unpinned xcodegen
  • document the pinned install in README and the pin's existence in CLAUDE.md
  • defer GoogleTest discovery until CTest execution
  • preserve the real xcodebuild exit status in quiet Swift-test runs

Why

The open SBP-2 pull requests each carried copies of the same CI stabilization
commits. Keeping the fixes in one prerequisite PR makes the feature diffs
reviewable. The quiet Swift-test pipeline separately appended || true before
reading PIPESTATUS, which could report success after xcodebuild failed.

Pinning only the workflow left the two halves free to drift. build.sh ran
whatever xcodegen was on PATH and regenerates ASFW.xcodeproj on every
non-test-only build. Homebrew ships 2.46.0 while the workflow pinned 2.45.4,
and their output is not byte-identical — 2.46.0 reorders the pbxproj targets
array. A single ./build.sh on a brew-current machine would commit a project
the drift check rejects, and that check tells you to regenerate, reproducing
the same diff. The version and its SHA-256 now live in .xcodegen-version,
read by both sides; the pin moves to 2.46.0 and the project is regenerated with
it (only the targets ordering changes, no semantic effect).

Three decisions worth flagging for review:

  • build.sh fails on a version mismatch rather than warning and skipping
    regeneration — a build silently missing a newly added source file is harder
    to diagnose than a version mismatch. --no-xcodegen is the escape hatch.
  • A missing or malformed .xcodegen-version is also fatal. Guarding the
    check behind the file's existence would mean deleting one file silently
    restores the behaviour the guard exists to prevent.
  • The README install block exports PATH and runs hash -r. Without it
    Homebrew's xcodegen keeps winning the lookup and the guard goes on firing
    even after a correct install.

Impact

Infrastructure only — no driver, app, protocol, or wire behavior changes.
Contributors with a mismatched or malformed pin now get an explicit error from
build.sh instead of a silently rejected pbxproj; contributors with no
xcodegen installed are unaffected, since the whole guard sits inside the
command -v xcodegen branch.

Validation

Project generation and the pin

  • downloaded XcodeGen 2.46.0, verified the pinned SHA-256, regenerated
    ASFW.xcodeproj: no drift
  • 2.45.4 vs 2.46.0 output differs only in targets ordering (identical after
    normalizing the pbxproj to sorted JSON)
  • CI reproduced the whole path on its own runner: pinned download, checksum,
    regeneration, zero drift
  • guard, all four paths: version mismatch / pin unreadable / XCODEGEN_VERSION
    undefined all stop without touching the pbxproj; matching version regenerates
  • README block run verbatim into a throwaway prefix: checksum verified and
    command -v xcodegen then resolved to the pinned 2.46.0, not the Homebrew copy

Test reporting and the rest

  • quiet pipeline preserves a simulated xcodebuild exit status of 42
  • ConfigROMStoreConcurrencyTests: 7/7 passed with PRE_TEST discovery
  • workflow YAML parses, bash -n build.sh, git diff --check

Follow-up for the stacked PRs

After this merges, #84#87 should be rebased onto main to drop the duplicated
CI commits. #85 and #86 carry pbxproj changes of their own and must have their
project regenerated with the pinned XcodeGen 2.46.0 as part of that rebase, or
the drift check will fail. #84 and #87 touch no pbxproj.

gly11 added 2 commits July 27, 2026 02:06
The pin added earlier in this branch only bound CI. build.sh still ran
whatever xcodegen was on PATH, and it regenerates ASFW.xcodeproj on every
non-test-only build. Homebrew currently ships 2.46.0 while the pin was
2.45.4, and their output is not byte-identical -- 2.46.0 reorders the
pbxproj `targets` array. So a single ./build.sh on a brew-current machine
produces a project the drift check rejects, and that check's error message
tells you to regenerate, which reproduces the same diff.

Move the version and its SHA-256 into .xcodegen-version and have both the
workflow and build.sh read it, so the two can no longer disagree.

build.sh now stops with an actionable error when the installed version
differs, rather than warning and skipping regeneration: a build silently
missing a newly added source file is much harder to diagnose than a version
mismatch. --no-xcodegen builds the committed project as-is for machines that
can't install the pin.

Bump the pin to 2.46.0 to match what Homebrew ships today, and regenerate
ASFW.xcodeproj with it. The only change is the `targets` array ordering,
which has no semantic effect.

Document how to install the pinned release in README -- the same download,
pin, and checksum CI uses -- since "install the pinned version" isn't
actionable without it.
@gly11 gly11 changed the title fix(ci): stabilize project generation and test failure reporting fix(build): pin XcodeGen for CI and local builds, stabilize test failure reporting Jul 26, 2026
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.

1 participant