Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 79 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,28 @@ jobs:
- name: Build renderer assets
run: pnpm run build

# electron-builder takes APPLE_API_KEY as a file path, not the key text.
- name: Write App Store Connect API key
if: matrix.platform == 'mac'
env:
APPLE_API_KEY_P8: ${{ secrets.APPLE_API_KEY_P8 }}
run: |
KEY_PATH="$RUNNER_TEMP/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8"
printf '%s' "$APPLE_API_KEY_P8" > "$KEY_PATH"
echo "APPLE_API_KEY=$KEY_PATH" >> "$GITHUB_ENV"
shell: bash

- name: Build release packages
# No signing certificate yet: mac.identity "-" in package.json forces ad-hoc signing so
# Apple Silicon builds launch. electron-builder only consults CSC_IDENTITY_AUTO_DISCOVERY
# when identity is unset, so it has no effect here - left unset for clarity, not because
# it changes this build.
# The Windows job must not see CSC_LINK: it would try to sign the NSIS installer with
# the Apple .p12.
run: ${{ matrix.build_command }}
shell: bash
env:
CSC_LINK: ${{ matrix.platform == 'mac' && secrets.CSC_LINK || '' }}
CSC_KEY_PASSWORD: ${{ matrix.platform == 'mac' && secrets.CSC_KEY_PASSWORD || '' }}
APPLE_API_KEY_ID: ${{ matrix.platform == 'mac' && secrets.APPLE_API_KEY_ID || '' }}
APPLE_API_ISSUER: ${{ matrix.platform == 'mac' && secrets.APPLE_API_ISSUER || '' }}
APPLE_TEAM_ID: ${{ matrix.platform == 'mac' && secrets.APPLE_TEAM_ID || '' }}

# The mac job packages x64 and arm64 from one node_modules, and pnpm only materialises
# the runner's own architecture, so a missing native binary is invisible until a user
Expand All @@ -102,14 +117,54 @@ jobs:
run: node test/verify-packaged-sharp.mjs release
shell: bash

- name: Upload build artifacts
uses: actions/upload-artifact@v4
# Each installer is its own unzipped artifact so one build can be downloaded and tested
# without pulling the whole platform set. archive: false takes exactly one file and names
# the artifact after it, hence one step per glob.
- name: Upload Windows installer
if: matrix.platform == 'win'
uses: actions/upload-artifact@v7
with:
path: release/*.exe
archive: false
if-no-files-found: error

- name: Upload macOS arm64 DMG
if: matrix.platform == 'mac'
uses: actions/upload-artifact@v7
with:
path: release/*-arm64.dmg
archive: false
if-no-files-found: error

- name: Upload macOS x64 DMG
if: matrix.platform == 'mac'
uses: actions/upload-artifact@v7
with:
name: release-${{ matrix.platform }}
path: release/*-x64.dmg
archive: false
if-no-files-found: error

- name: Upload macOS arm64 update zip
if: matrix.platform == 'mac'
uses: actions/upload-artifact@v7
with:
path: release/*-arm64.zip
archive: false
if-no-files-found: error

- name: Upload macOS x64 update zip
if: matrix.platform == 'mac'
uses: actions/upload-artifact@v7
with:
path: release/*-x64.zip
archive: false
if-no-files-found: error

- name: Upload update metadata
uses: actions/upload-artifact@v7
with:
name: release-meta-${{ matrix.platform }}
path: |
release/*.exe
release/*.dmg
release/*.zip
release/*.yml
release/*.yaml
release/*.blockmap
Expand All @@ -128,10 +183,22 @@ jobs:
with:
ref: ${{ needs.prepare.outputs.sha }}

- name: Download artifacts
uses: actions/download-artifact@v4
# The installers were uploaded unzipped. Without skip-decompress the mac update .zip files
# would be extracted instead of uploaded to the release as-is.
- name: Download installers
uses: actions/download-artifact@v8
with:
pattern: Power*
path: release-artifacts
merge-multiple: true
skip-decompress: true

- name: Download update metadata
uses: actions/download-artifact@v8
with:
pattern: release-meta-*
path: release-artifacts
merge-multiple: true

- name: Tag and publish release
env:
Expand Down
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,10 @@ Power Interview desktop client is supported on:

Release binaries are published on the [GitHub Releases](https://github.com/PowerInterviewAI/client-app/releases) page.

### Unsigned builds
### Code signing

Release artifacts are not yet code-signed, so the OS will warn on first launch:

- **macOS**: the app is ad-hoc signed (so it runs on Apple Silicon) but not notarized. If you see "app is damaged" or it is blocked, run `xattr -cr "/Applications/Power Interview AI.app"`, or right-click the app and choose Open.
- **Windows**: SmartScreen shows "Windows protected your PC". Click "More info" then "Run anyway".
- **macOS**: release builds are signed with a Developer ID Application certificate and notarized by Apple, so they open without a Gatekeeper warning. The release workflow needs the `CSC_LINK`, `CSC_KEY_PASSWORD`, `APPLE_API_KEY_P8`, `APPLE_API_KEY_ID`, `APPLE_API_ISSUER` and `APPLE_TEAM_ID` repository secrets; `mac.forceCodeSigning` fails the build if the certificate is missing. Releases up to v1.9.4 were ad-hoc signed only: if one shows "app is damaged", run `xattr -cr "/Applications/Power Interview AI.app"`.
- **Windows**: the installer is not code-signed yet, so SmartScreen shows "Windows protected your PC". Click "More info" then "Run anyway".

## Architecture

Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"concurrently": "^9.2.1",
"cross-env": "^10.1.0",
"electron": "^40.1.0",
"electron-builder": "^26.15.3",
"electron-builder": "^26.17.0",
"eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
Expand Down Expand Up @@ -147,9 +147,9 @@
"artifactName": "${productName}-${version}-${arch}.${ext}",
"category": "public.app-category.productivity",
"minimumSystemVersion": "14.4.0",
"identity": "-",
"hardenedRuntime": false,
"notarize": false,
"hardenedRuntime": true,
"notarize": true,
"forceCodeSigning": true,
"entitlements": "build/entitlements.mac.plist",
"entitlementsInherit": "build/entitlements.mac.inherit.plist",
"extendInfo": {
Expand Down
Loading
Loading