mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Avoid the following error in the always post condition: Error when executing always post condition: Also: org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: 1540dd3e-f4ca-410c-8c37-8977ada45325 hudson.AbortException: Failed to copy artifacts from RAN-ARM-Cross-Compile-Builder with filter: test_results*.html Add "optional: true" to copyArtifacts so that a missing HTML report is handled by the existing placeholder fallback instead of aborting the post condition. Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
957 lines
33 KiB
Groovy
957 lines
33 KiB
Groovy
#!/bin/groovy
|
|
/*
|
|
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
|
*/
|
|
|
|
// Location of the executor node
|
|
def nodeExecutor = params.nodeExecutor
|
|
|
|
// Tags to shorten pipeline duration
|
|
def doBuild = true
|
|
def do4Gtest = false
|
|
def do5Gtest = false
|
|
def do5GUeTest = false
|
|
|
|
//
|
|
def gitCommitAuthorEmailAddr
|
|
|
|
// list of failing stages
|
|
def failingStages = ""
|
|
|
|
OAI_Registry = "gracehopper3-oai.sboai.cs.eurecom.fr"
|
|
|
|
pipeline {
|
|
agent {
|
|
label nodeExecutor
|
|
}
|
|
options {
|
|
timestamps()
|
|
gitLabConnection('OAI GitLab')
|
|
ansiColor('xterm')
|
|
}
|
|
|
|
stages {
|
|
stage ("Verify Parameters") {
|
|
steps {
|
|
script {
|
|
env.JOB_TIMESTAMP = sh(returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"').trim()
|
|
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
|
|
def allParametersPresent = true
|
|
|
|
echo '\u2705 \u001B[32mVerify Labels\u001B[0m'
|
|
if ("MERGE".equals(env.gitlabActionType)) {
|
|
LABEL_CHECK = sh returnStdout: true, script: 'ci-scripts/checkGitLabMergeRequestLabels.sh --mr-id ' + env.gitlabMergeRequestIid
|
|
LABEL_CHECK = LABEL_CHECK.trim()
|
|
if (LABEL_CHECK == 'NONE') {
|
|
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Your merge request should have one of the mandatory labels:\n\n"
|
|
message += " - ~documentation (don't perform any stages)\n"
|
|
message += " - ~BUILD-ONLY (execute only build stages)\n"
|
|
message += " - ~4G-LTE (perform 4G tests)\n"
|
|
message += " - ~5G-NR (perform 5G tests)\n"
|
|
message += " - ~CI (perform both 4G and 5G tests)\n"
|
|
message += " - ~nrUE (perform only 5G-UE related tests including physims excluding LDPC tests)\n\n"
|
|
message += "Not performing CI due to lack of labels"
|
|
addGitLabMRComment comment: message
|
|
error('Not performing CI due to lack of labels')
|
|
} else if (LABEL_CHECK == 'FULL') {
|
|
do4Gtest = true
|
|
do5Gtest = true
|
|
do5GUeTest = true
|
|
} else if (LABEL_CHECK == "SHORTEN-4G") {
|
|
do4Gtest = true
|
|
} else if (LABEL_CHECK == 'SHORTEN-5G') {
|
|
do5Gtest = true
|
|
} else if (LABEL_CHECK == 'SHORTEN-5G-UE') {
|
|
do5GUeTest = true
|
|
} else if (LABEL_CHECK == 'SHORTEN-4G-5G-UE') {
|
|
do4Gtest = true
|
|
do5GUeTest = true
|
|
} else if (LABEL_CHECK == 'documentation') {
|
|
doBuild = false
|
|
} else {
|
|
// is "BUILD-ONLY", will only build
|
|
}
|
|
} else {
|
|
do4Gtest = true
|
|
do5Gtest = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("Verify Guidelines") {
|
|
steps {
|
|
echo "Git URL is ${GIT_URL}"
|
|
echo "GitLab Act is ${env.gitlabActionType}"
|
|
script {
|
|
if ("MERGE".equals(env.gitlabActionType)) {
|
|
// since a bit, in push events, gitlabUserEmail is not populated
|
|
gitCommitAuthorEmailAddr = env.gitlabUserEmail
|
|
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
|
|
// Validate MR commits: checks for missing Signed-off-by and merge commits
|
|
def mrValidationLog = "signedCommit_${env.BUILD_NUMBER}.log"
|
|
def mrValidationExitCode = sh(
|
|
script: "bash ./ci-scripts/pre-ci-check.sh -s origin/${env.gitlabSourceBranch} -t origin/${env.gitlabTargetBranch} > ${mrValidationLog} 2>&1",
|
|
returnStatus: true
|
|
)
|
|
def mrValidationMessage = readFile(mrValidationLog).trim()
|
|
sh "rm -f ${mrValidationLog}"
|
|
if (mrValidationExitCode >= 1) {
|
|
addGitLabMRComment comment: "${mrValidationMessage}"
|
|
}
|
|
if (mrValidationExitCode >= 2) {
|
|
error("${mrValidationMessage}")
|
|
}
|
|
} else {
|
|
echo "Git Branch is ${GIT_BRANCH}"
|
|
echo "Git Commit is ${GIT_COMMIT}"
|
|
// since a bit, in push events, gitlabUserEmail is not populated
|
|
gitCommitAuthorEmailAddr = sh returnStdout: true, script: 'git log -n1 --pretty=format:%ae ${GIT_COMMIT}'
|
|
gitCommitAuthorEmailAddr = gitCommitAuthorEmailAddr.trim()
|
|
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("Local-Repo-Push") {
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-Local-Repo-Push', 'Local-Repo-Push')
|
|
}
|
|
}
|
|
post {
|
|
failure {
|
|
script {
|
|
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Cannot perform CI - merge validation failed (merge conflict, git operation failure, or internal CI error)."
|
|
addGitLabMRComment comment: message
|
|
currentBuild.result = 'FAILURE'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Build Stages are Mandatory
|
|
stage ("Image Building Processes") {
|
|
when { expression {doBuild} }
|
|
parallel {
|
|
stage ("Ubuntu-Image-Builder") {
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-Ubuntu18-Image-Builder', 'Ubuntu-Image-Builder')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
ubuntuBuildStatus = finalizeDownstreamJob('RAN-Ubuntu18-Image-Builder')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += ubuntuBuildStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("Ubuntu-ARM-Image-Builder") {
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-Ubuntu-ARM-Image-Builder', 'Ubuntu-ARM-Image-Builder')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
ubuntuArmBuildStatus = finalizeDownstreamJob('RAN-Ubuntu-ARM-Image-Builder')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += ubuntuArmBuildStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("Ubuntu-Jetson-Image-Builder") {
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-Ubuntu-Jetson-Image-Builder', 'Ubuntu-Jetson-Image-Builder')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
ubuntuJetsonBuildStatus = finalizeDownstreamJob('RAN-Ubuntu-Jetson-Image-Builder')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += ubuntuJetsonBuildStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("RHEL-Cluster-Image-Builder") {
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-RHEL8-Cluster-Image-Builder', 'RHEL-Cluster-Image-Builder')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
rhelBuildStatus = finalizeDownstreamJob('RAN-RHEL8-Cluster-Image-Builder')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += rhelBuildStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("ARM-Cross-Compile") {
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-ARM-Cross-Compile-Builder', 'ARM-Cross-Compilation')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
armBuildStatus = finalizeDownstreamJob('RAN-ARM-Cross-Compile-Builder')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += armBuildStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("DockerHub-Push") {
|
|
when { expression {doBuild && "PUSH".equals(env.gitlabActionType)} }
|
|
steps {
|
|
script {
|
|
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
|
triggerDownstreamJob ('RAN-DockerHub-Push', 'DockerHub-Push')
|
|
}
|
|
}
|
|
}
|
|
post {
|
|
failure {
|
|
script {
|
|
echo "Push to Docker-Hub KO"
|
|
failingStages += '\n * RAN-DockerHub-Push'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("Image Test Processes") {
|
|
when { expression {doBuild} }
|
|
parallel {
|
|
stage ("PhySim-Cluster-5G") {
|
|
when { expression {do5Gtest || do5GUeTest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-PhySim-Cluster-5G', 'PhySim-Cluster-5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
physim5GStatus = finalizeDownstreamJob('RAN-PhySim-Cluster-5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += physim5GStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("PhySim-GraceHopper-5G") {
|
|
when { expression {do5Gtest || do5GUeTest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-PhySim-GraceHopper-5G', 'PhySim-GraceHopper-5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
physimGH5GStatus = finalizeDownstreamJob('RAN-PhySim-GraceHopper-5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += physimGH5GStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("Channel-Simulation") {
|
|
when { expression {do5Gtest || do5GUeTest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-Channel-Simulation', 'Channel-Simulation')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
channelSimStatus = finalizeDownstreamJob('RAN-Channel-Simulation')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += channelSimStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("PhySim-Cluster-4G") {
|
|
when { expression {do4Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-PhySim-Cluster-4G', 'PhySim-Cluster-4G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
physim4GStatus = finalizeDownstreamJob('RAN-PhySim-Cluster-4G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += physim4GStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("RF-Sim-Test-4G") {
|
|
when { expression {do4Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-RF-Sim-Test-4G', 'RF-Sim-Test-4G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
rfSim4GStatus = finalizeDownstreamJob('RAN-RF-Sim-Test-4G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += rfSim4GStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("VRT-Sim-Test-5G") {
|
|
when { expression {do5Gtest || do5GUeTest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-VRT-Sim-Test-5G', 'VRT-Sim-Test-5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
vrtSim5GStatus = finalizeDownstreamJob('RAN-VRT-Sim-Test-5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += vrtSim5GStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("RF-Sim-Test-5G") {
|
|
when { expression {do5Gtest || do5GUeTest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-RF-Sim-Test-5G', 'RF-Sim-Test-5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
rfSim5GStatus = finalizeDownstreamJob('RAN-RF-Sim-Test-5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += rfSim5GStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("OAI-FLEXRIC-RAN-Integration-Test") {
|
|
when { expression {do5Gtest || do5GUeTest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('OAI-FLEXRIC-RAN-Integration-Test', 'OAI-FLEXRIC-RAN-Integration-Test')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
flexricRAN5GStatus = finalizeDownstreamJob('OAI-FLEXRIC-RAN-Integration-Test')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += flexricRAN5GStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("L2-Sim-Test-4G") {
|
|
when { expression {do4Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-L2-Sim-Test-4G', 'L2-Sim-Test-4G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
l2Sim4GStatus = finalizeDownstreamJob('RAN-L2-Sim-Test-4G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += l2Sim4GStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("LTE-B200-FDD-LTEBOX-Container") {
|
|
when { expression {do4Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-LTE-FDD-LTEBOX-Container', 'LTE-FDD-LTEBOX-Container')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
lteTDDB200Status = finalizeDownstreamJob('RAN-LTE-FDD-LTEBOX-Container')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += lteTDDB200Status
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Pipeline to test OAI LTE-UE
|
|
stage ("LTE-B200-FDD-OAIUE-OAICN4G-Container") {
|
|
when { expression {do4Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-LTE-FDD-OAIUE-OAICN4G-Container', 'LTE-FDD-OAIUE-OAICN4G-Container')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
lteFDDB200OAIUEStatus = finalizeDownstreamJob('RAN-LTE-FDD-OAIUE-OAICN4G-Container')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += lteFDDB200OAIUEStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("LTE-B200-TDD-LTEBOX-Container") {
|
|
when { expression {do4Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-LTE-TDD-LTEBOX-Container', 'LTE-TDD-LTEBOX-Container')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
lteFDDB200Status = finalizeDownstreamJob('RAN-LTE-TDD-LTEBOX-Container')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += lteFDDB200Status
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("NSA-B200-Module-LTEBOX-Container") {
|
|
when { expression {do4Gtest || do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-NSA-B200-Module-LTEBOX-Container', 'NSA-B200-Module-LTEBOX-Container')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
nsaTDDB200Status = finalizeDownstreamJob('RAN-NSA-B200-Module-LTEBOX-Container')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += nsaTDDB200Status
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("SA-B200-Module-SABOX-Container") {
|
|
when { expression {do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-SA-B200-Module-SABOX-Container', 'SA-B200-Module-SABOX-Container')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
saTDDB200Status = finalizeDownstreamJob('RAN-SA-B200-Module-SABOX-Container')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += saTDDB200Status
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("gNB-N300-Timing-Phytest-LDPC") {
|
|
when { expression {do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-gNB-N300-Timing-Phytest-LDPC', 'gNB-N300-Timing-Phytest-LDPC')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
phytestLDPCoffloadStatus = finalizeDownstreamJob('RAN-gNB-N300-Timing-Phytest-LDPC')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += phytestLDPCoffloadStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("LTE-TDD-2x2-Container") {
|
|
when { expression {do4Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-LTE-TDD-2x2-Container', 'LTE-TDD-2x2-Container')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
lteTDD2x2N3xxStatus = finalizeDownstreamJob('RAN-LTE-TDD-2x2-Container')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += lteTDD2x2N3xxStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("SA-AW2S-CN5G") {
|
|
when { expression {do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-SA-AW2S-CN5G', 'SA-AW2S-CN5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
saAW2SStatus = finalizeDownstreamJob('RAN-SA-AW2S-CN5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += saAW2SStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("Sanity-Check OAI-CN5G") {
|
|
when { expression {do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerCN5GDownstreamJob ('OAI-CN5G-COTS-UE-Test', 'OAI-CN5G-COTS-UE-Test')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
cn5gCOTSUESanityCheck = finalizeDownstreamJob('OAI-CN5G-COTS-UE-Test')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += cn5gCOTSUESanityCheck
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("SA-AERIAL-CN5G") {
|
|
when { expression {do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-SA-AERIAL-CN5G', 'SA-AERIAL-CN5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
saAERIALStatus = finalizeDownstreamJob('RAN-SA-AERIAL-CN5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += saAERIALStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("SA-Multi-Antenna-CN5G") {
|
|
when { expression {do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-SA-Multi-Antenna-CN5G', 'SA-Multi-Antenna-CN5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
saMultiAntennaStatus = finalizeDownstreamJob('RAN-SA-Multi-Antenna-CN5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += saMultiAntennaStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("SA-FHI72-CN5G") {
|
|
when { expression {do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-SA-FHI72-CN5G', 'SA-FHI72-CN5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
saFHI72Status = finalizeDownstreamJob('RAN-SA-FHI72-CN5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += saFHI72Status
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("SA-FHI72-MPLANE-CN5G") {
|
|
when { expression {do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-SA-FHI72-MPLANE-CN5G', 'SA-FHI72-MPLANE-CN5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
saFHI72MplaneStatus = finalizeDownstreamJob('RAN-SA-FHI72-MPLANE-CN5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += saFHI72MplaneStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("SA-Handover-CN5G") {
|
|
when { expression {do5Gtest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-SA-Handover-CN5G', 'SA-Handover-CN5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
saHandoverStatus = finalizeDownstreamJob('RAN-SA-Handover-CN5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += saHandoverStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("SA-AERIAL-OAIUE-CN5G") {
|
|
when { expression {do5Gtest || do5GUeTest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-SA-AERIAL-OAIUE-CN5G', 'SA-AERIAL-OAIUE-CN5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
saAERIALOAIUEStatus = finalizeDownstreamJob('RAN-SA-AERIAL-OAIUE-CN5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += saAERIALOAIUEStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
stage ("SA-OAIUE-CN5G") {
|
|
when { expression {do5Gtest || do5GUeTest} }
|
|
steps {
|
|
script {
|
|
triggerDownstreamJob ('RAN-SA-OAIUE-CN5G', 'SA-OAIUE-CN5G')
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
script {
|
|
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
|
// due to parallel-time concurrency
|
|
saOAIUEStatus = finalizeDownstreamJob('RAN-SA-OAIUE-CN5G')
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
currentBuild.result = 'FAILURE'
|
|
failingStages += saOAIUEStatus
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
post {
|
|
success {
|
|
script {
|
|
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")"
|
|
if ("MERGE".equals(env.gitlabActionType)) {
|
|
addGitLabMRComment comment: message
|
|
def message2 = message + " -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")"
|
|
}
|
|
echo "Pipeline is SUCCESSFUL"
|
|
}
|
|
}
|
|
failure {
|
|
script {
|
|
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")"
|
|
if ("MERGE".equals(env.gitlabActionType)) {
|
|
def fullMessage = message + '\n\nList of failing test stages:' + failingStages
|
|
addGitLabMRComment comment: fullMessage
|
|
def message2 = message + " -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")"
|
|
}
|
|
echo "Pipeline FAILED"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ---- Slave Job functions
|
|
|
|
def triggerDownstreamJob (jobName, gitlabStatusName) {
|
|
def MR_NUMBER = "MERGE".equals(env.gitlabActionType) ? env.gitlabMergeRequestIid : 'develop'
|
|
// Workaround for the "cancelled" GitLab pipeline notification
|
|
// The downstream job is triggered with the propagate false so the following commands are executed
|
|
// Its status is now PASS/SUCCESS from a stage pipeline point of view
|
|
// localStatus variable MUST be analyzed to properly assess the status
|
|
def localStatus = build job: jobName,
|
|
parameters: [
|
|
string(name: 'targetRepo', value: String.valueOf(env.gitlabTargetRepoHttpUrl)),
|
|
string(name: 'sourceRepo', value: String.valueOf(env.gitlabSourceRepoHttpUrl)),
|
|
string(name: 'sourceBranch', value: String.valueOf(env.gitlabSourceBranch)),
|
|
string(name: 'sourceCommit', value: String.valueOf(env.gitlabMergeRequestLastCommit)),
|
|
string(name: 'requestNumber', value: String.valueOf(MR_NUMBER)),
|
|
booleanParam(name: 'mergeWithTarget', value: "MERGE".equals(env.gitlabActionType)),
|
|
string(name: 'targetBranch', value: String.valueOf(env.gitlabTargetBranch)),
|
|
string(name: 'repository', value: String.valueOf(params.ciRepositoryURL)),
|
|
string(name: 'branch', value: "${env.gitlabSourceBranch.replace('/', '-')}-${env.gitlabMergeRequestLastCommit}")
|
|
], propagate: false
|
|
def localResult = localStatus.getResult()
|
|
echo "${jobName} Slave Job status is ${localResult}"
|
|
gitlabCommitStatus(name: gitlabStatusName) {
|
|
if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
|
|
echo "${jobName} Slave Job is OK"
|
|
} else {
|
|
error "${jobName} Slave Job is KO"
|
|
}
|
|
}
|
|
}
|
|
|
|
def triggerCN5GDownstreamJob (jobName, gitlabStatusName) {
|
|
if ("MERGE".equals(env.gitlabActionType)) {
|
|
fullRanTag = OAI_Registry + '/oai-gnb:' + "${env.gitlabSourceBranch.replace('/', '-')}-${env.gitlabMergeRequestLastCommit}"
|
|
} else {
|
|
fullRanTag = OAI_Registry + '/oai-gnb:develop-' + env.GIT_COMMIT
|
|
}
|
|
// Workaround for the "cancelled" GitLab pipeline notification
|
|
// The downstream job is triggered with the propagate false so the following commands are executed
|
|
// Its status is now PASS/SUCCESS from a stage pipeline point of view
|
|
// localStatus variable MUST be analyzed to properly assess the status
|
|
def localStatus = build job: jobName,
|
|
parameters: [
|
|
string(name: 'FULL_RAN_TAG', value: String.valueOf(fullRanTag))
|
|
], propagate: false
|
|
def localResult = localStatus.getResult()
|
|
echo "${jobName} Slave Job status is ${localResult}"
|
|
gitlabCommitStatus(name: gitlabStatusName) {
|
|
if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
|
|
echo "${jobName} Slave Job is OK"
|
|
} else {
|
|
error "${jobName} Slave Job is KO"
|
|
}
|
|
}
|
|
}
|
|
|
|
def finalizeDownstreamJob(jobName) {
|
|
lock ('Parent-Lock') {
|
|
// In case of any non-success, we are retrieving the HTML report of the last completed
|
|
// downstream job. The only drop-back is that we may retrieve the HTML report of a previous build
|
|
if (jobName == 'OAI-CN5G-COTS-UE-Test') {
|
|
fileName = "test_results_oai_cn5g_cots_ue.html"
|
|
} else {
|
|
fileName = "test_results-${jobName}.html"
|
|
}
|
|
artifactUrl = BUILD_URL
|
|
if (!fileExists(fileName)) {
|
|
copyArtifacts(projectName: jobName,
|
|
filter: 'test_results*.html',
|
|
selector: lastCompleted(),
|
|
optional: true)
|
|
if (fileExists(fileName)) {
|
|
sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${env.JOB_TIMESTAMP}#' ${fileName}"
|
|
} else {
|
|
sh "echo \"could not copy results from ${jobName}, please check pipeline ${BUILD_URL}\" > ${fileName}"
|
|
}
|
|
archiveArtifacts artifacts: fileName
|
|
// BUILD_URL is like http://server:port/jenkins/job/foo/15/
|
|
// no need to add a prefixed '/'
|
|
artifactUrl += 'artifact/' + fileName
|
|
}
|
|
artifactUrl = "\n * [${jobName}](${artifactUrl})"
|
|
return artifactUrl
|
|
}
|
|
}
|