Repository navigation
Publish separate universal nightly track #1067
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
Changes from all commits
2e80a01
1ed4aa1
9395602
e23eb28
4022a46
8958769
76f53aa
4cce891
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,7 +58,7 @@ else | |
| echo "==> Building GhosttyKit.xcframework (this may take a few minutes)..." | ||
| ( | ||
| cd ghostty | ||
| zig build -Demit-xcframework=true -Doptimize=ReleaseFast | ||
| zig build -Demit-xcframework=true -Dxcframework-target=universal -Doptimize=ReleaseFast | ||
|
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. P2: The cache key/stamp does not include xcframework target, so existing same-SHA artifacts can bypass this new universal build setting and keep serving stale architecture output. Prompt for AI agentsThere 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.
This switches local GhosttyKit builds to universal, but Useful? React with 👍 / 👎. |
||
| ) | ||
| # Stamp the build output with the SHA it was built from | ||
| echo "$GHOSTTY_SHA" > "$LOCAL_SHA_STAMP" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| #!/usr/bin/env bash | ||
| # Regression test for universal GhosttyKit and Release build settings. | ||
| set -euo pipefail | ||
|
|
||
| ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" | ||
|
|
||
| for file in \ | ||
| "$ROOT_DIR/.github/workflows/build-ghosttykit.yml" \ | ||
| "$ROOT_DIR/scripts/setup.sh" \ | ||
| "$ROOT_DIR/scripts/build-sign-upload.sh" | ||
| do | ||
| if ! grep -Fq -- '-Dxcframework-target=universal' "$file"; then | ||
|
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. P2: This regression test relies on grep/awk checks of source text instead of verifying executable behavior, which violates the repository’s test quality policy. Prompt for AI agentsThere 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.
This test validates behavior by grepping/awking repository files instead of exercising runtime build behavior, so it is brittle to refactors and can still pass when the actual pipeline/build output is wrong. The repository policy in Useful? React with 👍 / 👎. |
||
| echo "FAIL: $file must build GhosttyKit with -Dxcframework-target=universal" | ||
| exit 1 | ||
| fi | ||
| done | ||
|
|
||
| if ! awk ' | ||
| /\/\* Release \*\// { in_release=1; next } | ||
| in_release && /ONLY_ACTIVE_ARCH = YES;/ { saw_yes=1 } | ||
| in_release && /ONLY_ACTIVE_ARCH = NO;/ { saw_no=1 } | ||
| in_release && /name = Release;/ { in_release=0 } | ||
| END { exit !(saw_no && !saw_yes) } | ||
| ' "$ROOT_DIR/GhosttyTabs.xcodeproj/project.pbxproj"; then | ||
| echo "FAIL: Release configurations in project.pbxproj must use ONLY_ACTIVE_ARCH = NO" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "PASS: GhosttyKit builds universal and Release configs disable ONLY_ACTIVE_ARCH" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| #!/usr/bin/env bash | ||
|
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. P1: This entire test file verifies source-code text patterns (awk/grep on the YAML workflow file) rather than observable runtime behavior, which the project's test quality policy explicitly prohibits. If the goal is to lock in universal-build and publish-guard behavior, consider a test that actually exercises the workflow outputs — e.g., a small script that invokes the build with the expected flags and verifies the resulting binary is universal via Prompt for AI agents |
||
| # Regression test for dual nightly macOS tracks. | ||
| set -euo pipefail | ||
|
|
||
| ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" | ||
| WORKFLOW_FILE="$ROOT_DIR/.github/workflows/nightly.yml" | ||
|
|
||
| if ! awk ' | ||
| /^ - name: Build Apple Silicon app \(Release\)/ { in_arm=1; next } | ||
| /^ - name: Build universal app \(Release\)/ { in_universal=1; next } | ||
| in_arm && /^ - name:/ { in_arm=0 } | ||
| in_universal && /^ - name:/ { in_universal=0 } | ||
|
Comment on lines
+8
to
+12
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.
This test only inspects Useful? React with 👍 / 👎. |
||
| in_arm && /-destination '\''platform=macOS,arch=arm64'\''/ { saw_arm_destination=1 } | ||
| in_arm && /ARCHS="arm64"/ { saw_arm_archs=1 } | ||
| in_arm && /ONLY_ACTIVE_ARCH=YES/ { saw_arm_only_active_arch=1 } | ||
| in_universal && /-destination '\''generic\/platform=macOS'\''/ { saw_universal_destination=1 } | ||
| in_universal && /ARCHS="arm64 x86_64"/ { saw_universal_archs=1 } | ||
| in_universal && /ONLY_ACTIVE_ARCH=NO/ { saw_universal_only_active_arch=1 } | ||
| END { | ||
| exit !(saw_arm_destination && saw_arm_archs && saw_arm_only_active_arch && saw_universal_destination && saw_universal_archs && saw_universal_only_active_arch) | ||
| } | ||
| ' "$WORKFLOW_FILE"; then | ||
| echo "FAIL: nightly workflow must force Apple Silicon nightly to arm64-only and universal nightly to both slices" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! awk ' | ||
| /^ - name: Verify nightly binary architectures/ { in_verify=1; next } | ||
| in_verify && /^ - name:/ { in_verify=0 } | ||
| in_verify && /lipo -archs "\$ARM_APP_BINARY"/ { saw_arm_app=1 } | ||
| in_verify && /lipo -archs "\$ARM_CLI_BINARY"/ { saw_arm_cli=1 } | ||
| in_verify && /lipo -archs "\$APP_BINARY"/ { saw_app=1 } | ||
| in_verify && /lipo -archs "\$CLI_BINARY"/ { saw_cli=1 } | ||
| in_verify && /\[\[ "\$ARM_APP_ARCHS" == "arm64" \]\]/ { saw_arm_app_assert=1 } | ||
| in_verify && /\[\[ "\$ARM_CLI_ARCHS" == "arm64" \]\]/ { saw_arm_cli_assert=1 } | ||
| END { exit !(saw_arm_app && saw_arm_cli && saw_app && saw_cli && saw_arm_app_assert && saw_arm_cli_assert) } | ||
| ' "$WORKFLOW_FILE"; then | ||
| echo "FAIL: nightly workflow must verify arm-only and universal slices with lipo" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! grep -Fq 'com.cmuxterm.app.nightly.universal' "$WORKFLOW_FILE"; then | ||
| echo "FAIL: nightly workflow must set a distinct .universal bundle ID" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! grep -Fq 'https://github.com/manaflow-ai/cmux/releases/download/nightly/appcast-universal.xml' "$WORKFLOW_FILE"; then | ||
| echo "FAIL: nightly workflow must publish a separate universal appcast feed" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! grep -Fq './scripts/sparkle_generate_appcast.sh "$NIGHTLY_UNIVERSAL_DMG_IMMUTABLE" nightly appcast-universal.xml' "$WORKFLOW_FILE"; then | ||
| echo "FAIL: nightly workflow must generate a separate universal appcast" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! grep -Fq "core.setOutput('should_publish', isMainRef ? 'true' : 'false');" "$WORKFLOW_FILE"; then | ||
| echo "FAIL: nightly decide step must expose should_publish based on whether the ref is main" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! awk ' | ||
| /^ - name: Upload branch nightly artifacts/ { in_upload=1; next } | ||
| in_upload && /^ - name:/ { in_upload=0 } | ||
| in_upload && /if: needs\.decide\.outputs\.should_publish != '\''true'\''/ { saw_if=1 } | ||
| in_upload && /uses: actions\/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4/ { saw_upload=1 } | ||
| in_upload && /cmux-nightly-macos\*\.dmg/ { saw_arm_artifacts=1 } | ||
| in_upload && /cmux-nightly-universal-macos\*\.dmg/ { saw_universal_artifacts=1 } | ||
| in_upload && /appcast-universal\.xml/ { saw_universal_appcast=1 } | ||
| END { exit !(saw_if && saw_upload && saw_arm_artifacts && saw_universal_artifacts && saw_universal_appcast) } | ||
|
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. P2: The branch-upload regression check omits Prompt for AI agents |
||
| ' "$WORKFLOW_FILE"; then | ||
| echo "FAIL: non-main nightly runs must upload both nightly variants and both appcasts" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! awk ' | ||
| /^ - name: Move nightly tag to built commit/ { in_move=1; next } | ||
| in_move && /^ - name:/ { in_move=0 } | ||
| in_move && /if: needs\.decide\.outputs\.should_publish == '\''true'\''/ { saw_move_if=1 } | ||
| END { exit !saw_move_if } | ||
| ' "$WORKFLOW_FILE"; then | ||
| echo "FAIL: moving the nightly tag must be gated to main nightly publishes" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! awk ' | ||
| /^ - name: Publish nightly release assets/ { in_publish=1; next } | ||
| in_publish && /^ - name:/ { in_publish=0 } | ||
| in_publish && /if: needs\.decide\.outputs\.should_publish == '\''true'\''/ { saw_publish_if=1 } | ||
| in_publish && /cmux-nightly-universal-macos-\$\{\{ github\.run_id \}\}\*\.dmg/ { saw_universal_immutable=1 } | ||
| in_publish && /cmux-nightly-universal-macos\.dmg/ { saw_universal_stable=1 } | ||
| in_publish && /appcast-universal\.xml/ { saw_universal_appcast=1 } | ||
| END { exit !(saw_publish_if && saw_universal_immutable && saw_universal_stable && saw_universal_appcast) } | ||
| ' "$WORKFLOW_FILE"; then | ||
| echo "FAIL: main nightly publish must include the universal assets and appcast" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "PASS: nightly workflow keeps separate Apple Silicon and universal nightly tracks" | ||
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.
Changing the GhosttyKit build to
-Dxcframework-target=universalwithout changing the artifact identity meansxcframework-${sha}can still resolve to an older single-arch release for the same SHA, because the workflow skips rebuilding when that tag already exists and downstream downloads are keyed by SHA. In that case nightly/release universal builds continue consuming a stale non-universal xcframework and can fail when x86_64 slices are required; include the target in the release key (or force a rebuild/migration) so the artifact identity matches its contents.Useful? React with 👍 / 👎.