v0.1.14 #14
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: Build Electron App | |
| on: | |
| release: | |
| types: [published] | |
| permissions: | |
| contents: write # Required to upload release assets | |
| jobs: | |
| build: | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 9 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24 | |
| cache: 'pnpm' | |
| cache-dependency-path: 'apps/x/pnpm-lock.yaml' | |
| - name: Extract version from tag | |
| id: version | |
| run: | | |
| VERSION="${GITHUB_REF#refs/tags/v}" | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "Extracted version: ${VERSION}" | |
| - name: Update package.json versions | |
| run: | | |
| node -e " | |
| const fs = require('fs'); | |
| const version = '${{ steps.version.outputs.version }}'; | |
| // Update apps/x/package.json | |
| const rootPackage = JSON.parse(fs.readFileSync('apps/x/package.json', 'utf8')); | |
| rootPackage.version = version; | |
| fs.writeFileSync('apps/x/package.json', JSON.stringify(rootPackage, null, 2) + '\n'); | |
| // Update apps/x/apps/main/package.json | |
| const mainPackage = JSON.parse(fs.readFileSync('apps/x/apps/main/package.json', 'utf8')); | |
| mainPackage.version = version; | |
| fs.writeFileSync('apps/x/apps/main/package.json', JSON.stringify(mainPackage, null, 2) + '\n'); | |
| console.log('Updated version to:', version); | |
| " | |
| - name: Import Code Signing Certificate | |
| env: | |
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| run: | | |
| # Create a temporary keychain | |
| KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db | |
| KEYCHAIN_PASSWORD=$(openssl rand -base64 32) | |
| # Create keychain | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| # Decode and import certificate | |
| echo "$APPLE_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/certificate.p12 | |
| security import $RUNNER_TEMP/certificate.p12 -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" | |
| # Allow codesign to access the keychain | |
| security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| # Add keychain to search list | |
| security list-keychain -d user -s "$KEYCHAIN_PATH" login.keychain | |
| # Verify certificate was imported | |
| security find-identity -v "$KEYCHAIN_PATH" | |
| # Clean up certificate file | |
| rm -f $RUNNER_TEMP/certificate.p12 | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| working-directory: apps/x | |
| - name: Build and publish to S3 | |
| env: | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| run: npm run publish | |
| working-directory: apps/x/apps/main | |
| - name: Diagnose built app | |
| run: | | |
| echo "=== Architecture Check ===" | |
| APP_PATH=$(find apps/x/apps/main/out -name "Rowboat.app" -type d | head -1) | |
| if [ -n "$APP_PATH" ]; then | |
| EXECUTABLE="$APP_PATH/Contents/MacOS/rowboat" | |
| if [ -f "$EXECUTABLE" ]; then | |
| echo "App executable found at: $EXECUTABLE" | |
| echo "Architecture:" | |
| lipo -info "$EXECUTABLE" || file "$EXECUTABLE" | |
| echo "" | |
| echo "=== Code Signing Check ===" | |
| codesign --verify --deep --strict --verbose=2 "$APP_PATH" || echo "App is not signed (this is OK if code signing secrets are not configured)" | |
| echo "" | |
| echo "=== _CodeSignature Check ===" | |
| if [ -d "$APP_PATH/Contents/_CodeSignature" ]; then | |
| echo "WARNING: _CodeSignature directory still exists!" | |
| ls -la "$APP_PATH/Contents/_CodeSignature" || true | |
| else | |
| echo "✓ No _CodeSignature directory (expected for unsigned app)" | |
| fi | |
| echo "" | |
| echo "=== Extended Attributes Check ===" | |
| xattr -l "$APP_PATH" | head -5 || echo "No extended attributes (or not on macOS)" | |
| echo "" | |
| echo "=== Gatekeeper Check ===" | |
| spctl --assess --type execute --verbose "$APP_PATH" || echo "Gatekeeper assessment failed (expected for unsigned apps)" | |
| else | |
| echo "Executable not found at: $EXECUTABLE" | |
| fi | |
| else | |
| echo "App bundle not found" | |
| fi | |
| continue-on-error: true | |
| - name: Upload workflow artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: distributables | |
| path: apps/x/apps/main/out/make/* | |
| retention-days: 30 | |
| - name: Attach files to GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: apps/x/apps/main/out/make/* | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Cleanup keychain | |
| if: always() | |
| run: | | |
| KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db | |
| if [ -f "$KEYCHAIN_PATH" ]; then | |
| security delete-keychain "$KEYCHAIN_PATH" || true | |
| fi |