Skip to content

🐛 fix: Check Applied condition before evaluating rollout status - #1243

Merged
openshift-merge-bot[bot] merged 1 commit into
open-cluster-management-io:mainfrom
haoqing0110:fix-rollout-applied-condition-check
Dec 1, 2025
Merged

🐛 fix: Check Applied condition before evaluating rollout status#1243
openshift-merge-bot[bot] merged 1 commit into
open-cluster-management-io:mainfrom
haoqing0110:fix-rollout-applied-condition-check

Conversation

@haoqing0110

@haoqing0110 haoqing0110 commented Nov 5, 2025

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

Summary

Related issue(s)

Fixes #1237

Summary by CodeRabbit

  • Bug Fixes

    • Ensure an "Applied" condition is required and evaluated before Progressing/Degraded to prevent stale observations and incorrect rollout status.
  • New Features

    • Centralized status-evaluation logic that consistently considers condition readiness and observed-generation when deriving rollout state.
  • Tests

    • Expanded and new tests covering Applied-first evaluation, observed-generation scenarios, and condition-readiness outcomes.

✏️ Tip: You can customize this high-level summary in your review settings.

@haoqing0110

Copy link
Copy Markdown
Member Author

/hold

@coderabbitai

coderabbitai Bot commented Nov 5, 2025

Copy link
Copy Markdown

Walkthrough

Adds helpers to centralize status gating and changes rollout status evaluation to require a present WorkApplied condition (observed for the current generation and Status=True) before evaluating WorkProgressing/WorkDegraded; tests and integration suites were updated to insert WorkApplied where appropriate.

Changes

Cohort / File(s) Summary
Reconciliation logic
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go
Introduce helper functions (shouldReturnToApply, isConditionReady), extract the WorkApplied condition, enforce Applied-first gating (check Applied → Progressing → Degraded with ObservedGeneration gating), and refactor clusterRolloutStatusFunc to use these helpers.
Unit tests
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
Update tests to insert an initial WorkApplied condition (with ObservedGeneration and timestamps) before setting WorkProgressing/WorkDegraded; add new tests TestShouldReturnToApply and TestIsConditionReady; adjust expected rollout statuses and LastTransitionTime values.
Integration tests
test/integration/work/manifestworkreplicaset_test.go
Insert WorkApplied status conditions (Type=WorkApplied, Status=True, with ObservedGeneration and reasons like Applied/AppliedManifestWorkComplete) across multiple test paths prior to existing WorkProgressing/Available/Degraded updates.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Focus review on manifestworkreplicaset_deploy_reconcile.go for ordering of gating checks, correctness of ObservedGeneration comparisons, and interactions between shouldReturnToApply and existing status branches.
  • Verify new unit tests (TestShouldReturnToApply, TestIsConditionReady) cover stale vs current ObservedGeneration, Unknown/False/True statuses, and boundary cases.
  • Check integration test insertions for consistent timestamps/ObservedGeneration usage affecting timing-based expectations.

Possibly related PRs

Suggested labels

lgtm, approved

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete; it only contains template placeholder sections (Summary and Related issue) without substantive implementation details or explanation of the changes. Add a Summary section explaining what was changed and why, and provide details about the Applied condition logic and how it fixes the identified gaps.
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding a check for the Applied condition before evaluating rollout status, which directly addresses the bug fix objective.
Linked Issues check ✅ Passed The code changes implement the core objective to check Applied condition before evaluating rollout status, addressing gaps #2 and #3 by establishing a gating order (Applied before Progressing/Degraded) to prevent premature rollout advancement.
Out of Scope Changes check ✅ Passed All changes are scoped to the ManifestWork rollout status evaluation logic; test updates align with implementation changes to enforce Applied-before-Progressing semantics with no unrelated modifications.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4cb6735 and 2176f60.

📒 Files selected for processing (3)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (2 hunks)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (12 hunks)
  • test/integration/work/manifestworkreplicaset_test.go (5 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go
📚 Learning: 2025-09-03T08:43:34.751Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: test/integration/work/completedmanifestwork_test.go:216-256
Timestamp: 2025-09-03T08:43:34.751Z
Learning: In TTL=0 ManifestWork deletion tests, avoid waiting for WorkComplete condition because the controller deletes the resource immediately upon completion, creating a race condition where the test tries to check completion status on an already-deleted resource.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
  • test/integration/work/manifestworkreplicaset_test.go
📚 Learning: 2025-07-01T02:27:10.927Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1053
File: vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/agent/client/manifestwork.go:237-237
Timestamp: 2025-07-01T02:27:10.927Z
Learning: In OCM ManifestWork agent client, when a work is being deleted (DeletionTimestamp set and finalizers removed), the agent publishes a status update event (types.UpdateRequestAction) with ResourceDeleted condition set to True to inform the hub that deletion is complete, rather than publishing a delete request event.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
  • test/integration/work/manifestworkreplicaset_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: integration
  • GitHub Check: unit
  • GitHub Check: verify
  • GitHub Check: build
  • GitHub Check: grpc-work-integration
  • GitHub Check: mqtt-work-integration
  • GitHub Check: e2e-singleton
  • GitHub Check: e2e-hosted
  • GitHub Check: e2e
🔇 Additional comments (12)
test/integration/work/manifestworkreplicaset_test.go (5)

389-394: LGTM! Correct Applied condition setup.

The WorkApplied condition is properly added before WorkProgressing with the correct Status, ObservedGeneration, and a descriptive Reason, aligning with the new Applied-first evaluation semantics.


413-418: LGTM! Consistent test setup.

The WorkApplied condition is consistently applied across the test iterations, maintaining the proper condition ordering.


456-461: LGTM! Applied condition properly set for failure scenario.

The WorkApplied condition is correctly configured for the max failure test scenario, allowing the rollout logic to proceed to evaluate Progressing/Degraded conditions.


518-525: LGTM! Applied condition supports minSuccessTime validation.

The WorkApplied condition is correctly set up to ensure the rollout respects the minSuccessTime constraint, preventing premature advancement based on stale timestamps.


594-600: LGTM! Clear documentation for progress deadline test.

The inline comment on line 594 helpfully explains the purpose of setting Applied=True before testing progress deadline behavior. This ensures the test validates the correct scenario where work has been applied by the hub controller.

pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (3)

221-226: LGTM! Clean refactoring with helper function.

The extraction of appliedCond and the use of shouldReturnToApply helper improves readability and centralizes the complex gating logic. The comment clearly states the purpose of this check.


260-291: LGTM! Excellent helper function with comprehensive documentation.

The shouldReturnToApply function is well-structured and thoroughly documented. The logic correctly enforces the Applied-first evaluation flow, preventing the use of stale timestamps from previous generations. The function appropriately:

  • Requires Applied condition to be ready AND Status=True (line 274)
  • Requires Progressing condition to be ready (line 279)
  • Waits for Degraded to catch up if it exists (line 286)

293-312: LGTM! Clean and reusable condition validation helper.

The isConditionReady function provides a clear, reusable way to validate condition readiness with appropriate checks in the correct order (existence → generation → status). The requireTrue parameter allows flexibility for different validation needs.

pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (4)

594-601: LGTM! Correct test setup for progress deadline validation.

The WorkApplied condition is properly added with a helpful comment explaining its purpose. This ensures the test validates the correct scenario where the Applied condition is satisfied before testing progress deadline behavior.


809-1213: LGTM! Comprehensive test coverage for Applied-first evaluation.

The test cases in TestClusterRolloutStatusFunc are thoroughly updated to validate the Applied-first evaluation flow. Notable improvements:

  • Test names clearly describe the scenario and expected behavior
  • New test cases cover critical edge cases: Applied=False, Applied=Unknown, stale ObservedGeneration
  • Expected statuses and LastTransitionTime values correctly reflect the new logic
  • WorkApplied conditions are consistently added to existing test cases

The test coverage ensures the rollout status evaluation behaves correctly across all condition combinations.


1215-1440: LGTM! Exceptional test coverage for shouldReturnToApply logic.

The TestShouldReturnToApply function provides comprehensive validation of the helper function with 13 well-structured test cases covering:

  • Missing conditions (nil Applied/Progressing)
  • Stale ObservedGeneration for each condition
  • Invalid Status values (False, Unknown)
  • Complex multi-condition scenarios (Degraded ahead of Applied, mixed stale/current states)
  • Success cases (all conditions ready)

Each test case includes a clear description field that documents the expected behavior. This thorough coverage ensures the Applied-first gating logic works correctly in all scenarios.


1442-1548: LGTM! Complete test coverage for isConditionReady helper.

The TestIsConditionReady function thoroughly validates the condition readiness checks with 7 test cases covering:

  • Nil condition handling
  • ObservedGeneration validation
  • Status validation with and without the requireTrue flag
  • All Status values (True, False, Unknown)

The test cases correctly validate that the helper enforces the appropriate constraints based on the requireTrue parameter, ensuring it can be safely reused for different validation needs.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@haoqing0110
haoqing0110 force-pushed the fix-rollout-applied-condition-check branch from af4dc06 to 31d8a33 Compare November 5, 2025 09:13

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af4dc06 and 31d8a33.

⛔ Files ignored due to path filters (86)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/LICENSE is excluded by !vendor/**
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/message.go is excluded by !vendor/**
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/option.go is excluded by !vendor/**
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/protocol.go is excluded by !vendor/**
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/write_producer_message.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/LICENSE is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/.gitignore is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/00version.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/README.md is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/adminapi.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/adminoptions.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/api.html is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_darwin_amd64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_darwin_arm64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_dynamic.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_glibc_linux_amd64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_glibc_linux_arm64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_musl_linux_amd64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_musl_linux_arm64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_windows.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/config.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/consumer.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/context.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/error.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/error_gen.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/event.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/generated_errors.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/glue_rdkafka.h is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/handle.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/header.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/kafka.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/.gitignore is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/LICENSES.txt is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/README.md is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/bundle-import.sh is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/import.sh is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_darwin_amd64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_darwin_arm64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_glibc_linux_amd64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_glibc_linux_arm64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_musl_linux_amd64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_musl_linux_arm64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_windows.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/rdkafka.h is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/rdkafka_mock.h is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/log.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/message.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/metadata.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/misc.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/mockcluster.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/offset.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/producer.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/select_rdkafka.h is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/testconf-example.json is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/time.go is excluded by !vendor/**
  • vendor/modules.txt is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/apis/cluster/v1alpha1/rollout.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/addon/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/cluster/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/csr/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/event/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/lease/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/options/generic.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/agent/client/manifestwork.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/source/client/manifestwork.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/constants/constants.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/clients/agentclient.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/clients/baseclient.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/clients/sourceclient.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/metrics/metrics_collector.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/builder/optionsbuilder.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/grpc/agentoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/grpc/options.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/grpc/sourceoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/kafka/agentoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/kafka/options.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/kafka/options_noop.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/kafka/sourceoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/mqtt/agentoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/mqtt/options.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/mqtt/sourceoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/options.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/ratelimiter.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/utils/ratelimiter.go is excluded by !vendor/**
📒 Files selected for processing (2)
  • go.mod (1 hunks)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • go.mod
🧬 Code graph analysis (1)
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (1)
vendor/open-cluster-management.io/api/work/v1/types.go (1)
  • WorkApplied (500-500)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: integration
  • GitHub Check: verify
  • GitHub Check: e2e-hosted
  • GitHub Check: unit
  • GitHub Check: e2e-singleton
  • GitHub Check: build
  • GitHub Check: e2e
🔇 Additional comments (2)
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (2)

221-221: Good addition of Applied condition check.

Retrieving the Applied condition aligns with the PR objective to check hub-side application status before evaluating agent-side conditions.


224-240: No backward compatibility issue—code correctly handles ManifestWorks without Applied condition.

The Applied condition is set by the spoke-side controller (pkg/work/spoke/controllers/manifestcontroller/manifestwork_reconciler.go:108) during normal manifest reconciliation. ManifestWorks created without the Applied condition is expected behavior, explicitly documented in appliedmanifestwork_reconciler.go:42–47 with graceful handling for missing conditions. The lines 224–240 correctly gate rollout evaluation until the condition exists and observes the current generation—this is proper design, not a bug. Old ManifestWorks will eventually have the condition set as the spoke applies them.

Likely an incorrect or invalid review comment.

Comment thread go.mod Outdated
@haoqing0110
haoqing0110 force-pushed the fix-rollout-applied-condition-check branch 2 times, most recently from f0f9234 to 82c57fa Compare November 5, 2025 16:54
@codecov

codecov Bot commented Nov 5, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 62.22%. Comparing base (8f8cd01) to head (2176f60).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1243      +/-   ##
==========================================
+ Coverage   62.19%   62.22%   +0.03%     
==========================================
  Files         210      210              
  Lines       17084    17099      +15     
==========================================
+ Hits        10625    10640      +15     
  Misses       5342     5342              
  Partials     1117     1117              
Flag Coverage Δ
unit 62.22% <100.00%> (+0.03%) ⬆️

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (1)

902-1135: Comprehensive test coverage, but consider adding one more scenario.

The test cases thoroughly cover various combinations of Progressing and Degraded conditions, and correctly inject the Applied condition in all scenarios that should progress past ToApply status.

However, consider adding a test case for:

  • Applied condition exists but Applied.ObservedGeneration != ManifestWork.Generation (should return ToApply)

This scenario is explicitly checked in the reconcile logic (lines 234-235 of manifestworkreplicaset_deploy_reconcile.go) but not directly tested here.

Add this test case to verify the Applied ObservedGeneration gating:

{
    name: "applied condition with unobserved generation - should return ToApply",
    manifestWork: &workapiv1.ManifestWork{
        ObjectMeta: metav1.ObjectMeta{
            Name:              "test-mw",
            Namespace:         "cls1",
            Generation:        2,
            CreationTimestamp: creationTime,
        },
        Status: workapiv1.ManifestWorkStatus{
            Conditions: []metav1.Condition{
                {
                    Type:               workapiv1.WorkApplied,
                    Status:             metav1.ConditionTrue,
                    ObservedGeneration: 1, // Stale generation
                    LastTransitionTime: now,
                    Reason:             "Applied",
                },
                {
                    Type:               workapiv1.WorkProgressing,
                    Status:             metav1.ConditionFalse,
                    ObservedGeneration: 2,
                    LastTransitionTime: now,
                    Reason:             "Completed",
                },
            },
        },
    },
    expectedStatus:         clustersdkv1alpha1.ToApply,
    expectedLastTransition: nil,
},
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0f9234 and 82c57fa.

⛔ Files ignored due to path filters (86)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/LICENSE is excluded by !vendor/**
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/message.go is excluded by !vendor/**
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/option.go is excluded by !vendor/**
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/protocol.go is excluded by !vendor/**
  • vendor/github.com/cloudevents/sdk-go/protocol/kafka_confluent/v2/write_producer_message.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/LICENSE is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/.gitignore is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/00version.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/README.md is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/adminapi.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/adminoptions.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/api.html is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_darwin_amd64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_darwin_arm64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_dynamic.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_glibc_linux_amd64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_glibc_linux_arm64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_musl_linux_amd64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_musl_linux_arm64.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/build_windows.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/config.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/consumer.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/context.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/error.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/error_gen.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/event.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/generated_errors.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/glue_rdkafka.h is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/handle.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/header.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/kafka.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/.gitignore is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/LICENSES.txt is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/README.md is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/bundle-import.sh is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/import.sh is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_darwin_amd64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_darwin_arm64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_glibc_linux_amd64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_glibc_linux_arm64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_musl_linux_amd64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_musl_linux_arm64.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/librdkafka_windows.a is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/rdkafka.h is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/librdkafka_vendor/rdkafka_mock.h is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/log.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/message.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/metadata.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/misc.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/mockcluster.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/offset.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/producer.go is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/select_rdkafka.h is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/testconf-example.json is excluded by !vendor/**
  • vendor/github.com/confluentinc/confluent-kafka-go/v2/kafka/time.go is excluded by !vendor/**
  • vendor/modules.txt is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/apis/cluster/v1alpha1/rollout.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/addon/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/cluster/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/csr/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/event/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/lease/client.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/options/generic.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/agent/client/manifestwork.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/source/client/manifestwork.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/constants/constants.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/clients/agentclient.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/clients/baseclient.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/clients/sourceclient.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/metrics/metrics_collector.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/builder/optionsbuilder.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/grpc/agentoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/grpc/options.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/grpc/sourceoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/kafka/agentoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/kafka/options.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/kafka/options_noop.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/kafka/sourceoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/mqtt/agentoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/mqtt/options.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/mqtt/sourceoptions.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/options.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/ratelimiter.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/utils/ratelimiter.go is excluded by !vendor/**
📒 Files selected for processing (6)
  • go.mod (1 hunks)
  • pkg/registration/register/grpc/spoke_driver.go (3 hunks)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (1 hunks)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (8 hunks)
  • pkg/work/hub/manager.go (2 hunks)
  • pkg/work/spoke/spokeagent.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • go.mod
  • pkg/registration/register/grpc/spoke_driver.go
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • pkg/work/hub/manager.go
  • pkg/work/spoke/spokeagent.go
📚 Learning: 2025-10-28T02:55:13.893Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1224
File: pkg/registration/register/grpc/spoke_driver.go:89-98
Timestamp: 2025-10-28T02:55:13.893Z
Learning: In pkg/registration/register/grpc/spoke_driver.go (Go), when calling cloudeventscsr.NewAgentClientHolder with GenericClientOptions, the watcher store does not need to be explicitly provided via WithClientWatcherStore. The GenericClientOptions.AgentClient() method automatically creates a default AgentInformerWatcherStore if none is provided, which satisfies the NewAgentClientHolder requirements.

Applied to files:

  • pkg/work/hub/manager.go
  • pkg/work/spoke/spokeagent.go
📚 Learning: 2025-09-03T08:43:34.751Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: test/integration/work/completedmanifestwork_test.go:216-256
Timestamp: 2025-09-03T08:43:34.751Z
Learning: In TTL=0 ManifestWork deletion tests, avoid waiting for WorkComplete condition because the controller deletes the resource immediately upon completion, creating a race condition where the test tries to check completion status on an already-deleted resource.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
📚 Learning: 2025-07-01T02:27:10.927Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1053
File: vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/agent/client/manifestwork.go:237-237
Timestamp: 2025-07-01T02:27:10.927Z
Learning: In OCM ManifestWork agent client, when a work is being deleted (DeletionTimestamp set and finalizers removed), the agent publishes a status update event (types.UpdateRequestAction) with ResourceDeleted condition set to True to inform the hub that deletion is complete, rather than publishing a delete request event.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
📚 Learning: 2025-09-08T06:10:32.388Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1164
File: test/integration/work/deleteoption_test.go:42-42
Timestamp: 2025-09-08T06:10:32.388Z
Learning: The startWorkAgent function in the OCM test suite uses variadic parameters for decorators (...agentOptionsDecorator), allowing it to be called with just ctx and clusterName without requiring an explicit nil decorator parameter.

Applied to files:

  • pkg/work/spoke/spokeagent.go
🧬 Code graph analysis (4)
pkg/work/hub/manager.go (1)
vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/builder/optionsbuilder.go (1)
  • NewConfigLoader (24-29)
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (1)
vendor/open-cluster-management.io/api/work/v1/types.go (1)
  • WorkApplied (500-500)
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (1)
vendor/open-cluster-management.io/api/work/v1/types.go (1)
  • WorkApplied (500-500)
pkg/work/spoke/spokeagent.go (1)
vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/generic/options/builder/optionsbuilder.go (1)
  • NewConfigLoader (24-29)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: integration
  • GitHub Check: unit
  • GitHub Check: verify
  • GitHub Check: e2e-singleton
  • GitHub Check: cloudevents-integration
  • GitHub Check: e2e-hosted
  • GitHub Check: e2e
🔇 Additional comments (5)
pkg/work/hub/manager.go (1)

21-21: LGTM! Clean refactoring to builder-based config loading.

The migration from generic.NewConfigLoader to builder.NewConfigLoader is straightforward and maintains the same API surface. Error handling and control flow remain unchanged.

Also applies to: 80-80

pkg/work/spoke/spokeagent.go (1)

25-25: LGTM! Consistent builder-based config loading.

The change aligns with the builder pattern migration seen in pkg/work/hub/manager.go. The multi-line formatting of the config loader call improves readability.

Also applies to: 229-230

pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (2)

231-233: Excellent documentation of the ordering requirement.

The comment clearly explains why Applied must be checked before Progressing/Degraded to prevent using stale timestamps from previous generations. This is critical for correct rollout timeout calculations.


221-240: Fix misleading comment about which controller sets WorkApplied condition.

Line 224 comment incorrectly states Applied condition is set by "hub controller" when it's actually set by the spoke/agent controller during manifest reconciliation. Update the comment to accurately reflect that Applied represents the spoke controller's view of work application state. The logic itself is correct—returning ToApply for works without an Applied condition is the intended safe behavior, not a breaking change. Existing ManifestWorks will naturally receive the Applied condition as the spoke controller reconciles them.

Likely an incorrect or invalid review comment.

pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (1)

594-601: Good test setup aligning with the new Applied condition requirement.

The test correctly sets the Applied condition with matching ObservedGeneration before simulating the Progressing/Degraded states. This ensures the gating logic allows evaluation of rollout status.

@haoqing0110
haoqing0110 force-pushed the fix-rollout-applied-condition-check branch from 82c57fa to 65130d6 Compare November 6, 2025 04:13
@haoqing0110

Copy link
Copy Markdown
Member Author

/assign @qiujian16 @youngbupark

@openshift-ci

openshift-ci Bot commented Nov 6, 2025

Copy link
Copy Markdown
Contributor

@haoqing0110: GitHub didn't allow me to assign the following users: youngbupark.

Note that only open-cluster-management-io members with read permissions, repo collaborators and people who have commented on this issue/PR can be assigned. Additionally, issues/PRs can only have 10 assignees at the same time.
For more information please see the contributor guide

Details

In response to this:

/assign @qiujian16 @youngbupark

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.

// IMPORTANT: Check Applied condition FIRST to ensure the work has been properly applied
// before checking agent-side conditions. This prevents using stale timestamps from
// previous generations when conditions update their ObservedGeneration without changing Status.
if appliedCond == nil ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this the only change made to fix this issue?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@haoqing0110
haoqing0110 force-pushed the fix-rollout-applied-condition-check branch from 65130d6 to 1df92e6 Compare November 25, 2025 09:19
@haoqing0110
haoqing0110 force-pushed the fix-rollout-applied-condition-check branch from 1df92e6 to e6ab9c9 Compare November 25, 2025 09:21

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/integration/work/manifestworkreplicaset_test.go (1)

389-394: LGTM! Consistent test updates align with controller requirements.

All test blocks correctly add the WorkApplied condition with Status=True and matching ObservedGeneration before setting WorkProgressing and WorkDegraded conditions. This properly tests the new gating logic in the controller.

Consider adding test coverage for Applied.Status=False scenario:

To ensure robust behavior, add a test case that verifies the controller returns ToApply status when the Applied condition exists but has Status=False. Example test scenario:

// Test that work stays in ToApply when Applied condition is False
workCopy := work.DeepCopy()
meta.SetStatusCondition(&workCopy.Status.Conditions, metav1.Condition{
    Type:               workapiv1.WorkApplied,
    Status:             metav1.ConditionFalse,  // Application failed
    Reason:             "ApplyFailed",
    ObservedGeneration: workCopy.Generation,
})
// Verify rollout doesn't proceed

Also applies to: 413-418, 456-461, 518-525, 593-600

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65130d6 and e6ab9c9.

⛔ Files ignored due to path filters (98)
  • go.sum is excluded by !**/*.sum
  • vendor/cloud.google.com/go/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/CHANGES.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/README.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/auth.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/compute.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/detect.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/doc.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/filetypes.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/grpctransport/dial_socketopt.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/grpctransport/directpath.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/grpctransport/grpctransport.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/grpctransport/pool.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/httptransport/httptransport.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/httptransport/transport.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/compute/compute.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/compute/manufacturer.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/compute/manufacturer_linux.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/compute/manufacturer_windows.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/credsfile/parse.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/internal.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/jwt/jwt.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/retry/retry.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cba.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/s2a.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/transport.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/version.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/oauth2adapt/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/threelegged.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/compute/metadata/CHANGES.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/compute/metadata/metadata.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/compute/metadata/retry.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/iam/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/iam/apiv1/iampb/iam_policy.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/iam/apiv1/iampb/options.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/iam/apiv1/iampb/policy.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/iam/apiv1/iampb/resource_policy_member.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/internal/detect/detect.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/internal/pubsub/message.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/internal/pubsub/publish.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/CHANGES.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/auxiliary.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/auxiliary_go123.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/doc.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/helpers.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/info.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/pubsubpb/pubsub.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/pubsubpb/pubsub_grpc.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/pubsubpb/schema.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/pubsubpb/schema_grpc.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/schema_client.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/subscription_admin_client.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/topic_admin_client.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/version.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/debug.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/doc.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/flow_controller.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/internal/distribution/distribution.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/internal/scheduler/publish_scheduler.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/internal/scheduler/receive_scheduler.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/internal/version.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/iterator.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/message.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/nodebug.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/publisher.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/pubsub.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/pullstream.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/service.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/shutdown.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/subscriber.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/trace.go is excluded by !vendor/**
📒 Files selected for processing (4)
  • go.mod (7 hunks)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (1 hunks)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (8 hunks)
  • test/integration/work/manifestworkreplicaset_test.go (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
  • go.mod
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: test/integration/work/completedmanifestwork_test.go:216-256
Timestamp: 2025-09-03T08:43:34.751Z
Learning: In TTL=0 ManifestWork deletion tests, avoid waiting for WorkComplete condition because the controller deletes the resource immediately upon completion, creating a race condition where the test tries to check completion status on an already-deleted resource.
📚 Learning: 2025-11-06T08:55:13.306Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1242
File: pkg/work/spoke/controllers/manifestcontroller/manifestwork_reconciler.go:88-88
Timestamp: 2025-11-06T08:55:13.306Z
Learning: In pkg/work/spoke/controllers/manifestcontroller/manifestwork_controller.go, the sync method initializes a logger with manifestWorkName and attaches it to the context before calling reconcile methods. Therefore, reconcile methods (like manifestworkReconciler.reconcile) that use klog.FromContext(ctx) automatically inherit the manifestWorkName context and do not need to add it again.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go
📚 Learning: 2025-09-03T08:43:34.751Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: test/integration/work/completedmanifestwork_test.go:216-256
Timestamp: 2025-09-03T08:43:34.751Z
Learning: In TTL=0 ManifestWork deletion tests, avoid waiting for WorkComplete condition because the controller deletes the resource immediately upon completion, creating a race condition where the test tries to check completion status on an already-deleted resource.

Applied to files:

  • test/integration/work/manifestworkreplicaset_test.go
📚 Learning: 2025-07-01T02:27:10.927Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1053
File: vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/agent/client/manifestwork.go:237-237
Timestamp: 2025-07-01T02:27:10.927Z
Learning: In OCM ManifestWork agent client, when a work is being deleted (DeletionTimestamp set and finalizers removed), the agent publishes a status update event (types.UpdateRequestAction) with ResourceDeleted condition set to True to inform the hub that deletion is complete, rather than publishing a delete request event.

Applied to files:

  • test/integration/work/manifestworkreplicaset_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: verify
  • GitHub Check: unit
  • GitHub Check: grpc-work-integration
  • GitHub Check: integration
  • GitHub Check: mqtt-work-integration
  • GitHub Check: e2e
  • GitHub Check: e2e-singleton
  • GitHub Check: e2e-hosted
🔇 Additional comments (2)
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (2)

221-221: LGTM!

Correctly retrieves the WorkApplied condition, consistent with how Progressing and Degraded conditions are retrieved.


224-233: Excellent documentation.

The comments clearly explain the gating logic and the rationale for checking the Applied condition first to prevent using stale timestamps. This will help future maintainers understand the ordering requirements.

@haoqing0110
haoqing0110 force-pushed the fix-rollout-applied-condition-check branch from e6ab9c9 to 6fe8455 Compare November 25, 2025 09:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

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

5-5: Replace directive points to personal fork (unresolved from previous review).

The replace directive still uses a personal fork (github.com/haoqing0110/sdk-go) with a pseudo-version, which was flagged in a previous review. This introduces supply chain risk and makes builds non-reproducible.

Action items:

  1. Verify when the upstream PR to open-cluster-management.io/sdk-go will be released, and plan to remove this replace directive immediately after
  2. If the change is urgent and cannot wait, add a comment in the repository (e.g., in a code or documentation file) documenting why the fork is needed, linking to the upstream PR, and creating a tracked issue to remove the replace directive once released

Once the official release is available, update line 5 to remove the replace directive and ensure the require statement on line 46 uses the official semantic version.

🧹 Nitpick comments (1)
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (1)

221-241: Applied-gated rollout status check looks correct; consider syncing comments with the new Status check.

The new appliedCond retrieval and gating condition correctly ensure we only honor Progressing/Degraded when:

  • WorkApplied exists,
  • WorkApplied.ObservedGeneration matches manifestWork.Generation,
  • WorkApplied.Status is ConditionTrue,
  • and Progressing/Degraded (if present) are for the same generation.

This matches the intended “Applied-first” behavior and closes the stale-condition window addressed in the linked issue.

One small doc nit: the comment block above still only mentions “no Applied” and “Applied hasn’t observed the latest spec”, but the code also returns ToApply when Applied.Status != True (apply failed). You may want to add a bullet like “Applied condition is False (apply failed)” so the comment fully mirrors the behavior.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6ab9c9 and 6fe8455.

⛔ Files ignored due to path filters (296)
  • go.sum is excluded by !**/*.sum
  • vendor/cloud.google.com/go/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/CHANGES.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/README.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/auth.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/compute.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/detect.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/doc.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/filetypes.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/grpctransport/dial_socketopt.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/grpctransport/directpath.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/grpctransport/grpctransport.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/grpctransport/pool.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/httptransport/httptransport.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/httptransport/transport.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/compute/compute.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/compute/manufacturer.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/compute/manufacturer_linux.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/compute/manufacturer_windows.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/credsfile/parse.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/internal.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/jwt/jwt.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/retry/retry.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cba.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/s2a.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/transport/transport.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/internal/version.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/oauth2adapt/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/auth/threelegged.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/compute/metadata/CHANGES.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/compute/metadata/metadata.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/compute/metadata/retry.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/iam/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/iam/apiv1/iampb/iam_policy.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/iam/apiv1/iampb/options.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/iam/apiv1/iampb/policy.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/iam/apiv1/iampb/resource_policy_member.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/internal/detect/detect.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/internal/pubsub/message.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/internal/pubsub/publish.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/CHANGES.md is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/LICENSE is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/auxiliary.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/auxiliary_go123.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/doc.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/helpers.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/info.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/pubsubpb/pubsub.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/pubsubpb/pubsub_grpc.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/pubsubpb/schema.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/pubsubpb/schema_grpc.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/schema_client.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/subscription_admin_client.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/topic_admin_client.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/apiv1/version.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/debug.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/doc.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/flow_controller.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/internal/distribution/distribution.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/internal/scheduler/publish_scheduler.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/internal/scheduler/receive_scheduler.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/internal/version.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/iterator.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/message.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/nodebug.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/publisher.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/pubsub.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/pullstream.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/service.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/shutdown.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/subscriber.go is excluded by !vendor/**
  • vendor/cloud.google.com/go/pubsub/v2/trace.go is excluded by !vendor/**
  • vendor/github.com/emicklei/go-restful/v3/CHANGES.md is excluded by !vendor/**
  • vendor/github.com/emicklei/go-restful/v3/README.md is excluded by !vendor/**
  • vendor/github.com/emicklei/go-restful/v3/compress.go is excluded by !vendor/**
  • vendor/github.com/emicklei/go-restful/v3/curly.go is excluded by !vendor/**
  • vendor/github.com/emicklei/go-restful/v3/entity_accessors.go is excluded by !vendor/**
  • vendor/github.com/emicklei/go-restful/v3/json.go is excluded by !vendor/**
  • vendor/github.com/emicklei/go-restful/v3/jsoniter.go is excluded by !vendor/**
  • vendor/github.com/emicklei/go-restful/v3/jsr311.go is excluded by !vendor/**
  • vendor/github.com/emicklei/go-restful/v3/route.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/.cirrus.yml is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/.editorconfig is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/.gitattributes is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/.gitignore is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/CHANGELOG.md is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/README.md is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/backend_fen.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/backend_inotify.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/backend_kqueue.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/backend_other.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/backend_windows.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/fsnotify.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/darwin.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/debug_darwin.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/debug_dragonfly.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/debug_freebsd.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/debug_kqueue.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/debug_linux.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/debug_netbsd.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/debug_openbsd.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/debug_solaris.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/debug_windows.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/freebsd.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/internal.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/unix.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/unix2.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/internal/windows.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/mkdoc.zsh is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/shared.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/staticcheck.conf is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/system_bsd.go is excluded by !vendor/**
  • vendor/github.com/fsnotify/fsnotify/system_darwin.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/README.md is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/bytestring.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/cache.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/common.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/decode.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/doc.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/encode.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/encode_map.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/encode_map_go117.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/omitzero_go124.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/omitzero_pre_go124.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/simplevalue.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/stream.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/structfields.go is excluded by !vendor/**
  • vendor/github.com/fxamacker/cbor/v2/tag.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/compiler/context.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/compiler/extensions.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/compiler/helpers.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/compiler/reader.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/jsonschema/models.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/jsonschema/reader.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/jsonschema/writer.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/openapiv2/document.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.go is excluded by !vendor/**
  • vendor/github.com/google/gnostic-models/openapiv3/document.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/.gitignore is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/CONTRIBUTING.md is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/LICENSE.md is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/README.md is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/fallback/s2a_fallback.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/handshaker/service/service.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/record.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/record/ticketsender.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/v2/README.md is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/v2/s2av2.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/retry/retry.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/s2a.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/s2a_options.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/s2a_utils.go is excluded by !vendor/**
  • vendor/github.com/google/s2a-go/stream/s2a_stream.go is excluded by !vendor/**
  • vendor/github.com/googleapis/enterprise-certificate-proxy/LICENSE is excluded by !vendor/**
  • vendor/github.com/googleapis/enterprise-certificate-proxy/client/client.go is excluded by !vendor/**
  • vendor/github.com/googleapis/enterprise-certificate-proxy/client/util/util.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/CHANGES.md is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/LICENSE is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/README.md is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.proto is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/error.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/error.proto is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/call_option.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/callctx/callctx.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/content_type.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/gax.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/header.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/internal/version.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/internallog/grpclog/grpclog.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/internallog/internal/internal.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/internallog/internallog.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/invoke.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/iterator/iterator.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/proto_json_stream.go is excluded by !vendor/**
  • vendor/github.com/googleapis/gax-go/v2/release-please-config.json is excluded by !vendor/**
  • vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/client.go is excluded by !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/BUILD.bazel is excluded by !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/annotations.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/annotations.proto is excluded by !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/annotations_protoopaque.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/buf.gen.yaml is excluded by !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.proto is excluded by !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2_protoopaque.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go is excluded by !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go is excluded by !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go is excluded by !vendor/**
  • vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go is excluded by !vendor/**
  • vendor/github.com/modern-go/reflect2/safe_type.go is excluded by !vendor/**
  • vendor/github.com/stoewer/go-strcase/.golangci.yml is excluded by !vendor/**
  • vendor/github.com/stoewer/go-strcase/camel.go is excluded by !vendor/**
  • vendor/github.com/stoewer/go-strcase/helper.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/authpb/auth.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/authpb/auth.proto is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/etcdserverpb/etcdserver.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/etcdserverpb/etcdserver.proto is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/etcdserverpb/raft_internal.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/etcdserverpb/raft_internal.proto is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/etcdserverpb/raft_internal_stringer.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/etcdserverpb/rpc.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/etcdserverpb/rpc.proto is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/membershippb/membership.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/membershippb/membership.proto is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/mvccpb/kv.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/mvccpb/kv.proto is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/v3rpc/rpctypes/error.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/v3rpc/rpctypes/metadatafields.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/version/version.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/versionpb/version.pb.go is excluded by !**/*.pb.go, !vendor/**
  • vendor/go.etcd.io/etcd/api/v3/versionpb/version.proto is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/dir_unix.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/dir_windows.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/fileutil.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/lock.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/lock_flock.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/lock_linux.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/lock_solaris.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/lock_unix.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/lock_windows.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/preallocate.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/preallocate_darwin.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/preallocate_unix.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/preallocate_unsupported.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/purge.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/sync.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/sync_darwin.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/fileutil/sync_linux.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/logutil/log_format.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/logutil/zap.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/logutil/zap_journal.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/tlsutil/tlsutil.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/keepalive_listener.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/limit_listen.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/listener.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/listener_opts.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/listener_tls.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/sockopt.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/sockopt_solaris.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/sockopt_unix.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/sockopt_wasm.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/sockopt_windows.go is excluded by !vendor/**
  • vendor/go.etcd.io/etcd/client/pkg/v3/transport/tls.go is excluded by !vendor/**
📒 Files selected for processing (4)
  • go.mod (7 hunks)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (1 hunks)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (8 hunks)
  • test/integration/work/manifestworkreplicaset_test.go (5 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-11-06T08:55:13.306Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1242
File: pkg/work/spoke/controllers/manifestcontroller/manifestwork_reconciler.go:88-88
Timestamp: 2025-11-06T08:55:13.306Z
Learning: In pkg/work/spoke/controllers/manifestcontroller/manifestwork_controller.go, the sync method initializes a logger with manifestWorkName and attaches it to the context before calling reconcile methods. Therefore, reconcile methods (like manifestworkReconciler.reconcile) that use klog.FromContext(ctx) automatically inherit the manifestWorkName context and do not need to add it again.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go
  • go.mod
📚 Learning: 2025-09-03T08:43:34.751Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: test/integration/work/completedmanifestwork_test.go:216-256
Timestamp: 2025-09-03T08:43:34.751Z
Learning: In TTL=0 ManifestWork deletion tests, avoid waiting for WorkComplete condition because the controller deletes the resource immediately upon completion, creating a race condition where the test tries to check completion status on an already-deleted resource.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
  • test/integration/work/manifestworkreplicaset_test.go
📚 Learning: 2025-07-01T02:27:10.927Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1053
File: vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/agent/client/manifestwork.go:237-237
Timestamp: 2025-07-01T02:27:10.927Z
Learning: In OCM ManifestWork agent client, when a work is being deleted (DeletionTimestamp set and finalizers removed), the agent publishes a status update event (types.UpdateRequestAction) with ResourceDeleted condition set to True to inform the hub that deletion is complete, rather than publishing a delete request event.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
  • test/integration/work/manifestworkreplicaset_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: mqtt-work-integration
  • GitHub Check: grpc-work-integration
  • GitHub Check: e2e
  • GitHub Check: e2e-hosted
  • GitHub Check: e2e-singleton
  • GitHub Check: integration
  • GitHub Check: unit
  • GitHub Check: build
  • GitHub Check: verify
🔇 Additional comments (4)
go.mod (1)

34-39: I need to verify the version changes in go.mod and research compatibility issues.

Now I need to check the go.mod file to confirm the exact version changes being made:

Based on my verification research, I can now provide the rewritten review comment:

No blocking compatibility issues found; however, verify test execution with these versions.

Kubernetes v1.34 will not include any removal or deprecation, focusing on enhancements. controller-runtime v0.22 is designed for k8s.io/* v0.34, and controller-runtime v0.22.3 includes a bump to k8s.io/* v0.34.1—the version pairing in this PR aligns with upstream expectations.

The codebase's extensive use of Kubernetes client libraries (k8s.io/api, k8s.io/apimachinery, k8s.io/client-go, k8s.io/apiserver, k8s.io/component-base) is standard and no version-specific TODOs or deprecation warnings were found in the code.

Recommended next step: Confirm the integration test suite passes with these updated versions to validate the reconciliation logic for ManifestWorkReplicaSet functions correctly.

pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (2)

594-601: Good: ProgressDeadline test now models Applied-first gating.

Setting WorkApplied to True with ObservedGeneration == mw.Generation before Progressing/Degraded in TestRequeueWithProgressDeadline aligns the fixture with the new controller gating and ensures the rollout timeout is exercised only after successful apply.


902-908: ClusterRolloutStatusFunc tests correctly incorporate WorkApplied precondition.

The added WorkApplied=True conditions (with matching ObservedGeneration) in the non‑ToApply scenarios make the table-driven tests accurately reflect the new rollout-status contract:

  • Gating on Applied before interpreting Progressing/Degraded.
  • Ensuring status/LastTransitionTime expectations are validated only when the work is known-applied for the current generation.

This is a solid update that protects these tests from future regressions in the gating logic.

Also applies to: 933-939, 971-977, 1009-1015, 1047-1053, 1079-1084, 1117-1122

test/integration/work/manifestworkreplicaset_test.go (1)

389-394: Integration rollout tests now correctly require Applied=True before agent conditions.

Across the progressive, max‑failure, min‑success‑time, and deadline‑tolerating tests, the new WorkApplied conditions (Status=True, ObservedGeneration == workCopy.Generation) are set before Progressing/Degraded. This matches the controller’s Applied-first gating and ensures these scenarios are exercising the intended rollout behavior, not relying on pre‑Applied agent conditions.

Also applies to: 413-418, 456-461, 518-525, 593-600

@haoqing0110
haoqing0110 force-pushed the fix-rollout-applied-condition-check branch from 6fe8455 to c146fb8 Compare November 26, 2025 06:21

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (1)

902-908: Consistent additions, but consider edge case coverage.

The WorkApplied conditions are consistently added to all test cases where Progressing has matching ObservedGeneration. This correctly validates the new gating logic.

However, based on issue #1237's objectives about preventing premature rollout advancement, consider adding test cases for these edge scenarios:

  • WorkApplied with Status=False
  • WorkApplied with ObservedGeneration < current Generation (stale Applied condition)
  • Progressing=False with old ObservedGeneration but newer WorkApplied.ObservedGeneration

These would verify the production code properly handles stale or inconsistent Applied conditions to prevent the rollout gaps mentioned in the issue.

Also applies to: 933-939, 971-977, 1009-1015, 1047-1053, 1078-1084, 1116-1122

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6fe8455 and c146fb8.

📒 Files selected for processing (3)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go (1 hunks)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (8 hunks)
  • test/integration/work/manifestworkreplicaset_test.go (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go
  • test/integration/work/manifestworkreplicaset_test.go
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: test/integration/work/completedmanifestwork_test.go:216-256
Timestamp: 2025-09-03T08:43:34.751Z
Learning: In TTL=0 ManifestWork deletion tests, avoid waiting for WorkComplete condition because the controller deletes the resource immediately upon completion, creating a race condition where the test tries to check completion status on an already-deleted resource.
📚 Learning: 2025-09-03T08:43:34.751Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: test/integration/work/completedmanifestwork_test.go:216-256
Timestamp: 2025-09-03T08:43:34.751Z
Learning: In TTL=0 ManifestWork deletion tests, avoid waiting for WorkComplete condition because the controller deletes the resource immediately upon completion, creating a race condition where the test tries to check completion status on an already-deleted resource.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
📚 Learning: 2025-07-01T02:27:10.927Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1053
File: vendor/open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work/agent/client/manifestwork.go:237-237
Timestamp: 2025-07-01T02:27:10.927Z
Learning: In OCM ManifestWork agent client, when a work is being deleted (DeletionTimestamp set and finalizers removed), the agent publishes a status update event (types.UpdateRequestAction) with ResourceDeleted condition set to True to inform the hub that deletion is complete, rather than publishing a delete request event.

Applied to files:

  • pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: build
  • GitHub Check: integration
  • GitHub Check: unit
  • GitHub Check: verify
  • GitHub Check: e2e-singleton
  • GitHub Check: e2e
  • GitHub Check: e2e-hosted
  • GitHub Check: grpc-work-integration
  • GitHub Check: mqtt-work-integration
🔇 Additional comments (1)
pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_test.go (1)

594-601: LGTM! WorkApplied condition correctly added.

The addition of the WorkApplied condition with matching ObservedGeneration correctly simulates a work that has been applied before transitioning to Progressing/Degraded states. This aligns with the PR objective to gate rollout status evaluation on the Applied condition.

@haoqing0110
haoqing0110 force-pushed the fix-rollout-applied-condition-check branch from c146fb8 to 4cb6735 Compare November 26, 2025 07:05
@qiujian16

qiujian16 commented Nov 26, 2025

Copy link
Copy Markdown
Member

@haoqing0110 do we have a clearer doc on rollingout and how conditions determine each step? Is this still consistent with what you wrote in enhancement proposal?

@haoqing0110

Copy link
Copy Markdown
Member Author

/unhold

@haoqing0110

Copy link
Copy Markdown
Member Author

@qiujian16 yes, need to update the manfiestwork rollout condition requirements part.
https://open-cluster-management.io/docs/concepts/work-distribution/manifestworkreplicaset/#condition-requirements

@youngbupark this PR may have a little effect on https://github.com/open-cluster-management-io/enhancements/pull/160/files , need to add a column for Applied, but it does not affect the overall design.

// - Degraded condition exists but hasn't observed the latest spec
// (Degraded is optional, but if it exists, we wait for it to catch up)
if progressingCond == nil ||
//

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

move this to a separated func and build ut around it.

This if branch is too complicated, try to simplify it to make easier to read in the separated func.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed. Add a new shouldReturnToApply func.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Qing Hao <qhao@redhat.com>
@haoqing0110
haoqing0110 force-pushed the fix-rollout-applied-condition-check branch from 4cb6735 to 2176f60 Compare November 28, 2025 04:35

@qiujian16 qiujian16 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/approve
/lgtm

@openshift-ci openshift-ci Bot added the lgtm label Dec 1, 2025
@openshift-ci

openshift-ci Bot commented Dec 1, 2025

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: haoqing0110, qiujian16

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 label Dec 1, 2025
@openshift-merge-bot
openshift-merge-bot Bot merged commit 26edb94 into open-cluster-management-io:main Dec 1, 2025
19 checks passed
@haoqing0110
haoqing0110 deleted the fix-rollout-applied-condition-check branch December 1, 2025 02:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

enhance the MWRS rollout gaps

5 participants