From f1437a058b9b3667eafca96f1f51fc2daff097c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Thu, 3 Aug 2023 14:23:28 +0200 Subject: [PATCH] ci: add Jenkinsfile and shell.nix for builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR consists of two components: * `ci/Jenkinsfile.build` - CI build for both Linux, MacOS, and Windows * `ci/Jenkinsfile.release` - Meta-build that combines two above. The purpose of the `release` job is to create a single GitHub releas that combines artifacts from all build jobs. The GitHub release created is in Draft mode and needs to be edited to update description and published. Signed-off-by: Jakub SokoĊ‚owski --- README.md | 4 ++ ci/Jenkinsfile.build | 81 +++++++++++++++++++++++++++++++++++++++ ci/Jenkinsfile.release | 87 ++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- tsconfig.json | 14 +++---- 5 files changed, 181 insertions(+), 8 deletions(-) create mode 100644 ci/Jenkinsfile.build create mode 100644 ci/Jenkinsfile.release diff --git a/README.md b/README.md index 668df09..46f57d7 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,8 @@ To create certificates you should first fill in the form, specifying lot number, the quantity of cards for which you need to create a certificate, destination path for the certificates file and choose the output encryption PGP key. You also need a Keycard to sign the certificates. Path `m/43'/60'/1581'/2'/0` will be used to sign. +# Continuous Integration +The CI builds can be found in Jenkins under [keycard-certify](https://ci.infra.status.im/job/keycard-certify/). + +The [`release`](https://ci.infra.status.im/job/keycard-certify/job/release/)` job builds the app for Linux, MacOS, and Windows, then publishes all artifacts to a GitHub release based on version set in `package.json`. diff --git a/ci/Jenkinsfile.build b/ci/Jenkinsfile.build new file mode 100644 index 0000000..c2036a9 --- /dev/null +++ b/ci/Jenkinsfile.build @@ -0,0 +1,81 @@ +#!/usr/bin/env groovy +// vim:ft=Jenkinsfile +library 'status-jenkins-lib@v1.7.12' + +pipeline { + /* Allows to run the same Jenkinsfile on different platforms. */ + agent { label params.AGENT_LABEL } + + parameters { + string( + name: 'AGENT_LABEL', + description: 'Label for targetted CI slave host: linux/macos/windows', + defaultValue: params.AGENT_LABEL ?: getAgentLabel(), + ) + } + + options { + timestamps() + ansiColor('xterm') + /* This also includes wait time in the queue. */ + timeout(time: 10, unit: 'MINUTES') + /* Abort old builds for non-main branches. */ + disableConcurrentBuilds() + /* Allows combined build to copy */ + copyArtifactPermission('/keycard-certify/*') + /* Limit builds retained. */ + buildDiscarder(logRotator( + numToKeepStr: '5', + daysToKeepStr: '30', + artifactNumToKeepStr: '3', + )) + } + + environment { + /* Disable MacOS app signing. + * https://www.electron.build/code-signing */ + CSC_IDENTITY_AUTO_DISCOVERY = "false" + } + + stages { + stage('Deps') { + steps { script { + sh 'npm install' + } } + } + + stage('Build') { + steps { script { + sh 'npm run dist' + } } + } + + stage('Upload') { + steps { + archiveArtifacts( + artifacts: 'dist/keycard-certify*', + excludes: 'dist/*.blockmap' + ) + } + } + } // stages + + post { + always { cleanWs() } + } // post +} // pipeline + +/* This allows us to use one Jenkinsfile and run + * jobs on different platforms based on job name. */ +def getAgentLabel() { + if (params.AGENT_LABEL) { return params.AGENT_LABEL } + /* We extract the name of the job from currentThread because + * before an agent is picked env is not available. */ + def tokens = Thread.currentThread().getName().split('/') + def labels = [] + /* Check if the job path contains any of the valid labels. */ + ['linux', 'macos', 'windows', 'x86_64', 'aarch64', 'arm64'].each { + if (tokens.contains(it)) { labels.add(it) } + } + return labels.join(' && ') +} diff --git a/ci/Jenkinsfile.release b/ci/Jenkinsfile.release new file mode 100644 index 0000000..d330e44 --- /dev/null +++ b/ci/Jenkinsfile.release @@ -0,0 +1,87 @@ +#!/usr/bin/env groovy +// vim:ft=Jenkinsfile +library 'status-jenkins-lib@v1.7.12' + +pipeline { + /* Allows to run the same Jenkinsfile on different platforms. */ + agent { label 'linux' } + + parameters { + booleanParam( + name: 'PUBLISH', + description: 'Trigger publishing of build results to GitHub.', + defaultValue: getPublishDefault(params.PUBLISH), + ) + } + + options { + timestamps() + ansiColor('xterm') + /* This also includes wait time in the queue. */ + timeout(time: 20, unit: 'MINUTES') + /* Abort old builds for non-main branches. */ + disableConcurrentBuilds() + /* Limit builds retained. */ + buildDiscarder(logRotator( + numToKeepStr: '10', + daysToKeepStr: '30', + )) + } + + stages { + stage('Build') { + parallel { + stage('Linux') { steps { script { + linux = jenkins.Build('keycard-certify/platforms/linux/x86_64') + } } } + stage('MacOS') { steps { script { + macos = jenkins.Build('keycard-certify/platforms/macos/x86_64') + } } } + stage('Windows') { steps { script { + windows = jenkins.Build('keycard-certify/platforms/windows/x86_64') + } } } + } + } + + stage('Archive') { + steps { script { + sh('rm -f pkg/*') + jenkins.copyArts(linux) + jenkins.copyArts(macos) + jenkins.copyArts(windows) + version = readJSON(file: 'package.json')['version'] + dir('pkg') { + /* generate sha256 checksums for upload */ + sh "sha256sum * | tee ../pkg/keycard-certify_${version}.sha256" + archiveArtifacts('*') + } + } } + } + + stage('Publish') { + when { expression { params.PUBLISH } } + steps { script { + github.publishReleaseFiles( + repo: 'keycard-certify', + version: "v${version}", + desc: ':warning: __Please fill me in!__', + verbose: true + ) + } } + } + } // stages + + post { + always { cleanWs() } + } // post +} // pipeline + +/* Helper that makes PUBLISH default to 'false' unless: + * - The build is for a release branch + * - A user explicitly specified a value + * Since release builds create and re-create GitHub drafts every time. */ +def Boolean getPublishDefault(Boolean previousValue) { + if (env.JOB_NAME.startsWith('keycard-certify/release')) { return true } + if (previousValue != null) { return previousValue } + return false +} diff --git a/package.json b/package.json index 8023953..dbae70c 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ }, "build": { "appId": "com.github.choppu.keycard-certify", - "productName": "Keycard Certify", + "productName": "keycard-certify", + "artifactName": "${productName}_${version}_${arch}.${ext}", "publish": false, "files": [ "**/*", diff --git a/tsconfig.json b/tsconfig.json index 65700ea..a4e97b3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,10 @@ { "compilerOptions": { - "target": "es5", - "module": "commonjs", - "strict": true, - "esModuleInterop": true, - "outDir": "./out", - "rootDir": "./src" + "target": "es5", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "outDir": "./out", + "rootDir": "./src" } -} \ No newline at end of file +}