Switch CI from self-hosted runners to GitHub-hosted macos-26 #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| on: | |
| push: | |
| branches: | |
| - main | |
| concurrency: | |
| group: build-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| runs-on: macos-26 | |
| permissions: | |
| contents: read | |
| env: | |
| MISE_HTTP_TIMEOUT: 120 | |
| MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| DEVELOPER_ID_CERT_P12: ${{ secrets.DEVELOPER_ID_CERT_P12 }} | |
| DEVELOPER_ID_CERT_PASSWORD: ${{ secrets.DEVELOPER_ID_CERT_PASSWORD }} | |
| DEVELOPER_ID_IDENTITY: ${{ secrets.DEVELOPER_ID_IDENTITY }} | |
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| submodules: recursive | |
| - name: Mise cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.local/share/mise | |
| ~/.cache/mise | |
| key: ${{ runner.os }}-${{ runner.arch }}-mise-v0-${{ hashFiles('**/mise.toml', '**/.mise.toml', '**/.tool-versions', '**/.config/mise.toml', '**/mise/config.toml', '**/mise.lock', '**/.mise.lock', '**/mise/config.lock', '**/.config/mise.lock', '**/mise.*.toml', '**/.mise.*.toml', '**/.config/mise.*.toml', '**/mise.*.lock', '**/.mise.*.lock', '**/.config/mise.*.lock') }} | |
| - run: brew install mise 2>/dev/null | |
| - run: mise install | |
| - name: Ghostty cache key | |
| run: | | |
| set -euo pipefail | |
| GHOSTTY_SHA=$(git -C ThirdParty/ghostty rev-parse HEAD) | |
| printf '%s\n' "GHOSTTY_SHA=$GHOSTTY_SHA" >> "$GITHUB_ENV" | |
| - name: Setup keychain | |
| run: | | |
| echo "$DEVELOPER_ID_CERT_P12" | base64 --decode > build-cert.p12 | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain | |
| security set-keychain-settings -t 3600 -u build.keychain | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain | |
| security import build-cert.p12 -k build.keychain -P "$DEVELOPER_ID_CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/xcodebuild | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain | |
| security list-keychains -d user -s build.keychain $(security list-keychains -d user | tr -d '"') | |
| security default-keychain -s build.keychain | |
| security find-identity -v -p codesigning build.keychain | |
| DEVELOPER_ID_IDENTITY_SHA=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application" | head -1 | awk '{print $2}') | |
| if [ -z "$DEVELOPER_ID_IDENTITY_SHA" ]; then | |
| echo "::error::Developer ID Application identity not found in keychain" | |
| exit 1 | |
| fi | |
| echo "DEVELOPER_ID_IDENTITY_SHA=$DEVELOPER_ID_IDENTITY_SHA" >> "$GITHUB_ENV" | |
| - name: Ghostty cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| Frameworks/GhosttyKit.xcframework | |
| Resources/ghostty | |
| Resources/terminfo | |
| key: ${{ runner.os }}-${{ runner.arch }}-ghostty-${{ env.GHOSTTY_SHA }} | |
| - name: Build ghostty | |
| run: | | |
| set -euo pipefail | |
| make build-ghostty-xcframework | |
| - name: Archive Xcode project | |
| run: | | |
| set -o pipefail | |
| xcodebuild -project supacode.xcodeproj -scheme supacode -configuration Release -archivePath build/supacode.xcarchive archive CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM="${{ secrets.APPLE_TEAM_ID }}" CODE_SIGN_IDENTITY="$DEVELOPER_ID_IDENTITY_SHA" OTHER_CODE_SIGN_FLAGS="--timestamp" -skipMacroValidation 2>&1 | mise exec -- xcsift -qw --format toon | |
| - name: Export archive | |
| run: | | |
| cat > build/ExportOptions.plist <<EOF | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| <plist version="1.0"> | |
| <dict> | |
| <key>method</key> | |
| <string>developer-id</string> | |
| <key>signingStyle</key> | |
| <string>manual</string> | |
| <key>signingCertificate</key> | |
| <string>$DEVELOPER_ID_IDENTITY</string> | |
| <key>teamID</key> | |
| <string>${{ secrets.APPLE_TEAM_ID }}</string> | |
| </dict> | |
| </plist> | |
| EOF | |
| set -o pipefail | |
| xcodebuild -exportArchive -archivePath build/supacode.xcarchive -exportPath build/export -exportOptionsPlist build/ExportOptions.plist 2>&1 | mise exec -- xcsift -qw --format toon | |
| - name: Re-sign frameworks | |
| run: | | |
| set -ex | |
| APP_PATH="$(find build/export -name "supacode.app" -maxdepth 3 -print -quit)" | |
| SPARKLE="$APP_PATH/Contents/Frameworks/Sparkle.framework/Versions/B" | |
| codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SPARKLE/XPCServices/Installer.xpc" | |
| codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp --preserve-metadata=entitlements -v "$SPARKLE/XPCServices/Downloader.xpc" | |
| codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SPARKLE/Updater.app" | |
| codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SPARKLE/Autoupdate" | |
| codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SPARKLE/Sparkle" | |
| codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$APP_PATH/Contents/Frameworks/Sparkle.framework" | |
| SENTRY_FRAMEWORK="$APP_PATH/Contents/Frameworks/Sentry.framework" | |
| codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SENTRY_FRAMEWORK/Versions/A/Sentry" | |
| codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SENTRY_FRAMEWORK" | |
| codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$APP_PATH" | |
| codesign -vvv --deep --strict "$APP_PATH" | |
| - name: Build DMG | |
| run: | | |
| APP_PATH="$(find build/export -name "supacode.app" -maxdepth 3 -print -quit)" | |
| mise exec -- create-dmg "$APP_PATH" build/ \ | |
| --overwrite \ | |
| --dmg-title="Supacode" \ | |
| --identity="$DEVELOPER_ID_IDENTITY_SHA" | |
| DMG_OUTPUT=$(find build -name "*.dmg" -maxdepth 1 | head -1) | |
| if [ "$DMG_OUTPUT" != "build/supacode.dmg" ]; then | |
| mv "$DMG_OUTPUT" build/supacode.dmg | |
| fi | |
| - uses: actions/upload-artifact@v6 | |
| with: | |
| name: supacode-${{ github.sha }} | |
| path: build/supacode.dmg |