ci: use GitHub-hosted macOS release runner (#3) #3
Workflow file for this run
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: release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| verify: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| steps: | |
| - uses: useblacksmith/checkout@v1 | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: 1.94.0 | |
| components: rustfmt, clippy | |
| - name: Verify release tag matches Cargo version | |
| shell: bash | |
| run: | | |
| version=$(sed -n 's/^version = "\([^"]*\)"/\1/p' Cargo.toml | head -1) | |
| escaped_version=${version//./\.} | |
| if [[ $GITHUB_REF_NAME != "v$version" \ | |
| && ! $GITHUB_REF_NAME =~ ^v${escaped_version}-pre(\.[0-9]+)?$ ]]; then | |
| echo "expected v${version}, v${version}-pre, or v${version}-pre.N" >&2 | |
| exit 1 | |
| fi | |
| - run: cargo fmt --check | |
| - run: cargo clippy --locked --all-targets --all-features -- -D warnings | |
| - run: cargo test --locked | |
| linux-x64: | |
| needs: verify | |
| runs-on: blacksmith-8vcpu-ubuntu-2404 | |
| steps: | |
| - uses: useblacksmith/checkout@v1 | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: 1.94.0 | |
| targets: x86_64-unknown-linux-gnu | |
| - name: Build and package | |
| shell: bash | |
| run: | | |
| version=${GITHUB_REF_NAME#v} | |
| cargo build --locked --release --target x86_64-unknown-linux-gnu | |
| mkdir -p stage dist | |
| cp target/x86_64-unknown-linux-gnu/release/kit stage/kit | |
| stage/kit --version | |
| tar -C stage -czf "dist/kit-v${version}-x86_64-unknown-linux-gnu.tar.gz" kit | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: kit-linux-x64 | |
| path: dist/* | |
| if-no-files-found: error | |
| macos-arm64: | |
| needs: verify | |
| runs-on: macos-15 | |
| outputs: | |
| signed: ${{ steps.signing.outputs.enabled }} | |
| env: | |
| MACOS_CERTIFICATE_P12_BASE64: ${{ secrets.MACOS_CERTIFICATE_P12_BASE64 }} | |
| MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} | |
| MACOS_SIGNING_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY }} | |
| APPLE_API_KEY_P8_BASE64: ${{ secrets.APPLE_API_KEY_P8_BASE64 }} | |
| APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} | |
| APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }} | |
| steps: | |
| - uses: useblacksmith/checkout@v1 | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: 1.94.0 | |
| targets: aarch64-apple-darwin | |
| - name: Check optional signing credentials | |
| id: signing | |
| shell: bash | |
| run: | | |
| credentials=( | |
| MACOS_CERTIFICATE_P12_BASE64 | |
| MACOS_CERTIFICATE_PASSWORD | |
| MACOS_SIGNING_IDENTITY | |
| APPLE_API_KEY_P8_BASE64 | |
| APPLE_API_KEY_ID | |
| APPLE_API_ISSUER_ID | |
| ) | |
| configured=0 | |
| for name in "${credentials[@]}"; do | |
| if [[ -n ${!name:-} ]]; then | |
| configured=$((configured + 1)) | |
| fi | |
| done | |
| if [[ $configured -eq 0 ]]; then | |
| echo "Apple credentials are not configured; building an unsigned macOS release." | |
| echo "enabled=false" >> "$GITHUB_OUTPUT" | |
| elif [[ $configured -eq ${#credentials[@]} ]]; then | |
| echo "enabled=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Apple signing credentials are only partially configured." >&2 | |
| exit 1 | |
| fi | |
| - name: Import Developer ID certificate | |
| if: steps.signing.outputs.enabled == 'true' | |
| shell: bash | |
| run: | | |
| keychain=$RUNNER_TEMP/kit-signing.keychain-db | |
| certificate=$RUNNER_TEMP/kit-signing.p12 | |
| printf '%s' "$MACOS_CERTIFICATE_P12_BASE64" | base64 --decode > "$certificate" | |
| security create-keychain -p "$MACOS_CERTIFICATE_PASSWORD" "$keychain" | |
| security set-keychain-settings -lut 21600 "$keychain" | |
| security unlock-keychain -p "$MACOS_CERTIFICATE_PASSWORD" "$keychain" | |
| security import "$certificate" -P "$MACOS_CERTIFICATE_PASSWORD" \ | |
| -f pkcs12 -k "$keychain" -T /usr/bin/codesign | |
| security set-key-partition-list -S apple-tool:,apple: -s \ | |
| -k "$MACOS_CERTIFICATE_PASSWORD" "$keychain" | |
| security list-keychains -d user -s "$keychain" login.keychain-db | |
| - name: Build and package | |
| shell: bash | |
| env: | |
| SIGN_RELEASE: ${{ steps.signing.outputs.enabled }} | |
| run: | | |
| version=${GITHUB_REF_NAME#v} | |
| cargo build --locked --release --target aarch64-apple-darwin | |
| mkdir -p stage dist | |
| cp target/aarch64-apple-darwin/release/kit stage/kit | |
| if [[ $SIGN_RELEASE == true ]]; then | |
| codesign --force --options runtime --timestamp \ | |
| --identifier com.danielkov.kit \ | |
| --sign "$MACOS_SIGNING_IDENTITY" stage/kit | |
| codesign --verify --strict --verbose=2 stage/kit | |
| ditto -c -k --keepParent stage/kit "$RUNNER_TEMP/kit-notarization.zip" | |
| api_key=$RUNNER_TEMP/AuthKey_${APPLE_API_KEY_ID}.p8 | |
| trap 'rm -f "$api_key"' EXIT | |
| printf '%s' "$APPLE_API_KEY_P8_BASE64" | base64 --decode > "$api_key" | |
| chmod 600 "$api_key" | |
| notary_log=$RUNNER_TEMP/kit-notarization.log | |
| xcrun notarytool submit "$RUNNER_TEMP/kit-notarization.zip" \ | |
| --key "$api_key" \ | |
| --key-id "$APPLE_API_KEY_ID" \ | |
| --issuer "$APPLE_API_ISSUER_ID" \ | |
| --wait 2>&1 | tee "$notary_log" | |
| if ! grep -Eq '(^|[[:space:]])status: Accepted([[:space:]]|$)' "$notary_log"; then | |
| echo "Apple did not accept the notarization submission." >&2 | |
| exit 1 | |
| fi | |
| fi | |
| stage/kit --version | |
| tar -C stage -czf "dist/kit-v${version}-aarch64-apple-darwin.tar.gz" kit | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: kit-macos-arm64 | |
| path: dist/* | |
| if-no-files-found: error | |
| publish: | |
| needs: [linux-x64, macos-arm64] | |
| runs-on: blacksmith-2vcpu-ubuntu-2404 | |
| permissions: | |
| contents: write | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| MACOS_SIGNED: ${{ needs.macos-arm64.outputs.signed }} | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: kit-* | |
| path: dist | |
| merge-multiple: true | |
| - name: Publish release | |
| shell: bash | |
| run: | | |
| cd dist | |
| sha256sum kit-*.tar.gz > SHA256SUMS | |
| prerelease=false | |
| if [[ $GITHUB_REF_NAME == *-pre* ]]; then | |
| prerelease=true | |
| fi | |
| if [[ $MACOS_SIGNED == true ]]; then | |
| signing_note="The macOS binary is Developer ID signed and notarized." | |
| else | |
| signing_note="The macOS binary is unsigned and not notarized." | |
| fi | |
| title="Kit ${GITHUB_REF_NAME#v}" | |
| notes="Prebuilt Kit binaries. $signing_note" | |
| if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then | |
| gh release upload "$GITHUB_REF_NAME" kit-*.tar.gz SHA256SUMS \ | |
| --clobber --repo "$GITHUB_REPOSITORY" | |
| else | |
| create_args=( | |
| "$GITHUB_REF_NAME" kit-*.tar.gz SHA256SUMS | |
| --repo "$GITHUB_REPOSITORY" | |
| --title "$title" | |
| --notes "$notes" | |
| ) | |
| if [[ $prerelease == true ]]; then | |
| create_args+=(--prerelease) | |
| fi | |
| gh release create "${create_args[@]}" | |
| fi | |
| edit_args=( | |
| "$GITHUB_REF_NAME" | |
| --repo "$GITHUB_REPOSITORY" | |
| --title "$title" | |
| --notes "$notes" | |
| --draft=false | |
| --prerelease="$prerelease" | |
| ) | |
| if [[ $prerelease == false ]]; then | |
| edit_args+=(--latest) | |
| fi | |
| gh release edit "${edit_args[@]}" |