Repository navigation
Build & Release #66
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 & Release | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| build: | |
| runs-on: macos-14 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install Rust | |
| run: | | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable | |
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | |
| source "$HOME/.cargo/env" | |
| rustup target add aarch64-apple-darwin x86_64-apple-darwin | |
| - name: Cache Rust dependencies | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| eagle-core/target | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| key: rust-${{ runner.os }}-${{ hashFiles('eagle-core/Cargo.lock') }} | |
| restore-keys: rust-${{ runner.os }}- | |
| - name: Build Rust (arm64) | |
| run: cd eagle-core && cargo build --release --target aarch64-apple-darwin | |
| - name: Build Rust (x86_64) | |
| run: cd eagle-core && cargo build --release --target x86_64-apple-darwin | |
| - name: Create universal Rust library | |
| run: | | |
| lipo -create \ | |
| eagle-core/target/aarch64-apple-darwin/release/libeagle_core.a \ | |
| eagle-core/target/x86_64-apple-darwin/release/libeagle_core.a \ | |
| -output eagle-core/target/release/libeagle_core.a | |
| - name: Compute version | |
| id: version | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| LAST_TAG=$(gh release list --limit 1 --json tagName -q '.[0].tagName' 2>/dev/null || echo "") | |
| if [[ "$LAST_TAG" =~ ^v0\.([0-9]+)\.([0-9]+)$ ]]; then | |
| MAJOR=0 | |
| MINOR="${BASH_REMATCH[1]}" | |
| PATCH="${BASH_REMATCH[2]}" | |
| PATCH=$((PATCH + 1)) | |
| else | |
| MAJOR=0 | |
| MINOR=2 | |
| PATCH=0 | |
| fi | |
| echo "version=${MAJOR}.${MINOR}.${PATCH}" >> "$GITHUB_OUTPUT" | |
| - name: Build Swift app | |
| run: | | |
| ls -d /Applications/Xcode* | sort -V | |
| XCODE_PATH=$(ls -d /Applications/Xcode* 2>/dev/null | sort -V | tail -1) | |
| sudo xcode-select -s "$XCODE_PATH" | |
| swift --version | |
| mkdir -p build/Eagle.app/Contents/MacOS | |
| mkdir -p build/Eagle.app/Contents/Resources | |
| cp Eagle/Info.plist build/Eagle.app/Contents/Info.plist | |
| /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${{ steps.version.outputs.version }}" build/Eagle.app/Contents/Info.plist | |
| cp Eagle/Resources/Eagle.icns build/Eagle.app/Contents/Resources/Eagle.icns | |
| swiftc \ | |
| -O \ | |
| -import-objc-header Eagle/BridgingHeader.h \ | |
| -L eagle-core/target/release \ | |
| -leagle_core \ | |
| -framework AppKit \ | |
| -framework SwiftUI \ | |
| -framework UniformTypeIdentifiers \ | |
| Eagle/Sources/Eagle/*.swift \ | |
| -o build/Eagle.app/Contents/MacOS/Eagle | |
| - name: Import signing certificate | |
| if: github.event_name != 'pull_request' | |
| env: | |
| DEVELOPER_P12: ${{ secrets.DEVELOPER_P12 }} | |
| DEVELOPER_P12_PASSWORD: ${{ secrets.DEVELOPER_P12_PASSWORD }} | |
| run: | | |
| KEYCHAIN_PATH=$RUNNER_TEMP/signing.keychain-db | |
| KEYCHAIN_PASSWORD=$(openssl rand -hex 16) | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| echo "$DEVELOPER_P12" | base64 --decode > $RUNNER_TEMP/developer.p12 | |
| security import $RUNNER_TEMP/developer.p12 \ | |
| -P "$DEVELOPER_P12_PASSWORD" \ | |
| -A \ | |
| -t cert \ | |
| -f pkcs12 \ | |
| -k "$KEYCHAIN_PATH" | |
| security list-keychain -d user -s "$KEYCHAIN_PATH" | |
| security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| - name: Code sign app | |
| if: github.event_name != 'pull_request' | |
| run: | | |
| IDENTITY=$(security find-identity -v -p codesigning $RUNNER_TEMP/signing.keychain-db | head -1 | grep -o '"[^"]*"' | tr -d '"') | |
| echo "Signing with identity: $IDENTITY" | |
| codesign --force --options runtime --sign "$IDENTITY" build/Eagle.app/Contents/MacOS/Eagle | |
| codesign --force --options runtime --sign "$IDENTITY" build/Eagle.app | |
| codesign --verify --deep --strict build/Eagle.app | |
| - name: Notarize app | |
| if: github.event_name != 'pull_request' | |
| env: | |
| MACOS_NOTARY_API_KEY: ${{ secrets.MACOS_NOTARY_API_KEY }} | |
| MACOS_NOTARY_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }} | |
| MACOS_NOTARY_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }} | |
| run: | | |
| echo "$MACOS_NOTARY_API_KEY" | base64 --decode > $RUNNER_TEMP/notary_key.p8 | |
| ditto -c -k --keepParent build/Eagle.app build/Eagle-notarize.zip | |
| xcrun notarytool submit build/Eagle-notarize.zip \ | |
| --key "$RUNNER_TEMP/notary_key.p8" \ | |
| --key-id "$MACOS_NOTARY_KEY_ID" \ | |
| --issuer "$MACOS_NOTARY_ISSUER_ID" \ | |
| --wait | |
| xcrun stapler staple build/Eagle.app | |
| - name: Create DMG | |
| run: | | |
| hdiutil create -volname Eagle \ | |
| -srcfolder build/Eagle.app \ | |
| -ov -format UDZO \ | |
| build/Eagle-${{ steps.version.outputs.version }}.dmg | |
| - name: Sign and notarize DMG | |
| if: github.event_name != 'pull_request' | |
| env: | |
| MACOS_NOTARY_API_KEY: ${{ secrets.MACOS_NOTARY_API_KEY }} | |
| MACOS_NOTARY_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }} | |
| MACOS_NOTARY_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }} | |
| run: | | |
| IDENTITY=$(security find-identity -v -p codesigning $RUNNER_TEMP/signing.keychain-db | head -1 | grep -o '"[^"]*"' | tr -d '"') | |
| codesign --force --sign "$IDENTITY" build/Eagle-${{ steps.version.outputs.version }}.dmg | |
| xcrun notarytool submit build/Eagle-${{ steps.version.outputs.version }}.dmg \ | |
| --key "$RUNNER_TEMP/notary_key.p8" \ | |
| --key-id "$MACOS_NOTARY_KEY_ID" \ | |
| --issuer "$MACOS_NOTARY_ISSUER_ID" \ | |
| --wait | |
| xcrun stapler staple build/Eagle-${{ steps.version.outputs.version }}.dmg | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: Eagle-${{ steps.version.outputs.version }}.dmg | |
| path: build/Eagle-${{ steps.version.outputs.version }}.dmg | |
| - name: Create release | |
| if: github.event_name != 'pull_request' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="v${{ steps.version.outputs.version }}" | |
| gh release create "$VERSION" \ | |
| --title "Eagle $VERSION" \ | |
| --notes "Automated build from $(git log -1 --pretty=%s)" \ | |
| --draft=false \ | |
| build/Eagle-${{ steps.version.outputs.version }}.dmg | |
| - name: Install kpkg | |
| if: github.event_name != 'pull_request' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release download --repo kandji-inc/kpkg --pattern '*.pkg' --dir /tmp | |
| sudo installer -pkg /tmp/*.pkg -target / | |
| - name: Deploy to Kandji | |
| if: github.event_name != 'pull_request' | |
| env: | |
| KANDJI_TOKEN: ${{ secrets.KANDJI_TOKEN }} | |
| KANDJI_API_URL: ${{ vars.KANDJI_API_URL }} | |
| run: | | |
| mkdir -p ~/Library/KandjiPackages | |
| envsubst < .github/kandji-config.json > ~/Library/KandjiPackages/config.json | |
| kpkg -p build/Eagle-${{ steps.version.outputs.version }}.dmg -n "Eagle" |