From 828230dbe33e1e9ee8a593115ebba232988ef161 Mon Sep 17 00:00:00 2001 From: Andy Stoneberg Date: Wed, 3 Sep 2025 16:23:38 -0400 Subject: [PATCH 1/5] ci: add publish workflow for controller This commit adds a GHA workflow to support publishing a container image for the `workspaces/controller` component as well as some updates to the `Makefile` to establish reasonable (but overridable) defaults. Key behavior: - Publishes controller images on any workspaces/ directory change - Builds images with commit SHA tags by default - "release" images with use the tag as defined by the `VERSION` file - a `-dirty` suffix is added to the tag if the codebase is not `porcelain` - no `latest` tag is ever produced on images - Uses `ghcr.io/kubeflow/notebooks` registry with configurable naming example image name from "random" commit: - `ghcr.io/kubeflow/notebooks/workspaces-controller:sha-3fa851ab3173942dbaa1a609468e7f9eadf5f4e4` example image name from release: - `ghcr.io/kubeflow/notebooks/workspaces-controller:v2.0.0` Signed-off-by: Andy Stoneberg --- .github/workflows/ws-controller-publish.yml | 56 +++++++++++++++++++++ workspaces/controller/Makefile | 9 +++- 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ws-controller-publish.yml diff --git a/.github/workflows/ws-controller-publish.yml b/.github/workflows/ws-controller-publish.yml new file mode 100644 index 000000000..cd43d6d4d --- /dev/null +++ b/.github/workflows/ws-controller-publish.yml @@ -0,0 +1,56 @@ +name: Build & Publish Controller container image +on: + push: + branches: + - main + - notebooks-v2 + - v*-branch + paths: + - workspaces/** ## NOTE: we publish changes on any commit to workspaces/ components + - releasing/version/VERSION + +env: + REGISTRY: ghcr.io/kubeflow/notebooks + NAME: workspaces-controller + +jobs: + push_to_registry: + name: Build & Push container image to GHCR + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: dorny/paths-filter@v3 + id: filter + with: + base: ${{ github.ref }} + filters: | + version: + - 'releasing/version/VERSION' + + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push multi-arch container image + run: | + cd workspaces/controller + make docker-buildx REGISTRY=${REGISTRY} NAME=${NAME} + + - name: Build and push multi-arch container image on Version change + id: version + if: steps.filter.outputs.version == 'true' + run: | + VERSION=$(cat releasing/version/VERSION) + cd workspaces/controller + make docker-buildx REGISTRY=${REGISTRY} NAME=${NAME} TAG=${VERSION} \ No newline at end of file diff --git a/workspaces/controller/Makefile b/workspaces/controller/Makefile index d14b1abe0..e33f3c6df 100644 --- a/workspaces/controller/Makefile +++ b/workspaces/controller/Makefile @@ -1,6 +1,11 @@ +GIT_COMMIT := $(shell git rev-parse HEAD) +GIT_TREE_STATE := $(shell test -n "`git status --porcelain`" && echo "-dirty" || echo "") + # Image URL to use all building/pushing image targets -TAG ?= $(shell git describe --tags --always --dirty) -IMG ?= ghcr.io/kubeflow/notebooks/workspaces-controller:$(TAG) +REGISTRY ?= ghcr.io/kubeflow/notebooks +NAME ?= workspaces-controller +TAG ?= sha-$(GIT_COMMIT)$(GIT_TREE_STATE) +IMG ?= $(REGISTRY)/$(NAME):$(TAG) # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. From 288d0cf1e23127b2627f2697e2deec350a0f10eb Mon Sep 17 00:00:00 2001 From: Mathew Wicks <5735406+thesuperzapper@users.noreply.github.com> Date: Thu, 25 Sep 2025 17:39:15 -0700 Subject: [PATCH 2/5] mathew: example rewrite 1 Signed-off-by: Mathew Wicks <5735406+thesuperzapper@users.noreply.github.com> --- .github/workflows/ws-backend-test.yml | 11 +++ .github/workflows/ws-build-image.yml | 95 +++++++++++++++++++ .github/workflows/ws-controller-publish.yml | 56 ----------- ...oller-test.yaml => ws-controller-test.yml} | 10 ++ .github/workflows/ws-frontend-test.yml | 11 ++- .github/workflows/ws-publish.yml | 69 ++++++++++++++ workspaces/backend/Makefile | 58 +++++------ workspaces/controller/Makefile | 43 +++------ workspaces/frontend/Makefile | 45 ++++----- 9 files changed, 253 insertions(+), 145 deletions(-) create mode 100644 .github/workflows/ws-build-image.yml delete mode 100644 .github/workflows/ws-controller-publish.yml rename .github/workflows/{ws-controller-test.yaml => ws-controller-test.yml} (88%) create mode 100644 .github/workflows/ws-publish.yml diff --git a/.github/workflows/ws-backend-test.yml b/.github/workflows/ws-backend-test.yml index 712dafb6d..2b1a38ae3 100644 --- a/.github/workflows/ws-backend-test.yml +++ b/.github/workflows/ws-backend-test.yml @@ -52,6 +52,17 @@ jobs: exit 1 fi + image-build: + needs: build + uses: ./.github/workflows/ws-build-image.yml + with: + image_name: workspaces-backend + build_file: ./workspaces/backend/Dockerfile + ## NOTE: we build the backend from the parent folder so it can COPY from controller + build_context: ./workspaces + build_platforms: linux/amd64,linux/ppc64le,linux/arm64/v8 + tag_with_sha: true + unit-tests: runs-on: ubuntu-latest needs: build diff --git a/.github/workflows/ws-build-image.yml b/.github/workflows/ws-build-image.yml new file mode 100644 index 000000000..cdbaf3fe8 --- /dev/null +++ b/.github/workflows/ws-build-image.yml @@ -0,0 +1,95 @@ +name: Build Image + +on: + workflow_call: + inputs: + image_name: + required: true + description: "the name of the image" + type: string + + tag_with_latest: + default: false + description: "if true, image tags will include 'latest'" + type: boolean + tag_with_semver: + default: false + description: "if true, image tags will include the version (from semver_raw, without 'v' prefix)" + type: boolean + tag_with_sha: + default: false + description: "if true, image tags will include the commit SHA (both short and long)" + type: boolean + + semver_raw: + default: "UNSET_SEMVER" + description: "the raw semver version (e.g., from VERSION file), used if tag_with_semver is true" + type: string + + build_file: + required: true + description: "path to Dockerfile" + type: string + build_context: + required: true + description: "path to build context folder" + type: string + build_platforms: + required: true + description: "list of target platforms for build, comma separated (e.g., linux/amd64,linux/arm64/v8)" + type: string + + push_to_registry: + default: false + description: "if true, push the built image to the registry" + type: boolean + +env: + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + +jobs: + build_image: + name: Build '${{ inputs.image_name }}' Image + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Install QEMU + uses: docker/setup-qemu-action@v3 + + - name: Install Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + if: ${{ inputs.push_to_registry }} + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate Image Metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.IMAGE_REGISTRY }}/${{ inputs.image_name }} + flavor: | + latest=${{ inputs.tag_with_latest }} + tags: | + type=semver,priority=1000,pattern={{version}},enable=${{ inputs.tag_with_semver }},value=${{ inputs.semver_raw }} + type=semver,priority=900,pattern={{major}}.{{minor}},enable=${{ inputs.tag_with_semver }},value=${{ inputs.semver_raw }} + type=sha,priority=200,prefix=sha-,format=short,enable=${{ inputs.tag_with_sha }} + type=sha,priority=100,prefix=sha-,format=long,enable=${{ inputs.tag_with_sha }} + + - name: Build and Push Image + uses: docker/build-push-action@v6 + with: + annotations: ${{ steps.meta.outputs.annotations }} + context: ${{ inputs.build_context }} + file: ${{ inputs.build_file }} + labels: ${{ steps.meta.outputs.labels }} + platforms: ${{ inputs.build_platforms }} + push: ${{ inputs.push_to_registry }} + tags: ${{ steps.meta.outputs.tags }} \ No newline at end of file diff --git a/.github/workflows/ws-controller-publish.yml b/.github/workflows/ws-controller-publish.yml deleted file mode 100644 index cd43d6d4d..000000000 --- a/.github/workflows/ws-controller-publish.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Build & Publish Controller container image -on: - push: - branches: - - main - - notebooks-v2 - - v*-branch - paths: - - workspaces/** ## NOTE: we publish changes on any commit to workspaces/ components - - releasing/version/VERSION - -env: - REGISTRY: ghcr.io/kubeflow/notebooks - NAME: workspaces-controller - -jobs: - push_to_registry: - name: Build & Push container image to GHCR - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - uses: dorny/paths-filter@v3 - id: filter - with: - base: ${{ github.ref }} - filters: | - version: - - 'releasing/version/VERSION' - - - name: Login to GHCR - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build and push multi-arch container image - run: | - cd workspaces/controller - make docker-buildx REGISTRY=${REGISTRY} NAME=${NAME} - - - name: Build and push multi-arch container image on Version change - id: version - if: steps.filter.outputs.version == 'true' - run: | - VERSION=$(cat releasing/version/VERSION) - cd workspaces/controller - make docker-buildx REGISTRY=${REGISTRY} NAME=${NAME} TAG=${VERSION} \ No newline at end of file diff --git a/.github/workflows/ws-controller-test.yaml b/.github/workflows/ws-controller-test.yml similarity index 88% rename from .github/workflows/ws-controller-test.yaml rename to .github/workflows/ws-controller-test.yml index 009642e46..8d6c87bff 100644 --- a/.github/workflows/ws-controller-test.yaml +++ b/.github/workflows/ws-controller-test.yml @@ -52,6 +52,16 @@ jobs: exit 1 fi + image-build: + needs: build + uses: ./.github/workflows/ws-build-image.yml + with: + image_name: workspaces-controller + build_file: ./workspaces/controller/Dockerfile + build_context: ./workspaces/controller + build_platforms: linux/amd64,linux/ppc64le,linux/arm64/v8 + tag_with_sha: true + unit-tests: runs-on: ubuntu-latest needs: build diff --git a/.github/workflows/ws-frontend-test.yml b/.github/workflows/ws-frontend-test.yml index e34b7cfb3..f99e35878 100644 --- a/.github/workflows/ws-frontend-test.yml +++ b/.github/workflows/ws-frontend-test.yml @@ -86,4 +86,13 @@ jobs: echo "Uncommitted file changes detected: $clean" git diff exit 1 - fi \ No newline at end of file + fi + + image-build: + uses: ./.github/workflows/ws-build-image.yml + with: + image_name: workspaces-frontend + build_file: ./workspaces/frontend/Dockerfile + build_context: ./workspaces/frontend + build_platforms: linux/amd64,linux/ppc64le,linux/arm64/v8 + tag_with_sha: true \ No newline at end of file diff --git a/.github/workflows/ws-publish.yml b/.github/workflows/ws-publish.yml new file mode 100644 index 000000000..2f6bf5c3a --- /dev/null +++ b/.github/workflows/ws-publish.yml @@ -0,0 +1,69 @@ +name: Publish + +permissions: + contents: read + packages: write + +on: + push: + branches: + - main + - notebooks-v2 + - v*-branch + paths: + - releasing/version/VERSION + ## NOTE: we publish container images on any commit to all components, so the tags are consistent across components + - workspaces/** + +jobs: + check_version: + runs-on: ubuntu-latest + outputs: + version_changed: ${{ steps.filter.outputs.version }} + version_raw: ${{ steps.get_version.outputs.version }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: dorny/paths-filter@v3 + id: filter + with: + base: ${{ github.ref }} + filters: | + version: + - 'releasing/version/VERSION' + + - name: Get Version + id: get_version + run: echo "version=$(cat releasing/version/VERSION)" >> $GITHUB_OUTPUT + + images: + uses: ./.github/workflows/ws-build-image.yml + needs: check_version + secrets: inherit + strategy: + fail-fast: false + matrix: + include: + - image_name: workspaces-backend + build_file: ./workspaces/backend/Dockerfile + ## NOTE: we build the backend from the parent folder so it can COPY from controller + build_context: ./workspaces + + - image_name: workspaces-controller + build_file: ./workspaces/controller/Dockerfile + build_context: ./workspaces/controller + + - image_name: workspaces-frontend + build_file: ./workspaces/frontend/Dockerfile + build_context: ./workspaces/frontend + with: + image_name: ${{ matrix.image_name }} + tag_with_latest: false # we don't use 'latest' tags for workspace images + tag_with_semver: ${{ needs.check_version.version_changed == 'true' }} + tag_with_sha: true + semver_raw: ${{ needs.version.version_raw }} + build_file: ${{ matrix.build_file }} + build_context: ${{ matrix.build_context }} + build_platforms: linux/amd64,linux/ppc64le,linux/arm64/v8 + push_to_registry: true \ No newline at end of file diff --git a/workspaces/backend/Makefile b/workspaces/backend/Makefile index 838996ed9..b3ff69a13 100644 --- a/workspaces/backend/Makefile +++ b/workspaces/backend/Makefile @@ -1,7 +1,13 @@ +GIT_COMMIT := $(shell git rev-parse HEAD) +GIT_TREE_STATE := $(shell test -n "`git status --porcelain`" && echo "-dirty" || echo "") + # Image URL to use all building/pushing image targets -IMG ?= nb-backend:latest -# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.31.0 +REGISTRY ?= ghcr.io/kubeflow/notebooks +NAME ?= workspaces-backend +TAG ?= sha-$(GIT_COMMIT)$(GIT_TREE_STATE) +IMG ?= $(REGISTRY)/$(NAME):$(TAG) +ARCH ?= linux/arm64/v8,linux/amd64,linux/ppc64le + # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) @@ -13,12 +19,6 @@ endif # Backend default port PORT ?= 4000 -# CONTAINER_TOOL defines the container tool to be used for building images. -# Be aware that the target commands are only tested with Docker which is -# scaffolded by default. However, you might want to replace it to use other -# tools. (i.e. podman) -CONTAINER_TOOL ?= docker - # Setting SHELL to bash allows bash commands to be executed by recipes. # Options are set to exit when a recipe line exits non-zero or a piped command fails. SHELL = /usr/bin/env bash -o pipefail @@ -86,34 +86,24 @@ build: fmt vet swag ## Build backend binary. run: fmt vet swag ## Run a backend from your host. go run ./cmd/main.go --port=$(PORT) -# If you wish to build the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ .PHONY: docker-build -docker-build: ## Build docker image with the backend. - $(CONTAINER_TOOL) build -f Dockerfile -t $(IMG) .. - +docker-build: + # NOTE: we are building in the context of the parent directory (..) + docker build --tag ${IMG} --file Dockerfile .. .PHONY: docker-push -docker-push: ## Push docker image with the backend. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ -# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) -# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64/v8,linux/amd64,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed '1,// s/^FROM/FROM --platform=$${BUILDPLATFORM}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name project-v3-builder - $(CONTAINER_TOOL) buildx use project-v3-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross .. - - $(CONTAINER_TOOL) buildx rm project-v3-builder - rm Dockerfile.cross +docker-push: + docker push ${IMG} + +.PHONY: docker-build-multi-arch +docker-build-multi-arch: + # NOTE: we are building in the context of the parent directory (..) + docker buildx build --platform ${ARCH} --tag ${IMG} --file Dockerfile .. + +.PHONY: docker-build-push-multi-arch +docker-build-push-multi-arch: + # NOTE: we are building in the context of the parent directory (..) + docker buildx build --platform ${ARCH} --tag ${IMG} --file Dockerfile --push .. ##@ Dependencies diff --git a/workspaces/controller/Makefile b/workspaces/controller/Makefile index e33f3c6df..47985aedc 100644 --- a/workspaces/controller/Makefile +++ b/workspaces/controller/Makefile @@ -6,6 +6,7 @@ REGISTRY ?= ghcr.io/kubeflow/notebooks NAME ?= workspaces-controller TAG ?= sha-$(GIT_COMMIT)$(GIT_TREE_STATE) IMG ?= $(REGISTRY)/$(NAME):$(TAG) +ARCH ?= linux/arm64/v8,linux/amd64,linux/ppc64le # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. @@ -18,12 +19,6 @@ else GOBIN=$(shell go env GOBIN) endif -# CONTAINER_TOOL defines the container tool to be used for building images. -# Be aware that the target commands are only tested with Docker which is -# scaffolded by default. However, you might want to replace it to use other -# tools. (i.e. podman) -CONTAINER_TOOL ?= docker - # Setting SHELL to bash allows bash commands to be executed by recipes. # Options are set to exit when a recipe line exits non-zero or a piped command fails. SHELL = /usr/bin/env bash -o pipefail @@ -105,33 +100,21 @@ build: manifests generate fmt vet ## Build manager binary. run: manifests generate fmt vet ## Run a controller from your host. go run ./cmd/main.go -# If you wish to build the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ .PHONY: docker-build -docker-build: ## Build docker image with the manager. - $(CONTAINER_TOOL) build -t ${IMG} . +docker-build: + docker build --tag ${IMG} . .PHONY: docker-push -docker-push: ## Push docker image with the manager. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ -# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) -# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64/v8,linux/amd64,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name project-v3-builder - $(CONTAINER_TOOL) buildx use project-v3-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm project-v3-builder - rm Dockerfile.cross +docker-push: + docker push ${IMG} + +.PHONY: docker-build-multi-arch +docker-build-multi-arch: + docker buildx build --platform ${ARCH} --tag ${IMG} . + +.PHONY: docker-build-push-multi-arch +docker-build-push-multi-arch: + docker buildx build --platform ${ARCH} --tag ${IMG} --push . .PHONY: build-installer build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment. diff --git a/workspaces/frontend/Makefile b/workspaces/frontend/Makefile index cc5ef28de..ceab7d752 100755 --- a/workspaces/frontend/Makefile +++ b/workspaces/frontend/Makefile @@ -1,9 +1,13 @@ -# Image URL to use for building/pushing the frontend image -IMG ?= nbv2-frontend:latest +GIT_COMMIT := $(shell git rev-parse HEAD) +GIT_TREE_STATE := $(shell test -n "`git status --porcelain`" && echo "-dirty" || echo "") + +# Image URL to use all building/pushing image targets +REGISTRY ?= ghcr.io/kubeflow/notebooks +NAME ?= workspaces-frontend +TAG ?= sha-$(GIT_COMMIT)$(GIT_TREE_STATE) +IMG ?= $(REGISTRY)/$(NAME):$(TAG) +ARCH ?= linux/arm64/v8,linux/amd64,linux/ppc64le -# CONTAINER_TOOL defines the container tool to be used for building images. -# Tested with Docker by default. You may replace with podman. -CONTAINER_TOOL ?= docker # Setting SHELL to bash allows bash commands to be executed by recipes. # Options are set to exit when a recipe line exits non-zero or a piped command fails. @@ -28,28 +32,21 @@ clean: ## Remove local test/build artifacts. ##@ Build -# If you wish to build the image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). Requires Docker BuildKit. .PHONY: docker-build -docker-build: ## Build docker image for the frontend. - $(CONTAINER_TOOL) build -t ${IMG} . +docker-build: + docker build --tag ${IMG} . .PHONY: docker-push -docker-push: ## Push docker image for the frontend. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for cross-platform support. -PLATFORMS ?= linux/arm64/v8,linux/amd64,linux/ppc64le - -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for cross-platform support. - # copy existing Dockerfile and insert --platform=$${BUILDPLATFORM} into Dockerfile.cross, preserving the original - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name project-v3-builder - $(CONTAINER_TOOL) buildx use project-v3-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm project-v3-builder - rm Dockerfile.cross +docker-push: + docker push ${IMG} + +.PHONY: docker-build-multi-arch +docker-build-multi-arch: + docker buildx build --platform ${ARCH} --tag ${IMG} . + +.PHONY: docker-build-push-multi-arch +docker-build-push-multi-arch: + docker buildx build --platform ${ARCH} --tag ${IMG} --push . ##@ Deployment From 225b47d6449695101f0a5b964223f9920ca9cb14 Mon Sep 17 00:00:00 2001 From: Andy Stoneberg Date: Tue, 30 Sep 2025 15:44:47 -0400 Subject: [PATCH 3/5] fix registry path to include owner and repo name Signed-off-by: Andy Stoneberg --- .github/workflows/ws-build-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ws-build-image.yml b/.github/workflows/ws-build-image.yml index cdbaf3fe8..c4e13c4ca 100644 --- a/.github/workflows/ws-build-image.yml +++ b/.github/workflows/ws-build-image.yml @@ -45,7 +45,7 @@ on: type: boolean env: - IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_REGISTRY: ghcr.io/${{ github.repository }} jobs: build_image: From 3e2c437b2aaaad18d0142a67d92f8388454a5f94 Mon Sep 17 00:00:00 2001 From: Andy Stoneberg Date: Wed, 1 Oct 2025 09:38:52 -0400 Subject: [PATCH 4/5] ci: fix ws-publish.yml with.semver_raw has an incorrect reference to version_raw output that results in an empty string always being passed - which prevented semver tags from ever being produced (even when they should be) Signed-off-by: Andy Stoneberg --- .github/workflows/ws-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ws-publish.yml b/.github/workflows/ws-publish.yml index 2f6bf5c3a..d06aff7a4 100644 --- a/.github/workflows/ws-publish.yml +++ b/.github/workflows/ws-publish.yml @@ -62,7 +62,7 @@ jobs: tag_with_latest: false # we don't use 'latest' tags for workspace images tag_with_semver: ${{ needs.check_version.version_changed == 'true' }} tag_with_sha: true - semver_raw: ${{ needs.version.version_raw }} + semver_raw: ${{ needs.check_version.version_raw }} build_file: ${{ matrix.build_file }} build_context: ${{ matrix.build_context }} build_platforms: linux/amd64,linux/ppc64le,linux/arm64/v8 From 284cc8f715a63601426ee34ba78fc5e434fc1fb4 Mon Sep 17 00:00:00 2001 From: Andy Stoneberg Date: Wed, 1 Oct 2025 11:27:29 -0400 Subject: [PATCH 5/5] fix: semver with references needs.check_version stores all its 'interesting data' under the 'outputs' attribute. This was not properly reflected in the 'with' block for images job. Signed-off-by: Andy Stoneberg --- .github/workflows/ws-publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ws-publish.yml b/.github/workflows/ws-publish.yml index d06aff7a4..ab157e2d3 100644 --- a/.github/workflows/ws-publish.yml +++ b/.github/workflows/ws-publish.yml @@ -60,9 +60,9 @@ jobs: with: image_name: ${{ matrix.image_name }} tag_with_latest: false # we don't use 'latest' tags for workspace images - tag_with_semver: ${{ needs.check_version.version_changed == 'true' }} + tag_with_semver: ${{ needs.check_version.outputs.version_changed == 'true' }} tag_with_sha: true - semver_raw: ${{ needs.check_version.version_raw }} + semver_raw: ${{ needs.check_version.outputs.version_raw }} build_file: ${{ matrix.build_file }} build_context: ${{ matrix.build_context }} build_platforms: linux/amd64,linux/ppc64le,linux/arm64/v8