Skip to content

Add auto-start, fix resource bundle loading, and improve CI #26

Add auto-start, fix resource bundle loading, and improve CI

Add auto-start, fix resource bundle loading, and improve CI #26

Workflow file for this run

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