Skip to content

Expand consolidated Quay promotion to OCP 4.11–4.22#5198

Open
deepsm007 wants to merge 1 commit into
openshift:mainfrom
deepsm007:revert-dptp-4340-gate-4.12
Open

Expand consolidated Quay promotion to OCP 4.11–4.22#5198
deepsm007 wants to merge 1 commit into
openshift:mainfrom
deepsm007:revert-dptp-4340-gate-4.12

Conversation

@deepsm007
Copy link
Copy Markdown
Contributor

@deepsm007 deepsm007 commented May 21, 2026

Summary

Expands the consolidated Quay promotion rollout from 4.12 only to 4.11 through 4.22, while 4.23 and 5.0 stay on the previous behavior to limit disruption on the newest streams.

For streams in the rollout:

  • Postsubmit promotion uses promotion-quay only (mirror to Quay, tag via quay-proxy into ocp/<version>:<component> without a -quay imagestream suffix).
  • CI payload assembly uses the reference image stream file fallback when building with oc adm release new.

For 4.23 and 5.0 (unchanged for now):

  • Both promotion and promotion-quay run.
  • Quay-proxy targets keep the ocp/<version>-quay:<component> naming.
  • Payload assembly uses --from-image-stream only.

Follow-up

/cc @openshift/test-platform

Overview

This PR expands support for consolidated Quay-based image promotion from just OCP 4.12 to a broader range: versions 4.11 through 4.22. Versions 4.23 and 5.0 remain on the previous two-step promotion workflow.

What Changed

For OCP versions 4.11–4.22 (consolidated Quay promotion):

  • Image mirroring: The promotion-quay step now mirrors images directly to Quay and tags them as ocp/<version>:<component> (without the -quay suffix)
  • Promotion behavior: Only the promotion-quay step runs for these versions; the separate promotion step is skipped
  • Release payload assembly: When building release payloams with oc adm release new, the CI operator now attempts to fetch and use the actual imagestream directly via --from-image-stream-file. If that fails or is unavailable, it gracefully falls back to --from-image-stream

For OCP versions 4.23 and 5.0 (legacy behavior preserved):

  • Both promotion and promotion-quay steps continue to run
  • Quay proxy targets retain the ocp/<version>-quay:<component> naming convention
  • Release payload assembly uses only --from-image-stream

Implementation Details

  • Added exported ConsolidatedQuayPromotionVersion() function to expose version eligibility checking
  • Version eligibility is determined by a new predicate that explicitly excludes 4.23 and 5.0, and returns true only for OCP 4.x with minor versions 11–22
  • Quay proxy stream naming now dynamically selects between "" (empty suffix) and "-quay" based on the version predicate
  • Tests updated across promotion, release creation, and defaults modules to reflect the new targeting behavior

CI Operator Impact

This change affects how CI images are promoted and how release payloads are assembled for supported OCP versions. The consolidated approach simplifies the promotion workflow by using a single, unified code path for Quay-based image handling across the 4.11–4.22 range, while maintaining backward compatibility for earlier (4.23+) versions.

@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label May 21, 2026
@openshift-ci openshift-ci Bot requested a review from a team May 21, 2026 10:50
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

openshift-ci-robot commented May 21, 2026

@deepsm007: This pull request references DPTP-4340 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

This reverts commit 3e6c611.

Tested here

/cc @openshift/test-platform

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 21, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR consolidates Quay promotion eligibility logic into a version-range predicate covering OpenShift 4.11–4.22, excluding 4.23 and 5.0. The predicate is exported as a public function and applied throughout promotion, release creation, and test fixtures. Mirror key formats are updated and fixture tagging logic is refactored from dynamic digest discovery to fixed digests.

Changes

Quay Promotion Version Consolidation

Layer / File(s) Summary
Version predicate definition and API
pkg/api/promotion.go
Introduces consolidatedQuayPromotionVersion predicate (4.11–4.22, excluding 4.23 and 5.0) and exports ConsolidatedQuayPromotionVersion. Updates ConsolidatedQuayPromotion and quayProxyStreamSuffix to branch on the predicate instead of exact version checks.
Release creation integration and alignment
pkg/steps/release/create_release.go, pkg/steps/release/create_release_test.go
buildOcAdmReleaseNewCommand refactored to use ConsolidatedQuayPromotionVersion for command selection. Test updated to use version 4.23, aligning with the new predicate logic.
Promotion mirror key test updates
pkg/api/promotion_test.go, pkg/steps/release/promote_test.go
Mirror key expectations updated to remove -quay suffix for versions within the consolidated range (4.20, 4.22), reflecting the new quayProxyStreamSuffix behavior.
Configuration test coverage for edge cases
pkg/defaults/defaults_test.go
Added test cases for versions 4.23 and 5.0, verifying that both [promotion] and [promotion-quay] steps are expected when the predicate evaluates false.
Fixture script refactoring: digest discovery to fixed digests
pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml, pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml
Replaced dynamic digest discovery (oc image info + sed parsing) with fixed-digest oc tag retry loops. Destination tags updated from ocp/<ver>-quay:* to ocp/<ver>:*; retry strategy simplified.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes


Suggested labels

lgtm, jira/valid-reference


Suggested reviewers

  • Prucek
  • droslean
🚥 Pre-merge checks | ✅ 12 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Coverage For New Features ⚠️ Warning New exported ConsolidatedQuayPromotionVersion lacks dedicated unit test. Only indirectly tested via higher-level functions; missing direct test for boundary conditions like 4.11, 4.23, 5.0. Add table-driven unit test for ConsolidatedQuayPromotionVersion covering versions: 4.10, 4.11, 4.12, 4.21, 4.22, 4.23, 5.0, and invalid formats.
✅ Passed checks (12 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: expanding consolidated Quay promotion support from 4.12 only to the 4.11–4.22 range, which is the core objective of this pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Go Error Handling ✅ Passed Go error handling follows best practices: errors are properly checked (not ignored), wrapped with context using fmt.Errorf with %w, no panic() statements, and value-type structs used safely.
Stable And Deterministic Test Names ✅ Passed No Ginkgo tests found in this PR. All tests use Go standard testing.T with table-driven patterns; the custom check for stable Ginkgo test names is not applicable.
Test Structure And Quality ✅ Passed The test code in this PR uses standard Go testing patterns (table-driven tests with t.Run) rather than Ginkgo. The check requires Ginkgo test assessment, which is not applicable here.
Microshift Test Compatibility ✅ Passed No Ginkgo e2e tests were added in this PR. Changes are limited to library code and unit tests using Go's standard testing.T framework. MicroShift compatibility check is not applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed This PR contains only changes to unit/integration tests in the ci-tools project itself (no Ginkgo e2e tests added). The SNO compatibility check is not applicable to this internal tooling test suite.
Topology-Aware Scheduling Compatibility ✅ Passed PR only modifies ci-tools test code and fixtures; no deployment manifests, operator code, or controllers with topology-unaware scheduling constraints are introduced.
Ote Binary Stdout Contract ✅ Passed PR modifies CI infrastructure code, not OTE binaries. No main(), suite-level code, or stdout writes detected.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PR contains no new Ginkgo e2e tests. All modifications are unit tests (testing.T) and test fixtures, which fall outside the scope of this IPv6/disconnected network compatibility check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
pkg/api/promotion.go (1)

110-112: ⚡ Quick win

Update outdated format comment in getQuayProxyTarget.

Line 111 still documents a -quay suffix, but Lines 114/129/136 now generate namespace/name:tag without it.

Suggested doc fix
-// Format: namespace/imagestream-name-quay:tag
+// Format: namespace/imagestream-name:tag
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/promotion.go` around lines 110 - 112, The comment for
getQuayProxyTarget is outdated (mentions a "-quay" suffix) — update the function
docstring to reflect the actual format produced by getQuayProxyTarget (i.e.,
"namespace/imagestream-name:tag" or "namespace/name:tag") and remove the "-quay"
mention; ensure the doc references the ImageStreamTagReference parameter and
clearly shows the exact output format used by the function.
pkg/steps/release/create_release_test.go (1)

99-112: ⚡ Quick win

Consider table-driven testing for broader version coverage.

The assemble_script test now only verifies version 4.15. If buildOcAdmReleaseNewCommand now always uses the shell-based approach regardless of version (per the layer description), consider extending this to a table-driven test covering multiple versions (e.g., 4.10, 4.12, 4.15) to verify the shell script generation works correctly with version-dependent flags across all supported versions.

♻️ Suggested table-driven structure
 t.Run("assemble_script", func(t *testing.T) {
-	srcPol := imagev1.SourceTagReferencePolicy
-	config := &api.ReleaseTagConfiguration{Name: "4.15", ReferencePolicy: &srcPol}
-	got := buildOcAdmReleaseNewCommand(config, "test-ns", "stable", "cvo-pullspec", "dest:tag", "0.0.1-ver")
-	want := `_CI_RELEASE_IS_FILE="/tmp/ci-operator-release-is-stable.yaml"
+	srcPol := imagev1.SourceTagReferencePolicy
+	tests := []struct {
+		name   string
+		config *api.ReleaseTagConfiguration
+		want   string
+	}{
+		{
+			name:   "4.12 with ReferencePolicy",
+			config: &api.ReleaseTagConfiguration{Name: "4.12", ReferencePolicy: &srcPol},
+			want: `_CI_RELEASE_IS_FILE="/tmp/ci-operator-release-is-stable.yaml"
+if oc get imagestream "stable" -n "test-ns" -o yaml > "${_CI_RELEASE_IS_FILE}" 2>/dev/null; then
+  oc adm release new --max-per-registry=32 -n test-ns --from-image-stream-file ${_CI_RELEASE_IS_FILE} --to-image-base cvo-pullspec --to-image dest:tag --name 0.0.1-ver --keep-manifest-list || oc adm release new --max-per-registry=32 -n test-ns --from-image-stream stable --to-image-base cvo-pullspec --to-image dest:tag --name 0.0.1-ver --keep-manifest-list
+else
+  oc adm release new --max-per-registry=32 -n test-ns --from-image-stream stable --to-image-base cvo-pullspec --to-image dest:tag --name 0.0.1-ver --keep-manifest-list
+fi`,
+		},
+		{
+			name:   "4.15 with ReferencePolicy",
+			config: &api.ReleaseTagConfiguration{Name: "4.15", ReferencePolicy: &srcPol},
+			want: `_CI_RELEASE_IS_FILE="/tmp/ci-operator-release-is-stable.yaml"
 if oc get imagestream "stable" -n "test-ns" -o yaml > "${_CI_RELEASE_IS_FILE}" 2>/dev/null; then
   oc adm release new --max-per-registry=32 -n test-ns --from-image-stream-file ${_CI_RELEASE_IS_FILE} --to-image-base cvo-pullspec --to-image dest:tag --name 0.0.1-ver --reference-mode=source --keep-manifest-list || oc adm release new --max-per-registry=32 -n test-ns --from-image-stream stable --to-image-base cvo-pullspec --to-image dest:tag --name 0.0.1-ver --reference-mode=source --keep-manifest-list
 else
   oc adm release new --max-per-registry=32 -n test-ns --from-image-stream stable --to-image-base cvo-pullspec --to-image dest:tag --name 0.0.1-ver --reference-mode=source --keep-manifest-list
-fi`
-	if diff := cmp.Diff(want, got); diff != "" {
-		t.Fatalf("buildOcAdmReleaseNewCommand() mismatch (-want +got):\n%s", diff)
+fi`,
+		},
 	}
+	
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got := buildOcAdmReleaseNewCommand(tt.config, "test-ns", "stable", "cvo-pullspec", "dest:tag", "0.0.1-ver")
+			if diff := cmp.Diff(tt.want, got); diff != "" {
+				t.Fatalf("buildOcAdmReleaseNewCommand() mismatch (-want +got):\n%s", diff)
+			}
+		})
+	}
 })

As per coding guidelines, prefer table-driven tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/steps/release/create_release_test.go` around lines 99 - 112, Update the
assemble_script test to be table-driven: create a slice of test cases with
different ReleaseTagConfiguration names/versions (e.g., "4.10", "4.12", "4.15")
and expected script outputs, then iterate and call buildOcAdmReleaseNewCommand
for each case, comparing got vs want (use cmp.Diff) and t.Fatalf on mismatch;
keep the test runner name ("assemble_script") and reference
buildOcAdmReleaseNewCommand and the
ReleaseTagConfiguration/SourceTagReferencePolicy setup so each case constructs
the config correctly and validates the shell-based command generation across
versions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/api/promotion.go`:
- Around line 110-112: The comment for getQuayProxyTarget is outdated (mentions
a "-quay" suffix) — update the function docstring to reflect the actual format
produced by getQuayProxyTarget (i.e., "namespace/imagestream-name:tag" or
"namespace/name:tag") and remove the "-quay" mention; ensure the doc references
the ImageStreamTagReference parameter and clearly shows the exact output format
used by the function.

In `@pkg/steps/release/create_release_test.go`:
- Around line 99-112: Update the assemble_script test to be table-driven: create
a slice of test cases with different ReleaseTagConfiguration names/versions
(e.g., "4.10", "4.12", "4.15") and expected script outputs, then iterate and
call buildOcAdmReleaseNewCommand for each case, comparing got vs want (use
cmp.Diff) and t.Fatalf on mismatch; keep the test runner name
("assemble_script") and reference buildOcAdmReleaseNewCommand and the
ReleaseTagConfiguration/SourceTagReferencePolicy setup so each case constructs
the config correctly and validates the shell-based command generation across
versions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: f05d85fa-a6ae-4438-a5cc-cf41973c69f9

📥 Commits

Reviewing files that changed from the base of the PR and between 003dbcd and 94149d2.

📒 Files selected for processing (10)
  • pkg/api/promotion.go
  • pkg/api/promotion_test.go
  • pkg/defaults/defaults.go
  • pkg/defaults/defaults_test.go
  • pkg/steps/release/create_release.go
  • pkg/steps/release/create_release_test.go
  • pkg/steps/release/promote_test.go
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_digest.yaml
💤 Files with no reviewable changes (3)
  • pkg/defaults/defaults_test.go
  • pkg/defaults/defaults.go
  • pkg/steps/release/create_release.go

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 21, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: deepsm007, Prucek

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label May 21, 2026
@deepsm007
Copy link
Copy Markdown
Contributor Author

/test lint validate-prow

pod timeout failure

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label May 21, 2026
@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e

@deepsm007
Copy link
Copy Markdown
Contributor Author

/unhold

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label May 21, 2026
@deepsm007
Copy link
Copy Markdown
Contributor Author

/test e2e

@deepsm007
Copy link
Copy Markdown
Contributor Author

/hold
cc @bradmwilliams to remove hold here and openshift/release#79592

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label May 21, 2026
@deepsm007 deepsm007 force-pushed the revert-dptp-4340-gate-4.12 branch 2 times, most recently from f2fc9a5 to 5e4f0a4 Compare May 21, 2026 18:31
@deepsm007 deepsm007 changed the title Revert "DPTP-4340: gate consolidated promotion to 4.12 only" Expand consolidated Quay promotion to OCP 4.11–4.22 May 21, 2026
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label May 21, 2026
@openshift-ci-robot openshift-ci-robot removed the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label May 21, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

@deepsm007: No Jira issue is referenced in the title of this pull request.
To reference a jira issue, add 'XYZ-NNN:' to the title of this pull request and request another refresh with /jira refresh.

Details

In response to this:

Summary

Expands the consolidated Quay promotion rollout from 4.12 only to 4.11 through 4.22, while 4.23 and 5.0 stay on the previous behavior to limit disruption on the newest streams.

For streams in the rollout:

  • Postsubmit promotion uses promotion-quay only (mirror to Quay, tag via quay-proxy into ocp/<version>:<component> without a -quay imagestream suffix).
  • CI payload assembly uses the reference image stream file fallback when building with oc adm release new.

For 4.23 and 5.0 (unchanged for now):

  • Both promotion and promotion-quay run.
  • Quay-proxy targets keep the ocp/<version>-quay:<component> naming.
  • Payload assembly uses --from-image-stream only.

Why

We want more release branches on the quay-proxy path without flipping every stream at once. Older supported branches (4.11–4.22) get the same treatment 4.12 already has; 4.23 and 5.0 can follow once this is stable.

Test plan

Follow-up

/cc @openshift/test-platform

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 21, 2026

New changes are detected. LGTM label has been removed.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pkg/api/promotion.go (2)

131-133: ⚡ Quick win

Add a Go doc comment for exported API.

ConsolidatedQuayPromotionReleaseVersion is exported and should have a proper doc comment for package consumers.

Suggested patch
-func ConsolidatedQuayPromotionReleaseVersion(name string) bool {
+// ConsolidatedQuayPromotionReleaseVersion reports whether a release stream name
+// is eligible for consolidated quay promotion.
+func ConsolidatedQuayPromotionReleaseVersion(name string) bool {
 	return consolidatedQuayPromotionVersion(name)
 }

As per coding guidelines, "Go documentation on Classes/Functions/Fields should be written properly" and "Comment important exported functions with their purpose, parameters, and return values."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/promotion.go` around lines 131 - 133, Add a Go doc comment for the
exported function ConsolidatedQuayPromotionReleaseVersion describing its
purpose, the parameter (name string) and the boolean return (what true/false
indicates); mention that it delegates to consolidatedQuayPromotionVersion(name)
so readers understand it forwards the check to that internal helper. Place the
comment immediately above the ConsolidatedQuayPromotionReleaseVersion
declaration following Go doc conventions (starts with the function name).

147-154: ⚡ Quick win

Update stale format comment to match conditional suffix behavior.

quayProxyStreamSuffix now omits -quay for consolidated versions, so the getQuayProxyTarget format comment is no longer always accurate.

Suggested patch
-// getQuayProxyTarget creates the quay-proxy target imagestream tag reference.
-// Format: namespace/imagestream-name-quay:tag
+// getQuayProxyTarget creates the quay-proxy target imagestream tag reference.
+// Format: namespace/imagestream-name[:tag], with "-quay" suffix for legacy streams only.

As per coding guidelines, "Comments should be useful and explain why code exists."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/promotion.go` around lines 147 - 154, Update the stale comment on
getQuayProxyTarget to reflect that the quayProxyStreamSuffix (used by
consolidatedQuayPromotionVersion and quayProxyStreamSuffix) conditionally omits
"-quay" for consolidated versions; change the format description to indicate the
suffix is conditional (e.g., "namespace/imagestream-name[
-quay-if-not-consolidated]:tag") and reference the
consolidatedQuayPromotionVersion/quayProxyStreamSuffix behavior so readers know
why the "-quay" may be absent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml`:
- Around line 15-17: The three retry loops that run oc tag (the for r in {1..3}
... oc tag ... && break patterns) silently succeed even if all attempts fail
because set +e prevents exiting on error; modify each loop to capture the oc tag
exit status and, after the loop, fail fast if tagging never succeeded (e.g., set
a success flag or store the last exit code from oc tag and if non-zero call exit
1 or return a non-zero error), or alternatively enable errexit for the block —
ensure you update the three tag blocks (the oc tag invocations for
ovn-kubernetes, ovn-kubernetes-base, and ovn-kubernetes-microshift) so that
exhausted retries cause the script/pod to exit non-zero to trigger correct
cleanup on failure.

---

Nitpick comments:
In `@pkg/api/promotion.go`:
- Around line 131-133: Add a Go doc comment for the exported function
ConsolidatedQuayPromotionReleaseVersion describing its purpose, the parameter
(name string) and the boolean return (what true/false indicates); mention that
it delegates to consolidatedQuayPromotionVersion(name) so readers understand it
forwards the check to that internal helper. Place the comment immediately above
the ConsolidatedQuayPromotionReleaseVersion declaration following Go doc
conventions (starts with the function name).
- Around line 147-154: Update the stale comment on getQuayProxyTarget to reflect
that the quayProxyStreamSuffix (used by consolidatedQuayPromotionVersion and
quayProxyStreamSuffix) conditionally omits "-quay" for consolidated versions;
change the format description to indicate the suffix is conditional (e.g.,
"namespace/imagestream-name[ -quay-if-not-consolidated]:tag") and reference the
consolidatedQuayPromotionVersion/quayProxyStreamSuffix behavior so readers know
why the "-quay" may be absent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: e2685d9b-0bab-469b-9bae-a87ca8a23668

📥 Commits

Reviewing files that changed from the base of the PR and between 94149d2 and 5e4f0a4.

📒 Files selected for processing (8)
  • pkg/api/promotion.go
  • pkg/api/promotion_test.go
  • pkg/defaults/defaults_test.go
  • pkg/steps/release/create_release.go
  • pkg/steps/release/create_release_test.go
  • pkg/steps/release/promote_test.go
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml

@deepsm007 deepsm007 force-pushed the revert-dptp-4340-gate-4.12 branch from 5e4f0a4 to a6bb288 Compare May 21, 2026 19:13
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/api/promotion.go`:
- Around line 136-145: The consolidatedQuayPromotionVersion function currently
uses fmt.Sscanf(name, "%d.%d", &major, &minor) which allows partial matches like
"4.12.1" to parse; update the parsing to require an exact "<major>.<minor>"
match (e.g. use a regex anchored ^(\d+)\.(\d+)$ or split on '.' and validate
there are exactly two numeric parts with strconv.Atoi) so only fully-formed
versions are accepted; keep the rest of the function logic (compare major to
consolidatedQuayPromotionMajor and minor to
consolidatedQuayPromotionMinMinor/consolidatedQuayPromotionMaxMinor) unchanged
and return false on any parse failure or extra trailing characters.

In
`@pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml`:
- Line 14: Replace single-quoted echo strings that contain the loop variable
(e.g. echo 'Tag attempt $r (all together)' and the other occurrences with '$r'
in their messages) with double-quoted strings so the shell expands $r at
runtime; locate the echo invocations in the for-loop retry blocks (the lines
printing "Tag attempt $r ..." and other retry messages) and change their quoting
to allow variable interpolation.

In
`@pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml`:
- Line 13: The echo statements inside the retry loops use single quotes so the
shell variable $r is not expanded; update each echo (e.g., the echo that
currently reads 'Tag attempt $r (all together)' and the other two similar echo
lines) to use double quotes so $r is interpolated (e.g., "Tag attempt $r ..."),
ensuring retry counts are logged correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 6fb2e661-d7d9-4040-87e2-57d86e557627

📥 Commits

Reviewing files that changed from the base of the PR and between 5e4f0a4 and a6bb288.

📒 Files selected for processing (11)
  • pkg/api/promotion.go
  • pkg/api/promotion_test.go
  • pkg/defaults/defaults_test.go
  • pkg/steps/release/create_release.go
  • pkg/steps/release/create_release_test.go
  • pkg/steps/release/promote.go
  • pkg/steps/release/promote_test.go
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_4.12.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml
✅ Files skipped from review due to trivial changes (1)
  • pkg/steps/release/promote_test.go

Comment thread pkg/api/promotion.go
Comment on lines +136 to 145
func consolidatedQuayPromotionVersion(name string) bool {
var major, minor int
if _, err := fmt.Sscanf(name, "%d.%d", &major, &minor); err != nil {
return false
}
if major != consolidatedQuayPromotionMajor {
return false
}
return gotMajor == major && gotMinor == minor
return minor >= consolidatedQuayPromotionMinMinor && minor <= consolidatedQuayPromotionMaxMinor
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In Go, with fmt.Sscanf and format "%d.%d", does scanning "4.12.1" or "4.12-foo" still return two successful assignments while leaving trailing input?

💡 Result:

Answer: No—both inputs will still successfully assign two values, and scanning does not require consuming the entire input. However, whether the second %d succeeds depends on what follows the first “.%d” component. For fmt.Sscanf with format "%d.%d": 1) Input "4.12.1" - First %d (%d) matches "4" and the literal '.' in the format matches the '.' after it. - Second %d matches "12" and stops when it encounters the next '.' (a non-digit for an integer scan). - Sscanf can stop before consuming all input (“need not consume its entire input”), so the remaining ".1" is left unconsumed. - Result: n == 2 (two successful assignments) and err == nil. 2) Input "4.12-foo" - First %d matches "4"; the '.' literal matches the '.' after it. - Second %d matches "12" and stops when it encounters '-' (not a digit for an integer scan). - Again, Sscanf need not consume its entire input, so the remaining "-foo" is left unconsumed. - Result: n == 2 (two successful assignments) and err == nil. Key rules from Go docs: - Sscanf returns the number of items successfully parsed, and it “need not consume its entire input.” [1] - Also, for Scanf/Sscanf, “text in the format string must match the input text; scanning stops if it does not,” and the return value indicates how many arguments were scanned. [2] Implication for your specific cases: after successfully matching “4” + "." + “12”, the parser is allowed to stop, so extra trailing characters like ".1" or "-foo" do not prevent the two assignments from succeeding. [1][2]

Citations:


Use strict parsing for consolidated-quay version gating (avoid fmt.Sscanf partial-match).

fmt.Sscanf(name, "%d.%d", ...) does not require consuming the whole string; values like 4.12.1 and 4.12-foo can still parse as major=4/minor=12 (n==2, err==nil), so they may incorrectly pass the consolidated-quay range checks. Switch to exact <major>.<minor> parsing.

Proposed fix
 import (
 	"fmt"
+	"strconv"
 	"strings"
@@
 func consolidatedQuayPromotionVersion(name string) bool {
-	var major, minor int
-	if _, err := fmt.Sscanf(name, "%d.%d", &major, &minor); err != nil {
+	parts := strings.Split(name, ".")
+	if len(parts) != 2 {
+		return false
+	}
+	major, err := strconv.Atoi(parts[0])
+	if err != nil {
+		return false
+	}
+	minor, err := strconv.Atoi(parts[1])
+	if err != nil {
 		return false
 	}
 	if major != consolidatedQuayPromotionMajor {
 		return false
 	}
 	return minor >= consolidatedQuayPromotionMinMinor && minor <= consolidatedQuayPromotionMaxMinor
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/promotion.go` around lines 136 - 145, The
consolidatedQuayPromotionVersion function currently uses fmt.Sscanf(name,
"%d.%d", &major, &minor) which allows partial matches like "4.12.1" to parse;
update the parsing to require an exact "<major>.<minor>" match (e.g. use a regex
anchored ^(\d+)\.(\d+)$ or split on '.' and validate there are exactly two
numeric parts with strconv.Atoi) so only fully-formed versions are accepted;
keep the rest of the function logic (compare major to
consolidatedQuayPromotionMajor and minor to
consolidatedQuayPromotionMinMinor/consolidatedQuayPromotionMaxMinor) unchanged
and return false on any parse failure or extra trailing characters.

for r in {1..5}; do
_digest=$(oc image info --registry-config=/etc/push-secret/.dockerconfigjson --filter-by-os=linux/amd64 quay-proxy.ci.openshift.org/openshift/ci:ocp_4.21_ovn-kubernetes | sed -n '/^Digest:[[:space:]]/s/^Digest:[[:space:]]*//p' | head -n1)
if [ -n "${_digest}" ] && oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@${_digest} ocp/4.21-quay:ovn-kubernetes; then
for r in {1..2}; do echo 'Tag attempt $r (all together)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ocp/4.21:ovn-kubernetes-base quay-proxy.ci.openshift.org/openshift/ci@sha256:ccc ocp/4.21:ovn-kubernetes-microshift && break; :; done
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix variable interpolation in echo statements.

Lines 14, 17, 30, and 43 use single quotes around messages containing $r, which prevents bash variable expansion. The logs will literally print $r instead of the retry attempt number (1, 2, 3), degrading observability during failure investigation.

🔧 Proposed fix
-      for r in {1..2}; do echo 'Tag attempt $r (all together)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ocp/4.21:ovn-kubernetes-base quay-proxy.ci.openshift.org/openshift/ci@sha256:ccc ocp/4.21:ovn-kubernetes-microshift && break; :; done
+      for r in {1..2}; do echo "Tag attempt $r (all together)"; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ocp/4.21:ovn-kubernetes-base quay-proxy.ci.openshift.org/openshift/ci@sha256:ccc ocp/4.21:ovn-kubernetes-microshift && break; :; done
       tagged=false
       for r in {1..3}; do
-        echo 'Tag attempt $r (individual)'
+        echo "Tag attempt $r (individual)"
         if oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes; then

...

       tagged=false
       for r in {1..3}; do
-        echo 'Tag attempt $r (individual)'
+        echo "Tag attempt $r (individual)"
         if oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ocp/4.21:ovn-kubernetes-base; then

...

       tagged=false
       for r in {1..3}; do
-        echo 'Tag attempt $r (individual)'
+        echo "Tag attempt $r (individual)"
         if oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:ccc ocp/4.21:ovn-kubernetes-microshift; then

Also applies to: 17-17, 30-30, 43-43

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml`
at line 14, Replace single-quoted echo strings that contain the loop variable
(e.g. echo 'Tag attempt $r (all together)' and the other occurrences with '$r'
in their messages) with double-quoted strings so the shell expands $r at
runtime; locate the echo invocations in the for-loop retry blocks (the lines
printing "Tag attempt $r ..." and other retry messages) and change their quoting
to allow variable interpolation.

for r in {1..5}; do
_digest=$(oc image info --registry-config=/etc/push-secret/.dockerconfigjson --filter-by-os=linux/amd64 quay-proxy.ci.openshift.org/openshift/ci:ocp_4.21_ovn-kubernetes | sed -n '/^Digest:[[:space:]]/s/^Digest:[[:space:]]*//p' | head -n1)
if [ -n "${_digest}" ] && oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@${_digest} ocp/4.21-quay:ovn-kubernetes; then
for r in {1..2}; do echo 'Tag attempt $r (all together)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes && break; :; done
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix variable interpolation in echo statements.

Lines 13, 16, and 29 use single quotes around messages containing $r, preventing bash variable expansion. Logs will show literal $r instead of retry attempt numbers, making failure diagnosis harder.

🔧 Proposed fix
-      for r in {1..2}; do echo 'Tag attempt $r (all together)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes && break; :; done
+      for r in {1..2}; do echo "Tag attempt $r (all together)"; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes && break; :; done
       tagged=false
       for r in {1..3}; do
-        echo 'Tag attempt $r (individual)'
+        echo "Tag attempt $r (individual)"
         if oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs; then

...

       tagged=false
       for r in {1..3}; do
-        echo 'Tag attempt $r (individual)'
+        echo "Tag attempt $r (individual)"
         if oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes; then

Also applies to: 16-16, 29-29

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml`
at line 13, The echo statements inside the retry loops use single quotes so the
shell variable $r is not expanded; update each echo (e.g., the echo that
currently reads 'Tag attempt $r (all together)' and the other two similar echo
lines) to use double quotes so $r is interpolated (e.g., "Tag attempt $r ..."),
ensuring retry counts are logged correctly.

@deepsm007 deepsm007 force-pushed the revert-dptp-4340-gate-4.12 branch from a6bb288 to 23e1641 Compare May 21, 2026 19:51
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
pkg/api/promotion_test.go (1)

221-235: ⚡ Quick win

Add a direct 5.0 case in TestQuayCombinedMirrorFunc.

This table now validates legacy suffix behavior for 4.23, but 5.0 is also excluded by contract. Adding a 5.0 mirror-key assertion here would protect helper-level boundary behavior from regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/promotion_test.go` around lines 221 - 235, Add a new table case in
TestQuayCombinedMirrorFunc mirroring the existing "4.23 uses quay suffix" entry
but with ImageStreamTagReference.Name set to "5.0" (and adjust any inlined tag
strings accordingly); name it e.g. "5.0 uses quay suffix" and add expected
mirror-key assertions replacing "4.23" with "5.0" (e.g.
"quay.io/openshift/ci:ocp_5.0_ovn-kubernetes",
"quay.io/openshift/ci:20241024102030_prune_ocp_5.0_ovn-kubernetes", and
"ocp/5.0-quay": "quay-proxy.ci.openshift.org/openshift/ci@sha256:abc123") so the
helper-level boundary behavior for 5.0 is asserted.
pkg/api/promotion.go (1)

133-135: ⚡ Quick win

Add GoDoc for exported ConsolidatedQuayPromotionStream.

Please document purpose/inputs/return behavior for this exported helper.

Proposed fix
+// ConsolidatedQuayPromotionStream reports whether a release stream name is in the
+// consolidated Quay promotion set.
 func ConsolidatedQuayPromotionStream(name string) bool {
 	return consolidatedQuayPromotionVersion(name)
 }

As per coding guidelines "Comment important exported functions with their purpose, parameters, and return values."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/promotion.go` around lines 133 - 135, Add a GoDoc comment immediately
above the exported function ConsolidatedQuayPromotionStream describing its
purpose, the meaning of the input parameter `name` and what the boolean return
value represents; ensure the comment starts with
"ConsolidatedQuayPromotionStream ..." and explains that it delegates to
consolidatedQuayPromotionVersion(name) and when/why it returns true or false.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/api/promotion_test.go`:
- Around line 221-235: Add a new table case in TestQuayCombinedMirrorFunc
mirroring the existing "4.23 uses quay suffix" entry but with
ImageStreamTagReference.Name set to "5.0" (and adjust any inlined tag strings
accordingly); name it e.g. "5.0 uses quay suffix" and add expected mirror-key
assertions replacing "4.23" with "5.0" (e.g.
"quay.io/openshift/ci:ocp_5.0_ovn-kubernetes",
"quay.io/openshift/ci:20241024102030_prune_ocp_5.0_ovn-kubernetes", and
"ocp/5.0-quay": "quay-proxy.ci.openshift.org/openshift/ci@sha256:abc123") so the
helper-level boundary behavior for 5.0 is asserted.

In `@pkg/api/promotion.go`:
- Around line 133-135: Add a GoDoc comment immediately above the exported
function ConsolidatedQuayPromotionStream describing its purpose, the meaning of
the input parameter `name` and what the boolean return value represents; ensure
the comment starts with "ConsolidatedQuayPromotionStream ..." and explains that
it delegates to consolidatedQuayPromotionVersion(name) and when/why it returns
true or false.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 0c2754ff-b3f8-421e-87c4-5bc93ea8e3fa

📥 Commits

Reviewing files that changed from the base of the PR and between a6bb288 and 23e1641.

📒 Files selected for processing (10)
  • pkg/api/promotion.go
  • pkg/api/promotion_test.go
  • pkg/defaults/defaults_test.go
  • pkg/steps/release/create_release.go
  • pkg/steps/release/create_release_test.go
  • pkg/steps/release/promote_test.go
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_4.12.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml

@deepsm007 deepsm007 force-pushed the revert-dptp-4340-gate-4.12 branch from 23e1641 to 679087c Compare May 24, 2026 19:57
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml`:
- Around line 13-15: The retry loops that run oc tag (the three loops with
patterns "for r in {1..2}; do ... oc tag ... && break; ... done" and the two
"for r in {1..3}; do ... oc tag ... && break; ... done" loops) can silently
succeed even when all attempts fail; change each loop to check whether the oc
tag ultimately succeeded and if not exit non‑zero (e.g., capture the command
status after the loop and call exit 1 or fail the step) so that exhausted
retries cause the script to fail and trigger correct cleanup on failure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 37329440-0cdf-43dc-a855-4c6990ee7959

📥 Commits

Reviewing files that changed from the base of the PR and between 23e1641 and 679087c.

📒 Files selected for processing (8)
  • pkg/api/promotion.go
  • pkg/api/promotion_test.go
  • pkg/defaults/defaults_test.go
  • pkg/steps/release/create_release.go
  • pkg/steps/release/create_release_test.go
  • pkg/steps/release/promote_test.go
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml
✅ Files skipped from review due to trivial changes (2)
  • pkg/steps/release/promote_test.go
  • pkg/steps/release/create_release_test.go

Comment on lines +13 to +15
for r in {1..2}; do echo 'Tag attempt $r (all together)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes && break; :; done
for r in {1..3}; do echo 'Tag attempt $r (individual)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs && break; backoff=$(($RANDOM % 120))s; echo Sleeping randomized $backoff before retry; sleep $backoff; done
for r in {1..5}; do
_digest=$(oc image info --registry-config=/etc/push-secret/.dockerconfigjson --filter-by-os=linux/amd64 quay-proxy.ci.openshift.org/openshift/ci:ocp_4.21_ovn-kubernetes | sed -n '/^Digest:[[:space:]]/s/^Digest:[[:space:]]*//p' | head -n1)
if [ -n "${_digest}" ] && oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@${_digest} ocp/4.21-quay:ovn-kubernetes; then
break
fi
echo "promotion-quay: digest-tag failed for ocp/4.21-quay:ovn-kubernetes attempt ${r}/5 (QCI digest may have moved after mirror)" >&2
if [ "${r}" -eq 5 ]; then
exit 1
fi
echo "promotion-quay: retrying digest-tag for ocp/4.21-quay:ovn-kubernetes (attempt $((r+1))/5 after randomized backoff)" >&2
backoff=$(($RANDOM % 120))s
sleep "${backoff}"
done

for r in {1..3}; do echo 'Tag attempt $r (individual)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes && break; backoff=$(($RANDOM % 120))s; echo Sleeping randomized $backoff before retry; sleep $backoff; done
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail when tag retries are exhausted.

With set +e, these loops can finish without a successful oc tag and still let the script pass, which masks promotion failures.

Proposed fix
-      for r in {1..3}; do echo 'Tag attempt $r (individual)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs && break; backoff=$(($RANDOM % 120))s; echo Sleeping randomized $backoff before retry; sleep $backoff; done
-      for r in {1..3}; do echo 'Tag attempt $r (individual)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes && break; backoff=$(($RANDOM % 120))s; echo Sleeping randomized $backoff before retry; sleep $backoff; done
+      tagged=false
+      for r in {1..3}; do
+        echo "Tag attempt $r (individual)"
+        if oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs; then
+          tagged=true
+          break
+        fi
+        backoff=$(($RANDOM % 120))s
+        echo "Sleeping randomized $backoff before retry"
+        sleep "$backoff"
+      done
+      if [ "$tagged" != "true" ]; then
+        echo "failed to tag ci/ci-quay:sanitize-prow-jobs after retries" >&2
+        exit 1
+      fi
+
+      tagged=false
+      for r in {1..3}; do
+        echo "Tag attempt $r (individual)"
+        if oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes; then
+          tagged=true
+          break
+        fi
+        backoff=$(($RANDOM % 120))s
+        echo "Sleeping randomized $backoff before retry"
+        sleep "$backoff"
+      done
+      if [ "$tagged" != "true" ]; then
+        echo "failed to tag ocp/4.21:ovn-kubernetes after retries" >&2
+        exit 1
+      fi

As per coding guidelines, changes under pkg/steps/** should ensure “correct cleanup on failure.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for r in {1..2}; do echo 'Tag attempt $r (all together)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes && break; :; done
for r in {1..3}; do echo 'Tag attempt $r (individual)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs && break; backoff=$(($RANDOM % 120))s; echo Sleeping randomized $backoff before retry; sleep $backoff; done
for r in {1..5}; do
_digest=$(oc image info --registry-config=/etc/push-secret/.dockerconfigjson --filter-by-os=linux/amd64 quay-proxy.ci.openshift.org/openshift/ci:ocp_4.21_ovn-kubernetes | sed -n '/^Digest:[[:space:]]/s/^Digest:[[:space:]]*//p' | head -n1)
if [ -n "${_digest}" ] && oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@${_digest} ocp/4.21-quay:ovn-kubernetes; then
break
fi
echo "promotion-quay: digest-tag failed for ocp/4.21-quay:ovn-kubernetes attempt ${r}/5 (QCI digest may have moved after mirror)" >&2
if [ "${r}" -eq 5 ]; then
exit 1
fi
echo "promotion-quay: retrying digest-tag for ocp/4.21-quay:ovn-kubernetes (attempt $((r+1))/5 after randomized backoff)" >&2
backoff=$(($RANDOM % 120))s
sleep "${backoff}"
done
for r in {1..3}; do echo 'Tag attempt $r (individual)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes && break; backoff=$(($RANDOM % 120))s; echo Sleeping randomized $backoff before retry; sleep $backoff; done
for r in {1..2}; do echo 'Tag attempt $r (all together)'; oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes && break; :; done
tagged=false
for r in {1..3}; do
echo "Tag attempt $r (individual)"
if oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:bbb ci/ci-quay:sanitize-prow-jobs; then
tagged=true
break
fi
backoff=$(($RANDOM % 120))s
echo "Sleeping randomized $backoff before retry"
sleep "$backoff"
done
if [ "$tagged" != "true" ]; then
echo "failed to tag ci/ci-quay:sanitize-prow-jobs after retries" >&2
exit 1
fi
tagged=false
for r in {1..3}; do
echo "Tag attempt $r (individual)"
if oc tag --source=docker --loglevel=2 --reference-policy='source' --import-mode='PreserveOriginal' --reference quay-proxy.ci.openshift.org/openshift/ci@sha256:aaa ocp/4.21:ovn-kubernetes; then
tagged=true
break
fi
backoff=$(($RANDOM % 120))s
echo "Sleeping randomized $backoff before retry"
sleep "$backoff"
done
if [ "$tagged" != "true" ]; then
echo "failed to tag ocp/4.21:ovn-kubernetes after retries" >&2
exit 1
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml`
around lines 13 - 15, The retry loops that run oc tag (the three loops with
patterns "for r in {1..2}; do ... oc tag ... && break; ... done" and the two
"for r in {1..3}; do ... oc tag ... && break; ... done" loops) can silently
succeed even when all attempts fail; change each loop to check whether the oc
tag ultimately succeeded and if not exit non‑zero (e.g., capture the command
status after the loop and call exit 1 or fail the step) so that exhausted
retries cause the script to fail and trigger correct cleanup on failure.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 24, 2026

@deepsm007: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/images 679087c link true /test images

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants