@@ -102,9 +102,73 @@ jobs:
102102 outputs :
103103 version : ${{ needs.version.outputs.version }}
104104
105+ sign-cli-windows :
106+ needs :
107+ - build-cli
108+ - version
109+ runs-on : blacksmith-4vcpu-windows-2025
110+ if : github.repository == 'anomalyco/opencode'
111+ steps :
112+ - uses : actions/checkout@v3
113+
114+ - uses : actions/download-artifact@v4
115+ with :
116+ name : opencode-cli
117+ path : packages/opencode/dist
118+
119+ - name : Setup git committer
120+ id : committer
121+ uses : ./.github/actions/setup-git-committer
122+ with :
123+ opencode-app-id : ${{ vars.OPENCODE_APP_ID }}
124+ opencode-app-secret : ${{ secrets.OPENCODE_APP_SECRET }}
125+
126+ - uses : ./.github/actions/windows-trusted-signing
127+ with :
128+ azure-client-id : ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }}
129+ azure-tenant-id : ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }}
130+ azure-subscription-id : ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }}
131+ trusted-signing-account-name : ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
132+ trusted-signing-certificate-profile : ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }}
133+ trusted-signing-endpoint : ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }}
134+ files : |
135+ ${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe
136+ ${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe
137+ ${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe
138+
139+ - name : Repack Windows CLI archives
140+ working-directory : packages/opencode/dist
141+ shell : pwsh
142+ run : |
143+ Compress-Archive -Path "opencode-windows-arm64\bin\*" -DestinationPath "opencode-windows-arm64.zip" -Force
144+ Compress-Archive -Path "opencode-windows-x64\bin\*" -DestinationPath "opencode-windows-x64.zip" -Force
145+ Compress-Archive -Path "opencode-windows-x64-baseline\bin\*" -DestinationPath "opencode-windows-x64-baseline.zip" -Force
146+
147+ - name : Upload signed Windows CLI release assets
148+ if : needs.version.outputs.release != ''
149+ shell : pwsh
150+ env :
151+ GH_TOKEN : ${{ steps.committer.outputs.token }}
152+ run : |
153+ gh release upload "v${{ needs.version.outputs.version }}" `
154+ "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64.zip" `
155+ "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64.zip" `
156+ "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline.zip" `
157+ --clobber `
158+ --repo "${{ needs.version.outputs.repo }}"
159+
160+ - uses : actions/upload-artifact@v4
161+ with :
162+ name : opencode-cli-signed-windows
163+ path : |
164+ packages/opencode/dist/opencode-windows-arm64
165+ packages/opencode/dist/opencode-windows-x64
166+ packages/opencode/dist/opencode-windows-x64-baseline
167+
105168 build-tauri :
106169 needs :
107170 - build-cli
171+ - sign-cli-windows
108172 - version
109173 continue-on-error : false
110174 strategy :
@@ -152,6 +216,16 @@ jobs:
152216
153217 - uses : ./.github/actions/setup-bun
154218
219+ - uses : ./.github/actions/windows-trusted-signing
220+ if : runner.os == 'Windows'
221+ with :
222+ azure-client-id : ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }}
223+ azure-tenant-id : ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }}
224+ azure-subscription-id : ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }}
225+ trusted-signing-account-name : ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
226+ trusted-signing-certificate-profile : ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }}
227+ trusted-signing-endpoint : ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }}
228+
155229 - uses : actions/setup-node@v4
156230 with :
157231 node-version : " 24"
@@ -190,6 +264,7 @@ jobs:
190264 env :
191265 OPENCODE_VERSION : ${{ needs.version.outputs.version }}
192266 GITHUB_TOKEN : ${{ steps.committer.outputs.token }}
267+ OPENCODE_CLI_ARTIFACT : ${{ (runner.os == 'Windows' && 'opencode-cli-signed-windows') || 'opencode-cli' }}
193268 RUST_TARGET : ${{ matrix.settings.target }}
194269 GH_TOKEN : ${{ github.token }}
195270 GITHUB_RUN_ID : ${{ github.run_id }}
@@ -246,9 +321,27 @@ jobs:
246321 APPLE_API_KEY : ${{ secrets.APPLE_API_KEY }}
247322 APPLE_API_KEY_PATH : ${{ runner.temp }}/apple-api-key.p8
248323
324+ - name : Verify signed Windows desktop artifacts
325+ if : runner.os == 'Windows'
326+ shell : pwsh
327+ run : |
328+ $files = @(
329+ "${{ github.workspace }}\packages\desktop\src-tauri\sidecars\opencode-cli-${{ matrix.settings.target }}.exe",
330+ "${{ github.workspace }}\packages\desktop\src-tauri\target\${{ matrix.settings.target }}\release\OpenCode.exe"
331+ )
332+ $files += Get-ChildItem "${{ github.workspace }}\packages\desktop\src-tauri\target\${{ matrix.settings.target }}\release\bundle\nsis\*.exe" | Select-Object -ExpandProperty FullName
333+
334+ foreach ($file in $files) {
335+ $sig = Get-AuthenticodeSignature $file
336+ if ($sig.Status -ne "Valid") {
337+ throw "Invalid signature for ${file}: $($sig.Status)"
338+ }
339+ }
340+
249341 build-electron :
250342 needs :
251343 - build-cli
344+ - sign-cli-windows
252345 - version
253346 continue-on-error : false
254347 strategy :
@@ -292,6 +385,16 @@ jobs:
292385
293386 - uses : ./.github/actions/setup-bun
294387
388+ - uses : ./.github/actions/windows-trusted-signing
389+ if : runner.os == 'Windows'
390+ with :
391+ azure-client-id : ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }}
392+ azure-tenant-id : ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }}
393+ azure-subscription-id : ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }}
394+ trusted-signing-account-name : ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
395+ trusted-signing-certificate-profile : ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }}
396+ trusted-signing-endpoint : ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }}
397+
295398 - uses : actions/setup-node@v4
296399 with :
297400 node-version : " 24"
@@ -326,6 +429,7 @@ jobs:
326429 env :
327430 OPENCODE_VERSION : ${{ needs.version.outputs.version }}
328431 OPENCODE_CHANNEL : ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
432+ OPENCODE_CLI_ARTIFACT : ${{ (runner.os == 'Windows' && 'opencode-cli-signed-windows') || 'opencode-cli' }}
329433 RUST_TARGET : ${{ matrix.settings.target }}
330434 GH_TOKEN : ${{ github.token }}
331435 GITHUB_RUN_ID : ${{ github.run_id }}
@@ -358,6 +462,21 @@ jobs:
358462 env :
359463 OPENCODE_CHANNEL : ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
360464
465+ - name : Verify signed Windows Electron artifacts
466+ if : runner.os == 'Windows'
467+ shell : pwsh
468+ run : |
469+ $files = @()
470+ $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*.exe" | Select-Object -ExpandProperty FullName
471+ $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*unpacked\*.exe" | Select-Object -ExpandProperty FullName
472+
473+ foreach ($file in $files | Select-Object -Unique) {
474+ $sig = Get-AuthenticodeSignature $file
475+ if ($sig.Status -ne "Valid") {
476+ throw "Invalid signature for ${file}: $($sig.Status)"
477+ }
478+ }
479+
361480 - uses : actions/upload-artifact@v4
362481 with :
363482 name : opencode-electron-${{ matrix.settings.target }}
@@ -373,6 +492,7 @@ jobs:
373492 needs :
374493 - version
375494 - build-cli
495+ - sign-cli-windows
376496 - build-tauri
377497 - build-electron
378498 runs-on : blacksmith-4vcpu-ubuntu-2404
@@ -411,6 +531,11 @@ jobs:
411531 name : opencode-cli
412532 path : packages/opencode/dist
413533
534+ - uses : actions/download-artifact@v4
535+ with :
536+ name : opencode-cli-signed-windows
537+ path : packages/opencode/dist
538+
414539 - uses : actions/download-artifact@v4
415540 if : needs.version.outputs.release
416541 with :
0 commit comments