Skip to content

Add no-op companion for API Compatibility required check#4995

Merged
ChrisJBurns merged 1 commit intomainfrom
chris/api-compat-noop-companion
Apr 21, 2026
Merged

Add no-op companion for API Compatibility required check#4995
ChrisJBurns merged 1 commit intomainfrom
chris/api-compat-noop-companion

Conversation

@ChrisJBurns
Copy link
Copy Markdown
Collaborator

Summary

Branch protection on main requires CRD Schema Compatibility to pass. The real workflow (api-compat.yml, introduced in #4980 and refined in #4987, #4991, #4993) is filtered to PRs touching cmd/thv-operator/api/**, deploy/charts/operator-crds/files/crds/**, or the workflow itself — correct in isolation, but it deadlocks every PR that doesn't touch those paths: the workflow never fires, the required check never reports, GitHub marks it as "expected — waiting to be reported" indefinitely, and the PR cannot merge.

Example: #4942 (a status-helper refactor that touches zero API surface) is currently blocked on this.

This PR adds a companion no-op workflow that satisfies the required check on PRs that don't touch the api surface.

How it works

.github/workflows/api-compat-noop.yml uses the same workflow name: (API Compatibility) and job name: (CRD Schema Compatibility) as the real workflow, so the resulting check-run context string is identical. Branch protection treats a successful report from either workflow as satisfying the requirement.

The two workflows use strictly complementary path filters:

File Filter Fires when
api-compat.yml paths: include the api-surface paths + api-compat*.yml PR touches any api-surface file or either workflow file
api-compat-noop.yml paths-ignore: same list PR touches nothing in that list

The real workflow also gets a small change: its self-watch path broadens from .github/workflows/api-compat.yml to .github/workflows/api-compat*.yml, so edits to either workflow fire the real check (and the companion skips via paths-ignore, avoiding a double-fire on workflow edits).

Caveats

  1. This PR unblocks itself. The edit to api-compat.yml matches the real workflow's paths: filter, so the real check fires on this very PR. No CRDs changed, so it reports Compatible and the PR is mergeable without the companion needing to exist yet.

  2. Currently-blocked PRs need a resync after merge. Introduce MutateAndPatchStatus helper for status writes #4942 (and any other PR stuck on the same deadlock) will remain stuck until someone pushes a commit, rebases onto main, or reopens the PR — that's what causes the branch-protection status to re-evaluate against the newly-merged companion. The fix does not unblock retroactively.

  3. Keep the paths lists in sync. If someone adds a new path to the real workflow's paths:, the same path must be added to the companion's paths-ignore: (and vice versa). Drift causes either a deadlock (path removed from paths-ignore but still in paths) or a double-fire (added to one without the other). The companion workflow's header comment calls this out explicitly.

Type of change

  • Bug fix
  • New feature
  • Refactoring
  • Dependency update
  • Documentation
  • Other

Test plan

  • Both workflow YAML files parse cleanly (python3 -c 'import yaml; yaml.safe_load(...)').
  • The real workflow's self-watch now matches api-compat*.yml, so this PR triggers the real check (no CRD changes → Compatible).
  • The companion's paths-ignore list is byte-identical to the real workflow's paths list (modulo the api-compat*.yml glob covering both workflow files).
  • After merge: verify Introduce MutateAndPatchStatus helper for status writes #4942 becomes mergeable after a resync (either a rebase onto main or any fresh push).
  • After merge: verify a fresh PR touching only a Go file outside cmd/thv-operator/api/ sees the companion workflow run to completion in seconds and reports CRD Schema Compatibility as success.
  • Unit tests (task test) — N/A, no Go changes.
  • Linting (task lint-fix) — N/A, no Go changes.

API Compatibility

  • This PR does not break the v1beta1 API.

Does this introduce a user-facing change?

No. Internal CI only. Contributors who previously saw PRs deadlock on the required status check will now see the check report success in seconds when their PR doesn't touch api surface.

Special notes for reviewers

  • Why a whole second workflow file. The canonical GitHub-recommended pattern for path-filtered required checks. Alternatives like dorny/paths-filter inside the main workflow trade the simpler file for more machinery; given this is a 30-line no-op, the two-file approach is cleaner.
  • Job timeout-minutes: 2. The no-op is a single echo — it should complete in well under a second. The 2-minute bound protects against runner starvation.
  • Check-name sensitivity. If either workflow's job.name: is ever renamed, both must move together, and the branch-protection required-check list must be updated to the new name. The current name CRD Schema Compatibility is load-bearing.

Generated with Claude Code

Branch protection on main requires the CRD Schema Compatibility check
to pass. The real workflow (api-compat.yml, introduced in #4980 and
refined in #4987, #4991, #4993) has a paths filter that limits it to
PRs touching cmd/thv-operator/api/**, files/crds/**, or the workflow
itself — correct in isolation, but deadlocks every PR that doesn't
touch those paths: the workflow never fires, the required check
never reports, GitHub marks it as expected-but-waiting forever, and
the PR cannot merge.

Add a companion workflow with paths-ignore set to the inverse path
list, reusing the same workflow name and job name so the check-run
context string is identical (CRD Schema Compatibility). On PRs that
don't touch the api surface, the companion runs in a few seconds,
echoes a short message, and reports success — satisfying branch
protection.

Broaden the real workflow's self-watch from .github/workflows/
api-compat.yml to .github/workflows/api-compat*.yml so edits to
either file fire the real check and keep the companion from firing
on its own edits.

Keep the paths and paths-ignore lists mutually exclusive. A path
that moves from one list needs to move from the other or the
deadlock (or a double-fire) returns.

Currently-open PRs blocked by this deadlock need to resync with
main (rebase, merge, or any fresh push) after this lands to pick
up the companion workflow. The fix does not unblock them
retroactively.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ChrisJBurns ChrisJBurns requested a review from JAORMX as a code owner April 21, 2026 21:50
@github-actions github-actions Bot added the size/XS Extra small PR: < 100 lines changed label Apr 21, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.99%. Comparing base (c717272) to head (d25eb39).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4995   +/-   ##
=======================================
  Coverage   68.98%   68.99%           
=======================================
  Files         552      552           
  Lines       72996    72996           
=======================================
+ Hits        50359    50364    +5     
+ Misses      19639    19634    -5     
  Partials     2998     2998           

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

@ChrisJBurns ChrisJBurns merged commit a543b35 into main Apr 21, 2026
68 of 69 checks passed
@ChrisJBurns ChrisJBurns deleted the chris/api-compat-noop-companion branch April 21, 2026 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XS Extra small PR: < 100 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants