Skip to content

⚠️ ClusterExtensionRevision API Updates#2491

Merged
openshift-merge-bot[bot] merged 1 commit intooperator-framework:mainfrom
dtfranz:cer-api-edits
Feb 17, 2026
Merged

⚠️ ClusterExtensionRevision API Updates#2491
openshift-merge-bot[bot] merged 1 commit intooperator-framework:mainfrom
dtfranz:cer-api-edits

Conversation

@dtfranz
Copy link
Contributor

@dtfranz dtfranz commented Feb 6, 2026

Fixing some missing flags and godoc comments brought up via API review.

Reviewer Checklist

  • API Go Documentation
  • Tests: Unit Tests (and E2E Tests, if appropriate)
  • Comprehensive Commit Messages
  • Links to related GitHub Issue(s)

@netlify
Copy link

netlify bot commented Feb 6, 2026

Deploy Preview for olmv1 ready!

Name Link
🔨 Latest commit 1225187
🔍 Latest deploy log https://app.netlify.com/projects/olmv1/deploys/6992c6e02ea96900088ac8c8
😎 Deploy Preview https://deploy-preview-2491--olmv1.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@dtfranz dtfranz changed the title ⚠ ClusterExtensionRevision API Updates ⚠ WIP: ClusterExtensionRevision API Updates Feb 6, 2026
@dtfranz
Copy link
Contributor Author

dtfranz commented Feb 6, 2026

/hold

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Feb 6, 2026
@dtfranz dtfranz changed the title ⚠ WIP: ClusterExtensionRevision API Updates ⚠️ WIP: ClusterExtensionRevision API Updates Feb 6, 2026
@dtfranz dtfranz marked this pull request as draft February 6, 2026 07:12
@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 Feb 6, 2026
@codecov
Copy link

codecov bot commented Feb 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.45%. Comparing base (1624bed) to head (1225187).
⚠️ Report is 11 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2491      +/-   ##
==========================================
- Coverage   69.82%   69.45%   -0.37%     
==========================================
  Files         102      102              
  Lines        8496     8505       +9     
==========================================
- Hits         5932     5907      -25     
- Misses       2091     2129      +38     
+ Partials      473      469       -4     
Flag Coverage Δ
e2e 45.89% <0.00%> (-0.28%) ⬇️
experimental-e2e 12.78% <0.00%> (-0.12%) ⬇️
unit 57.89% <100.00%> (-0.09%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@pedjak pedjak left a comment

Choose a reason for hiding this comment

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

I would expect additional validation tests to add, given that we added a few more restrictions/checks in this PR. Like for checking min/max size of given arrays, etc.

//
// Once set, even if empty, the phases field is immutable.
//
// Each phase in the list must have a unique name. The maximum number of phases is 20.
Copy link
Contributor

Choose a reason for hiding this comment

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

should we also set the min number of phases to 1?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, unless we can think of a genuinely useful reason to create a no-op CER? I can't think of one though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Update: Looks like we've intentionally built in the ability to have phases initially unset, and allow the normally immutable list to be updated once. If we want to preserve that, we can't set the minimum length to 1 with omitempty present. Removing omitempty removes our ability to leave it unset. Is it vital that we keep this in place?

Copy link
Contributor

Choose a reason for hiding this comment

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

While we only use inline objects, it's ok to set a minimum. When we move to sharding, it could be that we'll want to create the ClusterExtensionRevision object first, then create the shards with the ownerref, then update the revision with the shard refs.

Copy link
Member

Choose a reason for hiding this comment

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

Here's the helm chunked secret implementation: https://github.com/operator-framework/helm-operator-plugins/blob/f1e4eaf3b3924d3339dda2eee7f4520c47fd6162/pkg/storage/chunked.go#L62-L90

There we precompute everything, then:

  1. Create the immutable index object with all of the chunk references pre-filled
  2. Create the immutable chunks with owner refs to the index

We can do the same with the CER right?

  1. Make its phases fully immutable
  2. Generate the phase object contents and figure out what the names are going to be so we can pre-fill references in the CER
  3. Generate the CER with the phase object references pre-filled
  4. Generate the phase objects with the CER ownerRef

That way:

  1. If we try to read the phases from the CER after 3, but before 4, we correctly get an error instead of incorrectly assuming there are no phases
  2. If the CER is deleted between 3 and 4, we'll end up putting an ownerref on the phase objects that for an object that is already deleted and garbage collect will automatically delete the phase objects.
  3. Phases are immutable and create-only and we don't have to handle errors that could occur on an attempt to update the phases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks Joe - agreed on these points, but this will take some more work beyond just the API changes. Can we take care of this as a separate issue? Or is getting in the full immutability for phases too critical?

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 9, 2026
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 9, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the ClusterExtensionRevision API surface (Go types + generated CRDs/manifests) to address gaps identified during API review, primarily by tightening schema requirements and improving documentation.

Changes:

  • Make spec.lifecycleState and per-object collisionProtection required (removing CRD defaults).
  • Add/clarify schema constraints for inline phases (e.g., max phases/objects) and expand lifecycle/phase documentation.
  • Update operator-controller generator/tests and API validation tests to populate newly-required fields.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
manifests/experimental.yaml Updates experimental manifest schema/docs to reflect new required fields and constraints.
manifests/experimental-e2e.yaml Mirrors the experimental schema/doc updates for e2e manifests.
helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensionrevisions.yaml Updates the shipped Helm CRD for ClusterExtensionRevision with the new requirements/validations.
api/v1/clusterextensionrevision_types.go Source-of-truth API changes: required markers, added validations/limits, doc updates.
api/v1/clusterextensionrevision_types_test.go Adds/updates envtest-backed validity/immutability tests for the new schema.
api/v1/validation_test.go Updates validation tests to set LifecycleState where required.
internal/operator-controller/applier/boxcutter.go Ensures generated revision objects always set CollisionProtection.
internal/operator-controller/applier/boxcutter_test.go Updates expectations to include CollisionProtection in generated revision objects.
Comments suppressed due to low confidence (1)

api/v1/clusterextensionrevision_types.go:60

  • LifecycleState is marked +required and the CRD now requires it, but the Go JSON tag still uses omitempty. This is inconsistent with other required fields in this repo (which typically omit omitempty) and can cause marshaling to silently drop the field when the zero value is present, producing invalid objects. Consider removing omitempty (and update any constructors/tests that currently rely on omitting the field, e.g. helpers that build ClusterExtensionRevisionSpec{Revision: ...} without a lifecycleState).
	// +required
	// +kubebuilder:validation:Enum=Active;Archived
	// +kubebuilder:validation:XValidation:rule="oldSelf == 'Active' || oldSelf == 'Archived' && oldSelf == self", message="cannot un-archive"
	LifecycleState ClusterExtensionRevisionLifecycleState `json:"lifecycleState,omitempty"`


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@dtfranz dtfranz force-pushed the cer-api-edits branch 2 times, most recently from 35e7673 to 66b75c9 Compare February 12, 2026 07:49
Copilot AI review requested due to automatic review settings February 12, 2026 07:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Fixing some missing flags and godoc comments brought up via API review.

Signed-off-by: Daniel Franz <dfranz@redhat.com>
@dtfranz dtfranz changed the title ⚠️ WIP: ClusterExtensionRevision API Updates ⚠️ ClusterExtensionRevision API Updates Feb 17, 2026
@dtfranz
Copy link
Contributor Author

dtfranz commented Feb 17, 2026

/unhold

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Feb 17, 2026
@dtfranz dtfranz marked this pull request as ready for review February 17, 2026 04:05
Copilot AI review requested due to automatic review settings February 17, 2026 04:05
@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 17, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +146 to +158
"phases entries must have no more than 50 objects": {
spec: ClusterExtensionRevisionSpec{
LifecycleState: ClusterExtensionRevisionLifecycleStateActive,
Revision: 1,
Phases: []ClusterExtensionRevisionPhase{
{
Name: "too-many-objects",
Objects: make([]ClusterExtensionRevisionObject, 51),
},
},
},
valid: false,
},
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

The test case "phases entries must have no more than 50 objects" creates 51 ClusterExtensionRevisionObject instances using make(), which initializes them with zero values. Since CollisionProtection is now a required field, all 51 objects will have an empty CollisionProtection value that doesn't match the enum constraint. This test will likely fail due to the missing required field rather than testing the maxItems validation as intended. Consider initializing the objects with a valid CollisionProtection value to ensure the test properly validates the maxItems constraint.

Copilot uses AI. Check for mistakes.
Comment on lines +138 to +145
"phases must have no more than 20 phases": {
spec: ClusterExtensionRevisionSpec{
LifecycleState: ClusterExtensionRevisionLifecycleStateActive,
Revision: 1,
Phases: make([]ClusterExtensionRevisionPhase, 21),
},
valid: false,
},
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

The test case "phases must have no more than 20 phases" creates 21 ClusterExtensionRevisionPhase instances using make(), which initializes them with zero values including empty Name strings and empty Objects slices. Since Name has minLength=1 and Objects is required, these phases will fail validation for missing required fields rather than testing the maxItems constraint on phases. Consider initializing the phases with valid Name values and at least one valid Object to ensure the test properly validates the 20-phase limit.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@pedjak pedjak left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Feb 17, 2026
@perdasilva
Copy link
Contributor

/approve

@openshift-ci
Copy link

openshift-ci bot commented Feb 17, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: perdasilva

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 17, 2026
@openshift-merge-bot openshift-merge-bot bot merged commit 130c987 into operator-framework:main Feb 17, 2026
36 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-diff-lint-override approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

Comments