From 4a3f86a5903d8f6ff35e37b9736beae9008f30d7 Mon Sep 17 00:00:00 2001 From: Timothy LeBon Date: Fri, 5 Apr 2024 12:08:13 +0200 Subject: [PATCH] feat: pipeline cert update [WPB-7048] (#7744) * feat: test pipeline integration * chore: remove old signtool * chore: playing with pipeline * fix: credential declaring * chore: changing signing method * Use smctl to sign * Fix batch syntax for verify step * chore:update verification * chore: increment version --------- Co-authored-by: Sven Jost --- electron/wire.json | 2 +- jenkins/windows.groovy | 177 ++++++++++++++++++++++------------------- package.json | 2 +- 3 files changed, 97 insertions(+), 84 deletions(-) diff --git a/electron/wire.json b/electron/wire.json index bd8191b0ec2..44c06ca60f7 100644 --- a/electron/wire.json +++ b/electron/wire.json @@ -20,6 +20,6 @@ "privacyUrl": "https://wire.com/privacy/", "supportUrl": "https://support.wire.com", "updateUrl": "https://wire-app.wire.com/win/prod/", - "version": "3.34.0", + "version": "3.35.0", "websiteUrl": "https://wire.com" } diff --git a/jenkins/windows.groovy b/jenkins/windows.groovy index 7eeb6830dda..07b09f92a9f 100644 --- a/jenkins/windows.groovy +++ b/jenkins/windows.groovy @@ -4,107 +4,120 @@ def parseJson(def text) { } node('windows') { - def production = params.PRODUCTION - def custom = params.CUSTOM - def NODE = tool name: 'node-v16.17.1', type: 'nodejs' + def production = params.PRODUCTION + def custom = params.CUSTOM + def NODE = tool name: 'node-v16.17.1', type: 'nodejs' - def jenkinsbot_secret = '' - withCredentials([string(credentialsId: "${params.JENKINSBOT_SECRET}", variable: 'JENKINSBOT_SECRET')]) { - jenkinsbot_secret = env.JENKINSBOT_SECRET - } + def jenkinsbot_secret = '' - if (!production && !custom) { - env.APP_ENV = 'internal' - } + withCredentials([string(credentialsId: "${params.JENKINSBOT_SECRET}", variable: 'JENKINSBOT_SECRET')]) { + jenkinsbot_secret = env.JENKINSBOT_SECRET + } + + if (!production && !custom) { + env.APP_ENV = 'internal' + } - stage('Checkout & Clean') { - git branch: "${GIT_BRANCH}", url: 'https://github.com/wireapp/wire-desktop.git' - bat returnStatus: true, script: 'rmdir /s /q "node_modules"' - } + stage('Checkout & Clean') { + git branch: "${GIT_BRANCH}", url: 'https://github.com/wireapp/wire-desktop.git' + bat returnStatus: true, script: 'rmdir /s /q "node_modules"' + } - def wireJson = readFile('electron/wire.json') - def packageJson = readFile('package.json') - def (major, minor) = parseJson(wireJson).version.tokenize('.') - def version = "${major}.${minor}.${env.BUILD_NUMBER}" - def electronVersion = parseJson(packageJson).devDependencies.electron - currentBuild.displayName = version + def wireJson = readFile('electron/wire.json') + def packageJson = readFile('package.json') + def (major, minor) = parseJson(wireJson).version.tokenize('.') + def version = "${major}.${minor}.${env.BUILD_NUMBER}" + def electronVersion = parseJson(packageJson).devDependencies.electron + currentBuild.displayName = version - stage('Probe signtool') { - try { - timeout(activity: true, time: 30, unit: 'SECONDS') { - bat '"C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x86\\signtool.exe" sign /t http://timestamp.digicert.com /a C:\\Users\\jenkins\\Downloads\\Git-2.21.0-64-bit.exe' + stage('Sign test file') { + withCredentials([string(credentialsId: 'SM_API_KEY', variable: 'SM_API_KEY'), string(credentialsId: 'SM_HOST', variable: 'SM_HOST'), string(credentialsId: 'SM_CLIENT_CERT_PASSWORD', variable: 'SM_CLIENT_CERT_PASSWORD'), file(credentialsId: 'SM_CLIENT_CERT_FILE', variable: 'SM_CLIENT_CERT_FILE'), string(credentialsId: 'SM_KEYPAIR_ALIAS', variable: 'SM_KEYPAIR_ALIAS')]) { + try { + bat 'smctl sign --keypair-alias %SM_KEYPAIR_ALIAS% --config-file %SM_CLIENT_CERT_FILE% --input C:\\Users\\jenkins\\Downloads\\Git-2.21.0-64-bit.exe -v' + } catch (e) { + currentBuild.result = 'FAILED' + wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} signing installer failed**\n${BUILD_URL}" + throw e + } } - } catch(e) { - currentBuild.result = 'FAILED' - wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} signing failed**\n\nāš ļø Please **manually** enter the signing key on the machine or use the unlock dongle job!" - throw e } - } - stage('Build') { - try { - withEnv(["PATH+NODE=${NODE}", 'npm_config_target_arch=x64']) { - bat 'node -v' - bat 'npm -v' - bat 'npm install -g yarn' - bat 'yarn' - bat 'yarn build:win' + stage('Build') { + try { + withEnv(["PATH+NODE=${NODE}", 'npm_config_target_arch=x64']) { + bat 'node -v' + bat 'npm -v' + bat 'npm install -g yarn' + bat 'yarn' + bat 'yarn build:win' + } + } catch (e) { + currentBuild.result = 'FAILED' + wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} build failed**\n${BUILD_URL}" + throw e } - } catch(e) { - currentBuild.result = 'FAILED' - wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} build failed**\n${BUILD_URL}" - throw e } - } - stage('Build installer') { - try { - withEnv(["PATH+NODE=${NODE}",'npm_config_target_arch=x64']) { - bat 'yarn build:win:installer' + stage('Build installer') { + try { + withEnv(["PATH+NODE=${NODE}", 'npm_config_target_arch=x64']) { + bat 'yarn build:win:installer' + } + } catch (e) { + currentBuild.result = 'FAILED' + wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} building installer failed**\n${BUILD_URL}" + throw e } - } catch(e) { - currentBuild.result = 'FAILED' - wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} building installer failed**\n${BUILD_URL}" - throw e } - } - stage('Sign installer') { - try { - bat 'for %%f in ("wrap\\dist\\*-Setup.exe") do "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x86\\signtool.exe" sign /t http://timestamp.digicert.com /fd SHA256 /a "%%f"' - } catch(e) { - currentBuild.result = 'FAILED' - wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} signing installer failed**\n${BUILD_URL}" - throw e + stage('Sign installer') { + withCredentials([string(credentialsId: 'SM_API_KEY', variable: 'SM_API_KEY'), string(credentialsId: 'SM_HOST', variable: 'SM_HOST'), string(credentialsId: 'SM_CLIENT_CERT_PASSWORD', variable: 'SM_CLIENT_CERT_PASSWORD'), file(credentialsId: 'SM_CLIENT_CERT_FILE', variable: 'SM_CLIENT_CERT_FILE'), string(credentialsId: 'SM_KEYPAIR_ALIAS', variable: 'SM_KEYPAIR_ALIAS')]) { + try { + bat 'for %%f in ("wrap\\dist\\*-Setup.exe") do (smctl sign --keypair-alias %SM_KEYPAIR_ALIAS% --config-file %SM_CLIENT_CERT_FILE% --input %%f -v)' + } catch (e) { + currentBuild.result = 'FAILED' + wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} signing installer failed**\n${BUILD_URL}" + throw e + } + } } - } - - stage('Archive build artifacts') { - archiveArtifacts 'package.json,wrap\\dist\\**' - } - stage('Print hash') { - try { - if (production) { - bat 'certUtil -hashfile "wrap\\dist\\Wire-Setup.exe" SHA256' + stage('verify') { + try { + bat 'for %%f in (\"wrap\\dist\\*-Setup.exe\") do (signtool.exe verify /v /pa %%f)' + } + catch (e) { + currentBuild.result = 'FAILED' + wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} verifying installer failed**\n${BUILD_URL}" } - } catch(e) { - currentBuild.result = 'FAILED' - wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} printing hash failed**\n${BUILD_URL}" - throw e } - } + stage('Archive build artifacts') { + archiveArtifacts 'package.json,wrap\\dist\\**' + } - stage('Trigger smoke tests') { - if (production) { - try { - build job: 'Wrapper_Windows_Smoke_Tests', parameters: [run(description: '', name: 'WRAPPER_BUILD', runId: "Wrapper_Windows_Production#${BUILD_ID}"), string(name: 'WEBAPP_ENV', value: 'https://wire-webapp-master.zinfra.io/')], wait: false - } catch(e) { - wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} Unable to trigger smoke tests for ${version}**\n${BUILD_URL}" - print e + stage('Print hash') { + try { + if (production) { + bat 'certUtil -hashfile "wrap\\dist\\Wire-Setup.exe" SHA256' + } + } catch (e) { + currentBuild.result = 'FAILED' + wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} ${version} printing hash failed**\n${BUILD_URL}" + throw e + } } + + stage('Trigger smoke tests') { + if (production) { + try { + build job: 'Wrapper_Windows_Smoke_Tests', parameters: [run(description: '', name: 'WRAPPER_BUILD', runId: "Wrapper_Windows_Production#${BUILD_ID}"), string(name: 'WEBAPP_ENV', value: 'https://wire-webapp-master.zinfra.io/')], wait: false + } catch (e) { + wireSend secret: "${jenkinsbot_secret}", message: "šŸž **${JOB_NAME} Unable to trigger smoke tests for ${version}**\n${BUILD_URL}" + print e + } + } + } + + wireSend secret: "${jenkinsbot_secret}", message: "šŸž **New build of ${JOB_NAME} ${version}**\n- Download: [Jenkins](${BUILD_URL})\n- Electron version: ${electronVersion}\n- Branch: [${GIT_BRANCH}](https://github.com/wireapp/wire-desktop/commits/${GIT_BRANCH})" } - } - wireSend secret: "${jenkinsbot_secret}", message: "šŸž **New build of ${JOB_NAME} ${version}**\n- Download: [Jenkins](${BUILD_URL})\n- Electron version: ${electronVersion}\n- Branch: [${GIT_BRANCH}](https://github.com/wireapp/wire-desktop/commits/${GIT_BRANCH})" -} diff --git a/package.json b/package.json index dac47655feb..860c6369b51 100644 --- a/package.json +++ b/package.json @@ -201,6 +201,6 @@ "translate:upload": "ts-node -P tsconfig.bin.json ./bin/translations_upload.ts", "translate:download": "ts-node -P tsconfig.bin.json ./bin/translations_download.ts" }, - "version": "3.34.0", + "version": "3.35.0", "packageManager": "yarn@3.3.1" }