| #!/usr/bin/env groovy |
| //------------------------------------------------------------------------------- |
| // Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved. |
| // |
| // SPDX-License-Identifier: BSD-3-Clause |
| //------------------------------------------------------------------------------- |
| |
| @Library('trustedfirmware') _ |
| import org.trustedfirmware.Gerrit |
| |
| def nodeLabel = "docker-amd64-tf-m-jammy" |
| |
| // Helpers |
| @NonCPS |
| def getUpstreamProjectName() { |
| def causes = manager.build.getAction(hudson.model.CauseAction.class)?.getCauses() |
| def upstreamCause = causes?.find { it instanceof hudson.model.Cause$UpstreamCause } |
| return upstreamCause?.upstreamProject |
| } |
| |
| def archiveRequired(String pattern) { |
| def matchedFiles = findFiles(glob: pattern) |
| if (matchedFiles.length > 0) { |
| echo "Archiving required files: ${pattern}" |
| archiveArtifacts artifacts: pattern, allowEmptyArchive: false |
| } else { |
| error "Required artifacts not found for pattern: ${pattern}" |
| } |
| } |
| |
| def archiveOptional(String pattern) { |
| def matchedFiles = findFiles(glob: pattern) |
| if (matchedFiles.length > 0) { |
| echo "Archiving optional files: ${pattern}" |
| archiveArtifacts artifacts: pattern, allowEmptyArchive: false |
| } else { |
| echo "Optional artifacts missing for pattern: ${pattern} — skipping." |
| } |
| } |
| |
| timestamps { |
| node(nodeLabel) { |
| stage("Init") { |
| cleanWs() |
| dir("tf-m-ci-scripts") { |
| tfgit.checkout_ci_scripts() |
| sh "git rev-parse --short HEAD" |
| sh "./clone.sh" |
| } |
| } |
| |
| try { |
| stage("Build") { |
| if (env.CONFIG_NAME.contains("ARMCLANG")) { |
| withCredentials([string(credentialsId: 'ARMCLANG_UBL_CODE', variable: 'ARMCLANG_UBL_CODE')]) { |
| sh "tf-m-ci-scripts/jenkins/armclang-ubl.sh" |
| } |
| } |
| sh "tf-m-ci-scripts/run-build.sh" |
| } |
| |
| stage("Post") { |
| // Required artifacts (secure side) |
| def requiredSpePaths = [ |
| 'ci_build/spe/bin/**', |
| 'ci_build/spe/api_ns/bin/**', |
| 'ci_build/spe/api_ns/interface/**' |
| ] |
| requiredSpePaths.each { archiveRequired(it) } |
| |
| // Optional artifacts (non-secure side) |
| def optionalNspePaths = [ |
| 'ci_build/nspe/bin/**', |
| 'ci_build/nspe/*.bin' |
| ] |
| optionalNspePaths.each { archiveOptional(it) } |
| |
| // Handle upstream-specific artifacts |
| def upstreamProject = getUpstreamProjectName() |
| |
| if (upstreamProject == "tf-m-build-and-test") { |
| archiveRequired('ci_build/spe/build-spe/generated/**') |
| } |
| |
| if (upstreamProject == "tf-m-nightly-performance") { |
| sh "mkdir -p ${SHARE_FOLDER}/Memory_footprint/" |
| def output = sh(script: "python3 tf-m-ci-scripts/performance.py --generate-memory", returnStdout: true).trim() |
| println(output) |
| } |
| } |
| |
| } catch (Exception e) { |
| echo "Exception: ${e.getClass().getName()}: ${e.getMessage()}" |
| echo "Archiving all build files due to build error (to allow investigation)" |
| archiveArtifacts artifacts: 'ci_build/**', allowEmptyArchive: true |
| manager.buildFailure() |
| } finally { |
| def g = new Gerrit() |
| g.verifyStatusInWorkspace(currentBuild.result == 'SUCCESS' ? 1 : -1, env.CONFIG_NAME, 'build') |
| cleanWs() |
| } |
| } |
| } |