pipeline { agent any environment { CONTAINER_REGISTRY = credentials("container_registry") REGISTRY_NAMESPACE = credentials("registry_namespace") REPO_NAME = env.GIT_URL.replaceFirst(/^.*\/([^\/]+?).git$/, '$1') IMAGE_NAME = "${env.CONTAINER_REGISTRY}/${env.REGISTRY_NAMESPACE}/${env.REPO_NAME}:${env.BRANCH_NAME}" } stages { stage("Build") { when { tag "*" } steps { script { def architectures = ["aarch64", "x86_64"] def parallelStages = [:] for (arch in architectures) { def nodeLabel = arch parallelStages[arch] = { node(nodeLabel) { checkout scm def run_name = "${nodeLabel}-${env.BUILD_NUMBER}" def image_run_name = "${IMAGE_NAME}-${nodeLabel}-${env.BUILD_NUMBER}" sh "podman build -t ${image_run_name} ." sh "podman save -o ${run_name}.tar ${image_run_name}" stash includes: "${run_name}.tar", name: "${nodeLabel}-image" } } } parallel parallelStages env.ARCHITECTURES = architectures.join(',') } } } stage("Combine and Push") { when { tag "*" } agent any steps { script { def architectures = env.ARCHITECTURES.split(',') for (arch in architectures) { unstash "${arch}-image" sh "podman load -i ${arch}-${env.BUILD_NUMBER}.tar" } def manifestImages = architectures.collect { arch -> return "${IMAGE_NAME}-${arch}-${env.BUILD_NUMBER}" }.join(' ') sh """ podman manifest rm ${IMAGE_NAME} || true podman manifest create ${IMAGE_NAME} ${manifestImages} """ withCredentials([usernamePassword(credentialsId: "dockerhub", usernameVariable: "REG_USERNAME", passwordVariable: "REG_PASSWORD")]) { sh """ podman login ${CONTAINER_REGISTRY} -u ${REG_USERNAME} -p ${REG_PASSWORD} podman manifest push ${IMAGE_NAME} \ docker://${IMAGE_NAME} """ } } } } } }