Add auto-start, fix resource bundle loading, and improve CI #26
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] | |
| tags: ["v*"] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| build-and-test: | |
| name: Build & Test | |
| runs-on: m4-max | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build | |
| run: swift build | |
| - name: Test | |
| run: swift test | |
| release: | |
| name: Release (${{ matrix.arch }}) | |
| needs: build-and-test | |
| if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') | |
| runs-on: m4-max | |
| permissions: | |
| contents: write | |
| strategy: | |
| matrix: | |
| include: | |
| - arch: arm64 | |
| swift_arch: arm64 | |
| dmg_suffix: apple-silicon | |
| - arch: x86_64 | |
| swift_arch: x86_64 | |
| dmg_suffix: intel | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build release binary | |
| run: swift build -c release --arch ${{ matrix.swift_arch }} | |
| - name: Create app bundle | |
| env: | |
| REF_NAME: ${{ github.ref_name }} | |
| run: | | |
| APP_DIR="ErrandDesktop.app/Contents/MacOS" | |
| mkdir -p "$APP_DIR" | |
| cp .build/release/ErrandDesktop "$APP_DIR/" | |
| TAG="$REF_NAME" | |
| VERSION="${TAG#v}" | |
| if [[ ! "$TAG" =~ ^v ]]; then | |
| VERSION="0.0.0" | |
| fi | |
| cat > "ErrandDesktop.app/Contents/Info.plist" <<PLIST | |
| <?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>CFBundleExecutable</key> | |
| <string>ErrandDesktop</string> | |
| <key>CFBundleIdentifier</key> | |
| <string>sh.errand.desktop</string> | |
| <key>CFBundleName</key> | |
| <string>ErrandDesktop</string> | |
| <key>CFBundleVersion</key> | |
| <string>${VERSION}</string> | |
| <key>CFBundleShortVersionString</key> | |
| <string>${VERSION}</string> | |
| <key>LSMinimumSystemVersion</key> | |
| <string>26.0</string> | |
| <key>LSUIElement</key> | |
| <true/> | |
| </dict> | |
| </plist> | |
| PLIST | |
| cp ErrandDesktop.entitlements "ErrandDesktop.app/Contents/" | |
| # Create the resource bundle with app resources (icons, images). | |
| # SPM resources are excluded from the target; we manage the bundle ourselves | |
| # so Bundle.module works correctly in both flat builds and .app bundles. | |
| RESOURCES_DIR="ErrandDesktop.app/Contents/Resources" | |
| BUNDLE_DIR="$RESOURCES_DIR/ErrandDesktop_ErrandDesktop.bundle" | |
| mkdir -p "$BUNDLE_DIR" | |
| cp Sources/ErrandDesktop/Resources/*.png "$BUNDLE_DIR/" | |
| cp Sources/ErrandDesktop/Resources/AppIcon.icns "$RESOURCES_DIR/" | |
| - name: Import signing certificate | |
| env: | |
| CERTIFICATE_P12: ${{ secrets.CERTIFICATE_P12 }} | |
| CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_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" | |
| # Import Apple WWDR intermediate cert for trust chain | |
| curl -sL https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer -o "$RUNNER_TEMP/DeveloperIDG2CA.cer" | |
| security import "$RUNNER_TEMP/DeveloperIDG2CA.cer" -k "$KEYCHAIN_PATH" -T /usr/bin/codesign | |
| echo "$CERTIFICATE_P12" | base64 --decode > "$RUNNER_TEMP/certificate.p12" | |
| security import "$RUNNER_TEMP/certificate.p12" \ | |
| -P "$CERTIFICATE_PASSWORD" \ | |
| -A \ | |
| -t cert \ | |
| -f pkcs12 \ | |
| -k "$KEYCHAIN_PATH" | |
| # Allow codesign to access the keychain (fixes errSecInternalComponent) | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security list-keychain -d user -s "$KEYCHAIN_PATH" | |
| - name: Sign app bundle | |
| run: | | |
| codesign --deep --force --verify --verbose \ | |
| --sign "Developer ID Application" \ | |
| --options runtime \ | |
| --entitlements ErrandDesktop.entitlements \ | |
| "ErrandDesktop.app" | |
| - name: Create DMG | |
| env: | |
| DMG_SUFFIX: ${{ matrix.dmg_suffix }} | |
| run: | | |
| chmod +x scripts/create-dmg.sh | |
| scripts/create-dmg.sh ErrandDesktop.app "ErrandDesktop-${DMG_SUFFIX}.dmg" | |
| - name: Sign DMG | |
| env: | |
| DMG_SUFFIX: ${{ matrix.dmg_suffix }} | |
| run: | | |
| codesign --force --verify --verbose \ | |
| --sign "Developer ID Application" \ | |
| "ErrandDesktop-${DMG_SUFFIX}.dmg" | |
| - name: Notarize | |
| env: | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} | |
| TEAM_ID: ${{ secrets.TEAM_ID }} | |
| DMG_SUFFIX: ${{ matrix.dmg_suffix }} | |
| run: | | |
| xcrun notarytool submit "ErrandDesktop-${DMG_SUFFIX}.dmg" \ | |
| --apple-id "$APPLE_ID" \ | |
| --password "$APPLE_PASSWORD" \ | |
| --team-id "$TEAM_ID" \ | |
| --wait | |
| xcrun stapler staple "ErrandDesktop-${DMG_SUFFIX}.dmg" | |
| - name: Upload DMG artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ErrandDesktop-${{ matrix.dmg_suffix }}.dmg | |
| path: "ErrandDesktop-${{ matrix.dmg_suffix }}.dmg" | |
| - name: Create GitHub Release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: "ErrandDesktop-${{ matrix.dmg_suffix }}.dmg" | |
| generate_release_notes: true |