-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
CI: deterministic required iOS build gate (prevent iOS compile breaks on main) #6202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
0886258
342f7bc
1abd680
1dc2e1b
23089f6
ac6c927
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1251,3 +1251,86 @@ jobs: | |
| kill "$VDISPLAY_PERSISTENT_PID" >/dev/null 2>&1 || true | ||
| fi | ||
| rm -f /tmp/cmux-vdisplay-persistent.ready /tmp/cmux-vdisplay-persistent.id /tmp/cmux-vdisplay-persistent.log | ||
|
|
||
| ios-build: | ||
| # Deterministic iOS compile gate. The iOS app and the iOS-only CmuxMobile* | ||
| # packages are otherwise compiled ONLY in the non-required, flaky | ||
| # ios-simulator job (test-ios.yml), so an iOS-only compile break can merge | ||
| # green even though every required check passed. That is exactly how the | ||
| # @MainActor/nonisolated break in the composer image-decode path | ||
| # (TerminalComposerView) reached main. This job compiles the iOS app for the | ||
| # simulator WITHOUT running tests or booting a simulator, so it is | ||
| # deterministic (no virtual display, no sim boot) and safe to require. | ||
| # It runs on every PR and on push to main; make it a required status check. | ||
| runs-on: ${{ vars.MACOS_RUNNER_26 || 'warp-macos-26-arm64-6x' }} | ||
| timeout-minutes: 35 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
| submodules: recursive | ||
|
|
||
| - name: Select Xcode | ||
| run: | | ||
| set -euo pipefail | ||
| if [ -d "/Applications/Xcode.app/Contents/Developer" ]; then | ||
| XCODE_DIR="/Applications/Xcode.app/Contents/Developer" | ||
| else | ||
| XCODE_APP="$(find /Applications -maxdepth 1 -name 'Xcode*.app' -print 2>/dev/null | sort | tail -n 1 || true)" | ||
| if [ -n "$XCODE_APP" ]; then | ||
| XCODE_DIR="$XCODE_APP/Contents/Developer" | ||
| else | ||
| echo "No Xcode.app found under /Applications" >&2 | ||
| exit 1 | ||
| fi | ||
| fi | ||
| echo "DEVELOPER_DIR=$XCODE_DIR" >> "$GITHUB_ENV" | ||
| export DEVELOPER_DIR="$XCODE_DIR" | ||
| xcodebuild -version | ||
|
|
||
| - name: Provision GhosttyKit | ||
| run: | | ||
| # The iOS app links GhosttyKit (incl. its iOS + iOS-simulator slices) | ||
| # via a local-path binaryTarget, so it must exist before resolve. | ||
| # Mirror the ios-simulator job exactly: ensure-ghosttykit.sh manages | ||
| # its own $HOME/.cache/cmux/ghosttykit cache and writes the framework | ||
| # where the iOS workspace expects it. Do NOT add an actions/cache step | ||
| # keyed on repo-root GhosttyKit.xcframework here: ensure-ghosttykit.sh | ||
| # does not populate that path, and the shared ghosttykit-<sha> key is | ||
| # owned by the macOS jobs that use download-prebuilt (a real dir), so | ||
| # caching a symlink/absent path from this job would poison that key. | ||
| ./scripts/install-zig-ci.sh | ||
| ./scripts/ensure-ghosttykit.sh | ||
|
|
||
| - name: Cache Swift packages | ||
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | ||
| with: | ||
| path: .spm-cache-ios | ||
| key: spm-ios-${{ hashFiles('ios/cmuxPackage/Package.resolved') }} | ||
| restore-keys: spm-ios- | ||
|
cursor[bot] marked this conversation as resolved.
|
||
|
|
||
| - name: Resolve packages | ||
| run: | | ||
| set -euo pipefail | ||
| xcodebuild -workspace ios/cmux.xcworkspace \ | ||
| -scheme cmux-ios \ | ||
| -destination 'generic/platform=iOS Simulator' \ | ||
| -derivedDataPath /tmp/cmux-ios-build \ | ||
| -clonedSourcePackagesDirPath .spm-cache-ios \ | ||
| -resolvePackageDependencies | ||
|
|
||
| - name: Build iOS app for simulator (compile only, no tests, no boot) | ||
| run: | | ||
| set -euo pipefail | ||
| # build-for-testing compiles the app and the test targets for the | ||
| # simulator using a GENERIC destination, so nothing is booted and the | ||
| # result is deterministic. This catches the Swift compile breaks | ||
| # (actor isolation, missing await, etc.) that only manifest in the iOS | ||
| # build and are invisible to the macOS unit-test job. | ||
| xcodebuild -workspace ios/cmux.xcworkspace \ | ||
| -scheme cmux-ios \ | ||
| -destination 'generic/platform=iOS Simulator' \ | ||
| -derivedDataPath /tmp/cmux-ios-build \ | ||
| -clonedSourcePackagesDirPath .spm-cache-ios \ | ||
| CODE_SIGNING_ALLOWED=NO \ | ||
| build-for-testing | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify ios-build resolves packages explicitly, then builds without -disableAutomaticPackageResolution.
rg -n -C4 'name: Resolve packages|resolvePackageDependencies|name: Build iOS app for simulator|build-for-testing|disableAutomaticPackageResolution' .github/workflows/ci.ymlRepository: manaflow-ai/cmux Length of output: 7893 🌐 Web query:
💡 Result: The xcodebuild flag -disableAutomaticPackageResolution is used to prevent the build system from automatically resolving or updating Swift package dependencies to versions other than those explicitly recorded in the Package.resolved file [1][2][3]. By using this flag, you ensure that your CI pipeline or build environment strictly adheres to the state defined in the Package.resolved file [4]. This is a common best practice for CI/CD workflows to prevent unexpected dependency changes and to ensure build reproducibility [4][5]. Key points regarding this flag: - Functionality: It forces xcodebuild to rely on the existing Package.resolved file. If the project's dependencies are out of sync with this file, the build will typically fail rather than attempting to automatically resolve the differences [6][5]. - Usage: It is frequently paired with -onlyUsePackageVersionsFromResolvedFile, which serves a similar purpose [1][2][3]. - CI/CD Context: It is standard to include this flag in CI environments to guarantee that the code being tested uses the exact versions of dependencies that were vetted and committed to source control [4]. If you encounter an error stating that an out-of-date resolved file was detected, this indicates that your Package.resolved file does not match your current project dependency configuration [6][5]. In such cases, you must update the Package.resolved file in your local development environment and commit the changes to your repository before the CI can proceed successfully [4][6]. Citations:
🏁 Script executed: # Verify line numbers in the snippet match the comment range
sed -n '1328,1342p' .github/workflows/ci.ymlRepository: manaflow-ai/cmux Length of output: 528 Add Line 1320 explicitly resolves packages, but the subsequent Suggested patch xcodebuild -workspace ios/cmux.xcworkspace \
-scheme cmux-ios \
-destination 'generic/platform=iOS Simulator' \
-derivedDataPath /tmp/cmux-ios-build \
-clonedSourcePackagesDirPath .spm-cache-ios \
+ -disableAutomaticPackageResolution \
CODE_SIGNING_ALLOWED=NO \
build-for-testing🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The PR description lists "test-ios.yml also re-runs on push to main (iOS paths) for post-merge detection" as one of the explicit goals of this change. However, |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: manaflow-ai/cmux
Length of output: 9720
Add
persist-credentials: falseto theios-buildcheckout step for credential hardening.The checkout in this job leaves credentials persisted in the local git config by default, increasing token exposure in subsequent steps. This differs from the hardened pattern used in test-ios.yml. Add
persist-credentials: falseto align with security best practices.Suggested patch
- name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: + persist-credentials: false submodules: recursive📝 Committable suggestion
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 1268-1271: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Source: Linters/SAST tools