From 5455c812854ebdf5555e1d663196da1d43ac5d84 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Thu, 17 Aug 2023 14:40:53 +0200 Subject: [PATCH 01/70] add the bake version for build and deploy --- resources/io/jenkins/infra/docker/Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index ff2007c29..209085b89 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -52,6 +52,11 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) "$(IMAGE_DIR)" @echo "== Build succeeded" +buildbake: ## Build the Docker Image(s) with dockerbake file + @echo "== Building from DockerBake file" + docker buildx create --use + docker buildx bake --load + clean: ## Delete any file generated during the build steps @echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:" rm -f "$(call FixPath,$(IMAGE_DIR)/*.tar)" "$(HADOLINT_REPORT)" @@ -69,4 +74,8 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). docker image push "$(IMAGE_DEPLOY_NAME)" @echo "== Deploy succeeded" +deploybake: ## Tag and push the built image as specified by docker bake file + @echo "== Deploying with docker bake file" + docker buildx bake --push + .PHONY: all clean lint build test deploy From c5552a96ffefc38512a52bd1ac2de2f1000601ce Mon Sep 17 00:00:00 2001 From: smerle33 Date: Thu, 17 Aug 2023 14:41:22 +0200 Subject: [PATCH 02/70] add the dockerbake flag --- vars/buildDockerAndPublishImage.groovy | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 26f6012d3..80f86b436 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -15,6 +15,7 @@ def call(String imageShortName, Map userConfig=[:]) { imageDir: '.', // Relative path to the context directory for the Docker build registryNamespace: '', // Empty by default (means "autodiscover based on the current controller") unstash: '', // Allow to unstash files if not empty + dockerBakeFile: false, // Allow to build from a bake file instead ] // Merging the 2 maps - https://blog.mrhaki.com/2010/04/groovy-goodness-adding-maps-to-map_21.html @@ -139,9 +140,17 @@ def call(String imageShortName, Map userConfig=[:]) { stage("Build ${imageName}") { if (isUnix()) { - sh 'make build' + if (finalConfig.dockerBakeFile) { + sh 'make buildbake' + } else { + sh 'make build' + } } else { - powershell 'make build' + if (finalConfig.dockerBakeFile) { + powershell 'make buildbake' + } else { + powershell 'make build' + } } } //stage @@ -221,10 +230,19 @@ def call(String imageShortName, Map userConfig=[:]) { withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}"]) { // Please note that "make deploy" uses the environment variable "IMAGE_DEPLOY_NAME" if (isUnix()) { - sh 'make deploy' + if (finalConfig.dockerBakeFile) { + sh 'make deploybake' + } else { + sh 'make deploy' + } } else { - powershell 'make deploy' + if (finalConfig.dockerBakeFile) { + powershell 'make deploybake' + } else { + powershell 'make deploy' + } } + } // withEnv } //stage } // if From a76cf12a7f9054f35c80a604dd475a73d1c409b1 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 10:42:14 +0200 Subject: [PATCH 03/70] docker bake file --- resources/io/jenkins/infra/docker/Makefile | 6 ++++-- vars/buildDockerAndPublishImage.groovy | 12 +++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 209085b89..2a40cfb3c 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -10,6 +10,8 @@ endif IMAGE_NAME ?= helloworld IMAGE_DEPLOY_NAME ?= "$(IMAGE_NAME)" IMAGE_PLATFORM ?= linux/amd64 +DOCKER_BAKE_FILE ?= "docker-bake.hcl" + # Paths IMAGE_DOCKERFILE ?= "$(IMAGE_DIR)"/Dockerfile HADOLINT_REPORT ?= "$(IMAGE_DIR)"/hadolint.json @@ -55,7 +57,7 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" docker buildx create --use - docker buildx bake --load + docker buildx bake -f ${DOCKER_BAKE_FILE} --load clean: ## Delete any file generated during the build steps @echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:" @@ -76,6 +78,6 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). deploybake: ## Tag and push the built image as specified by docker bake file @echo "== Deploying with docker bake file" - docker buildx bake --push + docker buildx bake -f ${DOCKER_BAKE_FILE} --push .PHONY: all clean lint build test deploy diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 80f86b436..88fc571a3 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -15,7 +15,7 @@ def call(String imageShortName, Map userConfig=[:]) { imageDir: '.', // Relative path to the context directory for the Docker build registryNamespace: '', // Empty by default (means "autodiscover based on the current controller") unstash: '', // Allow to unstash files if not empty - dockerBakeFile: false, // Allow to build from a bake file instead + dockerBakeFile: '', // Allow to build from a bake file instead ] // Merging the 2 maps - https://blog.mrhaki.com/2010/04/groovy-goodness-adding-maps-to-map_21.html @@ -140,13 +140,14 @@ def call(String imageShortName, Map userConfig=[:]) { stage("Build ${imageName}") { if (isUnix()) { - if (finalConfig.dockerBakeFile) { + if (finalConfig.dockerBakeFile != '') { + sh 'docker run --rm --privileged multiarch/qemu-user-static --reset -p yes' sh 'make buildbake' } else { sh 'make build' } } else { - if (finalConfig.dockerBakeFile) { + if (finalConfig.dockerBakeFile != '') { powershell 'make buildbake' } else { powershell 'make build' @@ -230,13 +231,14 @@ def call(String imageShortName, Map userConfig=[:]) { withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}"]) { // Please note that "make deploy" uses the environment variable "IMAGE_DEPLOY_NAME" if (isUnix()) { - if (finalConfig.dockerBakeFile) { + if (finalConfig.dockerBakeFile != '') { + sh 'docker run --rm --privileged multiarch/qemu-user-static --reset -p yes' sh 'make deploybake' } else { sh 'make deploy' } } else { - if (finalConfig.dockerBakeFile) { + if (finalConfig.dockerBakeFile != '') { powershell 'make deploybake' } else { powershell 'make deploy' From 374d6f84b48558df714c1ac89debf93cdcb29512 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 10:49:05 +0200 Subject: [PATCH 04/70] no load --- resources/io/jenkins/infra/docker/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 2a40cfb3c..10ec9ceb6 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -57,7 +57,7 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" docker buildx create --use - docker buildx bake -f ${DOCKER_BAKE_FILE} --load + docker buildx bake -f ${DOCKER_BAKE_FILE} clean: ## Delete any file generated during the build steps @echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:" From 4dab2ef56b88cc2ad8c1c56b5aaa538686ff6d70 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 11:03:39 +0200 Subject: [PATCH 05/70] fix path for bakefile --- resources/io/jenkins/infra/docker/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 10ec9ceb6..db8d06929 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -57,7 +57,7 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" docker buildx create --use - docker buildx bake -f ${DOCKER_BAKE_FILE} + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --load clean: ## Delete any file generated during the build steps @echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:" @@ -78,6 +78,6 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). deploybake: ## Tag and push the built image as specified by docker bake file @echo "== Deploying with docker bake file" - docker buildx bake -f ${DOCKER_BAKE_FILE} --push + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push .PHONY: all clean lint build test deploy From 120f2bd58a2b56857c1f15314b3c8390c1a80e81 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 11:12:32 +0200 Subject: [PATCH 06/70] correct path for bake file --- resources/io/jenkins/infra/docker/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index db8d06929..9e9e00336 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -10,12 +10,11 @@ endif IMAGE_NAME ?= helloworld IMAGE_DEPLOY_NAME ?= "$(IMAGE_NAME)" IMAGE_PLATFORM ?= linux/amd64 -DOCKER_BAKE_FILE ?= "docker-bake.hcl" - # Paths IMAGE_DOCKERFILE ?= "$(IMAGE_DIR)"/Dockerfile HADOLINT_REPORT ?= "$(IMAGE_DIR)"/hadolint.json TEST_HARNESS ?= "$(IMAGE_DIR)"/cst.yml +DOCKER_BAKE_FILE ?= "$(IMAGE_DIR)"/docker-bake.hcl ## Image metadatas GIT_COMMIT_REV ?= $(shell git log -n 1 --pretty=format:'%h') From ec41bd1c8b87562be0ccba35f836345fe732dffb Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 11:45:48 +0200 Subject: [PATCH 07/70] DOCKERBAKEFILE env --- vars/buildDockerAndPublishImage.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 88fc571a3..cddb0c7bf 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -60,6 +60,7 @@ def call(String imageShortName, Map userConfig=[:]) { "IMAGE_DIR=${finalConfig.imageDir}", "IMAGE_DOCKERFILE=${finalConfig.dockerfile}", "IMAGE_PLATFORM=${finalConfig.platform}", + "DOCKER_BAKE_FILE=${finalConfig.dockerBakeFile}", ]) { infra.withDockerPullCredentials{ String nextVersion = '' From edca19f2557fdf06875dc4fa1cf38418c5381cc4 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 11:50:49 +0200 Subject: [PATCH 08/70] debug path --- resources/io/jenkins/infra/docker/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 9e9e00336..c9c10c152 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -56,6 +56,10 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" docker buildx create --use + @echo debug path + pwd + ls -lta + @echo fin debug docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --load clean: ## Delete any file generated during the build steps From b6f924634301186c1e223dce2e3a6bb9c1680b89 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 15:43:56 +0200 Subject: [PATCH 09/70] try to move the container run for qemu --- resources/io/jenkins/infra/docker/Makefile | 5 +---- vars/buildDockerAndPublishImage.groovy | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index c9c10c152..063dc53f5 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -56,10 +56,7 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" docker buildx create --use - @echo debug path - pwd - ls -lta - @echo fin debug + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --load clean: ## Delete any file generated during the build steps diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index cddb0c7bf..d1a6310a9 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -142,7 +142,7 @@ def call(String imageShortName, Map userConfig=[:]) { stage("Build ${imageName}") { if (isUnix()) { if (finalConfig.dockerBakeFile != '') { - sh 'docker run --rm --privileged multiarch/qemu-user-static --reset -p yes' + //sh 'docker run --rm --privileged multiarch/qemu-user-static --reset -p yes' sh 'make buildbake' } else { sh 'make build' From 26c53556d7708eeb57304a10dbb8c2b49f0b6916 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 16:11:22 +0200 Subject: [PATCH 10/70] build and load --- resources/io/jenkins/infra/docker/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 063dc53f5..7fc88d373 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -55,9 +55,10 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" - docker buildx create --use docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --load + docker buildx create --use + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set '*.platform=linux/"$(dpkg --print-architecture)"' --load clean: ## Delete any file generated during the build steps @echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:" From 88d7929216754fc3c1710c99335e3876b8312e5b Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 16:17:27 +0200 Subject: [PATCH 11/70] remove qemu for test and change simple quotes for load platform --- resources/io/jenkins/infra/docker/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 7fc88d373..c76fa00ab 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -55,10 +55,9 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes docker buildx create --use docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set '*.platform=linux/"$(dpkg --print-architecture)"' --load + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(dpkg --print-architecture)" --load clean: ## Delete any file generated during the build steps @echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:" From 5d475c5891ad58bdc4051001f689269226743fac Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 16:27:40 +0200 Subject: [PATCH 12/70] move to env variable the dpkg --- resources/io/jenkins/infra/docker/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index c76fa00ab..04d764704 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -22,6 +22,8 @@ GIT_SCM_URL ?= $(shell git config --get remote.origin.url) SCM_URI ?= $(subst git@github.com:,https://github.com/,"$(GIT_SCM_URL)") BUILD_DATE ?= $(shell date --utc '+%Y-%m-%dT%H:%M:%S' 2>/dev/null || gdate --utc '+%Y-%m-%dT%H:%M:%S') +RUN_PLAFORM ?= $(shell dpkg --print-architecture) + help: ## Show this Makefile's help @echo "Help:" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @@ -57,7 +59,7 @@ buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" docker buildx create --use docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(dpkg --print-architecture)" --load + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(RUN_PLAFORM)" --load clean: ## Delete any file generated during the build steps @echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:" From c11cbecb084038a11b74f33a393cdf3e426e4847 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 16:50:48 +0200 Subject: [PATCH 13/70] add a tag for debug purposes --- vars/buildDockerAndPublishImage.groovy | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index d1a6310a9..5cd38fe20 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -21,6 +21,9 @@ def call(String imageShortName, Map userConfig=[:]) { // Merging the 2 maps - https://blog.mrhaki.com/2010/04/groovy-goodness-adding-maps-to-map_21.html final Map finalConfig = defaultConfig << userConfig + // DEBUG ONLY FOR PUSH + TAG_NAME = "0.0.1-beta" + // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' final boolean semVerEnabledOnPrimaryBranch = finalConfig.automaticSemanticVersioning && env.BRANCH_IS_PRIMARY @@ -142,7 +145,6 @@ def call(String imageShortName, Map userConfig=[:]) { stage("Build ${imageName}") { if (isUnix()) { if (finalConfig.dockerBakeFile != '') { - //sh 'docker run --rm --privileged multiarch/qemu-user-static --reset -p yes' sh 'make buildbake' } else { sh 'make build' @@ -233,7 +235,6 @@ def call(String imageShortName, Map userConfig=[:]) { // Please note that "make deploy" uses the environment variable "IMAGE_DEPLOY_NAME" if (isUnix()) { if (finalConfig.dockerBakeFile != '') { - sh 'docker run --rm --privileged multiarch/qemu-user-static --reset -p yes' sh 'make deploybake' } else { sh 'make deploy' From f0ed588ea09010853fe53367faa8f020583ca178 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 16:57:09 +0200 Subject: [PATCH 14/70] add a tag for debug purposes --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 5cd38fe20..a5ad38167 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -22,7 +22,7 @@ def call(String imageShortName, Map userConfig=[:]) { final Map finalConfig = defaultConfig << userConfig // DEBUG ONLY FOR PUSH - TAG_NAME = "0.0.1-beta" + env.TAG_NAME = "0.0.1-beta" // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' From 7b39dd0a97e1b8f92d106b47845b7c557ad1af8e Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 17:19:25 +0200 Subject: [PATCH 15/70] test tagname as tag --- resources/io/jenkins/infra/docker/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 04d764704..0474a3964 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -80,6 +80,6 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). deploybake: ## Tag and push the built image as specified by docker bake file @echo "== Deploying with docker bake file" - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push + TAG = ${env.TAG_NAME}" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push .PHONY: all clean lint build test deploy From 71958d8aa5acbe1bd95add25895f42a0b9bb395b Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 17:30:17 +0200 Subject: [PATCH 16/70] tagname --- resources/io/jenkins/infra/docker/Makefile | 2 +- vars/buildDockerAndPublishImage.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 0474a3964..4a11afc45 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -80,6 +80,6 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). deploybake: ## Tag and push the built image as specified by docker bake file @echo "== Deploying with docker bake file" - TAG = ${env.TAG_NAME}" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push .PHONY: all clean lint build test deploy diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index a5ad38167..624e1d838 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -231,7 +231,7 @@ def call(String imageShortName, Map userConfig=[:]) { } } - withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}"]) { + withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}", "TAG_NAME=${env.TAG_NAME}"]) { // Please note that "make deploy" uses the environment variable "IMAGE_DEPLOY_NAME" if (isUnix()) { if (finalConfig.dockerBakeFile != '') { From 5f56408176b6277fe2f946cbedd01c08f0275d5a Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 17:53:46 +0200 Subject: [PATCH 17/70] change tag to remove beta --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 624e1d838..a5a93e411 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -22,7 +22,7 @@ def call(String imageShortName, Map userConfig=[:]) { final Map finalConfig = defaultConfig << userConfig // DEBUG ONLY FOR PUSH - env.TAG_NAME = "0.0.1-beta" + env.TAG_NAME = "0.0.1" // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' From 48752d963059fe654872b3c3814f042f4dfd4a59 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 18 Aug 2023 18:02:54 +0200 Subject: [PATCH 18/70] add some bake debug for tag --- resources/io/jenkins/infra/docker/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 4a11afc45..1fc5773f7 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -58,6 +58,7 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" docker buildx create --use + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(RUN_PLAFORM)" --load @@ -80,6 +81,7 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). deploybake: ## Tag and push the built image as specified by docker bake file @echo "== Deploying with docker bake file" - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push .PHONY: all clean lint build test deploy From 2bdca24f07e0c4ba3c5cede602235b81db4ab641 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 11:06:35 +0200 Subject: [PATCH 19/70] add env debug --- resources/io/jenkins/infra/docker/Makefile | 1 + vars/buildDockerAndPublishImage.groovy | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 1fc5773f7..19c70f1d6 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -57,6 +57,7 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" + env docker buildx create --use docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index a5a93e411..b9d5ddcfe 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -145,7 +145,7 @@ def call(String imageShortName, Map userConfig=[:]) { stage("Build ${imageName}") { if (isUnix()) { if (finalConfig.dockerBakeFile != '') { - sh 'make buildbake' + sh 'env && make buildbake' } else { sh 'make build' } @@ -235,7 +235,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Please note that "make deploy" uses the environment variable "IMAGE_DEPLOY_NAME" if (isUnix()) { if (finalConfig.dockerBakeFile != '') { - sh 'make deploybake' + sh 'env && make deploybake' } else { sh 'make deploy' } From 4951feebe867080dba48e1f3c70e433686f6cd54 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 11:07:31 +0200 Subject: [PATCH 20/70] change debug tag version --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index b9d5ddcfe..b8f058b9a 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -22,7 +22,7 @@ def call(String imageShortName, Map userConfig=[:]) { final Map finalConfig = defaultConfig << userConfig // DEBUG ONLY FOR PUSH - env.TAG_NAME = "0.0.1" + env.TAG_NAME = "0.0.2" // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' From 0d926bba4b035d78aa39b43b8681b685c1c48343 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 14:49:20 +0200 Subject: [PATCH 21/70] add some debug for TAG_NAME --- resources/io/jenkins/infra/docker/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 19c70f1d6..7d660f0d2 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -56,7 +56,7 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) @echo "== Build succeeded" buildbake: ## Build the Docker Image(s) with dockerbake file - @echo "== Building from DockerBake file" + @echo "== Building from DockerBake file with $(TAG_NAME)" env docker buildx create --use docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print @@ -81,7 +81,7 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). @echo "== Deploy succeeded" deploybake: ## Tag and push the built image as specified by docker bake file - @echo "== Deploying with docker bake file" + @echo "== Deploying with docker bake file with $(TAG_NAME)" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push From e39e83b3093d2207caf509b54e4e551b4890d702 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 15:14:23 +0200 Subject: [PATCH 22/70] more tag name debug --- resources/io/jenkins/infra/docker/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 7d660f0d2..0596939ae 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -56,9 +56,10 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) @echo "== Build succeeded" buildbake: ## Build the Docker Image(s) with dockerbake file - @echo "== Building from DockerBake file with $(TAG_NAME)" + @echo "== Building from DockerBake file with TAG $(TAG_NAME)" env docker buildx create --use + @echo "== TAG_NAME vaut $(TAG_NAME)" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(RUN_PLAFORM)" --load From 6566e60974fef6667699f6d46e86c90109ea87c6 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 16:02:10 +0200 Subject: [PATCH 23/70] revert all debug --- resources/io/jenkins/infra/docker/Makefile | 6 ++---- vars/buildDockerAndPublishImage.groovy | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 0596939ae..1fc5773f7 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -56,10 +56,8 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) @echo "== Build succeeded" buildbake: ## Build the Docker Image(s) with dockerbake file - @echo "== Building from DockerBake file with TAG $(TAG_NAME)" - env + @echo "== Building from DockerBake file" docker buildx create --use - @echo "== TAG_NAME vaut $(TAG_NAME)" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(RUN_PLAFORM)" --load @@ -82,7 +80,7 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). @echo "== Deploy succeeded" deploybake: ## Tag and push the built image as specified by docker bake file - @echo "== Deploying with docker bake file with $(TAG_NAME)" + @echo "== Deploying with docker bake file" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index b8f058b9a..9944a3cd6 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -145,7 +145,7 @@ def call(String imageShortName, Map userConfig=[:]) { stage("Build ${imageName}") { if (isUnix()) { if (finalConfig.dockerBakeFile != '') { - sh 'env && make buildbake' + sh 'make buildbake' } else { sh 'make build' } @@ -235,7 +235,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Please note that "make deploy" uses the environment variable "IMAGE_DEPLOY_NAME" if (isUnix()) { if (finalConfig.dockerBakeFile != '') { - sh 'env && make deploybake' + sh 'make deploybake' } else { sh 'make deploy' } From e34a35427fba520e874d7fdfbf3712058c09f79c Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 16:03:40 +0200 Subject: [PATCH 24/70] remove forced env TAG NAME --- vars/buildDockerAndPublishImage.groovy | 3 --- 1 file changed, 3 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 9944a3cd6..1a15ac10d 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -21,9 +21,6 @@ def call(String imageShortName, Map userConfig=[:]) { // Merging the 2 maps - https://blog.mrhaki.com/2010/04/groovy-goodness-adding-maps-to-map_21.html final Map finalConfig = defaultConfig << userConfig - // DEBUG ONLY FOR PUSH - env.TAG_NAME = "0.0.2" - // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' final boolean semVerEnabledOnPrimaryBranch = finalConfig.automaticSemanticVersioning && env.BRANCH_IS_PRIMARY From 898c6e13a060a877f107f26a34dce131b4119fd3 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 16:38:13 +0200 Subject: [PATCH 25/70] generated docker bake file --- vars/buildDockerAndPublishImage.groovy | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 1a15ac10d..ce6483998 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -23,6 +23,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' + final String bakefileContent = libraryResource 'io/jenkins/infra/docker/docker-bake.hcl' final boolean semVerEnabledOnPrimaryBranch = finalConfig.automaticSemanticVersioning && env.BRANCH_IS_PRIMARY // Only run 1 build at a time on primary branch to ensure builds won't use the same tag when semantic versionning is activated @@ -73,6 +74,8 @@ def call(String imageShortName, Map userConfig=[:]) { // The makefile to use must come from the pipeline to avoid a nasty user trying to exfiltrate data from the build // Even though we have mitigation through the multibranch job config allowing to build PRs only from the repository contributors writeFile file: 'Makefile', text: makefileContent + + writeFile file: 'docker-bake.override.hcl', text: bakefileContent } // stage // Automatic tagging on principal branch is not enabled by default, show potential next version in PR anyway @@ -144,7 +147,15 @@ def call(String imageShortName, Map userConfig=[:]) { if (finalConfig.dockerBakeFile != '') { sh 'make buildbake' } else { - sh 'make build' + if (cstConfigSuffix == "") { + //linux ==> generated docker bake + env.PLATFORMS=finalConfig.platform + env.DOCKER_BAKE_FILE='docker-bake.override.hcl' + sh 'env && make buildbake' + } else { + // still used for windows + sh 'make build' + } } } else { if (finalConfig.dockerBakeFile != '') { From 5862c15a627556cfb5914c28142c29a2eeb89cc1 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 16:40:25 +0200 Subject: [PATCH 26/70] template for docker bake --- .../infra/docker/docker-bake.override.hcl | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 resources/io/jenkins/infra/docker/docker-bake.override.hcl diff --git a/resources/io/jenkins/infra/docker/docker-bake.override.hcl b/resources/io/jenkins/infra/docker/docker-bake.override.hcl new file mode 100644 index 000000000..c77b467e5 --- /dev/null +++ b/resources/io/jenkins/infra/docker/docker-bake.override.hcl @@ -0,0 +1,40 @@ +variable "IMAGE_NAME" {} + +variable "REGISTRY" { + default = "docker.io" +} + +variable "TAG_NAME" { + default = "" +} + +# return the full image name +function "full_image_name" { + params = [tag] + result = notequal("", tag) ? "${REGISTRY}/${IMAGE_NAME}:${tag}" : "${REGISTRY}/${IMAGE_NAME}:latest" +} + +target "default" { + dockerfile = "Dockerfile" + context = "." + tags = [ + full_image_name("latest"), + full_image_name(TAG_NAME) + ] + platforms = "$(PLATFORMS)" + args = { + GIT_COMMIT_REV="$(GIT_COMMIT_REV)", + GIT_SCM_URL="$(GIT_SCM_URL)", + BUILD_DATE="$(BUILD_DATE)", + } + labels = { + "org.opencontainers.image.source"="$(GIT_SCM_URL)", + "org.label-schema.vcs-url"="$(GIT_SCM_URL)", + "org.opencontainers.image.url"="$(SCM_URI)", + "org.label-schema.url"="$(SCM_URI)", + "org.opencontainers.image.revision"="$(GIT_COMMIT_REV)", + "org.label-schema.vcs-ref"="$(GIT_COMMIT_REV)", + "org.opencontainers.image.created"="$(BUILD_DATE)", + "org.label-schema.build-date"="$(BUILD_DATE)", + } +} From dbbd9c36034b68d45a4a4c53a7e8808c54142601 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 16:42:07 +0200 Subject: [PATCH 27/70] rename docker bake file --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index ce6483998..8e145bd34 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -23,7 +23,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' - final String bakefileContent = libraryResource 'io/jenkins/infra/docker/docker-bake.hcl' + final String bakefileContent = libraryResource 'io/jenkins/infra/docker/docker-bake.override.hcl' final boolean semVerEnabledOnPrimaryBranch = finalConfig.automaticSemanticVersioning && env.BRANCH_IS_PRIMARY // Only run 1 build at a time on primary branch to ensure builds won't use the same tag when semantic versionning is activated From 56d31872b546f22fb872031f12c87172842c0781 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 16:56:33 +0200 Subject: [PATCH 28/70] override bake file in variable --- vars/buildDockerAndPublishImage.groovy | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 8e145bd34..ec603b348 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -23,7 +23,8 @@ def call(String imageShortName, Map userConfig=[:]) { // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' - final String bakefileContent = libraryResource 'io/jenkins/infra/docker/docker-bake.override.hcl' + final String overrideDockerBakeFile = 'docker-bake.override.hcl' + final String bakefileContent = libraryResource 'io/jenkins/infra/docker/$overrideDockerBakeFile' final boolean semVerEnabledOnPrimaryBranch = finalConfig.automaticSemanticVersioning && env.BRANCH_IS_PRIMARY // Only run 1 build at a time on primary branch to ensure builds won't use the same tag when semantic versionning is activated @@ -75,7 +76,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Even though we have mitigation through the multibranch job config allowing to build PRs only from the repository contributors writeFile file: 'Makefile', text: makefileContent - writeFile file: 'docker-bake.override.hcl', text: bakefileContent + writeFile file: '$overrideDockerBakeFile', text: bakefileContent } // stage // Automatic tagging on principal branch is not enabled by default, show potential next version in PR anyway @@ -149,9 +150,11 @@ def call(String imageShortName, Map userConfig=[:]) { } else { if (cstConfigSuffix == "") { //linux ==> generated docker bake - env.PLATFORMS=finalConfig.platform - env.DOCKER_BAKE_FILE='docker-bake.override.hcl' - sh 'env && make buildbake' + env. + env. + withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { + sh 'make buildbake' + } } else { // still used for windows sh 'make build' From 6a9466a9f70eec409b31ee55dd7c56b948834257 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 17:00:08 +0200 Subject: [PATCH 29/70] wip --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index ec603b348..3e2150583 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -24,7 +24,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' final String overrideDockerBakeFile = 'docker-bake.override.hcl' - final String bakefileContent = libraryResource 'io/jenkins/infra/docker/$overrideDockerBakeFile' + final String bakefileContent = libraryResource 'io/jenkins/infra/docker/' + $overrideDockerBakeFile final boolean semVerEnabledOnPrimaryBranch = finalConfig.automaticSemanticVersioning && env.BRANCH_IS_PRIMARY // Only run 1 build at a time on primary branch to ensure builds won't use the same tag when semantic versionning is activated From a33f95dcb6f5c1405913540afa49cebffe333890 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 17:04:17 +0200 Subject: [PATCH 30/70] wip --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 3e2150583..4a3cd0949 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -24,7 +24,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' final String overrideDockerBakeFile = 'docker-bake.override.hcl' - final String bakefileContent = libraryResource 'io/jenkins/infra/docker/' + $overrideDockerBakeFile + final String bakefileContent = libraryResource 'io/jenkins/infra/docker/' + overrideDockerBakeFile final boolean semVerEnabledOnPrimaryBranch = finalConfig.automaticSemanticVersioning && env.BRANCH_IS_PRIMARY // Only run 1 build at a time on primary branch to ensure builds won't use the same tag when semantic versionning is activated From 77d6b9b067cc28b522812a199ffe73bdc1799fdf Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 17:11:33 +0200 Subject: [PATCH 31/70] wip --- vars/buildDockerAndPublishImage.groovy | 2 -- 1 file changed, 2 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 4a3cd0949..dd2f1a305 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -150,8 +150,6 @@ def call(String imageShortName, Map userConfig=[:]) { } else { if (cstConfigSuffix == "") { //linux ==> generated docker bake - env. - env. withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { sh 'make buildbake' } From 4e7c5f422e5ad475d9f0088a1ecf51b0cf399470 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 17:19:50 +0200 Subject: [PATCH 32/70] debug path to file --- vars/buildDockerAndPublishImage.groovy | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index dd2f1a305..f7ea57774 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -77,6 +77,8 @@ def call(String imageShortName, Map userConfig=[:]) { writeFile file: 'Makefile', text: makefileContent writeFile file: '$overrideDockerBakeFile', text: bakefileContent + + sh 'ls -lta' //DEBUG } // stage // Automatic tagging on principal branch is not enabled by default, show potential next version in PR anyway @@ -151,6 +153,7 @@ def call(String imageShortName, Map userConfig=[:]) { if (cstConfigSuffix == "") { //linux ==> generated docker bake withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { + sh 'ls -lta' //DEBUG sh 'make buildbake' } } else { From 072da498b9d02592928d51ba22f2e5efcc511e83 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 17:25:00 +0200 Subject: [PATCH 33/70] variable as file name --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index f7ea57774..c3f1d7fc9 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -76,7 +76,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Even though we have mitigation through the multibranch job config allowing to build PRs only from the repository contributors writeFile file: 'Makefile', text: makefileContent - writeFile file: '$overrideDockerBakeFile', text: bakefileContent + writeFile file: overrideDockerBakeFile, text: bakefileContent sh 'ls -lta' //DEBUG } // stage From 5d6aaeeedc9feb3ff671c57dd3e12d1b16338002 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 17:31:57 +0200 Subject: [PATCH 34/70] remove debug and change platforms to array --- vars/buildDockerAndPublishImage.groovy | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index c3f1d7fc9..2a5faf0eb 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -77,8 +77,6 @@ def call(String imageShortName, Map userConfig=[:]) { writeFile file: 'Makefile', text: makefileContent writeFile file: overrideDockerBakeFile, text: bakefileContent - - sh 'ls -lta' //DEBUG } // stage // Automatic tagging on principal branch is not enabled by default, show potential next version in PR anyway @@ -152,8 +150,7 @@ def call(String imageShortName, Map userConfig=[:]) { } else { if (cstConfigSuffix == "") { //linux ==> generated docker bake - withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { - sh 'ls -lta' //DEBUG + withEnv (["PLATFORMS=[$finalConfig.platform]", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { sh 'make buildbake' } } else { From 008a89737228abdb146a7a3b2be9632829c9285b Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 17:39:14 +0200 Subject: [PATCH 35/70] list of string --- resources/io/jenkins/infra/docker/docker-bake.override.hcl | 2 +- vars/buildDockerAndPublishImage.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/docker-bake.override.hcl b/resources/io/jenkins/infra/docker/docker-bake.override.hcl index c77b467e5..34a287a12 100644 --- a/resources/io/jenkins/infra/docker/docker-bake.override.hcl +++ b/resources/io/jenkins/infra/docker/docker-bake.override.hcl @@ -21,7 +21,7 @@ target "default" { full_image_name("latest"), full_image_name(TAG_NAME) ] - platforms = "$(PLATFORMS)" + platforms = ["$(PLATFORMS)"] args = { GIT_COMMIT_REV="$(GIT_COMMIT_REV)", GIT_SCM_URL="$(GIT_SCM_URL)", diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 2a5faf0eb..cfb2d8347 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -150,7 +150,7 @@ def call(String imageShortName, Map userConfig=[:]) { } else { if (cstConfigSuffix == "") { //linux ==> generated docker bake - withEnv (["PLATFORMS=[$finalConfig.platform]", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { + withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { sh 'make buildbake' } } else { From 891abc909dae10838ece7c1c9670c79333387799 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 17:43:14 +0200 Subject: [PATCH 36/70] list of string --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index cfb2d8347..6f6549666 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -151,7 +151,7 @@ def call(String imageShortName, Map userConfig=[:]) { if (cstConfigSuffix == "") { //linux ==> generated docker bake withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { - sh 'make buildbake' + sh 'env && make buildbake' } } else { // still used for windows From 218e5c370b5431fa559248ff2967393aab6185c5 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 21 Aug 2023 17:49:14 +0200 Subject: [PATCH 37/70] list of string --- resources/io/jenkins/infra/docker/docker-bake.override.hcl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/io/jenkins/infra/docker/docker-bake.override.hcl b/resources/io/jenkins/infra/docker/docker-bake.override.hcl index 34a287a12..bf4476ea3 100644 --- a/resources/io/jenkins/infra/docker/docker-bake.override.hcl +++ b/resources/io/jenkins/infra/docker/docker-bake.override.hcl @@ -8,6 +8,10 @@ variable "TAG_NAME" { default = "" } +variable "PLATFORMS" { + default = "linux/arm64" +} + # return the full image name function "full_image_name" { params = [tag] @@ -21,7 +25,7 @@ target "default" { full_image_name("latest"), full_image_name(TAG_NAME) ] - platforms = ["$(PLATFORMS)"] + platforms = [PLATFORMS] args = { GIT_COMMIT_REV="$(GIT_COMMIT_REV)", GIT_SCM_URL="$(GIT_SCM_URL)", From 63295f53555bc514ac1827ba37439bf2f5c3f5d6 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 22 Aug 2023 10:04:54 +0200 Subject: [PATCH 38/70] remove debug and change linux flag --- vars/buildDockerAndPublishImage.groovy | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 6f6549666..25050cf4a 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -148,17 +148,18 @@ def call(String imageShortName, Map userConfig=[:]) { if (finalConfig.dockerBakeFile != '') { sh 'make buildbake' } else { - if (cstConfigSuffix == "") { + if (operatingSystem == "linux") { //linux ==> generated docker bake withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { - sh 'env && make buildbake' + sh 'make buildbake' } } else { - // still used for windows + // old process still used for windows sh 'make build' } } } else { + // the agent is a windows agent so we do not force bakefile if (finalConfig.dockerBakeFile != '') { powershell 'make buildbake' } else { From bff20b0fab955ce79206344f5c106d1915e76517 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 22 Aug 2023 10:44:25 +0200 Subject: [PATCH 39/70] add deploy with docker bake override file and still windows deploy --- vars/buildDockerAndPublishImage.groovy | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 25050cf4a..56ca0f17e 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -247,15 +247,19 @@ def call(String imageShortName, Map userConfig=[:]) { if (finalConfig.dockerBakeFile != '') { sh 'make deploybake' } else { - sh 'make deploy' + if (operatingSystem == "linux") { + //linux ==> generated docker bake + withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { + sh 'make deploybake' + } + } else { + // old process still used for windows + sh 'make deploy' + } } } else { - if (finalConfig.dockerBakeFile != '') { - powershell 'make deploybake' - } else { - powershell 'make deploy' - } - } + powershell 'make deploy' + } // unix agent } // withEnv } //stage From 1ad2172cd0b38cb73b581a00e7c275ccc8ff558f Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 22 Aug 2023 11:00:12 +0200 Subject: [PATCH 40/70] spotless --- vars/buildDockerAndPublishImage.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 56ca0f17e..b3dbfc19d 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -260,7 +260,6 @@ def call(String imageShortName, Map userConfig=[:]) { } else { powershell 'make deploy' } // unix agent - } // withEnv } //stage } // if From 366f006beaa3e24593da2ecf8a4c359b9de83732 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 22 Aug 2023 11:14:46 +0200 Subject: [PATCH 41/70] add a multiplatform test --- ...BuildDockerAndPublishImageStepTests.groovy | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/groovy/BuildDockerAndPublishImageStepTests.groovy b/test/groovy/BuildDockerAndPublishImageStepTests.groovy index 0c8d8367f..dfe39a40d 100644 --- a/test/groovy/BuildDockerAndPublishImageStepTests.groovy +++ b/test/groovy/BuildDockerAndPublishImageStepTests.groovy @@ -562,4 +562,37 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And all mocked/stubbed methods have to be called verifyMocks() } + + @Test + void itBuildsAndDeploysImageWithCustomPlatformOnPrincipalBranch() throws Exception { + def script = loadScript(scriptName) + mockPrincipalBranch() + withMocks{ + script.call(testImageName, [ + dockerfile: 'build.Dockerfile', + imageDir: 'docker/', + platform: 'linux/amd64,linux/arm64,linux/s390x', + automaticSemanticVersioning: true, + gitCredentials: 'git-creds', + registryNamespace: 'jenkins', + ]) + } + final String expectedImageName = 'jenkins/' + testImageName + printCallStack() + // Then we expect a successful build with the code cloned + assertJobStatusSuccess() + // With the common workflow run as expected + assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) + // And the environement variables set with the custom configuration values + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=docker/')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=build.Dockerfile')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'PLATFORMS=linux/amd64,linux/arm64,linux/s390x')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_NAME=' + expectedImageName)) + // But no tag and no deploy called (branch or PR) + assertTrue(assertMakeDeploy(expectedImageName)) + assertTrue(assertTagPushed(defaultGitTag)) + // And all mocked/stubbed methods have to be called + verifyMocks() + } } From 7f46acefc336c607fb620fe41b25322bf4db7f23 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 22 Aug 2023 11:22:56 +0200 Subject: [PATCH 42/70] take care of the Dockerfile name and context IMAGE_DIR variables --- .../io/jenkins/infra/docker/docker-bake.override.hcl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/docker-bake.override.hcl b/resources/io/jenkins/infra/docker/docker-bake.override.hcl index bf4476ea3..4e873e7ad 100644 --- a/resources/io/jenkins/infra/docker/docker-bake.override.hcl +++ b/resources/io/jenkins/infra/docker/docker-bake.override.hcl @@ -12,6 +12,14 @@ variable "PLATFORMS" { default = "linux/arm64" } +variable "DOCKERFILE" { + default = "Dockerfile" +} + +variable "IMAGE_DIR" { + default = "." +} + # return the full image name function "full_image_name" { params = [tag] @@ -19,8 +27,8 @@ function "full_image_name" { } target "default" { - dockerfile = "Dockerfile" - context = "." + dockerfile = "$(DOCKERFILE)" + context = "$(IMAGE_DIR)" tags = [ full_image_name("latest"), full_image_name(TAG_NAME) From d78bbdc2f951a4f925187f61fce693ed5e278ec6 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 22 Aug 2023 11:35:34 +0200 Subject: [PATCH 43/70] add debug --- resources/io/jenkins/infra/docker/Makefile | 3 +++ resources/io/jenkins/infra/docker/docker-bake.override.hcl | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 1fc5773f7..6bcfc2f3e 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -57,6 +57,9 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" + ## debug env variable + env + ## end debug docker buildx create --use docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" diff --git a/resources/io/jenkins/infra/docker/docker-bake.override.hcl b/resources/io/jenkins/infra/docker/docker-bake.override.hcl index 4e873e7ad..8d85bea29 100644 --- a/resources/io/jenkins/infra/docker/docker-bake.override.hcl +++ b/resources/io/jenkins/infra/docker/docker-bake.override.hcl @@ -12,7 +12,7 @@ variable "PLATFORMS" { default = "linux/arm64" } -variable "DOCKERFILE" { +variable "IMAGE_DOCKERFILE" { default = "Dockerfile" } @@ -27,7 +27,7 @@ function "full_image_name" { } target "default" { - dockerfile = "$(DOCKERFILE)" + dockerfile = "$(IMAGE_DOCKERFILE)" context = "$(IMAGE_DIR)" tags = [ full_image_name("latest"), From f62a347dea4cbdff3d405c4cb070c4efa39b51e0 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 22 Aug 2023 11:39:42 +0200 Subject: [PATCH 44/70] remove quotes --- resources/io/jenkins/infra/docker/docker-bake.override.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/io/jenkins/infra/docker/docker-bake.override.hcl b/resources/io/jenkins/infra/docker/docker-bake.override.hcl index 8d85bea29..bfb077029 100644 --- a/resources/io/jenkins/infra/docker/docker-bake.override.hcl +++ b/resources/io/jenkins/infra/docker/docker-bake.override.hcl @@ -28,7 +28,7 @@ function "full_image_name" { target "default" { dockerfile = "$(IMAGE_DOCKERFILE)" - context = "$(IMAGE_DIR)" + context = IMAGE_DIR tags = [ full_image_name("latest"), full_image_name(TAG_NAME) From 1cb3f11ba2db645730d17f044c1657299d7010e7 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 22 Aug 2023 11:45:26 +0200 Subject: [PATCH 45/70] remove quotes --- resources/io/jenkins/infra/docker/docker-bake.override.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/io/jenkins/infra/docker/docker-bake.override.hcl b/resources/io/jenkins/infra/docker/docker-bake.override.hcl index bfb077029..887510cad 100644 --- a/resources/io/jenkins/infra/docker/docker-bake.override.hcl +++ b/resources/io/jenkins/infra/docker/docker-bake.override.hcl @@ -27,7 +27,7 @@ function "full_image_name" { } target "default" { - dockerfile = "$(IMAGE_DOCKERFILE)" + dockerfile = IMAGE_DOCKERFILE context = IMAGE_DIR tags = [ full_image_name("latest"), From 19f6f8daf10d144c18f2c931e615dd616c68c646 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 23 Aug 2023 16:59:42 +0200 Subject: [PATCH 46/70] change platform to platforms by defaut --- resources/io/jenkins/infra/docker/Makefile | 4 +-- vars/buildDockerAndPublishImage.groovy | 34 +++++++++++++++------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 6bcfc2f3e..cff2c2563 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -9,7 +9,7 @@ endif IMAGE_NAME ?= helloworld IMAGE_DEPLOY_NAME ?= "$(IMAGE_NAME)" -IMAGE_PLATFORM ?= linux/amd64 +IMAGE_PLATFORMS ?= linux/amd64 # Paths IMAGE_DOCKERFILE ?= "$(IMAGE_DIR)"/Dockerfile HADOLINT_REPORT ?= "$(IMAGE_DIR)"/hadolint.json @@ -50,7 +50,7 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) --label "org.label-schema.vcs-ref=$(GIT_COMMIT_REV)" \ --label "org.opencontainers.image.created=$(BUILD_DATE)" \ --label "org.label-schema.build-date=$(BUILD_DATE)" \ - --platform "$(IMAGE_PLATFORM)" \ + --platform "$(IMAGE_PLATFORMS)" \ --file "$(call FixPath,$(IMAGE_DOCKERFILE))" \ "$(IMAGE_DIR)" @echo "== Build succeeded" diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index b3dbfc19d..434f45302 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -9,7 +9,8 @@ def call(String imageShortName, Map userConfig=[:]) { automaticSemanticVersioning: false, // Do not automagically increase semantic version by default includeImageNameInTag: false, // Set to true for multiple semversioned images built in parallel, will include the image name in tag to avoid conflict dockerfile: 'Dockerfile', // Obvious default - platform: 'linux/amd64', // Intel/AMD 64 Bits, following Docker platform identifiers + platform: '', // Kept for backward compatibility + platforms: '', // Allow to override the platform for multi-arch builds see default line 46 nextVersionCommand: 'jx-release-version', // Commmand line used to retrieve the next version gitCredentials: 'github-app-infra', // Credential ID for tagging and creating release imageDir: '.', // Relative path to the context directory for the Docker build @@ -36,18 +37,31 @@ def call(String imageShortName, Map userConfig=[:]) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX") final String buildDate = dateFormat.format(now) + // only one platform parameter is supported for now either platform or platforms + if (finalConfig.platforms != '' && finalConfig.platform != '') { + throw new Exception("Only one platform parameter is supported for now either platform or platforms, prefer platforms") + } else if (finalConfig.platform != '') { + finalConfig.platforms = finalConfig.platform + } else { + finalConfig.platforms = 'linux/amd64' + } + // Warn about potential Linux/Windows contradictions between platform & agentLabels, and set the Windows config suffix for CST files + // for now only one platform possible per windows build ! String cstConfigSuffix = '' - if (finalConfig.agentLabels.contains('windows') || finalConfig.platform.contains('windows')) { - if (finalConfig.agentLabels.contains('windows') && !finalConfig.platform.contains('windows')) { - echo "WARNING: A 'windows' agent is requested, but the 'platform' is set to '${finalConfig.platform}'." + if (finalConfig.agentLabels.contains('windows') || finalConfig.platforms.contains('windows')) { + if (finalConfig.platforms.split(',').length > 1) { + throw new Exception("with windows, only one platform can be specified within 'platforms'") + } + if (finalConfig.agentLabels.contains('windows') && !finalConfig.platforms.contains('windows')) { + echo "WARNING: A 'windows' agent is requested, but the 'platform(s)' is set to '${finalConfig.platforms}'." } - if (!finalConfig.agentLabels.contains('windows') && finalConfig.platform.contains('windows')) { - echo "WARNING: The 'platform' is set to '${finalConfig.platform}', but there isn't any 'windows' agent requested." + if (!finalConfig.agentLabels.contains('windows') && finalConfig.platforms.contains('windows')) { + echo "WARNING: The 'platforms' is set to '${finalConfig.platforms}', but there isn't any 'windows' agent requested." } cstConfigSuffix = '-windows' } - String operatingSystem = finalConfig.platform.split('/')[0] + String operatingSystem = finalConfig.platforms.split('/')[0] final InfraConfig infraConfig = new InfraConfig(env) final String defaultRegistryNamespace = infraConfig.getDockerRegistryNamespace() @@ -61,7 +75,7 @@ def call(String imageShortName, Map userConfig=[:]) { "IMAGE_NAME=${imageName}", "IMAGE_DIR=${finalConfig.imageDir}", "IMAGE_DOCKERFILE=${finalConfig.dockerfile}", - "IMAGE_PLATFORM=${finalConfig.platform}", + "IMAGE_PLATFORMS=${finalConfig.platforms}", "DOCKER_BAKE_FILE=${finalConfig.dockerBakeFile}", ]) { infra.withDockerPullCredentials{ @@ -150,7 +164,7 @@ def call(String imageShortName, Map userConfig=[:]) { } else { if (operatingSystem == "linux") { //linux ==> generated docker bake - withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { + withEnv (["PLATFORMS=$finalConfig.platforms", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { sh 'make buildbake' } } else { @@ -249,7 +263,7 @@ def call(String imageShortName, Map userConfig=[:]) { } else { if (operatingSystem == "linux") { //linux ==> generated docker bake - withEnv (["PLATFORMS=$finalConfig.platform", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { + withEnv (["PLATFORMS=$finalConfig.platforms", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { sh 'make deploybake' } } else { From c3768eb95dabe6fe8b4091e7939aa4fa05b14fe6 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 23 Aug 2023 17:16:13 +0200 Subject: [PATCH 47/70] change test for S IMAGE_PLATFORMS --- test/groovy/BuildDockerAndPublishImageStepTests.groovy | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/groovy/BuildDockerAndPublishImageStepTests.groovy b/test/groovy/BuildDockerAndPublishImageStepTests.groovy index dfe39a40d..6a509b29f 100644 --- a/test/groovy/BuildDockerAndPublishImageStepTests.groovy +++ b/test/groovy/BuildDockerAndPublishImageStepTests.groovy @@ -173,7 +173,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the expected environment variable defined to their defaults assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORM=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/amd64')) // And generated reports are recorded assertTrue(assertRecordIssues()) @@ -297,7 +297,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the environement variables set with the custom configuration values assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=docker/')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=build.Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORM=linux/s390x')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/s390x')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_NAME=' + expectedImageName)) // But no tag and no deploy called (branch or PR) assertTrue(assertMakeDeploy(expectedImageName)) @@ -481,7 +481,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the expected environment variables set to their default values assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORM=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/amd64')) // And generated reports recorded assertTrue(assertRecordIssues()) // And the deploy step called @@ -510,7 +510,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the expected environment variables set to their default values assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORM=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/amd64')) // And generated reports recorded assertTrue(assertRecordIssues()) // But no deploy step called (not on principal branch) @@ -545,7 +545,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the expected environment variable defined to their defaults assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORM=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/amd64')) // And generated reports are recorded assertTrue(assertRecordIssues()) From 00dbaeca6537a13b0e6a3990c99e4f61d63af728 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 23 Aug 2023 17:28:33 +0200 Subject: [PATCH 48/70] better handle of platform.s --- vars/buildDockerAndPublishImage.groovy | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 434f45302..65913b5d0 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -39,10 +39,13 @@ def call(String imageShortName, Map userConfig=[:]) { // only one platform parameter is supported for now either platform or platforms if (finalConfig.platforms != '' && finalConfig.platform != '') { + // both platform and platforms cannot be set at the same time throw new Exception("Only one platform parameter is supported for now either platform or platforms, prefer platforms") } else if (finalConfig.platform != '') { + // if platform is set, I override platforms with it finalConfig.platforms = finalConfig.platform - } else { + } else if (finalConfig.platforms == '') { + // if platforms is not set, I set it to linux/amd64 by default finalConfig.platforms = 'linux/amd64' } From 7986a8f1a3524473bc68d9e8e5efb9f7bd98594a Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 23 Aug 2023 17:29:03 +0200 Subject: [PATCH 49/70] remove env debug --- resources/io/jenkins/infra/docker/Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index cff2c2563..b49eb2e4d 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -57,9 +57,6 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) buildbake: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" - ## debug env variable - env - ## end debug docker buildx create --use docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" From 2668f46b5c8ed48333ccf8af6d8b8e0910764fde Mon Sep 17 00:00:00 2001 From: smerle33 Date: Thu, 24 Aug 2023 08:50:54 +0200 Subject: [PATCH 50/70] remove variable, set directly in command --- resources/io/jenkins/infra/docker/Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index b49eb2e4d..4fe1c3fcf 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -22,8 +22,6 @@ GIT_SCM_URL ?= $(shell git config --get remote.origin.url) SCM_URI ?= $(subst git@github.com:,https://github.com/,"$(GIT_SCM_URL)") BUILD_DATE ?= $(shell date --utc '+%Y-%m-%dT%H:%M:%S' 2>/dev/null || gdate --utc '+%Y-%m-%dT%H:%M:%S') -RUN_PLAFORM ?= $(shell dpkg --print-architecture) - help: ## Show this Makefile's help @echo "Help:" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @@ -60,7 +58,7 @@ buildbake: ## Build the Docker Image(s) with dockerbake file docker buildx create --use docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(RUN_PLAFORM)" --load + docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(shell dpkg --print-architecture)" --load clean: ## Delete any file generated during the build steps @echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:" From 5c3ce4580e278699f286cb763f08ceab1a4c477d Mon Sep 17 00:00:00 2001 From: smerle33 Date: Thu, 24 Aug 2023 18:27:53 +0200 Subject: [PATCH 51/70] reword and restructure after pair programming with damien --- resources/io/jenkins/infra/docker/Makefile | 8 +- ....override.hcl => jenkinsinfrabakefile.hcl} | 8 +- ...BuildDockerAndPublishImageStepTests.groovy | 118 +++++++++++++++--- vars/buildDockerAndPublishImage.groovy | 81 ++++++------ 4 files changed, 153 insertions(+), 62 deletions(-) rename resources/io/jenkins/infra/docker/{docker-bake.override.hcl => jenkinsinfrabakefile.hcl} (81%) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 4fe1c3fcf..42fcc69dd 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -9,7 +9,7 @@ endif IMAGE_NAME ?= helloworld IMAGE_DEPLOY_NAME ?= "$(IMAGE_NAME)" -IMAGE_PLATFORMS ?= linux/amd64 +BUILD_TARGETPLATFORM ?= linux/amd64 # Paths IMAGE_DOCKERFILE ?= "$(IMAGE_DIR)"/Dockerfile HADOLINT_REPORT ?= "$(IMAGE_DIR)"/hadolint.json @@ -48,12 +48,12 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) --label "org.label-schema.vcs-ref=$(GIT_COMMIT_REV)" \ --label "org.opencontainers.image.created=$(BUILD_DATE)" \ --label "org.label-schema.build-date=$(BUILD_DATE)" \ - --platform "$(IMAGE_PLATFORMS)" \ + --platform "$(BUILD_TARGETPLATFORM)" \ --file "$(call FixPath,$(IMAGE_DOCKERFILE))" \ "$(IMAGE_DIR)" @echo "== Build succeeded" -buildbake: ## Build the Docker Image(s) with dockerbake file +bake-build: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" docker buildx create --use docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print @@ -77,7 +77,7 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). docker image push "$(IMAGE_DEPLOY_NAME)" @echo "== Deploy succeeded" -deploybake: ## Tag and push the built image as specified by docker bake file +bake-deploy: ## Tag and push the built image as specified by docker bake file @echo "== Deploying with docker bake file" docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push diff --git a/resources/io/jenkins/infra/docker/docker-bake.override.hcl b/resources/io/jenkins/infra/docker/jenkinsinfrabakefile.hcl similarity index 81% rename from resources/io/jenkins/infra/docker/docker-bake.override.hcl rename to resources/io/jenkins/infra/docker/jenkinsinfrabakefile.hcl index 887510cad..7ac763408 100644 --- a/resources/io/jenkins/infra/docker/docker-bake.override.hcl +++ b/resources/io/jenkins/infra/docker/jenkinsinfrabakefile.hcl @@ -1,4 +1,4 @@ -variable "IMAGE_NAME" {} +variable "IMAGE_DEPLOY_NAME" {} variable "REGISTRY" { default = "docker.io" @@ -8,7 +8,7 @@ variable "TAG_NAME" { default = "" } -variable "PLATFORMS" { +variable "BAKE_TARGETPLATFORMS" { default = "linux/arm64" } @@ -23,7 +23,7 @@ variable "IMAGE_DIR" { # return the full image name function "full_image_name" { params = [tag] - result = notequal("", tag) ? "${REGISTRY}/${IMAGE_NAME}:${tag}" : "${REGISTRY}/${IMAGE_NAME}:latest" + result = notequal("", tag) ? "${REGISTRY}/${IMAGE_DEPLOY_NAME}:${tag}" : "${REGISTRY}/${IMAGE_DEPLOY_NAME}:latest" } target "default" { @@ -33,7 +33,7 @@ target "default" { full_image_name("latest"), full_image_name(TAG_NAME) ] - platforms = [PLATFORMS] + platforms = [BAKE_TARGETPLATFORMS] args = { GIT_COMMIT_REV="$(GIT_COMMIT_REV)", GIT_SCM_URL="$(GIT_SCM_URL)", diff --git a/test/groovy/BuildDockerAndPublishImageStepTests.groovy b/test/groovy/BuildDockerAndPublishImageStepTests.groovy index 6a509b29f..49407cf92 100644 --- a/test/groovy/BuildDockerAndPublishImageStepTests.groovy +++ b/test/groovy/BuildDockerAndPublishImageStepTests.groovy @@ -117,7 +117,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { Boolean assertBaseWorkflow() { return assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile') \ && (assertMethodCallContainsPattern('sh','make lint') || assertMethodCallContainsPattern('powershell','make lint')) \ - && (assertMethodCallContainsPattern('sh','make build') || assertMethodCallContainsPattern('powershell','make build')) \ + && (assertMethodCallContainsPattern('sh','make build') || assertMethodCallContainsPattern('sh','make bake-build') || assertMethodCallContainsPattern('powershell','make build')) \ && assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}") } @@ -132,7 +132,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // return if the "make deploy" was detected with the provided argument as image name Boolean assertMakeDeploy(String expectedImageName = fullTestImageName) { - return (assertMethodCallContainsPattern('sh','make deploy') || assertMethodCallContainsPattern('powershell','make deploy')) \ + return (assertMethodCallContainsPattern('sh','make deploy') || assertMethodCallContainsPattern('sh','make bake-deploy') || assertMethodCallContainsPattern('powershell','make deploy')) \ && assertMethodCallContainsPattern('withEnv', "IMAGE_DEPLOY_NAME=${expectedImageName}") } @@ -173,7 +173,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the expected environment variable defined to their defaults assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/amd64')) // And generated reports are recorded assertTrue(assertRecordIssues()) @@ -297,7 +297,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the environement variables set with the custom configuration values assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=docker/')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=build.Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/s390x')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/s390x')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_NAME=' + expectedImageName)) // But no tag and no deploy called (branch or PR) assertTrue(assertMakeDeploy(expectedImageName)) @@ -481,7 +481,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the expected environment variables set to their default values assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/amd64')) // And generated reports recorded assertTrue(assertRecordIssues()) // And the deploy step called @@ -510,7 +510,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the expected environment variables set to their default values assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/amd64')) // And generated reports recorded assertTrue(assertRecordIssues()) // But no deploy step called (not on principal branch) @@ -545,7 +545,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the expected environment variable defined to their defaults assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_PLATFORMS=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/amd64')) // And generated reports are recorded assertTrue(assertRecordIssues()) @@ -569,15 +569,10 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { mockPrincipalBranch() withMocks{ script.call(testImageName, [ - dockerfile: 'build.Dockerfile', - imageDir: 'docker/', platform: 'linux/amd64,linux/arm64,linux/s390x', automaticSemanticVersioning: true, - gitCredentials: 'git-creds', - registryNamespace: 'jenkins', ]) } - final String expectedImageName = 'jenkins/' + testImageName printCallStack() // Then we expect a successful build with the code cloned assertJobStatusSuccess() @@ -585,14 +580,105 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertTrue(assertBaseWorkflow()) assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And the environement variables set with the custom configuration values - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=docker/')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=build.Dockerfile')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) assertTrue(assertMethodCallContainsPattern('withEnv', 'PLATFORMS=linux/amd64,linux/arm64,linux/s390x')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_NAME=' + expectedImageName)) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_NAME=jenkinsciinfra/bitcoinMinerImage')) // But no tag and no deploy called (branch or PR) - assertTrue(assertMakeDeploy(expectedImageName)) + assertTrue(assertMakeDeploy()) assertTrue(assertTagPushed(defaultGitTag)) // And all mocked/stubbed methods have to be called verifyMocks() } + + @Test + void itBuildsAndDeploysImageWithSpecifiedBakeFileOnPrincipalBranch() throws Exception { + def script = loadScript(scriptName) + mockPrincipalBranch() + withMocks{ + script.call(testImageName, [ + dockerBakeFile: 'bake.yml', + ]) + } + + //final String expectedImageName = 'jenkins/' + testImageName + printCallStack() + + // Then we expect a successful build with the code cloned + assertJobStatusSuccess() + + // // With the common workflow run as expected + assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('sh', 'make bake-build')) + assertFalse(assertMethodCallContainsPattern('sh', 'make build')) + assertTrue(assertMethodCallContainsPattern('sh', 'make bake-deploy')) + assertFalse(assertMethodCallContainsPattern('sh', 'make deploy')) + // // And the environement variables set with the custom configuration values + assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'DOCKER_BAKE_FILE=bake.yml')) + // // And all mocked/stubbed methods have to be called + verifyMocks() + } + + @Test + void itFailWithBothPlatformAndPlatforms() throws Exception { + def script = loadScript(scriptName) + mockPrincipalBranch() + withMocks{ + script.call(testImageName, [ + platform: 'linux/amd64', + platforms: 'linux/arm64', + ]) + } + + printCallStack() + + // Then we expect a failing build + assertJobStatusFailure() + + // And the error message is shown + assertTrue(assertMethodCallContainsPattern('echo', 'ERROR: Only one platform parameter is supported for now either platform or platforms, prefer platforms.')) + } + + @Test + void itFailWithWindowsAndMoreThanOnePlatform() throws Exception { + def script = loadScript(scriptName) + mockPrincipalBranch() + withMocks{ + script.call(testImageName, [ + agentLabels: 'docker-windows', + platforms: 'linux/arm64,linux/amd64', + ]) + } + + printCallStack() + + // Then we expect a failing build + assertJobStatusFailure() + + // And the error message is shown + assertTrue(assertMethodCallContainsPattern('echo', 'ERROR: with windows, only one platform can be specified within platforms.')) + } + + @Test + void itDontBuildsAndDeploysImageWithWindowsAndBakeOnPrincipalBranch() throws Exception { + def script = loadScript(scriptName) + mockPrincipalBranch() + withMocks{ + script.call(testImageName, [ + dockerBakeFile: 'bake.yml', + platforms: 'windows/1804', + agentLabels: 'docker-windows', + ]) + } + + printCallStack() + + // Then we expect a failing build + assertJobStatusFailure() + + // And the error message is shown + assertTrue(assertMethodCallContainsPattern('echo', 'ERROR: dockerBakeFile is not supported on windows.')) + } } diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 65913b5d0..67c95cebb 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -9,8 +9,8 @@ def call(String imageShortName, Map userConfig=[:]) { automaticSemanticVersioning: false, // Do not automagically increase semantic version by default includeImageNameInTag: false, // Set to true for multiple semversioned images built in parallel, will include the image name in tag to avoid conflict dockerfile: 'Dockerfile', // Obvious default - platform: '', // Kept for backward compatibility - platforms: '', // Allow to override the platform for multi-arch builds see default line 46 + platform: '', // Kept for backward compatibility to be deprecated + platforms: '', // Allow to override the platform for multi-arch builds see default line 40 nextVersionCommand: 'jx-release-version', // Commmand line used to retrieve the next version gitCredentials: 'github-app-infra', // Credential ID for tagging and creating release imageDir: '.', // Relative path to the context directory for the Docker build @@ -24,8 +24,8 @@ def call(String imageShortName, Map userConfig=[:]) { // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' - final String overrideDockerBakeFile = 'docker-bake.override.hcl' - final String bakefileContent = libraryResource 'io/jenkins/infra/docker/' + overrideDockerBakeFile + final String jenkinsInfraBakeFile = 'jenkinsinfrabakefile.hcl' + final String bakefileContent = libraryResource 'io/jenkins/infra/docker/' + jenkinsInfraBakeFile final boolean semVerEnabledOnPrimaryBranch = finalConfig.automaticSemanticVersioning && env.BRANCH_IS_PRIMARY // Only run 1 build at a time on primary branch to ensure builds won't use the same tag when semantic versionning is activated @@ -40,7 +40,9 @@ def call(String imageShortName, Map userConfig=[:]) { // only one platform parameter is supported for now either platform or platforms if (finalConfig.platforms != '' && finalConfig.platform != '') { // both platform and platforms cannot be set at the same time - throw new Exception("Only one platform parameter is supported for now either platform or platforms, prefer platforms") + echo 'ERROR: Only one platform parameter is supported for now either platform or platforms, prefer platforms.' + currentBuild.result = 'FAILURE' + return } else if (finalConfig.platform != '') { // if platform is set, I override platforms with it finalConfig.platforms = finalConfig.platform @@ -54,7 +56,9 @@ def call(String imageShortName, Map userConfig=[:]) { String cstConfigSuffix = '' if (finalConfig.agentLabels.contains('windows') || finalConfig.platforms.contains('windows')) { if (finalConfig.platforms.split(',').length > 1) { - throw new Exception("with windows, only one platform can be specified within 'platforms'") + echo 'ERROR: with windows, only one platform can be specified within platforms.' + currentBuild.result = 'FAILURE' + return } if (finalConfig.agentLabels.contains('windows') && !finalConfig.platforms.contains('windows')) { echo "WARNING: A 'windows' agent is requested, but the 'platform(s)' is set to '${finalConfig.platforms}'." @@ -66,6 +70,12 @@ def call(String imageShortName, Map userConfig=[:]) { } String operatingSystem = finalConfig.platforms.split('/')[0] + if (operatingSystem == 'windows' && finalConfig.dockerBakeFile != '') { + echo 'ERROR: dockerBakeFile is not supported on windows.' + currentBuild.result = 'FAILURE' + return + } + final InfraConfig infraConfig = new InfraConfig(env) final String defaultRegistryNamespace = infraConfig.getDockerRegistryNamespace() final String registryNamespace = finalConfig.registryNamespace ?: defaultRegistryNamespace @@ -78,8 +88,9 @@ def call(String imageShortName, Map userConfig=[:]) { "IMAGE_NAME=${imageName}", "IMAGE_DIR=${finalConfig.imageDir}", "IMAGE_DOCKERFILE=${finalConfig.dockerfile}", - "IMAGE_PLATFORMS=${finalConfig.platforms}", - "DOCKER_BAKE_FILE=${finalConfig.dockerBakeFile}", + "BUILD_TARGETPLATFORM=${finalConfig.platforms}", + "BAKE_TARGETPLATFORMS=${finalConfig.platforms}", + "DOCKER_BAKE_FILE=${finalConfig.dockerBakeFile ?: jenkinsInfraBakeFile}", ]) { infra.withDockerPullCredentials{ String nextVersion = '' @@ -93,7 +104,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Even though we have mitigation through the multibranch job config allowing to build PRs only from the repository contributors writeFile file: 'Makefile', text: makefileContent - writeFile file: overrideDockerBakeFile, text: bakefileContent + } // stage // Automatic tagging on principal branch is not enabled by default, show potential next version in PR anyway @@ -161,28 +172,24 @@ def call(String imageShortName, Map userConfig=[:]) { } // stage stage("Build ${imageName}") { - if (isUnix()) { - if (finalConfig.dockerBakeFile != '') { - sh 'make buildbake' - } else { - if (operatingSystem == "linux") { - //linux ==> generated docker bake - withEnv (["PLATFORMS=$finalConfig.platforms", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { - sh 'make buildbake' - } + withEnv(["IMAGE_DEPLOY_NAME=${imageName}"]) { + if (isUnix()) { + if (finalConfig.dockerBakeFile != '') { + sh 'make bake-build' } else { - // old process still used for windows - sh 'make build' + if (operatingSystem == "linux") { + //linux ==> generated docker bake + writeFile file: jenkinsInfraBakeFile, text: bakefileContent + sh 'make bake-build' + } else { + // old process still used for windows + sh 'make build' + } } - } - } else { - // the agent is a windows agent so we do not force bakefile - if (finalConfig.dockerBakeFile != '') { - powershell 'make buildbake' } else { powershell 'make build' } - } + } // withEnv } //stage // There can be 2 kind of tests: per image and per repository @@ -257,27 +264,25 @@ def call(String imageShortName, Map userConfig=[:]) { imageDeployName += ":${env.TAG_NAME}" } } - - withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}", "TAG_NAME=${env.TAG_NAME}"]) { - // Please note that "make deploy" uses the environment variable "IMAGE_DEPLOY_NAME" - if (isUnix()) { + if (isUnix()) { + withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}"]) { + // Please note that "make deploy" and the generated bake deploy file uses the environment variable "IMAGE_DEPLOY_NAME" if (finalConfig.dockerBakeFile != '') { - sh 'make deploybake' + sh 'make bake-deploy' } else { if (operatingSystem == "linux") { //linux ==> generated docker bake - withEnv (["PLATFORMS=$finalConfig.platforms", "DOCKER_BAKE_FILE=$overrideDockerBakeFile"]) { - sh 'make deploybake' - } + sh 'make bake-deploy' } else { // old process still used for windows sh 'make deploy' } } - } else { - powershell 'make deploy' - } // unix agent - } // withEnv + } // withEnv + } else { + powershell 'make deploy' + } // unix agent + } //stage } // if } // withDockerPushCredentials From b6811f92c9958e7fda8fb2d209d0afe438be8f80 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 25 Aug 2023 11:55:33 +0200 Subject: [PATCH 52/70] mvn spotless:apply --- vars/buildDockerAndPublishImage.groovy | 3 --- 1 file changed, 3 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 67c95cebb..1d63a9093 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -103,8 +103,6 @@ def call(String imageShortName, Map userConfig=[:]) { // The makefile to use must come from the pipeline to avoid a nasty user trying to exfiltrate data from the build // Even though we have mitigation through the multibranch job config allowing to build PRs only from the repository contributors writeFile file: 'Makefile', text: makefileContent - - } // stage // Automatic tagging on principal branch is not enabled by default, show potential next version in PR anyway @@ -282,7 +280,6 @@ def call(String imageShortName, Map userConfig=[:]) { } else { powershell 'make deploy' } // unix agent - } //stage } // if } // withDockerPushCredentials From 5db7dcf76425cd43dca0a3a1cf10259fb5d6acdf Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 25 Aug 2023 15:42:45 +0200 Subject: [PATCH 53/70] rename platforms to targetplatforms and change default value else --- vars/buildDockerAndPublishImage.groovy | 38 ++++++++++++++------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 1d63a9093..08703f180 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -9,8 +9,7 @@ def call(String imageShortName, Map userConfig=[:]) { automaticSemanticVersioning: false, // Do not automagically increase semantic version by default includeImageNameInTag: false, // Set to true for multiple semversioned images built in parallel, will include the image name in tag to avoid conflict dockerfile: 'Dockerfile', // Obvious default - platform: '', // Kept for backward compatibility to be deprecated - platforms: '', // Allow to override the platform for multi-arch builds see default line 40 + targetplatforms: '', // defined the platforms to build as TARGET nextVersionCommand: 'jx-release-version', // Commmand line used to retrieve the next version gitCredentials: 'github-app-infra', // Credential ID for tagging and creating release imageDir: '.', // Relative path to the context directory for the Docker build @@ -37,38 +36,41 @@ def call(String imageShortName, Map userConfig=[:]) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX") final String buildDate = dateFormat.format(now) + // only one platform parameter is supported for now either platform or platforms - if (finalConfig.platforms != '' && finalConfig.platform != '') { + if (finalConfig.platform && finalConfig.targetplatforms) { // both platform and platforms cannot be set at the same time - echo 'ERROR: Only one platform parameter is supported for now either platform or platforms, prefer platforms.' + echo 'ERROR: Only one platform parameter is supported for now either platform or targetplatforms, prefer targetplatforms.' currentBuild.result = 'FAILURE' return - } else if (finalConfig.platform != '') { + } else if (finalConfig.platform) { // if platform is set, I override platforms with it - finalConfig.platforms = finalConfig.platform - } else if (finalConfig.platforms == '') { - // if platforms is not set, I set it to linux/amd64 by default - finalConfig.platforms = 'linux/amd64' + finalConfig.targetplatforms = finalConfig.platform + } + + // Default Value if targetplatforms is not set, I set it to linux/amd64 by default + if (finalConfig.targetplatforms == '') { + finalConfig.targetplatforms = 'linux/amd64' } // Warn about potential Linux/Windows contradictions between platform & agentLabels, and set the Windows config suffix for CST files // for now only one platform possible per windows build ! String cstConfigSuffix = '' - if (finalConfig.agentLabels.contains('windows') || finalConfig.platforms.contains('windows')) { - if (finalConfig.platforms.split(',').length > 1) { + if (finalConfig.agentLabels.contains('windows') || finalConfig.targetplatforms.contains('windows')) { + if (finalConfig.targetplatforms.split(',').length > 1) { echo 'ERROR: with windows, only one platform can be specified within platforms.' currentBuild.result = 'FAILURE' return } - if (finalConfig.agentLabels.contains('windows') && !finalConfig.platforms.contains('windows')) { - echo "WARNING: A 'windows' agent is requested, but the 'platform(s)' is set to '${finalConfig.platforms}'." + if (finalConfig.agentLabels.contains('windows') && !finalConfig.targetplatforms.contains('windows')) { + echo "WARNING: A 'windows' agent is requested, but the 'platform(s)' is set to '${finalConfig.targetplatforms}'." } - if (!finalConfig.agentLabels.contains('windows') && finalConfig.platforms.contains('windows')) { - echo "WARNING: The 'platforms' is set to '${finalConfig.platforms}', but there isn't any 'windows' agent requested." + if (!finalConfig.agentLabels.contains('windows') && finalConfig.targetplatforms.contains('windows')) { + echo "WARNING: The 'targetplatforms' is set to '${finalConfig.targetplatforms}', but there isn't any 'windows' agent requested." } cstConfigSuffix = '-windows' } - String operatingSystem = finalConfig.platforms.split('/')[0] + String operatingSystem = finalConfig.targetplatforms.split('/')[0] if (operatingSystem == 'windows' && finalConfig.dockerBakeFile != '') { echo 'ERROR: dockerBakeFile is not supported on windows.' @@ -88,8 +90,8 @@ def call(String imageShortName, Map userConfig=[:]) { "IMAGE_NAME=${imageName}", "IMAGE_DIR=${finalConfig.imageDir}", "IMAGE_DOCKERFILE=${finalConfig.dockerfile}", - "BUILD_TARGETPLATFORM=${finalConfig.platforms}", - "BAKE_TARGETPLATFORMS=${finalConfig.platforms}", + "BUILD_TARGETPLATFORM=${finalConfig.targetplatforms}", + "BAKE_TARGETPLATFORMS=${finalConfig.targetplatforms}", "DOCKER_BAKE_FILE=${finalConfig.dockerBakeFile ?: jenkinsInfraBakeFile}", ]) { infra.withDockerPullCredentials{ From 8e57caf2e669a8666e2e013d7f1f51931ed18858 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 25 Aug 2023 17:38:30 +0200 Subject: [PATCH 54/70] factorize and chores --- vars/buildDockerAndPublishImage.groovy | 107 +++++++++++++------------ 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 08703f180..db04f60fa 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -3,6 +3,49 @@ import java.text.SimpleDateFormat import java.util.Date import java.text.DateFormat +def makecall(String action, String imageDeployName, String targetOperationSystem, String SpecificDockerBakeFile) { + final String jenkinsInfraBakeFile = 'jenkinsinfrabakefile.hcl' + final String bakefileContent = libraryResource 'io/jenkins/infra/docker/' + jenkinsInfraBakeFile + if (action != 'build' && action != 'deploy'){ + echo 'ERROR: makecall need an action parameter with value: `build` or `deploy`.' + currentBuild.result = 'FAILURE' + return + } + if (imageDeployName == '') { + echo 'ERROR: makecall need an action imageDeployName.' + currentBuild.result = 'FAILURE' + return + } + if (targetOperationSystem == '') { + echo 'ERROR: targetOperationSystem cannot be empty.' + currentBuild.result = 'FAILURE' + return + } + // Please note that "make deploy" and the generated bake deploy file uses the environment variable "IMAGE_DEPLOY_NAME" + withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}"]) { + if (isUnix()) { + if (SpecificDockerBakeFile) { + withEnv(["DOCKER_BAKE_FILE=${SpecificDockerBakeFile}"]) { + sh 'make bake-$action' + } + } else { + if (targetOperationSystem == "linux") { + //linux ==> generated docker bake + writeFile file: jenkinsInfraBakeFile, text: bakefileContent + withEnv(["DOCKER_BAKE_FILE=${jenkinsInfraBakeFile}"]) { + sh 'make bake-$action' + } + } else { + // old process still used for windows + sh 'make $action' + } + } + } else { + powershell 'make $action' + } // unix agent + } // withEnv +} + def call(String imageShortName, Map userConfig=[:]) { def defaultConfig = [ agentLabels: 'docker || linux-amd64-docker', // String expression for the labels the agent must match @@ -17,14 +60,12 @@ def call(String imageShortName, Map userConfig=[:]) { unstash: '', // Allow to unstash files if not empty dockerBakeFile: '', // Allow to build from a bake file instead ] - // Merging the 2 maps - https://blog.mrhaki.com/2010/04/groovy-goodness-adding-maps-to-map_21.html final Map finalConfig = defaultConfig << userConfig // Retrieve Library's Static File Resources final String makefileContent = libraryResource 'io/jenkins/infra/docker/Makefile' - final String jenkinsInfraBakeFile = 'jenkinsinfrabakefile.hcl' - final String bakefileContent = libraryResource 'io/jenkins/infra/docker/' + jenkinsInfraBakeFile + final boolean semVerEnabledOnPrimaryBranch = finalConfig.automaticSemanticVersioning && env.BRANCH_IS_PRIMARY // Only run 1 build at a time on primary branch to ensure builds won't use the same tag when semantic versionning is activated @@ -36,16 +77,16 @@ def call(String imageShortName, Map userConfig=[:]) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX") final String buildDate = dateFormat.format(now) - - // only one platform parameter is supported for now either platform or platforms - if (finalConfig.platform && finalConfig.targetplatforms) { - // both platform and platforms cannot be set at the same time - echo 'ERROR: Only one platform parameter is supported for now either platform or targetplatforms, prefer targetplatforms.' - currentBuild.result = 'FAILURE' - return - } else if (finalConfig.platform) { + if (finalConfig.platform) { + if (finalConfig.targetplatforms) { + // only one platform parameter is supported both platform and platforms cannot be set at the same time + echo 'ERROR: Only one platform parameter is supported for now either platform or targetplatforms, prefer `targetplatforms`.' + currentBuild.result = 'FAILURE' + return + } // if platform is set, I override platforms with it finalConfig.targetplatforms = finalConfig.platform + echo "WARNING: `platform` is deprecated, use `targetplatforms` instead." } // Default Value if targetplatforms is not set, I set it to linux/amd64 by default @@ -58,7 +99,7 @@ def call(String imageShortName, Map userConfig=[:]) { String cstConfigSuffix = '' if (finalConfig.agentLabels.contains('windows') || finalConfig.targetplatforms.contains('windows')) { if (finalConfig.targetplatforms.split(',').length > 1) { - echo 'ERROR: with windows, only one platform can be specified within platforms.' + echo 'ERROR: with windows, only one platform can be specified within targetplatforms.' currentBuild.result = 'FAILURE' return } @@ -82,6 +123,7 @@ def call(String imageShortName, Map userConfig=[:]) { final String defaultRegistryNamespace = infraConfig.getDockerRegistryNamespace() final String registryNamespace = finalConfig.registryNamespace ?: defaultRegistryNamespace final String imageName = registryNamespace + '/' + imageShortName + echo "INFO: Resolved Container Image Name: ${imageName}" node(finalConfig.agentLabels) { @@ -92,7 +134,6 @@ def call(String imageShortName, Map userConfig=[:]) { "IMAGE_DOCKERFILE=${finalConfig.dockerfile}", "BUILD_TARGETPLATFORM=${finalConfig.targetplatforms}", "BAKE_TARGETPLATFORMS=${finalConfig.targetplatforms}", - "DOCKER_BAKE_FILE=${finalConfig.dockerBakeFile ?: jenkinsInfraBakeFile}", ]) { infra.withDockerPullCredentials{ String nextVersion = '' @@ -172,24 +213,7 @@ def call(String imageShortName, Map userConfig=[:]) { } // stage stage("Build ${imageName}") { - withEnv(["IMAGE_DEPLOY_NAME=${imageName}"]) { - if (isUnix()) { - if (finalConfig.dockerBakeFile != '') { - sh 'make bake-build' - } else { - if (operatingSystem == "linux") { - //linux ==> generated docker bake - writeFile file: jenkinsInfraBakeFile, text: bakefileContent - sh 'make bake-build' - } else { - // old process still used for windows - sh 'make build' - } - } - } else { - powershell 'make build' - } - } // withEnv + makecall('build', imageName, operatingSystem, finalConfig.dockerBakeFile) } //stage // There can be 2 kind of tests: per image and per repository @@ -264,25 +288,8 @@ def call(String imageShortName, Map userConfig=[:]) { imageDeployName += ":${env.TAG_NAME}" } } - if (isUnix()) { - withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}"]) { - // Please note that "make deploy" and the generated bake deploy file uses the environment variable "IMAGE_DEPLOY_NAME" - if (finalConfig.dockerBakeFile != '') { - sh 'make bake-deploy' - } else { - if (operatingSystem == "linux") { - //linux ==> generated docker bake - sh 'make bake-deploy' - } else { - // old process still used for windows - sh 'make deploy' - } - } - } // withEnv - } else { - powershell 'make deploy' - } // unix agent - } //stage + makecall('deploy', imageDeployName, operatingSystem, finalConfig.dockerBakeFile) + } } // if } // withDockerPushCredentials From b49e1107d441f149fb462b49373c9fa8dcc5afac Mon Sep 17 00:00:00 2001 From: smerle33 Date: Fri, 25 Aug 2023 17:39:05 +0200 Subject: [PATCH 55/70] change test but error on same for build and deploy need to find a way to test --- ...BuildDockerAndPublishImageStepTests.groovy | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/test/groovy/BuildDockerAndPublishImageStepTests.groovy b/test/groovy/BuildDockerAndPublishImageStepTests.groovy index 49407cf92..16d33c2e6 100644 --- a/test/groovy/BuildDockerAndPublishImageStepTests.groovy +++ b/test/groovy/BuildDockerAndPublishImageStepTests.groovy @@ -117,7 +117,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { Boolean assertBaseWorkflow() { return assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile') \ && (assertMethodCallContainsPattern('sh','make lint') || assertMethodCallContainsPattern('powershell','make lint')) \ - && (assertMethodCallContainsPattern('sh','make build') || assertMethodCallContainsPattern('sh','make bake-build') || assertMethodCallContainsPattern('powershell','make build')) \ + && (assertMethodCallContainsPattern('sh','make $action') || assertMethodCallContainsPattern('sh','make bake-$action') || assertMethodCallContainsPattern('powershell','make $action')) \ && assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}") } @@ -132,7 +132,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // return if the "make deploy" was detected with the provided argument as image name Boolean assertMakeDeploy(String expectedImageName = fullTestImageName) { - return (assertMethodCallContainsPattern('sh','make deploy') || assertMethodCallContainsPattern('sh','make bake-deploy') || assertMethodCallContainsPattern('powershell','make deploy')) \ + return (assertMethodCallContainsPattern('sh','make $action') || assertMethodCallContainsPattern('sh','make bake-$action') || assertMethodCallContainsPattern('powershell','make $action')) \ && assertMethodCallContainsPattern('withEnv', "IMAGE_DEPLOY_NAME=${expectedImageName}") } @@ -622,13 +622,32 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { } @Test - void itFailWithBothPlatformAndPlatforms() throws Exception { + void itBuildWithWarningWithPlatform() throws Exception { def script = loadScript(scriptName) mockPrincipalBranch() withMocks{ script.call(testImageName, [ platform: 'linux/amd64', - platforms: 'linux/arm64', + ]) + } + + printCallStack() + + // Then we expect a failing build + assertJobStatusSuccess() + + // And the error message is shown + assertTrue(assertMethodCallContainsPattern('echo', 'WARNING: `platform` is deprecated, use `targetplatforms` instead.')) + } + + @Test + void itFailWithBothPlatformAndTargetplatforms() throws Exception { + def script = loadScript(scriptName) + mockPrincipalBranch() + withMocks{ + script.call(testImageName, [ + platform: 'linux/amd64', + targetplatforms: 'linux/arm64', ]) } @@ -638,7 +657,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertJobStatusFailure() // And the error message is shown - assertTrue(assertMethodCallContainsPattern('echo', 'ERROR: Only one platform parameter is supported for now either platform or platforms, prefer platforms.')) + assertTrue(assertMethodCallContainsPattern('echo', 'ERROR: Only one platform parameter is supported for now either platform or targetplatforms, prefer `targetplatforms`.')) } @Test @@ -648,7 +667,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { withMocks{ script.call(testImageName, [ agentLabels: 'docker-windows', - platforms: 'linux/arm64,linux/amd64', + targetplatforms: 'linux/arm64,linux/amd64', ]) } @@ -658,7 +677,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertJobStatusFailure() // And the error message is shown - assertTrue(assertMethodCallContainsPattern('echo', 'ERROR: with windows, only one platform can be specified within platforms.')) + assertTrue(assertMethodCallContainsPattern('echo', 'ERROR: with windows, only one platform can be specified within targetplatforms.')) } @Test @@ -668,7 +687,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { withMocks{ script.call(testImageName, [ dockerBakeFile: 'bake.yml', - platforms: 'windows/1804', + targetplatforms: 'windows/1804', agentLabels: 'docker-windows', ]) } From 769483105ca3799175de4e5a662189526dfccede Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 28 Aug 2023 11:05:12 +0200 Subject: [PATCH 56/70] revert test with correct action --- test/groovy/BuildDockerAndPublishImageStepTests.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/groovy/BuildDockerAndPublishImageStepTests.groovy b/test/groovy/BuildDockerAndPublishImageStepTests.groovy index 16d33c2e6..42ea516d9 100644 --- a/test/groovy/BuildDockerAndPublishImageStepTests.groovy +++ b/test/groovy/BuildDockerAndPublishImageStepTests.groovy @@ -117,7 +117,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { Boolean assertBaseWorkflow() { return assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile') \ && (assertMethodCallContainsPattern('sh','make lint') || assertMethodCallContainsPattern('powershell','make lint')) \ - && (assertMethodCallContainsPattern('sh','make $action') || assertMethodCallContainsPattern('sh','make bake-$action') || assertMethodCallContainsPattern('powershell','make $action')) \ + && (assertMethodCallContainsPattern('sh','make build') || assertMethodCallContainsPattern('sh','make bake-build') || assertMethodCallContainsPattern('powershell','make build')) \ && assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}") } @@ -132,7 +132,7 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // return if the "make deploy" was detected with the provided argument as image name Boolean assertMakeDeploy(String expectedImageName = fullTestImageName) { - return (assertMethodCallContainsPattern('sh','make $action') || assertMethodCallContainsPattern('sh','make bake-$action') || assertMethodCallContainsPattern('powershell','make $action')) \ + return (assertMethodCallContainsPattern('sh','make deploy') || assertMethodCallContainsPattern('sh','make bake-deploy') || assertMethodCallContainsPattern('powershell','make deploy')) \ && assertMethodCallContainsPattern('withEnv', "IMAGE_DEPLOY_NAME=${expectedImageName}") } From 4bfd3b2f3ba76efd0e857f6b6a2982ebc14a291a Mon Sep 17 00:00:00 2001 From: smerle33 Date: Mon, 28 Aug 2023 11:05:47 +0200 Subject: [PATCH 57/70] replace single quotes by double quotes to enable groovy interpolation --- vars/buildDockerAndPublishImage.groovy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index db04f60fa..00d6900fd 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -26,22 +26,22 @@ def makecall(String action, String imageDeployName, String targetOperationSystem if (isUnix()) { if (SpecificDockerBakeFile) { withEnv(["DOCKER_BAKE_FILE=${SpecificDockerBakeFile}"]) { - sh 'make bake-$action' + sh "make bake-$action" } } else { if (targetOperationSystem == "linux") { //linux ==> generated docker bake writeFile file: jenkinsInfraBakeFile, text: bakefileContent withEnv(["DOCKER_BAKE_FILE=${jenkinsInfraBakeFile}"]) { - sh 'make bake-$action' + sh "make bake-$action" } } else { // old process still used for windows - sh 'make $action' + sh "make $action" } } } else { - powershell 'make $action' + powershell "make $action" } // unix agent } // withEnv } From d27e0cc47d34c8aea69a66accb4d84d6fd30cec0 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 29 Aug 2023 09:38:31 +0200 Subject: [PATCH 58/70] move tag manually add to the function --- vars/buildDockerAndPublishImage.groovy | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 00d6900fd..a283cb84a 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -21,6 +21,23 @@ def makecall(String action, String imageDeployName, String targetOperationSystem currentBuild.result = 'FAILURE' return } + + if (action == 'deploy') { + String imageDeployName = imageName + if (env.TAG_NAME) { + if (imageDeployName.contains(env.TAG_NAME)) { + // The tag is already within the image name to deploy no need to add it again + } else { + // User could specify a tag in the image name. In that case the git tag is appended. Otherwise the docker tag is set to the git tag. + if (imageDeployName.contains(':')) { + imageDeployName += "-${env.TAG_NAME}" + } else { + imageDeployName += ":${env.TAG_NAME}" + } + } + } + } + // Please note that "make deploy" and the generated bake deploy file uses the environment variable "IMAGE_DEPLOY_NAME" withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}"]) { if (isUnix()) { @@ -279,15 +296,6 @@ def call(String imageShortName, Map userConfig=[:]) { infra.withDockerPushCredentials{ if (env.TAG_NAME || env.BRANCH_IS_PRIMARY) { stage("Deploy ${imageName}") { - String imageDeployName = imageName - if (env.TAG_NAME) { - // User could specify a tag in the image name. In that case the git tag is appended. Otherwise the docker tag is set to the git tag. - if (imageDeployName.contains(':')) { - imageDeployName += "-${env.TAG_NAME}" - } else { - imageDeployName += ":${env.TAG_NAME}" - } - } makecall('deploy', imageDeployName, operatingSystem, finalConfig.dockerBakeFile) } } // if From edbc5b819a73479dd249a4d2ba245d0e1f080d18 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 29 Aug 2023 09:46:57 +0200 Subject: [PATCH 59/70] remove duplicate variable definition --- vars/buildDockerAndPublishImage.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index a283cb84a..bf4f4a92a 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -23,7 +23,6 @@ def makecall(String action, String imageDeployName, String targetOperationSystem } if (action == 'deploy') { - String imageDeployName = imageName if (env.TAG_NAME) { if (imageDeployName.contains(env.TAG_NAME)) { // The tag is already within the image name to deploy no need to add it again From a59fb6b365e62ca1e1b289aeb15adbde8164cb09 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 29 Aug 2023 10:11:56 +0200 Subject: [PATCH 60/70] rename variable --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index bf4f4a92a..f54bcc99e 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -295,7 +295,7 @@ def call(String imageShortName, Map userConfig=[:]) { infra.withDockerPushCredentials{ if (env.TAG_NAME || env.BRANCH_IS_PRIMARY) { stage("Deploy ${imageName}") { - makecall('deploy', imageDeployName, operatingSystem, finalConfig.dockerBakeFile) + makecall('deploy', imageName, operatingSystem, finalConfig.dockerBakeFile) } } // if } // withDockerPushCredentials From 7bf6023e98dc99738c28cee6397162c168d4c583 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 29 Aug 2023 10:20:12 +0200 Subject: [PATCH 61/70] add tag only with legacy process for windows target / agent --- vars/buildDockerAndPublishImage.groovy | 43 +++++++++++++++++--------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index f54bcc99e..54871bf5f 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -22,21 +22,6 @@ def makecall(String action, String imageDeployName, String targetOperationSystem return } - if (action == 'deploy') { - if (env.TAG_NAME) { - if (imageDeployName.contains(env.TAG_NAME)) { - // The tag is already within the image name to deploy no need to add it again - } else { - // User could specify a tag in the image name. In that case the git tag is appended. Otherwise the docker tag is set to the git tag. - if (imageDeployName.contains(':')) { - imageDeployName += "-${env.TAG_NAME}" - } else { - imageDeployName += ":${env.TAG_NAME}" - } - } - } - } - // Please note that "make deploy" and the generated bake deploy file uses the environment variable "IMAGE_DEPLOY_NAME" withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}"]) { if (isUnix()) { @@ -53,10 +38,38 @@ def makecall(String action, String imageDeployName, String targetOperationSystem } } else { // old process still used for windows + if (action == 'deploy') { + if (env.TAG_NAME) { + if (imageDeployName.contains(env.TAG_NAME)) { + // The tag is already within the image name to deploy no need to add it again + } else { + // User could specify a tag in the image name. In that case the git tag is appended. Otherwise the docker tag is set to the git tag. + if (imageDeployName.contains(':')) { + imageDeployName += "-${env.TAG_NAME}" + } else { + imageDeployName += ":${env.TAG_NAME}" + } + } + } + } sh "make $action" } } } else { + if (action == 'deploy') { + if (env.TAG_NAME) { + if (imageDeployName.contains(env.TAG_NAME)) { + // The tag is already within the image name to deploy no need to add it again + } else { + // User could specify a tag in the image name. In that case the git tag is appended. Otherwise the docker tag is set to the git tag. + if (imageDeployName.contains(':')) { + imageDeployName += "-${env.TAG_NAME}" + } else { + imageDeployName += ":${env.TAG_NAME}" + } + } + } + } powershell "make $action" } // unix agent } // withEnv From e929bef6245f575a964e8860212d706648c69822 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 29 Aug 2023 14:53:02 +0200 Subject: [PATCH 62/70] cleanup unit tests --- ...BuildDockerAndPublishImageStepTests.groovy | 84 +++++++++---------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/test/groovy/BuildDockerAndPublishImageStepTests.groovy b/test/groovy/BuildDockerAndPublishImageStepTests.groovy index 42ea516d9..9224e1327 100644 --- a/test/groovy/BuildDockerAndPublishImageStepTests.groovy +++ b/test/groovy/BuildDockerAndPublishImageStepTests.groovy @@ -130,12 +130,6 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { ) } - // return if the "make deploy" was detected with the provided argument as image name - Boolean assertMakeDeploy(String expectedImageName = fullTestImageName) { - return (assertMethodCallContainsPattern('sh','make deploy') || assertMethodCallContainsPattern('sh','make bake-deploy') || assertMethodCallContainsPattern('powershell','make deploy')) \ - && assertMethodCallContainsPattern('withEnv', "IMAGE_DEPLOY_NAME=${expectedImageName}") - } - Boolean assertTagPushed(String newVersion) { return assertMethodCallContainsPattern('echo','Configuring credential.helper') \ && assertMethodCallContainsPattern('echo',"Tagging and pushing the new version: ${newVersion}") \ @@ -174,12 +168,13 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DEPLOY_NAME=' + fullTestImageName)) // And generated reports are recorded assertTrue(assertRecordIssues()) // And the deploy step called - assertTrue(assertMakeDeploy()) + assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) // And `unstash` isn't called assertFalse(assertMethodCall('unstash')) @@ -209,7 +204,9 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And generated reports are recorded with named without ':' but '-' instead assertTrue(assertRecordIssues(fullCustomImageName.replaceAll(':','-'))) // With the deploy step called with the correct image name - assertTrue(assertMakeDeploy(fullCustomImageName)) + assertMethodCallContainsPattern('sh','make bake-deploy') + assertMethodCallContainsPattern('withEnv', "IMAGE_DEPLOY_NAME=${fullCustomImageName}") + // But no tag pushed assertFalse(assertTagPushed(defaultGitTag)) // And all mocked/stubbed methods have to be called @@ -235,7 +232,9 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And generated reports are recorded assertTrue(assertRecordIssues()) // And the deploy step called - assertTrue(assertMakeDeploy()) + assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DEPLOY_NAME=' +fullTestImageName)) + // And the tag pushed assertTrue(assertTagPushed(defaultGitTag)) // But no release created (no tag triggering the build) @@ -264,7 +263,9 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And generated reports are recorded assertTrue(assertRecordIssues()) // And the deploy step called - assertTrue(assertMakeDeploy()) + assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DEPLOY_NAME=' + fullTestImageName)) + // And the tag pushed assertTrue(assertTagPushed(defaultGitTagIncludingImageName)) // But no release created (no tag triggering the build) @@ -300,7 +301,9 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/s390x')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_NAME=' + expectedImageName)) // But no tag and no deploy called (branch or PR) - assertTrue(assertMakeDeploy(expectedImageName)) + assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DEPLOY_NAME=' + expectedImageName)) + assertTrue(assertTagPushed(defaultGitTag)) // And all mocked/stubbed methods have to be called verifyMocks() @@ -322,7 +325,8 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertTrue(assertBaseWorkflow()) assertTrue(assertMethodCallContainsPattern('node', 'docker')) // But no deploy step called for latest - assertFalse(assertMakeDeploy()) + assertFalse(assertMethodCallContainsPattern('sh','make bake-deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'TAG_NAME=null')) // And no release (no tag) assertFalse(assertTagPushed(defaultGitTag)) // And all mocked/stubbed methods have to be called @@ -346,7 +350,10 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertTrue(assertBaseWorkflow()) assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And the deploy step called for latest - assertTrue(assertMakeDeploy("${fullTestImageName}:${defaultGitTag}")) + assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DEPLOY_NAME=' + fullTestImageName)) + assertTrue(assertMethodCallContainsPattern('withEnv', 'TAG_NAME=' + defaultGitTag)) + // And the release is created (tag triggering the build) assertTrue(assertReleaseCreated()) // But no tag pushed @@ -379,7 +386,10 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertTrue(assertBaseWorkflow()) assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And the deploy step called for latest - assertTrue(assertMakeDeploy("${fullTestImageName}:${defaultGitTag}")) + assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DEPLOY_NAME=' + fullTestImageName)) + assertTrue(assertMethodCallContainsPattern('withEnv', 'TAG_NAME=' + defaultGitTag)) + // And the release is not created as no next release draft exists assertFalse(assertReleaseCreated()) // But no tag pushed @@ -402,7 +412,10 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build with the code cloned assertJobStatusSuccess() // With the deploy step called with the correct image name - assertTrue(assertMakeDeploy("${fullCustomImageName}-${customGitTag}")) + assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', "IMAGE_DEPLOY_NAME=${fullCustomImageName}")) + assertTrue(assertMethodCallContainsPattern('withEnv', "TAG_NAME=${customGitTag}")) + // And all mocked/stubbed methods have to be called verifyMocks() } @@ -465,33 +478,6 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { verifyMocks() } - @Test - void itBuildsAndDeploysWithDockerEngineOnPrincipalBranch() throws Exception { - def script = loadScript(scriptName) - mockPrincipalBranch() - withMocks { - script.call(testImageName) - } - printCallStack() - // Then we expect a successful build with the code cloned - assertJobStatusSuccess() - // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) - assertTrue(assertMethodCallContainsPattern('node', 'docker')) - // And the expected environment variables set to their default values - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/amd64')) - // And generated reports recorded - assertTrue(assertRecordIssues()) - // And the deploy step called - assertTrue(assertMakeDeploy()) - // But no release created automatically - assertFalse(assertTagPushed(defaultGitTag)) - // And all mocked/stubbed methods been called - verifyMocks() - } - @Test void itBuildsOnlyOnChangeRequestWithWindowsContainers() throws Exception { helper.registerAllowedMethod('isUnix', [], { false }) @@ -511,10 +497,13 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) assertTrue(assertMethodCallContainsPattern('withEnv', 'BAKE_TARGETPLATFORMS=linux/amd64')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_NAME=' + fullTestImageName)) // And generated reports recorded assertTrue(assertRecordIssues()) // But no deploy step called (not on principal branch) - assertFalse(assertMakeDeploy()) + assertFalse(assertMethodCallContainsPattern('sh','make deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'TAG_NAME=null')) + // But no release created automatically assertFalse(assertTagPushed(defaultGitTag)) // And all mocked/stubbed methods been called @@ -551,7 +540,8 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertTrue(assertRecordIssues()) // And the deploy step called - assertTrue(assertMakeDeploy()) + assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DEPLOY_NAME=' + fullTestImageName)) // And `unstash` is called assertTrue(assertMethodCallContainsPattern('unstash', 'stashName')) @@ -583,9 +573,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DOCKERFILE=Dockerfile')) assertTrue(assertMethodCallContainsPattern('withEnv', 'PLATFORMS=linux/amd64,linux/arm64,linux/s390x')) - assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_NAME=jenkinsciinfra/bitcoinMinerImage')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_NAME=' + fullTestImageName)) // But no tag and no deploy called (branch or PR) - assertTrue(assertMakeDeploy()) + assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) + assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DEPLOY_NAME=' + fullTestImageName)) + assertTrue(assertTagPushed(defaultGitTag)) // And all mocked/stubbed methods have to be called verifyMocks() From 3d020403f1bc5ec73882ebf1d88862ac241b661a Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 29 Aug 2023 14:53:31 +0200 Subject: [PATCH 63/70] cleanup factorisation with damien --- vars/buildDockerAndPublishImage.groovy | 53 +++++++------------------- 1 file changed, 13 insertions(+), 40 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 54871bf5f..13caa2b56 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -4,8 +4,7 @@ import java.util.Date import java.text.DateFormat def makecall(String action, String imageDeployName, String targetOperationSystem, String SpecificDockerBakeFile) { - final String jenkinsInfraBakeFile = 'jenkinsinfrabakefile.hcl' - final String bakefileContent = libraryResource 'io/jenkins/infra/docker/' + jenkinsInfraBakeFile + final String bakefileContent = libraryResource 'io/jenkins/infra/docker/jenkinsinfrabakefile.hcl' if (action != 'build' && action != 'deploy'){ echo 'ERROR: makecall need an action parameter with value: `build` or `deploy`.' currentBuild.result = 'FAILURE' @@ -23,50 +22,24 @@ def makecall(String action, String imageDeployName, String targetOperationSystem } // Please note that "make deploy" and the generated bake deploy file uses the environment variable "IMAGE_DEPLOY_NAME" - withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}"]) { + withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}", "TAG_NAME=${env.TAG_NAME}"]) { if (isUnix()) { - if (SpecificDockerBakeFile) { - withEnv(["DOCKER_BAKE_FILE=${SpecificDockerBakeFile}"]) { - sh "make bake-$action" - } - } else { - if (targetOperationSystem == "linux") { - //linux ==> generated docker bake - writeFile file: jenkinsInfraBakeFile, text: bakefileContent - withEnv(["DOCKER_BAKE_FILE=${jenkinsInfraBakeFile}"]) { - sh "make bake-$action" - } - } else { - // old process still used for windows - if (action == 'deploy') { - if (env.TAG_NAME) { - if (imageDeployName.contains(env.TAG_NAME)) { - // The tag is already within the image name to deploy no need to add it again - } else { - // User could specify a tag in the image name. In that case the git tag is appended. Otherwise the docker tag is set to the git tag. - if (imageDeployName.contains(':')) { - imageDeployName += "-${env.TAG_NAME}" - } else { - imageDeployName += ":${env.TAG_NAME}" - } - } - } - } - sh "make $action" - } + if (! SpecificDockerBakeFile) { + SpecificDockerBakeFile = 'jenkinsinfrabakefile.hcl' + //linux ==> generated docker bake + writeFile file: SpecificDockerBakeFile, text: bakefileContent + } + withEnv(["DOCKER_BAKE_FILE=${SpecificDockerBakeFile}"]) { + sh "make bake-$action" } } else { if (action == 'deploy') { if (env.TAG_NAME) { - if (imageDeployName.contains(env.TAG_NAME)) { - // The tag is already within the image name to deploy no need to add it again + // User could specify a tag in the image name. In that case the git tag is appended. Otherwise the docker tag is set to the git tag. + if (imageDeployName.contains(':')) { + imageDeployName += "-${env.TAG_NAME}" } else { - // User could specify a tag in the image name. In that case the git tag is appended. Otherwise the docker tag is set to the git tag. - if (imageDeployName.contains(':')) { - imageDeployName += "-${env.TAG_NAME}" - } else { - imageDeployName += ":${env.TAG_NAME}" - } + imageDeployName += ":${env.TAG_NAME}" } } } From a0be4e7525458b860520fe2f334f06651c582894 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Tue, 29 Aug 2023 15:04:24 +0200 Subject: [PATCH 64/70] add warning if no target platform specified --- vars/buildDockerAndPublishImage.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 13caa2b56..ce19c6bd4 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -93,6 +93,7 @@ def call(String imageShortName, Map userConfig=[:]) { // Default Value if targetplatforms is not set, I set it to linux/amd64 by default if (finalConfig.targetplatforms == '') { + echo "WARNING: `platform` is deprecated, use `targetplatforms` instead." finalConfig.targetplatforms = 'linux/amd64' } From 7e9a0914fe446d85880e6b2f1ccb37af5cd07a45 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 30 Aug 2023 15:56:38 +0200 Subject: [PATCH 65/70] add readme and txt documentation --- README.adoc | 40 ++++++++++++++++++++++++----- vars/buildDockerAndPublishImage.txt | 12 +++++++-- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/README.adoc b/README.adoc index 07be5ca37..3f2787ec2 100644 --- a/README.adoc +++ b/README.adoc @@ -189,18 +189,45 @@ Supported parameters: `imageName`:: Name of the docker image to build -`configs`:: -(Optional) extra flags - -registry: override the smart default of jenkinsciinfra/ or jenkins4eval/ -dockerfile: override the default dockerfile of Dockerfile +`config`:: +(Optional) map of extra flags + +* agentLabels: String expression for the labels the agent must match +* automaticSemanticVersioning: Do not automagically increase semantic version by default +* includeImageNameInTag: Set to true for multiple semversioned images built in parallel, will include the image name in tag to avoid conflict +* dockerfile: override the default dockerfile of Dockerfile +* targetplatforms: defined the platforms to build as TARGET +* nextVersionCommand: Commmand line used to retrieve the next version (default 'jx-release-version') +* gitCredentials: override Credential ID for tagging and creating release +* imageDir: Relative path to the context directory for the Docker build +* registryNamespace: empty = autodiscover based on the current controller, but can override the smart default of jenkinsciinfra/ or jenkins4eval/ +* unstash: Allow to unstash files if not empty +* dockerBakeFile: Allow to build from a bake file instead ==== Example [source, groovy] ---- -buildDockerImage_k8s('plugins-site-api') +buildDockerAndPublishImage('plugins-site-api') +buildDockerAndPublishImage('inbound-agent-maven:jdk8-nanoserver', [ + dockerfile: 'maven/jdk8/Dockerfile.nanoserver', + agentLabels: 'docker-windows-2019 && amd64', + targetplatforms: 'windows/amd64', + imageDir: 'maven/jdk8', + ]) +---- + +is also called from `parallelDockerUpdatecli` with `config` within `buildDockerConfig` like this : +[source, groovy] +---- +parallelDockerUpdatecli([ + imageName: 'wiki', + rebuildImageOnPeriodicJob: false, + updatecliConfig: [containerMemory: '1G'], + buildDockerConfig : [targetplatforms: 'linux/amd64,linux/arm64,linux/s390x'] +]) ---- + == Contribute === Requirements @@ -213,4 +240,3 @@ buildDockerImage_k8s('plugins-site-api') By adding `@Library('pipeline-library@pull//head') _` at the top of a Jenkinsfile from a repository built on one of the *.ci.jenkins.io instances, you can test your pipeline library pull request on ci.jenkins.io. A repository is dedicated for these kind of tests: https://github.com/jenkinsci/jenkins-infra-test-plugin/ - diff --git a/vars/buildDockerAndPublishImage.txt b/vars/buildDockerAndPublishImage.txt index 0543b0bfe..c8fb2a59b 100644 --- a/vars/buildDockerAndPublishImage.txt +++ b/vars/buildDockerAndPublishImage.txt @@ -10,7 +10,8 @@ The following arguments are available for this function: * Boolean **automaticSemanticVersioning**: (Optional, defaults to "false") Should a release be created for every merge to the mainBranch. This uses "jx-release-version" to determine the version number based on the commit history. * Boolean **includeImageNameInTag**: (Optional, defaults to "false") Set to true for multiple semversioned images built in parallel, will include the image name in tag to avoid conflict * String **dockerfile**: (Optional, defaults to "Dockerfile") Relative path to the Dockerfile to use within the repository (Example: "build.dockerfile", "docker/Dockerfile"). - * String **platform**: (Optional, defaults to "linux/amd64") Name of the docker platform to use when building this image. For multiple platforms use a comma separated list (Example: "linux/amd64,linux/arm64"). + * String ~~**platform**~~: DEPRECATED (Optional, defaults to "linux/amd64") Name of the docker platform to use when building this image.. + * String **targetplatforms**: (Optional, defaults to "linux/amd64") Name of the docker platforms separated by comma, to use as target when building this image. For multiple platforms use a comma separated list (Example: "linux/amd64,linux/arm64"). * String **nextVersionCommand** (Optional, defaults to "jx-release-version") If "automaticSemanticVersioning" is set, this is the command to retrieve the next version (to use for tagging and releasing) * String **gitCredentials**: (Optional, defaults to "") If "automaticSemanticVersioning" is set, name of the credential to use when tagging the git repository. Support user/password or GitHub App credential types. * String **imageDir**: (Optional, defaults to ".", the parent directory of the Dockerfile) Path to a directory to use as build context (Example: "docker/", "python/2.7") ref: https://docs.docker.com/engine/reference/commandline/build/#description. @@ -56,7 +57,7 @@ parallel( buildDockerAndPublishImage('maven-jdk8-nanoserver', [ imageDir: 'maven/jdk8', dockerfile: 'Dockerfile.nanoserver', - platform: 'windows/amd64', + targetplatforms: 'windows/amd64', agentLabels: 'windows', automaticSemanticVersioning: true, includeImageNameInTag: true, @@ -64,3 +65,10 @@ parallel( }, ) + +Build of three linux images in parallel (imply docker bake inside) +

+buildDockerAndPublishImage('wiki',[
+  targetplatforms: 'linux/amd64,linux/arm64,linux/s390x'
+]),
+
From b5f8a0e720be3ec17e26b0be6b9281150984e9bd Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 30 Aug 2023 16:34:42 +0200 Subject: [PATCH 66/70] add test and unfactorize some --- ...BuildDockerAndPublishImageStepTests.groovy | 117 +++++++++++++++--- 1 file changed, 97 insertions(+), 20 deletions(-) diff --git a/test/groovy/BuildDockerAndPublishImageStepTests.groovy b/test/groovy/BuildDockerAndPublishImageStepTests.groovy index 9224e1327..5cb4ade8f 100644 --- a/test/groovy/BuildDockerAndPublishImageStepTests.groovy +++ b/test/groovy/BuildDockerAndPublishImageStepTests.groovy @@ -113,14 +113,6 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { addEnvVar('TAG_NAME', gitTag) } - // Return if the set of methods expected for ALL pipeline run have been detected in the callstack - Boolean assertBaseWorkflow() { - return assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile') \ - && (assertMethodCallContainsPattern('sh','make lint') || assertMethodCallContainsPattern('powershell','make lint')) \ - && (assertMethodCallContainsPattern('sh','make build') || assertMethodCallContainsPattern('sh','make bake-build') || assertMethodCallContainsPattern('powershell','make build')) \ - && assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}") - } - // Return if the usual static checks had been recorded with the usual pattern Boolean assertRecordIssues(String imageName = fullTestImageName) { final String reportId = "${imageName}-hadolint-${mockedTimestamp}".replaceAll('/','-').replaceAll(':', '-') @@ -161,7 +153,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And the expected environment variable defined to their defaults @@ -199,7 +195,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build with the code cloned assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And generated reports are recorded with named without ':' but '-' instead assertTrue(assertRecordIssues(fullCustomImageName.replaceAll(':','-'))) @@ -227,7 +227,10 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build with the code cloned assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And generated reports are recorded assertTrue(assertRecordIssues()) @@ -258,7 +261,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build with the code cloned assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And generated reports are recorded assertTrue(assertRecordIssues()) @@ -293,7 +300,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build with the code cloned assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And the environement variables set with the custom configuration values assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=docker/')) @@ -322,7 +333,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) // But no deploy step called for latest assertFalse(assertMethodCallContainsPattern('sh','make bake-deploy')) @@ -347,7 +362,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And the deploy step called for latest assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) @@ -383,7 +402,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And the deploy step called for latest assertTrue(assertMethodCallContainsPattern('sh','make bake-deploy')) @@ -491,7 +514,12 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build with the code cloned assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('powershell','make lint')) + assertTrue(assertMethodCallContainsPattern('powershell','make build')) + + assertTrue(assertMethodCallContainsPattern('node', 'docker-windows')) // And the expected environment variables set to their default values assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) @@ -528,7 +556,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And the expected environment variable defined to their defaults @@ -567,7 +599,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // Then we expect a successful build with the code cloned assertJobStatusSuccess() // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('node', 'docker')) // And the environement variables set with the custom configuration values assertTrue(assertMethodCallContainsPattern('withEnv', 'IMAGE_DIR=.')) @@ -600,7 +636,11 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { assertJobStatusSuccess() // // With the common workflow run as expected - assertTrue(assertBaseWorkflow()) + assertTrue(assertMethodCallContainsPattern('libraryResource','io/jenkins/infra/docker/Makefile')) + assertTrue(assertMethodCallContainsPattern('withEnv', "BUILD_DATE=${mockedSimpleDate}")) + assertTrue(assertMethodCallContainsPattern('sh','make lint')) + assertTrue(assertMethodCallContainsPattern('sh','make bake-build')) + assertTrue(assertMethodCallContainsPattern('sh', 'make bake-build')) assertFalse(assertMethodCallContainsPattern('sh', 'make build')) assertTrue(assertMethodCallContainsPattern('sh', 'make bake-deploy')) @@ -692,4 +732,41 @@ class BuildDockerAndPublishImageStepTests extends BaseTest { // And the error message is shown assertTrue(assertMethodCallContainsPattern('echo', 'ERROR: dockerBakeFile is not supported on windows.')) } + + @Test + void itWarnIfWindowsAgentAndNotWindowsTarget() throws Exception { + def script = loadScript(scriptName) + mockPrincipalBranch() + withMocks{ + script.call(testImageName, [ + targetplatforms: 'linux/amd64', + agentLabels: 'docker-windows', + ]) + } + printCallStack() + + // Then we expect a failing build + assertJobStatusSuccess() + + // And the error message is shown + assertTrue(assertMethodCallContainsPattern('echo', 'WARNING: A \'windows\' agent is requested, but the \'platform(s)\' is set to')) + } + + @Test + void itWarnIfNotWindowsAgentButWindowsTarget() throws Exception { + def script = loadScript(scriptName) + mockPrincipalBranch() + withMocks{ + script.call(testImageName, [ + targetplatforms: 'windows/1804', + ]) + } + printCallStack() + + // Then we expect a failing build + assertJobStatusSuccess() + + // And the error message is shown + assertTrue(assertMethodCallContainsPattern('echo', 'WARNING: The \'targetplatforms\' is set to \'windows/1804\', but there isn\'t any \'windows\' agent requested.')) + } } From b5198340a936aa4b6fbaf131261e027fc0221fae Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 30 Aug 2023 16:35:42 +0200 Subject: [PATCH 67/70] move some command and remove comments, also add the bake-test to ensure load of image --- resources/io/jenkins/infra/docker/Makefile | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/resources/io/jenkins/infra/docker/Makefile b/resources/io/jenkins/infra/docker/Makefile index 42fcc69dd..d9bba666f 100644 --- a/resources/io/jenkins/infra/docker/Makefile +++ b/resources/io/jenkins/infra/docker/Makefile @@ -55,10 +55,8 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE) bake-build: ## Build the Docker Image(s) with dockerbake file @echo "== Building from DockerBake file" - docker buildx create --use - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(shell dpkg --print-architecture)" --load + @docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" + clean: ## Delete any file generated during the build steps @echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:" @@ -70,6 +68,13 @@ test: ## Execute the test harness on the Docker Image container-structure-test test --driver=docker --image="$(IMAGE_NAME)" --config="$(call FixPath,$(TEST_HARNESS))" @echo "== Test succeeded" +bake-test: ## Execute the test harness on the Docker Image with load + @echo "== Load $(IMAGE_NAME) within docker engine from docker bake buildx engine" + @docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(shell dpkg --print-architecture)" --load + @echo "== Test $(IMAGE_NAME) with $(call FixPath,$(TEST_HARNESS)) from $(IMAGE_NAME) with container-structure-test:" + container-structure-test test --driver=docker --image="$(IMAGE_NAME)" --config="$(call FixPath,$(TEST_HARNESS))" + @echo "== Test succeeded" + ## This steps expects that you are logged to the Docker registry to push image into deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). @echo "== Deploying $(IMAGE_NAME) to $(IMAGE_DEPLOY_NAME) with docker:" @@ -79,7 +84,6 @@ deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY). bake-deploy: ## Tag and push the built image as specified by docker bake file @echo "== Deploying with docker bake file" - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --print - docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push + @docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push .PHONY: all clean lint build test deploy From aef6007c439289744382dfb4bf70c72db74e3434 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 30 Aug 2023 16:36:20 +0200 Subject: [PATCH 68/70] chore some infos with new comments --- vars/buildDockerAndPublishImage.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.txt b/vars/buildDockerAndPublishImage.txt index c8fb2a59b..b337120d3 100644 --- a/vars/buildDockerAndPublishImage.txt +++ b/vars/buildDockerAndPublishImage.txt @@ -11,12 +11,13 @@ The following arguments are available for this function: * Boolean **includeImageNameInTag**: (Optional, defaults to "false") Set to true for multiple semversioned images built in parallel, will include the image name in tag to avoid conflict * String **dockerfile**: (Optional, defaults to "Dockerfile") Relative path to the Dockerfile to use within the repository (Example: "build.dockerfile", "docker/Dockerfile"). * String ~~**platform**~~: DEPRECATED (Optional, defaults to "linux/amd64") Name of the docker platform to use when building this image.. - * String **targetplatforms**: (Optional, defaults to "linux/amd64") Name of the docker platforms separated by comma, to use as target when building this image. For multiple platforms use a comma separated list (Example: "linux/amd64,linux/arm64"). + * String **targetplatforms**: (Optional, defaults to "linux/amd64") Define the (comma separated) list of Docker supported platforms to build the image for. Defaults to `linux/amd64` when unspecified. Incompatible with the legacy `platform` attribute. * String **nextVersionCommand** (Optional, defaults to "jx-release-version") If "automaticSemanticVersioning" is set, this is the command to retrieve the next version (to use for tagging and releasing) * String **gitCredentials**: (Optional, defaults to "") If "automaticSemanticVersioning" is set, name of the credential to use when tagging the git repository. Support user/password or GitHub App credential types. * String **imageDir**: (Optional, defaults to ".", the parent directory of the Dockerfile) Path to a directory to use as build context (Example: "docker/", "python/2.7") ref: https://docs.docker.com/engine/reference/commandline/build/#description. * String **registry**: (Optional, defaults to "" which defines the registry based on the current controller setup) Container registry to deploy this image to (Example: "ghcr.io", "python/2.7"). * String **unstash**: (Optional, default to "") Allow to restore files from a previously saved stash if not empty, should contain the name of the last stashed as per https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#unstash-restore-files-previously-stashed. + * String **dockerBakeFile**: (Optionan, default to "") Specify the path to a custom Docker Bake file to use instead of the default one The lint phase generates a report when it fails, recorded by the hadolint tool in your Jenkins instance. From e0c105ff1ef897cebaddbfb22237c15665da0439 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 30 Aug 2023 16:37:01 +0200 Subject: [PATCH 69/70] take care of comments in PR --- vars/buildDockerAndPublishImage.groovy | 39 +++++++------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index ce19c6bd4..64d695576 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -3,33 +3,19 @@ import java.text.SimpleDateFormat import java.util.Date import java.text.DateFormat -def makecall(String action, String imageDeployName, String targetOperationSystem, String SpecificDockerBakeFile) { +// makecall is a function to concentrate all the call to 'make' +def makecall(String action, String imageDeployName, String targetOperationSystem, String specificDockerBakeFile) { final String bakefileContent = libraryResource 'io/jenkins/infra/docker/jenkinsinfrabakefile.hcl' - if (action != 'build' && action != 'deploy'){ - echo 'ERROR: makecall need an action parameter with value: `build` or `deploy`.' - currentBuild.result = 'FAILURE' - return - } - if (imageDeployName == '') { - echo 'ERROR: makecall need an action imageDeployName.' - currentBuild.result = 'FAILURE' - return - } - if (targetOperationSystem == '') { - echo 'ERROR: targetOperationSystem cannot be empty.' - currentBuild.result = 'FAILURE' - return - } // Please note that "make deploy" and the generated bake deploy file uses the environment variable "IMAGE_DEPLOY_NAME" withEnv(["IMAGE_DEPLOY_NAME=${imageDeployName}", "TAG_NAME=${env.TAG_NAME}"]) { if (isUnix()) { - if (! SpecificDockerBakeFile) { - SpecificDockerBakeFile = 'jenkinsinfrabakefile.hcl' - //linux ==> generated docker bake - writeFile file: SpecificDockerBakeFile, text: bakefileContent + if (! specificDockerBakeFile) { + specificDockerBakeFile = 'jenkinsinfrabakefile.hcl' + writeFile file: specificDockerBakeFile, text: bakefileContent } - withEnv(["DOCKER_BAKE_FILE=${SpecificDockerBakeFile}"]) { + withEnv(["DOCKER_BAKE_FILE=${specificDockerBakeFile}"]) { + sh 'docker buildx create --use' sh "make bake-$action" } } else { @@ -54,13 +40,13 @@ def call(String imageShortName, Map userConfig=[:]) { automaticSemanticVersioning: false, // Do not automagically increase semantic version by default includeImageNameInTag: false, // Set to true for multiple semversioned images built in parallel, will include the image name in tag to avoid conflict dockerfile: 'Dockerfile', // Obvious default - targetplatforms: '', // defined the platforms to build as TARGET + targetplatforms: '', // // Define the (comma separated) list of Docker supported platforms to build the image for. Defaults to `linux/amd64` when unspecified. Incompatible with the legacy `platform` attribute. nextVersionCommand: 'jx-release-version', // Commmand line used to retrieve the next version gitCredentials: 'github-app-infra', // Credential ID for tagging and creating release imageDir: '.', // Relative path to the context directory for the Docker build registryNamespace: '', // Empty by default (means "autodiscover based on the current controller") unstash: '', // Allow to unstash files if not empty - dockerBakeFile: '', // Allow to build from a bake file instead + dockerBakeFile: '', // Specify the path to a custom Docker Bake file to use instead of the default one ] // Merging the 2 maps - https://blog.mrhaki.com/2010/04/groovy-goodness-adding-maps-to-map_21.html final Map finalConfig = defaultConfig << userConfig @@ -93,7 +79,6 @@ def call(String imageShortName, Map userConfig=[:]) { // Default Value if targetplatforms is not set, I set it to linux/amd64 by default if (finalConfig.targetplatforms == '') { - echo "WARNING: `platform` is deprecated, use `targetplatforms` instead." finalConfig.targetplatforms = 'linux/amd64' } @@ -228,11 +213,7 @@ def call(String imageShortName, Map userConfig=[:]) { if (fileExists(testHarness)) { stage("Test ${testName} for ${imageName}") { withEnv(["TEST_HARNESS=${testHarness}"]) { - if (isUnix()) { - sh 'make test' - } else { - powershell 'make test' - } + makecall('test', imageName, operatingSystem, finalConfig.dockerBakeFile) } // withEnv } //stage } else { From fcc0873104f94cbecd17779ff698264aca284883 Mon Sep 17 00:00:00 2001 From: smerle33 Date: Wed, 30 Aug 2023 17:40:51 +0200 Subject: [PATCH 70/70] using a name builx environement to avoid rebuild on each call --- vars/buildDockerAndPublishImage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/buildDockerAndPublishImage.groovy b/vars/buildDockerAndPublishImage.groovy index 64d695576..15a541689 100644 --- a/vars/buildDockerAndPublishImage.groovy +++ b/vars/buildDockerAndPublishImage.groovy @@ -15,7 +15,7 @@ def makecall(String action, String imageDeployName, String targetOperationSystem writeFile file: specificDockerBakeFile, text: bakefileContent } withEnv(["DOCKER_BAKE_FILE=${specificDockerBakeFile}"]) { - sh 'docker buildx create --use' + sh 'export BUILDX_BUILDER_NAME=buildx-builder; docker buildx use "${BUILDX_BUILDER_NAME}" 2>/dev/null || docker buildx create --use --name="${BUILDX_BUILDER_NAME}"' sh "make bake-$action" } } else {