@@ -98,15 +98,129 @@ jobs:
9898 - uses : actions/upload-artifact@v4
9999 with :
100100 name : opencode-cli
101- path : packages/opencode/dist
101+ path : |
102+ packages/opencode/dist/opencode-darwin*
103+ packages/opencode/dist/opencode-linux*
104+
105+ - uses : actions/upload-artifact@v4
106+ with :
107+ name : opencode-cli-windows
108+ path : packages/opencode/dist/opencode-windows*
102109 outputs :
103110 version : ${{ needs.version.outputs.version }}
104111
112+ sign-cli-windows :
113+ needs :
114+ - build-cli
115+ - version
116+ runs-on : blacksmith-4vcpu-windows-2025
117+ if : github.repository == 'anomalyco/opencode'
118+ env :
119+ AZURE_CLIENT_ID : ${{ secrets.AZURE_CLIENT_ID }}
120+ AZURE_TENANT_ID : ${{ secrets.AZURE_TENANT_ID }}
121+ AZURE_SUBSCRIPTION_ID : ${{ secrets.AZURE_SUBSCRIPTION_ID }}
122+ AZURE_TRUSTED_SIGNING_ACCOUNT_NAME : ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
123+ AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE : ${{ secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }}
124+ AZURE_TRUSTED_SIGNING_ENDPOINT : ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }}
125+ steps :
126+ - uses : actions/checkout@v3
127+
128+ - uses : actions/download-artifact@v4
129+ with :
130+ name : opencode-cli-windows
131+ path : packages/opencode/dist
132+
133+ - name : Setup git committer
134+ id : committer
135+ uses : ./.github/actions/setup-git-committer
136+ with :
137+ opencode-app-id : ${{ vars.OPENCODE_APP_ID }}
138+ opencode-app-secret : ${{ secrets.OPENCODE_APP_SECRET }}
139+
140+ - name : Azure login
141+ uses : azure/login@v2
142+ with :
143+ client-id : ${{ env.AZURE_CLIENT_ID }}
144+ tenant-id : ${{ env.AZURE_TENANT_ID }}
145+ subscription-id : ${{ env.AZURE_SUBSCRIPTION_ID }}
146+
147+ - uses : azure/artifact-signing-action@v1
148+ with :
149+ endpoint : ${{ env.AZURE_TRUSTED_SIGNING_ENDPOINT }}
150+ signing-account-name : ${{ env.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
151+ certificate-profile-name : ${{ env.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }}
152+ files : |
153+ ${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe
154+ ${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe
155+ ${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe
156+ exclude-environment-credential : true
157+ exclude-workload-identity-credential : true
158+ exclude-managed-identity-credential : true
159+ exclude-shared-token-cache-credential : true
160+ exclude-visual-studio-credential : true
161+ exclude-visual-studio-code-credential : true
162+ exclude-azure-cli-credential : false
163+ exclude-azure-powershell-credential : true
164+ exclude-azure-developer-cli-credential : true
165+ exclude-interactive-browser-credential : true
166+
167+ - name : Verify Windows CLI signatures
168+ shell : pwsh
169+ run : |
170+ $files = @(
171+ "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe",
172+ "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe",
173+ "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe"
174+ )
175+
176+ foreach ($file in $files) {
177+ $sig = Get-AuthenticodeSignature $file
178+ if ($sig.Status -ne "Valid") {
179+ throw "Invalid signature for ${file}: $($sig.Status)"
180+ }
181+ }
182+
183+ - name : Repack Windows CLI archives
184+ working-directory : packages/opencode/dist
185+ shell : pwsh
186+ run : |
187+ Compress-Archive -Path "opencode-windows-arm64\bin\*" -DestinationPath "opencode-windows-arm64.zip" -Force
188+ Compress-Archive -Path "opencode-windows-x64\bin\*" -DestinationPath "opencode-windows-x64.zip" -Force
189+ Compress-Archive -Path "opencode-windows-x64-baseline\bin\*" -DestinationPath "opencode-windows-x64-baseline.zip" -Force
190+
191+ - name : Upload signed Windows CLI release assets
192+ if : needs.version.outputs.release != ''
193+ shell : pwsh
194+ env :
195+ GH_TOKEN : ${{ steps.committer.outputs.token }}
196+ run : |
197+ gh release upload "v${{ needs.version.outputs.version }}" `
198+ "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64.zip" `
199+ "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64.zip" `
200+ "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline.zip" `
201+ --clobber `
202+ --repo "${{ needs.version.outputs.repo }}"
203+
204+ - uses : actions/upload-artifact@v4
205+ with :
206+ name : opencode-cli-signed-windows
207+ path : |
208+ packages/opencode/dist/opencode-windows-arm64
209+ packages/opencode/dist/opencode-windows-x64
210+ packages/opencode/dist/opencode-windows-x64-baseline
211+
105212 build-tauri :
106213 needs :
107214 - build-cli
108215 - version
109216 continue-on-error : false
217+ env :
218+ AZURE_CLIENT_ID : ${{ secrets.AZURE_CLIENT_ID }}
219+ AZURE_TENANT_ID : ${{ secrets.AZURE_TENANT_ID }}
220+ AZURE_SUBSCRIPTION_ID : ${{ secrets.AZURE_SUBSCRIPTION_ID }}
221+ AZURE_TRUSTED_SIGNING_ACCOUNT_NAME : ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
222+ AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE : ${{ secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }}
223+ AZURE_TRUSTED_SIGNING_ENDPOINT : ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }}
110224 strategy :
111225 fail-fast : false
112226 matrix :
@@ -152,6 +266,14 @@ jobs:
152266
153267 - uses : ./.github/actions/setup-bun
154268
269+ - name : Azure login
270+ if : runner.os == 'Windows'
271+ uses : azure/login@v2
272+ with :
273+ client-id : ${{ env.AZURE_CLIENT_ID }}
274+ tenant-id : ${{ env.AZURE_TENANT_ID }}
275+ subscription-id : ${{ env.AZURE_SUBSCRIPTION_ID }}
276+
155277 - uses : actions/setup-node@v4
156278 with :
157279 node-version : " 24"
@@ -190,6 +312,7 @@ jobs:
190312 env :
191313 OPENCODE_VERSION : ${{ needs.version.outputs.version }}
192314 GITHUB_TOKEN : ${{ steps.committer.outputs.token }}
315+ OPENCODE_CLI_ARTIFACT : ${{ (runner.os == 'Windows' && 'opencode-cli-windows') || 'opencode-cli' }}
193316 RUST_TARGET : ${{ matrix.settings.target }}
194317 GH_TOKEN : ${{ github.token }}
195318 GITHUB_RUN_ID : ${{ github.run_id }}
@@ -246,11 +369,34 @@ jobs:
246369 APPLE_API_KEY : ${{ secrets.APPLE_API_KEY }}
247370 APPLE_API_KEY_PATH : ${{ runner.temp }}/apple-api-key.p8
248371
372+ - name : Verify signed Windows desktop artifacts
373+ if : runner.os == 'Windows'
374+ shell : pwsh
375+ run : |
376+ $files = @(
377+ "${{ github.workspace }}\packages\desktop\src-tauri\sidecars\opencode-cli-${{ matrix.settings.target }}.exe"
378+ )
379+ $files += Get-ChildItem "${{ github.workspace }}\packages\desktop\src-tauri\target\${{ matrix.settings.target }}\release\bundle\nsis\*.exe" | Select-Object -ExpandProperty FullName
380+
381+ foreach ($file in $files) {
382+ $sig = Get-AuthenticodeSignature $file
383+ if ($sig.Status -ne "Valid") {
384+ throw "Invalid signature for ${file}: $($sig.Status)"
385+ }
386+ }
387+
249388 build-electron :
250389 needs :
251390 - build-cli
252391 - version
253392 continue-on-error : false
393+ env :
394+ AZURE_CLIENT_ID : ${{ secrets.AZURE_CLIENT_ID }}
395+ AZURE_TENANT_ID : ${{ secrets.AZURE_TENANT_ID }}
396+ AZURE_SUBSCRIPTION_ID : ${{ secrets.AZURE_SUBSCRIPTION_ID }}
397+ AZURE_TRUSTED_SIGNING_ACCOUNT_NAME : ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
398+ AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE : ${{ secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }}
399+ AZURE_TRUSTED_SIGNING_ENDPOINT : ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }}
254400 strategy :
255401 fail-fast : false
256402 matrix :
@@ -292,6 +438,14 @@ jobs:
292438
293439 - uses : ./.github/actions/setup-bun
294440
441+ - name : Azure login
442+ if : runner.os == 'Windows'
443+ uses : azure/login@v2
444+ with :
445+ client-id : ${{ env.AZURE_CLIENT_ID }}
446+ tenant-id : ${{ env.AZURE_TENANT_ID }}
447+ subscription-id : ${{ env.AZURE_SUBSCRIPTION_ID }}
448+
295449 - uses : actions/setup-node@v4
296450 with :
297451 node-version : " 24"
@@ -326,6 +480,7 @@ jobs:
326480 env :
327481 OPENCODE_VERSION : ${{ needs.version.outputs.version }}
328482 OPENCODE_CHANNEL : ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
483+ OPENCODE_CLI_ARTIFACT : ${{ (runner.os == 'Windows' && 'opencode-cli-windows') || 'opencode-cli' }}
329484 RUST_TARGET : ${{ matrix.settings.target }}
330485 GH_TOKEN : ${{ github.token }}
331486 GITHUB_RUN_ID : ${{ github.run_id }}
@@ -358,6 +513,22 @@ jobs:
358513 env :
359514 OPENCODE_CHANNEL : ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
360515
516+ - name : Verify signed Windows Electron artifacts
517+ if : runner.os == 'Windows'
518+ shell : pwsh
519+ run : |
520+ $files = @()
521+ $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*.exe" | Select-Object -ExpandProperty FullName
522+ $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*unpacked\*.exe" | Select-Object -ExpandProperty FullName
523+ $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*unpacked\resources\opencode-cli.exe" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
524+
525+ foreach ($file in $files | Select-Object -Unique) {
526+ $sig = Get-AuthenticodeSignature $file
527+ if ($sig.Status -ne "Valid") {
528+ throw "Invalid signature for ${file}: $($sig.Status)"
529+ }
530+ }
531+
361532 - uses : actions/upload-artifact@v4
362533 with :
363534 name : opencode-electron-${{ matrix.settings.target }}
@@ -373,6 +544,7 @@ jobs:
373544 needs :
374545 - version
375546 - build-cli
547+ - sign-cli-windows
376548 - build-tauri
377549 - build-electron
378550 runs-on : blacksmith-4vcpu-ubuntu-2404
@@ -411,6 +583,16 @@ jobs:
411583 name : opencode-cli
412584 path : packages/opencode/dist
413585
586+ - uses : actions/download-artifact@v4
587+ with :
588+ name : opencode-cli-windows
589+ path : packages/opencode/dist
590+
591+ - uses : actions/download-artifact@v4
592+ with :
593+ name : opencode-cli-signed-windows
594+ path : packages/opencode/dist
595+
414596 - uses : actions/download-artifact@v4
415597 if : needs.version.outputs.release
416598 with :
0 commit comments