diff --git a/.github/workflows/desktop-release.yml b/.github/workflows/desktop-release.yml index 42799aa..ebc69f5 100644 --- a/.github/workflows/desktop-release.yml +++ b/.github/workflows/desktop-release.yml @@ -46,21 +46,42 @@ jobs: - name: Self-test the SSH tunnel transport # Runs a real SSH server in-process, so it needs a display-free Electron. # xvfb is only required on Linux; the other runners have a window server. + # + # ELECTRON_DISABLE_SANDBOX: GitHub-hosted Linux runners ship Electron's + # chrome-sandbox without root:4755, so Chromium aborts with SIGTRAP + # before the test starts ("SUID sandbox helper binary … is not + # configured correctly"). Verified on desktop-v1.0.0. Sandbox is + # irrelevant for this headless selftest. working-directory: desktop + env: + ELECTRON_DISABLE_SANDBOX: '1' run: ${{ matrix.os == 'ubuntu-latest' && 'xvfb-run --auto-servernum npm run selftest:tunnel' || 'npm run selftest:tunnel' }} shell: bash - name: Build installers working-directory: desktop env: - # Signing is skipped when these are unset; electron-builder warns and - # produces unsigned artifacts rather than failing the build. - CSC_LINK: ${{ secrets.DESKTOP_CSC_LINK }} - CSC_KEY_PASSWORD: ${{ secrets.DESKTOP_CSC_KEY_PASSWORD }} + # Keep secrets in DESKTOP_* names first. Passing an empty CSC_LINK from + # an unset repository secret still counts as "set" for electron-builder, + # which then tries to open it as a file and fails macOS with + # "…/desktop not a file" (observed on desktop-v1.0.0). Only export the + # real CSC_* / Apple vars when a signing secret is actually configured. + DESKTOP_CSC_LINK: ${{ secrets.DESKTOP_CSC_LINK }} + DESKTOP_CSC_KEY_PASSWORD: ${{ secrets.DESKTOP_CSC_KEY_PASSWORD }} APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} - run: npx electron-builder ${{ matrix.target }} --publish never + run: | + set -euo pipefail + if [ -n "${DESKTOP_CSC_LINK:-}" ]; then + export CSC_LINK="$DESKTOP_CSC_LINK" + export CSC_KEY_PASSWORD="${DESKTOP_CSC_KEY_PASSWORD:-}" + else + export CSC_IDENTITY_AUTO_DISCOVERY=false + echo "No DESKTOP_CSC_LINK secret — building unsigned installers." + fi + npx electron-builder ${{ matrix.target }} --publish never + shell: bash - uses: actions/upload-artifact@v4 with: diff --git a/desktop/README.md b/desktop/README.md index 9a7ad3a..2688185 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -91,6 +91,13 @@ environment variables to enable it: - macOS: `CSC_LINK`, `CSC_KEY_PASSWORD`, plus `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, `APPLE_TEAM_ID` for notarisation. - Windows: `CSC_LINK`, `CSC_KEY_PASSWORD` (or an Azure Trusted Signing config). +CI (`.github/workflows/desktop-release.yml`) builds **unsigned** installers unless +the repository secret `DESKTOP_CSC_LINK` is set. An empty `CSC_LINK` still counts +as configured for electron-builder and fails the macOS job — the workflow only +exports `CSC_*` when that secret is non-empty, and otherwise sets +`CSC_IDENTITY_AUTO_DISCOVERY=false`. Linux selftests set `ELECTRON_DISABLE_SANDBOX=1` +because hosted runners lack a correctly permissioned `chrome-sandbox`. + **Auto-update** is opt-in. `package.json` sets `"publish": null`, so no update feed is baked in and the updater no-ops. To enable it, either set a `publish` target (GitHub Releases, S3, generic) before building, or point