Bump notarization deadline to 2 hours #13
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: | |
| - "release-[0-9]+.[0-9]+.[0-9]+*" | |
| permissions: | |
| contents: write | |
| jobs: | |
| build-cli: | |
| strategy: | |
| matrix: | |
| include: | |
| - target: aarch64-apple-darwin | |
| os: macos-latest | |
| artifact: ralph-macos-arm64 | |
| - target: x86_64-apple-darwin | |
| os: macos-latest | |
| artifact: ralph-macos-x86_64 | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-latest | |
| artifact: ralph-windows-x86_64 | |
| - target: aarch64-pc-windows-msvc | |
| os: windows-latest | |
| artifact: ralph-windows-arm64 | |
| - target: x86_64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| artifact: ralph-linux-x86_64 | |
| - target: aarch64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| artifact: ralph-linux-arm64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install cross-compilation tools (Linux ARM64) | |
| if: matrix.target == 'aarch64-unknown-linux-gnu' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gcc-aarch64-linux-gnu | |
| echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV | |
| - name: Build | |
| run: cargo build --release --target ${{ matrix.target }} -p ralph-cli | |
| - name: Prepare artifact (Unix) | |
| if: runner.os != 'Windows' | |
| run: | | |
| cp target/${{ matrix.target }}/release/ralph ${{ matrix.artifact }} | |
| chmod +x ${{ matrix.artifact }} | |
| - name: Prepare artifact (Windows) | |
| if: runner.os == 'Windows' | |
| run: cp target/${{ matrix.target }}/release/ralph.exe ${{ matrix.artifact }}.exe | |
| - name: Sign and notarize (macOS) | |
| if: runner.os == 'macOS' | |
| env: | |
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | |
| APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} | |
| APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} | |
| APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }} | |
| ARTIFACT: ${{ matrix.artifact }} | |
| run: | | |
| set -euo pipefail | |
| # Create a temporary keychain and import the signing certificate | |
| KEYCHAIN_PATH="$RUNNER_TEMP/signing.keychain-db" | |
| KEYCHAIN_PASSWORD=$(uuidgen) | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| CERT_PATH="$RUNNER_TEMP/cert.p12" | |
| echo "$APPLE_CERTIFICATE" | base64 --decode > "$CERT_PATH" | |
| security import "$CERT_PATH" -k "$KEYCHAIN_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"') | |
| # Sign the binary with hardened runtime and a secure timestamp | |
| codesign --force --options runtime --timestamp \ | |
| --sign "$APPLE_SIGNING_IDENTITY" "$ARTIFACT" | |
| codesign --verify --verbose "$ARTIFACT" | |
| # Notarize: zip the binary and submit to the notary service. | |
| # Bare binaries can't be stapled, so Gatekeeper does an online check | |
| # on first run instead. | |
| export APPLE_API_KEY_PATH="$RUNNER_TEMP/AuthKey.p8" | |
| echo "$APPLE_API_KEY_BASE64" | base64 --decode > "$APPLE_API_KEY_PATH" | |
| ZIP_PATH="$RUNNER_TEMP/$ARTIFACT.zip" | |
| /usr/bin/ditto -c -k --keepParent "$ARTIFACT" "$ZIP_PATH" | |
| ./scripts/notarize.sh "$ZIP_PATH" | |
| # Cleanup | |
| security delete-keychain "$KEYCHAIN_PATH" | |
| rm -f "$CERT_PATH" "$APPLE_API_KEY_PATH" "$ZIP_PATH" | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: ${{ matrix.artifact }}${{ runner.os == 'Windows' && '.exe' || '' }} | |
| build-desktop: | |
| strategy: | |
| matrix: | |
| include: | |
| - os: macos-latest | |
| target: aarch64-apple-darwin | |
| artifact: ralph-desktop-macos-arm64 | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| artifact: ralph-desktop-windows-x86_64 | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| artifact: ralph-desktop-linux-x86_64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - name: Install frontend dependencies | |
| run: npm ci | |
| - name: Install Linux dependencies | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf | |
| - name: Build Tauri app | |
| id: tauri | |
| uses: tauri-apps/tauri-action@v0 | |
| env: | |
| # Signing only — notarization is done manually in the next step | |
| # because Tauri's built-in notarization uses `notarytool --wait` | |
| # which hangs on transient network errors in CI. | |
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | |
| KEYCHAIN_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| with: | |
| args: --target ${{ matrix.target }} | |
| includeUpdaterJson: false | |
| - name: Notarize and staple DMG (macOS) | |
| if: runner.os == 'macOS' | |
| env: | |
| APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} | |
| APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} | |
| APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }} | |
| run: | | |
| set -euo pipefail | |
| export APPLE_API_KEY_PATH="$RUNNER_TEMP/AuthKey.p8" | |
| echo "$APPLE_API_KEY_BASE64" | base64 --decode > "$APPLE_API_KEY_PATH" | |
| DMG=$(ls target/${{ matrix.target }}/release/bundle/dmg/*.dmg | head -n1) | |
| echo "Notarizing $DMG" | |
| ./scripts/notarize.sh "$DMG" | |
| xcrun stapler staple "$DMG" | |
| xcrun stapler validate "$DMG" | |
| rm -f "$APPLE_API_KEY_PATH" | |
| - name: Upload desktop artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: | | |
| target/${{ matrix.target }}/release/bundle/dmg/*.dmg | |
| target/${{ matrix.target }}/release/bundle/nsis/*.exe | |
| target/${{ matrix.target }}/release/bundle/msi/*.msi | |
| target/${{ matrix.target }}/release/bundle/deb/*.deb | |
| target/${{ matrix.target }}/release/bundle/appimage/*.AppImage | |
| release: | |
| needs: [build-cli, build-desktop] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Extract version from tag | |
| id: version | |
| run: echo "version=${GITHUB_REF_NAME#release-}" >> $GITHUB_OUTPUT | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| name: v${{ steps.version.outputs.version }} | |
| generate_release_notes: true | |
| body: | | |
| ## macOS notes | |
| The desktop app (`.dmg`) and CLI binaries are signed and notarized | |
| with a Developer ID. macOS will check Apple's notary service | |
| online on first launch — no manual `xattr` workaround needed. | |
| files: artifacts/**/* |