From 582f69ed1710d49cafa246fb94b3f3b1eee91c75 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Thu, 26 Feb 2026 21:19:08 +1000 Subject: [PATCH 01/13] feat(ci): sign Windows CLI and desktop builds --- .github/workflows/publish.yml | 131 ++++++++++++++++++ .github/workflows/sign-cli.yml | 54 -------- packages/desktop/scripts/prepare.ts | 3 +- .../desktop/src-tauri/tauri.beta.conf.json | 4 + packages/desktop/src-tauri/tauri.conf.json | 4 + .../desktop/src-tauri/tauri.prod.conf.json | 4 + script/sign-windows.ps1 | 51 +++++++ 7 files changed, 196 insertions(+), 55 deletions(-) delete mode 100644 .github/workflows/sign-cli.yml create mode 100644 script/sign-windows.ps1 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8d4c9038a7e4..83106e47b6d7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -103,9 +103,93 @@ jobs: outputs: version: ${{ needs.version.outputs.version }} + sign-cli-windows: + needs: + - build-cli + - version + runs-on: blacksmith-4vcpu-windows-2025 + if: github.repository == 'anomalyco/opencode' + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: "10.0.x" + + - name: Install sign tool + shell: pwsh + run: | + dotnet tool install --tool-path "$env:RUNNER_TEMP\sign" --prerelease sign + "$env:RUNNER_TEMP\sign" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Azure login + uses: azure/login@v2 + with: + client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} + subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} + + - uses: actions/download-artifact@v4 + with: + name: opencode-cli + path: packages/opencode/dist + + - name: Sign Windows CLI binaries + shell: pwsh + env: + AZURE_TRUSTED_SIGNING_ACCOUNT_NAME: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} + AZURE_TRUSTED_SIGNING_ENDPOINT: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} + run: | + ./script/sign-windows.ps1 ` + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe" ` + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe" + + - name: Verify Windows CLI signatures + shell: pwsh + run: | + $files = @( + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe", + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe" + ) + + foreach ($file in $files) { + $sig = Get-AuthenticodeSignature $file + if ($sig.Status -ne "Valid") { + throw "Invalid signature for ${file}: $($sig.Status)" + } + } + + - name: Repack Windows CLI archives + shell: pwsh + working-directory: packages/opencode/dist + run: | + Compress-Archive -Path "opencode-windows-x64\bin\*" -DestinationPath "opencode-windows-x64.zip" -Force + Compress-Archive -Path "opencode-windows-x64-baseline\bin\*" -DestinationPath "opencode-windows-x64-baseline.zip" -Force + + - name: Upload signed Windows CLI release assets + if: needs.version.outputs.release != '' + shell: pwsh + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release upload "v${{ needs.version.outputs.version }}" ` + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64.zip" ` + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline.zip" ` + --clobber ` + --repo "${{ needs.version.outputs.repo }}" + + - uses: actions/upload-artifact@v4 + with: + name: opencode-cli-signed-windows + path: | + packages/opencode/dist/opencode-windows-x64 + packages/opencode/dist/opencode-windows-x64-baseline + build-tauri: needs: - build-cli + - sign-cli-windows - version continue-on-error: false strategy: @@ -150,6 +234,26 @@ jobs: - uses: ./.github/actions/setup-bun + - uses: actions/setup-dotnet@v4 + if: runner.os == 'Windows' + with: + dotnet-version: "10.0.x" + + - name: Install sign tool + if: runner.os == 'Windows' + shell: pwsh + run: | + dotnet tool install --tool-path "$env:RUNNER_TEMP\sign" --prerelease sign + "$env:RUNNER_TEMP\sign" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Azure login + if: runner.os == 'Windows' + uses: azure/login@v2 + with: + client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} + subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} + - name: Cache apt packages if: contains(matrix.settings.host, 'ubuntu') uses: actions/cache@v4 @@ -184,6 +288,7 @@ jobs: env: OPENCODE_VERSION: ${{ needs.version.outputs.version }} GITHUB_TOKEN: ${{ steps.committer.outputs.token }} + OPENCODE_CLI_ARTIFACT: ${{ (runner.os == 'Windows' && 'opencode-cli-signed-windows') || 'opencode-cli' }} RUST_TARGET: ${{ matrix.settings.target }} GH_TOKEN: ${{ github.token }} GITHUB_RUN_ID: ${{ github.run_id }} @@ -230,6 +335,9 @@ jobs: releaseCommitish: ${{ github.sha }} env: GITHUB_TOKEN: ${{ steps.committer.outputs.token }} + AZURE_TRUSTED_SIGNING_ACCOUNT_NAME: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} + AZURE_TRUSTED_SIGNING_ENDPOINT: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} TAURI_BUNDLER_NEW_APPIMAGE_FORMAT: true TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} @@ -240,10 +348,28 @@ jobs: APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} APPLE_API_KEY_PATH: ${{ runner.temp }}/apple-api-key.p8 + - name: Verify signed Windows desktop artifacts + if: runner.os == 'Windows' + shell: pwsh + run: | + $files = @( + "${{ github.workspace }}\packages\desktop\src-tauri\sidecars\opencode-cli-${{ matrix.settings.target }}.exe", + "${{ github.workspace }}\packages\desktop\src-tauri\target\${{ matrix.settings.target }}\release\OpenCode.exe" + ) + $files += Get-ChildItem "${{ github.workspace }}\packages\desktop\src-tauri\target\${{ matrix.settings.target }}\release\bundle\nsis\*.exe" | Select-Object -ExpandProperty FullName + + foreach ($file in $files) { + $sig = Get-AuthenticodeSignature $file + if ($sig.Status -ne "Valid") { + throw "Invalid signature for ${file}: $($sig.Status)" + } + } + publish: needs: - version - build-cli + - sign-cli-windows - build-tauri runs-on: blacksmith-4vcpu-ubuntu-2404 steps: @@ -281,6 +407,11 @@ jobs: name: opencode-cli path: packages/opencode/dist + - uses: actions/download-artifact@v4 + with: + name: opencode-cli-signed-windows + path: packages/opencode/dist + - name: Cache apt packages (AUR) uses: actions/cache@v4 with: diff --git a/.github/workflows/sign-cli.yml b/.github/workflows/sign-cli.yml deleted file mode 100644 index d9d61fd800eb..000000000000 --- a/.github/workflows/sign-cli.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: sign-cli - -on: - push: - branches: - - brendan/desktop-signpath - workflow_dispatch: - -permissions: - contents: read - actions: read - -jobs: - sign-cli: - runs-on: blacksmith-4vcpu-ubuntu-2404 - if: github.repository == 'anomalyco/opencode' - steps: - - uses: actions/checkout@v3 - with: - fetch-tags: true - - - uses: ./.github/actions/setup-bun - - - name: Build - run: | - ./packages/opencode/script/build.ts - - - name: Upload unsigned Windows CLI - id: upload_unsigned_windows_cli - uses: actions/upload-artifact@v4 - with: - name: unsigned-opencode-windows-cli - path: packages/opencode/dist/opencode-windows-x64/bin/opencode.exe - if-no-files-found: error - - - name: Submit SignPath signing request - id: submit_signpath_signing_request - uses: signpath/github-action-submit-signing-request@v1 - with: - api-token: ${{ secrets.SIGNPATH_API_KEY }} - organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }} - project-slug: ${{ secrets.SIGNPATH_PROJECT_SLUG }} - signing-policy-slug: ${{ secrets.SIGNPATH_SIGNING_POLICY_SLUG }} - artifact-configuration-slug: ${{ secrets.SIGNPATH_ARTIFACT_CONFIGURATION_SLUG }} - github-artifact-id: ${{ steps.upload_unsigned_windows_cli.outputs.artifact-id }} - wait-for-completion: true - output-artifact-directory: signed-opencode-cli - - - name: Upload signed Windows CLI - uses: actions/upload-artifact@v4 - with: - name: signed-opencode-windows-cli - path: signed-opencode-cli/*.exe - if-no-files-found: error diff --git a/packages/desktop/scripts/prepare.ts b/packages/desktop/scripts/prepare.ts index d802f2d89eeb..dc2c793f349b 100755 --- a/packages/desktop/scripts/prepare.ts +++ b/packages/desktop/scripts/prepare.ts @@ -10,10 +10,11 @@ await Bun.write("./package.json", JSON.stringify(pkg, null, 2) + "\n") console.log(`Updated package.json version to ${Script.version}`) const sidecarConfig = getCurrentSidecar() +const artifact = Bun.env.OPENCODE_CLI_ARTIFACT ?? "opencode-cli" const dir = "src-tauri/target/opencode-binaries" await $`mkdir -p ${dir}` -await $`gh run download ${Bun.env.GITHUB_RUN_ID} -n opencode-cli`.cwd(dir) +await $`gh run download ${Bun.env.GITHUB_RUN_ID} -n ${artifact}`.cwd(dir) await copyBinaryToSidecarFolder(windowsify(`${dir}/${sidecarConfig.ocBinary}/bin/opencode`)) diff --git a/packages/desktop/src-tauri/tauri.beta.conf.json b/packages/desktop/src-tauri/tauri.beta.conf.json index 4dd7879933c6..f2cf1d267e7b 100644 --- a/packages/desktop/src-tauri/tauri.beta.conf.json +++ b/packages/desktop/src-tauri/tauri.beta.conf.json @@ -12,6 +12,10 @@ "icons/beta/icon.ico" ], "windows": { + "signCommand": { + "cmd": "powershell", + "args": ["-ExecutionPolicy", "Bypass", "-File", "../../../script/sign-windows.ps1", "%1"] + }, "nsis": { "installerIcon": "icons/beta/icon.ico" } diff --git a/packages/desktop/src-tauri/tauri.conf.json b/packages/desktop/src-tauri/tauri.conf.json index d5ca15b8a71b..265044625b1c 100644 --- a/packages/desktop/src-tauri/tauri.conf.json +++ b/packages/desktop/src-tauri/tauri.conf.json @@ -45,6 +45,10 @@ "entitlements": "./entitlements.plist" }, "windows": { + "signCommand": { + "cmd": "powershell", + "args": ["-ExecutionPolicy", "Bypass", "-File", "../../../script/sign-windows.ps1", "%1"] + }, "nsis": { "installerIcon": "icons/dev/icon.ico", "headerImage": "assets/nsis-header.bmp", diff --git a/packages/desktop/src-tauri/tauri.prod.conf.json b/packages/desktop/src-tauri/tauri.prod.conf.json index 0416c59cbb9f..39561e45dc63 100644 --- a/packages/desktop/src-tauri/tauri.prod.conf.json +++ b/packages/desktop/src-tauri/tauri.prod.conf.json @@ -12,6 +12,10 @@ "icons/prod/icon.ico" ], "windows": { + "signCommand": { + "cmd": "powershell", + "args": ["-ExecutionPolicy", "Bypass", "-File", "../../../script/sign-windows.ps1", "%1"] + }, "nsis": { "installerIcon": "icons/prod/icon.ico" } diff --git a/script/sign-windows.ps1 b/script/sign-windows.ps1 new file mode 100644 index 000000000000..c39ae3d65916 --- /dev/null +++ b/script/sign-windows.ps1 @@ -0,0 +1,51 @@ +param( + [Parameter(ValueFromRemainingArguments = $true)] + [string[]] $Path +) + +$ErrorActionPreference = "Stop" + +if (-not $Path -or $Path.Count -eq 0) { + throw "At least one path is required" +} + +$vars = @{ + endpoint = $env:AZURE_TRUSTED_SIGNING_ENDPOINT + account = $env:AZURE_TRUSTED_SIGNING_ACCOUNT_NAME + profile = $env:AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE +} + +if ($vars.Values | Where-Object { -not $_ }) { + Write-Host "Skipping Windows signing because Trusted Signing is not configured" + exit 0 +} + +if (-not (Get-Command sign -ErrorAction SilentlyContinue)) { + Write-Host "Skipping Windows signing because sign was not found on PATH" + exit 0 +} + +$files = $Path | ForEach-Object { Resolve-Path $_ } | Select-Object -ExpandProperty Path -Unique + +if (-not $files -or $files.Count -eq 0) { + throw "No files matched the requested paths" +} + +$groups = $files | Group-Object { Split-Path $_ -Parent } + +foreach ($group in $groups) { + $dir = $group.Name + $names = $group.Group | ForEach-Object { Split-Path $_ -Leaf } + + & sign code trusted-signing ` + -b $dir ` + -tse $vars.endpoint ` + -tscp $vars.profile ` + -tsa $vars.account ` + @names ` + -v Information + + if ($LASTEXITCODE -ne 0) { + throw "Trusted Signing failed for $($group.Name)" + } +} From d3cb3c9e176f04959bf4bef17ea99444a7eca620 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 06:29:01 +1000 Subject: [PATCH 02/13] fix(ci): use signed Windows CLI artifacts for desktop releases Include the ARM64 Windows CLI build in Trusted Signing outputs and route Windows Electron packaging through the signed artifact so beta and production desktop releases ship the expected signed sidecar. --- .github/workflows/publish.yml | 7 +++++++ packages/desktop-electron/scripts/prepare.ts | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b0008b106ef6..1075777b3af5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -141,6 +141,7 @@ jobs: AZURE_TRUSTED_SIGNING_ENDPOINT: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} run: | ./script/sign-windows.ps1 ` + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe" ` "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe" ` "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe" @@ -148,6 +149,7 @@ jobs: shell: pwsh run: | $files = @( + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe", "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe", "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe" ) @@ -163,6 +165,7 @@ jobs: shell: pwsh working-directory: packages/opencode/dist run: | + Compress-Archive -Path "opencode-windows-arm64\bin\*" -DestinationPath "opencode-windows-arm64.zip" -Force Compress-Archive -Path "opencode-windows-x64\bin\*" -DestinationPath "opencode-windows-x64.zip" -Force Compress-Archive -Path "opencode-windows-x64-baseline\bin\*" -DestinationPath "opencode-windows-x64-baseline.zip" -Force @@ -173,6 +176,7 @@ jobs: GH_TOKEN: ${{ github.token }} run: | gh release upload "v${{ needs.version.outputs.version }}" ` + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64.zip" ` "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64.zip" ` "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline.zip" ` --clobber ` @@ -182,6 +186,7 @@ jobs: with: name: opencode-cli-signed-windows path: | + packages/opencode/dist/opencode-windows-arm64 packages/opencode/dist/opencode-windows-x64 packages/opencode/dist/opencode-windows-x64-baseline @@ -374,6 +379,7 @@ jobs: build-electron: needs: - build-cli + - sign-cli-windows - version continue-on-error: false strategy: @@ -451,6 +457,7 @@ jobs: env: OPENCODE_VERSION: ${{ needs.version.outputs.version }} OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }} + OPENCODE_CLI_ARTIFACT: ${{ (runner.os == 'Windows' && 'opencode-cli-signed-windows') || 'opencode-cli' }} RUST_TARGET: ${{ matrix.settings.target }} GH_TOKEN: ${{ github.token }} GITHUB_RUN_ID: ${{ github.run_id }} diff --git a/packages/desktop-electron/scripts/prepare.ts b/packages/desktop-electron/scripts/prepare.ts index 3764db921063..2c786a97efb5 100755 --- a/packages/desktop-electron/scripts/prepare.ts +++ b/packages/desktop-electron/scripts/prepare.ts @@ -13,11 +13,12 @@ await Bun.write("./package.json", JSON.stringify(pkg, null, 2) + "\n") console.log(`Updated package.json version to ${Script.version}`) const sidecarConfig = getCurrentSidecar() +const artifact = Bun.env.OPENCODE_CLI_ARTIFACT ?? "opencode-cli" const dir = "resources/opencode-binaries" await $`mkdir -p ${dir}` -await $`gh run download ${Bun.env.GITHUB_RUN_ID} -n opencode-cli`.cwd(dir) +await $`gh run download ${Bun.env.GITHUB_RUN_ID} -n ${artifact}`.cwd(dir) await copyBinaryToSidecarFolder(windowsify(`${dir}/${sidecarConfig.ocBinary}/bin/opencode`)) From 1bd67034857e64cee37f48ea96cd2a882e6f3c61 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 06:38:06 +1000 Subject: [PATCH 03/13] refactor(ci): extract Windows trusted signing action Move the repeated Azure Trusted Signing setup and verification into a reusable repo action so the CLI signing job and Windows desktop packaging share the same signing configuration. --- .../windows-trusted-signing/action.yml | 73 ++++++++++++++++ .github/workflows/publish.yml | 85 +++++-------------- 2 files changed, 93 insertions(+), 65 deletions(-) create mode 100644 .github/actions/windows-trusted-signing/action.yml diff --git a/.github/actions/windows-trusted-signing/action.yml b/.github/actions/windows-trusted-signing/action.yml new file mode 100644 index 000000000000..edf52cb518a6 --- /dev/null +++ b/.github/actions/windows-trusted-signing/action.yml @@ -0,0 +1,73 @@ +name: "Windows Trusted Signing" +description: "Set up Azure Trusted Signing and optionally sign Windows binaries" +inputs: + azure-client-id: + description: "Azure client ID for OIDC login" + required: true + azure-tenant-id: + description: "Azure tenant ID for OIDC login" + required: true + azure-subscription-id: + description: "Azure subscription ID for OIDC login" + required: true + trusted-signing-account-name: + description: "Azure Trusted Signing account name" + required: true + trusted-signing-certificate-profile: + description: "Azure Trusted Signing certificate profile" + required: true + trusted-signing-endpoint: + description: "Azure Trusted Signing endpoint" + required: true + files: + description: "Optional newline-delimited list of files to sign and verify" + required: false + default: "" +runs: + using: "composite" + steps: + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: "10.0.x" + + - name: Install sign tool + shell: pwsh + run: | + dotnet tool install --tool-path "$env:RUNNER_TEMP\sign" --prerelease sign + "$env:RUNNER_TEMP\sign" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - uses: azure/login@v2 + with: + client-id: ${{ inputs.azure-client-id }} + tenant-id: ${{ inputs.azure-tenant-id }} + subscription-id: ${{ inputs.azure-subscription-id }} + + - name: Export Trusted Signing environment + shell: pwsh + run: | + "AZURE_TRUSTED_SIGNING_ACCOUNT_NAME=${{ inputs.trusted-signing-account-name }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + "AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE=${{ inputs.trusted-signing-certificate-profile }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + "AZURE_TRUSTED_SIGNING_ENDPOINT=${{ inputs.trusted-signing-endpoint }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Sign files + if: inputs.files != '' + shell: pwsh + run: | + $files = @' +${{ inputs.files }} +'@ -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ } + & ./script/sign-windows.ps1 @files + + - name: Verify signatures + if: inputs.files != '' + shell: pwsh + run: | + $files = @' +${{ inputs.files }} +'@ -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ } + foreach ($file in $files) { + $sig = Get-AuthenticodeSignature $file + if ($sig.Status -ne "Valid") { + throw "Invalid signature for ${file}: $($sig.Status)" + } + } diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1075777b3af5..afc4ae59f50f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -111,59 +111,27 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-dotnet@v4 - with: - dotnet-version: "10.0.x" - - - name: Install sign tool - shell: pwsh - run: | - dotnet tool install --tool-path "$env:RUNNER_TEMP\sign" --prerelease sign - "$env:RUNNER_TEMP\sign" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - - name: Azure login - uses: azure/login@v2 - with: - client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} - subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} - - uses: actions/download-artifact@v4 with: name: opencode-cli path: packages/opencode/dist - - name: Sign Windows CLI binaries - shell: pwsh - env: - AZURE_TRUSTED_SIGNING_ACCOUNT_NAME: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} - AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} - AZURE_TRUSTED_SIGNING_ENDPOINT: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} - run: | - ./script/sign-windows.ps1 ` - "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe" ` - "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe" ` - "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe" - - - name: Verify Windows CLI signatures - shell: pwsh - run: | - $files = @( - "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe", - "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe", - "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe" - ) - - foreach ($file in $files) { - $sig = Get-AuthenticodeSignature $file - if ($sig.Status -ne "Valid") { - throw "Invalid signature for ${file}: $($sig.Status)" - } - } + - uses: ./.github/actions/windows-trusted-signing + with: + azure-client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} + azure-tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} + azure-subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} + trusted-signing-account-name: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + trusted-signing-certificate-profile: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} + trusted-signing-endpoint: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} + files: | + ${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe + ${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe + ${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe - name: Repack Windows CLI archives - shell: pwsh working-directory: packages/opencode/dist + shell: pwsh run: | Compress-Archive -Path "opencode-windows-arm64\bin\*" -DestinationPath "opencode-windows-arm64.zip" -Force Compress-Archive -Path "opencode-windows-x64\bin\*" -DestinationPath "opencode-windows-x64.zip" -Force @@ -241,25 +209,15 @@ jobs: - uses: ./.github/actions/setup-bun - - uses: actions/setup-dotnet@v4 - if: runner.os == 'Windows' - with: - dotnet-version: "10.0.x" - - - name: Install sign tool - if: runner.os == 'Windows' - shell: pwsh - run: | - dotnet tool install --tool-path "$env:RUNNER_TEMP\sign" --prerelease sign - "$env:RUNNER_TEMP\sign" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - - name: Azure login + - uses: ./.github/actions/windows-trusted-signing if: runner.os == 'Windows' - uses: azure/login@v2 with: - client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} - subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} + azure-client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} + azure-tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} + azure-subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} + trusted-signing-account-name: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + trusted-signing-certificate-profile: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} + trusted-signing-endpoint: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} - uses: actions/setup-node@v4 with: @@ -346,9 +304,6 @@ jobs: releaseCommitish: ${{ github.sha }} env: GITHUB_TOKEN: ${{ steps.committer.outputs.token }} - AZURE_TRUSTED_SIGNING_ACCOUNT_NAME: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} - AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} - AZURE_TRUSTED_SIGNING_ENDPOINT: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} TAURI_BUNDLER_NEW_APPIMAGE_FORMAT: true TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} From 072013d764a0ddf2b0181625c93dcfd5809134d6 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 06:42:39 +1000 Subject: [PATCH 04/13] chore(ci): remove obsolete SignPath policy Drop the leftover SignPath policy now that Windows release signing is handled through Azure Trusted Signing, so the branch no longer carries an unused signing path. --- .signpath/policies/opencode/test-signing.yml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .signpath/policies/opencode/test-signing.yml diff --git a/.signpath/policies/opencode/test-signing.yml b/.signpath/policies/opencode/test-signing.yml deleted file mode 100644 index 683b27adb754..000000000000 --- a/.signpath/policies/opencode/test-signing.yml +++ /dev/null @@ -1,5 +0,0 @@ -github-policies: - runners: - allowed_groups: - - "GitHub Actions" - - "blacksmith runners 01kbd5v56sg8tz7rea39b7ygpt" From b0ce0038de212d0a1b4b8de2cde112fdc8d28273 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 06:52:23 +1000 Subject: [PATCH 05/13] fix(ci): tighten Azure artifact signing flow Rename the reusable signing action to Azure Artifact Signing and make the Windows signing helper tolerate unmatched paths until the explicit no-files check runs. --- .github/actions/windows-trusted-signing/action.yml | 2 +- script/sign-windows.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/windows-trusted-signing/action.yml b/.github/actions/windows-trusted-signing/action.yml index edf52cb518a6..0b423e0f0947 100644 --- a/.github/actions/windows-trusted-signing/action.yml +++ b/.github/actions/windows-trusted-signing/action.yml @@ -1,4 +1,4 @@ -name: "Windows Trusted Signing" +name: "Azure Artifact Signing" description: "Set up Azure Trusted Signing and optionally sign Windows binaries" inputs: azure-client-id: diff --git a/script/sign-windows.ps1 b/script/sign-windows.ps1 index c39ae3d65916..4e47bfd94202 100644 --- a/script/sign-windows.ps1 +++ b/script/sign-windows.ps1 @@ -25,7 +25,7 @@ if (-not (Get-Command sign -ErrorAction SilentlyContinue)) { exit 0 } -$files = $Path | ForEach-Object { Resolve-Path $_ } | Select-Object -ExpandProperty Path -Unique +$files = $Path | ForEach-Object { Resolve-Path $_ -ErrorAction SilentlyContinue } | Select-Object -ExpandProperty Path -Unique if (-not $files -or $files.Count -eq 0) { throw "No files matched the requested paths" From 1c6707cfa9772f8b96a281156e1e490a324f566c Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 06:58:28 +1000 Subject: [PATCH 06/13] fix(ci): sign Windows Electron release artifacts Wire Azure Artifact Signing into the Electron packaging flow so the packaged app and installer executables are signed before publish metadata is generated, and fix the reusable signing action to handle file lists correctly. --- .../windows-trusted-signing/action.yml | 12 ++++----- .github/workflows/publish.yml | 25 +++++++++++++++++++ .../electron-builder.config.ts | 20 +++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/.github/actions/windows-trusted-signing/action.yml b/.github/actions/windows-trusted-signing/action.yml index 0b423e0f0947..5b184470e2ea 100644 --- a/.github/actions/windows-trusted-signing/action.yml +++ b/.github/actions/windows-trusted-signing/action.yml @@ -52,19 +52,19 @@ runs: - name: Sign files if: inputs.files != '' shell: pwsh + env: + INPUT_FILES: ${{ inputs.files }} run: | - $files = @' -${{ inputs.files }} -'@ -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ } + $files = $env:INPUT_FILES -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ } & ./script/sign-windows.ps1 @files - name: Verify signatures if: inputs.files != '' shell: pwsh + env: + INPUT_FILES: ${{ inputs.files }} run: | - $files = @' -${{ inputs.files }} -'@ -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ } + $files = $env:INPUT_FILES -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ } foreach ($file in $files) { $sig = Get-AuthenticodeSignature $file if ($sig.Status -ne "Valid") { diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index afc4ae59f50f..bfdc88e25106 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -378,6 +378,16 @@ jobs: - uses: ./.github/actions/setup-bun + - uses: ./.github/actions/windows-trusted-signing + if: runner.os == 'Windows' + with: + azure-client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} + azure-tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} + azure-subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} + trusted-signing-account-name: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + trusted-signing-certificate-profile: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} + trusted-signing-endpoint: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} + - uses: actions/setup-node@v4 with: node-version: "24" @@ -445,6 +455,21 @@ jobs: env: OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }} + - name: Verify signed Windows Electron artifacts + if: runner.os == 'Windows' + shell: pwsh + run: | + $files = @() + $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*.exe" | Select-Object -ExpandProperty FullName + $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*unpacked\*.exe" | Select-Object -ExpandProperty FullName + + foreach ($file in $files | Select-Object -Unique) { + $sig = Get-AuthenticodeSignature $file + if ($sig.Status -ne "Valid") { + throw "Invalid signature for ${file}: $($sig.Status)" + } + } + - uses: actions/upload-artifact@v4 with: name: opencode-electron-${{ matrix.settings.target }} diff --git a/packages/desktop-electron/electron-builder.config.ts b/packages/desktop-electron/electron-builder.config.ts index e6b4bcd2b979..be42274f9876 100644 --- a/packages/desktop-electron/electron-builder.config.ts +++ b/packages/desktop-electron/electron-builder.config.ts @@ -1,5 +1,24 @@ +import { execFile } from "node:child_process" +import path from "node:path" +import { fileURLToPath } from "node:url" +import { promisify } from "node:util" + import type { Configuration } from "electron-builder" +const execFileAsync = promisify(execFile) +const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..") +const signScript = path.join(rootDir, "script", "sign-windows.ps1") + +async function signWindows(configuration: { path: string }) { + if (process.platform !== "win32") return + + await execFileAsync( + "pwsh", + ["-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", signScript, configuration.path], + { cwd: rootDir }, + ) +} + const channel = (() => { const raw = process.env.OPENCODE_CHANNEL if (raw === "dev" || raw === "beta" || raw === "prod") return raw @@ -44,6 +63,7 @@ const getBase = (): Configuration => ({ }, win: { icon: `resources/icons/icon.ico`, + sign: signWindows, target: ["nsis"], }, nsis: { From 3f5bd3dfabdb1d60bda2fc574fa9f34430c2f9b1 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 07:21:28 +1000 Subject: [PATCH 07/13] fix(ci): repair beta Windows signing uploads Use the app token for cross-repo beta release uploads and update the Windows signing helper to use Azure Artifact Signing with stable single-file argument handling. --- .github/workflows/publish.yml | 9 ++++++++- script/sign-windows.ps1 | 16 ++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bfdc88e25106..38caf6ca2aae 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -116,6 +116,13 @@ jobs: name: opencode-cli path: packages/opencode/dist + - name: Setup git committer + id: committer + uses: ./.github/actions/setup-git-committer + with: + opencode-app-id: ${{ vars.OPENCODE_APP_ID }} + opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }} + - uses: ./.github/actions/windows-trusted-signing with: azure-client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} @@ -141,7 +148,7 @@ jobs: if: needs.version.outputs.release != '' shell: pwsh env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ steps.committer.outputs.token }} run: | gh release upload "v${{ needs.version.outputs.version }}" ` "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64.zip" ` diff --git a/script/sign-windows.ps1 b/script/sign-windows.ps1 index 4e47bfd94202..d8e160f47b6f 100644 --- a/script/sign-windows.ps1 +++ b/script/sign-windows.ps1 @@ -16,7 +16,7 @@ $vars = @{ } if ($vars.Values | Where-Object { -not $_ }) { - Write-Host "Skipping Windows signing because Trusted Signing is not configured" + Write-Host "Skipping Windows signing because Azure Artifact Signing is not configured" exit 0 } @@ -25,7 +25,7 @@ if (-not (Get-Command sign -ErrorAction SilentlyContinue)) { exit 0 } -$files = $Path | ForEach-Object { Resolve-Path $_ -ErrorAction SilentlyContinue } | Select-Object -ExpandProperty Path -Unique +$files = @($Path | ForEach-Object { Resolve-Path $_ -ErrorAction SilentlyContinue } | Select-Object -ExpandProperty Path -Unique) if (-not $files -or $files.Count -eq 0) { throw "No files matched the requested paths" @@ -35,17 +35,17 @@ $groups = $files | Group-Object { Split-Path $_ -Parent } foreach ($group in $groups) { $dir = $group.Name - $names = $group.Group | ForEach-Object { Split-Path $_ -Leaf } + $names = @($group.Group | ForEach-Object { Split-Path $_ -Leaf }) - & sign code trusted-signing ` + & sign code artifact-signing ` -b $dir ` - -tse $vars.endpoint ` - -tscp $vars.profile ` - -tsa $vars.account ` + -ase $vars.endpoint ` + -ascp $vars.profile ` + -asa $vars.account ` @names ` -v Information if ($LASTEXITCODE -ne 0) { - throw "Trusted Signing failed for $($group.Name)" + throw "Azure Artifact Signing failed for $($group.Name)" } } From 9fd0275e624da419c8f2a5ff911433c46d78182c Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 07:42:26 +1000 Subject: [PATCH 08/13] fix(ci): use valid electron-builder signing config Move the custom Windows Electron signing hook under signtoolOptions so electron-builder accepts the config and still signs the packaged app and installer during release builds. --- packages/desktop-electron/electron-builder.config.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/desktop-electron/electron-builder.config.ts b/packages/desktop-electron/electron-builder.config.ts index be42274f9876..6da90f848c62 100644 --- a/packages/desktop-electron/electron-builder.config.ts +++ b/packages/desktop-electron/electron-builder.config.ts @@ -63,7 +63,9 @@ const getBase = (): Configuration => ({ }, win: { icon: `resources/icons/icon.ico`, - sign: signWindows, + signtoolOptions: { + sign: signWindows, + }, target: ["nsis"], }, nsis: { From 628039f9f798510ee9f4ab581c4080cfa3c4c353 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 08:14:12 +1000 Subject: [PATCH 09/13] fix(ci): verify shipped Tauri Windows artifacts Stop checking the raw Cargo output after bundling and only verify the signed Windows sidecar and NSIS artifacts that Tauri actually ships. --- .github/workflows/publish.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 38caf6ca2aae..cab039d66ca4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -326,8 +326,7 @@ jobs: shell: pwsh run: | $files = @( - "${{ github.workspace }}\packages\desktop\src-tauri\sidecars\opencode-cli-${{ matrix.settings.target }}.exe", - "${{ github.workspace }}\packages\desktop\src-tauri\target\${{ matrix.settings.target }}\release\OpenCode.exe" + "${{ github.workspace }}\packages\desktop\src-tauri\sidecars\opencode-cli-${{ matrix.settings.target }}.exe" ) $files += Get-ChildItem "${{ github.workspace }}\packages\desktop\src-tauri\target\${{ matrix.settings.target }}\release\bundle\nsis\*.exe" | Select-Object -ExpandProperty FullName From 3e5092021d0b4bfdde4284f55e36bfef038ff76c Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 09:55:20 +1000 Subject: [PATCH 10/13] fix(ci): streamline Windows desktop signing artifacts Split the CLI workflow outputs so Windows signing only processes Windows binaries, stop non-Windows desktop jobs from waiting on the Windows signing job, and sign Windows desktop sidecars locally during packaging so release builds still ship signed binaries without the extra artifact handoff. --- .github/workflows/publish.yml | 23 ++++++++++++++++------ packages/desktop-electron/scripts/utils.ts | 3 +++ packages/desktop/scripts/utils.ts | 3 +++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index cab039d66ca4..c4af58eb5773 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -98,7 +98,14 @@ jobs: - uses: actions/upload-artifact@v4 with: name: opencode-cli - path: packages/opencode/dist + path: | + packages/opencode/dist/opencode-darwin* + packages/opencode/dist/opencode-linux* + + - uses: actions/upload-artifact@v4 + with: + name: opencode-cli-windows + path: packages/opencode/dist/opencode-windows* outputs: version: ${{ needs.version.outputs.version }} @@ -113,7 +120,7 @@ jobs: - uses: actions/download-artifact@v4 with: - name: opencode-cli + name: opencode-cli-windows path: packages/opencode/dist - name: Setup git committer @@ -168,7 +175,6 @@ jobs: build-tauri: needs: - build-cli - - sign-cli-windows - version continue-on-error: false strategy: @@ -264,7 +270,7 @@ jobs: env: OPENCODE_VERSION: ${{ needs.version.outputs.version }} GITHUB_TOKEN: ${{ steps.committer.outputs.token }} - OPENCODE_CLI_ARTIFACT: ${{ (runner.os == 'Windows' && 'opencode-cli-signed-windows') || 'opencode-cli' }} + OPENCODE_CLI_ARTIFACT: ${{ (runner.os == 'Windows' && 'opencode-cli-windows') || 'opencode-cli' }} RUST_TARGET: ${{ matrix.settings.target }} GH_TOKEN: ${{ github.token }} GITHUB_RUN_ID: ${{ github.run_id }} @@ -340,7 +346,6 @@ jobs: build-electron: needs: - build-cli - - sign-cli-windows - version continue-on-error: false strategy: @@ -428,7 +433,7 @@ jobs: env: OPENCODE_VERSION: ${{ needs.version.outputs.version }} OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }} - OPENCODE_CLI_ARTIFACT: ${{ (runner.os == 'Windows' && 'opencode-cli-signed-windows') || 'opencode-cli' }} + OPENCODE_CLI_ARTIFACT: ${{ (runner.os == 'Windows' && 'opencode-cli-windows') || 'opencode-cli' }} RUST_TARGET: ${{ matrix.settings.target }} GH_TOKEN: ${{ github.token }} GITHUB_RUN_ID: ${{ github.run_id }} @@ -468,6 +473,7 @@ jobs: $files = @() $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*.exe" | Select-Object -ExpandProperty FullName $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*unpacked\*.exe" | Select-Object -ExpandProperty FullName + $files += Get-ChildItem "${{ github.workspace }}\packages\desktop-electron\dist\*unpacked\resources\opencode-cli.exe" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName foreach ($file in $files | Select-Object -Unique) { $sig = Get-AuthenticodeSignature $file @@ -530,6 +536,11 @@ jobs: name: opencode-cli path: packages/opencode/dist + - uses: actions/download-artifact@v4 + with: + name: opencode-cli-windows + path: packages/opencode/dist + - uses: actions/download-artifact@v4 with: name: opencode-cli-signed-windows diff --git a/packages/desktop-electron/scripts/utils.ts b/packages/desktop-electron/scripts/utils.ts index 1c0add87d306..35603eb080ff 100644 --- a/packages/desktop-electron/scripts/utils.ts +++ b/packages/desktop-electron/scripts/utils.ts @@ -63,6 +63,9 @@ export async function copyBinaryToSidecarFolder(source: string) { await $`mkdir -p ${dir}` const dest = windowsify(`${dir}/opencode-cli`) await $`cp ${source} ${dest}` + if (process.platform === "win32") { + await $`pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File ../../script/sign-windows.ps1 ${dest}` + } if (process.platform === "darwin") await $`codesign --force --sign - ${dest}` console.log(`Copied ${source} to ${dest}`) diff --git a/packages/desktop/scripts/utils.ts b/packages/desktop/scripts/utils.ts index 06ff25946ea8..6e1662a3f070 100644 --- a/packages/desktop/scripts/utils.ts +++ b/packages/desktop/scripts/utils.ts @@ -48,6 +48,9 @@ export async function copyBinaryToSidecarFolder(source: string, target = RUST_TA await $`mkdir -p src-tauri/sidecars` const dest = windowsify(`src-tauri/sidecars/opencode-cli-${target}`) await $`cp ${source} ${dest}` + if (process.platform === "win32") { + await $`pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File ../../script/sign-windows.ps1 ${dest}` + } console.log(`Copied ${source} to ${dest}`) } From 49e674bbb7c64898c0f0aa26d056d2f1a5ed0e1d Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 10:05:58 +1000 Subject: [PATCH 11/13] fix(ci): gate Windows signing to GitHub Actions Keep local desktop dev and packaging flows from invoking Azure Artifact Signing while preserving the GitHub Actions signing path for Tauri and Electron release builds. --- packages/desktop-electron/electron-builder.config.ts | 1 + packages/desktop-electron/scripts/utils.ts | 2 +- packages/desktop/scripts/utils.ts | 2 +- script/sign-windows.ps1 | 5 +++++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/desktop-electron/electron-builder.config.ts b/packages/desktop-electron/electron-builder.config.ts index 6da90f848c62..70441d8d7f88 100644 --- a/packages/desktop-electron/electron-builder.config.ts +++ b/packages/desktop-electron/electron-builder.config.ts @@ -11,6 +11,7 @@ const signScript = path.join(rootDir, "script", "sign-windows.ps1") async function signWindows(configuration: { path: string }) { if (process.platform !== "win32") return + if (process.env.GITHUB_ACTIONS !== "true") return await execFileAsync( "pwsh", diff --git a/packages/desktop-electron/scripts/utils.ts b/packages/desktop-electron/scripts/utils.ts index 35603eb080ff..a182cbeeefc7 100644 --- a/packages/desktop-electron/scripts/utils.ts +++ b/packages/desktop-electron/scripts/utils.ts @@ -63,7 +63,7 @@ export async function copyBinaryToSidecarFolder(source: string) { await $`mkdir -p ${dir}` const dest = windowsify(`${dir}/opencode-cli`) await $`cp ${source} ${dest}` - if (process.platform === "win32") { + if (process.platform === "win32" && Bun.env.GITHUB_ACTIONS === "true") { await $`pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File ../../script/sign-windows.ps1 ${dest}` } if (process.platform === "darwin") await $`codesign --force --sign - ${dest}` diff --git a/packages/desktop/scripts/utils.ts b/packages/desktop/scripts/utils.ts index 6e1662a3f070..de042624aa92 100644 --- a/packages/desktop/scripts/utils.ts +++ b/packages/desktop/scripts/utils.ts @@ -48,7 +48,7 @@ export async function copyBinaryToSidecarFolder(source: string, target = RUST_TA await $`mkdir -p src-tauri/sidecars` const dest = windowsify(`src-tauri/sidecars/opencode-cli-${target}`) await $`cp ${source} ${dest}` - if (process.platform === "win32") { + if (process.platform === "win32" && Bun.env.GITHUB_ACTIONS === "true") { await $`pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File ../../script/sign-windows.ps1 ${dest}` } diff --git a/script/sign-windows.ps1 b/script/sign-windows.ps1 index d8e160f47b6f..2ddcbed43beb 100644 --- a/script/sign-windows.ps1 +++ b/script/sign-windows.ps1 @@ -9,6 +9,11 @@ if (-not $Path -or $Path.Count -eq 0) { throw "At least one path is required" } +if ($env:GITHUB_ACTIONS -ne "true") { + Write-Host "Skipping Windows signing because this is not running on GitHub Actions" + exit 0 +} + $vars = @{ endpoint = $env:AZURE_TRUSTED_SIGNING_ENDPOINT account = $env:AZURE_TRUSTED_SIGNING_ACCOUNT_NAME From d9714eac492089cffe341773048f6a7fc4c6c298 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 10:36:47 +1000 Subject: [PATCH 12/13] refactor(ci): use Azure signing action directly Replace the thin repo wrapper with Azure's maintained artifact-signing action for the CLI signing job, inline Windows Azure login in packaging jobs, and move the packaging hook script onto the TrustedSigning module path. --- .../windows-trusted-signing/action.yml | 73 --------------- .github/workflows/publish.yml | 89 ++++++++++++++----- script/sign-windows.ps1 | 54 ++++++----- 3 files changed, 102 insertions(+), 114 deletions(-) delete mode 100644 .github/actions/windows-trusted-signing/action.yml diff --git a/.github/actions/windows-trusted-signing/action.yml b/.github/actions/windows-trusted-signing/action.yml deleted file mode 100644 index 5b184470e2ea..000000000000 --- a/.github/actions/windows-trusted-signing/action.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: "Azure Artifact Signing" -description: "Set up Azure Trusted Signing and optionally sign Windows binaries" -inputs: - azure-client-id: - description: "Azure client ID for OIDC login" - required: true - azure-tenant-id: - description: "Azure tenant ID for OIDC login" - required: true - azure-subscription-id: - description: "Azure subscription ID for OIDC login" - required: true - trusted-signing-account-name: - description: "Azure Trusted Signing account name" - required: true - trusted-signing-certificate-profile: - description: "Azure Trusted Signing certificate profile" - required: true - trusted-signing-endpoint: - description: "Azure Trusted Signing endpoint" - required: true - files: - description: "Optional newline-delimited list of files to sign and verify" - required: false - default: "" -runs: - using: "composite" - steps: - - uses: actions/setup-dotnet@v4 - with: - dotnet-version: "10.0.x" - - - name: Install sign tool - shell: pwsh - run: | - dotnet tool install --tool-path "$env:RUNNER_TEMP\sign" --prerelease sign - "$env:RUNNER_TEMP\sign" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - - uses: azure/login@v2 - with: - client-id: ${{ inputs.azure-client-id }} - tenant-id: ${{ inputs.azure-tenant-id }} - subscription-id: ${{ inputs.azure-subscription-id }} - - - name: Export Trusted Signing environment - shell: pwsh - run: | - "AZURE_TRUSTED_SIGNING_ACCOUNT_NAME=${{ inputs.trusted-signing-account-name }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - "AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE=${{ inputs.trusted-signing-certificate-profile }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - "AZURE_TRUSTED_SIGNING_ENDPOINT=${{ inputs.trusted-signing-endpoint }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Sign files - if: inputs.files != '' - shell: pwsh - env: - INPUT_FILES: ${{ inputs.files }} - run: | - $files = $env:INPUT_FILES -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ } - & ./script/sign-windows.ps1 @files - - - name: Verify signatures - if: inputs.files != '' - shell: pwsh - env: - INPUT_FILES: ${{ inputs.files }} - run: | - $files = $env:INPUT_FILES -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ } - foreach ($file in $files) { - $sig = Get-AuthenticodeSignature $file - if ($sig.Status -ne "Valid") { - throw "Invalid signature for ${file}: $($sig.Status)" - } - } diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c4af58eb5773..276e07748d7d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -115,6 +115,13 @@ jobs: - version runs-on: blacksmith-4vcpu-windows-2025 if: github.repository == 'anomalyco/opencode' + env: + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + AZURE_TRUSTED_SIGNING_ACCOUNT_NAME: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE: ${{ secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} + AZURE_TRUSTED_SIGNING_ENDPOINT: ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} steps: - uses: actions/checkout@v3 @@ -130,18 +137,48 @@ jobs: opencode-app-id: ${{ vars.OPENCODE_APP_ID }} opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }} - - uses: ./.github/actions/windows-trusted-signing + - name: Azure login + uses: azure/login@v2 with: - azure-client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} - azure-tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} - azure-subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} - trusted-signing-account-name: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} - trusted-signing-certificate-profile: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} - trusted-signing-endpoint: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} + client-id: ${{ env.AZURE_CLIENT_ID }} + tenant-id: ${{ env.AZURE_TENANT_ID }} + subscription-id: ${{ env.AZURE_SUBSCRIPTION_ID }} + + - uses: azure/artifact-signing-action@v1 + with: + endpoint: ${{ env.AZURE_TRUSTED_SIGNING_ENDPOINT }} + signing-account-name: ${{ env.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + certificate-profile-name: ${{ env.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} files: | ${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe ${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe ${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe + exclude-environment-credential: true + exclude-workload-identity-credential: true + exclude-managed-identity-credential: true + exclude-shared-token-cache-credential: true + exclude-visual-studio-credential: true + exclude-visual-studio-code-credential: true + exclude-azure-cli-credential: false + exclude-azure-powershell-credential: true + exclude-azure-developer-cli-credential: true + exclude-interactive-browser-credential: true + + - name: Verify Windows CLI signatures + shell: pwsh + run: | + $files = @( + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-arm64\bin\opencode.exe", + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe", + "${{ github.workspace }}\packages\opencode\dist\opencode-windows-x64-baseline\bin\opencode.exe" + ) + + foreach ($file in $files) { + $sig = Get-AuthenticodeSignature $file + if ($sig.Status -ne "Valid") { + throw "Invalid signature for ${file}: $($sig.Status)" + } + } - name: Repack Windows CLI archives working-directory: packages/opencode/dist @@ -177,6 +214,13 @@ jobs: - build-cli - version continue-on-error: false + env: + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + AZURE_TRUSTED_SIGNING_ACCOUNT_NAME: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE: ${{ secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} + AZURE_TRUSTED_SIGNING_ENDPOINT: ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} strategy: fail-fast: false matrix: @@ -222,15 +266,13 @@ jobs: - uses: ./.github/actions/setup-bun - - uses: ./.github/actions/windows-trusted-signing + - name: Azure login if: runner.os == 'Windows' + uses: azure/login@v2 with: - azure-client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} - azure-tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} - azure-subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} - trusted-signing-account-name: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} - trusted-signing-certificate-profile: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} - trusted-signing-endpoint: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} + client-id: ${{ env.AZURE_CLIENT_ID }} + tenant-id: ${{ env.AZURE_TENANT_ID }} + subscription-id: ${{ env.AZURE_SUBSCRIPTION_ID }} - uses: actions/setup-node@v4 with: @@ -348,6 +390,13 @@ jobs: - build-cli - version continue-on-error: false + env: + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + AZURE_TRUSTED_SIGNING_ACCOUNT_NAME: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE: ${{ secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} + AZURE_TRUSTED_SIGNING_ENDPOINT: ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} strategy: fail-fast: false matrix: @@ -389,15 +438,13 @@ jobs: - uses: ./.github/actions/setup-bun - - uses: ./.github/actions/windows-trusted-signing + - name: Azure login if: runner.os == 'Windows' + uses: azure/login@v2 with: - azure-client-id: ${{ vars.AZURE_CLIENT_ID || secrets.AZURE_CLIENT_ID }} - azure-tenant-id: ${{ vars.AZURE_TENANT_ID || secrets.AZURE_TENANT_ID }} - azure-subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID || secrets.AZURE_SUBSCRIPTION_ID }} - trusted-signing-account-name: ${{ vars.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} - trusted-signing-certificate-profile: ${{ vars.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE || secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} - trusted-signing-endpoint: ${{ vars.AZURE_TRUSTED_SIGNING_ENDPOINT || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} + client-id: ${{ env.AZURE_CLIENT_ID }} + tenant-id: ${{ env.AZURE_TENANT_ID }} + subscription-id: ${{ env.AZURE_SUBSCRIPTION_ID }} - uses: actions/setup-node@v4 with: diff --git a/script/sign-windows.ps1 b/script/sign-windows.ps1 index 2ddcbed43beb..aaf2a5b657fd 100644 --- a/script/sign-windows.ps1 +++ b/script/sign-windows.ps1 @@ -25,32 +25,46 @@ if ($vars.Values | Where-Object { -not $_ }) { exit 0 } -if (-not (Get-Command sign -ErrorAction SilentlyContinue)) { - Write-Host "Skipping Windows signing because sign was not found on PATH" - exit 0 +$moduleVersion = "0.5.8" +$module = Get-Module -ListAvailable -Name TrustedSigning | Where-Object { $_.Version -eq [version] $moduleVersion } + +if (-not $module) { + try { + Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope CurrentUser | Out-Null + } + catch { + Write-Host "NuGet package provider install skipped: $($_.Exception.Message)" + } + + Install-Module -Name TrustedSigning -RequiredVersion $moduleVersion -Force -Repository PSGallery -Scope CurrentUser } +Import-Module TrustedSigning -RequiredVersion $moduleVersion -Force + $files = @($Path | ForEach-Object { Resolve-Path $_ -ErrorAction SilentlyContinue } | Select-Object -ExpandProperty Path -Unique) if (-not $files -or $files.Count -eq 0) { throw "No files matched the requested paths" } -$groups = $files | Group-Object { Split-Path $_ -Parent } - -foreach ($group in $groups) { - $dir = $group.Name - $names = @($group.Group | ForEach-Object { Split-Path $_ -Leaf }) - - & sign code artifact-signing ` - -b $dir ` - -ase $vars.endpoint ` - -ascp $vars.profile ` - -asa $vars.account ` - @names ` - -v Information - - if ($LASTEXITCODE -ne 0) { - throw "Azure Artifact Signing failed for $($group.Name)" - } +$params = @{ + Endpoint = $vars.endpoint + CodeSigningAccountName = $vars.account + CertificateProfileName = $vars.profile + Files = ($files -join ",") + FileDigest = "SHA256" + TimestampDigest = "SHA256" + TimestampRfc3161 = "http://timestamp.acs.microsoft.com" + ExcludeEnvironmentCredential = $true + ExcludeWorkloadIdentityCredential = $true + ExcludeManagedIdentityCredential = $true + ExcludeSharedTokenCacheCredential = $true + ExcludeVisualStudioCredential = $true + ExcludeVisualStudioCodeCredential = $true + ExcludeAzureCliCredential = $false + ExcludeAzurePowerShellCredential = $true + ExcludeAzureDeveloperCliCredential = $true + ExcludeInteractiveBrowserCredential = $true } + +Invoke-TrustedSigning @params From 3d67e02de9558ba2f0bd7c160a56adcc18965b90 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Sat, 28 Mar 2026 11:09:14 +1000 Subject: [PATCH 13/13] chore(ci): prefer process env in desktop signing scripts Use Node-compatible environment access in the desktop prepare and sidecar signing paths for the workflow changes added in this branch, while leaving unrelated Bun-specific runtime code untouched. --- packages/desktop-electron/scripts/prepare.ts | 4 ++-- packages/desktop-electron/scripts/utils.ts | 2 +- packages/desktop/scripts/prepare.ts | 4 ++-- packages/desktop/scripts/utils.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/desktop-electron/scripts/prepare.ts b/packages/desktop-electron/scripts/prepare.ts index 2c786a97efb5..3704b2e61323 100755 --- a/packages/desktop-electron/scripts/prepare.ts +++ b/packages/desktop-electron/scripts/prepare.ts @@ -13,12 +13,12 @@ await Bun.write("./package.json", JSON.stringify(pkg, null, 2) + "\n") console.log(`Updated package.json version to ${Script.version}`) const sidecarConfig = getCurrentSidecar() -const artifact = Bun.env.OPENCODE_CLI_ARTIFACT ?? "opencode-cli" +const artifact = process.env.OPENCODE_CLI_ARTIFACT ?? "opencode-cli" const dir = "resources/opencode-binaries" await $`mkdir -p ${dir}` -await $`gh run download ${Bun.env.GITHUB_RUN_ID} -n ${artifact}`.cwd(dir) +await $`gh run download ${process.env.GITHUB_RUN_ID} -n ${artifact}`.cwd(dir) await copyBinaryToSidecarFolder(windowsify(`${dir}/${sidecarConfig.ocBinary}/bin/opencode`)) diff --git a/packages/desktop-electron/scripts/utils.ts b/packages/desktop-electron/scripts/utils.ts index a182cbeeefc7..19b96b0a161f 100644 --- a/packages/desktop-electron/scripts/utils.ts +++ b/packages/desktop-electron/scripts/utils.ts @@ -63,7 +63,7 @@ export async function copyBinaryToSidecarFolder(source: string) { await $`mkdir -p ${dir}` const dest = windowsify(`${dir}/opencode-cli`) await $`cp ${source} ${dest}` - if (process.platform === "win32" && Bun.env.GITHUB_ACTIONS === "true") { + if (process.platform === "win32" && process.env.GITHUB_ACTIONS === "true") { await $`pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File ../../script/sign-windows.ps1 ${dest}` } if (process.platform === "darwin") await $`codesign --force --sign - ${dest}` diff --git a/packages/desktop/scripts/prepare.ts b/packages/desktop/scripts/prepare.ts index dc2c793f349b..729bf6ae137c 100755 --- a/packages/desktop/scripts/prepare.ts +++ b/packages/desktop/scripts/prepare.ts @@ -10,11 +10,11 @@ await Bun.write("./package.json", JSON.stringify(pkg, null, 2) + "\n") console.log(`Updated package.json version to ${Script.version}`) const sidecarConfig = getCurrentSidecar() -const artifact = Bun.env.OPENCODE_CLI_ARTIFACT ?? "opencode-cli" +const artifact = process.env.OPENCODE_CLI_ARTIFACT ?? "opencode-cli" const dir = "src-tauri/target/opencode-binaries" await $`mkdir -p ${dir}` -await $`gh run download ${Bun.env.GITHUB_RUN_ID} -n ${artifact}`.cwd(dir) +await $`gh run download ${process.env.GITHUB_RUN_ID} -n ${artifact}`.cwd(dir) await copyBinaryToSidecarFolder(windowsify(`${dir}/${sidecarConfig.ocBinary}/bin/opencode`)) diff --git a/packages/desktop/scripts/utils.ts b/packages/desktop/scripts/utils.ts index de042624aa92..111871d3e3ec 100644 --- a/packages/desktop/scripts/utils.ts +++ b/packages/desktop/scripts/utils.ts @@ -48,7 +48,7 @@ export async function copyBinaryToSidecarFolder(source: string, target = RUST_TA await $`mkdir -p src-tauri/sidecars` const dest = windowsify(`src-tauri/sidecars/opencode-cli-${target}`) await $`cp ${source} ${dest}` - if (process.platform === "win32" && Bun.env.GITHUB_ACTIONS === "true") { + if (process.platform === "win32" && process.env.GITHUB_ACTIONS === "true") { await $`pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File ../../script/sign-windows.ps1 ${dest}` }