5
5
tags :
6
6
- " v*"
7
7
8
- # on: workflow_dispatch
9
- # on: push
8
+ env :
9
+ KEYPAIR_PROD : KP_Khiops_HSM
10
+ KEYPAIR_TEST : KP_Khiops_Test
10
11
11
12
jobs :
12
13
release :
@@ -16,45 +17,281 @@ jobs:
16
17
strategy :
17
18
matrix :
18
19
os : [macos-latest, ubuntu-latest, windows-latest]
19
-
20
+ # os: [macos-latest, windows-latest]
21
+ # os: [windows-latest]
20
22
steps :
21
23
- name : Check out Git repository
22
24
uses : actions/checkout@v4
25
+ continue-on-error : true
26
+
27
+ - name : Replace SSH with HTTPS in yarn.lock (Linux/macOS)
28
+ if : runner.os != 'Windows'
29
+ run : |
30
+ if [[ "$(uname)" == "Darwin" ]]; then
31
+ sed -i '' 's#git+ssh://[email protected] #https://github.com#g' yarn.lock
32
+ else
33
+ sed -i 's#git+ssh://[email protected] #https://github.com#g' yarn.lock
34
+ fi
35
+ continue-on-error : true
36
+
37
+ - name : Replace SSH with HTTPS in yarn.lock (Windows)
38
+ if : runner.os == 'Windows'
39
+ shell : pwsh
40
+ run : |
41
+ (Get-Content yarn.lock) -replace 'git\+ssh://[email protected] ', 'https://github.com' | Set-Content yarn.lock
42
+ continue-on-error : true
23
43
24
44
- name : Install Node.js, NPM and Yarn
25
45
uses : actions/setup-node@v4
26
46
with :
27
- node-version : 20
47
+ node-version : 22
48
+ continue-on-error : true
49
+
28
50
- run : yarn setEnv
29
51
env :
30
52
TRACKER_ID : ${{ secrets.TRACKER_ID }}
53
+ continue-on-error : true
31
54
32
55
- name : Prepare for app notarization (macOS)
33
56
if : startsWith(matrix.os, 'macos')
34
57
# Import Apple API key for app notarization on macOS
35
58
run : |
36
59
mkdir -p ~/private_keys/
37
60
echo '${{ secrets.api_key }}' > ~/private_keys/AuthKey_${{ secrets.api_key_id }}.p8
61
+ continue-on-error : true
38
62
39
63
- name : Force Install Dependencies Before Build
40
64
run : yarn install --verbose
65
+ continue-on-error : true
66
+
67
+ # Configuration of SAAS signature for Windows only
68
+ - name : Install DigiCert Client tools (Windows only)
69
+ if : runner.os == 'Windows'
70
+
71
+ continue-on-error : true
72
+
73
+ - name : Validate secrets (Windows only)
74
+ if : runner.os == 'Windows'
75
+ run : |
76
+ # Verify that all required secrets are present
77
+ if [[ -z "${{ secrets.SM_HOST }}" ]]; then
78
+ echo "❌ SM_HOST secret is missing"
79
+ exit 1
80
+ fi
81
+ if [[ -z "${{ secrets.SM_API_KEY }}" ]]; then
82
+ echo "❌ SM_API_KEY secret is missing"
83
+ exit 1
84
+ fi
85
+ if [[ -z "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" ]]; then
86
+ echo "❌ SM_CLIENT_CERT_FILE_B64 secret is missing"
87
+ exit 1
88
+ fi
89
+ if [[ -z "${{ secrets.SM_CLIENT_CERT_PASSWORD }}" ]]; then
90
+ echo "❌ SM_CLIENT_CERT_PASSWORD secret is missing"
91
+ exit 1
92
+ fi
93
+ echo "✅ All required secrets are present"
94
+ shell : bash
95
+ continue-on-error : true
96
+
97
+ - name : Set up certificate (Windows only)
98
+ if : runner.os == 'Windows'
99
+ run : |
100
+ echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
101
+ if [[ ! -f "/d/Certificate_pkcs12.p12" ]]; then
102
+ echo "❌ Failed to create certificate file"
103
+ exit 1
104
+ fi
105
+ echo "✅ Certificate file created successfully"
106
+ shell : bash
107
+ continue-on-error : true
108
+
109
+ - name : Set variables for signature (Windows only)
110
+ if : runner.os == 'Windows'
111
+ id : variables-used-by-smctl
112
+ run : |
113
+ echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
114
+ echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
115
+ echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV"
116
+ echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
117
+
118
+ echo "KEYPAIR=$KEYPAIR_PROD" >> "$GITHUB_ENV"
119
+ echo "::notice::Using Production key for signature"
120
+
121
+ # Verify that the environment variables are properly defined
122
+ echo "✅ Environment variables set:"
123
+ echo "SM_HOST: ${{ secrets.SM_HOST }}"
124
+ shell : bash
125
+ continue-on-error : true
41
126
42
- - name : Build/release Electron
127
+ - name : " Build Electron"
43
128
uses :
samuelmeuli/[email protected]
44
129
with :
45
130
build_script_name : " build:prod"
46
- # GitHub token, automatically provided to the action
47
- # (No need to define this secret in the repo settings)
48
131
github_token : ${{ secrets.github_token }}
49
-
50
- # If the commit is tagged with a version (e.g. "v1.0.0"),
51
- # release the app after building
52
- release : ${{ startsWith(github.ref, 'refs/tags/v') }}
53
- # release: true
54
-
55
132
mac_certs : ${{ secrets.mac_certs }}
56
133
mac_certs_password : ${{ secrets.mac_certs_password }}
57
134
env :
58
- # macOS notarization API key
59
135
API_KEY_ID : ${{ secrets.api_key_id }}
60
136
API_KEY_ISSUER_ID : ${{ secrets.api_key_issuer_id }}
137
+ continue-on-error : true
138
+
139
+ # Signing Windows executables after the build
140
+ - name : Sign Windows executables
141
+ if : runner.os == 'Windows'
142
+ run : |
143
+ echo "🔍 Searching for khiops Setup .exe file to sign..."
144
+
145
+ # Search specifically for Setup .exe file in release directory
146
+ setup_exe=""
147
+
148
+ if [[ -d "release" ]]; then
149
+ echo "Searching in release directory..."
150
+ setup_exe=$(find release -maxdepth 1 -name "*khiops*Setup*.exe" -type f | head -1)
151
+ fi
152
+
153
+ if [[ -z "$setup_exe" ]]; then
154
+ echo "❌ No khiops Setup .exe file found to sign"
155
+ exit 1
156
+ fi
157
+
158
+ echo "📋 Found Setup file to sign: $setup_exe"
159
+
160
+ # Test DigiCert connection before signing
161
+ echo "🔐 Testing DigiCert connection..."
162
+ if ! smctl healthcheck --all; then
163
+ echo "❌ DigiCert healthcheck failed"
164
+ exit 1
165
+ fi
166
+ # Sign the Setup file (overwrites the original by default)
167
+ echo "🖊️ Signing: $setup_exe"
168
+
169
+ if OUTPUT=$(smctl sign --keypair-alias "$KEYPAIR" --config-file "C:/Users/RUNNER~1/AppData/Local/Temp/smtools-windows-x64/pkcs11properties.cfg" --input "$setup_exe" 2>&1); then
170
+ echo "$OUTPUT"
171
+ if echo "$OUTPUT" | grep -q "SUCCESSFUL\|SUCCESS"; then
172
+ echo "✅ Successfully signed: $setup_exe"
173
+ else
174
+ echo "❌ Failed to sign: $setup_exe"
175
+ echo "Output: $OUTPUT"
176
+ exit 1
177
+ fi
178
+ else
179
+ echo "❌ Command failed for: $setup_exe"
180
+ echo "Error: $OUTPUT"
181
+ exit 1
182
+ fi
183
+
184
+ shell : bash
185
+ continue-on-error : true
186
+
187
+ # List all .exe files
188
+ - name : List all .exe files
189
+ if : runner.os == 'Windows'
190
+ shell : pwsh
191
+ run : |
192
+ Write-Output "📂 Listing all .exe files in release directory..."
193
+ Get-ChildItem -Path release -Filter *.exe | ForEach-Object { Write-Output $_.FullName; Write-Output $_.Length }
194
+ Write-Output "✅ Listed all .exe files."
195
+ continue-on-error : true
196
+
197
+ # Delete old non signed exe from release
198
+ # it is named like : khiops-covisualization-Setup-X.Y.Z.exe
199
+ - name : Delete old non signed exe from release
200
+ if : runner.os == 'Windows'
201
+ shell : pwsh
202
+ run : |
203
+ Write-Output "🗑️ Deleting old non-signed executables..."
204
+ $files = Get-ChildItem -Path release -Filter "khiops-covisualization-Setup-*.exe"
205
+ if ($files) {
206
+ Remove-Item $files.FullName -Force
207
+ Write-Output "✅ Old non-signed executables deleted."
208
+ } else {
209
+ Write-Output "No old non-signed executables found."
210
+ }
211
+ continue-on-error : true
212
+
213
+ # Delete old khiops.covisualization.Setup.X.Y.Z.exe.blockmap
214
+ - name : Delete old blockmap files
215
+ if : runner.os == 'Windows'
216
+ shell : pwsh
217
+ run : |
218
+ Write-Output "🗑️ Deleting old blockmap files..."
219
+ $blockmap_files = Get-ChildItem -Path release -Filter "khiops.covisualization.Setup.*.exe.blockmap"
220
+ if ($blockmap_files) {
221
+ Remove-Item $blockmap_files.FullName -Force
222
+ Write-Output "✅ Old blockmap files deleted."
223
+ } else {
224
+ Write-Output "No old blockmap files found."
225
+ }
226
+ continue-on-error : true
227
+
228
+ # Rename signed exe from khiops.covisualization.Setup-X.Y.Z.exe to khiops-covisualization-Setup-X.Y.Z.exe
229
+ - name : Rename signed executable khiops-covisualization-Setup-*.exe
230
+ if : runner.os == 'Windows'
231
+ shell : pwsh
232
+ run : |
233
+ Write-Output "🔄 Renaming signed executable..."
234
+ # Find the signed executable and rename it
235
+ $signed_exe = Get-ChildItem -Path release -Filter "khiops covisualization Setup *.exe" | Select-Object -First 1
236
+ if (-not $signed_exe) {
237
+ Write-Output "❌ No signed executable found to rename"
238
+ exit 1
239
+ }
240
+ $new_name = "release/khiops-covisualization-Setup-$($env:GITHUB_REF.Split('/')[-1].TrimStart('v')).exe"
241
+ Move-Item $signed_exe.FullName $new_name
242
+ Write-Output "✅ Renamed signed executable to: $new_name"
243
+ continue-on-error : true
244
+
245
+ # Udpate latest.yml sha for Windows
246
+ - name : Update latest.yml for Windows
247
+ if : runner.os == 'Windows'
248
+ shell : pwsh
249
+ run : |
250
+ $exe = Get-ChildItem -Path release -Filter "khiops-covisualization-Setup-*.exe" | Select-Object -First 1
251
+ if (-not $exe) {
252
+ Write-Error "No signed executable found in release directory."
253
+ exit 1
254
+ }
255
+ $hash = Get-FileHash -Algorithm SHA512 -Path $exe.FullName
256
+ $hex = $hash.Hash
257
+ $bytes = for ($i = 0; $i -lt $hex.Length; $i += 2) { [Convert]::ToByte($hex.Substring($i, 2), 16) }
258
+ $base64 = [Convert]::ToBase64String($bytes)
259
+ $size = (Get-Item $exe.FullName).Length
260
+ $latestYml = "release/latest.yml"
261
+ if (-not (Test-Path $latestYml)) {
262
+ Write-Error "latest.yml not found."
263
+ exit 1
264
+ }
265
+ (Get-Content $latestYml) -replace "(sha512:\s*).+", "`$1$base64" | Set-Content $latestYml
266
+ Write-Output "✅ Updated sha512 in latest.yml"
267
+ continue-on-error : true
268
+
269
+ # Now we can create the release with the signed files
270
+ - name : Extract version from tag
271
+ if : startsWith(github.ref, 'refs/tags/v')
272
+ id : version
273
+ run : echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
274
+ shell : bash
275
+
276
+ - name : Create GitHub Release with signed files
277
+ if : startsWith(github.ref, 'refs/tags/v')
278
+
279
+ with :
280
+ allowUpdates : true
281
+ tag : ${{ github.ref_name }}
282
+ name : ${{ steps.version.outputs.VERSION }}
283
+ artifacts : |
284
+ release/*Setup*.exe
285
+ release/*.dmg
286
+ release/*.AppImage
287
+ release/*.deb
288
+ release/*.rpm
289
+ release/*.zip
290
+ release/*.tar.gz
291
+ release/latest-linux.yml
292
+ release/latest-mac.yml
293
+ release/latest.yml
294
+ release/*.blockmap
295
+ generateReleaseNotes : true
296
+ draft : true
297
+ continue-on-error : true
0 commit comments