Skip to content

fix: restore quay prune tags and resync IS on promotion-quay failure#5240

Open
deepsm007 wants to merge 1 commit into
openshift:mainfrom
deepsm007:fix/promotion-prune-rollback
Open

fix: restore quay prune tags and resync IS on promotion-quay failure#5240
deepsm007 wants to merge 1 commit into
openshift:mainfrom
deepsm007:fix/promotion-prune-rollback

Conversation

@deepsm007

@deepsm007 deepsm007 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

/cc hold

Overview

This PR improves error handling and recovery in the image promotion workflow when promoting container images to Quay fails. The changes ensure that failed promotions are properly rolled back by restoring Quay floating tags from backup copies and re-syncing the OpenShift ImageStream references.

Changes to Promotion Pod Generation

The promotion step generation in pkg/steps/release/promote.go has been refactored to provide better failure recovery for Quay-based promotion operations. The key improvements include:

  • Separated mirror and post-mirror logic: The promotion pod now distinguishes between the image mirroring phase and the subsequent digest resolution/tagging phase, each with its own error handling strategy.

  • Failure recovery for mirror operations: When the initial oc image mirror command fails, the pod now restores the Quay floating tags from the prune backup images before reporting the failure.

  • Failure recovery for promotion operations: When the post-mirror tagging/promotion phase fails, the pod now:

    1. Restores the Quay floating tags from prune backup images
    2. Re-syncs the application ImageStreams by re-querying image digests from the restored Quay tags
    3. Preserves and properly propagates the original failure exit code
  • Graceful degradation: The restore and re-sync operations are best-effort and will not mask the original failure code, ensuring promotion failures are still reported but with attempted cleanup.

Test Fixture Updates

Test fixtures across four scenarios have been updated to reflect the new error handling behavior:

  • Basic Quay promotion (zz_fixture_TestGetPromotionPod_promotion_quay.yaml)
  • Quay promotion with version tags (zz_fixture_TestGetPromotionPod_promotion_quay_4.12.yaml)
  • Quay promotion with multiple tags (zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml)
  • Quay promotion in non-release namespaces (zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml)

Each fixture now includes proper exit code tracking and conditional rollback logic that mirrors the updated implementation.

Practical Impact

For CI operators using the image promotion workflow, this change provides improved reliability when promoting images to Quay registries. Failed promotion attempts will now attempt to restore a consistent state before failing, reducing the likelihood of orphaned or inconsistent image tags in both Quay and OpenShift's internal ImageStreams.

@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

openshift-ci Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@deepsm007: GitHub didn't allow me to request PR reviews from the following users: hold.

Note that only openshift members and repo collaborators can review this PR, and authors cannot review their own PRs.

Details

In response to this:

/cc hold

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.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 8, 2026
@openshift-ci

openshift-ci Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci

openshift-ci Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: deepsm007

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

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 55d118f4-ee8b-430e-b092-82ffb6cc1332

📥 Commits

Reviewing files that changed from the base of the PR and between 193fbcf and 3dc07ca.

📒 Files selected for processing (5)
  • pkg/steps/release/promote.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 as they are similar to previous changes (5)
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml
  • pkg/steps/release/promote.go
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_4.12.yaml

📝 Walkthrough

Walkthrough

Promotion pod execution now captures mirror and promotion phase exit codes separately and performs targeted rollback logic: on mirror failure, it restores quay floating tags from prune backups; on promotion failure, it restores those tags and re-syncs application ImageStreams by re-resolving digests for the tracked official quay ImageStream tag pairs.

Changes

Quay promotion pod resilience and rollback

Layer / File(s) Summary
Official ImageStream targets tracking structure
pkg/steps/release/promote.go
Introduces quayOfficialISTag struct to carry derived quay-proxy floating tags and original ImageStream tag keys, replacing prior pair tracking for later post-mirror digest resolve/tag generation and failure rollback.
Mirror and post-mirror command separation
pkg/steps/release/promote.go
Splits shell-command generation into mirrorCommands and postMirrorCommands slices; post-mirror resolve/tag retry commands are generated from official quay ImageStream targets.
Promotion pod shell-script assembly with error handling and rollback
pkg/steps/release/promote.go
Reworks shell-script assembly to compute pruneMirror separately and conditionally run prune/mirror/post-mirror with set +e/set -e for quay steps; captures exit codes and on failure restores quay floating tags from prune backups and re-syncs application ImageStreams by re-resolving digests for tracked official targets.
Test fixtures for quay promotion error handling
pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay.yaml, zz_fixture_TestGetPromotionPod_promotion_quay_4.12.yaml, zz_fixture_TestGetPromotionPod_promotion_quay_multiple_tags.yaml, zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml
Four fixtures demonstrate the generated shell script behavior; each captures mirror and promotion exit codes and on failure restores prune-backup floating tags and re-syncs ImageStream tags before propagating the original failure code.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

lgtm

Suggested reviewers

  • danilo-gemoli
🚥 Pre-merge checks | ✅ 14 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Go Error Handling ⚠️ Warning New functions use strings.LastIndex() directly in slice operations without checking for -1, violating defensive programming practices. Check if strings.LastIndex returns -1 before slicing using conditional like if idx := strings.LastIndex(...); idx != -1.
Test Structure And Quality ❓ Inconclusive The custom check specifies "Ginkgo test code" requirements, but the codebase uses standard Go table-driven tests (testing.T), not Ginkgo framework. The check is not applicable to this PR's test style. Clarify whether the check applies to standard Go tests or only Ginkgo tests, or verify the test framework used in the PR context.
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: restoring Quay prune tags and resyncing ImageStreams on promotion-quay failure, which aligns with the refactored error handling across all modified files.
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.
Test Coverage For New Features ✅ Passed Comprehensive test coverage provided: 3 unit tests for helper functions and 6 fixture-based integration tests validating error handling logic including rollback and ImageStream re-sync.
Stable And Deterministic Test Names ✅ Passed All test names in promote_test.go are static and deterministic. No Ginkgo tests, dynamic names, fmt.Sprintf, or runtime-dependent values detected in test titles.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests are added in this PR. Changes are to internal promotion logic (promote.go) and YAML test fixtures (promote_test.go data files), which use standard Go unit tests, not Ginkgo.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR does not add new Ginkgo e2e tests. It modifies release library code and unit test fixtures only; check does not apply.
Topology-Aware Scheduling Compatibility ✅ Passed PR changes ephemeral CI promotion pods with only architecture-based nodeSelector. No topology-problematic affinity, PDB, spread constraints, or control-plane targeting present.
Ote Binary Stdout Contract ✅ Passed No OTE Binary Stdout Contract violations detected. Changes modify getPromotionPod() function and test fixtures/code; no process-level stdout writes from fmt.Print, os.Stdout, or klog are present.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PR contains no new Ginkgo e2e tests—only unit test fixture updates for TestGetPromotionPod, which uses standard Go testing (testing.T), not Ginkgo.
No-Weak-Crypto ✅ Passed No weak cryptography patterns, custom crypto implementations, or insecure secret comparisons detected in code changes.
Container-Privileges ✅ Passed PR contains no privileged container configurations, host access flags, or security context escalations. Changes are limited to shell script command refactoring for error handling.
No-Sensitive-Data-In-Logs ✅ Passed Echo statements only log informational messages (retry counts, status). Credentials file path passed to commands but not echoed. No sensitive data exposed.

✏️ 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.

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/steps/release/promote.go (1)

345-358: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Rollback path is currently bypassed by exit 1 inside retry helpers.

Line [349]-[354] and Line [372]-[374] exit 1 from inside the generated retry blocks. That exits the shell before Line [517]/Line [530] can capture _mirror_exit or _promotion_exit, so the new rollback/re-sync logic never runs on retry exhaustion.

Proposed fix
 func getMirrorRetryShell(registryConfig string, images []string, loglevel int) string {
 	mirrorCmd := getMirrorCommand(registryConfig, images, loglevel)
 	n := quayPromotionMirrorAttempts
-	return fmt.Sprintf(`for r in {1..%d}; do
+	return fmt.Sprintf(`_mirror_ok=0
+for r in {1..%d}; do
   echo Mirror attempt $r
-  if %s; then break; fi
-  if [ "${r}" -eq %d ]; then
-    exit 1
+  if %s; then
+    _mirror_ok=1
+    break
   fi
-  backoff=$(($RANDOM %% 120))s
-  echo Sleeping randomized $backoff before retry
-  sleep $backoff
-done`, n, mirrorCmd, n)
+  if [ "${r}" -lt %d ]; then
+    backoff=$(($RANDOM %% 120))s
+    echo Sleeping randomized $backoff before retry
+    sleep $backoff
+  fi
+done
+[ "${_mirror_ok}" -eq 1 ]`, n, mirrorCmd, n)
 }
 
 func getResolveAndTagRetryShell(registryConfig, quayProxyTag, isTag string, loglevel int, filterByOS string) string {
@@
-	return fmt.Sprintf(`for r in {1..%d}; do
+	return fmt.Sprintf(`_tag_ok=0
+for r in {1..%d}; do
   _digest=$(oc image info --registry-config=%s --filter-by-os=%s %s | sed -n '/^Digest:[[:space:]]/s/^Digest:[[:space:]]*//p' | head -n1)
   if [ -n "${_digest}" ] && oc tag --source=docker --loglevel=%d --reference-policy='source' --import-mode='PreserveOriginal' --reference %s@${_digest} %s; then
+    _tag_ok=1
     break
   fi
   echo "promotion-quay: digest-tag failed for %s attempt ${r}/%d (QCI digest may have moved after mirror)" >&2
-  if [ "${r}" -eq %d ]; then
-    exit 1
-  fi
-  echo "promotion-quay: retrying digest-tag for %s (attempt $((r+1))/%d after randomized backoff)" >&2
-  backoff=$(($RANDOM %% %d))s
-  sleep "${backoff}"
+  if [ "${r}" -lt %d ]; then
+    echo "promotion-quay: retrying digest-tag for %s (attempt $((r+1))/%d after randomized backoff)" >&2
+    backoff=$(($RANDOM %% %d))s
+    sleep "${backoff}"
+  fi
 done
+[ "${_tag_ok}" -eq 1 ]
 `, n, registryConfig, filterByOS, quayIOTag, loglevel, repo, isTag,
 		isTag, n,
-		n,
+		n,
 		isTag, n,
 		120)
 }

As per coding guidelines, "Errors should be handled correctly - determine whether to ignore, log, wrap and raise up"—the current control flow drops the intended recovery/rollback path on failure.

Also applies to: 362-384, 514-537

🤖 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/promote.go` around lines 345 - 358, The generated retry
shells (from getMirrorRetryShell calling getMirrorCommand, and the similar retry
helpers) currently call `exit 1` on final failure which terminates the pod
before the outer logic can capture `_mirror_exit`/`_promotion_exit` and run
rollback; change those `exit 1` occurrences to set the appropriate failure
marker variable (e.g. `_mirror_exit=1` or `_promotion_exit=1`) and break out of
the loop instead of exiting, so the outer wrapper can inspect the marker and
perform rollback/resync; update getMirrorRetryShell (and the analogous retry
generator) to set the marker and break on exhaustion rather than calling `exit`.

Source: Coding guidelines

🤖 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.

Outside diff comments:
In `@pkg/steps/release/promote.go`:
- Around line 345-358: The generated retry shells (from getMirrorRetryShell
calling getMirrorCommand, and the similar retry helpers) currently call `exit 1`
on final failure which terminates the pod before the outer logic can capture
`_mirror_exit`/`_promotion_exit` and run rollback; change those `exit 1`
occurrences to set the appropriate failure marker variable (e.g.
`_mirror_exit=1` or `_promotion_exit=1`) and break out of the loop instead of
exiting, so the outer wrapper can inspect the marker and perform
rollback/resync; update getMirrorRetryShell (and the analogous retry generator)
to set the marker and break on exhaustion rather than calling `exit`.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 08940a10-6386-4b17-aa58-b19d7ed43f6b

📥 Commits

Reviewing files that changed from the base of the PR and between e6b1341 and 53918f9.

📒 Files selected for processing (5)
  • pkg/steps/release/promote.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

Copy link
Copy Markdown
Contributor Author

/test all

@deepsm007 deepsm007 force-pushed the fix/promotion-prune-rollback branch from 53918f9 to 193fbcf Compare June 9, 2026 14:32

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/steps/release/promote.go (1)

349-358: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Rollback handlers are unreachable when retry loops hit exit 1.

At Line 353 and Line 373, the generated retry loops call exit 1. In the quay flow, that exits the shell before _mirror_exit/_promotion_exit is captured, so the rollback blocks at Line 519+ and Line 532+ never run on terminal failures.

Suggested fix
-		if len(mirrorCommands) > 0 {
+		if len(mirrorCommands) > 0 {
 			parts = append(parts, "set +e")
-			parts = append(parts, mirrorCommands...)
+			parts = append(parts, fmt.Sprintf("(\n%s\n)", strings.Join(mirrorCommands, "\n")))
 			parts = append(parts, "_mirror_exit=$?", "set -e")
 			if mirrorFailureRollback != "" {
 				parts = append(parts, fmt.Sprintf(`if [ "${_mirror_exit}" -ne 0 ]; then
 %s
 exit "${_mirror_exit}"
 fi`, mirrorFailureRollback))
 			} else {
 				parts = append(parts, `if [ "${_mirror_exit}" -ne 0 ]; then exit "${_mirror_exit}"; fi`)
 			}
 		}
 		if len(postMirrorCommands) > 0 {
 			parts = append(parts, "set +e")
-			parts = append(parts, postMirrorCommands...)
+			parts = append(parts, fmt.Sprintf("(\n%s\n)", strings.Join(postMirrorCommands, "\n")))
 			parts = append(parts, "_promotion_exit=$?", "set -e")
 			if postFailureRollback != "" {
 				parts = append(parts, fmt.Sprintf(`if [ "${_promotion_exit}" -ne 0 ]; then
 %s
 fi`, postFailureRollback))
 			}
 			parts = append(parts, `exit "${_promotion_exit}"`)
 		}

Also applies to: 366-374, 515-537

🤖 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/promote.go` around lines 349 - 358, The retry loop
templates in promote.go embed "exit 1" which kills the shell and prevents trap
handlers like _mirror_exit and _promotion_exit from running; update the
generated loops (the strings that include mirrorCmd and promotionCmd built
around the variables n and mirrorCmd/promotionCmd) to use "return 1" (or "false"
if inside a subshell) instead of "exit 1" so failures return a non-zero status
to the caller and allow the caller-level traps/rollback blocks (e.g.,
_mirror_exit and _promotion_exit) to execute; apply this change to all retry
templates mentioned (the mirror/promotion retry loop generation that references
mirrorCmd/promotionCmd and n, including the other occurrences flagged around the
promotion and rollback sections).
🤖 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.

Outside diff comments:
In `@pkg/steps/release/promote.go`:
- Around line 349-358: The retry loop templates in promote.go embed "exit 1"
which kills the shell and prevents trap handlers like _mirror_exit and
_promotion_exit from running; update the generated loops (the strings that
include mirrorCmd and promotionCmd built around the variables n and
mirrorCmd/promotionCmd) to use "return 1" (or "false" if inside a subshell)
instead of "exit 1" so failures return a non-zero status to the caller and allow
the caller-level traps/rollback blocks (e.g., _mirror_exit and _promotion_exit)
to execute; apply this change to all retry templates mentioned (the
mirror/promotion retry loop generation that references mirrorCmd/promotionCmd
and n, including the other occurrences flagged around the promotion and rollback
sections).

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 323d0409-88b5-4073-9f1b-b31fcdc4b14f

📥 Commits

Reviewing files that changed from the base of the PR and between 53918f9 and 193fbcf.

📒 Files selected for processing (6)
  • Makefile
  • pkg/steps/release/promote.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 as they are similar to previous changes (2)
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_4.12.yaml
  • pkg/steps/release/testdata/zz_fixture_TestGetPromotionPod_promotion_quay_non_release_namespace.yaml

@deepsm007 deepsm007 marked this pull request as ready for review June 9, 2026 15:34
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 9, 2026
@deepsm007 deepsm007 force-pushed the fix/promotion-prune-rollback branch 2 times, most recently from 193fbcf to 3dc07ca Compare June 9, 2026 15:35
@deepsm007

Copy link
Copy Markdown
Contributor Author

/test e2e

@deepsm007

Copy link
Copy Markdown
Contributor Author

/unhold

@deepsm007

Copy link
Copy Markdown
Contributor Author

/override ci/prow/integration

Failure unrelated

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Tests from second stage were triggered manually. Pipeline can be controlled only manually, until HEAD changes. Use command to trigger second stage.

@openshift-ci

openshift-ci Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@deepsm007: Overrode contexts on behalf of deepsm007: ci/prow/integration

Details

In response to this:

/override ci/prow/integration

Failure unrelated

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.

@openshift-ci

openshift-ci Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@deepsm007: all tests passed!

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.

@deepsm007

Copy link
Copy Markdown
Contributor Author

/hold

@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 Jun 9, 2026
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.

1 participant