245 lines
10 KiB
Groovy
245 lines
10 KiB
Groovy
pipeline {
|
|
parameters {
|
|
string(
|
|
name: 'IMAGE_VERSION',
|
|
defaultValue: '',
|
|
description: 'Optional override for the Docker image tag (e.g., stable, release, 0.0.2). Leave empty to use the commit hash.'
|
|
)
|
|
string(
|
|
name: 'GIT_REF',
|
|
defaultValue: '',
|
|
description: 'Branch or tag to build. Leave empty to use Jenkins-provided branch or default to main.'
|
|
)
|
|
booleanParam(
|
|
name: 'CLEAN_BUILD',
|
|
defaultValue: false,
|
|
description: 'Run docker build --pull --no-cache when true.'
|
|
)
|
|
}
|
|
|
|
agent any
|
|
|
|
environment {
|
|
GIT_URL = 'https://gitea.mindboost.team/mindboost/education-flagger.git'
|
|
HEADER_IMAGE_NAME = 'mindboost/education-flagger-header'
|
|
UPDATER_IMAGE_NAME = 'mindboost/education-flagger-updater'
|
|
LOCAL_HEADER_IMAGE_NAME = 'education_flagger_header_image'
|
|
LOCAL_UPDATER_IMAGE_NAME = 'education_flagger_updater_image'
|
|
GIT_CREDENTIALS_ID = 'b5f383be-8c74-40f9-b7e1-3a9c5856df0e'
|
|
REGISTRY_CREDENTIALS_ID = '62d300cc-d8c6-437a-8699-c58b9e1edcb0'
|
|
REGISTRY_SCHEME = 'https'
|
|
REGISTRY_HOST = 'gitea.mindboost.team'
|
|
}
|
|
|
|
stages {
|
|
stage('Checkout') {
|
|
steps {
|
|
script {
|
|
def selectedRef = params?.GIT_REF?.trim()
|
|
if (!selectedRef) {
|
|
selectedRef = env.CHANGE_BRANCH ?: env.BRANCH_NAME ?: env.GIT_BRANCH
|
|
}
|
|
if (!selectedRef) {
|
|
selectedRef = 'main'
|
|
echo "No GIT_REF supplied. Falling back to 'main'."
|
|
}
|
|
|
|
def normalizedRef = selectedRef.replaceFirst('^origin/', '')
|
|
def branchSpec = normalizedRef.startsWith('refs/') ? normalizedRef : "*/${normalizedRef}"
|
|
echo "Checking out '${branchSpec}' from ${env.GIT_URL}"
|
|
|
|
checkout([
|
|
$class: 'GitSCM',
|
|
branches: [[name: branchSpec]],
|
|
userRemoteConfigs: [[
|
|
url: env.GIT_URL,
|
|
credentialsId: env.GIT_CREDENTIALS_ID
|
|
]]
|
|
])
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Check Repository') {
|
|
steps {
|
|
script {
|
|
sh 'pwd'
|
|
sh 'ls -la'
|
|
sh 'git status'
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Determine Version') {
|
|
steps {
|
|
script {
|
|
def imageVersion = ''
|
|
|
|
if (params?.IMAGE_VERSION) {
|
|
imageVersion = params.IMAGE_VERSION.trim()
|
|
echo "Using build parameter IMAGE_VERSION=${imageVersion}"
|
|
}
|
|
|
|
if (!imageVersion) {
|
|
def longSha = sh(
|
|
script: 'git rev-parse HEAD',
|
|
returnStdout: true
|
|
).trim()
|
|
imageVersion = "sha256-${longSha}"
|
|
echo "No IMAGE_VERSION provided. Falling back to commit hash: ${imageVersion}"
|
|
}
|
|
|
|
def sanitized = imageVersion.replaceAll('[^A-Za-z0-9_.-]', '-')
|
|
if (sanitized != imageVersion) {
|
|
echo "Sanitized version value from '${imageVersion}' to '${sanitized}' for Docker tag compatibility."
|
|
}
|
|
|
|
env.IMAGE_TAG = sanitized
|
|
echo "Resolved image tag: ${env.IMAGE_TAG}"
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Get Commit Hash') {
|
|
steps {
|
|
script {
|
|
env.GIT_COMMIT_SHORT = sh(
|
|
script: 'git rev-parse --short HEAD',
|
|
returnStdout: true
|
|
).trim()
|
|
echo "Commit Hash: ${env.GIT_COMMIT_SHORT}"
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Check Docker Images with the same tag') {
|
|
steps {
|
|
script {
|
|
def cleanBuild = params?.CLEAN_BUILD == true
|
|
def headerImageExists = sh(
|
|
script: "docker images -q ${env.LOCAL_HEADER_IMAGE_NAME}:${env.IMAGE_TAG} || true",
|
|
returnStdout: true
|
|
).trim()
|
|
def updaterImageExists = sh(
|
|
script: "docker images -q ${env.LOCAL_UPDATER_IMAGE_NAME}:${env.IMAGE_TAG} || true",
|
|
returnStdout: true
|
|
).trim()
|
|
|
|
if (cleanBuild) {
|
|
echo "CLEAN_BUILD=true: ignoring existing local images for tag ${env.IMAGE_TAG}."
|
|
} else if (headerImageExists && updaterImageExists) {
|
|
echo "Both Docker images with tag ${env.IMAGE_TAG} already exist locally. Skipping build."
|
|
currentBuild.result = 'SUCCESS'
|
|
return
|
|
} else {
|
|
echo 'At least one local Docker image is missing. Building fresh images.'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Build Docker Images') {
|
|
when {
|
|
expression { currentBuild.result == null }
|
|
}
|
|
steps {
|
|
script {
|
|
def cleanBuild = params?.CLEAN_BUILD == true
|
|
def buildFlags = cleanBuild ? '--pull --no-cache ' : ''
|
|
sh "docker build ${buildFlags}-t ${env.LOCAL_HEADER_IMAGE_NAME}:${env.IMAGE_TAG} ."
|
|
sh "docker build ${buildFlags}-t ${env.LOCAL_UPDATER_IMAGE_NAME}:${env.IMAGE_TAG} ./asn-updater"
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Push Docker Images') {
|
|
when {
|
|
expression { currentBuild.result == null }
|
|
}
|
|
steps {
|
|
script {
|
|
withCredentials([
|
|
usernamePassword(
|
|
credentialsId: env.REGISTRY_CREDENTIALS_ID,
|
|
usernameVariable: 'REGISTRY_USER',
|
|
passwordVariable: 'REGISTRY_PASS'
|
|
)
|
|
]) {
|
|
def registryAuthority = env.REGISTRY_HOST
|
|
def registryEndpoint = "${env.REGISTRY_SCHEME}://${registryAuthority}"
|
|
def remoteHeaderImageTag = "${registryAuthority}/${env.HEADER_IMAGE_NAME}:${env.IMAGE_TAG}"
|
|
def remoteUpdaterImageTag = "${registryAuthority}/${env.UPDATER_IMAGE_NAME}:${env.IMAGE_TAG}"
|
|
|
|
withEnv([
|
|
"REGISTRY_AUTHORITY=${registryAuthority}",
|
|
"REGISTRY_ENDPOINT=${registryEndpoint}",
|
|
"REMOTE_HEADER_IMAGE_TAG=${remoteHeaderImageTag}",
|
|
"REMOTE_UPDATER_IMAGE_TAG=${remoteUpdaterImageTag}"
|
|
]) {
|
|
sh '''
|
|
set -eux
|
|
if [ -z "${IMAGE_TAG:-}" ]; then
|
|
echo "IMAGE_TAG is empty. Did the Determine Version stage run?" >&2
|
|
exit 1
|
|
fi
|
|
if [ -z "${REGISTRY_USER:-}" ]; then
|
|
echo "REGISTRY_USER is empty. Check Jenkins credentials mapping." >&2
|
|
exit 1
|
|
fi
|
|
if [ -z "${REGISTRY_PASS:-}" ]; then
|
|
echo "REGISTRY_PASS is empty. Check Jenkins credentials mapping." >&2
|
|
exit 1
|
|
fi
|
|
if [ -z "${REGISTRY_AUTHORITY:-}" ]; then
|
|
echo "REGISTRY_AUTHORITY is empty. Registry authority not resolved." >&2
|
|
exit 1
|
|
fi
|
|
if [ -z "${REGISTRY_ENDPOINT:-}" ]; then
|
|
echo "REGISTRY_ENDPOINT is empty. Registry endpoint not resolved." >&2
|
|
exit 1
|
|
fi
|
|
if [ -z "${REMOTE_HEADER_IMAGE_TAG:-}" ]; then
|
|
echo "REMOTE_HEADER_IMAGE_TAG is empty. Derived header Docker tag missing." >&2
|
|
exit 1
|
|
fi
|
|
if [ -z "${REMOTE_UPDATER_IMAGE_TAG:-}" ]; then
|
|
echo "REMOTE_UPDATER_IMAGE_TAG is empty. Derived updater Docker tag missing." >&2
|
|
exit 1
|
|
fi
|
|
|
|
docker --version
|
|
docker info
|
|
docker image inspect "$LOCAL_HEADER_IMAGE_NAME:$IMAGE_TAG" >/dev/null
|
|
docker image inspect "$LOCAL_UPDATER_IMAGE_NAME:$IMAGE_TAG" >/dev/null
|
|
|
|
echo "Logging into Docker registry $REGISTRY_ENDPOINT as $REGISTRY_USER"
|
|
echo "$REGISTRY_PASS" | docker login "$REGISTRY_ENDPOINT" --username "$REGISTRY_USER" --password-stdin
|
|
docker tag "$LOCAL_HEADER_IMAGE_NAME:$IMAGE_TAG" "$REMOTE_HEADER_IMAGE_TAG"
|
|
docker tag "$LOCAL_UPDATER_IMAGE_NAME:$IMAGE_TAG" "$REMOTE_UPDATER_IMAGE_TAG"
|
|
echo "Pushing Docker image $REMOTE_HEADER_IMAGE_TAG to $REGISTRY_AUTHORITY"
|
|
docker push "$REMOTE_HEADER_IMAGE_TAG"
|
|
echo "Pushing Docker image $REMOTE_UPDATER_IMAGE_TAG to $REGISTRY_AUTHORITY"
|
|
docker push "$REMOTE_UPDATER_IMAGE_TAG"
|
|
docker logout "$REGISTRY_ENDPOINT"
|
|
'''
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Cleanup Docker Images') {
|
|
when {
|
|
expression { currentBuild.result == null }
|
|
}
|
|
steps {
|
|
sh '''
|
|
set -eux
|
|
docker image prune -f
|
|
docker builder prune -f
|
|
'''
|
|
}
|
|
}
|
|
}
|
|
}
|