From 604e9c8b03d3c58ea21956f251e53bf7173f2d9f Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Mon, 30 Jun 2025 17:23:42 -0400 Subject: [PATCH 1/3] Revert "ci(app): electron builder Windows signing workaround (#18479)" This reverts commit 26c3bf06009a11581539c2f96a2c646cfd7c1ecb. --- .github/workflows/app-test-build-deploy.yaml | 26 -------------------- 1 file changed, 26 deletions(-) diff --git a/.github/workflows/app-test-build-deploy.yaml b/.github/workflows/app-test-build-deploy.yaml index 900b26662ad4..2d104a737d5f 100644 --- a/.github/workflows/app-test-build-deploy.yaml +++ b/.github/workflows/app-test-build-deploy.yaml @@ -221,32 +221,6 @@ jobs: run: | make -C app dist - - name: Install and Invoke TrustedSigning @0.5.3 on dummy executable - # Work around from https://github.com/electron-userland/electron-builder/issues/9076#issuecomment-2855541018 - if: startsWith(matrix.os, 'windows') && contains(needs.determine-build-type.outputs.type, 'release') - shell: pwsh - run: | - Install-Module -Name TrustedSigning -RequiredVersion 0.5.3 -Force -Repository PSGallery - # Create a dummy executable file - $dummyExePath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "dummy.exe" - Set-Content -Path $dummyExePath -Value "This is a dummy executable for testing purposes." - # Invoke Trusted Signing on the dummy executable - # Necessary to force dependency resolution - try { - Invoke-TrustedSigning ` - -Endpoint 'https://eus.codesigning.azure.net/' ` - -CertificateProfileName 'dummyName' ` - -CodeSigningAccountName 'dummyName' ` - -TimestampRfc3161 'http://timestamp.acs.microsoft.com' ` - -TimestampDigest 'SHA256' ` - -FileDigest 'SHA256' ` - -Files $dummyExePath - } catch { - Write-Host "Invoke-TrustedSigning failed: $($_.Exception.Message)" - # Prevent the script from exiting with a non-zero status - exit 0 - } - # build the desktop app and deploy it - name: 'build ${{matrix.variant}} app for ${{ matrix.os }}' if: matrix.target == 'desktop' From bf47c6b1035e0b088fe8f6d0f72e6c0ef73da812 Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Mon, 30 Jun 2025 17:25:07 -0400 Subject: [PATCH 2/3] Revert "ci(app): Azure trusted signing for Windows (#18450)" This reverts commit 6e42e4b37d97994be528794d8573072920d029d5. --- .github/workflows/app-test-build-deploy.yaml | 36 ++++++++++- app-shell/electron-builder.config.js | 10 +-- app-shell/scripts/windows-custom-sign.js | 66 ++++++++++++++++++++ 3 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 app-shell/scripts/windows-custom-sign.js diff --git a/.github/workflows/app-test-build-deploy.yaml b/.github/workflows/app-test-build-deploy.yaml index 2d104a737d5f..7322db49154e 100644 --- a/.github/workflows/app-test-build-deploy.yaml +++ b/.github/workflows/app-test-build-deploy.yaml @@ -211,6 +211,32 @@ jobs: python-version: '3.10' - name: check make version run: make --version + - name: 'Configure Windows code signing environment' + if: startsWith(matrix.os, 'windows') && contains(needs.determine-build-type.outputs.type, 'release') + shell: bash + run: | + echo "${{ secrets.SM_CLIENT_CERT_FILE_B64_V2 }}" | base64 --decode > /d/Certificate_pkcs12.p12 + echo "${{ secrets.WINDOWS_CSC_B64}}" | base64 --decode > /d/opentrons_labworks_inc.crt + echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH + echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH + echo "C:\Program Files\DigiCert\DigiCert Keylocker Tools" >> $GITHUB_PATH + + - name: 'Setup Windows code signing helpers' + if: startsWith(matrix.os, 'windows') && contains(needs.determine-build-type.outputs.type, 'release') + shell: cmd + env: + SM_HOST: ${{ secrets.SM_HOST_V2 }} + SM_CLIENT_CERT_FILE: "D:\\Certificate_pkcs12.p12" + SM_CLIENT_CERT_PASSWORD: ${{secrets.SM_CLIENT_CERT_PASSWORD_V2}} + SM_API_KEY: ${{secrets.SM_API_KEY_V2}} + run: | + curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/Keylockertools-windows-x64.msi/download -H "x-api-key:${{secrets.SM_API_KEY_V2}}" -o Keylockertools-windows-x64.msi + msiexec /i Keylockertools-windows-x64.msi /quiet /qn + smksp_registrar.exe list + smctl.exe keypair ls + C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user + smksp_cert_sync.exe + smctl.exe healthcheck --all # Do the frontend dist bundle - name: 'bundle ${{matrix.variant}} frontend' @@ -229,9 +255,13 @@ jobs: OT_APP_MIXPANEL_ID: ${{ secrets.OT_APP_MIXPANEL_ID }} OT_APP_INTERCOM_ID: ${{ secrets.OT_APP_INTERCOM_ID }} WINDOWS_SIGN: ${{ format('{0}', contains(needs.determine-build-type.outputs.type, 'release')) }} - AZURE_TENANT_ID: ${{secrets.AZURE_TENANT_ID}} - AZURE_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}} - AZURE_CLIENT_SECRET: ${{secrets.AZURE_CLIENT_SECRET}} + SM_CODE_SIGNING_CERT_SHA1_HASH: ${{secrets.SM_CODE_SIGNING_CERT_SHA1_HASH_V2}} + SM_KEYPAIR_ALIAS: ${{secrets.SM_KEYPAIR_ALIAS_V2}} + SM_HOST: ${{ secrets.SM_HOST_V2 }} + SM_CLIENT_CERT_FILE: "D:\\Certificate_pkcs12.p12" + SM_CLIENT_CERT_PASSWORD: ${{secrets.SM_CLIENT_CERT_PASSWORD_V2}} + SM_API_KEY: ${{secrets.SM_API_KEY_V2}} + WINDOWS_CSC_FILEPATH: "D:\\opentrons_labworks_inc.crt" CSC_LINK: ${{ secrets.OT_APP_CSC_MACOS_V2 }} CSC_KEY_PASSWORD: ${{ secrets.OT_APP_CSC_KEY_MACOS_V2 }} APPLE_ID: ${{ secrets.OT_APP_APPLE_ID_V2 }} diff --git a/app-shell/electron-builder.config.js b/app-shell/electron-builder.config.js index 27f510d109b4..ea94be54b6aa 100644 --- a/app-shell/electron-builder.config.js +++ b/app-shell/electron-builder.config.js @@ -67,11 +67,11 @@ module.exports = async () => ({ target: ['nsis'], icon: project === 'robot-stack' ? 'build/icon.ico' : 'build/three.ico', forceCodeSigning: WINDOWS_SIGN, - azureSignOptions: { - publisherName: 'OPENTRONS LABWORKS INC.', - codeSigningAccountName: 'desktop-app-signing', - certificateProfileName: 'OpentronsDesktopApp', - endpoint: 'https://eus.codesigning.azure.net', + signtoolOptions: { + publisherName: 'Opentrons Labworks Inc.', + rfc3161TimeStampServer: 'http://timestamp.digicert.com', + sign: 'scripts/windows-custom-sign.js', + signingHashAlgorithms: ['sha256'], }, }, nsis: { diff --git a/app-shell/scripts/windows-custom-sign.js b/app-shell/scripts/windows-custom-sign.js new file mode 100644 index 000000000000..f0735a50989c --- /dev/null +++ b/app-shell/scripts/windows-custom-sign.js @@ -0,0 +1,66 @@ +// from https://github.com/electron-userland/electron-builder/issues/7605 + +'use strict' + +const { execSync } = require('node:child_process') + +exports.default = async configuration => { + const { WINDOWS_SIGN } = process.env + if (WINDOWS_SIGN !== 'true') { + return + } + const signCmd = `smctl sign --keypair-alias="${String( + process.env.SM_KEYPAIR_ALIAS + )}" --input "${String(configuration.path)}" --certificate="${String( + process.env.WINDOWS_CSC_FILEPATH + )}" --exit-non-zero-on-fail --failfast --verbose` + console.log(signCmd) + try { + const signProcess = execSync(signCmd, { + stdio: 'pipe', + }) + console.log(`Sign success!`) + console.log( + `Sign stdout: ${signProcess?.stdout?.toString() ?? ''}` + ) + console.log( + `Sign stderr: ${signProcess?.stderr?.toString() ?? ''}` + ) + console.log(`Sign code: ${signProcess.code}`) + } catch (err) { + console.error(`Exception running sign: ${err.status}! +Process stdout: + ${err?.stdout?.toString() ?? ''} +------------- +Process stderr: +${err?.stdout?.toString() ?? ''} +------------- +`) + throw err + } + const verifyCmd = `smctl sign verify --fingerprint="${String( + process.env.SM_CODE_SIGNING_CERT_SHA1_HASH + )}" --input="${String(configuration.path)}" --verbose` + console.log(verifyCmd) + try { + const verifyProcess = execSync(verifyCmd, { stdio: 'pipe' }) + console.log(`Verify success!`) + console.log( + `Verify stdout: ${verifyProcess?.stdout?.toString() ?? ''}` + ) + console.log( + `Verify stderr: ${verifyProcess?.stderr?.toString() ?? ''}` + ) + } catch (err) { + console.error(` +Exception running verification: ${err.status}! +Process stdout: + ${err?.stdout?.toString() ?? ''} +-------------- +Process stderr: + ${err?.stderr?.toString() ?? ''} +-------------- +`) + throw err + } +} From 375a9beb5b64af709a72bb0474f461f2704cb97f Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Mon, 30 Jun 2025 17:26:07 -0400 Subject: [PATCH 3/3] fix(app): use new publisher name alongside current This will allow users to update to the new app whenever we switch to azure trusted signing. --- app-shell/electron-builder.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app-shell/electron-builder.config.js b/app-shell/electron-builder.config.js index ea94be54b6aa..1871a2d8153c 100644 --- a/app-shell/electron-builder.config.js +++ b/app-shell/electron-builder.config.js @@ -68,7 +68,7 @@ module.exports = async () => ({ icon: project === 'robot-stack' ? 'build/icon.ico' : 'build/three.ico', forceCodeSigning: WINDOWS_SIGN, signtoolOptions: { - publisherName: 'Opentrons Labworks Inc.', + publisherName: ['Opentrons Labworks Inc.', 'OPENTRONS LABWORKS INC.'], rfc3161TimeStampServer: 'http://timestamp.digicert.com', sign: 'scripts/windows-custom-sign.js', signingHashAlgorithms: ['sha256'],