Merge pull request #26 from beautyfree/release-please--branches--main… #26
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: Release | |
| # Two triggers that cover the two ways a release lands here: | |
| # | |
| # 1. `release: [created]` — fires when release-please creates the draft | |
| # release after its PR is merged. This is the normal path. Draft | |
| # releases don't create a git tag until they're published, so tag | |
| # push alone wouldn't fire (see commit 4032f11 for the draft switch). | |
| # | |
| # 2. `push: tags: v*` — fallback for when a maintainer hand-creates a | |
| # tag locally (e.g. to rebuild a release whose assets got corrupted). | |
| # Also covers anyone using a PAT-based release-please flow where the | |
| # tag push genuinely does trigger workflows. | |
| # | |
| # Both paths resolve the tag/release via TAG_NAME below so the downstream | |
| # softprops/gh-release steps don't care which trigger fired. | |
| on: | |
| release: | |
| types: [created] | |
| push: | |
| tags: | |
| - "v*" | |
| permissions: | |
| contents: write | |
| concurrency: | |
| # Deduplicate by tag so the `release: created` + late `push: tags` never | |
| # run simultaneously for the same version. | |
| group: ${{ github.workflow }}-${{ github.event.release.tag_name || github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| build-desktop: | |
| name: Build ${{ matrix.label }} | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - label: macos | |
| runner: macos-14 | |
| script: dist:mac | |
| - label: windows-x64 | |
| runner: windows-latest | |
| script: dist:win | |
| - label: linux-x64 | |
| runner: ubuntu-latest | |
| script: dist:linux | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| # On `release: created` for a draft, there's no git tag yet — use | |
| # the release's target commit sha. On tag push, github.ref resolves | |
| # to the tag itself (checkout picks that up by default). | |
| ref: ${{ github.event.release.target_commitish || github.ref }} | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| # create-dmg builds the styled drag-to-Applications DMG that | |
| # scripts/repack-dmg.sh wraps around electron-builder's signed .app. | |
| - name: Install create-dmg (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install create-dmg | |
| # Native module build toolchain for better-sqlite3 under Electron's ABI. | |
| - name: Install Linux deps | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| build-essential pkg-config python3 \ | |
| libxss1 libnss3 libasound2t64 \ | |
| fakeroot dpkg | |
| - run: bun install --frozen-lockfile | |
| # Rebuild native modules (better-sqlite3) against the Electron ABI | |
| # bundled by electron-builder. Runs on every OS — electron-builder | |
| # handles the platform-specific node-gyp invocation. | |
| - name: Rebuild native modules | |
| run: bunx electron-builder install-app-deps | |
| # Import the Developer ID signing cert into a temporary keychain. | |
| # Without this, electron-builder's codesign step fails with | |
| # "The specified item could not be found in the keychain." | |
| - name: Import Developer ID certificate (macOS) | |
| if: runner.os == 'macOS' | |
| env: | |
| MACOS_CERT_P12: ${{ secrets.MACOS_CERT_P12 }} | |
| MACOS_CERT_P12_PASSWORD: ${{ secrets.MACOS_CERT_P12_PASSWORD }} | |
| MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} | |
| run: | | |
| KEYCHAIN_PATH="$RUNNER_TEMP/skiller-build.keychain-db" | |
| CERT_PATH="$RUNNER_TEMP/cert.p12" | |
| echo "$MACOS_CERT_P12" | base64 --decode > "$CERT_PATH" | |
| security create-keychain -p "$MACOS_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | |
| security unlock-keychain -p "$MACOS_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security import "$CERT_PATH" \ | |
| -P "$MACOS_CERT_P12_PASSWORD" \ | |
| -A -t cert -f pkcs12 \ | |
| -k "$KEYCHAIN_PATH" | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: \ | |
| -s -k "$MACOS_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security list-keychain -d user -s "$KEYCHAIN_PATH" login.keychain | |
| rm -f "$CERT_PATH" | |
| # notarytool / @electron/notarize needs the .p8 file on disk. Secret | |
| # should be the raw contents of AuthKey_XXXX.p8 (multiline). | |
| - name: Write notarization API key (macOS) | |
| if: runner.os == 'macOS' && env.APPLE_API_KEY_P8 != '' | |
| env: | |
| APPLE_API_KEY_P8: ${{ secrets.APPLE_API_KEY_P8 }} | |
| run: | | |
| KEY_PATH="$RUNNER_TEMP/AuthKey.p8" | |
| printf '%s' "$APPLE_API_KEY_P8" > "$KEY_PATH" | |
| chmod 600 "$KEY_PATH" | |
| echo "APPLE_API_KEY=$KEY_PATH" >> "$GITHUB_ENV" | |
| - name: Build app | |
| env: | |
| # electron-builder reads GH_TOKEN for its publish step; we publish | |
| # via softprops below instead but the var being set also unlocks | |
| # electron-builder's release-draft verification. | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # macOS signing + notarization. Env-var names follow electron-builder's | |
| # conventions (NB: `APPLE_API_ISSUER`, not `APPLE_API_KEY_ISSUER` — | |
| # electron-builder rejects the "_KEY_" variant). | |
| CSC_NAME: ${{ secrets.CSC_NAME }} | |
| APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} | |
| APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} | |
| run: bun run ${{ matrix.script }} | |
| # Upload every artifact (including latest-*.yml and .blockmap files — | |
| # electron-updater needs them alongside the binaries). | |
| # The release itself (with CHANGELOG body) was already created by | |
| # release-please when the Release PR merged — we only attach assets. | |
| - name: Upload build outputs to Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ github.event.release.tag_name || github.ref_name }} | |
| # release-please creates the Release as a draft (see config). We | |
| # keep it a draft here too so softprops doesn't accidentally flip | |
| # it to published — the final publish-release job does that after | |
| # all three OS builds finish. | |
| draft: true | |
| # GitHub Releases shows assets in reverse upload order (newest on | |
| # top). Upload the auto-updater plumbing (yml, blockmap, zip) FIRST | |
| # and the human-facing installers LAST so the download list leads | |
| # with .dmg / .exe / .AppImage instead of the .zip that | |
| # electron-updater needs but end users should ignore. | |
| files: | | |
| artifacts/*.yml | |
| artifacts/*.blockmap | |
| artifacts/*.zip | |
| artifacts/*.tar.xz | |
| artifacts/*.deb | |
| artifacts/*.AppImage | |
| artifacts/*.exe | |
| artifacts/*.dmg | |
| fail_on_unmatched_files: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # Flip the release from draft to published ONLY after every matrix build | |
| # succeeded and uploaded its artifacts. This avoids the awkward window where | |
| # a user lands on the Releases page with only the Linux installer visible | |
| # because mac/win builds are still running. | |
| publish-release: | |
| needs: build-desktop | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Publish draft release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release edit "${{ github.event.release.tag_name || github.ref_name }}" \ | |
| --repo "${{ github.repository }}" \ | |
| --draft=false |