Newer
Older
#!groovy
// Load shared library at master branch
// the path to the repo with this library should be specified in Jenkins
// https://tomd.xyz/jenkins-shared-library/
// https://www.jenkins.io/doc/book/pipeline/shared-libraries/
@Library('nrp-shared-libs@master') _
// Before starting pipeline, we try to get the proper image tag
def DEFAULT_BRANCH = 'development'
// selectTopicBranch function is used to choose the correct branch name as topic
// the function is defined in shared libs
//
// In case there is a PR for a branch, then Jenkins runs a pipeline for this pull request, not for the branch,
// even if there are new commits to the branch (until PR is not closed). The BRANCH_NAME variable in this case is something like PR-###
// The name of the branch which is merged is stored in CHANGE_BRANCH variable. Thus, we should choose CHANGE_BRANCH as topic
//
// If there is a branch without PR, then Jenkins creates build for it normally for every push and the branch name is stored in BRANCH_NAME variable.
// CHANGE_BRANCH is empty in this case. Thus, we choose BRANCH_NAME as topic for branches without PR.
def TOPIC_BRANCH = selectTopicBranch(env.BRANCH_NAME, env.CHANGE_BRANCH)
// We try to pull the image with the topic name, or use default tag otherwise
def IMG_TAG = checkImageTag("${TOPIC_BRANCH}", "${DEFAULT_BRANCH}")
pipeline {
environment {
USER_SCRIPTS_DIR = "user-scripts"
ADMIN_SCRIPTS_DIR = "admin-scripts"
GAZEBO_ROS_DIR = "GazeboRosPackages"
EXP_CONTROL_DIR = "ExperimentControl"
CLE_DIR = "CLE"
BRAIN_SIMULATION_DIR = "BrainSimulation"
EXDBACKEND_DIR = "ExDBackend"
// GIT_CHECKOUT_DIR is a dir of the main project (that was pushed)
GIT_CHECKOUT_DIR = "${env.BRAIN_SIMULATION_DIR}"
// That is needed to pass the variables into environment with the same name from
// Jenkins global scope (def ..=..)
TOPIC_BRANCH = "${TOPIC_BRANCH}"
DEFAULT_BRANCH = "${DEFAULT_BRANCH}"
CODE_COVERAGE_LINE = 29
}
agent {
docker {
label 'ci_label'
// NEXUS_REGISTRY_IP and NEXUS_REGISTRY_PORT are Jenkins global variables
registryUrl "https://${env.NEXUS_REGISTRY_IP}:${env.NEXUS_REGISTRY_PORT}"
registryCredentialsId 'nexusadmin'
image "nrp:${IMG_TAG}"
args '--entrypoint="" -u root --privileged'
}
}
options {
// Skip code checkout prior running pipeline (only Jenkinsfile is checked out)
skipDefaultCheckout true
}
stages {
stage('Code checkout') {
steps {
// clear workspace
sh "rm -rf *"
// Notify BitBucket on the start of the job
// The Bitbucket Build Status Notifier is used
// REF: https://plugins.jenkins.io/bitbucket-build-status-notifier/
bitbucketStatusNotify(buildState: 'INPROGRESS', buildName: 'Code checkout')
// Debug information on available environment
echo sh(script: 'env|sort', returnStdout: true)
// Checkout main project to GIT_CHECKOUT_DIR
dir(env.GIT_CHECKOUT_DIR) {
checkout([
$class: "GitSCM",
branches: scm.branches,
extensions: [
[$class: 'CloneOption', noTags: false],
[$class: 'LocalBranch', localBranch: "**"]
],
userRemoteConfigs: scm.userRemoteConfigs
])
sh 'chown -R "${USER}" ./'
}
// Clone all dependencies
// cloneRepoTopic:
// 1 - directory to checkout
// 2 - repo
// 3 - name of topic branch
// 4 - default branch if topic unavailable
// 5 - username for chown
cloneRepoTopic(env.ADMIN_SCRIPTS_DIR, 'git@bitbucket.org:hbpneurorobotics/admin-scripts.git', env.TOPIC_BRANCH, 'master', '${USER}')
cloneRepoTopic(env.USER_SCRIPTS_DIR, 'git@bitbucket.org:hbpneurorobotics/user-scripts.git', env.TOPIC_BRANCH, env.DEFAULT_BRANCH, '${USER}')
cloneRepoTopic(env.GAZEBO_ROS_DIR, 'git@bitbucket.org:hbpneurorobotics/gazeborospackages.git', env.TOPIC_BRANCH, env.DEFAULT_BRANCH, '${USER}')
cloneRepoTopic(env.EXP_CONTROL_DIR, 'git@bitbucket.org:hbpneurorobotics/experimentcontrol.git', env.TOPIC_BRANCH, env.DEFAULT_BRANCH, '${USER}')
cloneRepoTopic(env.CLE_DIR, 'git@bitbucket.org:hbpneurorobotics/cle.git', env.TOPIC_BRANCH, env.DEFAULT_BRANCH, '${USER}')
cloneRepoTopic(env.EXDBACKEND_DIR, 'git@bitbucket.org:hbpneurorobotics/exdbackend.git', env.TOPIC_BRANCH, env.DEFAULT_BRANCH, '${USER}')
sh "git config --global --add safe.directory '*'"
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
}
}
stage('Build GazeboRosPackages') {
steps {
bitbucketStatusNotify(buildState: 'INPROGRESS', buildName: 'Building GazeboRosPackages')
// Use GazeboRosPackages build script
dir(env.GAZEBO_ROS_DIR){
// Determine explicitly the shell as bash (needed for proper user-scripts operation)
sh 'bash .ci/build.bash ${WORKSPACE}/${USER_SCRIPTS_DIR}/'
}
}
}
stage('Build and test BrainSimulation') {
steps {
bitbucketStatusNotify(buildState: 'INPROGRESS', buildName: 'Build and test ' + env.GIT_CHECKOUT_DIR)
dir(env.GIT_CHECKOUT_DIR){
// this is a workaround to pass all env vars into script run by the other user (now we are root)
// STAGE_NAME and CHANGE_* have spaces and is not imported then normally, thus delete it, because it's unneeded
// enquote all vars to avoid problems with spaces
sh 'env > .ci/env'
sh 'sudo -H -u bbpnrsoa bash .ci/build.bash'
// deliver artifacts
makeReports(false, env.CODE_COVERAGE_LINE)
}
}
}
}
post {
always {
dir(env.GIT_CHECKOUT_DIR){
archiveArtifacts 'p*.*'
archiveArtifacts 'test-reports/*.*'
archiveArtifacts 'coverage.xml'
}
}
aborted {
bitbucketStatusNotify(buildState: 'FAILED', buildDescription: 'Build aborted!')
}
failure {
bitbucketStatusNotify(buildState: 'FAILED', buildDescription: 'Build failed, see console output!')
}
success{
bitbucketStatusNotify(buildState: 'SUCCESSFUL', buildDescription: 'branch ' + env.GIT_BRANCH)
}
}
}