-
Notifications
You must be signed in to change notification settings - Fork 59
163 lines (142 loc) · 7.49 KB
/
Copy pathrelease_desktop_app.yml
File metadata and controls
163 lines (142 loc) · 7.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
name: Release Desktop App
# Single-job release flow preserved from the original samuelmeuli-based
# pipeline. Each dispatch builds one platform; release tagging + GitHub
# Releases upload are handled identically across all three (samuelmeuli's
# `release: true` consumes the commit's version tag and uploads the
# electron-builder outputs to the matching GH Release).
#
# Signing model:
# macOS — Apple Developer ID via mac_certs (P12 in secrets.MAC_CERTS),
# electron-builder's built-in notarytool flow using
# APPLE_ID + APPLE_APP_SPECIFIC_PASSWORD env (teamId hardcoded
# in package.json — public info anyway).
# Windows — Authenticode via Google Cloud KMS (WIF + CNG provider +
# scripts/windows-kms-sign.js). Private key never leaves GCP;
# public leaf cert handed in via WINDOWS_CODESIGN_CERT_BASE64.
# Linux — AppImage, unsigned.
on:
workflow_dispatch:
inputs:
build_type:
description: "Build Type"
required: true
type: choice
options:
- ubuntu-latest
- windows-2022
- macos-latest
default: windows-2022
jobs:
release:
permissions:
contents: write # samuelmeuli uses github_token to publish releases
id-token: write # OIDC for GCP Workload Identity Federation (Windows)
env:
EP_GH_IGNORE_TIME: true
# Notarize credentials consumed by electron-builder's built-in
# notarytool flow during the macOS sign step. Empty on non-mac runs;
# the action then skips notarization cleanly.
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
if: github.ref == 'refs/heads/master'|| github.ref == 'refs/heads/production'
runs-on: ${{ github.event.inputs.build_type }}
steps:
- name: EOL autocrlf input
if: ${{ github.event.inputs.build_type != 'windows-2019' }}
run: git config --global core.autocrlf input
- name: EOL autocrlf true
if: ${{ github.event.inputs.build_type == 'windows-2019' }}
run: git config --global core.autocrlf true
- name: Check out Git repository
uses: actions/checkout@v4
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v4
with:
node-version: 20.9.0
# Replaces the legacy `Install Distutils` step. node-gyp@9.3.1 (the
# legacy app's pinned version) still imports distutils.version, which
# Python 3.12+ removed (PEP 632). Pinning Python to 3.11 brings
# distutils back as stdlib for both windows-2022 and ubuntu-latest
# runners.
- name: Set up Python 3.11 for node-gyp
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install desktop app dependencies
run: bash ./install.sh
# ─── Windows: GCP KMS signing setup (replaces windows_certs P12) ────
# Runs only on windows-2022. The MSI + config drop is required so
# signtool can use the "Google Cloud KMS Provider" CSP from the
# win.sign hook later in the build step.
- name: Auth to Google Cloud (KMS)
if: ${{ github.event.inputs.build_type == 'windows-2022' }}
uses: google-github-actions/auth@c200f3691d83b41bf9bbd8638997a462592937ed # v2
with:
workload_identity_provider: ${{ vars.WIF_PROVIDER }}
service_account: ${{ vars.WIF_SERVICE_ACCOUNT }}
- name: Install + configure KMS CNG provider
if: ${{ github.event.inputs.build_type == 'windows-2022' }}
shell: pwsh
env:
GCP_PROJECT_ID: ${{ vars.WIN_SIGN_KMS_PROJECT }}
GCP_KMS_LOCATION: ${{ vars.WIN_SIGN_KMS_LOCATION }}
GCP_KMS_KEY_RING: ${{ vars.WIN_SIGN_KMS_KEY_RING }}
GCP_KMS_KEY_NAME: ${{ vars.WIN_SIGN_KMS_KEY_NAME }}
GCP_KMS_KEY_VERSION: ${{ vars.WIN_SIGN_KMS_KEY_VERSION }}
run: |
$ErrorActionPreference = 'Stop'
# --- Install MSI ---
$cngVersion = '1.3'
$expectedHash = '4CB9FBF6F17F58CA1B404BF532C2D75519F5B3378F646B9C3AC4361E640F2450'
$cngUrl = "https://github.com/GoogleCloudPlatform/kms-integrations/releases/download/cng-v${cngVersion}/kmscng-${cngVersion}-windows-amd64.zip"
Invoke-WebRequest -Uri $cngUrl -OutFile kmscng.zip
$actualHash = (Get-FileHash -Path kmscng.zip -Algorithm SHA256).Hash
if ($actualHash -ne $expectedHash) {
throw "CNG checksum mismatch — expected $expectedHash, got $actualHash"
}
Expand-Archive -Path kmscng.zip -DestinationPath kmscng
$msi = Get-ChildItem -Path kmscng -Filter '*.msi' -Recurse | Select-Object -First 1
if (-not $msi) { throw 'No MSI in extracted kmscng archive' }
$proc = Start-Process msiexec.exe -Wait -PassThru `
-ArgumentList "/i `"$($msi.FullName)`" /quiet /norestart"
if ($proc.ExitCode -ne 0) { throw "MSI install failed (exit $($proc.ExitCode))" }
# --- Write the CNG key-path config ---
$required = @('GCP_PROJECT_ID','GCP_KMS_LOCATION','GCP_KMS_KEY_RING','GCP_KMS_KEY_NAME','GCP_KMS_KEY_VERSION')
foreach ($v in $required) {
if (-not [Environment]::GetEnvironmentVariable($v)) { throw "Missing required variable: $v" }
}
$keyPath = "projects/$env:GCP_PROJECT_ID/locations/$env:GCP_KMS_LOCATION/keyRings/$env:GCP_KMS_KEY_RING/cryptoKeys/$env:GCP_KMS_KEY_NAME/cryptoKeyVersions/$env:GCP_KMS_KEY_VERSION"
$configDir = 'C:\Windows\KMSCNG'
New-Item -ItemType Directory -Path $configDir -Force | Out-Null
"resources:`n - crypto_key_version: `"$keyPath`"" |
Out-File -Encoding utf8NoBOM -FilePath "$configDir\config.yaml"
- name: Build/release Electron app
uses: samuelmeuli/action-electron-builder@v1.6.0
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
# ─── Windows GCP KMS signing (consumed by scripts/windows-kms-sign.js) ──
# On non-Windows builds these resolve to empty / are unused; the
# sign script self-skips when USE_KMS_SIGNING is not 'true'.
USE_KMS_SIGNING: ${{ github.event.inputs.build_type == 'windows-2022' && 'true' || '' }}
WIN_SIGN_CERT_BASE64: ${{ secrets.WINDOWS_CODESIGN_CERT_BASE64 }}
GCP_PROJECT_ID: ${{ vars.WIN_SIGN_KMS_PROJECT }}
GCP_KMS_LOCATION: ${{ vars.WIN_SIGN_KMS_LOCATION }}
GCP_KMS_KEY_RING: ${{ vars.WIN_SIGN_KMS_KEY_RING }}
GCP_KMS_KEY_NAME: ${{ vars.WIN_SIGN_KMS_KEY_NAME }}
GCP_KMS_KEY_VERSION: ${{ vars.WIN_SIGN_KMS_KEY_VERSION }}
with:
# GitHub token, automatically provided to the action
# (No need to define this secret in the repo settings)
github_token: ${{ secrets.publish_token }}
package_root: "."
mac_certs: ${{ secrets.bstack_mac_certs }}
mac_certs_password: ${{ secrets.bstack_mac_certs_password }}
# windows_certs / windows_certs_password intentionally removed.
# Windows codesigning now happens inside electron-builder via the
# win.sign hook (scripts/windows-kms-sign.js) using the GCP KMS CNG
# provider — the private key never lands on the runner. The hook
# reads USE_KMS_SIGNING / WIN_SIGN_CERT_BASE64 / GCP_KMS_* from the
# env block above.
# If the commit is tagged with a version (e.g. "v1.0.0"),
# release the app after building
release: true