Skip to content

OCPSTRAT-2876: Allow inclusion/exclusion of manifests based on the OCP major version#1282

Open
JoelSpeed wants to merge 2 commits intoopenshift:mainfrom
JoelSpeed:major-version-inclusion
Open

OCPSTRAT-2876: Allow inclusion/exclusion of manifests based on the OCP major version#1282
JoelSpeed wants to merge 2 commits intoopenshift:mainfrom
JoelSpeed:major-version-inclusion

Conversation

@JoelSpeed
Copy link
Contributor

@JoelSpeed JoelSpeed commented Dec 24, 2025

This introduces a new CVO manifest filter based on the OCP major version.

The intended usage would allow folks to say "this manifest should be deployed on OCP 5 and skipped on OCP 4"

The library-go component here is limiting this feature to FeatureGate and CustomResourceDefinition only for now.

This is not intended for use beyond the feature gating mechanisms we have today. We expect FeatureGate and CustomResourceDefinition yamls to vary by release, but all other inclusion/exclusion should be handled by existing mechanisms like the feature-gate inclusion mechanism.

Example usage:

release.openshift.io/major-version: 5,6,7

Summary by CodeRabbit

  • New Features

    • Release manifests can be filtered by release major version; rendering and sync now respect payload major-version metadata.
  • Tests

    • Added unit and integration tests covering major-version-based manifest inclusion/exclusion and rendering scenarios.
  • Chores

    • Upgraded Go toolchain and numerous module dependencies; updated metadata parsing to support semantic release versions.

@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 Dec 24, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 24, 2025

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

@coderabbitai
Copy link

coderabbitai bot commented Dec 24, 2025

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

Release semver is parsed and the major version is threaded through payload render and CVO flows; manifest inclusion/filtering now considers release.openshift.io/major-version annotations. Tests and testdata were added/updated to validate major-version based inclusion/exclusion.

Changes

Cohort / File(s) Summary
Dependency updates
go.mod
Bumped Go toolchain and many dependencies (OpenShift, Kubernetes, Prometheus, ginkgo/gomega, OpenTelemetry, protobufs); added a replace for github.com/onsi/ginkgo/v2github.com/openshift/onsi-ginkgo/v2 (versioned pseudo-replace).
Manifest inclusion config
lib/manifest/manifest.go
Added MajorVersion *uint64 to InclusionConfiguration; split manifest inclusion config into update/current variants and threaded MajorVersion into inclusion checks and capability determination.
Payload structs & parsing
pkg/payload/payload.go, pkg/payload/payload_test.go
Added ParsedVersion semver.Version to Update; loadPayloadMetadata now parses release version into ParsedVersion; updated tests to populate ParsedVersion; GetImplicitlyEnabledCapabilities signature extended to accept update/current major-version pointers.
Rendering & render tests
pkg/payload/render.go, pkg/payload/render_test.go
Added loadReleaseVersion and threaded majorVersion *uint64 through renderDir/render flows and manifest.Include calls; added comprehensive tests for major-version filtering and helpers to generate test manifests.
CVO runtime & include plumbing
pkg/cvo/sync_worker.go, pkg/cvo/featuregate_integration_test.go
Pass ptr.To(payloadUpdate.ParsedVersion.Major) into GetImplicitlyEnabledCapabilities and manifest.Include; updated Include callsites to the new signature (extra final parameter).
CVO scenario tests
pkg/cvo/cvo_scenarios_test.go
Added TestCVO_MajorVersionManifestFiltering (duplicate identical test declarations present).
Testdata: major-version manifests & metadata
pkg/cvo/testdata/majorversiontest-v5/release-manifests/*
Added multiple CRD manifests with various release.openshift.io/major-version annotations, an ImageStream, and Cincinnati release metadata (v5.0.0-xyz) to exercise inclusion/exclusion logic.
Small callsite updates
pkg/cvo/..., pkg/payload/...
Updated callsites and signatures to accept/pass the additional major-version parameter where manifest.Include and capability functions changed.

Sequence Diagram

sequenceDiagram
    participant Release as Release Metadata
    participant Parser as Version Parser
    participant Payload as Payload/Render
    participant CVO as CVO Sync Worker
    participant Filter as Manifest Include/Filter
    participant Cluster as Cluster API

    Release->>Parser: loadReleaseVersion()
    Parser->>Parser: Parse semantic version (e.g. 5.0.0)
    Parser->>Payload: provide ParsedVersion.Major

    Payload->>CVO: pass majorVersion (*uint64)
    CVO->>Filter: GetImplicitlyEnabledCapabilities(manifests, ..., majorVersion)
    CVO->>Filter: Include(manifests..., majorVersion)
    Filter->>Filter: Evaluate `release.openshift.io/major-version` annotation against majorVersion
    alt matches major
        Filter->>Cluster: apply manifest
    else excluded
        Filter-->>CVO: skip manifest
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding manifest inclusion/exclusion based on OCP major version. It directly aligns with the primary objective of the PR and accurately summarizes the feature being introduced.
Stable And Deterministic Test Names ✅ Passed Test function names and all test case names in t.Run() calls are hardcoded descriptive strings. String concatenation is used only for fixture generation, not test titles.
Test Structure And Quality ✅ Passed Repository uses standard Go testing framework exclusively with 71 tests in pkg/cvo and 0 Ginkgo It blocks; check is not applicable to this codebase.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 24, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: JoelSpeed
Once this PR has been reviewed and has the lgtm label, please assign davidhurta 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

@JoelSpeed JoelSpeed force-pushed the major-version-inclusion branch 2 times, most recently from 39354c8 to ef0e8c6 Compare January 30, 2026 12:20
@JoelSpeed JoelSpeed changed the title [WIP] Allow inclusion/exclusion of manifests based on the OCP major version [WIP] OCPSTRAT-2876: Allow inclusion/exclusion of manifests based on the OCP major version Jan 30, 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 Jan 30, 2026
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Jan 30, 2026

@JoelSpeed: This pull request references OCPSTRAT-2876 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 feature to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Currently based on #1273

TODO

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.

@JoelSpeed JoelSpeed force-pushed the major-version-inclusion branch from ef0e8c6 to 2d6aae6 Compare February 4, 2026 18:07
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 4, 2026

@JoelSpeed: This pull request references OCPSTRAT-2876 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 feature to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This introduces a new CVO manifest filter based on the OCP major version.

The intended usage would allow folks to say "this manifest should be deployed on OCP 5 and skipped on OCP 4"

The library-go component here is limiting this feature to FeatureGate and CustomResourceDefinition only for now.

This is not intended for use beyond the feature gating mechanisms we have today. We expect FeatureGate and CustomResourceDefinition yamls to vary by release, but all other inclusion/exclusion should be handled by existing mechanisms like the feature-gate inclusion mechanism.

Example usage:

release.openshift.io/major-version: 5,6,7

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.

@JoelSpeed JoelSpeed changed the title [WIP] OCPSTRAT-2876: Allow inclusion/exclusion of manifests based on the OCP major version OCPSTRAT-2876: Allow inclusion/exclusion of manifests based on the OCP major version Feb 4, 2026
@JoelSpeed JoelSpeed marked this pull request as ready for review February 4, 2026 18:20
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 4, 2026
@JoelSpeed
Copy link
Contributor Author

@DavidHurta If you are available, I'd appreciate if you could help me with this feature as well

@DavidHurta
Copy link
Contributor

@JoelSpeed, I will be happy to assist.

/cc

@openshift-ci openshift-ci bot requested a review from DavidHurta February 4, 2026 21:39
Copy link
Contributor

@DavidHurta DavidHurta left a comment

Choose a reason for hiding this comment

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

The PR looks solid!

A few comments about a thing here or there, but nothing drastic.
The overall functionality is 👍

ImageRef *imagev1.ImageStream

Architecture string
MajorVersion *uint64
Copy link
Contributor

@DavidHurta DavidHurta Feb 12, 2026

Choose a reason for hiding this comment

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

Here, the purpose of MajorVersion is starting to become a bit fuzzy in comparison to the Release.Version field. The meaning of MajorVersion in the inclusion filtering context is clear; however, here we use it in a general struct type representing the contents of a release image. Thus, their purpose becomes less clear.

We could do one of the following:

  • Document MajorVersion field to make the difference between Release.Version and MajorVersion clearer.
  • Leave only one source of truth (that is, Release.Version), and extract the major version when needed using a function.
  • Create a new field ParsedVersion semver.Version; we could use it to get access to the parsed cached version of the update easily. This could even be utilized in the future when we need easy access to the parsed version of an update, which is more handy for fine grained processing. This would bring additional value to the new field, make it more general, and make its distinction clearer. The call sites requiring the MajorVersion would need to be updated to just ptr.To(payload.ParsedVersion.Major), so it would still be readable. I am more inclined towards this approach, but I am curious what you think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like the parsed version approach, I'll see what that looks like locally

return requiredFeatureSet, enabledFeatureGates, nil
}

func loadReleaseVersion(releaseDir string) (semver.Version, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Here we start to duplicate some logic. I am curious whether we could leverage the existing loadReleaseMetadata function here instead of manually loading the release version.

The loadReleaseMetadata function also contains some additional validation, such as:

	if metadata.Kind != "cincinnati-metadata-v0" {
		return release, fmt.Errorf("unrecognized Cincinnati metadata kind %q", metadata.Kind)
	}

Copy link
Contributor

Choose a reason for hiding this comment

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

Something like:

func loadReleaseVersion(releaseDir string) (semver.Version, error) {
	release, err := loadReleaseMetadata(releaseDir)
	if err != nil {
		return semver.Version{}, err
	}

	parsedVersion, err := semver.Parse(release.Version)
	if err != nil {
		return semver.Version{}, err
	}
	return parsedVersion, nil
}

}
}

func TestRenderDirWithMajorVersionFiltering(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment not related to the selected line


Thank you for the complex testing of the rendering!

The overall testing coverage of the PR is solid. However, we do not have an integration test to determine whether the CVO will actually apply the manifest based on the major version. I am doubtful whether this feature will receive end-to-end tests. Thus, I think it would be beneficial to increase the test coverage to ensure that the CVO truly does respect the major version when loading and applying manifests, WDYT?

Something like: DavidHurta@ee1907b

@JoelSpeed JoelSpeed force-pushed the major-version-inclusion branch from 2d6aae6 to adefaa3 Compare March 4, 2026 12:49
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 4, 2026

@JoelSpeed: This pull request references OCPSTRAT-2876 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 feature to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This introduces a new CVO manifest filter based on the OCP major version.

The intended usage would allow folks to say "this manifest should be deployed on OCP 5 and skipped on OCP 4"

The library-go component here is limiting this feature to FeatureGate and CustomResourceDefinition only for now.

This is not intended for use beyond the feature gating mechanisms we have today. We expect FeatureGate and CustomResourceDefinition yamls to vary by release, but all other inclusion/exclusion should be handled by existing mechanisms like the feature-gate inclusion mechanism.

Example usage:

release.openshift.io/major-version: 5,6,7

Summary by CodeRabbit

  • New Features

  • Release manifests can now be filtered and selectively enabled based on the release major version, enabling version-specific component deployment and compatibility management.

  • Dependencies

  • Updated OpenShift API and supporting library dependencies.

  • Tests

  • Added comprehensive test coverage validating major version-based manifest filtering across multiple version scenarios.

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.

@JoelSpeed JoelSpeed force-pushed the major-version-inclusion branch from adefaa3 to ede695d Compare March 4, 2026 12:54
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@go.mod`:
- Line 37: Remove the personal-fork replace directive that points "replace
github.com/openshift/library-go => github.com/JoelSpeed/library-go
v0.0.0-20260130121715-6e5ccfd0da42" from go.mod and instead reference the
official upstream module; update the module requirement for
github.com/openshift/library-go to the appropriate upstream version/tag (or
remove the replace entirely if the required upstream version is already
satisfied) so builds use the official org package rather than the JoelSpeed
fork.

In `@lib/manifest/manifest.go`:
- Line 67: The test suite lacks coverage for cross-major-version behavior in
GetImplicitlyEnabledCapabilities: add a new case within
TestGetImplicitlyEnabledCapabilities that constructs a currentManifest and an
updateManifest with different MajorVersion values (e.g., currentMajor=4,
updateMajor=5) and invokes the code path that uses
manifestInclusionConfiguration.MajorVersion for each manifest evaluation; ensure
the updateManifest is evaluated with the update payload's MajorVersion (set the
manifestInclusionConfiguration used for updateManifest accordingly) and assert
the returned implicitly enabled capabilities reflect the update-major evaluation
rather than the current-major one, referencing
TestGetImplicitlyEnabledCapabilities, GetImplicitlyEnabledCapabilities,
currentManifest, updateManifest, and manifestInclusionConfiguration when
locating where to add the case.

In `@pkg/cvo/sync_worker.go`:
- Around line 451-452: The implicit-capability calculation is using the current
payload major version (w.payload.ParsedVersion.Major) instead of the
target/update payload major version, causing incorrect results during
cross-major upgrades; update the call to
payload.GetImplicitlyEnabledCapabilities (the invocation that assigns
implicitlyEnabledCaps) to pass the target payload's major version
(payloadUpdate.ParsedVersion.Major) via ptr.To(...) rather than
w.payload.ParsedVersion.Major so the evaluation uses the update payload's
version.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml`:
- Around line 4-11: The CRD's metadata.name is invalid — update metadata.name to
follow the required "<plural>.<group>" format by replacing the current value of
metadata.name with the concatenation of spec.names.plural and spec.group (e.g.,
set metadata.name to "noversions.test.io") so it matches spec.names.plural and
spec.group; verify the fields metadata.name, spec.names.plural, and spec.group
are consistent.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 86b819d9-2e3c-4b03-9cde-3e35027f9e1a

📥 Commits

Reviewing files that changed from the base of the PR and between 54dc4ef and adefaa3.

⛔ Files ignored due to path filters (21)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/types_backup.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/library-go/pkg/manifest/manifest.go is excluded by !**/vendor/**, !vendor/**
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (17)
  • go.mod
  • lib/manifest/manifest.go
  • pkg/cvo/cvo_scenarios_test.go
  • pkg/cvo/featuregate_integration_test.go
  • pkg/cvo/sync_worker.go
  • pkg/cvo/testdata/majorversiontest-v5/manifests/.gitkeep
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_40_version-4-or-5.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/image-references
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/release-metadata
  • pkg/payload/payload.go
  • pkg/payload/payload_test.go
  • pkg/payload/render.go
  • pkg/payload/render_test.go

go.mod Outdated
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
)

replace github.com/openshift/library-go => github.com/JoelSpeed/library-go v0.0.0-20260130121715-6e5ccfd0da42
Copy link

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
set -euo pipefail

# Verify whether go.mod contains a personal-fork replacement for library-go.
rg -n '^replace\s+github.com/openshift/library-go\s*=>\s*github.com/[^/]+/library-go' go.mod

# Show related direct requirement lines for context.
rg -n 'github.com/openshift/library-go|^replace ' go.mod

Repository: openshift/cluster-version-operator

Length of output: 487


Remove the personal-fork replace directive and update to the upstream github.com/openshift/library-go version.

Using a non-org fork for production dependencies weakens provenance, reproducibility, and long-term maintainability. The current replace at line 37 redirects to github.com/JoelSpeed/library-go, which bypasses official org version control. Switch to the upstream version before merging.

Proposed change
-replace github.com/openshift/library-go => github.com/JoelSpeed/library-go v0.0.0-20260130121715-6e5ccfd0da42
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@go.mod` at line 37, Remove the personal-fork replace directive that points
"replace github.com/openshift/library-go => github.com/JoelSpeed/library-go
v0.0.0-20260130121715-6e5ccfd0da42" from go.mod and instead reference the
official upstream module; update the module requirement for
github.com/openshift/library-go to the appropriate upstream version/tag (or
remove the replace entirely if the required upstream version is already
satisfied) so builds use the official org package rather than the JoelSpeed
fork.

Comment on lines +4 to +11
name: noversion
annotations:
include.release.openshift.io/self-managed-high-availability: "true"
spec:
group: test.io
names:
kind: NoVersion
plural: noversions
Copy link

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

🌐 Web query:

Kubernetes CustomResourceDefinition metadata.name format spec.names.plural spec.group

💡 Result:

For a Kubernetes CustomResourceDefinition (CRD), the required relationship is:

So, given:

  • spec.group: stable.example.com
  • spec.names.plural: crontabs

Then:

Additional relevant constraints:

Citations:


Use a valid CRD name format (<plural>.<group>)

Line 4 sets metadata.name: noversion, but with spec.names.plural: noversions and spec.group: test.io, this must be noversions.test.io per the Kubernetes CRD API contract. Invalid CRD names violate the required naming constraint and will fail validation.

Suggested fix
 metadata:
-  name: noversion
+  name: noversions.test.io
   annotations:
     include.release.openshift.io/self-managed-high-availability: "true"
📝 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
name: noversion
annotations:
include.release.openshift.io/self-managed-high-availability: "true"
spec:
group: test.io
names:
kind: NoVersion
plural: noversions
name: noversions.test.io
annotations:
include.release.openshift.io/self-managed-high-availability: "true"
spec:
group: test.io
names:
kind: NoVersion
plural: noversions
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml`
around lines 4 - 11, The CRD's metadata.name is invalid — update metadata.name
to follow the required "<plural>.<group>" format by replacing the current value
of metadata.name with the concatenation of spec.names.plural and spec.group
(e.g., set metadata.name to "noversions.test.io") so it matches
spec.names.plural and spec.group; verify the fields metadata.name,
spec.names.plural, and spec.group are consistent.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 4, 2026

@JoelSpeed: This pull request references OCPSTRAT-2876 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 feature to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This introduces a new CVO manifest filter based on the OCP major version.

The intended usage would allow folks to say "this manifest should be deployed on OCP 5 and skipped on OCP 4"

The library-go component here is limiting this feature to FeatureGate and CustomResourceDefinition only for now.

This is not intended for use beyond the feature gating mechanisms we have today. We expect FeatureGate and CustomResourceDefinition yamls to vary by release, but all other inclusion/exclusion should be handled by existing mechanisms like the feature-gate inclusion mechanism.

Example usage:

release.openshift.io/major-version: 5,6,7

Summary by CodeRabbit

  • New Features

  • Release manifests can be filtered by release major version to enable version-specific component inclusion.

  • Tests

  • Added comprehensive tests validating major-version-based manifest filtering across many scenarios.

  • Dependencies

  • Updated OpenShift API and related library versions; aligned a library replacement across the module.

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.

@JoelSpeed JoelSpeed force-pushed the major-version-inclusion branch from ede695d to 47b4565 Compare March 4, 2026 13:03
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (3)
pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml (1)

4-11: ⚠️ Potential issue | 🟠 Major

CRD name mismatch remains unresolved (metadata.name vs <plural>.<group>).

This still should be noversions.test.io to satisfy CRD naming requirements.

Suggested fix
 metadata:
-  name: noversion
+  name: noversions.test.io
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml`
around lines 4 - 11, The CRD's metadata.name is invalidly set to "noversion";
update metadata.name to match the required <plural>.<group> pattern by setting
it to "noversions.test.io" so it matches spec.names.plural ("noversions") and
spec.group ("test.io")—look for the metadata.name field and the
spec.names.plural / spec.group entries in this manifest (the resource currently
named "noversion") and change metadata.name to "noversions.test.io".
lib/manifest/manifest.go (1)

60-87: ⚠️ Potential issue | 🟠 Major

Separate major-version context for update vs current manifest evaluation.

Both branches currently use the same MajorVersion. In cross-major upgrades, currentManifest should be evaluated with the current payload major, while updateManifest should use the target payload major.

Possible fix direction
-func GetImplicitlyEnabledCapabilities(
-	updatePayloadManifests []manifest.Manifest,
-	currentPayloadManifests []manifest.Manifest,
-	manifestInclusionConfiguration InclusionConfiguration,
-	currentImplicitlyEnabled sets.Set[configv1.ClusterVersionCapability],
-) sets.Set[configv1.ClusterVersionCapability] {
+func GetImplicitlyEnabledCapabilities(
+	updatePayloadManifests []manifest.Manifest,
+	currentPayloadManifests []manifest.Manifest,
+	updateInclusionConfiguration InclusionConfiguration,
+	currentInclusionConfiguration InclusionConfiguration,
+	currentImplicitlyEnabled sets.Set[configv1.ClusterVersionCapability],
+) sets.Set[configv1.ClusterVersionCapability] {

  // update manifest include check
- manifestInclusionConfiguration.MajorVersion,
+ updateInclusionConfiguration.MajorVersion,

  // current manifest include check
- manifestInclusionConfiguration.MajorVersion,
+ currentInclusionConfiguration.MajorVersion,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/manifest/manifest.go` around lines 60 - 87, The two
IncludeAllowUnknownCapabilities calls must evaluate with different major-version
contexts: keep using manifestInclusionConfiguration.MajorVersion (target major)
when calling updateManifest.IncludeAllowUnknownCapabilities (and assigning
updateManErr), but when iterating currentPayloadManifests call
currentManifest.IncludeAllowUnknownCapabilities with the current payload major
instead of reusing the same MajorVersion; obtain the current payload major from
the current payload metadata (or add a currentMajor variable derived from
currentManifest/currentPayload) and pass that as the MajorVersion argument so
updateManifest uses the target major and currentManifest uses the current-major
context.
pkg/cvo/sync_worker.go (1)

451-452: ⚠️ Potential issue | 🟠 Major

Use target payload major version for implicit-capability evaluation.

At Line [452], this still passes the current payload major (w.payload.ParsedVersion.Major). For cross-major updates, implicit-capability resolution should use the target payload major (payloadUpdate.ParsedVersion.Major), or manifests can be evaluated against the wrong major-version filter.

Suggested fix
-		implicitlyEnabledCaps = capability.SortedList(payload.GetImplicitlyEnabledCapabilities(payloadUpdate.Manifests, w.payload.Manifests,
-			work.Capabilities, work.EnabledFeatureGates, ptr.To(w.payload.ParsedVersion.Major)))
+		implicitlyEnabledCaps = capability.SortedList(payload.GetImplicitlyEnabledCapabilities(payloadUpdate.Manifests, w.payload.Manifests,
+			work.Capabilities, work.EnabledFeatureGates, ptr.To(payloadUpdate.ParsedVersion.Major)))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cvo/sync_worker.go` around lines 451 - 452, The call computing
implicitlyEnabledCaps uses the current payload major
(w.payload.ParsedVersion.Major) but should use the target payload major from
payloadUpdate for cross-major updates: update the call to
payload.GetImplicitlyEnabledCapabilities so its last argument is
ptr.To(payloadUpdate.ParsedVersion.Major) (keeping capability.SortedList and
assignment to implicitlyEnabledCaps unchanged) to ensure manifest filtering uses
the target payload major instead of w.payload.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@lib/manifest/manifest.go`:
- Around line 60-87: The two IncludeAllowUnknownCapabilities calls must evaluate
with different major-version contexts: keep using
manifestInclusionConfiguration.MajorVersion (target major) when calling
updateManifest.IncludeAllowUnknownCapabilities (and assigning updateManErr), but
when iterating currentPayloadManifests call
currentManifest.IncludeAllowUnknownCapabilities with the current payload major
instead of reusing the same MajorVersion; obtain the current payload major from
the current payload metadata (or add a currentMajor variable derived from
currentManifest/currentPayload) and pass that as the MajorVersion argument so
updateManifest uses the target major and currentManifest uses the current-major
context.

In `@pkg/cvo/sync_worker.go`:
- Around line 451-452: The call computing implicitlyEnabledCaps uses the current
payload major (w.payload.ParsedVersion.Major) but should use the target payload
major from payloadUpdate for cross-major updates: update the call to
payload.GetImplicitlyEnabledCapabilities so its last argument is
ptr.To(payloadUpdate.ParsedVersion.Major) (keeping capability.SortedList and
assignment to implicitlyEnabledCaps unchanged) to ensure manifest filtering uses
the target payload major instead of w.payload.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml`:
- Around line 4-11: The CRD's metadata.name is invalidly set to "noversion";
update metadata.name to match the required <plural>.<group> pattern by setting
it to "noversions.test.io" so it matches spec.names.plural ("noversions") and
spec.group ("test.io")—look for the metadata.name field and the
spec.names.plural / spec.group entries in this manifest (the resource currently
named "noversion") and change metadata.name to "noversions.test.io".

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 366b0564-c600-4e8f-9a02-0bbc9a478b95

📥 Commits

Reviewing files that changed from the base of the PR and between adefaa3 and ede695d.

⛔ Files ignored due to path filters (21)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/types_backup.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/library-go/pkg/manifest/manifest.go is excluded by !**/vendor/**, !vendor/**
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (17)
  • go.mod
  • lib/manifest/manifest.go
  • pkg/cvo/cvo_scenarios_test.go
  • pkg/cvo/featuregate_integration_test.go
  • pkg/cvo/sync_worker.go
  • pkg/cvo/testdata/majorversiontest-v5/manifests/.gitkeep
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_40_version-4-or-5.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/image-references
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/release-metadata
  • pkg/payload/payload.go
  • pkg/payload/payload_test.go
  • pkg/payload/render.go
  • pkg/payload/render_test.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/image-references
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/release-metadata
  • go.mod
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml
  • pkg/payload/payload_test.go
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_40_version-4-or-5.yaml

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 4, 2026

@JoelSpeed: This pull request references OCPSTRAT-2876 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 feature to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This introduces a new CVO manifest filter based on the OCP major version.

The intended usage would allow folks to say "this manifest should be deployed on OCP 5 and skipped on OCP 4"

The library-go component here is limiting this feature to FeatureGate and CustomResourceDefinition only for now.

This is not intended for use beyond the feature gating mechanisms we have today. We expect FeatureGate and CustomResourceDefinition yamls to vary by release, but all other inclusion/exclusion should be handled by existing mechanisms like the feature-gate inclusion mechanism.

Example usage:

release.openshift.io/major-version: 5,6,7

Summary by CodeRabbit

  • New Features

  • Release manifests can be filtered by release major version to enable version-specific component inclusion.

  • Tests

  • Added comprehensive tests validating major-version-based manifest filtering across many scenarios.

  • Chores

  • Updated platform library versions and aligned module replacements to ensure consistent dependency resolution.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml (1)

4-11: ⚠️ Potential issue | 🟠 Major

Use a valid CRD name format (<plural>.<group>).

Line 4 uses metadata.name: noversion, but with spec.names.plural: noversions and spec.group: test.io, it should be noversions.test.io. This can hide real validation failures in tests that model CRD application.

Suggested fix
 metadata:
-  name: noversion
+  name: noversions.test.io
   annotations:
     include.release.openshift.io/self-managed-high-availability: "true"

Run this read-only check to find CRD name mismatches in the same testdata set:

#!/bin/bash
set -euo pipefail

python - <<'PY'
import glob
import re
import sys

def parse_fields(path):
    name = plural = group = None
    section = None
    for raw in open(path, encoding="utf-8"):
        line = raw.rstrip("\n")
        if re.match(r'^\s*metadata:\s*$', line):
            section = "metadata"
            continue
        if re.match(r'^\s*spec:\s*$', line):
            section = "spec"
            continue
        if re.match(r'^\s*names:\s*$', line):
            section = "names"
            continue

        m = re.match(r'^\s*name:\s*("?[^"]+"?|\S+)\s*$', line)
        if m and section == "metadata" and name is None:
            name = m.group(1).strip('"')
            continue

        m = re.match(r'^\s*group:\s*("?[^"]+"?|\S+)\s*$', line)
        if m and section == "spec":
            group = m.group(1).strip('"')
            continue

        m = re.match(r'^\s*plural:\s*("?[^"]+"?|\S+)\s*$', line)
        if m and section == "names":
            plural = m.group(1).strip('"')
            continue
    return name, plural, group

failed = False
for path in sorted(glob.glob("pkg/cvo/testdata/majorversiontest-v5/release-manifests/*.yaml")):
    text = open(path, encoding="utf-8").read()
    if "kind: CustomResourceDefinition" not in text:
        continue
    name, plural, group = parse_fields(path)
    if not (name and plural and group):
        continue
    expected = f"{plural}.{group}"
    if name != expected:
        failed = True
        print(f"{path}: metadata.name={name!r}, expected={expected!r}")

if failed:
    sys.exit(1)

print("All CRD metadata.name values match <plural>.<group>.")
PY
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml`
around lines 4 - 11, The CRD's metadata.name is incorrect — it should be the
fully-qualified "<plural>.<group>" value; update metadata.name from "noversion"
to "noversions.test.io" so that metadata.name equals spec.names.plural + "." +
spec.group (ensure fields referenced: metadata.name, spec.names.plural,
spec.group, kind: NoVersion).
🧹 Nitpick comments (1)
pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml (1)

3-13: CRD naming convention: metadata.name should be {plural}.{group}

Kubernetes CRDs require metadata.name to follow the pattern {spec.names.plural}.{spec.group}. For this CRD, it should be version4onlies.test.io rather than version4only.

Since this is test data for manifest filtering logic (not applied to a real cluster), this may be intentional for simplicity. However, aligning with the real CRD naming convention would make the test data more representative.

Suggested fix
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
-  name: version4only
+  name: version4onlies.test.io
   annotations:
     include.release.openshift.io/self-managed-high-availability: "true"
     release.openshift.io/major-version: "4"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml`
around lines 3 - 13, The CRD's metadata.name is incorrect: Kubernetes requires
metadata.name to be "{spec.names.plural}.{spec.group}"; update the metadata.name
value from "version4only" to "version4onlies.test.io" so it matches
spec.names.plural ("version4onlies") and spec.group ("test.io") for the
Version4Only CRD entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml`:
- Around line 4-11: The CRD's metadata.name is incorrect — it should be the
fully-qualified "<plural>.<group>" value; update metadata.name from "noversion"
to "noversions.test.io" so that metadata.name equals spec.names.plural + "." +
spec.group (ensure fields referenced: metadata.name, spec.names.plural,
spec.group, kind: NoVersion).

---

Nitpick comments:
In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml`:
- Around line 3-13: The CRD's metadata.name is incorrect: Kubernetes requires
metadata.name to be "{spec.names.plural}.{spec.group}"; update the metadata.name
value from "version4only" to "version4onlies.test.io" so it matches
spec.names.plural ("version4onlies") and spec.group ("test.io") for the
Version4Only CRD entry.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: a30e62f6-db56-4087-b9c8-63ce0a309981

📥 Commits

Reviewing files that changed from the base of the PR and between ede695d and 47b4565.

⛔ Files ignored due to path filters (21)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/types_backup.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/library-go/pkg/manifest/manifest.go is excluded by !**/vendor/**, !vendor/**
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (17)
  • go.mod
  • lib/manifest/manifest.go
  • pkg/cvo/cvo_scenarios_test.go
  • pkg/cvo/featuregate_integration_test.go
  • pkg/cvo/sync_worker.go
  • pkg/cvo/testdata/majorversiontest-v5/manifests/.gitkeep
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_40_version-4-or-5.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/image-references
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/release-metadata
  • pkg/payload/payload.go
  • pkg/payload/payload_test.go
  • pkg/payload/render.go
  • pkg/payload/render_test.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • pkg/cvo/featuregate_integration_test.go
  • go.mod
  • pkg/cvo/sync_worker.go
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/release-metadata
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml

@JoelSpeed JoelSpeed force-pushed the major-version-inclusion branch from 47b4565 to 594b873 Compare March 5, 2026 11:57
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 5, 2026

@JoelSpeed: This pull request references OCPSTRAT-2876 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 feature to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This introduces a new CVO manifest filter based on the OCP major version.

The intended usage would allow folks to say "this manifest should be deployed on OCP 5 and skipped on OCP 4"

The library-go component here is limiting this feature to FeatureGate and CustomResourceDefinition only for now.

This is not intended for use beyond the feature gating mechanisms we have today. We expect FeatureGate and CustomResourceDefinition yamls to vary by release, but all other inclusion/exclusion should be handled by existing mechanisms like the feature-gate inclusion mechanism.

Example usage:

release.openshift.io/major-version: 5,6,7

Summary by CodeRabbit

  • New Features

  • Release manifests can be filtered by release major version, enabling version-aware inclusion during payload rendering and sync.

  • Tests

  • Added comprehensive unit and integration tests validating major-version-based manifest filtering and rendering across many scenarios.

  • Chores

  • Updated module dependency versions and aligned replace directives for consistent builds.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (3)
go.mod (1)

37-37: ⚠️ Potential issue | 🟠 Major

Avoid merging with a personal fork replacement in go.mod.

At Line 37, github.com/openshift/library-go is replaced with a personal fork. This should be removed (or limited to local/dev-only workflows) before merge to preserve provenance and reproducibility.

Suggested change
-replace github.com/openshift/library-go => github.com/JoelSpeed/library-go v0.0.0-20260130121715-6e5ccfd0da42
#!/bin/bash
set -euo pipefail

# Verify whether personal/library fork replacements remain in module file.
rg -n '^replace\s+github.com/openshift/library-go' go.mod

# Show required library-go entry for upstream pin visibility.
rg -n 'github.com/openshift/library-go\s+v' go.mod
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@go.mod` at line 37, Remove the personal-fork replace directive for
github.com/openshift/library-go in go.mod (the line "replace
github.com/openshift/library-go => github.com/JoelSpeed/library-go ...") before
merging; either delete that replace, scope it to local/dev-only via a separate
go.work or developer-only patch, or replace it with the appropriate upstream
module version pin so provenance is preserved and builds are reproducible.
pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml (1)

1-19: ⚠️ Potential issue | 🟡 Minor

Use valid CRD name format (<plural>.<group>).

The CRD metadata.name must follow the Kubernetes naming convention: <spec.names.plural>.<spec.group>. Currently set to noversion, but should be noversions.test.io to match spec.names.plural: noversions and spec.group: test.io.

Suggested fix
 metadata:
-  name: noversion
+  name: noversions.test.io
   annotations:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml`
around lines 1 - 19, metadata.name is not following the `<plural>.<group>`
convention: update the CRD's metadata.name to match spec.names.plural and
spec.group by setting it to "noversions.test.io" (ensure you modify the
metadata.name field in the CRD entry where metadata.name is currently
"noversion" so it equals spec.names.plural + "." + spec.group).
pkg/cvo/sync_worker.go (1)

451-452: ⚠️ Potential issue | 🟠 Major

Use target payload major version for implicit capability evaluation.

At line 452, w.payload.ParsedVersion.Major (current payload) is passed, but payloadUpdate.ParsedVersion.Major (target payload) should be used. During cross-major upgrades (e.g., 4→5), evaluating update manifests against the current version could compute incorrect implicitly-enabled capabilities.

Suggested fix
 	if w.payload != nil {
 		implicitlyEnabledCaps = capability.SortedList(payload.GetImplicitlyEnabledCapabilities(payloadUpdate.Manifests, w.payload.Manifests,
-			work.Capabilities, work.EnabledFeatureGates, ptr.To(w.payload.ParsedVersion.Major)))
+			work.Capabilities, work.EnabledFeatureGates, ptr.To(payloadUpdate.ParsedVersion.Major)))
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cvo/sync_worker.go` around lines 451 - 452, The call computing
implicitlyEnabledCaps uses the current payload major version
(w.payload.ParsedVersion.Major) but should use the target update's major
version; update the argument passed to payload.GetImplicitlyEnabledCapabilities
(inside capability.SortedList(...) that assigns implicitlyEnabledCaps) to use
payloadUpdate.ParsedVersion.Major instead of w.payload.ParsedVersion.Major so
implicit capability evaluation is performed against the target payload version.
🧹 Nitpick comments (1)
pkg/payload/render_test.go (1)

277-306: Consider removing namespace from CRD test manifests.

CRDs are cluster-scoped resources and don't have a namespace field in their metadata. While this may not break the test since it's just checking file inclusion/exclusion, it creates technically invalid CRD manifests.

💡 Suggested fix
 func createTestManifestYAML(apiVersion, kind, name string, annotations map[string]string) string {
 	yaml := `apiVersion: ` + apiVersion + `
 kind: ` + kind + `
 metadata:
-  name: ` + name + `
-  namespace: test-namespace`
+  name: ` + name
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/payload/render_test.go` around lines 277 - 306, The
createTestManifestYAML helper currently always injects a namespace into metadata
which produces invalid CRD manifests; update createTestManifestYAML so it omits
the "namespace: test-namespace" line when the manifest represents a
cluster-scoped CRD (e.g. when kind == "CustomResourceDefinition" and/or
apiVersion indicates apiextensions.k8s.io/v1). Keep the metadata block and
annotations for all kinds, but conditionally build the metadata string without
the namespace for CRDs so the output is valid cluster-scoped YAML.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@go.mod`:
- Line 37: Remove the personal-fork replace directive for
github.com/openshift/library-go in go.mod (the line "replace
github.com/openshift/library-go => github.com/JoelSpeed/library-go ...") before
merging; either delete that replace, scope it to local/dev-only via a separate
go.work or developer-only patch, or replace it with the appropriate upstream
module version pin so provenance is preserved and builds are reproducible.

In `@pkg/cvo/sync_worker.go`:
- Around line 451-452: The call computing implicitlyEnabledCaps uses the current
payload major version (w.payload.ParsedVersion.Major) but should use the target
update's major version; update the argument passed to
payload.GetImplicitlyEnabledCapabilities (inside capability.SortedList(...) that
assigns implicitlyEnabledCaps) to use payloadUpdate.ParsedVersion.Major instead
of w.payload.ParsedVersion.Major so implicit capability evaluation is performed
against the target payload version.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml`:
- Around line 1-19: metadata.name is not following the `<plural>.<group>`
convention: update the CRD's metadata.name to match spec.names.plural and
spec.group by setting it to "noversions.test.io" (ensure you modify the
metadata.name field in the CRD entry where metadata.name is currently
"noversion" so it equals spec.names.plural + "." + spec.group).

---

Nitpick comments:
In `@pkg/payload/render_test.go`:
- Around line 277-306: The createTestManifestYAML helper currently always
injects a namespace into metadata which produces invalid CRD manifests; update
createTestManifestYAML so it omits the "namespace: test-namespace" line when the
manifest represents a cluster-scoped CRD (e.g. when kind ==
"CustomResourceDefinition" and/or apiVersion indicates apiextensions.k8s.io/v1).
Keep the metadata block and annotations for all kinds, but conditionally build
the metadata string without the namespace for CRDs so the output is valid
cluster-scoped YAML.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 2be614e1-9314-4a05-a3bf-973f15cfc63b

📥 Commits

Reviewing files that changed from the base of the PR and between 47b4565 and 594b873.

⛔ Files ignored due to path filters (21)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/types_backup.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/library-go/pkg/manifest/manifest.go is excluded by !**/vendor/**, !vendor/**
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (17)
  • go.mod
  • lib/manifest/manifest.go
  • pkg/cvo/cvo_scenarios_test.go
  • pkg/cvo/featuregate_integration_test.go
  • pkg/cvo/sync_worker.go
  • pkg/cvo/testdata/majorversiontest-v5/manifests/.gitkeep
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_40_version-4-or-5.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/image-references
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/release-metadata
  • pkg/payload/payload.go
  • pkg/payload/payload_test.go
  • pkg/payload/render.go
  • pkg/payload/render_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • pkg/payload/payload.go
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/release-metadata
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml

@JoelSpeed JoelSpeed force-pushed the major-version-inclusion branch from 594b873 to f327a2f Compare March 6, 2026 11:26
JoelSpeed and others added 2 commits March 6, 2026 11:29
@JoelSpeed JoelSpeed force-pushed the major-version-inclusion branch from f327a2f to 879afb3 Compare March 6, 2026 11:29
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 6, 2026

@JoelSpeed: This pull request references OCPSTRAT-2876 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 feature to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This introduces a new CVO manifest filter based on the OCP major version.

The intended usage would allow folks to say "this manifest should be deployed on OCP 5 and skipped on OCP 4"

The library-go component here is limiting this feature to FeatureGate and CustomResourceDefinition only for now.

This is not intended for use beyond the feature gating mechanisms we have today. We expect FeatureGate and CustomResourceDefinition yamls to vary by release, but all other inclusion/exclusion should be handled by existing mechanisms like the feature-gate inclusion mechanism.

Example usage:

release.openshift.io/major-version: 5,6,7

Summary by CodeRabbit

  • New Features

  • Release manifests can be filtered by release major version; rendering and sync now respect payload major-version metadata.

  • Tests

  • Added unit and integration tests covering major-version-based manifest inclusion/exclusion and rendering scenarios.

  • Chores

  • Upgraded Go toolchain and numerous module dependencies; updated metadata parsing to support semantic release versions.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
pkg/payload/render_test.go (1)

254-266: Assert against unexpected extra manifests as well.

Current checks validate expected includes/excludes, but they still pass if an unexpected manifest is rendered.

Proposed assertion hardening
 			// Verify expected exclusions
 			for _, expectedExcludedName := range tt.expectedExclusions {
 				if includedManifests[expectedExcludedName] {
 					t.Errorf("Expected manifest %s to be excluded, but it was found in output", expectedExcludedName)
 				}
 			}
+
+			// Verify there are no unexpected inclusions
+			expectedSet := sets.New[string](tt.expectedInclusions...)
+			for manifestName := range includedManifests {
+				if !expectedSet.Has(manifestName) {
+					t.Errorf("Unexpected manifest %s was included", manifestName)
+				}
+			}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/payload/render_test.go` around lines 254 - 266, Test currently only
checks expected inclusions/exclusions but allows unexpected extra manifests;
after the existing loops in the test (which reference includedManifests,
tt.expectedInclusions, tt.expectedExclusions) add a check that no extra
manifests were produced: either assert len(includedManifests) ==
len(tt.expectedInclusions) or iterate over keys in includedManifests and fail if
any key is not present in tt.expectedInclusions; this ensures any unexpected
rendered manifest causes the test to fail.
pkg/payload/render.go (1)

290-293: Consider using semver.ParseTolerant() for v-prefixed version robustness.

semver.Parse() strictly rejects leading v and will fail on versions like v1.2.3. For Cincinnati metadata versions, using semver.ParseTolerant() is the idiomatic approach—it strips the v prefix automatically and is already available in the library.

Also update the error format to use %w instead of %v for consistency with pkg/payload/payload.go:

Suggested improvement
-	parsedVersion, err := semver.Parse(release.Version)
+	parsedVersion, err := semver.ParseTolerant(release.Version)
 	if err != nil {
-		return semver.Version{}, fmt.Errorf("cincinnati metadata version %q is not a valid semantic version: %v", release.Version, err)
+		return semver.Version{}, fmt.Errorf("cincinnati metadata version %q is not a valid semantic version: %w", release.Version, err)
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/payload/render.go` around lines 290 - 293, Replace the strict
semver.Parse call with semver.ParseTolerant to accept v-prefixed versions (i.e.,
change semver.Parse(release.Version) to semver.ParseTolerant(release.Version)),
and update the error construction to wrap the original error with %w (e.g.,
fmt.Errorf(...: %w, err)) so parsedVersion, release.Version and the returned
error use the tolerant parser and proper error wrapping.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/manifest/manifest.go`:
- Around line 92-96: The code dereferences optional Capabilities
(currentManifestInclusionConfiguration.Capabilities.EnabledCapabilities) without
a nil check; guard the pointer by checking
currentManifestInclusionConfiguration.Capabilities != nil before accessing
EnabledCapabilities and treat a nil Capabilities as an empty set/slice when
building the sets.New call, so the Difference call uses an empty set instead of
panicking; apply the same nil-guarding approach anywhere Capabilities is
dereferenced (refer to updateManifest.GetManifestCapabilities(),
currentManifest.GetManifestCapabilities(), and
currentManifestInclusionConfiguration.Capabilities.EnabledCapabilities) and
return the union logic unchanged but using an empty set when Capabilities is
nil.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml`:
- Line 4: The CRD's metadata.name must follow the Kubernetes API-valid form
"<spec.names.plural>.<spec.group>" for apiextensions.k8s.io/v1; update
metadata.name from "version5only" to match spec.names.plural and spec.group
(i.e., "version5onlies.test.io") so it equals spec.names.plural + "." +
spec.group, and verify the same correction is applied where those fields are
referenced elsewhere in this manifest (the spec.names.plural and spec.group
entries).

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml`:
- Around line 4-12: Replace the invalid CRD metadata.name value with the
canonical "<spec.names.plural>.<spec.group>" form: set metadata.name to the
concatenation of spec.names.plural and spec.group (e.g., change metadata.name
from "excludeversion3" to "excludeversion3s.test.io") so it matches the CRD
spec; update the metadata.name field in the manifest alongside spec.names.plural
and spec.group to ensure they align.

---

Nitpick comments:
In `@pkg/payload/render_test.go`:
- Around line 254-266: Test currently only checks expected inclusions/exclusions
but allows unexpected extra manifests; after the existing loops in the test
(which reference includedManifests, tt.expectedInclusions,
tt.expectedExclusions) add a check that no extra manifests were produced: either
assert len(includedManifests) == len(tt.expectedInclusions) or iterate over keys
in includedManifests and fail if any key is not present in
tt.expectedInclusions; this ensures any unexpected rendered manifest causes the
test to fail.

In `@pkg/payload/render.go`:
- Around line 290-293: Replace the strict semver.Parse call with
semver.ParseTolerant to accept v-prefixed versions (i.e., change
semver.Parse(release.Version) to semver.ParseTolerant(release.Version)), and
update the error construction to wrap the original error with %w (e.g.,
fmt.Errorf(...: %w, err)) so parsedVersion, release.Version and the returned
error use the tolerant parser and proper error wrapping.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: adc636c4-f2ae-43e9-acd1-c77d555e6102

📥 Commits

Reviewing files that changed from the base of the PR and between 594b873 and 879afb3.

⛔ Files ignored due to path filters (283)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/go-logr/logr/.golangci.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-logr/logr/funcr/funcr.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/AUTHORS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/CONTRIBUTORS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/clone.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/custom_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/decode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/deprecated.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/discard.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/duration.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/duration_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/encode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/encode_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/equal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/extensions.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/extensions_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/lib.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/lib_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/message_set.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_reflect.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/properties.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/properties_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/skip_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_marshal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_merge.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_unmarshal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/text.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/text_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/text_parser.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/timestamp.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/wrappers.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/CHANGELOG.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/format/format.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/gomega_dsl.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/assertion.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/async_assertion.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/duration_bundle.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/gomega.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/polling_signal_error.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/vetoptdesc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/and.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_directory.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_element_of_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_false_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_identical_to.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_true_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/consist_of.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/equal_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_each_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_exact_elements.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_existing_field_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_field.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_header_with_value_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_len_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_value.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_iter.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_noiter.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_error_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_json_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/not.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/or.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/panic_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/receive_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/satisfy_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/semi_structured_data_support.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/succeed_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/type_support.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/with_transform.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/types/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_ingress.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_insights.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_network.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_networks.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_openshift-controller-manager_01_builds.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_backup.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_crio_credential_provider_config.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_insights.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha2/types_insights.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha2/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/legacyfeaturegates.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/util.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/types_network.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_00_cluster-version-operator_01_clusterversionoperators-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_00_cluster-version-operator_01_clusterversionoperators-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_00_cluster-version-operator_01_clusterversionoperators.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_10_etcd_01_etcdbackups-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_10_etcd_01_etcdbackups-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_10_etcd_01_etcdbackups.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/security/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/security/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/acceptrisk.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/alibabacloudplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/alibabacloudresourcetag.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/apiserver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/apiserverencryption.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/apiservernamedservingcert.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/apiserverservingcerts.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/apiserverspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/audit.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/auditcustomrule.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/authenticationspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/authenticationstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/awsdnsspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/awsingressspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/awskmsconfig.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/awsplatformspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/awsplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/awsresourcetag.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/awsserviceendpoint.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/azureplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/azureresourcetag.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/baremetalplatformloadbalancer.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/baremetalplatformspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/baremetalplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/basicauthidentityprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/build.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/builddefaults.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/buildoverrides.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/buildspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/cloudcontrollermanagerstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/cloudloadbalancerconfig.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/cloudloadbalancerips.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clustercondition.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusterimagepolicy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusterimagepolicyspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusterimagepolicystatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusternetworkentry.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusteroperator.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusteroperatorstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusteroperatorstatuscondition.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusterversion.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusterversioncapabilitiesspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusterversioncapabilitiesstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusterversionspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/clusterversionstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/componentoverride.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/componentroutespec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/componentroutestatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/conditionalupdate.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/conditionalupdaterisk.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/configmapfilereference.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/configmapnamereference.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/console.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/consoleauthentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/consolespec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/consolestatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/custom.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/customfeaturegates.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/customtlsprofile.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/deprecatedwebhooktokenauthenticator.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/dns.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/dnsplatformspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/dnsspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/dnszone.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/equinixmetalplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/externalipconfig.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/externalippolicy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/externalplatformspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/externalplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/extramapping.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/featuregate.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/featuregateattributes.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/featuregatedetails.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/featuregateselection.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/featuregatestatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gatherconfig.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gathererconfig.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gatherers.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gcpplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gcpresourcelabel.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gcpresourcetag.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/githubidentityprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gitlabidentityprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/googleidentityprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/htpasswdidentityprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/hubsource.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/hubsourcestatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/ibmcloudplatformspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/ibmcloudplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/ibmcloudserviceendpoint.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/identityprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/identityproviderconfig.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/image.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagecontentpolicy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagecontentpolicyspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagedigestmirrors.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagedigestmirrorset.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagedigestmirrorsetspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagelabel.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagepolicy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagepolicyfulciocawithrekorrootoftrust.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagepolicypkirootoftrust.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagepolicypublickeyrootoftrust.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagepolicyspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagepolicystatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagesigstoreverificationpolicy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagespec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagestatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagetagmirrors.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagetagmirrorset.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/imagetagmirrorsetspec.go is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (17)
  • go.mod
  • lib/manifest/manifest.go
  • pkg/cvo/cvo_scenarios_test.go
  • pkg/cvo/featuregate_integration_test.go
  • pkg/cvo/sync_worker.go
  • pkg/cvo/testdata/majorversiontest-v5/manifests/.gitkeep
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_10_no-version.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_40_version-4-or-5.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/image-references
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/release-metadata
  • pkg/payload/payload.go
  • pkg/payload/payload_test.go
  • pkg/payload/render.go
  • pkg/payload/render_test.go
✅ Files skipped from review due to trivial changes (1)
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/image-references
🚧 Files skipped from review as they are similar to previous changes (4)
  • pkg/cvo/featuregate_integration_test.go
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_40_version-4-or-5.yaml
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/release-metadata
  • pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_20_version-4-only.yaml

Comment on lines 92 to 96
newImplicitlyEnabled := sets.New[configv1.ClusterVersionCapability](updateManifest.GetManifestCapabilities()...).
Difference(sets.New[configv1.ClusterVersionCapability](currentManifest.GetManifestCapabilities()...)).
Difference(currentImplicitlyEnabled).
Difference(sets.New[configv1.ClusterVersionCapability](manifestInclusionConfiguration.Capabilities.EnabledCapabilities...))
Difference(sets.New[configv1.ClusterVersionCapability](currentManifestInclusionConfiguration.Capabilities.EnabledCapabilities...))
ret = ret.Union(newImplicitlyEnabled)
Copy link

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:

# First, let's locate and examine the manifest.go file
find . -name "manifest.go" | grep -E "lib/manifest"

Repository: openshift/cluster-version-operator

Length of output: 104


🏁 Script executed:

# Read the relevant section of the file to understand the context
head -c 20000 lib/manifest/manifest.go | tail -c 10000

Repository: openshift/cluster-version-operator

Length of output: 4937


🏁 Script executed:

# Get the specific lines in question (92-96) with surrounding context
sed -n '75,110p' lib/manifest/manifest.go

Repository: openshift/cluster-version-operator

Length of output: 1495


🏁 Script executed:

# Find the struct definition for InclusionConfiguration to understand the Capabilities field
rg "type.*InclusionConfiguration" -A 10

Repository: openshift/cluster-version-operator

Length of output: 837


🏁 Script executed:

# Search for the Capabilities field definition
rg "Capabilities.*\[\]" lib/manifest/ -B 2 -A 2

Repository: openshift/cluster-version-operator

Length of output: 60


🏁 Script executed:

# Search for callers of GetImplicitlyEnabledCapabilities
rg "GetImplicitlyEnabledCapabilities" -B 2 -A 5

Repository: openshift/cluster-version-operator

Length of output: 4565


🏁 Script executed:

# Check if there's a nil guard before line 96 that wasn't visible
sed -n '85,100p' lib/manifest/manifest.go

Repository: openshift/cluster-version-operator

Length of output: 995


Guard optional Capabilities before dereference.

Capabilities is documented as optional but the code dereferences it unconditionally without a nil check, which can cause a panic. Since Capabilities *configv1.ClusterVersionCapabilitiesStatus is a pointer field with documentation stating "if non-nil", the function must handle the nil case.

Suggested fix
+			enabledCaps := sets.Set[configv1.ClusterVersionCapability]{}
+			if currentManifestInclusionConfiguration.Capabilities != nil {
+				enabledCaps = sets.New[configv1.ClusterVersionCapability](
+					currentManifestInclusionConfiguration.Capabilities.EnabledCapabilities...,
+				)
+			}
 			newImplicitlyEnabled := sets.New[configv1.ClusterVersionCapability](updateManifest.GetManifestCapabilities()...).
 				Difference(sets.New[configv1.ClusterVersionCapability](currentManifest.GetManifestCapabilities()...)).
 				Difference(currentImplicitlyEnabled).
-				Difference(sets.New[configv1.ClusterVersionCapability](currentManifestInclusionConfiguration.Capabilities.EnabledCapabilities...))
+				Difference(enabledCaps)
📝 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
newImplicitlyEnabled := sets.New[configv1.ClusterVersionCapability](updateManifest.GetManifestCapabilities()...).
Difference(sets.New[configv1.ClusterVersionCapability](currentManifest.GetManifestCapabilities()...)).
Difference(currentImplicitlyEnabled).
Difference(sets.New[configv1.ClusterVersionCapability](manifestInclusionConfiguration.Capabilities.EnabledCapabilities...))
Difference(sets.New[configv1.ClusterVersionCapability](currentManifestInclusionConfiguration.Capabilities.EnabledCapabilities...))
ret = ret.Union(newImplicitlyEnabled)
enabledCaps := sets.Set[configv1.ClusterVersionCapability]{}
if currentManifestInclusionConfiguration.Capabilities != nil {
enabledCaps = sets.New[configv1.ClusterVersionCapability](
currentManifestInclusionConfiguration.Capabilities.EnabledCapabilities...,
)
}
newImplicitlyEnabled := sets.New[configv1.ClusterVersionCapability](updateManifest.GetManifestCapabilities()...).
Difference(sets.New[configv1.ClusterVersionCapability](currentManifest.GetManifestCapabilities()...)).
Difference(currentImplicitlyEnabled).
Difference(enabledCaps)
ret = ret.Union(newImplicitlyEnabled)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/manifest/manifest.go` around lines 92 - 96, The code dereferences
optional Capabilities
(currentManifestInclusionConfiguration.Capabilities.EnabledCapabilities) without
a nil check; guard the pointer by checking
currentManifestInclusionConfiguration.Capabilities != nil before accessing
EnabledCapabilities and treat a nil Capabilities as an empty set/slice when
building the sets.New call, so the Difference call uses an empty set instead of
panicking; apply the same nil-guarding approach anywhere Capabilities is
dereferenced (refer to updateManifest.GetManifestCapabilities(),
currentManifest.GetManifestCapabilities(), and
currentManifestInclusionConfiguration.Capabilities.EnabledCapabilities) and
return the union logic unchanged but using an empty set when Capabilities is
nil.

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: version5only
Copy link

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
# Step 1: Check the target file content
echo "=== File Content ==="
cat -n "pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml"

echo ""
echo "=== Running verification script ==="
python - <<'PY'
import glob, sys, yaml

failed = False
for path in glob.glob("pkg/cvo/testdata/**/release-manifests/*.yaml", recursive=True):
    with open(path, "r", encoding="utf-8") as f:
        for doc in yaml.safe_load_all(f):
            if not isinstance(doc, dict):
                continue
            if doc.get("kind") != "CustomResourceDefinition":
                continue
            api = doc.get("apiVersion", "")
            if not api.startswith("apiextensions.k8s.io/"):
                continue

            spec = doc.get("spec") or {}
            names = spec.get("names") or {}
            group = spec.get("group")
            plural = names.get("plural")
            actual = (doc.get("metadata") or {}).get("name")
            expected = f"{plural}.{group}" if plural and group else None

            if expected and actual != expected:
                failed = True
                print(f"{path}: metadata.name={actual!r}, expected={expected!r}")

if failed:
    sys.exit(1)
print("All CRD fixture names match <plural>.<group>.")
PY
echo "Script exit code: $?"

Repository: openshift/cluster-version-operator

Length of output: 1473


CRD name does not match API-valid format for apiextensions.k8s.io/v1.

Line 4, metadata.name: version5only does not match the required CRD naming form <spec.names.plural>.<spec.group>, which is version5onlies.test.io (lines 12 and 9). This affects the validity of the test fixture when applied to a Kubernetes cluster.

Suggested fix
 metadata:
-  name: version5only
+  name: version5onlies.test.io

Also applies to: 9-9, 12-12

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_30_version-5-only.yaml`
at line 4, The CRD's metadata.name must follow the Kubernetes API-valid form
"<spec.names.plural>.<spec.group>" for apiextensions.k8s.io/v1; update
metadata.name from "version5only" to match spec.names.plural and spec.group
(i.e., "version5onlies.test.io") so it equals spec.names.plural + "." +
spec.group, and verify the same correction is applied where those fields are
referenced elsewhere in this manifest (the spec.names.plural and spec.group
entries).

Comment on lines +4 to +12
name: excludeversion3
annotations:
include.release.openshift.io/self-managed-high-availability: "true"
release.openshift.io/major-version: "-3"
spec:
group: test.io
names:
kind: ExcludeVersion3
plural: excludeversion3s
Copy link

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:

# Read the actual file content
cat -n pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml

Repository: openshift/cluster-version-operator

Length of output: 670


🏁 Script executed:

# Check for other CRD examples in the same test directory
find pkg/cvo/testdata/majorversiontest-v5/release-manifests -name "*.yaml" -type f | head -20 | xargs grep -l "apiVersion.*apiextensions"

Repository: openshift/cluster-version-operator

Length of output: 491


🏁 Script executed:

# Examine a few other CRD manifests to check naming patterns
find pkg/cvo/testdata/majorversiontest-v5/release-manifests -name "*.yaml" -type f -exec grep -l "kind: CustomResourceDefinition" {} \; | head -3 | xargs -I {} sh -c 'echo "=== {} ===" && head -20 "{}"'

Repository: openshift/cluster-version-operator

Length of output: 1715


🌐 Web query:

Kubernetes CRD metadata.name requirement apiextensions.k8s.io/v1

💡 Result:

For a CustomResourceDefinition (apiVersion: apiextensions.k8s.io/v1), the CRD object’s metadata.name is required and must:

  • Match the spec fields and be in the form:
    <spec.names.plural>.<spec.group> (for example, crontabs.stable.example.com). [1]
  • Be a valid DNS subdomain name derived from the resource name and API group. [2]

Sources: Kubernetes CRD task docs show the explicit <plural>.<group> requirement in the CRD example. [1] Kubernetes “Custom Resources” concept docs describe the DNS-subdomain constraint for the CRD object name. [2]


🏁 Script executed:

# Check if these test manifests are actually validated or used as test data
find pkg/cvo/testdata -name "*.yaml" | head -5 | xargs grep -l "kind: CustomResourceDefinition" | xargs head -30

Repository: openshift/cluster-version-operator

Length of output: 1090


🏁 Script executed:

# Check the test files that use these manifests to understand their purpose
fd -e "test.go" pkg/cvo | head -5 | xargs grep -l "majorversiontest-v5" | head -2

Repository: openshift/cluster-version-operator

Length of output: 411


🏁 Script executed:

# Search for test code that uses these majorversiontest-v5 manifests
rg "majorversiontest-v5" -t go pkg/cvo

Repository: openshift/cluster-version-operator

Length of output: 186


🏁 Script executed:

# Check if there's any validation or loading of these CRD manifests in tests
rg "0000_50_exclude-version-3" pkg/cvo

Repository: openshift/cluster-version-operator

Length of output: 60


🏁 Script executed:

# Look for any Kubernetes CRD validation being performed in the codebase
rg "metadata\.name" pkg/cvo -t yaml | grep -i customresource

Repository: openshift/cluster-version-operator

Length of output: 60


🏁 Script executed:

# Check the test code to understand what it's doing with these manifests
sed -n '1,100p' pkg/cvo/cvo_scenarios_test.go | grep -A 30 "setupCVOTest"

Repository: openshift/cluster-version-operator

Length of output: 1570


🏁 Script executed:

# Look for any comments about intentional malformation or test purposes in the test data directory
find pkg/cvo/testdata/majorversiontest-v5 -name "README*" -o -name "*.md" | xargs cat 2>/dev/null

Repository: openshift/cluster-version-operator

Length of output: 60


🏁 Script executed:

# Check if this test data directory has any documentation or comments about intended behavior
ls -la pkg/cvo/testdata/majorversiontest-v5/

Repository: openshift/cluster-version-operator

Length of output: 314


🏁 Script executed:

# Look at the test that uses this data to see if it's testing error handling or valid scenarios
rg -A 50 "setupCVOTest.*majorversiontest-v5" pkg/cvo/cvo_scenarios_test.go | head -80

Repository: openshift/cluster-version-operator

Length of output: 1514


🏁 Script executed:

# Check if these CRDs would actually be applied or if they're just parsed as test fixtures
rg "applyManifests\|LoadManifests\|parseManifests" pkg/cvo -t go | head -10

Repository: openshift/cluster-version-operator

Length of output: 60


🏁 Script executed:

# Verify the test expectations more closely - what does GetName() return?
rg "GetName\(\)" pkg/cvo/cvo_scenarios_test.go -A 2 -B 2 | head -30

Repository: openshift/cluster-version-operator

Length of output: 853


🏁 Script executed:

# Check if there are any other test directories with similar patterns to understand this design
find pkg/cvo/testdata -type d | head -10

Repository: openshift/cluster-version-operator

Length of output: 457


🏁 Script executed:

# Look for any documentation or README in the testdata directory
find pkg/cvo/testdata -type f \( -name "README*" -o -name "*.md" -o -name "*.txt" \) | xargs cat 2>/dev/null

Repository: openshift/cluster-version-operator

Length of output: 60


🏁 Script executed:

# Check how the manifests are loaded and processed - are they validated?
rg "LoadPayload\|loadManifest\|parseManifest" pkg/cvo -t go -A 3 | head -40

Repository: openshift/cluster-version-operator

Length of output: 60


🏁 Script executed:

# Check if there's any code that would validate CRD metadata.name format
rg "metadata.name\|spec.names.plural\|spec.group" pkg/cvo -t go | head -20

Repository: openshift/cluster-version-operator

Length of output: 60


🏁 Script executed:

# Look at what the test actually checks - does it validate the manifests or just the behavior?
sed -n '1,150p' pkg/cvo/cvo_scenarios_test.go | tail -60

Repository: openshift/cluster-version-operator

Length of output: 2147


🏁 Script executed:

# Final confirmation: check the exact content one more time to match review snippet
sed -n '3,12p' pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml

Repository: openshift/cluster-version-operator

Length of output: 330


Use a valid CRD metadata.name (<plural>.<group>).

This manifest sets metadata.name to excludeversion3, but per the Kubernetes CustomResourceDefinition specification, it must match the format <spec.names.plural>.<spec.group>. The correct value is excludeversion3s.test.io.

Suggested fix
 metadata:
-  name: excludeversion3
+  name: excludeversion3s.test.io
📝 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
name: excludeversion3
annotations:
include.release.openshift.io/self-managed-high-availability: "true"
release.openshift.io/major-version: "-3"
spec:
group: test.io
names:
kind: ExcludeVersion3
plural: excludeversion3s
name: excludeversion3s.test.io
annotations:
include.release.openshift.io/self-managed-high-availability: "true"
release.openshift.io/major-version: "-3"
spec:
group: test.io
names:
kind: ExcludeVersion3
plural: excludeversion3s
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@pkg/cvo/testdata/majorversiontest-v5/release-manifests/0000_50_exclude-version-3.yaml`
around lines 4 - 12, Replace the invalid CRD metadata.name value with the
canonical "<spec.names.plural>.<spec.group>" form: set metadata.name to the
concatenation of spec.names.plural and spec.group (e.g., change metadata.name
from "excludeversion3" to "excludeversion3s.test.io") so it matches the CRD
spec; update the metadata.name field in the manifest alongside spec.names.plural
and spec.group to ensure they align.

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

Labels

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.

3 participants