Skip to content

perf(release): reuse CI's GhosttyKit cache and build arm64-only#117

Merged
arzafran merged 1 commit into
mainfrom
perf/release-cache-xcframework-arm64
Jul 9, 2026
Merged

perf(release): reuse CI's GhosttyKit cache and build arm64-only#117
arzafran merged 1 commit into
mainfrom
perf/release-cache-xcframework-arm64

Conversation

@arzafran

@arzafran arzafran commented Jul 9, 2026

Copy link
Copy Markdown
Member

What this does

Ships get faster. Every push to main currently takes ~45 min to build and publish, and the biggest chunk of that (~14 min) is rebuilding the Ghostty framework from source on every single ship — for no reason. This makes the release reuse the framework CI already built, and drops Intel Mac builds since we're Apple Silicon only now.

Rough effect: the auto-ship lane goes from ~45 min to ~15-18 min, and the release job itself from ~25 min to ~8-9 min.

Why the framework was rebuilding every time

The prebuilt-framework release has never once published. build-ghosttykit.yml uploads to the ghostty fork using a token that resolves empty, and when it's empty the upload step just silently exits 0 and reports success. So there are zero releases on the fork despite 175+ green runs, the pinned checksums point at nothing, and download-prebuilt-ghosttykit.sh 404s and source-builds every time.

Rather than chase the missing token (needs repo-admin), this sidesteps it: CI already caches the built framework keyed by ghostty SHA, and the release runs on the exact same commit right after CI. So the release just restores that cache. Cache miss falls back to today's behavior, so nothing new can break.

Summary

  • release.yml: add an actions/cache step for GhosttyKit.xcframework keyed identically to CI (ghosttykit-v2-<hash>); the download/source-build step now only runs on a cache miss.
  • release.yml: build the Release app ARCHS="arm64" (was arm64 x86_64); the arch-verify step now asserts single-arch arm64.
  • build-ghosttykit.yml + ensure-ghosttykit.sh: -Dxcframework-target=native (arm64-only) instead of universal.
  • ensure-ghosttykit.sh: the Xcode-26 ranlib-refresh workaround now matches whichever macos slice exists (macos-arm64 or macos-arm64_x86_64) so it keeps running on the arm64 path.
  • test_ci_universal_release_settings.sh: inverted to assert arm64-only (also swapped a stale setup.sh check to ensure-ghosttykit.sh, the file that actually carries the flag — that check was silently passing on nothing before).
  • Remote-daemon server binaries (linux/amd64 etc.) are untouched — those aren't the Mac app.

What's intentionally not here

  • Single notarization — saves ~90s but the app inside the DMG loses its offline-stapled Gatekeeper ticket. Not worth it against the cache win.
  • Parallelizing the build with CI — after the cache fix the release job is already short; the cross-workflow artifact hand-off is complexity we don't need.

Follow-up (not this PR)

The dead prebuilt-publish pipeline is still there, now bypassed. Two ways to resolve it later: add the GHOSTTY_RELEASE_TOKEN secret and make the upload fail loudly instead of lying, or delete build-ghosttykit.yml + the hand-maintained checksums entirely and go cache-only.

Test Plan

  • ruby -ryaml loads both workflow files
  • bash -n on the touched scripts
  • tests/test_ci_universal_release_settings.sh passes
  • no stale arm64 x86_64 / xcframework-target=universal refs remain
  • first green-CI auto-ship on main shows the release job restoring the cache (cache hit) instead of source-building

The auto-ship lane rebuilt GhosttyKit from source on every ship (~14 min)
because the prebuilt xcframework release has never actually published — the
cross-repo upload silently exits 0 when its token is empty, so there are zero
releases on the ghostty fork despite the pinned checksums.

Instead of depending on that broken pipeline, release.yml now restores the same
xcframework cache CI already builds (same ghostty-SHA key, same commit via
workflow_run), and only falls back to the download/source-build on a cache miss.

Also drop the Intel slice: the shipped Mac app and the GhosttyKit build are now
arm64-only (native), halving the compile when it does run. Remote-daemon server
binaries stay cross-platform. The ranlib-refresh workaround now matches whichever
macos slice exists so it keeps running on the arm64 path.
@arzafran arzafran merged commit b27ca0c into main Jul 9, 2026
8 checks passed
@arzafran arzafran deleted the perf/release-cache-xcframework-arm64 branch July 9, 2026 21:54
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