Skip to content

ci(stack): check migrations against the proposed stack version bump - #1983

Draft
kristinapathak wants to merge 1 commit into
mainfrom
kpathak/ci-stack-upgrade-policy
Draft

kristinapathak wants to merge 1 commit into
mainfrom
kpathak/ci-stack-upgrade-policy

Conversation

@kristinapathak

Copy link
Copy Markdown
Collaborator

First piece of #1974. Closes #1975.

Summary

  • Adds tools/stack-upgrade-policy, a Go tool that reports the schema migrations a stack release candidate introduces since that stack's last published release tag, and fails when they do not match the version bump the candidate is proposing.
  • Adds tools/ci/check-stack-upgrade-policy, the bash entrypoint, mirroring tools/ci/chart-service-edge.
  • Declares migration_paths for nvcf-self-managed-stack in the existing release metadata rather than adding a new per-stack config file. The compute-plane and observability stacks declare none, so the check is an explicit no-op for them until they ship schema.
  • Runs as a pull_request-only matrix job over all three stacks in build-test.yml.

Why this shape

The upgrade contract is that a customer installs each stack major version in order, derived from the version numbers alone — no published catalog, no floor field to maintain per release. What that rule needs in exchange is that a major boundary actually gets cut whenever a candidate contains something a customer cannot safely skip past.

That is not decidable by eye. A stack-pin diff is a list of chart versions moving, and nothing in 1.5.3 -> 2.0.0 says a migration landed. In a monorepo the evidence is computable, which also means it cannot be forgotten the way a declaration written in a PR two months earlier can.

Additive migrations never qualify. golang-migrate applies the ordered set per keyspace, so a cluster many versions behind still arrives at the right schema; skipping stack versions never skips schema migrations.

Destructive migrations and deleted migration files do. A drop is unrecoverable without a restore, and a deleted migration is how a compatibility bridge stops shipping — once it is gone, a cluster arriving later has no way to run it.

The proposed bump comes from the existing tools/ci/release-bump-type, so this and semantic-release agree on what the candidate is proposing rather than deriving it twice.

Known limitations

  • The baseline is the stack's last release tag rather than the pinned migrations image, because the stack does not pin that image — see release: stack bundles do not pin the cassandra-migrations image version #1976. Until it does, "what landed since the last stack release" is the closest available answer to what the bundle ships.
  • Evidence is limited to .sql files under the declared paths. Component-side async backfill tasks live outside migrations/ and are not detected yet.

Test plan

  • 28 unit tests, written test-first. go test -C tools/stack-upgrade-policy ./...
  • Picked up automatically by tools/ci/check-go-tools: ok tools/stack-upgrade-policy (built, vetted, tested)
  • Comment stripping is covered by a regression test — nvcf_api/03_init_tables.up.sql documents a "high-churn write/delete workload" above a CREATE TABLE, and a classifier reading raw text calls that destructive.
  • Cross-checked the classifier against the full live corpus: it flags exactly the four real drops (nvcf_api/07_drop_gpu_spec, nvcf_autoscaler/04_drop_obsolete_function_tables, nvct_api/05_drop_health_info, nvct_api/06_delete_health_udt) and leaves the other 38 files additive.
  • Ran against this repo: nvcf-self-managed-stack: 0 migration change(s) since deploy/stacks/self-managed/v1.0.0, exit 0; observability reports no migration paths, exit 0.
  • gofmt, go vet, and actionlint clean.
  • Confirm the matrix job behaves on a real PR (this one).

🤖 Generated with Claude Code

The upgrade contract is that a customer installs each stack major version
in order, derived from the version numbers alone so nothing has to publish
a catalog or maintain a floor per release. What that rule needs in exchange
is that a major boundary is actually cut whenever a candidate contains
something a customer cannot safely skip past.

That is not decidable by eye. A stack-pin diff is a list of chart versions
moving, and nothing in "1.5.3 -> 2.0.0" says a migration landed. In a
monorepo the evidence is computable instead, which also means it cannot be
forgotten the way a declaration written in a pull request months earlier
can.

Additive migrations never qualify: golang-migrate applies the ordered set
per keyspace, so a cluster many versions behind still arrives at the right
schema. Destructive migrations and deleted migration files do, because a
drop is unrecoverable without a restore and a deleted migration is how a
compatibility bridge stops shipping.

Comments are stripped before classifying. nvcf_api/03_init_tables.up.sql
documents a "high-churn write/delete workload" above a CREATE TABLE, and a
classifier reading raw text calls that destructive. Run over the current
corpus the classifier finds exactly the four real drops and leaves the
other 38 files additive.

The baseline is the stack's last release tag rather than the pinned
migrations image, because the stack does not pin that image yet (#1976).

Refs #1975
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kristinapathak kristinapathak added the ci Continuous integration, build, and release pipeline work label Sep 18, 2026
@kristinapathak kristinapathak self-assigned this Sep 18, 2026
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci Continuous integration, build, and release pipeline work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

release: CI check validating stack version bumps against migration evidence

1 participant