Skip to content

ART-21775: add doozer beta:release-payload:rebase-and-build command - #3218

Draft
ashwindasr wants to merge 4 commits into
openshift-eng:mainfrom
ashwindasr:ART-21775-release-payload-rebase-and-build
Draft

ART-21775: add doozer beta:release-payload:rebase-and-build command#3218
ashwindasr wants to merge 4 commits into
openshift-eng:mainfrom
ashwindasr:ART-21775-release-payload-rebase-and-build

Conversation

@ashwindasr

@ashwindasr ashwindasr commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the doozer rebase+build flow described in ART-21775 (part of the ART-14237 epic to build named release payloads in Konflux instead of running oc adm release new --to-image directly on buildvm).

Adds a new doozer beta:release-payload:rebase-and-build command that:

  • Runs oc adm release new --to-dir to snapshot the release manifests already populated in the group's build-sync imagestream (imagestream name/namespace derived automatically from --group/--assembly, or optionally sourced from an existing release pullspec via --from-release)
  • Resolves the cluster-version-operator pullspec from the generated image-references manifest
  • Writes a minimal Dockerfile (FROM <cvo-pullspec> + COPY release-manifests/ /release-manifests/)
  • Pushes the rebased content to openshift-priv/ocp-release-payloads on a per-group/assembly branch, reusing BuildRepo
  • Ensures the Konflux Application/Component exist and triggers a PipelineRun via KonfluxClient, reusing existing Konflux build infrastructure
  • Supports --push (git push + Konflux build vs. local-only rebase), --dry-run (skip actual git pushes / Konflux API calls), and --output json for machine-parseable results

Konflux builds a single multi-arch manifest list per PipelineRun, so this command determines all supported architectures from the group config (runtime.get_global_konflux_arches()) and passes them as building_arches. The --arch flag only selects which brew-arch imagestream to source manifests from (e.g. ocp vs ocp-s390x).

Test plan

  • Added unit tests in doozer/tests/cli/test_release_payload.py covering naming helpers, imagestream resolution, manifest generation (success + error cases), rebase (Dockerfile/commit), build (Konflux API + outcome handling), and the top-level run() flow (--push/--dry-run interactions, error propagation)
  • uv run pytest doozer/tests/cli/test_release_payload.py -- 21 passed
  • uv run pytest doozer/tests/ -- full doozer suite passes (1451 passed, 15 skipped)
  • uv run ruff check / uv run ruff format --check pass on all new/modified files

Summary by CodeRabbit

  • New Features

    • Added a command to rebase OpenShift release payloads and optionally build them in Konflux.
    • Supports dry runs, configurable repositories and registries, architecture selection, branch publishing, and JSON-formatted output.
    • Validates generated release manifests and reports source image, configuration, and build errors clearly.
    • Supports monitoring multi-architecture builds and handling disabled assemblies.
  • Tests

    • Added comprehensive coverage for rebasing, manifest validation, building, error handling, architecture selection, publishing, and dry-run behavior.

Adds a new doozer CLI command that generates release payload manifests
via `oc adm release new --to-dir`, writes a Dockerfile layering those
manifests onto the cluster-version-operator image, pushes the result to
openshift-priv/ocp-release-payloads, and triggers a Konflux build of the
release payload image. Reuses BuildRepo for git operations and
KonfluxClient for Application/Component/PipelineRun management.

Co-authored-by: Cursor <cursoragent@cursor.com>

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED
@openshift-ci

openshift-ci Bot commented Aug 2, 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-robot

openshift-ci-robot commented Aug 2, 2026

Copy link
Copy Markdown

@ashwindasr: This pull request references ART-21775 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:

Summary

Implements the doozer rebase+build flow described in ART-21775 (part of the ART-14237 epic to build named release payloads in Konflux instead of running oc adm release new --to-image directly on buildvm).

Adds a new doozer beta:release-payload:rebase-and-build command that:

  • Runs oc adm release new --to-dir to snapshot the release manifests already populated in the group's build-sync imagestream (imagestream name/namespace derived automatically from --group/--assembly, or optionally sourced from an existing release pullspec via --from-release)
  • Resolves the cluster-version-operator pullspec from the generated image-references manifest
  • Writes a minimal Dockerfile (FROM <cvo-pullspec> + COPY release-manifests/ /release-manifests/)
  • Pushes the rebased content to openshift-priv/ocp-release-payloads on a per-group/assembly branch, reusing BuildRepo
  • Ensures the Konflux Application/Component exist and triggers a PipelineRun via KonfluxClient, reusing existing Konflux build infrastructure
  • Supports --push (git push + Konflux build vs. local-only rebase), --dry-run (skip actual git pushes / Konflux API calls), and --output json for machine-parseable results

Konflux builds a single multi-arch manifest list per PipelineRun, so this command determines all supported architectures from the group config (runtime.get_global_konflux_arches()) and passes them as building_arches. The --arch flag only selects which brew-arch imagestream to source manifests from (e.g. ocp vs ocp-s390x).

Test plan

  • Added unit tests in doozer/tests/cli/test_release_payload.py covering naming helpers, imagestream resolution, manifest generation (success + error cases), rebase (Dockerfile/commit), build (Konflux API + outcome handling), and the top-level run() flow (--push/--dry-run interactions, error propagation)
  • uv run pytest doozer/tests/cli/test_release_payload.py -- 21 passed
  • uv run pytest doozer/tests/ -- full doozer suite passes (1451 passed, 15 skipped)
  • uv run ruff check / uv run ruff format --check pass on all new/modified files

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 do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 2, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Aug 2, 2026
@openshift-ci

openshift-ci Bot commented Aug 2, 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 assign locriandev for approval. 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

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: openshift-eng/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2610261c-7111-45fc-b455-a833e017f300

📥 Commits

Reviewing files that changed from the base of the PR and between 0d613e7 and 9986179.

📒 Files selected for processing (2)
  • doozer/doozerlib/cli/release_payload.py
  • doozer/tests/cli/test_release_payload.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • doozer/tests/cli/test_release_payload.py
  • doozer/doozerlib/cli/release_payload.py

Walkthrough

Changes

The PR adds a CLI command that generates OpenShift release payload manifests, commits them to a source repository, and optionally starts and monitors a multi-architecture Konflux build. It also adds constants, command registration, configuration options, error handling, and tests.

Release payload workflow

Layer / File(s) Summary
Manifest generation and validation
doozer/doozerlib/cli/release_payload.py, doozer/tests/cli/test_release_payload.py
The CLI resolves imagestreams, runs oc adm release new, validates the image-references manifest, and extracts the CVO pullspec. Tests cover release inputs, architectures, command arguments, and validation errors.
Repository rebase and commit
doozer/doozerlib/cli/release_payload.py, doozer/doozerlib/constants.py, doozer/tests/cli/test_release_payload.py
The CLI removes stale repository content, writes the Dockerfile and manifests, and commits the generated sources. Constants define the working directory and source repository.
Konflux build orchestration
doozer/doozerlib/cli/release_payload.py, doozer/tests/cli/test_release_payload.py
The CLI configures the Konflux application and component, starts a hermetic multi-architecture PipelineRun, waits for completion, and returns build metadata.
CLI wiring and execution
doozer/doozerlib/cli/__main__.py, doozer/doozerlib/cli/release_payload.py, doozer/tests/cli/test_release_payload.py
The command exposes release, repository, registry, Konflux, push, dry-run, and JSON options. It validates runtime state, handles failures, and emits results.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ReleasePayloadRebaseAndBuildCli
  participant OpenShiftCLI
  participant GitRepository
  participant Konflux
  User->>ReleasePayloadRebaseAndBuildCli: invoke release_payload_rebase_and_build
  ReleasePayloadRebaseAndBuildCli->>OpenShiftCLI: generate and validate release manifests
  OpenShiftCLI-->>ReleasePayloadRebaseAndBuildCli: return image-references and CVO pullspec
  ReleasePayloadRebaseAndBuildCli->>GitRepository: write and commit payload sources
  GitRepository-->>ReleasePayloadRebaseAndBuildCli: return committed repository
  ReleasePayloadRebaseAndBuildCli->>Konflux: start multi-architecture PipelineRun
  Konflux-->>ReleasePayloadRebaseAndBuildCli: return build outcome
  ReleasePayloadRebaseAndBuildCli-->>User: emit JSON or human-readable result
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error The CLI logs full commands, CVO pullspecs, repository URLs, and Konflux URLs, exposing user-supplied values and the internal Konflux hostname. Redact credentials and internal hostnames; log only safe identifiers instead of full commands, pullspecs, repository URLs, and pipeline URLs.
Ai-Attribution ⚠️ Warning The four release-payload commits identify Cursor with Co-authored-by trailers, but none has an Assisted-by or Generated-by trailer. Replace each AI Co-authored-by: Cursor trailer with the required Red Hat Assisted-by or Generated-by trailer, and do not use Co-Authored-By for AI tools.
✅ Passed checks (9 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the new doozer release payload rebase-and-build command, which is the main change in the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
No-Weak-Crypto ✅ Passed PR code uses no MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB, custom crypto, or secret/token comparisons; only SHA256 image digests appear in fixtures.
Container-Privileges ✅ Passed The complete PR diff adds no privileged, hostPID, hostNetwork, hostIPC, SYS_ADMIN, allowPrivilegeEscalation, or root security settings.
No-Hardcoded-Secrets ✅ Passed Feature additions contain no API keys, tokens, passwords, private keys, credential-bearing URLs, or base64 literals; auth uses file paths and KONFLUX_SA_KUBECONFIG.
No-Injection-Vectors ✅ Passed The new CLI uses yaml.safe_load and passes oc/git commands as argument lists to create_subprocess_exec; no SQL concatenation, shell=True, eval/exec, pickle.loads, or os.system was found.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

🧹 Nitpick comments (6)
doozer/doozerlib/cli/release_payload.py (3)

207-208: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer a domain exception over IOError for this precondition.

The missing commit is a programming or workflow error, not an I/O failure. DoozerFatalError is already imported and is used for the other fatal conditions in this file. A change also requires an update to test_build_raises_without_commit in doozer/tests/cli/test_release_payload.py.

♻️ Proposed change
         if not build_repo.commit_hash:
-            raise IOError("Release payload repository must have a commit to build. Did you rebase?")
+            raise DoozerFatalError("Release payload repository must have a commit to build. Did you rebase?")
🤖 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/release_payload.py` around lines 207 - 208, Replace the
IOError raised by the missing-commit precondition in the release payload build
flow with the already imported DoozerFatalError, preserving the existing
message. Update test_build_raises_without_commit to expect DoozerFatalError
instead of IOError.

273-273: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Replace the assert with an explicit check.

Python removes assert statements when the interpreter runs with -O. If group_config is None, the failure then moves to a later AttributeError. Raise an explicit error instead.

♻️ Proposed change
-        assert runtime.group_config is not None, "group_config is not loaded; Doozer bug?"
+        if runtime.group_config is None:
+            raise DoozerFatalError("group_config is not loaded; Doozer bug?")
🤖 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/release_payload.py` at line 273, Replace the assert
guarding runtime.group_config with an explicit None check that raises an
appropriate error using the existing diagnostic message, ensuring the failure
occurs even when Python runs with optimizations.

485-491: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Log the exception before you exit for JSON output.

The --output json branch replaces the exception with str(e) and exits. The traceback is then lost. Log the exception first so failures stay diagnosable in CI.

Note: the static analysis hint that recommends jsonify targets Flask responses. It does not apply to this Click command.

♻️ Proposed change
     except Exception as e:
         if output == 'json':
+            LOGGER.exception("Release payload rebase and build failed")
             click.echo(json.dumps({"error": str(e)}, indent=2))
             sys.exit(1)
         raise
🤖 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/release_payload.py` around lines 485 - 491, Update the
exception handler around cli_obj.run so the JSON-output branch logs the caught
exception, including traceback details, before emitting the JSON error and
exiting. Preserve the existing non-JSON behavior that re-raises the exception,
and do not replace Click output handling with Flask-specific jsonify.

Source: Linters/SAST tools

doozer/tests/cli/test_release_payload.py (3)

144-146: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Strengthen the negative assertion.

assertNotIn("--from-image-stream=4.21-konflux-art-latest", cmd) passes even if the command contains a different --from-image-stream value. Assert that no --from-image-stream argument exists at all.

♻️ Proposed change
         cmd = mock_cmd_assert_async.call_args.args[0]
         self.assertIn("--from-release=registry.example.com/ocp/release:4.21.0", cmd)
-        self.assertNotIn("--from-image-stream=4.21-konflux-art-latest", cmd)
+        self.assertFalse([arg for arg in cmd if str(arg).startswith("--from-image-stream")])
+        self.assertNotIn("--reference-mode=source", cmd)
🤖 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/tests/cli/test_release_payload.py` around lines 144 - 146, Strengthen
the assertions around cmd in the release payload test by verifying that no
argument with the --from-image-stream option exists, regardless of its value;
retain the existing assertion for the expected --from-release argument.

340-340: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Avoid the hardcoded /tmp path in the mock attribute.

Ruff reports S108 on this line. The value is only used in a log message, so a neutral placeholder removes the finding without changing test behavior.

♻️ Proposed change
-        self.build_repo.local_dir = "/tmp/release-payload"
+        self.build_repo.local_dir = Path(tempfile.gettempdir(), "release-payload")
🤖 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/tests/cli/test_release_payload.py` at line 340, Replace the hardcoded
/tmp/release-payload value assigned to self.build_repo.local_dir with a neutral
non-filesystem placeholder, preserving its use in the log message and the test’s
behavior.

Source: Linters/SAST tools


343-442: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding a test for the Click command wrapper.

The tests cover ReleasePayloadRebaseAndBuildCli well. They do not cover release_payload_rebase_and_build. A CliRunner test would confirm the KONFLUX_SA_KUBECONFIG fallback, the --output json payload, and the exit code 1 on failure.

🤖 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/tests/cli/test_release_payload.py` around lines 343 - 442, Add a
CliRunner-based test for the release_payload_rebase_and_build command wrapper,
covering KONFLUX_SA_KUBECONFIG fallback behavior, JSON output via --output json,
and exit code 1 when the command fails. Reuse the existing
ReleasePayloadRebaseAndBuildCli test fixtures and mock the underlying execution
so the test verifies wrapper behavior without performing real rebases or builds.
🤖 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 `@doozer/doozerlib/cli/release_payload.py`:
- Around line 207-208: Replace the IOError raised by the missing-commit
precondition in the release payload build flow with the already imported
DoozerFatalError, preserving the existing message. Update
test_build_raises_without_commit to expect DoozerFatalError instead of IOError.
- Line 273: Replace the assert guarding runtime.group_config with an explicit
None check that raises an appropriate error using the existing diagnostic
message, ensuring the failure occurs even when Python runs with optimizations.
- Around line 485-491: Update the exception handler around cli_obj.run so the
JSON-output branch logs the caught exception, including traceback details,
before emitting the JSON error and exiting. Preserve the existing non-JSON
behavior that re-raises the exception, and do not replace Click output handling
with Flask-specific jsonify.

In `@doozer/tests/cli/test_release_payload.py`:
- Around line 144-146: Strengthen the assertions around cmd in the release
payload test by verifying that no argument with the --from-image-stream option
exists, regardless of its value; retain the existing assertion for the expected
--from-release argument.
- Line 340: Replace the hardcoded /tmp/release-payload value assigned to
self.build_repo.local_dir with a neutral non-filesystem placeholder, preserving
its use in the log message and the test’s behavior.
- Around line 343-442: Add a CliRunner-based test for the
release_payload_rebase_and_build command wrapper, covering KONFLUX_SA_KUBECONFIG
fallback behavior, JSON output via --output json, and exit code 1 when the
command fails. Reuse the existing ReleasePayloadRebaseAndBuildCli test fixtures
and mock the underlying execution so the test verifies wrapper behavior without
performing real rebases or builds.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift-eng/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e9281ac1-9e04-4ccc-bf9d-1c90268e3e1c

📥 Commits

Reviewing files that changed from the base of the PR and between 338d943 and 8fab520.

📒 Files selected for processing (4)
  • doozer/doozerlib/cli/__main__.py
  • doozer/doozerlib/cli/release_payload.py
  • doozer/doozerlib/constants.py
  • doozer/tests/cli/test_release_payload.py

Use a single shared Application (release-payloads) for all release payload
builds, and scope the per-group Component name (release-payload-<group>)
underneath it, rather than having a separate Application per group.

Co-authored-by: Cursor <cursoragent@cursor.com>

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED

@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

🤖 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/release_payload.py`:
- Around line 100-107: Update get_component_name so distinct group names
containing "." and "_" cannot produce the same Component name; either validate
and reject ambiguous group names before formatting or encode these separators
bijectively while preserving the existing release-payload prefix and valid-name
requirements.
🪄 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: openshift-eng/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 21648ec5-0e61-4b6d-ad51-125c66146342

📥 Commits

Reviewing files that changed from the base of the PR and between 8fab520 and 253d073.

📒 Files selected for processing (2)
  • doozer/doozerlib/cli/release_payload.py
  • doozer/tests/cli/test_release_payload.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • doozer/tests/cli/test_release_payload.py

Comment on lines +100 to +107
def get_component_name(group: str) -> str:
"""Konflux Component name for a group's release payload builds.

There is a single Component per group underneath the shared `release-payloads`
Application (Konflux builds all architectures as one multi-arch manifest list from
a single PipelineRun per group/assembly), e.g. `release-payload-openshift-4-21`.
"""
return f"release-payload-{group}".replace(".", "-").replace("_", "-")

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.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 12 \
  '\b(get_component_name|construct_dest_branch|ensure_component|start_pipeline_run_for_image_build|revision|commit_sha|git_url)\b' \
  --glob '*.py' .

Repository: openshift-eng/art-tools

Length of output: 50380


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- release_payload.py outline ---'
ast-grep outline doozer/doozerlib/cli/release_payload.py

printf '%s\n' '--- relevant implementation ---'
sed -n '1,260p' doozer/doozerlib/cli/release_payload.py

printf '%s\n' '--- exact call sites and definitions ---'
rg -n -C 8 \
  'def get_component_name|get_component_name\(|def construct_dest_branch|construct_dest_branch\(|def ensure_component|ensure_component\(|def start_pipeline_run_for_image_build|start_pipeline_run_for_image_build\(' \
  doozer/doozerlib doozer/tests

Repository: openshift-eng/art-tools

Length of output: 50379


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- branch construction ---'
rg -n -C 10 'def construct_dest_branch|construct_dest_branch\(' doozer/doozerlib/backend/rebaser.py doozer/doozerlib doozer/tests \
  | head -n 220

printf '%s\n' '--- Konflux component and PipelineRun implementations ---'
rg -n -C 14 'async def ensure_component|def ensure_component|async def start_pipeline_run_for_image_build|def start_pipeline_run_for_image_build' \
  doozer/doozerlib/backend/konflux_client.py artcommonlib 2>/dev/null | head -n 360

printf '%s\n' '--- release payload tests and group/assembly inputs ---'
sed -n '1,180p' doozer/tests/cli/test_release_payload.py
rg -n --glob '*.py' --glob '*.yml' --glob '*.yaml' \
  'group\s*=|group:|assembly\s*=|assembly:' doozer/doozerlib/cli/release_payload.py doozer/tests/cli/test_release_payload.py config ocp-build-data 2>/dev/null \
  | head -n 300

Repository: openshift-eng/art-tools

Length of output: 16508


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- construct_dest_branch body ---'
sed -n '108,145p' doozer/doozerlib/backend/rebaser.py

printf '%s\n' '--- component resource and replacement behavior ---'
sed -n '720,875p' doozer/doozerlib/backend/konflux_client.py
sed -n '1460,1565p' doozer/doozerlib/backend/konflux_client.py

printf '%s\n' '--- group validation and release-payload invocation ---'
rg -n -C 8 \
  'group_name|runtime\.group|--group|group.*pattern|group.*replace|assembly.*group' \
  doozer/doozerlib/cli/release_payload.py doozer/doozerlib/runtime.py doozer/doozerlib/cli doozer/tests/cli/test_release_payload.py \
  | head -n 420

printf '%s\n' '--- normalization probe ---'
python3 - <<'PY'
def component(group):
    return f"release-payload-{group}".replace(".", "-").replace("_", "-")

for left, right in [("foo.bar", "foo_bar"), ("openshift-4.21", "openshift_4-21")]:
    print(left, "=>", component(left))
    print(right, "=>", component(right))
    print("collision:", component(left) == component(right))
PY

Repository: openshift-eng/art-tools

Length of output: 49899


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- exact resource mutation helpers ---'
rg -n -C 16 'async def _create_or_replace|async def _replace|def _new_pipelinerun_for_image_build' \
  doozer/doozerlib/backend/konflux_client.py

printf '%s\n' '--- PipelineRun source fields ---'
sed -n '1280,1475p' doozer/doozerlib/backend/konflux_client.py

printf '%s\n' '--- group option and runtime assignment ---'
rg -n -C 12 \
  'click\.option\(.*group|group: Optional|self\.group\s*=|group_config.*name|group_config.*load|--group' \
  doozer/doozerlib/cli/__init__.py doozer/doozerlib/runtime.py doozer/doozerlib \
  | head -n 360

Repository: openshift-eng/art-tools

Length of output: 41549


Use a collision-free Component name when group names allow . and _.

foo.bar and foo_bar map to the same Component. start_pipeline_run_for_image_build does pass each build's explicit git_url and commit_sha, so assembly-specific source commits remain isolated. Add group-name validation or encode separators without collisions.

🤖 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/release_payload.py` around lines 100 - 107, Update
get_component_name so distinct group names containing "." and "_" cannot produce
the same Component name; either validate and reject ambiguous group names before
formatting or encode these separators bijectively while preserving the existing
release-payload prefix and valid-name requirements.

The Component (and its git branch) is now shared by every assembly of a
group, so include the assembly in the generateName prefix; otherwise
builds for different assemblies are indistinguishable by name in the
Konflux UI PipelineRun list.

Co-authored-by: Cursor <cursoragent@cursor.com>

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED
Drop the group/component prefix from the PipelineRun generateName and use
release-payload-<assembly> instead; the group is redundant since assembly
names already encode it (e.g. group openshift-4.21, assembly 4.21.1).

Co-authored-by: Cursor <cursoragent@cursor.com>

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants