diff --git a/.github/workflows/image-push.yml b/.github/workflows/image-push.yml index b74b62f..30cffe5 100644 --- a/.github/workflows/image-push.yml +++ b/.github/workflows/image-push.yml @@ -12,6 +12,8 @@ jobs: contents: read id-token: write runs-on: runs-on,runner=4cpu-linux-x64,run-id=${{ github.run_id }} + outputs: + digest: ${{ steps.digest.outputs.digest }} steps: - name: Check out code uses: actions/checkout@v4 @@ -22,9 +24,6 @@ jobs: echo "$(make -s log | grep TAG)" >> "$GITHUB_ENV" echo "$(make -s log | grep ARCH)" >> "$GITHUB_ENV" - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Docker meta id: meta-amd64 uses: docker/metadata-action@v5 @@ -36,49 +35,42 @@ jobs: with: secrets: | secret/data/github/repo/${{ github.repository }}/dockerhub/${{ github.repository_owner }}/credentials username | DOCKER_USERNAME ; - secret/data/github/repo/${{ github.repository }}/dockerhub/${{ github.repository_owner }}/credentials password | DOCKER_PASSWORD - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Container Registry - uses: docker/login-action@v3 - with: - username: ${{ env.DOCKER_USERNAME }} - password: ${{ env.DOCKER_PASSWORD }} + secret/data/github/repo/${{ github.repository }}/dockerhub/${{ github.repository_owner }}/credentials password | DOCKER_PASSWORD ; + secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials registry | PRIME_REGISTRY ; + secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials username | PRIME_REGISTRY_USERNAME ; + secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials password | PRIME_REGISTRY_PASSWORD - - name: Build container image + - name: Build and push container image id: build-amd64 - uses: docker/build-push-action@v6 + uses: rancher/ecm-distro-tools/actions/publish-image@master + env: + META_LABELS: ${{ steps.meta-amd64.outputs.labels }} with: - context: . - file: Dockerfile - platforms: linux/amd64 - labels: ${{ steps.meta-amd64.outputs.labels }} - outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true - build-args: | - TAG=${{ env.TAG }} - ARCH=${{ env.ARCH }} - - - name: Export digest - run: | - mkdir -p /tmp/digests - digest="${{ steps.build-amd64.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}" + image: hardened-calico + tag: ${{ github.event.release.tag_name }} - - name: Upload digest - uses: actions/upload-artifact@v4 - with: - name: digests-linux-amd64 - path: /tmp/digests/* - if-no-files-found: error - retention-days: 1 + public-repo: rancher + public-username: ${{ env.DOCKER_USERNAME }} + public-password: ${{ env.DOCKER_PASSWORD }} + + prime-repo: rancher + prime-registry: ${{ env.PRIME_REGISTRY }} + prime-username: ${{ env.PRIME_REGISTRY_USERNAME }} + prime-password: ${{ env.PRIME_REGISTRY_PASSWORD }} + + - name: Digest + id: digest + run: | + IMAGE_DIGEST=$(jq -r '.["containerimage.digest"]' /tmp/metadata.json) + echo "digest=$IMAGE_DIGEST" >> "$GITHUB_OUTPUT" build-arm64-digest: permissions: contents: read id-token: write runs-on: runs-on,runner=4cpu-linux-arm64,run-id=${{ github.run_id }} + outputs: + digest: ${{ steps.digest.outputs.digest }} steps: - name: Check out code uses: actions/checkout@v4 @@ -89,9 +81,6 @@ jobs: echo "$(make -s log | grep TAG)" >> "$GITHUB_ENV" echo "$(make -s log | grep ARCH)" >> "$GITHUB_ENV" - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Docker meta id: meta-arm64 uses: docker/metadata-action@v5 @@ -103,43 +92,35 @@ jobs: with: secrets: | secret/data/github/repo/${{ github.repository }}/dockerhub/${{ github.repository_owner }}/credentials username | DOCKER_USERNAME ; - secret/data/github/repo/${{ github.repository }}/dockerhub/${{ github.repository_owner }}/credentials password | DOCKER_PASSWORD - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + secret/data/github/repo/${{ github.repository }}/dockerhub/${{ github.repository_owner }}/credentials password | DOCKER_PASSWORD ; + secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials registry | PRIME_REGISTRY ; + secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials username | PRIME_REGISTRY_USERNAME ; + secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials password | PRIME_REGISTRY_PASSWORD - - name: Login to Container Registry - uses: docker/login-action@v3 - with: - username: ${{ env.DOCKER_USERNAME }} - password: ${{ env.DOCKER_PASSWORD }} - - - name: Build container image + - name: Build and push container image id: build-arm64 - uses: docker/build-push-action@v6 + uses: rancher/ecm-distro-tools/actions/publish-image@master + env: + META_LABELS: ${{ steps.meta-arm64.outputs.labels }} with: - context: . - file: Dockerfile - platforms: linux/arm64 - labels: ${{ steps.meta-arm64.outputs.labels }} - outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true - build-args: | - TAG=${{ env.TAG }} - ARCH=${{ env.ARCH }} - - - name: Export digest + image: hardened-calico + tag: ${{ github.event.release.tag_name }} + + public-repo: rancher + public-username: ${{ env.DOCKER_USERNAME }} + public-password: ${{ env.DOCKER_PASSWORD }} + + prime-repo: rancher + prime-registry: ${{ env.PRIME_REGISTRY }} + prime-username: ${{ env.PRIME_REGISTRY_USERNAME }} + prime-password: ${{ env.PRIME_REGISTRY_PASSWORD }} + + - name: Digest + id: digest run: | - mkdir -p /tmp/digests - digest="${{ steps.build-arm64.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}" + IMAGE_DIGEST=$(jq -r '.["containerimage.digest"]' /tmp/metadata.json) + echo "digest=$IMAGE_DIGEST" >> "$GITHUB_OUTPUT" - - name: Upload digest - uses: actions/upload-artifact@v4 - with: - name: digests-linux-arm64 - path: /tmp/digests/* - if-no-files-found: error - retention-days: 1 merge: permissions: contents: read @@ -149,16 +130,6 @@ jobs: - build-amd64-digest - build-arm64-digest steps: - - name: Download digests - uses: actions/download-artifact@v4 - with: - path: /tmp/digests - pattern: digests-* - merge-multiple: true - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -170,20 +141,32 @@ jobs: with: secrets: | secret/data/github/repo/${{ github.repository }}/dockerhub/${{ github.repository_owner }}/credentials username | DOCKER_USERNAME ; - secret/data/github/repo/${{ github.repository }}/dockerhub/${{ github.repository_owner }}/credentials password | DOCKER_PASSWORD - - - name: Login to Container Registry - uses: docker/login-action@v3 - with: - username: ${{ env.DOCKER_USERNAME }} - password: ${{ env.DOCKER_PASSWORD }} + secret/data/github/repo/${{ github.repository }}/dockerhub/${{ github.repository_owner }}/credentials password | DOCKER_PASSWORD ; + secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials registry | PRIME_REGISTRY ; + secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials username | PRIME_REGISTRY_USERNAME ; + secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials password | PRIME_REGISTRY_PASSWORD - name: Create manifest list and push - working-directory: /tmp/digests - run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) - + id: push-manifest + uses: rancher/ecm-distro-tools/actions/publish-image@master + env: + DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta.outputs.json }} + REGISTRY_IMAGE: ${{ env.REGISTRY_IMAGE }} + IMAGE_DIGESTS: ${{ needs.build-amd64-digest.outputs.digest }} ${{ needs.build-arm64-digest.outputs.digest }} + with: + make-target: manifest-push + image: hardened-calico + tag: ${{ github.event.release.tag_name }} + + public-repo: rancher + public-username: ${{ env.DOCKER_USERNAME }} + public-password: ${{ env.DOCKER_PASSWORD }} + + prime-repo: rancher + prime-registry: ${{ env.PRIME_REGISTRY }} + prime-username: ${{ env.PRIME_REGISTRY_USERNAME }} + prime-password: ${{ env.PRIME_REGISTRY_PASSWORD }} + - name: Inspect image run: | docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} diff --git a/Makefile b/Makefile index 60a9366..b2abbe9 100644 --- a/Makefile +++ b/Makefile @@ -10,9 +10,21 @@ else ARCH=$(UNAME_M) endif +ifndef TARGET_PLATFORMS + ifeq ($(UNAME_M), x86_64) + TARGET_PLATFORMS:=linux/amd64 + else ifeq ($(UNAME_M), aarch64) + TARGET_PLATFORMS:=linux/arm64 + else + TARGET_PLATFORMS:=linux/$(UNAME_M) + endif +endif + BUILD_META=-build$(shell date +%Y%m%d) ORG ?= rancher +MACHINE := rancher TAG ?= ${GITHUB_ACTION_TAG} +REGISTRY_IMAGE ?= $(ORG)/hardened-calico K3S_ROOT_VERSION ?= v0.14.0 @@ -20,10 +32,18 @@ ifeq ($(TAG),) TAG := v3.28.1$(BUILD_META) endif +IMAGE ?= $(REGISTRY_IMAGE):$(TAG) + +LABEL_ARGS = $(foreach label,$(META_LABELS),--label $(label)) + ifeq (,$(filter %$(BUILD_META),$(TAG))) $(error TAG $(TAG) needs to end with build metadata: $(BUILD_META)) endif +buildx-machine: + @docker buildx ls | grep $(MACHINE) || \ + docker buildx create --name=$(MACHINE) --platform=linux/arm64,linux/amd64 + .PHONY: image-build image-build: docker buildx build --no-cache \ @@ -31,11 +51,31 @@ image-build: --pull \ --build-arg TAG=$(TAG:$(BUILD_META)=) \ --build-arg K3S_ROOT_VERSION=$(K3S_ROOT_VERSION) \ - --tag $(ORG)/hardened-calico:$(TAG) \ - --tag $(ORG)/hardened-calico:$(TAG)-$(ARCH) \ + --tag $(IMAGE) \ + --tag $(IMAGE)-$(ARCH) \ --load \ . +.PHONY: push-image +push-image: buildx-machine + docker buildx build \ + --builder=$(MACHINE) \ + --sbom=true \ + --attest type=provenance,mode=max \ + --platform=$(TARGET_PLATFORMS) \ + --build-arg TAG=$(TAG:$(BUILD_META)=) \ + --build-arg K3S_ROOT_VERSION=$(K3S_ROOT_VERSION) \ + --output type=image,name=$(REGISTRY_IMAGE),push-by-digest=true,name-canonical=true,push=true \ + $(LABEL_ARGS) \ + --push \ + --iidfile /tmp/image.digest \ + --metadata-file /tmp/metadata.json \ + . + +.PHONY: manifest-push +manifest-push: + docker buildx imagetools create -t $(IMAGE) -t $(REGISTRY_IMAGE):latest $(IMAGE_DIGESTS) + .PHONY: image-push image-push: docker push $(ORG)/hardened-calico:$(TAG)-$(ARCH) @@ -53,3 +93,5 @@ log: @echo "SRC=$(SRC)" @echo "BUILD_META=$(BUILD_META)" @echo "UNAME_M=$(UNAME_M)" + @echo "META_LABELS=$(META_LABELS)" + @echo "LABEL_ARGS=$(LABEL_ARGS)"