Skip to content

Make sync-ci-images pipeline steps best-effort#3030

Open
shruti-rh wants to merge 2 commits into
openshift-eng:mainfrom
shruti-rh:sync-ci-images-resilient
Open

Make sync-ci-images pipeline steps best-effort#3030
shruti-rh wants to merge 2 commits into
openshift-eng:mainfrom
shruti-rh:sync-ci-images-resilient

Conversation

@shruti-rh

Copy link
Copy Markdown
Contributor

Each doozer step (gen-buildconfigs, mirror, start-builds, check-upstream, prs-open) now runs independently. If one fails (e.g. missing Konflux build, missing CI image), the pipeline continues with remaining steps and returns exit code 25 (partial) instead of crashing with exit code 50.

This prevents transient or data issues in one step from blocking the entire sync workflow.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

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

Separates critical vs best-effort doozer phases in SyncCIImagesPipeline with an async step wrapper, persists SHA conditionally, always cleans the clone dir, and returns 25 on any non-critical failures; images_streams now tracks missing upstream manifests and exits 25 when images were skipped.

Changes

Best-effort sync CI images pipeline

Layer / File(s) Summary
Step wrapper
pyartcd/pyartcd/pipelines/sync_ci_images.py
Added internal async _run_step() that runs a coroutine, logs exceptions with traceback, returns True on success, returns False for non-critical failures, and re-raises when critical=True.
Docstring update
pyartcd/pyartcd/pipelines/sync_ci_images.py
Updated run() docstring to define return codes: 0 success, 25 partial/unstable completion due to non-critical step failures.
Run control flow and post-run actions
pyartcd/pyartcd/pipelines/sync_ci_images.py
Reworked run() to call doozer phases via _run_step() (marking gen-buildconfigs and mirror critical), track non-critical failures in failed_steps, persist current SHA to Redis unless dry_run and prs-open partial, always clean up the local clone dir, log failed step names if any, and return 25 when non-critical steps failed; otherwise return 0.

images_streams PR opening

Layer / File(s) Summary
State for upstream-image tracking
doozer/doozerlib/cli/images_streams.py
Adds checked_upstream_images/missing_upstream_images state and an images_skipped flag used to signal exit-25 when upstream manifests are missing.
Upstream existence helper
doozer/doozerlib/cli/images_streams.py
Extracts check_if_upstream_image_exists returning a boolean, records missing upstream images unless --ignore-missing-images is set, and avoids re-raising on lookup failures.
Desired-parent and ci_build_root resolution
doozer/doozerlib/cli/images_streams.py
Uses the helper during builder-parent resolution and ci_build_root resolution; on missing upstream manifests sets images_skipped and aborts processing that image.
Exit guard for skipped images
doozer/doozerlib/cli/images_streams.py
Adds final guard to exit with code 25 when images_skipped is true, indicating PR opening was skipped due to missing upstream manifests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (1)
pyartcd/pyartcd/pipelines/sync_ci_images.py (1)

609-619: 💤 Low value

Add type hint for coro parameter.

The coro parameter lacks a type annotation, reducing IDE support and documentation clarity.

+from typing import Coroutine, Any
+
-    async def _run_step(self, name: str, coro) -> bool:
+    async def _run_step(self, name: str, coro: Coroutine[Any, Any, Any]) -> bool:
🤖 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 `@pyartcd/pyartcd/pipelines/sync_ci_images.py` around lines 609 - 619, The
_run_step method's coro parameter is untyped; add a proper typing annotation
(e.g., coro: Awaitable[Any] or coro: Coroutine[Any, Any, Any]) and import the
corresponding symbol from typing at the top of the module so IDEs and linters
know this is an awaitable; update the signature of _run_step(name: str, coro) ->
bool to _run_step(self, name: str, coro: Awaitable[Any]) -> bool (or use
Coroutine[Any, Any, Any]) and ensure the import (from typing import Awaitable,
Any) is added.
🤖 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 `@pyartcd/pyartcd/pipelines/sync_ci_images.py`:
- Around line 675-676: _prs-open's special return code (25) is ignored because
_run_step only treats exceptions as failures; call
_open_reconciliation_prs(doozer_opts) directly for the 'prs-open' step, capture
its return code, and if it returns 25 append 'prs-open' to failed_steps and skip
the Redis update path (i.e., preserve the "don't update Redis on partial
success" behavior) otherwise treat success normally; this change touches the
'prs-open' invocation (replace the _run_step wrapper), the
_open_reconciliation_prs function return handling, and the code that updates
Redis after steps to ensure Redis is only updated when no partial-success rc==25
occurred.

---

Nitpick comments:
In `@pyartcd/pyartcd/pipelines/sync_ci_images.py`:
- Around line 609-619: The _run_step method's coro parameter is untyped; add a
proper typing annotation (e.g., coro: Awaitable[Any] or coro: Coroutine[Any,
Any, Any]) and import the corresponding symbol from typing at the top of the
module so IDEs and linters know this is an awaitable; update the signature of
_run_step(name: str, coro) -> bool to _run_step(self, name: str, coro:
Awaitable[Any]) -> bool (or use Coroutine[Any, Any, Any]) and ensure the import
(from typing import Awaitable, Any) is added.
🪄 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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 1351eede-73f5-4e6a-a763-b29ef83c34b2

📥 Commits

Reviewing files that changed from the base of the PR and between 717d239 and 9e79e97.

📒 Files selected for processing (1)
  • pyartcd/pyartcd/pipelines/sync_ci_images.py

Comment thread pyartcd/pyartcd/pipelines/sync_ci_images.py Outdated
@locriandev

Copy link
Copy Markdown
Contributor

The pipeline has a dependency chain where gen-buildconfigs generates and applies BuildConfigs to the CI cluster, then mirror copies builder and base images to CI registries, then start-builds triggers CI builds, wait pauses for build completion, check-upstream verifies imagestream consistency, and finally prs-open creates reconciliation PRs.

The gen-buildconfigs step is critical because without BuildConfigs applied to the cluster, there is nothing for downstream steps to build, mirror, or verify. If this fails, downstream steps will either fail or operate on stale state. This step should raise an exception and abort the pipeline.

The mirror step is also critical because builds need these images to execute. If mirroring fails, builds will fail with image pull errors. This step should also raise an exception and abort the pipeline.

The start-builds step can be best-effort because builds might already exist from previous runs, and missing Konflux builds should not block the entire workflow. If this fails, the pipeline can still verify existing state and open remediation PRs. The step should log a warning and continue.

The check-upstream step can be best-effort because this is validation, not a prerequisite for remediation. Even if verification fails, PRs can still be opened to fix drift. The step should log a warning and continue.

The prs-open step can be best-effort because it already returns rc=25 for partial success. If this fails, the pipeline can still mark the run as successful. The step should log a warning and return rc=25.

Modified _run_step() method:

async def _run_step(self, name: str, coro, critical: bool = False) -> bool:
"""
Run a pipeline step, catching and logging errors.

Args:
    name: Step name for logging
    coro: Async coroutine to execute
    critical: If True, re-raise exception after logging (hard failure)

Returns:
    True if the step succeeded, False if it failed.
    
Raises:
    Exception: If critical=True and step fails
"""
try:
    await coro
    return True
except Exception as e:
    self._logger.warning('%s: Step "%s" failed: %s', self.version, name, e, exc_info=True)
    if critical:
        self._logger.error('%s: Critical step "%s" failed, aborting pipeline', self.version, name)
        raise
    return False

Modified run() method:

async def run(self) -> int:
"""
Main pipeline: sync CI images for a single OCP version.

Critical steps (gen-buildconfigs, mirror) must succeed or the pipeline aborts.
Other steps (start-builds, check-upstream, prs-open) are best-effort: if one
fails (e.g. missing Konflux build, transient CI issue), the pipeline continues
with remaining steps and returns 25 (partial/unstable).

Workflow:
1. Check for changes in ocp-build-data
2. Generate and apply BuildConfigs to CI cluster [CRITICAL]
3. Mirror builder/base images to CI registries [CRITICAL]
4. Trigger CI builds [best-effort]
5. Wait for builds to complete
6. Verify upstream imagestream consistency [best-effort]
7. Open PRs to reconcile any BuildConfig drift [best-effort]

Returns:
    Return code: 0=success, 25=partial (some non-critical steps failed), 50=failure
"""
jenkins.update_title(f' [{self.version}]')
self._logger.info(f"Starting sync-ci-images for {self.version}")

group_dir = None

try:
    has_changes, current_sha = await self._check_for_changes()
    if not has_changes:
        return 0

    group_dir = await self._prepare_build_data()

    failed_steps = []
    with self._create_registry_config() as auth_file:
        self._logger.info(f"Created registry config: {auth_file}")
        doozer_opts = self._build_doozer_options(group_dir, auth_file)

        await self._run_step(
            'gen-buildconfigs',
            self._generate_and_apply_buildconfigs(doozer_opts),
            critical=True
        )

        await self._run_step(
            'mirror',
            self._mirror_images_to_ci(doozer_opts, auth_file),
            critical=True
        )

        if not await self._run_step('start-builds', self._trigger_ci_builds(doozer_opts)):
            failed_steps.append('start-builds')

        await self._wait_for_builds()

        if not await self._run_step('check-upstream', self._verify_upstream_consistency(doozer_opts)):
            failed_steps.append('check-upstream')

        if not await self._run_step('prs-open', self._open_reconciliation_prs(doozer_opts)):
            failed_steps.append('prs-open')

    await self._record_successful_run(current_sha)
    self._cleanup(group_dir)

    if failed_steps:
        self._logger.warning(
            '%s: Completed with errors in non-critical steps: %s',
            self.version,
            ', '.join(failed_steps),
        )
        return 25

    return 0

except Exception as e:
    self._logger.error(f"{self.version}: Failed with error: {e}", exc_info=True)
    self._cleanup(group_dir)
    raise

The key change from the current PR is adding a critical parameter to _run_step() to distinguish hard failures from soft failures. The gen-buildconfigs and mirror steps use critical=True because they are prerequisites for downstream operations, while start-builds, check-upstream, and prs-open continue to be best-effort. The updated docstring clarifies which steps are critical versus best-effort, and the logging distinguishes non-critical steps in the warning message.

The PR goal of preventing transient or data issues from blocking the workflow is valid for missing Konflux builds in start-builds, missing CI images in check-upstream, and PR failures in prs-open. However, BuildConfig generation failures mean there is no sync to perform, and mirror failures mean builds cannot pull base images, so these should remain hard failures that abort the pipeline.

@locriandev locriandev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/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 8, 2026
@openshift-ci

openshift-ci Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from locriandev. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found 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

@shruti-rh shruti-rh requested a review from locriandev June 8, 2026 14:11

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (2)
pyartcd/pyartcd/pipelines/sync_ci_images.py (2)

692-693: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Stale comment at line 586 contradicts new behavior.

Line 586 states "Don't update Redis on partial success - retry on next run", but line 692-693 now explicitly updates Redis even when failed_steps is non-empty. The comment at line 586 should be removed or updated to reflect the new intent.

Suggested fix at line 586
         if rc == 25:
             self._logger.warning(f"{self.version}: Some PRs skipped (rc=25)")
-            return 25  # Don't update Redis on partial success - retry on next run
+            return 25
🤖 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 `@pyartcd/pyartcd/pipelines/sync_ci_images.py` around lines 692 - 693, The
comment "Don't update Redis on partial success - retry on next run" is stale
because the code now calls await self._record_successful_run(current_sha) even
when failed_steps is non-empty; remove or update that comment near the
failed_steps handling to reflect the new intent (either delete the line or
change wording to indicate that partial successes are recorded to prevent
re-running the same SHA), and ensure references around the failed_steps variable
and the _record_successful_run(current_sha) call remain consistent.

776-778: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

**CLI docstring inconsistent with run() semantics.**The CLI docstring at lines 776-778 describes rc=25 as "some PRs were skipped", but the run() method's docstring (line 653) now defines 25 as "partial (non-critical steps failed)". Update the CLI docstring to match the broader semantics.

Suggested fix
     Return codes:
-        25: Partial success (some PRs were skipped)
+        25: Partial/unstable (non-critical steps failed)
🤖 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 `@pyartcd/pyartcd/pipelines/sync_ci_images.py` around lines 776 - 778, Update
the CLI docstring in sync_ci_images.py so its exit-code descriptions match the
run() method's semantics: replace the line "25: Partial success (some PRs were
skipped)" with a description that matches run()'s docstring (e.g., "25: Partial
(non-critical steps failed)" or similar wording). Locate the CLI/help docstring
block that lists the numeric exit codes and align the text for code 25 with the
run() method's explanation found in run(). Ensure the wording is consistent and
clear across both docstrings.
🤖 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 `@pyartcd/pyartcd/pipelines/sync_ci_images.py`:
- Around line 692-693: The comment "Don't update Redis on partial success -
retry on next run" is stale because the code now calls await
self._record_successful_run(current_sha) even when failed_steps is non-empty;
remove or update that comment near the failed_steps handling to reflect the new
intent (either delete the line or change wording to indicate that partial
successes are recorded to prevent re-running the same SHA), and ensure
references around the failed_steps variable and the
_record_successful_run(current_sha) call remain consistent.
- Around line 776-778: Update the CLI docstring in sync_ci_images.py so its
exit-code descriptions match the run() method's semantics: replace the line "25:
Partial success (some PRs were skipped)" with a description that matches run()'s
docstring (e.g., "25: Partial (non-critical steps failed)" or similar wording).
Locate the CLI/help docstring block that lists the numeric exit codes and align
the text for code 25 with the run() method's explanation found in run(). Ensure
the wording is consistent and clear across both docstrings.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 6421bd4c-634d-4709-9452-18a8c34feb0a

📥 Commits

Reviewing files that changed from the base of the PR and between 9e79e97 and af0b698.

📒 Files selected for processing (1)
  • pyartcd/pyartcd/pipelines/sync_ci_images.py

@shruti-rh shruti-rh force-pushed the sync-ci-images-resilient branch 4 times, most recently from f9adc73 to b187252 Compare June 10, 2026 07:44
Each doozer step (gen-buildconfigs, mirror, start-builds,
check-upstream, prs-open) now runs independently. If one fails
(e.g. missing Konflux build, missing CI image), the pipeline
continues with remaining steps and returns exit code 25 (partial)
instead of crashing with exit code 50.

This prevents transient or data issues in one step from blocking
the entire sync workflow.

Signed-off-by: Shruti Anekar <sanekar@redhat.com>
rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED
@shruti-rh shruti-rh force-pushed the sync-ci-images-resilient branch from b187252 to a5f93ff Compare June 10, 2026 09:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@doozer/doozerlib/cli/images_streams.py`:
- Around line 1921-1923: The primary parent_upstream_image is never validated —
add a check using check_if_upstream_image_exists(parent_upstream_image) before
appending it or proceeding to open PRs; if the check fails, set images_skipped
(or mirror the existing failure path) and break/return or call exit(25)
consistent with the builder-parent handling so the final parent manifest absence
triggers the same skip/exit behavior as the other upstream_image checks.
- Around line 1882-1894: check_if_upstream_image_exists currently swallows all
exceptions from util.oc_image_info_for_arch(upstream_image) and treats them as
"missing", which hides real oc/auth/network errors; change the logic to call
util.oc_image_info_for_arch(upstream_image, strict=False) and if it returns None
treat the image as missing, but let real exceptions propagate (or handle/log
them separately) instead of mapping them to missing_upstream_images;
additionally, ensure the same existence check/gating is applied to
parent_upstream_image resolved from from_config (i.e., pass
parent_upstream_image through check_if_upstream_image_exists the same way you do
for desired_ci_build_root_image and builder-derived upstream images so a missing
parent manifest is caught and added to missing_upstream_images).
🪄 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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 8e99c0cd-c012-4d21-b949-34d5aad4aa9b

📥 Commits

Reviewing files that changed from the base of the PR and between ebcdceb and a5f93ff.

📒 Files selected for processing (2)
  • doozer/doozerlib/cli/images_streams.py
  • pyartcd/pyartcd/pipelines/sync_ci_images.py

Comment on lines +1882 to +1894
util.oc_image_info_for_arch(upstream_image)
checked_upstream_images.add(upstream_image)
return True
except Exception:
yellow_print(
f'Unable to access upstream image {upstream_image} for {dgk}'
' -- check whether buildconfigs are running successfully.'
)
checked_upstream_images.add(upstream_image)
if ignore_missing_images:
return True
missing_upstream_images.add(upstream_image)
return False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify API behavior and call pattern for manifest-missing handling
rg -n -C3 'def oc_image_info_for_arch|strict:\s*bool\s*=\s*True|manifest unknown' artcommon/artcommonlib/util.py
rg -n -C3 'check_if_upstream_image_exists|oc_image_info_for_arch\(' doozer/doozerlib/cli/images_streams.py

Repository: openshift-eng/art-tools

Length of output: 4687


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the exact helper and the nearby builder/parent resolution logic
sed -n '1820,1965p' doozer/doozerlib/cli/images_streams.py

# Locate any other uses of parent_upstream_image / oc_image_info_for_arch in this file
rg -n "parent_upstream_image|desired_parents|check_if_upstream_image_exists\(|oc_image_info_for_arch\(" doozer/doozerlib/cli/images_streams.py

Repository: openshift-eng/art-tools

Length of output: 8827


Don’t downgrade non-manifest oc failures to “missing image”, and gate parent_upstream_image too

  • check_if_upstream_image_exists() catches broad Exception around util.oc_image_info_for_arch(upstream_image), but oc_image_info_for_arch(..., strict=False) is specifically designed to return None only for “manifest unknown”; other failures (auth/network/oc errors) should raise instead of being treated as missing (line ~1885).
  • Existence gating is applied for builder-derived upstream images and desired_ci_build_root_image, but not for parent_upstream_image resolved from from_config, so a missing parent manifest can slip through despite the skip-gating intent.
Proposed fix (for the broad exception handling)
-            try:
-                util.oc_image_info_for_arch(upstream_image)
-                checked_upstream_images.add(upstream_image)
-                return True
-            except Exception:
-                yellow_print(
-                    f'Unable to access upstream image {upstream_image} for {dgk}'
-                    ' -- check whether buildconfigs are running successfully.'
-                )
-                checked_upstream_images.add(upstream_image)
-                if ignore_missing_images:
-                    return True
-                missing_upstream_images.add(upstream_image)
-                return False
+            info = util.oc_image_info_for_arch(upstream_image, strict=False)
+            checked_upstream_images.add(upstream_image)
+            if info is not None:
+                return True
+
+            yellow_print(
+                f'Unable to find upstream image manifest {upstream_image} for {dgk}'
+                ' -- check whether buildconfigs are running successfully.'
+            )
+            if ignore_missing_images:
+                return True
+            missing_upstream_images.add(upstream_image)
+            return False
📝 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
util.oc_image_info_for_arch(upstream_image)
checked_upstream_images.add(upstream_image)
return True
except Exception:
yellow_print(
f'Unable to access upstream image {upstream_image} for {dgk}'
' -- check whether buildconfigs are running successfully.'
)
checked_upstream_images.add(upstream_image)
if ignore_missing_images:
return True
missing_upstream_images.add(upstream_image)
return False
info = util.oc_image_info_for_arch(upstream_image, strict=False)
checked_upstream_images.add(upstream_image)
if info is not None:
return True
yellow_print(
f'Unable to find upstream image manifest {upstream_image} for {dgk}'
' -- check whether buildconfigs are running successfully.'
)
if ignore_missing_images:
return True
missing_upstream_images.add(upstream_image)
return False
🧰 Tools
🪛 Ruff (0.15.15)

[warning] 1885-1885: Do not catch blind exception: Exception

(BLE001)


[warning] 1887-1887: Function definition does not bind loop variable dgk

(B023)

🤖 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 `@doozer/doozerlib/cli/images_streams.py` around lines 1882 - 1894,
check_if_upstream_image_exists currently swallows all exceptions from
util.oc_image_info_for_arch(upstream_image) and treats them as "missing", which
hides real oc/auth/network errors; change the logic to call
util.oc_image_info_for_arch(upstream_image, strict=False) and if it returns None
treat the image as missing, but let real exceptions propagate (or handle/log
them separately) instead of mapping them to missing_upstream_images;
additionally, ensure the same existence check/gating is applied to
parent_upstream_image resolved from from_config (i.e., pass
parent_upstream_image through check_if_upstream_image_exists the same way you do
for desired_ci_build_root_image and builder-derived upstream images so a missing
parent manifest is caught and added to missing_upstream_images).

Source: Linters/SAST tools

Comment thread doozer/doozerlib/cli/images_streams.py
rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED

Signed-off-by: Shruti Anekar <sanekar@redhat.com>
@shruti-rh shruti-rh force-pushed the sync-ci-images-resilient branch from 24b30d4 to 6072ca8 Compare June 10, 2026 14:17
@openshift-ci

openshift-ci Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

@shruti-rh: 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/security 6072ca8 link false /test security

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

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.

2 participants