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', [:]) Map tasks = options.get('tasks', [ 'test': 'test', 'build': 'build', 'release': 'release' ]) String jobHistory = options.get('jobHistory', '10') 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') { def containerImage = buildContainerImage(baseImage, hooks) 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') } stage('Run post hooks') { runHook(hooks, 'post') } } } } } void buildContainerImage(String baseImage, Map hooks) { String imageName = 'cadoles-standard-make-ci' dir(".${imageName}") { String dockerfile = libraryResource 'com/cadoles/standard-make/Dockerfile' 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}" runHook(hooks, 'image') return docker.build("${imageName}:${imageTag}", '.') } } void runHook(Map hooks, String name) { if (!hooks[name]) { println("No hook '${name}' defined. Skipping.") return } if (hooks[name] instanceof Closure) { hooks[name]() } 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 }