-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
186 lines (169 loc) · 7.51 KB
/
Copy pathdesktop-release.yml
File metadata and controls
186 lines (169 loc) · 7.51 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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
name: Desktop Release
on:
push:
tags:
- 'v*'
- 'beta-v*'
workflow_dispatch:
inputs:
version:
description: 'Version number (e.g. 0.0.15) — used for dry-run testing without a tag'
required: true
default: '0.0.0-test'
publish:
description: 'Publish to GitHub Releases'
required: true
type: choice
options:
- never
- always
default: 'never'
permissions:
contents: write
id-token: write
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
platform: --mac
- os: ubuntu-latest
platform: --linux
- os: windows-latest
platform: --win
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Extract version
id: version
shell: bash
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="${{ inputs.version }}"
else
TAG=${GITHUB_REF#refs/tags/}
VERSION=${TAG#beta-}
VERSION=${VERSION#v}
fi
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'; then
echo "::error::Version '$VERSION' is not valid semver (expected X.Y.Z). Fix your tag name."
exit 1
fi
echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT"
- name: Detect Windows signing eligibility
id: sign
shell: bash
run: |
# Sign Windows builds only on production v* tags (not beta-v*, not workflow_dispatch).
# This matches the single OIDC federated credential configured in Entra ID.
if [ "${{ matrix.os }}" = "windows-latest" ] \
&& [ "${{ github.event_name }}" = "push" ] \
&& [[ "$GITHUB_REF" == refs/tags/v* ]]; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
echo "Windows signing: ENABLED (v* tag on windows-latest)"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
echo "Windows signing: skipped"
fi
- name: Verify Apple notarization credentials
if: matrix.os == 'macos-latest'
shell: bash
# Fails in seconds with the same 401 notarytool would throw after the
# full build, instead of wasting ~15 min of build time on bad secrets.
run: |
xcrun notarytool history \
--apple-id "$APPLE_ID" \
--password "$APPLE_APP_SPECIFIC_PASSWORD" \
--team-id "$APPLE_TEAM_ID" > /dev/null
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- name: Setup pnpm
uses: pnpm/action-setup@v5
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 22
cache: 'pnpm'
cache-dependency-path: |
surfsense_web/pnpm-lock.yaml
surfsense_desktop/pnpm-lock.yaml
- name: Install web dependencies
run: pnpm install
working-directory: surfsense_web
- name: Build Next.js standalone
run: pnpm build
working-directory: surfsense_web
env:
NEXT_PUBLIC_FASTAPI_BACKEND_URL: ${{ vars.HOSTED_BACKEND_URL }}
SURFSENSE_BACKEND_INTERNAL_URL: ${{ vars.HOSTED_BACKEND_URL }}
NEXT_PUBLIC_ZERO_CACHE_URL: ${{ vars.NEXT_PUBLIC_ZERO_CACHE_URL }}
NEXT_PUBLIC_DEPLOYMENT_MODE: ${{ vars.NEXT_PUBLIC_DEPLOYMENT_MODE }}
NEXT_PUBLIC_AUTH_TYPE: ${{ vars.NEXT_PUBLIC_AUTH_TYPE }}
NEXT_PUBLIC_ETL_SERVICE: ${{ vars.NEXT_PUBLIC_ETL_SERVICE }}
NEXT_PUBLIC_POSTHOG_KEY: ${{ secrets.NEXT_PUBLIC_POSTHOG_KEY }}
- name: Install desktop dependencies
run: pnpm install
working-directory: surfsense_desktop
- name: Build Electron
run: pnpm build
working-directory: surfsense_desktop
env:
HOSTED_BACKEND_URL: ${{ vars.HOSTED_BACKEND_URL }}
HOSTED_FRONTEND_URL: ${{ vars.HOSTED_FRONTEND_URL }}
GOOGLE_DESKTOP_CLIENT_ID: ${{ vars.GOOGLE_DESKTOP_CLIENT_ID }}
POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
POSTHOG_HOST: ${{ vars.POSTHOG_HOST }}
- name: Package & Publish
shell: bash
run: |
CMD=(pnpm exec electron-builder ${{ matrix.platform }} \
--config electron-builder.yml \
--publish "${{ inputs.publish || 'always' }}" \
-c.extraMetadata.version="${{ steps.version.outputs.VERSION }}")
# node-mac-permissions is the only native dependency and is darwin-only.
# electron-builder's internal rebuild would try to node-gyp compile it on
# Windows (no Visual Studio) and Linux, so skip the rebuild there. On macOS
# the rebuild must stay enabled for per-arch (x64/arm64) builds.
if [ "${{ matrix.platform }}" != "--mac" ]; then
CMD+=(-c.npmRebuild=false)
fi
if [ "${{ steps.sign.outputs.enabled }}" = "true" ]; then
CMD+=(-c.win.azureSignOptions.publisherName="$WINDOWS_PUBLISHER_NAME")
CMD+=(-c.win.azureSignOptions.endpoint="$AZURE_CODESIGN_ENDPOINT")
CMD+=(-c.win.azureSignOptions.codeSigningAccountName="$AZURE_CODESIGN_ACCOUNT")
CMD+=(-c.win.azureSignOptions.certificateProfileName="$AZURE_CODESIGN_PROFILE")
fi
"${CMD[@]}"
working-directory: surfsense_desktop
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GOOGLE_DESKTOP_CLIENT_ID: ${{ vars.GOOGLE_DESKTOP_CLIENT_ID }}
WINDOWS_PUBLISHER_NAME: ${{ vars.WINDOWS_PUBLISHER_NAME }}
AZURE_CODESIGN_ENDPOINT: ${{ vars.AZURE_CODESIGN_ENDPOINT }}
AZURE_CODESIGN_ACCOUNT: ${{ vars.AZURE_CODESIGN_ACCOUNT }}
AZURE_CODESIGN_PROFILE: ${{ vars.AZURE_CODESIGN_PROFILE }}
# macOS Developer ID signing + notarization. Only the macos-latest runner
# consumes these; Windows/Linux runners ignore them. CSC_LINK accepts either
# a file path or a base64-encoded .p12 blob — electron-builder auto-detects.
CSC_LINK: ${{ secrets.MAC_CERT_P12_BASE64 }}
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERT_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
# TEMP DEBUG — remove once the codesign hang on macos-latest is diagnosed.
# Surfaces the exact codesign / notarize commands electron-builder spawns,
# so we can see which subprocess hangs.
DEBUG: electron-builder,electron-osx-sign*,@electron/notarize*
ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES: "true"
# Service principal credentials for Azure.Identity EnvironmentCredential used by the
# TrustedSigning PowerShell module. Only populated when signing is enabled.
# electron-builder 26 does not yet support OIDC federated tokens for Azure signing,
# so we fall back to client-secret auth. Rotate AZURE_CLIENT_SECRET before expiry.
AZURE_TENANT_ID: ${{ steps.sign.outputs.enabled == 'true' && secrets.AZURE_TENANT_ID || '' }}
AZURE_CLIENT_ID: ${{ steps.sign.outputs.enabled == 'true' && secrets.AZURE_CLIENT_ID || '' }}
AZURE_CLIENT_SECRET: ${{ steps.sign.outputs.enabled == 'true' && secrets.AZURE_CLIENT_SECRET || '' }}