Skip to content

ci: fix flaky Xcode 26 selection killed by SIGPIPE under pipefail - #82

Merged
NuPlay merged 1 commit into
mainfrom
fix/ci-xcode-selection-pipefail
Aug 29, 2026
Merged

ci: fix flaky Xcode 26 selection killed by SIGPIPE under pipefail#82
NuPlay merged 1 commit into
mainfrom
fix/ci-xcode-selection-pipefail

Conversation

@NuPlay

@NuPlay NuPlay commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Problem

The Select Xcode 26 step tested each candidate with:

if [ -d "${candidate}" ] && DEVELOPER_DIR="${candidate}/Contents/Developer" xcodebuild -version | grep -q '^Xcode 26'; then

under set -euo pipefail.

grep -q exits the moment it matches. xcodebuild is then still writing, takes SIGPIPE, and dies with an uncaught NSFileHandleOperationException (*** -[_NSStdIOFileHandle writeData:]: Broken pipe, Abort trap: 6). pipefail propagates that as the exit status of the whole pipeline, so the condition evaluated false for the candidate that actually was Xcode 26, the loop fell through every entry, and the job failed with Xcode 26 is required for this CI job.

Whether xcodebuild finishes writing before grep closes the pipe is a race, which is why this only failed sometimes. Four pull request runs on the same day:

run result Abort trap occurrences in the step log
#78 pass 0
#79 pass 0
#80 fail 4
#81 fail 4

Note the failures are entirely inside this step - nothing was ever compiled, so the failures said nothing about the code in those PRs.

Fix

Capture the version output into a variable and match it with case, so there is no pipe and nothing can be signalled mid-write.

version="$(DEVELOPER_DIR="${candidate}/Contents/Developer" xcodebuild -version 2>/dev/null || true)"

case "${version}" in
  "Xcode 26"*)
    XCODE_APP="${candidate}"
    break
    ;;
esac

Verification

Reproduced the mechanism deterministically with a producer large enough to lose the race every time:

old pattern -> candidate REJECTED even though the version matched   <-- the bug
new pattern -> candidate SELECTED

Should be merged before the other open pull requests, so their runs stop failing at random.

The Xcode selection loop tested each candidate with:

    xcodebuild -version | grep -q '^Xcode 26'

under `set -euo pipefail`. `grep -q` exits the moment it matches, xcodebuild
then takes SIGPIPE while it is still writing, dies with an uncaught
NSFileHandleOperationException ("Broken pipe", Abort trap: 6), and `pipefail`
propagates that as the exit status of the whole pipeline. The condition
therefore evaluated false for the candidate that actually *was* Xcode 26, the
loop fell through every entry, and the job failed with
"Xcode 26 is required for this CI job."

Whether xcodebuild finished writing before grep closed the pipe is a race, so
this only failed intermittently: of four pull request runs on the same day,
two passed with no abort trap and two failed with four abort traps each.

Capture the version output into a variable and match it with `case` instead, so
no pipe exists and nothing can be signalled mid-write.
Copilot AI lite review requested due to automatic review settings August 29, 2026 04:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change removes a known race-prone pipeline pattern in CI and replaces it with a deterministic, low-risk string match without affecting build/test behavior beyond Xcode selection.

Pull request overview

This PR fixes a flaky CI failure in the “Select Xcode 26” workflow step by removing a pipefail-sensitive xcodebuild | grep -q pipeline that could intermittently reject the correct Xcode due to SIGPIPE behavior.

Changes:

  • Replace xcodebuild -version | grep -q '^Xcode 26' with capturing xcodebuild -version output into a variable and matching via case.
  • Add an in-script rationale explaining the SIGPIPE + pipefail failure mode and why the new approach is race-free.
File summaries
File Description
.github/workflows/ci.yml Makes Xcode 26 selection deterministic by avoiding a fragile `xcodebuild
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@NuPlay NuPlay self-assigned this Aug 29, 2026
@NuPlay NuPlay added the bug Something isn't working label Aug 29, 2026
@NuPlay
NuPlay merged commit e23a32f into main Aug 29, 2026
2 checks passed
@NuPlay
NuPlay deleted the fix/ci-xcode-selection-pipefail branch August 29, 2026 04:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants