Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ describe exactly what you tested below the checkbox.
- [ ] Linting (`task lint-fix`)
- [ ] Manual testing (describe below)

## API Compatibility

<!--
The CRD Schema Compatibility check guards the v1beta1 operator API.
If the check flags this PR as Incompatible and the break is intentional,
apply the `api-break-allowed` label and describe below:

1. Which fields, types, or CRDs are changing.
2. Why the break is unavoidable.
3. The user-facing migration path (what cluster admins need to do).

See CONTRIBUTING.md → "API Stability" for the full rubric. Coordinate
with maintainers before applying the label.

Remove this section entirely if the PR does not touch operator API surface.
-->

- [ ] This PR does not break the `v1beta1` API, OR the `api-break-allowed` label is applied and the migration guidance is described above.

## Changes

<!--
Expand Down
18 changes: 11 additions & 7 deletions .github/workflows/api-compat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ name: API Compatibility

# This workflow guards the stability of the v1beta1 operator API surface.
#
# Phase 1 (current): advisory only. `crd-schema-check` runs with
# continue-on-error: true so breaking-change findings are surfaced via the
# job's step summary but do not block merges. Remove continue-on-error in
# Phase 2 to start enforcing.
# A breaking CRD schema change (field removal, type change, required-field
# addition, etc.) fails this check and blocks the PR. If the break is
# intentional — almost exclusively for graduation to v1beta2 — apply the
# `api-break-allowed` label to skip the check. See CONTRIBUTING.md → "API
# Stability" for the full rubric.

on:
pull_request:
Expand All @@ -28,8 +29,11 @@ jobs:
crd-schema-check:
name: CRD Schema Compatibility
runs-on: ubuntu-latest
# Phase 1: advisory only. Remove in Phase 2 to enforce.
continue-on-error: true
# Skip the check entirely when `api-break-allowed` is applied — a
# required check that is skipped (rather than failed) counts as passing
# for branch protection, so this is the escape hatch for intentional
# breaks. Do not remove the label guard without a replacement path.
if: ${{ !contains(github.event.pull_request.labels.*.name, 'api-break-allowed') }}
# Expected runtime is ~1 minute (checkout + go setup + git fetch tag +
# go install + per-CRD checker loop). 10 minutes is a cheap upper
# bound that protects against a hung go install or git fetch.
Expand Down Expand Up @@ -146,7 +150,7 @@ jobs:
fi

{
echo "## API Compatibility — CRD Schema Check (Phase 1: advisory)"
echo "## API Compatibility — CRD Schema Check"
echo ""
echo "**Baseline**: $BASELINE_TAG"
echo "**Status**: $STATUS"
Expand Down
38 changes: 38 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,41 @@ We follow the commit formatting recommendations found on
1. Do not end the subject line with a period
1. Use the imperative mood in the subject line
1. Use the body to explain what and why vs. how

## API Stability

The `v1beta1` operator API is stable. CRD schemas and Go types under
`cmd/thv-operator/api/v1beta1/` carry a compatibility commitment to users
running the published operator chart. Contributors must not:

- Remove or rename any field, type, or CRD kind in `v1beta1`.
- Change a field's Go type, JSON tag, or OpenAPI schema type.
- Add new required fields to existing types.
- Narrow validation rules (smaller `maxLength`, stricter `pattern`, fewer
`enum` values).
- Rename a finalizer or change a CRD `shortName`.
- Flip a CRD's `spec.scope` between `Namespaced` and `Cluster`.
- Un-serve a currently-served version without a deprecation-cycle release.

New fields must be optional. New behaviour must be opt-in via new fields.
The `CRD Schema Compatibility` CI check enforces the CRD side of this
contract against the last published release tag on every PR that touches
`cmd/thv-operator/api/**` or `deploy/charts/operator-crds/files/crds/**`.

### The `api-break-allowed` escape hatch

If you have a genuine reason to break the API — the main expected use
case is graduation to `v1beta2` — apply the `api-break-allowed` label to
the PR. This skips the compatibility check.

Before applying the label:

1. **Coordinate with maintainers first.** Open a Discord thread or an
issue describing what you are breaking and why.
2. **Describe the break in the PR description.** Spell out which API
elements are changing, what clusters need to do to migrate, and whether
downstream consumers (CLI, chart users, operator integrations) need
coordinated releases.
3. **Do not use the label to silence a false positive.** If the check
fires on a change you believe is non-breaking, file a bug against the
workflow — silencing it hides real breaks on subsequent PRs.
Loading