Skip to content

ci-operator: Introduce cluster_profile_literal#5247

Open
danilo-gemoli wants to merge 5 commits into
openshift:mainfrom
danilo-gemoli:feat/ci-operator/literal-cluster-profile
Open

ci-operator: Introduce cluster_profile_literal#5247
danilo-gemoli wants to merge 5 commits into
openshift:mainfrom
danilo-gemoli:feat/ci-operator/literal-cluster-profile

Conversation

@danilo-gemoli

@danilo-gemoli danilo-gemoli commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

This is part of some preparatory work to move cluster profiles definition out of the code base.

The idea of this PR is to let ci-operator-configresolved resolving the cluster_profile stanza into the new cluster_profile_literal one.

The following test:

tests:
- as: e2e
  steps:
    cluster_profile: aws-5

will be expanded into:

tests:
- as: e2e
  steps:
    cluster_profile_literal:
      name: aws-5
      secret: cluster-secrets-aws-5
      cluster_type: aws
      lease_type: aws-5-quota-slice

This allow tests to use cluster profiles defined solely into the configuration /ci-operator/step-registry/cluster-profiles/cluster-profiles-config.yaml rather than into the code.

Another noticeable change concerns type Parameters interface that has now gained three new functions:

1. func (p *Parameters) GetString(name string) (string, error)
2. func (p *Parameters) Get(name string) (any, error)
3. func GetParamTyped[T any](params Parameters, name string) (T, error)

(1) is a drop-in replacement of the old func (p *Parameters) Get(name string) (string, error).
(2) allows client to retrieve parameters in a type unsafe manner.
(3) leverages (2) to retrieve parameters in a type safe (this time) manner.

Note that functions (2) and (3) shall be merged together if the Golang team will ever accept the "Generic Methods" proposal golang/go#77273

Summary

This PR makes ci-operator's config resolution expand a test's cluster_profile string reference into a structured cluster_profile_literal object populated from cluster-profile configuration loaded from the registry. It also changes the Parameters API to support untyped retrieval, an explicit string accessor, generic typed retrieval, and distinct parameter error types so structured profile details can be passed through parameters safely.

What this means for CI users / operators

  • Tests may keep a simple reference like cluster_profile: aws-5; during resolution the resolver will replace that with a cluster_profile_literal containing explicit metadata (name, cluster_type, lease_type, secret, owners, etc.).
  • Cluster profile definitions can be stored and maintained in registry/release configuration (step-registry/cluster-profiles config) rather than hard-coded in code or duplicated in tests.
  • Secrets, lease metadata and STS-related information referenced by a profile are injected into resolved configurations; missing/undefined profile names are caught during validation with clear errors rather than producing obscure runtime failures.

Components affected and behavioral changes

  • Registry resolver (pkg/registry)

    • Accepts registry-loaded clusterProfiles, validates against them, and resolves cluster_profile names to structured ClusterProfileDetails.
    • New helper resolveClusterProfile; Validate and NewResolver signatures updated to take clusterProfiles.
    • Expanded configs set MultiStageTestConfigurationLiteral.ClusterProfileLiteral (pointer to resolved details) or return a validation error for undefined profiles.
  • Loading & CLI tools (cmd/*, pkg/load, pkg/rehearse, pkg/defaults, release tooling)

    • load.Registry now loads ClusterProfilesConfig and returns clusterProfiles; callers capture and forward clusterProfiles into registry.NewResolver so resolution can use configured profiles end-to-end.
    • CLI tools and agents updated to pass clusterProfiles through resolver construction.
  • API, types & validation (pkg/api, pkg/validation)

    • MultiStageTestConfigurationLiteral replaces the string cluster_profile with ClusterProfileLiteral *ClusterProfileLiteral (json:"cluster_profile_literal,omitempty").
    • ClusterProfileFromParams and related helpers now work with structured ClusterProfileDetails; validation and call sites switch from empty-string sentinels to nil-pointer checks.
  • Steps, leases & IP-pool logic (pkg/steps, pkg/api/leases)

    • Steps and lease/IP-pool code now accept and operate on optional *ClusterProfileLiteral / *ClusterProfileDetails instead of string sentinels and separate secret-name parameters.
    • Lease step exposes api.ClusterProfileParam as a *api.ClusterProfileDetails when present; api.ClusterProfileSecretNameParam has been removed.
    • Environment wiring, STS role handling, lease acquisition and secret import use resolved profile fields directly.
  • Parameters API (pkg/api/parameters.go and callers)

    • Parameters.Get now returns (any, error); new GetString(name string) (string, error) provides legacy string semantics.
    • New error types ErrParamNotFound and ErrParamTypeMismatch and a generic helper GetParamTyped[T] support typed retrieval of structured values.
    • Call sites updated to use GetString for plain-string inputs and Get/GetParamTyped for structured parameter values (e.g., *ClusterProfileDetails).
  • Tests & fixtures

    • Unit and integration tests, and expected resolver fixtures, updated to use cluster_profile_literal objects and the new Parameters API behavior; some fixtures adjust secret names to match resolved profile data.

Practical impact

  • Test authors can reference centrally managed cluster profiles by name and avoid duplicating lease/secret metadata in test configs.
  • Downstream steps receive a single structured cluster-profile object (or nil), simplifying secret import, STS role extraction, lease acquisition, pod environment wiring, and label population.
  • Profile misconfiguration (missing profile definitions) is detected at resolution/validation time with explicit errors.

Review guidance

  • Confirm load.Registry loads clusterProfiles and that all resolver call sites forward the clusterProfiles value to registry.NewResolver.
  • Verify conversions from string-sentinel semantics to pointer-based ClusterProfileLiteral usage are consistent and nil-checked across code and tests.
  • Audit usages of GetString vs Get/GetParamTyped to ensure correct handling of ErrParamNotFound vs ErrParamTypeMismatch and correct propagation of structured profile values.

@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

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Cluster-profile handling is migrated from string enums to literal/details structs; Parameters API returns any with typed errors; registry loads and validates cluster profiles and passes them into resolver; lease/multi-stage/ip-pool steps, defaults, validation, commands, and tests updated to use new shapes.

Changes

Cluster profile object model and Parameters API

Layer / File(s) Summary
Parameters API: untyped to typed value support
pkg/api/parameters.go, pkg/api/parameters_test.go
Parameters now return any with ErrParamNotFound/ErrParamTypeMismatch, add GetString, and provide GetParamTyped[T] for typed retrieval. DeferredParameters normalized behavior and tests updated.
Cluster profile types and accessors
pkg/api/types.go, pkg/api/clusterprofile.go, pkg/api/constant.go
Introduces ClusterProfileLiteral and ClusterProfileDetails usage; MultiStageTestConfigurationLiteral replaces cluster_profile with cluster_profile_literal; ClusterProfileFromParams returns *ClusterProfileDetails; removed ClusterProfileSecretNameParam.
Test helpers and mock Parameters implementations
pkg/defaults/defaults_test.go, pkg/steps/multi_stage/multi_stage_test.go, pkg/steps/ip_pool_test.go
Test helpers switched to map[string]any, added GetString, and updated mocks to return typed errors and values.

Registry loading, validation, and resolver

Layer / File(s) Summary
Registry loading and validation with cluster profiles
pkg/load/load.go, pkg/registry/resolver.go, pkg/load/agents/registryAgent.go
load.Registry loads cluster profiles; registry.Validate and NewResolver accept clusterProfiles and store them on the registry.
Registry resolution and test updates
pkg/registry/resolver.go, pkg/registry/resolver_test.go
Resolver resolves named cluster profiles into ClusterProfileDetails and sets ClusterProfileLiteral on expanded outputs; tests updated to pass a clusterProfilesMap and to expect literals; adds undefined-profile error case.
Command entry points and registry agent loader
cmd/*, pkg/cmd/release/util.go
CLI entry points and registry-replacer updated to capture clusterProfiles from load.Registry and pass into registry.NewResolver.

Lease step and STS integration

Layer / File(s) Summary
Lease step profile storage and parameter export
pkg/steps/lease.go, pkg/steps/lease_test.go
leaseStep stores resolved *ClusterProfileDetails; Provides() exposes api.ClusterProfileParam as that pointer; secret-name parameter removed; tests updated accordingly.
Leases API and defaults integration
pkg/api/leases.go, pkg/api/leases_test.go, pkg/defaults/*
Leases and defaults wiring now use ClusterProfileLiteral/details for lease creation and IP pool wiring; defaults switched to GetString where appropriate.

Multi-stage step and pod generation

Layer / File(s) Summary
Multi-stage step profile storage and environment
pkg/steps/multi_stage/multi_stage.go, pkg/steps/multi_stage/gen.go
multiStageTestStep.profile is *ClusterProfileLiteral; profile checks use nil; profileSecretName() simplified; environment and STS ARNs fetched via GetString; pod generation and addProfile accept literal objects.
Multi-stage tests and fixtures
pkg/steps/multi_stage/*_test.go, pkg/steps/multi_stage/testdata/*.yaml
Tests updated to use ClusterProfileLiteral, fakeStepParams{} for params, and fixtures adjusted to reference explicit secret names.

IP pool step

Layer / File(s) Summary
IP pool step profile parameter and tests
pkg/steps/ip_pool.go, pkg/steps/ip_pool_test.go
ipPoolStep.profile is *ClusterProfileLiteral; run() treats missing profile as non-fatal and uses GetString for region; tests updated to construct ClusterProfileLiteral and new fake params.

Prowgen, validation, rehearse, and command tests

Layer / File(s) Summary
Prowgen and validation
pkg/prowgen/jobbase.go, pkg/validation/*
Prow job labels derive from ClusterProfileLiteral fields; validateClusterProfile now accepts a string name and literal validation gates on pointer presence; tests updated.
Rehearse and test call-site updates
pkg/rehearse/*, pkg/rehearse/jobs_test.go, cmd/ci-operator/main_test.go
Rehearse resolver creation and multiple test call sites updated to pass the new clusterProfiles argument (or nil) to NewResolver; some tests updated to use literal/profile pointer inputs.

Test fixtures and integration artifacts

Layer / File(s) Summary
Integration fixtures and ProwJob expected updates
test/integration/ci-operator-configresolver/**, test/integration/pj-rehearse/expected.yaml
Expected resolver outputs and fixtures updated to use cluster_profile_literal objects (with name, lease_type, cluster_type, secret) or null where appropriate; several encoded CONFIG_SPEC values refreshed.

🎯 4 (Complex) | ⏱️ ~60 minutes

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

@openshift-ci openshift-ci Bot requested review from Prucek and deepsm007 June 11, 2026 15:34
@openshift-ci

openshift-ci Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: danilo-gemoli

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 approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 11, 2026
@danilo-gemoli

Copy link
Copy Markdown
Contributor Author

@coderabbitai help

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

CodeRabbit commands

These commands are invoked using PR/Issue comments.

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai rate limit to show your current review rate limit status.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai evaluate custom pre-merge check --instructions <custom-checks-instructions> --name <custom-checks-title> [--mode <error|warning>] to validate the custom pre-merge checks instructions. Defaults to error when --mode is omitted.
  • @coderabbitai ignore pre-merge checks to override pre-merge checks and get an approval on PR.
  • @coderabbitai run pre-merge checks to run pre-merge checks on the pull request.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai emit path instructions to emit generated path-specific review instructions for this repository.
  • @coderabbitai resolve merge conflict to automatically resolve merge conflicts.
  • @coderabbitai autofix to automatically fix issues identified in unresolved review comments.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai generate configuration to create a PR that adds the current resolved configuration as .coderabbit.yaml (or show it if already present).
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, support, documentation and community

  • Visit our status page to check the current availability of CodeRabbit.
  • Create a ticket on our support page for assistance with any issues or questions.
  • Visit our documentation site for detailed information on how to use CodeRabbit.
  • Join our Discord community to connect with other users and get help from the community.
  • Follow us on X/Twitter for updates and announcements.

@danilo-gemoli

Copy link
Copy Markdown
Contributor Author

/test e2e

@danilo-gemoli

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (1)
cmd/ci-operator/main_test.go (1)

1819-1823: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Assert the comparison result in this test.

Line 1822 calls reflect.DeepEqual(...) but ignores the result, so the test always passes even if output is wrong.

Suggested fix
 for _, tc := range testCases {
 	t.Run(tc.name, func(t *testing.T) {
 		tc.options.getClusterProfileNamesFromTargets()
-		reflect.DeepEqual(tc.expectedProfileNames, tc.options.clusterProfiles)
+		if diff := cmp.Diff(tc.expectedProfileNames, tc.options.clusterProfiles); diff != "" {
+			t.Fatalf("unexpected cluster profile names (-want,+got): %s", diff)
+		}
 	})
 }
🤖 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 `@cmd/ci-operator/main_test.go` around lines 1819 - 1823, The test currently
calls reflect.DeepEqual(tc.expectedProfileNames, tc.options.clusterProfiles) but
ignores the boolean result; update the subtest in the t.Run closure to assert
the result by checking if !reflect.DeepEqual(...) and calling t.Fatalf or
t.Errorf with a descriptive message including the expected and actual values.
Locate the loop over testCases and the
tc.options.getClusterProfileNamesFromTargets() call and add the assertion
immediately after that call to fail the test when the comparison returns false.
🧹 Nitpick comments (2)
pkg/api/parameters.go (1)

13-39: ⚡ Quick win

Add GoDoc for newly exported API symbols.

ErrParamNotFound, ErrParamTypeMismatch, and GetParamTyped are exported but undocumented. Please add proper GoDoc comments describing behavior and expected usage.

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

Also applies to: 210-233

🤖 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/parameters.go` around lines 13 - 39, Add GoDoc comments for the
exported types and function: document ErrParamNotFound (what it represents, the
meaning of its param field and when it is returned), ErrParamTypeMismatch
(describe want/got fields and when this error is used), and GetParamTyped
(describe the purpose, input parameters, expected return values, and error cases
including when ErrParamNotFound or ErrParamTypeMismatch are returned). Also add
short comments for the Error() and Is() methods to state their behavior (Error
returns the formatted message; Is implements error comparison semantics). Keep
comments concise and follow GoDoc style placed immediately above each exported
symbol.

Source: Coding guidelines

pkg/api/clusterprofile.go (1)

1210-1212: ⚡ Quick win

Add GoDoc for exported ClusterProfileFromParams.

Line 1210 changes an exported API but still lacks a leading doc comment. Please document return semantics (especially nil/error behavior) for callers.

As per coding guidelines, **/*.go: “Go documentation on Classes/Functions/Fields should be written properly”.

🤖 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/clusterprofile.go` around lines 1210 - 1212, Add a GoDoc comment
above the exported function ClusterProfileFromParams that succinctly describes
its purpose (convert Parameters into a *ClusterProfileDetails), its return
semantics (returns a non-nil *ClusterProfileDetails and nil error on success;
returns nil and a non-nil error if the parameter is missing or cannot be
decoded), and mention that it delegates to GetParamTyped with
ClusterProfileParam; include any relevant expectations about the params input
(e.g., that ClusterProfileParam must be present).

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.

Inline comments:
In `@pkg/load/load.go`:
- Around line 200-205: The code unconditionally calls
ClusterProfilesConfig(clusterProfilesConfigPath) which fails with an opaque
error when clusterProfilesConfigPath is empty; modify the load logic in the
function that currently invokes ClusterProfilesConfig to first check if
clusterProfilesConfigPath is empty/blank and, if so, set profiles to an
empty/default value (or skip loading) instead of calling ClusterProfilesConfig;
when the path is non-empty, call ClusterProfilesConfig and wrap any returned
error with the resolved clusterProfilesConfigPath (include the path in the error
message) so diagnostics show the file that failed to open; keep the rest of the
flow (including the subsequent registry.Validate(references, chains, workflows,
observers, profiles)) unchanged.

In `@pkg/prowgen/jobbase.go`:
- Around line 174-176: The literal branch is using the raw field
clusterProfile.ClusterType which can be empty/mismatched; change it to derive
the cloud label from the profile's resolved ClusterType (use
clusterProfile.ClusterType() or look up ClusterProfile.Name to get its
ClusterType) so the call p.WithLabel(cioperatorapi.CloudLabel, ...) uses the
canonical/mapped value; alternatively validate/mutate clusterProfile.ClusterType
to match ClusterProfile.Name before calling p.WithLabel.

In `@pkg/validation/test.go`:
- Around line 452-462: When v.validClusterProfiles is configured (non-nil) you
must treat absence of the profile in that map as a validation failure instead of
falling back to the static list; change the logic around v.validClusterProfiles
and api.ClusterProfile(profileName) so that if v.validClusterProfiles != nil and
the key is missing you return an error (use the same message pattern with
fieldRoot and profileName), otherwise if the key exists call
verifyClusterProfileOwnership(...) as currently done; keep the existing fallback
to slices.Contains(api.ClusterProfiles(), api.ClusterProfile(profileName)) only
when v.validClusterProfiles is nil.

---

Outside diff comments:
In `@cmd/ci-operator/main_test.go`:
- Around line 1819-1823: The test currently calls
reflect.DeepEqual(tc.expectedProfileNames, tc.options.clusterProfiles) but
ignores the boolean result; update the subtest in the t.Run closure to assert
the result by checking if !reflect.DeepEqual(...) and calling t.Fatalf or
t.Errorf with a descriptive message including the expected and actual values.
Locate the loop over testCases and the
tc.options.getClusterProfileNamesFromTargets() call and add the assertion
immediately after that call to fail the test when the comparison returns false.

---

Nitpick comments:
In `@pkg/api/clusterprofile.go`:
- Around line 1210-1212: Add a GoDoc comment above the exported function
ClusterProfileFromParams that succinctly describes its purpose (convert
Parameters into a *ClusterProfileDetails), its return semantics (returns a
non-nil *ClusterProfileDetails and nil error on success; returns nil and a
non-nil error if the parameter is missing or cannot be decoded), and mention
that it delegates to GetParamTyped with ClusterProfileParam; include any
relevant expectations about the params input (e.g., that ClusterProfileParam
must be present).

In `@pkg/api/parameters.go`:
- Around line 13-39: Add GoDoc comments for the exported types and function:
document ErrParamNotFound (what it represents, the meaning of its param field
and when it is returned), ErrParamTypeMismatch (describe want/got fields and
when this error is used), and GetParamTyped (describe the purpose, input
parameters, expected return values, and error cases including when
ErrParamNotFound or ErrParamTypeMismatch are returned). Also add short comments
for the Error() and Is() methods to state their behavior (Error returns the
formatted message; Is implements error comparison semantics). Keep comments
concise and follow GoDoc style placed immediately above each exported symbol.
🪄 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: 203881ef-54b7-4fd4-90f4-533024d2bf1d

📥 Commits

Reviewing files that changed from the base of the PR and between 4b8b1c4 and 218fb74.

📒 Files selected for processing (37)
  • cmd/ci-operator-checkconfig/main.go
  • cmd/ci-operator-prowgen/main.go
  • cmd/ci-operator/main.go
  • cmd/ci-operator/main_test.go
  • cmd/registry-replacer/main.go
  • cmd/registry-replacer/testdata/zz_fixture_TestReplacer_Unused_base_images_are_pruned.yaml
  • pkg/api/clusterprofile.go
  • pkg/api/constant.go
  • pkg/api/leases.go
  • pkg/api/leases_test.go
  • pkg/api/parameters.go
  • pkg/api/parameters_test.go
  • pkg/api/types.go
  • pkg/cmd/release/util.go
  • pkg/defaults/defaults.go
  • pkg/defaults/defaults_test.go
  • pkg/load/agents/registryAgent.go
  • pkg/load/load.go
  • pkg/prowgen/jobbase.go
  • pkg/registry/resolver.go
  • pkg/registry/resolver_test.go
  • pkg/rehearse/jobs_test.go
  • pkg/rehearse/rehearse.go
  • pkg/steps/ip_pool.go
  • pkg/steps/ip_pool_test.go
  • pkg/steps/lease.go
  • pkg/steps/lease_test.go
  • pkg/steps/multi_stage/gen.go
  • pkg/steps/multi_stage/gen_test.go
  • pkg/steps/multi_stage/multi_stage.go
  • pkg/steps/multi_stage/multi_stage_test.go
  • pkg/steps/multi_stage/run_test.go
  • pkg/steps/multi_stage/testdata/zz_fixture_TestGenerateObservers.yaml
  • pkg/steps/multi_stage/testdata/zz_fixture_TestGeneratePods_STS_volumes.yaml
  • pkg/steps/multi_stage/testdata/zz_fixture_TestGeneratePods_generate_pods.yaml
  • pkg/validation/test.go
  • pkg/validation/test_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/release (manual)
  • openshift/ci-docs (manual)
  • openshift/release-controller (manual)
  • openshift/ci-chat-bot (manual)

Comment thread pkg/load/load.go
Comment thread pkg/prowgen/jobbase.go
Comment thread pkg/validation/test.go

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

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 `@pkg/api/types.go`:
- Around line 1327-1329: You renamed the serialized field to
cluster_profile_literal which breaks existing consumers; to fix, preserve
compatibility by keeping the new ClusterProfileLiteral *ClusterProfileLiteral
`json:"cluster_profile_literal"` field and add a backward-compatible alias field
(e.g., ClusterProfile *ClusterProfileLiteral `json:"cluster_profile,omitempty"`)
or add struct tags that accept both names, and ensure code that reads/serializes
(constructors/unmarshal helpers) prefers ClusterProfileLiteral when present but
falls back to ClusterProfile; reference the MultiStageTestConfigurationLiteral
type and ClusterProfileLiteral/ClusterProfile fields when making this change.
- Around line 952-965: FromClusterProfileDetails currently dereferences
profileDetails unconditionally and ClusterProfileLiteral omits fields like
owners and config_map; make the conversion nil-safe (if profileDetails == nil
return nil) and lossless by adding Owners and ConfigMap (and any other missing
ClusterProfileDetails fields you need preserved) to ClusterProfileLiteral and
copying those fields in FromClusterProfileDetails; ensure you copy slices/maps
defensively (nil -> nil, deep-copy if necessary) so configresolved can
round-trip externally defined profiles without data loss.
🪄 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: 563f7c79-b64c-4ba6-b54a-3e5bd33a8e72

📥 Commits

Reviewing files that changed from the base of the PR and between 218fb74 and f34bf40.

⛔ Files ignored due to path filters (2)
  • pkg/api/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • pkg/webreg/zz_generated.ci_operator_reference.go is excluded by !**/zz_generated*
📒 Files selected for processing (25)
  • cmd/ci-operator/main_test.go
  • pkg/api/leases.go
  • pkg/api/leases_test.go
  • pkg/api/parameters.go
  • pkg/api/types.go
  • pkg/defaults/defaults_test.go
  • pkg/prowgen/jobbase.go
  • pkg/registry/resolver.go
  • pkg/registry/resolver_test.go
  • pkg/steps/ip_pool.go
  • pkg/steps/ip_pool_test.go
  • pkg/steps/lease.go
  • pkg/steps/lease_test.go
  • pkg/steps/multi_stage/gen.go
  • pkg/steps/multi_stage/gen_test.go
  • pkg/steps/multi_stage/multi_stage.go
  • pkg/steps/multi_stage/multi_stage_test.go
  • pkg/validation/test.go
  • pkg/validation/test_test.go
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-injected.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-installer-as-base.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-golang111.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-regChange.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2.json
  • test/integration/ci-operator-configresolver/expected/resolved-config.json
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/release (manual)
  • openshift/ci-docs (manual)
  • openshift/release-controller (manual)
  • openshift/ci-chat-bot (manual)
✅ Files skipped from review due to trivial changes (1)
  • test/integration/ci-operator-configresolver/expected/resolved-config.json
🚧 Files skipped from review as they are similar to previous changes (17)
  • pkg/prowgen/jobbase.go
  • cmd/ci-operator/main_test.go
  • pkg/steps/ip_pool_test.go
  • pkg/api/leases.go
  • pkg/steps/multi_stage/gen_test.go
  • pkg/steps/ip_pool.go
  • pkg/steps/multi_stage/gen.go
  • pkg/steps/lease_test.go
  • pkg/api/parameters.go
  • pkg/defaults/defaults_test.go
  • pkg/registry/resolver.go
  • pkg/steps/lease.go
  • pkg/steps/multi_stage/multi_stage_test.go
  • pkg/api/leases_test.go
  • pkg/validation/test.go
  • pkg/registry/resolver_test.go
  • pkg/steps/multi_stage/multi_stage.go

Comment thread pkg/api/types.go
Comment on lines +952 to +965
type ClusterProfileLiteral struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
LeaseType string `yaml:"lease_type,omitempty" json:"lease_type,omitempty"`
ClusterType string `yaml:"cluster_type,omitempty" json:"cluster_type,omitempty"`
Secret string `yaml:"secret,omitempty" json:"secret,omitempty"`
}

func FromClusterProfileDetails(profileDetails *ClusterProfileDetails) *ClusterProfileLiteral {
return &ClusterProfileLiteral{
Name: string(profileDetails.Name),
LeaseType: profileDetails.LeaseType,
ClusterType: profileDetails.ClusterType,
Secret: profileDetails.Secret,
}

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 | 🏗️ Heavy lift

Preserve the full cluster profile payload in the literal converter.

ClusterProfileLiteral only carries name, lease_type, cluster_type, and secret, and FromClusterProfileDetails() dereferences profileDetails unconditionally. That makes the resolved form lossy for profile data this PR says should survive expansion (owners, config_map) and turns a nil profile into a panic instead of a nil literal. Please make this conversion lossless and nil-safe so configresolved can round-trip externally defined profiles.

🤖 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/types.go` around lines 952 - 965, FromClusterProfileDetails currently
dereferences profileDetails unconditionally and ClusterProfileLiteral omits
fields like owners and config_map; make the conversion nil-safe (if
profileDetails == nil return nil) and lossless by adding Owners and ConfigMap
(and any other missing ClusterProfileDetails fields you need preserved) to
ClusterProfileLiteral and copying those fields in FromClusterProfileDetails;
ensure you copy slices/maps defensively (nil -> nil, deep-copy if necessary) so
configresolved can round-trip externally defined profiles without data loss.

Comment thread pkg/api/types.go Outdated
Comment on lines +1327 to +1329
type MultiStageTestConfigurationLiteral struct {
// ClusterProfile defines the profile/cloud provider for end-to-end test steps.
ClusterProfile ClusterProfile `json:"cluster_profile"`
// ClusterProfileLiteral defines the profile/cloud provider for end-to-end test steps.
ClusterProfileLiteral *ClusterProfileLiteral `json:"cluster_profile_literal"`

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 | 🏗️ Heavy lift

This serialized field rename is a breaking contract.

Changing resolved configs from steps.cluster_profile to steps.cluster_profile_literal without a compatibility path will break linked consumers that still read the scalar field. One concrete example is openshift/release::ci-operator/platform-balance/step-jobs-by-platform.py, which indexes _test['steps']['cluster_profile']. Please either land those consumer updates in the same stack or preserve the old field until they do.

🤖 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/types.go` around lines 1327 - 1329, You renamed the serialized field
to cluster_profile_literal which breaks existing consumers; to fix, preserve
compatibility by keeping the new ClusterProfileLiteral *ClusterProfileLiteral
`json:"cluster_profile_literal"` field and add a backward-compatible alias field
(e.g., ClusterProfile *ClusterProfileLiteral `json:"cluster_profile,omitempty"`)
or add struct tags that accept both names, and ensure code that reads/serializes
(constructors/unmarshal helpers) prefers ClusterProfileLiteral when present but
falls back to ClusterProfile; reference the MultiStageTestConfigurationLiteral
type and ClusterProfileLiteral/ClusterProfile fields when making this change.

Source: Linked repositories

@danilo-gemoli

Copy link
Copy Markdown
Contributor Author

/test e2e

@danilo-gemoli

Copy link
Copy Markdown
Contributor Author

/retest-required

@danilo-gemoli danilo-gemoli force-pushed the feat/ci-operator/literal-cluster-profile branch from f34bf40 to adbe543 Compare June 12, 2026 13:11

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

🧹 Nitpick comments (1)
pkg/api/parameters.go (1)

13-16: ⚡ Quick win

Add proper Go doc comments for the exported API.

ErrParamNotFound, ErrParamTypeMismatch, DeferredParameters, NewDeferredParameters, Map, Set, Add, and GetParamTyped are exported without doc comments, and the GetString comment still starts with Get. That breaks godoc and the repo's Go-doc requirement.

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

Also applies to: 28-31, 51-57, 59-107, 145-165, 212-234

🤖 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/parameters.go` around lines 13 - 16, Add proper Go doc comments for
all exported types and functions so godoc requirements are satisfied: add a
comment starting with the exact exported name for ErrParamNotFound and
ErrParamTypeMismatch describing the error and fields, document the
DeferredParameters type explaining its purpose, describe NewDeferredParameters
(what it constructs and returns), and document Map, Set, Add, GetParamTyped
methods (their behavior, parameters and return values); also update the
GetString comment to start with "GetString" (not "Get") and describe what it
returns. Ensure each comment is a single or multi-line Go comment directly above
the declaration and begins with the exported identifier.

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.

Nitpick comments:
In `@pkg/api/parameters.go`:
- Around line 13-16: Add proper Go doc comments for all exported types and
functions so godoc requirements are satisfied: add a comment starting with the
exact exported name for ErrParamNotFound and ErrParamTypeMismatch describing the
error and fields, document the DeferredParameters type explaining its purpose,
describe NewDeferredParameters (what it constructs and returns), and document
Map, Set, Add, GetParamTyped methods (their behavior, parameters and return
values); also update the GetString comment to start with "GetString" (not "Get")
and describe what it returns. Ensure each comment is a single or multi-line Go
comment directly above the declaration and begins with the exported identifier.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 39f4fff9-ecad-452b-a724-287f6e6b443f

📥 Commits

Reviewing files that changed from the base of the PR and between f34bf40 and adbe543.

⛔ Files ignored due to path filters (2)
  • pkg/api/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • pkg/webreg/zz_generated.ci_operator_reference.go is excluded by !**/zz_generated*
📒 Files selected for processing (27)
  • cmd/ci-operator/main_test.go
  • cmd/registry-replacer/testdata/zz_fixture_TestReplacer_Unused_base_images_are_pruned.yaml
  • pkg/api/leases.go
  • pkg/api/leases_test.go
  • pkg/api/parameters.go
  • pkg/api/types.go
  • pkg/defaults/defaults_test.go
  • pkg/prowgen/jobbase.go
  • pkg/registry/resolver.go
  • pkg/registry/resolver_test.go
  • pkg/steps/ip_pool.go
  • pkg/steps/ip_pool_test.go
  • pkg/steps/lease.go
  • pkg/steps/lease_test.go
  • pkg/steps/multi_stage/gen.go
  • pkg/steps/multi_stage/gen_test.go
  • pkg/steps/multi_stage/multi_stage.go
  • pkg/steps/multi_stage/multi_stage_test.go
  • pkg/validation/test.go
  • pkg/validation/test_test.go
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-injected.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-installer-as-base.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-golang111.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-regChange.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2.json
  • test/integration/ci-operator-configresolver/expected/resolved-config.json
  • test/integration/pj-rehearse/expected.yaml
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/release (manual)
  • openshift/ci-docs (manual)
  • openshift/release-controller (manual)
  • openshift/ci-chat-bot (manual)
💤 Files with no reviewable changes (1)
  • cmd/registry-replacer/testdata/zz_fixture_TestReplacer_Unused_base_images_are_pruned.yaml
🚧 Files skipped from review as they are similar to previous changes (24)
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-golang111.json
  • test/integration/ci-operator-configresolver/expected/resolved-config.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-injected.json
  • pkg/api/leases.go
  • pkg/prowgen/jobbase.go
  • pkg/validation/test_test.go
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-regChange.json
  • pkg/steps/lease_test.go
  • pkg/steps/ip_pool_test.go
  • pkg/registry/resolver.go
  • pkg/steps/lease.go
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-installer-as-base.json
  • cmd/ci-operator/main_test.go
  • pkg/steps/multi_stage/gen_test.go
  • pkg/defaults/defaults_test.go
  • pkg/validation/test.go
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2.json
  • pkg/steps/multi_stage/gen.go
  • pkg/steps/ip_pool.go
  • pkg/steps/multi_stage/multi_stage_test.go
  • pkg/steps/multi_stage/multi_stage.go
  • pkg/api/types.go
  • pkg/registry/resolver_test.go
  • pkg/api/leases_test.go

@danilo-gemoli

Copy link
Copy Markdown
Contributor Author

/test e2e

@danilo-gemoli danilo-gemoli force-pushed the feat/ci-operator/literal-cluster-profile branch from adbe543 to 398d3cd Compare June 12, 2026 15:54

@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)
cmd/ci-operator/main_test.go (1)

1750-1825: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

This test never asserts the migrated behavior.

Line 1822 drops the reflect.DeepEqual result, so the test always passes. On top of that, it compares []string against o.clusterProfiles, which is populated as []metrics.ClusterProfileForTarget in cmd/ci-operator/main.go, so the assertion would still be wrong if wired in. Please assert on the extracted ProfileName values (or change the expected type) so this migration is actually covered.

Suggested fix
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
 			tc.options.getClusterProfileNamesFromTargets()
-			reflect.DeepEqual(tc.expectedProfileNames, tc.options.clusterProfiles)
+			actualProfileNames := make([]string, 0, len(tc.options.clusterProfiles))
+			for _, profile := range tc.options.clusterProfiles {
+				actualProfileNames = append(actualProfileNames, profile.ProfileName)
+			}
+			if diff := cmp.Diff(tc.expectedProfileNames, actualProfileNames); diff != "" {
+				t.Fatalf("unexpected cluster profile names (-want +got):\n%s", diff)
+			}
 		})
 	}
 }
🤖 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 `@cmd/ci-operator/main_test.go` around lines 1750 - 1825, The test
TestGetClusterProfileNamesFromTargets never asserts because the
reflect.DeepEqual result is discarded and also compares []string to
options.clusterProfiles which is a []metrics.ClusterProfileForTarget; update the
test to call tc.options.getClusterProfileNamesFromTargets(), extract the
ProfileName values from tc.options.clusterProfiles (the slice of
metrics.ClusterProfileForTarget) into a []string and then assert equality with
tc.expectedProfileNames (use t.Fatalf or t.Errorf on mismatch or a test helper
like require.Equal). Ensure you reference the getClusterProfileNamesFromTargets
method and the options.clusterProfiles field when locating and fixing the
assertion.
🤖 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 `@cmd/ci-operator/main_test.go`:
- Around line 1750-1825: The test TestGetClusterProfileNamesFromTargets never
asserts because the reflect.DeepEqual result is discarded and also compares
[]string to options.clusterProfiles which is a
[]metrics.ClusterProfileForTarget; update the test to call
tc.options.getClusterProfileNamesFromTargets(), extract the ProfileName values
from tc.options.clusterProfiles (the slice of metrics.ClusterProfileForTarget)
into a []string and then assert equality with tc.expectedProfileNames (use
t.Fatalf or t.Errorf on mismatch or a test helper like require.Equal). Ensure
you reference the getClusterProfileNamesFromTargets method and the
options.clusterProfiles field when locating and fixing the assertion.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: ffc4f19d-dbed-4e5b-8f57-24ab63907bf3

📥 Commits

Reviewing files that changed from the base of the PR and between adbe543 and 398d3cd.

⛔ Files ignored due to path filters (2)
  • pkg/api/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • pkg/webreg/zz_generated.ci_operator_reference.go is excluded by !**/zz_generated*
📒 Files selected for processing (27)
  • cmd/ci-operator/main_test.go
  • cmd/registry-replacer/testdata/zz_fixture_TestReplacer_Unused_base_images_are_pruned.yaml
  • pkg/api/leases.go
  • pkg/api/leases_test.go
  • pkg/api/parameters.go
  • pkg/api/types.go
  • pkg/defaults/defaults_test.go
  • pkg/prowgen/jobbase.go
  • pkg/registry/resolver.go
  • pkg/registry/resolver_test.go
  • pkg/steps/ip_pool.go
  • pkg/steps/ip_pool_test.go
  • pkg/steps/lease.go
  • pkg/steps/lease_test.go
  • pkg/steps/multi_stage/gen.go
  • pkg/steps/multi_stage/gen_test.go
  • pkg/steps/multi_stage/multi_stage.go
  • pkg/steps/multi_stage/multi_stage_test.go
  • pkg/validation/test.go
  • pkg/validation/test_test.go
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-injected.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-installer-as-base.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-golang111.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-regChange.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2.json
  • test/integration/ci-operator-configresolver/expected/resolved-config.json
  • test/integration/pj-rehearse/expected.yaml
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/release (manual)
  • openshift/ci-docs (manual)
  • openshift/release-controller (manual)
  • openshift/ci-chat-bot (manual)
💤 Files with no reviewable changes (2)
  • cmd/registry-replacer/testdata/zz_fixture_TestReplacer_Unused_base_images_are_pruned.yaml
  • test/integration/ci-operator-configresolver/expected/resolved-config.json
✅ Files skipped from review due to trivial changes (1)
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-injected.json
🚧 Files skipped from review as they are similar to previous changes (21)
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-regChange.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2-golang111.json
  • pkg/validation/test.go
  • test/integration/ci-operator-configresolver/expected/openshift-installer-console-merged-release-4.2-installer-as-base.json
  • test/integration/ci-operator-configresolver/expected/openshift-installer-release-4.2.json
  • pkg/prowgen/jobbase.go
  • pkg/validation/test_test.go
  • pkg/steps/multi_stage/multi_stage_test.go
  • pkg/steps/ip_pool.go
  • pkg/steps/lease.go
  • pkg/registry/resolver.go
  • pkg/steps/multi_stage/gen_test.go
  • pkg/api/leases_test.go
  • test/integration/pj-rehearse/expected.yaml
  • pkg/steps/ip_pool_test.go
  • pkg/defaults/defaults_test.go
  • pkg/steps/lease_test.go
  • pkg/steps/multi_stage/multi_stage.go
  • pkg/api/types.go
  • pkg/api/parameters.go
  • pkg/registry/resolver_test.go

@openshift-ci

openshift-ci Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

@danilo-gemoli: The following tests 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/integration 398d3cd link true /test integration
ci/prow/e2e adbe543 link true /test e2e
ci/prow/breaking-changes 398d3cd link false /test breaking-changes

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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant