feat(macOS): sign and notarize app #493
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: pipeline | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - "v*" | |
| pull_request: | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Install | |
| env: | |
| PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true" | |
| PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" | |
| run: yarn --immutable | |
| - name: Lint | |
| run: yarn lint:all | |
| format: | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Install | |
| env: | |
| PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true" | |
| PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" | |
| run: yarn --immutable --mode=skip-build | |
| - name: Format | |
| run: yarn fmt:check | |
| test: | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Install | |
| env: | |
| PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true" | |
| PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" | |
| run: yarn --immutable | |
| - name: Test | |
| run: yarn test --coverage | |
| env: | |
| CI: true | |
| - name: Publish Coverage | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| test-types: | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Install | |
| env: | |
| PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true" | |
| PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" | |
| run: yarn --immutable | |
| - name: Test types | |
| run: yarn test:types | |
| env: | |
| CI: true | |
| storybook: | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Install | |
| env: | |
| PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true" | |
| PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" | |
| run: yarn --immutable | |
| - name: Build | |
| run: yarn build:storybook | |
| - name: Store storybook | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: storybook-static | |
| retention-days: 1 | |
| if-no-files-found: error | |
| path: storybook-static | |
| compile: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| max-parallel: 3 | |
| matrix: | |
| os: [macos-latest, ubuntu-22.04, windows-latest] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Setup Python 3.9 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.9" | |
| - name: Install required python deps | |
| run: python3 -m pip install setuptools | |
| - name: Install | |
| env: | |
| PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true" | |
| PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" | |
| run: yarn --immutable | |
| - name: Install build deps (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update && sudo apt-get install -y libudev-dev | |
| - name: Build | |
| run: yarn compile:production | |
| env: | |
| GITHUB_PR_BUILDS_KEY: ${{ secrets.PR_BUILDS_TOKEN }} | |
| - name: Store compiled source | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: compiled-${{ matrix.os }} | |
| retention-days: 1 | |
| if-no-files-found: error | |
| path: build | |
| build-and-test-app: | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| DISPLAY: :0 | |
| strategy: | |
| fail-fast: false | |
| max-parallel: 3 | |
| matrix: | |
| os: [macos-latest, ubuntu-22.04, windows-latest] | |
| needs: compile | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Install | |
| env: | |
| PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true" | |
| PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "true" | |
| run: yarn --immutable | |
| - name: Fetch compiled source | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: compiled-${{ matrix.os }} | |
| path: build | |
| - name: Setup Code Signing (macOS) | |
| if: runner.os == 'macOS' && github.event_name != 'pull_request' | |
| run: | | |
| # Code signing | |
| echo 'CSC_LINK=${{ secrets.APPLE_CERT }}' >> $GITHUB_ENV | |
| echo 'CSC_KEY_PASSWORD=${{ secrets.APPLE_CERT_PASSWORD }}' >> $GITHUB_ENV | |
| # Notarization | |
| mkdir -p ~/private_keys/ | |
| echo '${{ secrets.APPLE_API_KEY }}' > ~/private_keys/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8 | |
| echo 'APPLE_API_KEY=~/private_keys/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8' >> $GITHUB_ENV | |
| echo 'APPLE_API_KEY_ID=${{ secrets.APPLE_API_KEY_ID }}' >> $GITHUB_ENV | |
| echo 'APPLE_API_ISSUER=${{ secrets.APPLE_API_ISSUER_ID }}' >> $GITHUB_ENV | |
| - name: Build | |
| run: yarn run pack | |
| - name: Upload build | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-builds-${{ matrix.os }} | |
| retention-days: 15 | |
| if-no-files-found: error | |
| path: | | |
| dist/*.snap | |
| dist/*.AppImage | |
| dist/*.msi | |
| dist/*.dmg | |
| dist/latest-mac.yml | |
| dist/latest-linux.yml | |
| - run: yarn playwright install --with-deps chromium chromium | |
| - name: Setup xvfb (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| # start xvfb in the background | |
| sudo /usr/bin/Xvfb $DISPLAY -screen 0 1280x1024x24 & | |
| - name: Run tests | |
| run: yarn e2e:app | |
| env: | |
| CI: "true" | |
| PWTEST_VIDEO: "true" | |
| HEADFUL: "true" | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Upload test results | |
| uses: actions/upload-artifact@v4 | |
| if: ${{ failure() }} | |
| with: | |
| name: electron-${{ matrix.os }}-test-results | |
| path: playwright-report | |
| - name: Upload video recordings | |
| uses: actions/upload-artifact@v4 | |
| if: ${{ failure() }} | |
| with: | |
| name: electron-${{ matrix.os }}-recordings | |
| path: e2e-recordings | |
| e2e-web: | |
| needs: compile | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Install | |
| env: | |
| PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true" | |
| PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 | |
| run: yarn --immutable --mode=skip-build | |
| - name: Install browsers | |
| run: yarn playwright install --with-deps | |
| - name: Fetch compiled source | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: compiled-ubuntu-22.04 | |
| path: build | |
| - name: Run tests | |
| run: yarn e2e:web | |
| env: | |
| CI: "true" | |
| PWTEST_VIDEO: "true" | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: actions/upload-artifact@v4 | |
| if: ${{ failure() }} | |
| with: | |
| name: video-web-linux-test-results | |
| path: playwright-report | |
| preview-web: | |
| needs: [compile, storybook] | |
| # Only run for PRs from branches within the same repository, not forks | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: read | |
| deployments: write | |
| pull-requests: write | |
| steps: | |
| - if: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target'}} | |
| name: Checkout PR | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| - if: ${{ github.event_name == 'push' }} | |
| name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Fetch compiled source | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: compiled-ubuntu-22.04 | |
| path: build | |
| - name: Fetch storybook build | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: storybook-static | |
| path: build/renderer/storybook | |
| - name: Deploy preview | |
| id: cloudflare-preview | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| command: pages deploy build/renderer --project-name=buddy | |
| gitHubToken: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Find preview comment if present | |
| uses: peter-evans/find-comment@v3 | |
| id: find-preview-comment | |
| with: | |
| issue-number: ${{ github.event.pull_request.number }} | |
| comment-author: "github-actions[bot]" | |
| body-includes: Buddy has been automatically deployed to Cloudflare | |
| - name: Create or update preview URL comment | |
| uses: peter-evans/create-or-update-comment@v4 | |
| with: | |
| comment-id: ${{ steps.find-preview-comment.outputs.comment-id }} | |
| issue-number: ${{ github.event.pull_request.number }} | |
| body: | | |
| EdgeTX Buddy has been automatically deployed to Cloudflare. | |
| ✅ Preview: ${{ steps.cloudflare-preview.outputs.deployment-url }} | |
| ✅ Storybook: ${{ steps.cloudflare-preview.outputs.deployment-url }}/storybook | |
| edit-mode: replace | |
| release-web-prod: | |
| needs: [e2e-web, test, storybook] | |
| runs-on: ubuntu-22.04 | |
| if: github.event_name != 'pull_request' | |
| permissions: | |
| contents: read | |
| deployments: write | |
| steps: | |
| - name: Fetch compiled source | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: compiled-ubuntu-22.04 | |
| path: build | |
| - name: Publish | |
| id: cloudflare-publish | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| command: pages deploy build/renderer --project-name=buddy | |
| gitHubToken: ${{ secrets.GITHUB_TOKEN }} | |
| release-app: | |
| needs: [build-and-test-app, test] | |
| runs-on: ubuntu-22.04 | |
| if: github.event_name != 'pull_request' | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Fetch binaries | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: app-builds-* | |
| path: app-builds | |
| merge-multiple: true | |
| - name: Delete previous latest release | |
| if: startsWith(github.ref, 'refs/tags/v') != true | |
| run: | | |
| # Check if 'latest' release exists and delete it if it does | |
| if gh release view latest --repo ${{ github.repository }} &>/dev/null; then | |
| echo "Deleting previous 'latest' release" | |
| gh release delete latest --yes --repo ${{ github.repository }} | |
| else | |
| echo "No previous 'latest' release found" | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Update latest tag | |
| run: | | |
| git config --global user.name "GitHub Actions" | |
| git config --global user.email "[email protected]" | |
| # Delete the tag locally and remotely if it exists | |
| git tag -d latest 2>/dev/null || true | |
| git push origin :refs/tags/latest 2>/dev/null || true | |
| # Create new tag pointing to current commit | |
| git tag -a latest -m "Latest build" | |
| git push origin latest --force | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Release latest build | |
| if: startsWith(github.ref, 'refs/tags/v') != true | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| name: "Latest Build" | |
| files: | | |
| app-builds/*.snap | |
| app-builds/*.dmg | |
| app-builds/*.msi | |
| app-builds/*.AppImage | |
| prerelease: true | |
| tag_name: latest | |
| - name: Release tagged build | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| name: "Release Build" | |
| files: | | |
| app-builds/*.snap | |
| app-builds/*.dmg | |
| app-builds/*.msi | |
| app-builds/*.AppImage | |
| draft: true |