Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/nightly-step-coverage.json
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,27 @@
"Hand the stapled cmux NIGHTLY DMG to the verify job": {"pr": "ci-guards.yml:workflow-guard-tests:Validate Sparkle appcast macOS floor"},
"Record the attempt": {"plumbing": true},
"Cleanup keychain": {"nightly_only": "deletes the signing keychain"}},
"sign-nightly-identity-legacy-blacksmith": {
"Hold the whole Mac before any credential": {"pr": "ci-guards.yml:workflow-guard-tests:Validate a signing job on an owned Mac holds the whole Mac and deletes its keychain"},
"Claim the whole Mac for signing": {"pr": "ci-guards.yml:workflow-guard-tests:Validate a signing job on an owned Mac holds the whole Mac and deletes its keychain"},
"Mint the release App token for this job's gh calls": {"nightly_only": "mints release GitHub App token"},
"Send this job's gh calls as the release App, github.token as the fallback": {"pr": "ci-guards.yml:workflow-guard-tests:Validate the nightly publish jobs send gh calls as the release App first"},
"Wait through GitHub API rate limits in this job's gh calls": {"pr": "ci-guards.yml:workflow-guard-tests:Validate nightly publish-path gh calls wait through a rate limit"},
"Prepare current NEXT DMG for the parallel identity": {"nightly_only": "rewrites the prepared Release cmux.app's Info.plist for the cmux NEXT identity before Developer ID signing; needs the Release app only the nightly builds"},
"Skip a build the old feed already has": {"pr": "ci-guards.yml:workflow-guard-tests:Validate the nightly-next release-ring tags"},
"Initialize cmux-next notices submodule": {"plumbing": true},
"Parse signing and notarize scripts with /bin/bash 3.2": {"pr": "signing-keychain-macos.yml:bash32-syntax:Parse every scripts/ci shell script with bash 3.2"},
"Select Xcode": {"plumbing": true}, "Install create-dmg": {"plumbing": true},
"Download the published cmux NEXT DMG": {"plumbing": true},
"Import signing cert": {"nightly_only": "imports Developer ID signing certificate"},
"Sign the build as cmux NIGHTLY": {"nightly_only": "signs with Developer ID and profile"},
"Download the pending cmux NIGHTLY-identity submission": {"plumbing": true},
"Check out the build's own source for the bundle checks": {"plumbing": true},
"Notarize the cmux NIGHTLY DMG": {"nightly_only": "notarizes cmux NIGHTLY DMG (Apple)"},
"Keep the pending cmux NIGHTLY-identity submission": {"plumbing": true},
"Hand the stapled cmux NIGHTLY DMG to the verify job": {"pr": "ci-guards.yml:workflow-guard-tests:Validate Sparkle appcast macOS floor"},
"Record the attempt": {"plumbing": true},
"Cleanup keychain": {"nightly_only": "deletes the signing keychain"}},
"verify-nightly-identity-legacy": {
"Select Xcode": {"plumbing": true},
"Check out the build's own source for the bundle checks": {"plumbing": true},
Expand Down
4 changes: 4 additions & 0 deletions .github/runners.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"cmux-next-cua-helper-identity.yml#helper-identity": "macos-runtime-tests",
"cmux-next-daemon-macos-shadow.yml#cmux-next-daemon-macos-shadow": "macos-runtime-tests",
"cmux-next-dev-daily.yml#sign": "apple-signing-release",
"cmux-next-dev-daily.yml#sign-blacksmith": "apple-signing-release",
"cmux-next-dev-daily.yml#verify": "apple-signing-release",
"cmux-next-fast-tier-seed.yml#seed": "apple-app-build",
"cmux-next-frame-pacing.yml#bench": {
Expand Down Expand Up @@ -224,6 +225,7 @@
"nightly.yml#refresh-compilation-cache": "apple-app-build",
"nightly.yml#refresh-test-compilation-cache": "apple-app-build",
"nightly.yml#sign-nightly-identity-legacy": "apple-signing-release",
"nightly.yml#sign-nightly-identity-legacy-blacksmith": "apple-signing-release",
"nightly.yml#signer-dmg-image": "apple-signing-release",
"nightly.yml#verify-final-dmg-nightly": "apple-signing-release",
"nightly.yml#verify-nightly-identity-legacy": "apple-signing-release",
Expand All @@ -237,9 +239,11 @@
"relay-tls.yml#system-keychain": "macos-runtime-tests",
"release.yml#build-ghostty-cli-helper": "apple-app-build",
"release.yml#build-sign-notarize": "apple-signing-release",
"release.yml#build-sign-notarize-blacksmith": "apple-signing-release",
"reload-build.yml#build": "apple-app-build",
"remote-daemon.yml#remote-daemon-macos-tests": "macos-runtime-tests",
"repair-v0-64-25-helper-rpaths.yml#repair": "apple-signing-release",
"repair-v0-64-25-helper-rpaths.yml#repair-blacksmith": "apple-signing-release",
"repair-v0-64-25-helper-rpaths.yml#verify-shipped": "apple-signing-release",
"resume-nightly-notarization.yml#resume": "apple-signing-release",
"resume-nightly-notarization.yml#verify-stapled": "apple-signing-release",
Expand Down
54 changes: 40 additions & 14 deletions .github/workflows/cmux-next-dev-daily.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,15 @@ jobs:
environment: release
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'macos-26' || github.run_attempt == 1 && needs.pick-sign-runner.outputs.owned && fromJSON(needs.pick-sign-runner.outputs.owned) || github.run_attempt > 1 && needs.pick-sign-runner.outputs.alternate || needs.pick-sign-runner.outputs.runner || 'blacksmith-6vcpu-macos-26' }}
timeout-minutes: 30
permissions:
permissions: &sign-permissions
actions: read
contents: read
outputs:
outputs: &sign-outputs
# owned when the claim gate passed on an owned Mac; the Blacksmith twin signs when it did not.
claim: ${{ steps.claim-gate.outputs.claim }}
signed: ${{ steps.package.outputs.signed }}
source_sha: ${{ steps.package.outputs.source_sha }}
env:
env: &sign-env
SOURCE_RUN_ID: ${{ inputs.source_run_id }}
RELEASE_TAG: cmux-next-dev
APP_NAME: cmux NEXT DEV
Expand All @@ -118,18 +120,27 @@ jobs:
cmux NEXT DEV Release compile
cmux app scheme compile (Debug)
cmux-next Release compile (Xcode 26)
steps:
steps: &sign-steps
# First, before the checkout's token or any secret: on an owned Mac this job holds the whole
# mini (glaeda's exclusive class) or fails here (tests/test_ci_signing_owned_mac.py CLAIM_GATE).
- name: Hold the whole Mac before any credential
id: claim-gate
shell: bash
run: |
owned=""
case "${RUNNER_NAME:-}" in *-glaeda|*-glaeda-*) owned=1 ;; esac
if [ -d /Users/Shared/cmux-build-fleet ]; then owned=1; fi
if [ -n "$owned" ] && [ "${GLAEDA_JOB_CLAIM:-}" != exclusive ]; then
echo "::error title=Signing runner::This owned Mac did not give the job the whole mini; its re-run takes Blacksmith."
exit 1
if [ -n "$owned" ]; then
if [ "${GLAEDA_JOB_CLAIM:-}" != exclusive ]; then
echo "::error title=Signing runner::This owned Mac did not give the job the whole mini; this run's Blacksmith job signs instead."
exit 1
fi
case "${GLAEDA_HOOK_SHA256:-}" in
2695209c13db5fe7514daf76d3e8e547b9569ad9a545225e52f7e07dd83d69e4|41e29cd9dca8cdee88ce069b61956674bb79c2c3da90af5520e3e397bfbedeef) ;;
*) echo "::error title=Signing runner::glaeda hook ${GLAEDA_HOOK_SHA256:-unnamed} is not one scripts/ci/glaeda-signing-hooks.txt lists; this run's Blacksmith job signs instead."
exit 1 ;;
esac
echo "claim=owned" >> "$GITHUB_OUTPUT"
fi

# SOURCE_SHA is the commit the source run built: a dev daily run of
Expand Down Expand Up @@ -299,6 +310,21 @@ jobs:
|| security delete-keychain "$CMUX_NEXT_DEV_DAILY_KEYCHAIN" >/dev/null 2>&1 || true
fi

sign-blacksmith:
needs: [pick-sign-runner, sign]
# The same run signs on Blacksmith when the owned Mac took sign but its claim gate never passed
# (glaeda refused the job, or a hook scripts/ci/glaeda-signing-hooks.txt does not list admitted it).
if: "!cancelled() && github.run_attempt == 1 && needs.pick-sign-runner.outputs.owned != '' && needs.sign.result != 'skipped' && needs.sign.result != 'cancelled' && needs.sign.outputs.claim != 'owned'"
name: Sign cmux NEXT DEV on Blacksmith
environment: release
# Blacksmith only: this run's sign when the owned Mac refused the job (its claim gate).
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'macos-26' || github.run_attempt > 1 && needs.pick-sign-runner.outputs.alternate || needs.pick-sign-runner.outputs.runner || 'blacksmith-6vcpu-macos-26' }}
timeout-minutes: 30
permissions: *sign-permissions
outputs: *sign-outputs
env: *sign-env
steps: *sign-steps

# Offers verify to the owned Macs (Leo, 2026-10-24: owned Macs before
# Blacksmith). It runs e2e_runner_pool.py, test-e2e.yml's picker, as
# iroh-release-gate.yml does: an owned pool on the lane's Xcode pin while
Expand All @@ -307,8 +333,8 @@ jobs:
# skipped pick or a failure of this job leaves verify on Blacksmith. The
# routing App key stays in this Linux job; verify holds no secret.
runner:
needs: sign
if: needs.sign.outputs.signed == 'true'
needs: [sign, sign-blacksmith]
if: "!cancelled() && (needs.sign-blacksmith.result == 'skipped' && needs.sign.result || needs.sign-blacksmith.result) == 'success' && ((needs.sign-blacksmith.outputs.signed || needs.sign.outputs.signed) == 'true')"
environment: release
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || 'blacksmith-4vcpu-ubuntu-2404' }}
timeout-minutes: 5
Expand Down Expand Up @@ -423,8 +449,8 @@ jobs:
verify:
name: Verify signed cmux NEXT DEV
# No environment and no secrets: this job runs the app's diff sidecar.
needs: [sign, runner]
if: ${{ !cancelled() && needs.sign.result == 'success' && needs.sign.outputs.signed == 'true' }}
needs: [sign, runner, sign-blacksmith]
if: ${{ !cancelled() && (needs.sign-blacksmith.result == 'skipped' && needs.sign.result || needs.sign-blacksmith.result) == 'success' && (needs.sign-blacksmith.outputs.signed || needs.sign.outputs.signed) == 'true' }}
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'macos-26' || (github.run_attempt == 1 && needs.runner.outputs.label || 'blacksmith-6vcpu-macos-26') }}
timeout-minutes: 15
permissions:
Expand Down Expand Up @@ -479,8 +505,8 @@ jobs:
# nightly)." Signing and codesign verification remain the admission gate;
# the sidecar verification job runs independently and never blocks the
# cutting-edge DEV artifact.
needs: [sign]
if: needs.sign.outputs.signed == 'true'
needs: [sign, sign-blacksmith]
if: "!cancelled() && (needs.sign-blacksmith.result == 'skipped' && needs.sign.result || needs.sign-blacksmith.result) == 'success' && ((needs.sign-blacksmith.outputs.signed || needs.sign.outputs.signed) == 'true')"
# This copy's publish updates the rolling release without a lease, so its
# group still serializes it. main's copy, the one that runs, replaced the
# group with an R2 lease and a newest-wins check.
Expand All @@ -494,7 +520,7 @@ jobs:
env:
RELEASE_TAG: cmux-next-dev
APP_ARCHIVE_NAME: cmux-NEXT-DEV.zip
SOURCE_SHA: ${{ needs.sign.outputs.source_sha }}
SOURCE_SHA: ${{ (needs.sign-blacksmith.outputs.source_sha || needs.sign.outputs.source_sha) }}
steps:
- name: Download the signed app
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
Expand Down
Loading
Loading