import org.jenkinsci.plugins.pipeline.modeldefinition.Utils def call(Map options = [:]) { String baseImage = options.get('baseImage', 'reg.cadoles.com/proxy_cache/library/ubuntu:22.04') Map hooks = options.get('hooks', [ 'pre': null, 'post-success': null, 'post-always': null, 'post-failure': null, ]) Map tasks = options.get('tasks', [ 'test': 'test', 'build': 'build', 'release': 'release' ]) String jobHistory = options.get('jobHistory', '10') String dockerfileExtension = options.get('dockerfileExtension', '') node { properties([ buildDiscarder(logRotator(daysToKeepStr: jobHistory, numToKeepStr: jobHistory)), ]) stage('Cancel older jobs') { int buildNumber = env.BUILD_NUMBER as int if (buildNumber > 1) { milestone(buildNumber - 1) } milestone(buildNumber) } stage('Checkout project') { checkout(scm) } stage('Run pre hooks') { runHook(hooks, 'pre') } stage('Run in container') { try { def containerImage = buildContainerImage(baseImage, dockerfileExtension) containerImage.inside('-v /var/run/docker.sock:/var/run/docker.sock') { String repo = env.JOB_NAME if (env.BRANCH_NAME ==~ /^PR-.*$/) { repo = env.JOB_NAME - "/${env.JOB_BASE_NAME}" } stage('Run tests') { catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { String testReport = runTask(tasks, 'test', true) if (!!testReport?.trim()) { if (env.CHANGE_ID) { gitea.commentPullRequest(repo, env.CHANGE_ID, "# Test report\n\n ${testReport}") } else { print testReport } } } } stage('Build project') { runTask(tasks, 'build') } stage('Release project') { runTask(tasks, 'release') } } } catch(Exception ex) { runHook(hooks, 'post-failure', [ex]) throw ex } finally { runHook(hooks, 'post-always') cleanWs() } runHook(hooks, 'post-success') } } } void buildContainerImage(String baseImage, String dockerfileExtension) { String imageName = 'cadoles-standard-make-ci' dir(".${imageName}") { String dockerfile = libraryResource 'com/cadoles/standard-make/Dockerfile' dockerfile = """ ${dockerfile} ${dockerfileExtension} """ writeFile file:'Dockerfile', text: "FROM ${baseImage}\n\n" + dockerfile String addLetsEncryptCA = libraryResource 'com/cadoles/common/add-letsencrypt-ca.sh' writeFile file:'add-letsencrypt-ca.sh', text:addLetsEncryptCA String safeJobName = URLDecoder.decode(env.JOB_NAME).toLowerCase().replace('/', '-').replace(' ', '-') String imageTag = "${safeJobName}-${env.BUILD_ID}" return docker.build("${imageName}:${imageTag}", '.') } } void runHook(Map hooks, String name, List args = []) { if (!hooks[name]) { println("No hook '${name}' defined. Skipping.") return } if (hooks[name] instanceof Closure) { hooks[name](*args) } else { error("Hook '${name}' seems to be defined but is not a closure !") } } String runTask(Map tasks, String name, Boolean returnStdout = false) { if (!tasks[name]) { println("No task '${name}' defined. Skipping.") return } String result = sh(script: "make ${tasks[name]}", returnStdout: returnStdout) return result }