From 9189f3a8268367583745117065b9a9a230ed4e6c Mon Sep 17 00:00:00 2001 From: Sophia Guo Date: Tue, 20 Jun 2023 11:32:17 -0400 Subject: [PATCH] Add a post build stage Add sbom sign job in post build stage Signed-off-by: Sophia Guo --- pipelines/build/common/build_base_file.groovy | 41 ++++++++++++- tools/post-build/Jenkinsfile | 61 +++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 tools/post-build/Jenkinsfile diff --git a/pipelines/build/common/build_base_file.groovy b/pipelines/build/common/build_base_file.groovy index c398d6b35..59f3c550b 100644 --- a/pipelines/build/common/build_base_file.groovy +++ b/pipelines/build/common/build_base_file.groovy @@ -747,6 +747,40 @@ class Builder implements Serializable { return true } + /* + Call job to do post task. For now enable sbom sign + */ + def postStage() { + context.stage('post-build') { + //Job name need to discuss + context.println "Post build - parallel post tasks, e.g. sbom sign" + def postBuildJob = context.build job: 'Sophia_pipeline', + parameters: [ + context.string(name: 'UPSTREAM_JOB_NAME', value: env.JOB_NAME), + context.string(name: 'UPSTREAM_JOB_NUMBER', value: "${currentBuild.getNumber()}") + ] + context.node('worker') { + // Remove any previous workspace artifacts + context.sh 'rm -rf *.json || true' + context.copyArtifacts( + projectName: 'Sophia_pipeline', + selector: context.specific("${postBuildJob.getNumber()}"), + filter: '*.json', + fingerprintArtifacts: true, + target: 'sbom/', + flatten: true) + + // Archive signed sbom in Jenkins + try { + context.timeout(time: pipelineTimeouts.ARCHIVE_ARTIFACTS_TIMEOUT, unit: 'HOURS') { + context.archiveArtifacts artifacts: "sbom/*.json" + } + } catch (FlowInterruptedException e) { + throw new Exception("[ERROR] Archive artifact timeout (${pipelineTimeouts.ARCHIVE_ARTIFACTS_TIMEOUT} HOURS) for Sophia_pipeline has been reached. Exiting...") + } + } + } + } /* Call job to push artifacts to github. Usually it's only executed on a nightly build @@ -927,7 +961,12 @@ class Builder implements Serializable { } } context.parallel jobs - + + try { + postStage() + } catch (Exception e) { + context.println(e.message) + } // publish to github if needed // Don't publish release automatically if (publish && !release) { diff --git a/tools/post-build/Jenkinsfile b/tools/post-build/Jenkinsfile new file mode 100644 index 000000000..a1ed10b6a --- /dev/null +++ b/tools/post-build/Jenkinsfile @@ -0,0 +1,61 @@ +// Build once a day +CRON_SETTINGS = '''H H * * *''' +NODE_LABEL = 'dockerBuild&&linux&&x64' + +pipeline { + agent none + parameters { + string(name: 'UPSTREAM_JOB_NAME', defaultValue: '', description: 'Pipeline job with sbom filesCompared nightly build job name') + string(name: 'UPSTREAM_JOB_NUMBER', defaultValue: '', description: 'Pipeline job number') + + } + stages { + stage('Post-Build') { + parallel { + stage('sbomSign') { + agent { + label NODE_LABEL + } + steps { + sbomSign() + } + } + } + } + } +} + +def sbomSign() { + cleanWs() + docker.image('adoptopenjdk/centos7_build_image').inside { + checkout scm + checkout([$class: 'GitSCM', branches: [[name: 'post']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: "sbomSign"]], submoduleCfg: [], userRemoteConfigs: [[url: "https://github.com/sophia-guo/openjdk-build.git"]]]) + copyArtifacts excludes: '**/OpenJDK*-sbom*metadata.json', + filter: '**/OpenJDK*-sbom*.json', + fingerprintArtifacts: true, + flatten: true, + projectName: "${params.UPSTREAM_JOB_NAME}", + target: 'sbom/', + selector: specific("${params.UPSTREAM_JOB_NUMBER}") + script { + dir("sbomSign/cyclonedx-lib") { + sh label: 'build-sign-sbom', script: ''' + JAVA_HOME=/usr/lib/jvm/jdk-17 ant clean + JAVA_HOME=/usr/lib/jvm/jdk-17 ant build-sign-sbom + openssl genpkey -algorithm RSA -pass pass:test -outform PEM -out testPrivateFile -pkeyopt rsa_keygen_bits:2048 + openssl rsa -in testPrivateFile -passin pass:test -pubout -out publicPemFile + ''' + } + def sbomFiles = findFiles(glob: "**/OpenJDK*-sbom*.json") + for (def sbomFile: sbomFiles) { + def sbomFileName = sbomFile.path + def classPath = "sbomSign/cyclonedx-lib/build/jar/*" + sh label: 'sign-sbom', script: """ + /usr/lib/jvm/jdk-17/bin/java -cp "${classPath}" temurin.sbom.TemurinSignSBOM --signSBOM --jsonFile ${sbomFileName} --privateKeyFile ./sbomSign/cyclonedx-lib/testPrivateFile + /usr/lib/jvm/jdk-17/bin/java -cp "${classPath}" temurin.sbom.TemurinSignSBOM --verifySignature --jsonFile ${sbomFileName} --publicKeyFile ./sbomSign/cyclonedx-lib/publicPemFile + """ + } + } + archiveArtifacts artifacts: "**/OpenJDK*-sbom*.json" + } +}