Skip to content

Comments

🌱 Add collisionProtection inheritance hierarchy to ClusterExtensionRevision#2513

Merged
openshift-merge-bot[bot] merged 1 commit intooperator-framework:mainfrom
pedjak:OPRUN-4349
Feb 19, 2026
Merged

🌱 Add collisionProtection inheritance hierarchy to ClusterExtensionRevision#2513
openshift-merge-bot[bot] merged 1 commit intooperator-framework:mainfrom
pedjak:OPRUN-4349

Conversation

@pedjak
Copy link
Contributor

@pedjak pedjak commented Feb 17, 2026

Description

Add collisionProtection as a required field at the spec level and an optional field at the phase level, with inheritance resolution: object > phase > spec. This reduces verbosity by letting users set a single spec-level default instead of repeating the value on every object.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

Reviewer Checklist

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

Copilot AI review requested due to automatic review settings February 17, 2026 17:45
@netlify
Copy link

netlify bot commented Feb 17, 2026

Deploy Preview for olmv1 ready!

Name Link
🔨 Latest commit ffcdfc2
🔍 Latest deploy log https://app.netlify.com/projects/olmv1/deploys/6996fe9b9fa54a0009d42353
😎 Deploy Preview https://deploy-preview-2513--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.

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 to introduce a phases wrapper (.spec.phases) that supports collision protection inheritance (phases-level default → per-phase → per-object), and wires the new shape through controller logic, tests, and published CRD manifests.

Changes:

  • Restructure .spec.phases from []Phase to *ClusterExtensionRevisionPhases{ collisionProtection, items[] }, and make per-object collisionProtection optional.
  • Implement collision protection resolution (object > phase > phases-level > default Prevent) in the controller.
  • Update CRD manifests, deepcopy generation, and unit/e2e tests for the new schema and behavior.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/e2e/steps/steps.go Update phase iteration to handle .spec.phases.items and nil .spec.phases.
manifests/experimental.yaml CRD schema update for phases wrapper + collisionProtection inheritance fields.
manifests/experimental-e2e.yaml Same CRD schema update for the e2e manifest variant.
internal/operator-controller/controllers/clusterextensionrevision_controller_test.go Update test fixtures to construct Phases: &...{Items: ...}.
internal/operator-controller/controllers/clusterextensionrevision_controller_internal_test.go Add unit test for collision protection resolution; update fixtures to new phases shape.
internal/operator-controller/controllers/clusterextensionrevision_controller.go Add resolveCollisionProtection and apply effective CP when configuring boxcutter options.
internal/operator-controller/applier/boxcutter_test.go Update tests to assert against .spec.phases.items and new phases struct construction.
internal/operator-controller/applier/boxcutter.go Generate revisions with Phases wrapper; update object collection to handle nil .spec.phases.
helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensionrevisions.yaml Helm-packaged CRD schema update matching the new phases wrapper.
api/v1/zz_generated.deepcopy.go Regenerated deepcopy to include ClusterExtensionRevisionPhases and pointer field copying.
api/v1/clusterextensionrevision_types_test.go Update immutability/validity tests for new schema and collisionProtection validation.
api/v1/clusterextensionrevision_types.go Define ClusterExtensionRevisionPhases, add collisionProtection fields, and make object CP optional.

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

@codecov
Copy link

codecov bot commented Feb 17, 2026

Codecov Report

❌ Patch coverage is 92.85714% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 73.27%. Comparing base (130c987) to head (ffcdfc2).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
...controllers/clusterextensionrevision_controller.go 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2513      +/-   ##
==========================================
+ Coverage   73.21%   73.27%   +0.05%     
==========================================
  Files         102      103       +1     
  Lines        8505     8516      +11     
==========================================
+ Hits         6227     6240      +13     
+ Misses       1802     1801       -1     
+ Partials      476      475       -1     
Flag Coverage Δ
e2e 45.82% <0.00%> (-0.10%) ⬇️
experimental-e2e 53.54% <78.57%> (+0.14%) ⬆️
unit 57.94% <92.85%> (+0.07%) ⬆️

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

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 9 out of 9 changed files in this pull request and generated 1 comment.


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

Comment on lines +480 to +489
// EffectiveCollisionProtection resolves the collision protection value using
// the inheritance hierarchy: object > phase > spec > default ("Prevent").
func EffectiveCollisionProtection(cp ...ocv1.CollisionProtection) ocv1.CollisionProtection {
ecp := ocv1.CollisionProtectionPrevent
for _, c := range cp {
if c != "" {
ecp = c
}
}
return ecp
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

EffectiveCollisionProtection is exported and uses a variadic parameter, but its correctness depends on callers supplying values in a specific order (spec, phase, object) even though the doc comment describes an inheritance hierarchy (object > phase > spec). To prevent accidental misuse, consider changing the signature to explicit named parameters (specCP, phaseCP, objectCP) (or otherwise enforcing/documenting the required argument order) so future callers can’t invert precedence silently.

Copilot uses AI. Check for mistakes.
//
// The resolution order is: object > phase > spec > default ("Prevent").
//
// +optional
Copy link
Contributor

Choose a reason for hiding this comment

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

api review feedback encouraged us to make this required + no default. Maybe it makes sense?

},
valid: true,
},
"spec collisionProtection rejects invalid values": {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we're going with omitempty and "" for unset, maybe it's also worth checking that "" is rejected?

@pedjak pedjak requested a review from perdasilva February 18, 2026 18:55
Copilot AI review requested due to automatic review settings February 18, 2026 21:20
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 10 out of 10 changed files in this pull request and generated no new comments.


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

// When set, this value is used as the default for any phase or object that does not
// explicitly specify its own collisionProtection.
//
// The resolution order is: object > phase > spec > default ("Prevent").
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 remove the default call out here since it's required now?

Suggested change
// The resolution order is: object > phase > spec > default ("Prevent").
// The resolution order is: object > phase > spec

// When set, this value is used as the default for any object in this phase that does not
// explicitly specify its own collisionProtection.
//
// The resolution order is: object > phase > spec > default ("Prevent").
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 carry the same comment here or have a phase specific one that says it inherits from spec by default and the allowable values, etc.?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

let me rephrase it.

// the same resource, resulting in increased load on the API server and etcd.
//
// +required
// When omitted, the value is inherited from the phase, then spec, then defaults to "Prevent".
Copy link
Contributor

@perdasilva perdasilva Feb 19, 2026

Choose a reason for hiding this comment

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

Same with the default here, since it's now required

Suggested change
// When omitted, the value is inherited from the phase, then spec, then defaults to "Prevent".
// When omitted, the value is inherited from the phase, then spec.

// EffectiveCollisionProtection resolves the collision protection value using
// the inheritance hierarchy: object > phase > spec > default ("Prevent").
func EffectiveCollisionProtection(cp ...ocv1.CollisionProtection) ocv1.CollisionProtection {
ecp := ocv1.CollisionProtectionPrevent
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 set any default? maybe we should error if unset (although that should be caught at ingress time anyway)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well, this is the default: Prevent - if passed collision protection are empty, we return this.

…sion

Add collisionProtection as a required field at the spec level and an
optional field at the phase level, with inheritance resolution:
object > phase > spec > default ("Prevent"). This reduces verbosity by
letting users set a single spec-level default instead of repeating the
value on every object.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@perdasilva
Copy link
Contributor

/approve

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 19, 2026
Copy link
Member

@rashmigottipati rashmigottipati 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 19, 2026
@openshift-ci
Copy link

openshift-ci bot commented Feb 19, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: perdasilva, rashmigottipati

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
Copy link

openshift-ci bot commented Feb 19, 2026

@pedjak: /override requires failed status contexts, check run or a prowjob name to operate on.
The following unknown contexts/checkruns were given:

  • api-diff-linet/lint-api-diff

Only the following failed contexts/checkruns were expected:

  • Verify PR title
  • crd-diff
  • e2e
  • experimental-e2e
  • extension-developer-e2e
  • go-apidiff
  • go-verdiff
  • goreleaser
  • lint
  • lint-api-diff
  • netlify/olmv1/deploy-preview
  • st2ex-e2e
  • tide
  • unit-test-basic
  • upgrade-ex2ex-e2e
  • upgrade-st2st-e2e
  • verify

If you are trying to override a checkrun that has a space in it, you must put a double quote on the context.

Details

In response to this:

/override api-diff-linet/lint-api-diff

we have introduced a new field in this PR

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-ci
Copy link

openshift-ci bot commented Feb 19, 2026

@pedjak: /override requires failed status contexts, check run or a prowjob name to operate on.
The following unknown contexts/checkruns were given:

  • api-diff-lint

Only the following failed contexts/checkruns were expected:

  • Verify PR title
  • crd-diff
  • e2e
  • experimental-e2e
  • extension-developer-e2e
  • go-apidiff
  • go-verdiff
  • goreleaser
  • lint
  • lint-api-diff
  • netlify/olmv1/deploy-preview
  • st2ex-e2e
  • tide
  • unit-test-basic
  • upgrade-ex2ex-e2e
  • upgrade-st2st-e2e
  • verify

If you are trying to override a checkrun that has a space in it, you must put a double quote on the context.

Details

In response to this:

/override api-diff-lint

we have introduced a new field in this PR

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@pedjak
Copy link
Contributor Author

pedjak commented Feb 19, 2026

/override lint-api-diff

we have introduced a new field in this PR

@openshift-ci
Copy link

openshift-ci bot commented Feb 19, 2026

@pedjak: Overrode contexts on behalf of pedjak: lint-api-diff

Details

In response to this:

/override lint-api-diff

we have introduced a new field in this PR

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@pedjak
Copy link
Contributor Author

pedjak commented Feb 19, 2026

/override upgrade-ex2ex-e2e

We have introduced a new required .spec.collisionProtection that makes the existing CER instance invalid and thus the job is failing. Given that CER is experimental, we do not need to take migration into consideration.

@openshift-ci
Copy link

openshift-ci bot commented Feb 19, 2026

@pedjak: Overrode contexts on behalf of pedjak: upgrade-ex2ex-e2e

Details

In response to this:

/override upgrade-ex2ex-e2e

We have introduced a new required .spec.collisionProtection that makes the existing CER instance invalid and thus the job is failing. Given that CER is experimental, we do not need to take migration into consideration.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-merge-bot openshift-merge-bot bot merged commit af6733e into operator-framework:main Feb 19, 2026
30 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants