commit 7574d64450207aa9158d92a7b655eb92c4e6ceee Author: Manuele Simi Date: Sat Jan 16 15:57:51 2021 -0500 First sketch of the pipeline. diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..71985af --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,175 @@ +#!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/master/actions/${actionFile}" +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/master/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}" + + } + + parameters { + + 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 tag') { + 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 = "https://code-repo.d4science.org/gCubeSystem/{$repo_name}" + echo "Checkout SHA from reference $commit" + 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 repository = repo_url.replaceFirst(".+://", "https://${GIT_USERNAME}:${GIT_PASSWORD}@") + sh(""" + cat $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}".splitEachLine(',') { project -> + if (!project) + return + projects.add(project) + } + return projects +} \ No newline at end of file