Repository: rook/rook
Pull request #15742: build: Stop publishing release artifacts for non-released builds
Author: login: travisn
Labels: name: backport-release-1.17
Created: 2025-04-16T23:23:39Z | Merged: 2025-04-21T19:26:41Z

Tentative changes as proposed in #15638...
- The helm charts will now only be published when it is an officially tagged release build.
- The images will only be published to all repos for dockerhub, quay, and ghcr when it is a tagged release.
- The images will be published only to dockerhub for all master and interim release branch builds.
- Remove obsolete option to choose which images to build. Ceph is the only one.
- Remove obsolete option to clean the release builds, no need for this with github actions.
- Also included are other small improvements to clean up the release scripts.

<!-- Thank you for contributing to Rook! -->

<!-- STEPS TO FOLLOW:
  1. Add a description of the changes (frequently the same as the commit description)
  2. Enter the issue number next to "Resolves #" below (if there is no tracking issue resolved, **remove that section**)
  3. Review our Contributing documentation at https://rook.io/docs/rook/latest/Contributing/development-flow/
  4. Follow the steps in the checklist below, starting with the **Commit Message Formatting**.
-->

**Issue resolved by this Pull Request:**
Resolves #15638

**Checklist:**

- [ ] **Commit Message Formatting**: Commit titles and messages follow guidelines in the [developer guide](https://rook.io/docs/rook/latest/Contributing/development-flow/#commit-structure).
- [ ] Reviewed the developer guide on [Submitting a Pull Request](https://rook.io/docs/rook/latest/Contributing/development-flow/#submitting-a-pull-request)
- [ ] [Pending release notes](https://github.com/rook/rook/blob/master/PendingReleaseNotes.md) updated with breaking and/or notable changes for the next minor release.
- [ ] Documentation has been updated, if necessary.
- [ ] Unit tests have been added, if necessary.
- [ ] Integration tests have been added, if necessary.


Linked issue #15638: Stop publishing Rook builds from master
<!-- **Are you in the right place?**
1. For issues or feature requests, please create an issue in this repository.
2. For general technical and non-technical questions, we are happy to help you on our [Rook.io Slack](https://slack.rook.io/).
3. Did you already search the existing open issues for anything similar? -->

**Is this a bug report or feature request?**
* Bug Report

**Deviation from expected behavior:**
The Rook builds, including images and helm charts, are currently published from the master and release branch builds, to dockerhub, quay, and ghcr. Really, the only builds we should be publishing officially are the tagged builds from the master branch. It can be confusing the users who want to install the latest release build, and we do not want to make it easy for them to install an intermittent build.

**Expected behavior:**
Users should have easy access to the released builds, but not the intermittent master or release branch builds. Let's consider the following changes:
- Master builds: 
   - Only publish images as before (before #15274) to dockerhub, but not to quay or gchr.
   - Don't push helm charts to any OCI repo
- Release builds: 
   - For intermittent builds (not tagged), only push images to dockerhub, but not quay or ghcr.
   - For intermittent builds, don't push helm charts to any OCI repo.

**How to reproduce it (minimal and precise):**
<!-- Please let us know any circumstances for reproduction of your bug. -->
For example, see:
- [GHCR images](https://github.com/rook/rook/pkgs/container/ceph)
- [GHCR helm chart](https://github.com/rook/rook/pkgs/container/rook-ceph)
- [Quay images](https://quay.io/repository/rook/ceph?tab=tags)
- [Quay helm chart](https://quay.io/repository/rook/rook-ceph?tab=tags)
- [Dockerhub images](https://hub.docker.com/r/rook/ceph/tags/)
- [Dockerhub chart](https://hub.docker.com/r/rook/rook-ceph/tags)

Linked issue comments: user: login: jhoblitt
created_at: 2025-04-02T23:44:14Z
body: I think having the master helm charts available is useful for test deployments.  Is there some way we could preserve them as a nightly/etc.?
author_association: MEMBER
user: login: subhamkrai
created_at: 2025-04-03T06:08:08Z
body: @travisn is this new behavior with my change or old behaviour?
author_association: CONTRIBUTOR
user: login: travisn
created_at: 2025-04-03T14:17:02Z
body: > [@travisn](https://github.com/travisn) is this new behavior with my change or old behaviour?

It's not related directly to your change in #15274, but after that and also #15542, I've been thinking about really where we want to publish builds. It feels too aggressive to publish all these builds, since users might deploy them accidentally. If the non-released builds are too prominent, it just seems like it can cause problems. So I want to review and consider what is best. Before making these changes, let's discuss in depth though to make sure we have an approach that makes the most sense.

> I think having the master helm charts available is useful for test deployments. Is there some way we could preserve them as a nightly/etc.?

You are the first I've heard of using the helm charts for testing in master, but surely there are others. In the [helm docs](https://rook.io/docs/rook/latest-release/Helm-Charts/operator-chart/#release) we only have documented the release charts, so I wasn't sure if the master charts were discoverable. With the charts now published to multiple OCI registries, it's given me pause about whether they are needed. 

We do have the ability to [build a local helm chart](https://rook.io/docs/rook/latest-release/Helm-Charts/operator-chart/#development-build) for testing. Would that be sufficient? Then you can build a test chart whenever needed. 
author_association: MEMBER
user: login: travisn
created_at: 2025-04-16T22:04:37Z
body: > > I think having the master helm charts available is useful for test deployments. Is there some way we could preserve them as a nightly/etc.?
> 
> You are the first I've heard of using the helm charts for testing in master, but surely there are others. In the [helm docs](https://rook.io/docs/rook/latest-release/Helm-Charts/operator-chart/#release) we only have documented the release charts, so I wasn't sure if the master charts were discoverable. With the charts now published to multiple OCI registries, it's given me pause about whether they are needed.
> 
> We do have the ability to [build a local helm chart](https://rook.io/docs/rook/latest-release/Helm-Charts/operator-chart/#development-build) for testing. Would that be sufficient? Then you can build a test chart whenever needed.

@jhoblitt Any more thoughts on this? Publishing the master charts still seems off to me.
author_association: MEMBER
user: login: jhoblitt
created_at: 2025-04-17T00:12:21Z
body: > [@jhoblitt](https://github.com/jhoblitt) Any more thoughts on this? Publishing the master charts still seems off to me.

I do build the charts locally and them publish them into a helm repo for rolling out forked builds to my production env.   Having charts available tied to a specific CI build would be useful for gitops driven testing on dev clusters but I won't nack removal of these builds.
author_association: MEMBER

Diff:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index bddc9b255905..820398c0d94f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -36,7 +36,7 @@ jobs:
 
       - name: build rook
         run: |
-          GOPATH=$(go env GOPATH) make clean && make -j$nproc IMAGES='ceph' BUILD_CONTAINER_IMAGE=false build
+          GOPATH=$(go env GOPATH) make clean && make -j$nproc BUILD_CONTAINER_IMAGE=false build
 
       - name: validate build
         run: tests/scripts/validate_modified_files.sh build
diff --git a/Documentation/Helm-Charts/ceph-cluster-chart.gotmpl.md b/Documentation/Helm-Charts/ceph-cluster-chart.gotmpl.md
index fe7e2e7e8f76..3c0a1d20e13a 100644
--- a/Documentation/Helm-Charts/ceph-cluster-chart.gotmpl.md
+++ b/Documentation/Helm-Charts/ceph-cluster-chart.gotmpl.md
@@ -13,7 +13,6 @@ This chart is a simple packaging of templates that will optionally create Rook r
 
 ## Prerequisites
 
-* Kubernetes 1.22+
 * Helm 3.x
 * Install the [Rook Operator chart](operator-chart.md)
 
@@ -24,8 +23,6 @@ The [configuration](#configuration) section lists the parameters that can be con
 recommended that the rook operator be installed into the `rook-ceph` namespace. The clusters can be installed
 into the same namespace as the operator or a separate namespace.
 
-Rook currently publishes builds of this chart to the `release` and `master` channels.
-
 **Before installing, review the values.yaml to confirm if the default settings need to be updated.**
 
 * If the operator was installed in a namespace other than `rook-ceph`, the namespace
@@ -38,7 +35,7 @@ Rook currently publishes builds of this chart to the `release` and `master` chan
 
 ### **Release**
 
-The release channel is the most recent release of Rook that is considered stable for the community.
+The `release` channel is the most recent release of Rook that is considered stable for the community.
 
 The example install assumes you have first installed the [Rook Operator Helm Chart](operator-chart.md)
 and created your customized values.yaml.
diff --git a/Documentation/Helm-Charts/ceph-cluster-chart.md b/Documentation/Helm-Charts/ceph-cluster-chart.md
index d8fd88f91c34..cf49dbdee831 100644
--- a/Documentation/Helm-Charts/ceph-cluster-chart.md
+++ b/Documentation/Helm-Charts/ceph-cluster-chart.md
@@ -16,7 +16,6 @@ This chart is a simple packaging of templates that will optionally create Rook r
 
 ## Prerequisites
 
-* Kubernetes 1.22+
 * Helm 3.x
 * Install the [Rook Operator chart](operator-chart.md)
 
@@ -27,8 +26,6 @@ The [configuration](#configuration) section lists the parameters that can be con
 recommended that the rook operator be installed into the `rook-ceph` namespace. The clusters can be installed
 into the same namespace as the operator or a separate namespace.
 
-Rook currently publishes builds of this chart to the `release` and `master` channels.
-
 **Before installing, review the values.yaml to confirm if the default settings need to be updated.**
 
 * If the operator was installed in a namespace other than `rook-ceph`, the namespace
@@ -41,7 +38,7 @@ Rook currently publishes builds of this chart to the `release` and `master` chan
 
 ### **Release**
 
-The release channel is the most recent release of Rook that is considered stable for the community.
+The `release` channel is the most recent release of Rook that is considered stable for the community.
 
 The example install assumes you have first installed the [Rook Operator Helm Chart](operator-chart.md)
 and created your customized values.yaml.
diff --git a/Documentation/Helm-Charts/operator-chart.gotmpl.md b/Documentation/Helm-Charts/operator-chart.gotmpl.md
index 3a045f4094d2..a8f4a8943571 100644
--- a/Documentation/Helm-Charts/operator-chart.gotmpl.md
+++ b/Documentation/Helm-Charts/operator-chart.gotmpl.md
@@ -11,7 +11,6 @@ This chart bootstraps a [rook-ceph-operator](https://github.com/rook/rook) deplo
 
 ## Prerequisites
 
-* Kubernetes 1.22+
 * Helm 3.x
 
 See the [Helm support matrix](https://helm.sh/docs/topics/version_skew/) for more details.
@@ -25,11 +24,9 @@ The Ceph Operator helm chart will install the basic components necessary to crea
 
 The `helm install` command deploys rook on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. It is recommended that the rook operator be installed into the `rook-ceph` namespace (you will install your clusters into separate namespaces).
 
-Rook currently publishes builds of the Ceph operator to the `release` and `master` channels.
-
 ### **Release**
 
-The release channel is the most recent release of Rook that is considered stable for the community.
+The `release` channel is the most recent release of Rook that is considered stable for the community.
 
 ```console
 helm repo add rook-release https://charts.rook.io/release
diff --git a/Documentation/Helm-Charts/operator-chart.md b/Documentation/Helm-Charts/operator-chart.md
index a881158f3435..64afdc65304a 100644
--- a/Documentation/Helm-Charts/operator-chart.md
+++ b/Documentation/Helm-Charts/operator-chart.md
@@ -14,7 +14,6 @@ This chart bootstraps a [rook-ceph-operator](https://github.com/rook/rook) deplo
 
 ## Prerequisites
 
-* Kubernetes 1.22+
 * Helm 3.x
 
 See the [Helm support matrix](https://helm.sh/docs/topics/version_skew/) for more details.
@@ -28,11 +27,9 @@ The Ceph Operator helm chart will install the basic components necessary to crea
 
 The `helm install` command deploys rook on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. It is recommended that the rook operator be installed into the `rook-ceph` namespace (you will install your clusters into separate namespaces).
 
-Rook currently publishes builds of the Ceph operator to the `release` and `master` channels.
-
 ### **Release**
 
-The release channel is the most recent release of Rook that is considered stable for the community.
+The `release` channel is the most recent release of Rook that is considered stable for the community.
 
 ```console
 helm repo add rook-release https://charts.rook.io/release
diff --git a/Makefile b/Makefile
index cf4f6ebe5448..488ade028ee2 100644
--- a/Makefile
+++ b/Makefile
@@ -162,7 +162,7 @@ fmt: $(YQ) ## Check formatting of go sources.
 
 fmt-fix: $(YQ) ## Reformatting of go sources.
 	@$(MAKE) go.fmt-fix
- 
+
 golangci-lint: $(YQ)
 	@$(MAKE) go.golangci-lint
 
@@ -253,7 +253,6 @@ generate: gen.codegen gen.crds gen.rbac gen.docs gen.crd-docs ## Update all gene
 define HELPTEXT
 available options:
     DEBUG        Whether to generate debug symbols. Default is 0.
-    IMAGES       Backend images to make. All by default. See: /rook/images/ dir
     PLATFORM     The platform to build.
     SUITE        The test suite to run.
     TESTFILTER   Tests to run in a suite.
diff --git a/build/makelib/common.mk b/build/makelib/common.mk
index d61242293310..d87a9cdcea55 100644
--- a/build/makelib/common.mk
+++ b/build/makelib/common.mk
@@ -100,12 +100,9 @@ SED_IN_PLACE = $(ROOT_DIR)/build/sed-in-place
 export SED_IN_PLACE
 
 # This is a neat little target that prints any variable value from the Makefile
-# Usage: make echo.IMAGES echo.PLATFORM
+# Usage: make echo.PLATFORM
 echo.%: ; @echo $* = $($*)
 
-# Select which images (backends) to make; default to all possible images
-IMAGES ?= ceph
-
 COMMA := ,
 SPACE :=
 SPACE +=
diff --git a/build/release/Makefile b/build/release/Makefile
index 83f4d3c2d8cf..2d0e7a76ef83 100644
--- a/build/release/Makefile
+++ b/build/release/Makefile
@@ -17,14 +17,6 @@ all: build
 include ../makelib/common.mk
 include ../makelib/helm.mk
 
-# ====================================================================================
-# Options
-
-CHANNEL ?= master
-ifeq ($(filter master release,$(CHANNEL)),)
-$(error invalid channel $(CHANNEL))
-endif
-
 # When running the tag pipeline or release build we always want to add the alpha, beta, or rc suffix
 # if provided. Otherwise, it's a master build where we don't want to apply the suffix.
 ifneq ($(TAG_WITH_SUFFIX),true)
@@ -55,29 +47,27 @@ ifeq ($(COMMIT_HASH),)
 override COMMIT_HASH := $(shell git rev-parse HEAD)
 endif
 
-REMOTE_NAME ?= origin
-
 PLATFORMS ?= $(ALL_PLATFORMS)
 
 # "helm" flavor is for pushing to s3/https endpoint
 # "charts" flavor is for pushing to oci endpoint
-ifneq ($(filter master release-%,$(BRANCH_NAME)),)
 FLAVORS ?= output images docs helm charts
-else
-FLAVORS ?= output
-override BRANCH_NAME := pr/$(BRANCH_NAME)
-endif
 
 DOCKER_REGISTRY ?= docker.io/rook
 QUAY_REGISTRY ?= quay.io/rook
 GHCR_REGISTRY ?= ghcr.io/rook
-REGISTRIES ?= $(DOCKER_REGISTRY) $(QUAY_REGISTRY) $(GHCR_REGISTRY)
+ifeq ($(TAGGED_RELEASE),false)
+# Publish always to dockerhub, including master and interim builds
+REGISTRIES = $(DOCKER_REGISTRY)
+else
+# Publish the images to all registries for tagged releases
+REGISTRIES = $(DOCKER_REGISTRY) $(QUAY_REGISTRY) $(GHCR_REGISTRY)
+endif
 IMAGE_ARCHS := $(subst linux_,,$(filter linux_%,$(PLATFORMS)))
 IMAGE_PLATFORMS := $(subst _,/,$(subst $(SPACE),$(COMMA),$(filter linux_%,$(PLATFORMS))))
 IMAGE_PLATFORMS_COMMA := $(shell echo "$(IMAGE_PLATFORMS)" | sed 's/ /,/g' | sed 's/.$$//')
 
 S3_BUCKET ?= rook.releases
-S3_CP := aws s3 cp --only-show-errors
 S3_SYNC := aws s3 sync --only-show-errors
 S3_SYNC_DEL := aws s3 sync --only-show-errors --delete
 
@@ -99,33 +89,10 @@ $(MANIFEST_TOOL):
 build: $(addprefix build.,$(FLAVORS)) ;
 publish: $(addprefix publish.,$(FLAVORS)) ;
 promote: $(addprefix promote.,$(FLAVORS)) ;
-clean: $(addprefix clean.,$(FLAVORS)) ;
 
 # catch all for unimplemented targets / flavors
 %: ; @:
 
-# ====================================================================================
-# tagging a release
-
-VERSION_REGEX := ^v\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)[-]*\([alpha|beta|rc]\)*[\.]*\([0-9]*\)$$
-VERSION_VALID := $(shell echo "$(VERSION)" | grep -q '$(VERSION_REGEX)' && echo 1 || echo 0)
-VERSION_MAJOR := $(shell echo "$(VERSION)" | sed -e 's/$(VERSION_REGEX)/\1/')
-VERSION_MINOR := $(shell echo "$(VERSION)" | sed -e 's/$(VERSION_REGEX)/\2/')
-VERSION_PATCH := $(shell echo "$(VERSION)" | sed -e 's/$(VERSION_REGEX)/\3/')
-
-tag:
-ifneq ($(VERSION_VALID),1)
-	$(error invalid version $(VERSION), must be a semantic version with v[Major].[Minor].[Patch] and an optional suffix such as -alpha.0, -beta.1, or -rc.2)
-endif
-	@echo === tagging commit hash $(COMMIT_HASH) with $(VERSION) and parsed v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
-	git tag -f -m "release $(VERSION)" $(VERSION) $(COMMIT_HASH)
-	git push $(REMOTE_NAME) $(VERSION)
-	set -e; if ! git ls-remote --heads $(REMOTE_NAME) | grep -q refs/heads/release-$(VERSION_MAJOR).$(VERSION_MINOR); then \
-		echo === creating new release branch release-$(VERSION_MAJOR).$(VERSION_MINOR) ;\
-		git branch -f release-$(VERSION_MAJOR).$(VERSION_MINOR) $(COMMIT_HASH) ;\
-		git push $(REMOTE_NAME) release-$(VERSION_MAJOR).$(VERSION_MINOR) ;\
-	fi
-
 # ====================================================================================
 # docs
 
@@ -146,16 +113,16 @@ publish.docs:
 
 # ====================================================================================
 # helm
-
+HELM_CHANNEL = release
 HELM_TEMP := $(shell mktemp -d)
-HELM_URL := $(HELM_BASE_URL)/$(CHANNEL)
+HELM_URL := $(HELM_BASE_URL)/$(HELM_CHANNEL)
 
 promote.helm: $(HELM)
 #	copy existing charts to a temp dir, then combine with new charts, reindex, and upload
-	$(S3_SYNC) s3://$(HELM_S3_BUCKET)/$(CHANNEL) $(HELM_TEMP)
+	$(S3_SYNC) s3://$(HELM_S3_BUCKET)/$(HELM_CHANNEL) $(HELM_TEMP)
 	$(S3_SYNC) s3://$(S3_BUCKET)/build/$(BRANCH_NAME)/$(VERSION)/charts $(HELM_TEMP)
 	$(HELM) repo index --url $(HELM_URL) $(HELM_TEMP)
-	$(S3_SYNC_DEL) $(HELM_TEMP) s3://$(HELM_S3_BUCKET)/$(CHANNEL)
+	$(S3_SYNC_DEL) $(HELM_TEMP) s3://$(HELM_S3_BUCKET)/$(HELM_CHANNEL)
 	rm -fr $(HELM_TEMP)
 
 # set the helm cart version number.
@@ -177,9 +144,6 @@ build.chart.$(1):
 	mkdir -p $(HELM_OUTPUT_DIR)
 	$(HELM) package --version $(HELM_CHART_VERSION) --app-version $(VERSION) $(HELM_CHARTS_DIR)/$(1) --destination $(HELM_OUTPUT_DIR)
 build.all.charts: build.chart.$(1)
-clean.chart.$(1):
-	@rm -fr $(HELM_OUTPUT_DIR)/$(1)-$(HELM_CHART_VERSION).tgz
-clean.all.charts: clean.chart.$(1)
 endef
 $(foreach c,$(HELM_CHARTS),$(eval $(call chart.build,$(c))))
 
@@ -197,54 +161,42 @@ $(foreach r,$(REGISTRIES), $(foreach c,$(HELM_CHARTS),$(eval $(call chart.target
 publish.output:
 	$(S3_SYNC_DEL) $(OUTPUT_DIR) s3://$(S3_BUCKET)/build/$(BRANCH_NAME)/$(VERSION)
 promote.output:
-	$(S3_SYNC_DEL) s3://$(S3_BUCKET)/build/$(BRANCH_NAME)/$(VERSION) s3://$(S3_BUCKET)/$(CHANNEL)/$(VERSION)
-	$(S3_SYNC_DEL) s3://$(S3_BUCKET)/build/$(BRANCH_NAME)/$(VERSION) s3://$(S3_BUCKET)/$(CHANNEL)/current
+	$(S3_SYNC_DEL) s3://$(S3_BUCKET)/build/$(BRANCH_NAME)/$(VERSION) s3://$(S3_BUCKET)/$(HELM_CHANNEL)/$(VERSION)
+	$(S3_SYNC_DEL) s3://$(S3_BUCKET)/build/$(BRANCH_NAME)/$(VERSION) s3://$(S3_BUCKET)/$(HELM_CHANNEL)/current
 
 # ====================================================================================
 # images
 
-# 1: registry 2: image, 3: arch
+# 1: registry 2: arch
 define repo.targets
-build.image.$(1).$(2).$(3):
-	$(DOCKERCMD) tag $(BUILD_REGISTRY)/$(2)-$(3) $(1)/$(2)-$(3):$(VERSION)
-	@# Save image as _output/images/linux_<arch>/<image>.tar.gz (no builds for darwin or windows)
-	mkdir -p $(OUTPUT_DIR)/images/linux_$(3)
-	$(DOCKERCMD) save $(BUILD_REGISTRY)/$(2)-$(3) | gzip -c > $(OUTPUT_DIR)/images/linux_$(3)/$(2).tar.gz
-build.all.images: build.image.$(1).$(2).$(3)
-publish.image.$(1).$(2).$(3): ; @$(DOCKERCMD) push $(1)/$(2)-$(3):$(VERSION)
-publish.all.images: publish.image.$(1).$(2).$(3)
-# tag the master image, but do not tag the release image with a generic channel tag
-promote.image.$(1).$(2).$(3):
-	$(DOCKERCMD) pull $(1)/$(2)-$(3):$(VERSION)
-	$(DOCKERCMD) tag $(1)/$(2)-$(3):$(VERSION) $(1)/$(2)-$(3):$(CHANNEL)
-	[ "$(CHANNEL)" = "release" ] || $(DOCKERCMD) push $(1)/$(2)-$(3):$(CHANNEL)
-promote.all.images: promote.image.$(1).$(2).$(3)
-clean.image.$(1).$(2).$(3):
-	[ -z "$$$$($(DOCKERCMD) images -q $(1)/$(2)-$(3):$(VERSION))" ] || $(DOCKERCMD) rmi $(1)/$(2)-$(3):$(VERSION)
-	[ -z "$$$$($(DOCKERCMD) images -q $(1)/$(2)-$(3):$(CHANNEL))" ] || $(DOCKERCMD) rmi $(1)/$(2)-$(3):$(CHANNEL)
-clean.all.images: clean.image.$(1).$(2).$(3)
+build.image.$(1).$(2):
+	$(DOCKERCMD) tag $(BUILD_REGISTRY)/ceph-$(2) $(1)/ceph-$(2):$(VERSION)
+	$(DOCKERCMD) tag $(BUILD_REGISTRY)/ceph-$(2) $(1)/ceph-$(2):$(BRANCH_NAME)
+	@# Save image as _output/images/linux_<arch>/ceph.tar.gz (no builds for darwin or windows)
+	mkdir -p $(OUTPUT_DIR)/images/linux_$(2)
+	$(DOCKERCMD) save $(BUILD_REGISTRY)/ceph-$(2) | gzip -c > $(OUTPUT_DIR)/images/linux_$(2)/ceph.tar.gz
+build.all.images: build.image.$(1).$(2)
+publish.image.$(1).$(2):
+	@$(DOCKERCMD) push $(1)/ceph-$(2):$(VERSION)
+	@$(DOCKERCMD) push $(1)/ceph-$(2):$(BRANCH_NAME)
+
+publish.all.images: publish.image.$(1).$(2)
 endef
-$(foreach r,$(REGISTRIES), $(foreach i,$(IMAGES), $(foreach a,$(IMAGE_ARCHS),$(eval $(call repo.targets,$(r),$(i),$(a))))))
+$(foreach r,$(REGISTRIES), $(foreach a,$(IMAGE_ARCHS),$(eval $(call repo.targets,$(r),$(a)))))
+
+define repo.manifest.targets
+publish.manifest.image.$(1): $(MANIFEST_TOOL)
+	$(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(1)/ceph-ARCH:$(VERSION) --target $(1)/ceph:$(VERSION)
+	$(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(1)/ceph-ARCH:$(BRANCH_NAME) --target $(1)/ceph:$(BRANCH_NAME)
 
-publish.manifest.image.%: publish.all.images $(MANIFEST_TOOL)
-	$(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(DOCKER_REGISTRY)/$*-ARCH:$(VERSION) --target $(DOCKER_REGISTRY)/$*:$(VERSION)
-	$(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(QUAY_REGISTRY)/$*-ARCH:$(VERSION) --target $(QUAY_REGISTRY)/$*:$(VERSION)
-	$(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(GHCR_REGISTRY)/$*-ARCH:$(VERSION) --target $(GHCR_REGISTRY)/$*:$(VERSION)
+publish.images: publish.manifest.image.$(1)
+endef
+$(foreach r,$(REGISTRIES),$(eval $(call repo.manifest.targets,$(r))))
 
-# add the "master" tag to the master image, but do not add the "release" tag for the release channel
-promote.manifest.image.%: promote.all.images $(MANIFEST_TOOL)
-	[ "$(CHANNEL)" = "release" ] || $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(DOCKER_REGISTRY)/$*-ARCH:$(VERSION) --target $(DOCKER_REGISTRY)/$*:$(CHANNEL)
-	[ "$(CHANNEL)" = "release" ] || $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(QUAY_REGISTRY)/$*-ARCH:$(VERSION) --target $(QUAY_REGISTRY)/$*:$(CHANNEL)
-	[ "$(CHANNEL)" = "release" ] || $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(GHCR_REGISTRY)/$*-ARCH:$(VERSION) --target $(GHCR_REGISTRY)/$*:$(CHANNEL)
 
 build.images: build.all.images
-publish.images: $(addprefix publish.manifest.image.,$(IMAGES))
-promote.images: $(addprefix promote.manifest.image.,$(IMAGES))
-clean.images: clean.all.images
-
 build.charts: build.all.charts
 promote.charts: promote.all.charts
-clean.charts: clean.all.charts
 
 # ====================================================================================
 # Help
@@ -255,16 +207,12 @@ help:
 	@echo ''
 	@echo 'Targets:'
 	@echo '    build        Build all release artifacts.'
-	@echo '    clean        Remove all release artifacts.'
 	@echo '    publish      Publish all release artifacts.'
-	@echo '    promote      Promote a build to a channel.'
-	@echo '    tag          Tag a build for release.'
+	@echo '    promote      Publish the helm charts.'
 	@echo ''
 	@echo 'Options:'
 	@echo '    VERSION      Sets the release version.'
 	@echo '    BRANCH_NAME  Name of the branch we are releasing from.'
-	@echo '    CHANNEL      Sets the release channel. Can be set to master,'
-	@echo '                 or release. Default is not set.'
 	@echo '    PLATFORMS    The supported platforms to build when running.'
 	@echo '                 the build.all target. The default is'
 	@echo '                 all supported platforms'
diff --git a/tests/scripts/build-release.sh b/tests/scripts/build-release.sh
index cabbfcf808fd..a193c287e15d 100755
--- a/tests/scripts/build-release.sh
+++ b/tests/scripts/build-release.sh
@@ -13,18 +13,17 @@ function  build() {
     $MAKE mod.check
 }
 
-function publish() {
+function publish_images_and_docs() {
     build
     $MAKE -C build/release build BRANCH_NAME=${BRANCH_NAME} TAG_WITH_SUFFIX=${TAG_WITH_SUFFIX} GIT_API_TOKEN=${GIT_API_TOKEN}
     git status &
     git diff &
-    $MAKE -C build/release publish BRANCH_NAME=${BRANCH_NAME} TAG_WITH_SUFFIX=${TAG_WITH_SUFFIX} AWS_ACCESS_KEY_ID=${AWS_USR} AWS_SECRET_ACCESS_KEY=${AWS_PSW} GIT_API_TOKEN=${GIT_API_TOKEN}
+    $MAKE -C build/release publish BRANCH_NAME=${BRANCH_NAME} TAG_WITH_SUFFIX=${TAG_WITH_SUFFIX} AWS_ACCESS_KEY_ID=${AWS_USR} AWS_SECRET_ACCESS_KEY=${AWS_PSW} GIT_API_TOKEN=${GIT_API_TOKEN} TAGGED_RELEASE=${TAGGED_RELEASE}
 }
 
-function promote() {
-    # automatically promote the master builds
-    echo "Promoting from branch ${BRANCH_NAME}"
-    $MAKE -C build/release promote BRANCH_NAME=${BRANCH_NAME} TAG_WITH_SUFFIX=${TAG_WITH_SUFFIX} CHANNEL=${CHANNEL} AWS_ACCESS_KEY_ID=${AWS_USR} AWS_SECRET_ACCESS_KEY=${AWS_PSW}
+function publish_charts() {
+    echo "Publishing helm charts for release build"
+    $MAKE -C build/release promote BRANCH_NAME=${BRANCH_NAME} TAG_WITH_SUFFIX=${TAG_WITH_SUFFIX} AWS_ACCESS_KEY_ID=${AWS_USR} AWS_SECRET_ACCESS_KEY=${AWS_PSW}
 }
 
 #############
@@ -46,14 +45,12 @@ if [ -n "${GIT_API_TOKEN}" ]; then
     export DOCS_GIT_REPO="https://${GIT_API_TOKEN}@${DOCS_GIT_REPO}"
 fi
 
-SHOULD_PROMOTE=true
+TAGGED_RELEASE=false
 if [[ ${GITHUB_REF} =~ master ]]; then
     echo "Publishing from master"
-    CHANNEL=master
 else
     echo "Tagging with suffix for release and tagged builds"
     TAG_WITH_SUFFIX=true
-    CHANNEL=release
 
     # If a tag, find the source release branch
     if [[ $BRANCH_NAME = v* ]]; then
@@ -64,15 +61,15 @@ else
             exit 1
         fi
         echo "Publishing tag ${TAG_NAME} in branch ${BRANCH_NAME}"
+        TAGGED_RELEASE=true
     else
         echo "Publishing from release branch ${BRANCH_NAME}"
-        SHOULD_PROMOTE=false
     fi
 fi
 
 
-publish
+publish_images_and_docs
 
-if [[ "$SHOULD_PROMOTE" = true ]]; then
-  promote
+if [[ "$TAGGED_RELEASE" = true ]]; then
+  publish_charts
 fi
diff --git a/tests/scripts/github-action-helper.sh b/tests/scripts/github-action-helper.sh
index da27b709af1f..22d3c091e0ee 100755
--- a/tests/scripts/github-action-helper.sh
+++ b/tests/scripts/github-action-helper.sh
@@ -181,7 +181,7 @@ function build_rook() {
   fi
   GOPATH=$(go env GOPATH) make clean
   for _ in $(seq 1 3); do
-    if ! o=$(make -j"$(nproc)" IMAGES='ceph' "$build_type"); then
+    if ! o=$(make -j"$(nproc)" "$build_type"); then
       case "$o" in
       *"$NETWORK_ERROR"*)
         echo "network failure occurred, retrying..."


Reviews:
user: login: BlaineEXE
body: I went through the logic of this as best as I could, and I think it all checks out.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-18T17:44:14Z
user: login: subhamkrai
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T15:55:46Z
user: login: travisn
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-21T19:24:11Z

Review comments:
diff_hunk: @@ -55,29 +47,27 @@ ifeq ($(COMMIT_HASH),)
 override COMMIT_HASH := $(shell git rev-parse HEAD)
 endif
 
-REMOTE_NAME ?= origin
-
 PLATFORMS ?= $(ALL_PLATFORMS)
 
 # "helm" flavor is for pushing to s3/https endpoint
 # "charts" flavor is for pushing to oci endpoint
-ifneq ($(filter master release-%,$(BRANCH_NAME)),)
 FLAVORS ?= output images docs helm charts
-else
-FLAVORS ?= output
-override BRANCH_NAME := pr/$(BRANCH_NAME)
-endif
 
 DOCKER_REGISTRY ?= docker.io/rook
 QUAY_REGISTRY ?= quay.io/rook
 GHCR_REGISTRY ?= ghcr.io/rook
-REGISTRIES ?= $(DOCKER_REGISTRY) $(QUAY_REGISTRY) $(GHCR_REGISTRY)
+ifeq ($(TAGGED_RELEASE),false)
+# Publish always to dockerhub, including master and interim builds
+REGISTRIES = $(DOCKER_REGISTRY)
+else
+# Publish the images to all registries for tagged releases
+REGISTRIES = $(DOCKER_REGISTRY) $(QUAY_REGISTRY) $(GHCR_REGISTRY)
+endif
path: build/release/Makefile
user: login: BlaineEXE
body: Nit/opinion: it might be easier to read/maintain this code if this were moved down to be just above `define repo.targets` where it's used.
created_at: 2025-04-18T17:43:47Z
author_association: MEMBER
diff_hunk: @@ -55,29 +47,27 @@ ifeq ($(COMMIT_HASH),)
 override COMMIT_HASH := $(shell git rev-parse HEAD)
 endif
 
-REMOTE_NAME ?= origin
-
 PLATFORMS ?= $(ALL_PLATFORMS)
 
 # "helm" flavor is for pushing to s3/https endpoint
 # "charts" flavor is for pushing to oci endpoint
-ifneq ($(filter master release-%,$(BRANCH_NAME)),)
 FLAVORS ?= output images docs helm charts
-else
-FLAVORS ?= output
-override BRANCH_NAME := pr/$(BRANCH_NAME)
-endif
 
 DOCKER_REGISTRY ?= docker.io/rook
 QUAY_REGISTRY ?= quay.io/rook
 GHCR_REGISTRY ?= ghcr.io/rook
-REGISTRIES ?= $(DOCKER_REGISTRY) $(QUAY_REGISTRY) $(GHCR_REGISTRY)
+ifeq ($(TAGGED_RELEASE),false)
+# Publish always to dockerhub, including master and interim builds
+REGISTRIES = $(DOCKER_REGISTRY)
+else
+# Publish the images to all registries for tagged releases
+REGISTRIES = $(DOCKER_REGISTRY) $(QUAY_REGISTRY) $(GHCR_REGISTRY)
+endif
path: build/release/Makefile
user: login: travisn
body: It's also used in the helm chart section on line 156, so it's not as clear where to move it. I think it's nice to see variables defined together as much as possible earlier in the file so I'll leave it here for now. 
created_at: 2025-04-21T19:24:11Z
author_association: MEMBER

PR comments:
user: login: travisn
created_at: 2025-04-18T16:38:54Z
body: This will be difficult to review and test before we just merge it to confirm the behavior. Before spending time on the review, we may want to discuss in more detail. 
author_association: MEMBER
user: login: BlaineEXE
created_at: 2025-04-18T17:01:50Z
body: > This will be difficult to review and test before we just merge it to confirm the behavior. Before spending time on the review, we may want to discuss in more detail.

Happy to discuss. I think we can take a try it an see approach here too. It should be possible to merge into master and then see how it behaves. Since this is aimed at not publishing master builds to non-Docker repos, we should get pretty quick feedback about whether that part is working and fix as needed. In the worst case, we can always revert it before the next release.
author_association: MEMBER
user: login: travisn
created_at: 2025-04-21T21:32:31Z
body: The artifacts all look as expected in master after one small fix in #15759, going ahead with the backport to release branch.
author_association: MEMBER