feat(standard-make): create standard make-based pipeline
This commit is contained in:
parent
83867e3a98
commit
6f0de93c77
|
@ -0,0 +1,26 @@
|
|||
ARG JQ_VERSION=1.6
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
wget tar curl ca-certificates \
|
||||
openssl bash git unzip build-essential gnupg
|
||||
|
||||
COPY add-letsencrypt-ca.sh /root/add-letsencrypt-ca.sh
|
||||
|
||||
RUN bash /root/add-letsencrypt-ca.sh \
|
||||
&& rm -f /root/add-letsencrypt-ca.sh
|
||||
|
||||
# Install JQ
|
||||
RUN wget -O /usr/local/bin/jq https://github.com/stedolan/jq/releases/download/jq-${JQ_VERSION}/jq-linux64 \
|
||||
&& chmod +x /usr/local/bin/jq
|
||||
|
||||
# Install Docker client
|
||||
RUN install -m 0755 -d /etc/apt/keyrings \
|
||||
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
|
||||
&& chmod a+r /etc/apt/keyrings/docker.gpg \
|
||||
&& echo \
|
||||
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
||||
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
|
||||
tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y docker-ce-cli
|
|
@ -0,0 +1,220 @@
|
|||
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
|
||||
|
||||
void call(Map options = [:]) {
|
||||
Map hooks = options.get('hooks', [
|
||||
'pre': null,
|
||||
|
||||
'pre-test': null,
|
||||
'post-test': null,
|
||||
|
||||
'pre-build': null,
|
||||
'post-build': null,
|
||||
|
||||
'pre-release': null,
|
||||
'post-release': null,
|
||||
|
||||
'post-success': null,
|
||||
'post-always': null,
|
||||
'post-failure': null,
|
||||
])
|
||||
String testTask = options.get('testTask', 'test')
|
||||
String buildTask = options.get('buildTask', 'build')
|
||||
String releaseTask = options.get('releaseTask', 'release')
|
||||
String jobHistory = options.get('jobHistory', '5')
|
||||
|
||||
String baseDockerfile = options.get('baseDockerfile', '')
|
||||
String baseImage = options.get('baseImage', 'reg.cadoles.com/proxy_cache/library/ubuntu:22.04')
|
||||
String dockerfileExtension = options.get('dockerfileExtension', '')
|
||||
List credentials = options.get('credentials', [])
|
||||
|
||||
List<String> releaseBranches = options.get('releaseBranches', ['develop', 'testing', 'stable'])
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
try {
|
||||
def containerImage = buildContainerImage(baseImage, baseDockerfile, 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}"
|
||||
}
|
||||
|
||||
withCredentials(credentials) {
|
||||
stage('Run pre hooks') {
|
||||
runHook(hooks, 'pre')
|
||||
}
|
||||
|
||||
stage('Run tests') {
|
||||
runHook(hooks, 'pre-test')
|
||||
|
||||
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
|
||||
def ( status, output ) = runAndCaptureTask('testTask', testTask)
|
||||
|
||||
if (!!output.trim() && env.CHANGE_ID) {
|
||||
String gitCommit = sh(script: 'git rev-parse --short HEAD', returnStdout: true)
|
||||
String report = """
|
||||
|# Test report for ${gitCommit}
|
||||
|
|
||||
|```
|
||||
|${output}
|
||||
|```
|
||||
|""".trim().stripMargin()
|
||||
|
||||
gitea.commentPullRequest(repo, env.CHANGE_ID, report)
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
throw new Exception("Task `${testTask}` failed !")
|
||||
}
|
||||
}
|
||||
|
||||
runHook(hooks, 'post-test')
|
||||
}
|
||||
|
||||
stage('Build project') {
|
||||
runHook(hooks, 'pre-build')
|
||||
runTask('buildTask', buildTask)
|
||||
runHook(hooks, 'post-build')
|
||||
}
|
||||
|
||||
stage('Release project') {
|
||||
if (releaseBranches.contains(env.BRANCH_NAME)) {
|
||||
try {
|
||||
runHook(hooks, 'pre-release')
|
||||
runTask('releaseTask', releaseTask)
|
||||
runHook(hooks, 'post-release')
|
||||
} catch (Exception ex) {
|
||||
rocketSend(
|
||||
message: """
|
||||
|:warning: Une erreur est survenue lors de la publication de ${env.JOB_NAME}:
|
||||
|
|
||||
|```
|
||||
|${ex}
|
||||
|```
|
||||
|
|
||||
|[Visualiser le job](${env.RUN_DISPLAY_URL})
|
||||
|
|
||||
|@${utils.getBuildUser()}
|
||||
""".stripMargin(),
|
||||
rawMessage: true
|
||||
)
|
||||
|
||||
throw ex
|
||||
}
|
||||
|
||||
rocketSend(
|
||||
message: """
|
||||
|:white_check_mark: Nouvelle publication terminée de ${env.JOB_NAME}:
|
||||
|
|
||||
|[Visualiser le job](${env.RUN_DISPLAY_URL})
|
||||
|
|
||||
|@${utils.getBuildUser()}
|
||||
""".stripMargin(),
|
||||
rawMessage: true
|
||||
)
|
||||
} else {
|
||||
println("Current branch '${env.BRANCH_NAME}' not in releases branches (${releaseBranches}). Skipping.")
|
||||
Utils.markStageSkippedForConditional('Release project')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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 baseDockerfile, String dockerfileExtension) {
|
||||
String imageName = 'cadoles-standard-make-ci'
|
||||
dir(".${imageName}") {
|
||||
String dockerfile = ''
|
||||
|
||||
if (baseDockerfile) {
|
||||
dockerfile = baseDockerfile
|
||||
} else {
|
||||
dockerfile = libraryResource 'com/cadoles/standard-make/Dockerfile'
|
||||
dockerfile = "FROM ${baseImage}\n" + dockerfile
|
||||
}
|
||||
|
||||
dockerfile = """
|
||||
${dockerfile}
|
||||
${dockerfileExtension}
|
||||
"""
|
||||
|
||||
writeFile file:'Dockerfile', text: 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 !")
|
||||
}
|
||||
}
|
||||
|
||||
void runTask(String name, task) {
|
||||
if (!task) {
|
||||
println("No task '${name}' defined. Skipping.")
|
||||
return [ -1, '' ]
|
||||
}
|
||||
|
||||
sh(script: """#!/bin/bash
|
||||
make ${task}
|
||||
""")
|
||||
}
|
||||
|
||||
List runAndCaptureTask(String name, task) {
|
||||
if (!task) {
|
||||
println("No task '${name}' defined. Skipping.")
|
||||
return [ -1, '' ]
|
||||
}
|
||||
|
||||
String outputFile = ".${name}-output"
|
||||
int status = sh(script: """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make ${task} 2>&1 | tee '${outputFile}'
|
||||
""", returnStatus: true)
|
||||
|
||||
String output = readFile(outputFile)
|
||||
|
||||
sh(script: "rm -f '${outputFile}'")
|
||||
|
||||
return [status, output]
|
||||
}
|
Loading…
Reference in New Issue