gCubeActionExecutor/Jenkinsfile

182 lines
5.7 KiB
Groovy

#!groovy
/**
* Checkouts and executes actions over a list of repositories.
*
* Manuele Simi (ISTI-CNR)
*/
def agent_root_folder = '/var/lib/jenkins/.m2'
//locate the action file
String actionURL = "https://code-repo.d4science.org/manuele.simi/gCubeActions/raw/branch/main/actions/${action_file}"
println "Querying ${actionURL}"
//save the action code
def action_code = actionURL.toURL().getText()
//TODO: get the list of repos from Jenkins?
//locate the repos file
String repoURL = "https://code-repo.d4science.org/manuele.simi/gCubeActions/raw/branch/main/repos/${repo_list}"
println "Querying ${repoURL}"
//save the action code
def repo_content = repoURL.toURL().getText()
def projects = parseProjectList(repo_content)
pipeline {
agent {
label 'CD'
}
environment {
AGENT_ROOT_FOLDER = "${agent_root_folder}"
PIPELINE_BUILD_NUMBER = "${env.BUILD_NUMBER}"
ACTION_REPORT = "${agent_root_folder}/actions.${env.BUILD_NUMBER}.csv"
BASH_FRAGMENT="${action_code}"
REPO_ROOT="${repo_root}"
}
parameters {
string(name: 'repo_root',
defaultValue: 'https://code-repo.d4science.org/gCubeSystem/',
description: 'The root URL of the repositories')
string(name: 'repo_list',
defaultValue: 'default_list.txt',
description: 'The file with the list of repositories to update')
string(name: 'action_file',
defaultValue: '',
description: 'The file with the Bash fragment to execute.')
}
stages {
stage('initialize report') {
steps {
sh '''
date=`date`
echo "#Build ${PIPELINE_BUILD_NUMBER},," > $ACTION_REPORT
echo "#StartTime ${date},," >> $ACTION_REPORT
echo "Project,Repo,Result" >> $ACTION_REPORT
'''
}
}
stage('clone and exec') {
steps {
script {
for (int i = 0; i < projects.size(); i++) {
stage(projects[i]) {
echo "About to execute over ${projects[i]}"
checkout_and_exec(projects[i], action_code)
sh "echo -e ${projects[i]},'',Completed >> $ACTION_REPORT"
}
}
}
}
}
}
// post-build actions
post {
always {
script {
sh '''
cp $ACTION_REPORT ./actions.${PIPELINE_BUILD_NUMBER}.csv
cat ./actions.${PIPELINE_BUILD_NUMBER}.csv
'''
}
}
success {
echo 'The actions pipeline worked!'
emailext attachmentsPattern: "**/actions.${env.BUILD_NUMBER}.csv",
to: 'manuele.simi@isti.cnr.it',
subject: "Actions report(build #${PIPELINE_BUILD_NUMBER})",
body: "${currentBuild.fullDisplayName}. Build time: ${currentBuild.durationString}. See ${env.BUILD_URL}"
}
failure {
echo 'The actions pipeline has failed'
emailext attachLog: true,
to: 'manuele.simi@isti.cnr.it',
subject: "[Jenkins build D4S] build ${currentBuild.fullDisplayName} failed",
body: "Something is wrong with ${env.BUILD_URL}"
}
}
}
/**
* Clones the repository and executes the fragment
* NOTE: 'credentialsId' be manually configured in Jenkins to access all the repos
*/
def checkout_and_exec(repo_name, actions) {
def repo_url = "${repo_root}/${repo_name}"
sh(script: "rm -r ${repo_name} || true", returnStdout: true)?.trim()
checkout([
$class : 'GitSCM',
branches : [[name: '*/master']],
doGenerateSubmoduleConfigurations: false,
extensions : [
[$class: 'RelativeTargetDirectory', relativeTargetDir: repo_name],
[$class: 'CloneOption', noTags: false, reference: '']
],
submoduleCfg : [],
userRemoteConfigs : [
[credentialsId: '88b54962-1c0e-49cb-8155-22276860f346', url: repo_url] //git.gcube credentials on jenkins
]
])
// just to show we can access the cloned repository
get_last_commit(repo_name)
//exec the action
exec(actions, repo_url, repo_name)
}
String get_last_commit(repo_name) {
String msg;
dir(repo_name) {
msg = sh(script: 'git rev-parse HEAD', returnStdout: true)?.trim()
}
return msg;
}
/**
Execs the bash fragment
*/
def exec(actions, repo_url, repo_name) {
dir(repo_name) {
withCredentials([usernamePassword(credentialsId: '88b54962-1c0e-49cb-8155-22276860f346', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
def complete_url = "${repo_url}/${repo_name}.git"
def repository = complete_url.replaceFirst(".+://", "https://${GIT_USERNAME}:${GIT_PASSWORD}@")
sh("""
git remote set-url origin $repository
git remote -v
echo $actions > actions.sh
chmod a+x actions.sh
source actions.sh
rm actions.sh
git push --force origin
""")
}
}
}
//a non CPS method is necessary for the usage of splitEachLine()
@NonCPS
def parseProjectList(def text) {
def projects = []
text.readLines().each { project ->
if (!project)
return
projects.add(project)
}
return projects
}