From 9281c3fe2a2d3f2a5f622d21a12f7b6aeb1451da Mon Sep 17 00:00:00 2001 From: Jerome Touffe-Blin Date: Sat, 25 Nov 2023 12:03:40 +1100 Subject: [PATCH] Build docker cross-platform with buildx --- .circleci/config.yml | 48 +++++++++++++++++++++++++++++++++++++++++++- Makefile | 38 ++++++++++++++++++++--------------- 2 files changed, 69 insertions(+), 17 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7fca8db..e46108d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,7 +30,42 @@ jobs: command: make setup - run: name: "build and test" - command: make build test-race check bench-race coveralls + command: make build junit-test test-race check bench-race coveralls + - store_test_results: + path: test-report.xml + build-docker: + docker: # executor type + - image: cimg/base:stable # primary container will run the latest, production-ready base image + steps: + - checkout + - setup_remote_docker: + docker_layer_caching: true + - run: + name: Docker build + command: | + docker login -u="$DOCKERHUB_USERNAME" -p="$DOCKERHUB_PASSWORD" + make docker + release: + docker: # executor type + - image: cimg/base:stable # primary container will run the latest, production-ready base image + steps: + - checkout + - setup_remote_docker: + docker_layer_caching: true + - run: + name: Docker push + command: | + if [ ! -z "$CIRCLE_TAG" ]; then + docker login -u="$DOCKERHUB_USERNAME" -p="$DOCKERHUB_PASSWORD" + echo "Executing release on tag build $CIRCLE_TAG" + if [ "$CIRCLE_TAG" = "dev" ]; then + make docker-dev + else + make release-ci + fi + else + echo "Not executing release on non-tag build" + fi # Orchestrate jobs using workflows # See: https://circleci.com/docs/configuration-reference/#workflows @@ -38,3 +73,14 @@ workflows: kube2iam-workflow: jobs: - build-and-test + - build-docker + - release: + requires: + - build-and-test + - build-docker + filters: + branches: + only: + - main + - /release-[\w\.]+/ + diff --git a/Makefile b/Makefile index 706ee16..480e257 100644 --- a/Makefile +++ b/Makefile @@ -10,13 +10,14 @@ GIT_HASH := $$(git rev-parse --short HEAD) GOBUILD_VERSION_ARGS := -ldflags "-s -X $(VERSION_VAR)=$(REPO_VERSION) -X $(GIT_VAR)=$(GIT_HASH) -X $(BUILD_DATE_VAR)=$(BUILD_DATE)" # useful for other docker repos DOCKER_REPO ?= jtblin -CPU_ARCH ?= amd64 +CPU_ARCH ?= arm64 IMAGE_NAME := $(DOCKER_REPO)/$(BINARY_NAME)-$(CPU_ARCH) MANIFEST_NAME := $(DOCKER_REPO)/$(BINARY_NAME) ARCH ?= darwin GOLANGCI_LINT_VERSION ?= v1.23.8 GOLANGCI_LINT_CONCURRENCY ?= 4 GOLANGCI_LINT_DEADLINE ?= 180 +PLATFORMS ?= linux/arm/v7,linux/arm64/v8,linux/amd64 # useful for passing --build-arg http_proxy :) DOCKER_BUILD_FLAGS := @@ -60,7 +61,7 @@ coveralls: ./cover.sh goveralls -coverprofile=coverage.out -service=circle-ci -repotoken=$(COVERALLS_TOKEN) -junit-test: build +junit-test: go test -v ./... | go-junit-report > test-report.xml check: @@ -72,11 +73,12 @@ check-all: golangci-lint run --enable=gocyclo --concurrency=$(GOLANGCI_LINT_CONCURRENCY) --deadline=600s docker: - docker build -t $(IMAGE_NAME):$(GIT_HASH) . $(DOCKER_BUILD_FLAGS) + docker buildx create --name multiarch --use + docker buildx build --push --platform $(PLATFORMS) -t $(MANIFEST_NAME):$(GIT_HASH) . $(DOCKER_BUILD_FLAGS) -docker-dev: docker - docker tag $(IMAGE_NAME):$(GIT_HASH) $(IMAGE_NAME):dev - docker push $(IMAGE_NAME):dev +docker-dev: + docker tag $(MANIFEST_NAME):$(GIT_HASH) $(MANIFEST_NAME):dev + docker push $(MANIFEST_NAME):dev release: check test docker docker push $(IMAGE_NAME):$(GIT_HASH) @@ -87,20 +89,24 @@ ifeq (, $(findstring -rc, $(REPO_VERSION))) docker push $(IMAGE_NAME):latest endif -release-manifest: - for tag in latest $(REPO_VERSION); do \ - for arch in amd64 arm64; do \ - docker pull $(MANIFEST_NAME)-$$arch:$$tag; \ - done; \ - docker manifest create $(MANIFEST_NAME):$$tag --amend \ - $(MANIFEST_NAME)-amd64:$$tag \ - $(MANIFEST_NAME)-arm64:$$tag; \ - docker manifest push $(MANIFEST_NAME):$$tag; \ - done +release-ci: + docker tag $(MANIFEST_NAME):$(GIT_HASH) $(MANIFEST_NAME):$(REPO_VERSION) + docker push $(MANIFEST_NAME):$(REPO_VERSION) +ifeq (, $(findstring -rc, $(REPO_VERSION))) + docker tag $(MANIFEST_NAME):$(GIT_HASH) $(MANIFEST_NAME):latest + docker push $(MANIFEST_NAME):latest +endif version: @echo $(REPO_VERSION) +info-release: + @echo IMAGE_NAME=$(IMAGE_NAME) + @echo GIT_HASH=$(GIT_HASH) + @echo REPO_VERSION=$(REPO_VERSION) + @echo MANIFEST_NAME=$(MANIFEST_NAME) + @echo PLATFORMS=$(PLATFORMS) + clean: rm -rf build/bin/*