ci: add PR version-suggestion comment (precursor to auto-release) - #6
Merged
Conversation
aesslinger
force-pushed
the
ci/semver-checks
branch
from
August 11, 2026 17:28
8ed9c87 to
8e3425b
Compare
A precursor to eventually automating tag/release creation: when a PR's title implies a version bump, CI now posts a comment suggesting the next tag/version — without creating anything. Several real design decisions, each resolved with the user rather than assumed: - Type -> bump mapping: standard Conventional Commits (feat->minor, fix/refactor/perf->patch, docs/style/chore/test/ci/build->none, !/BREAKING CHANGE->major). - Beta-phase behavior: while the baseline version carries a -beta.N/-rc.N suffix, a release-worthy PR just increments that stage's counter, not a full patch/minor/major recompute -- nothing has shipped stable yet. - Prerelease channel: NOT signaled in the title. Checked precedent first (semantic-release/release-please control channel via labels or release- train branches, not embedded title syntax; no Tabularis repo does this either) and settled on a required prerelease:alpha|beta|rc|stable PR label. Missing label is a hard error -- the job fails rather than guessing a default channel. - Version baseline: latest git tag on main, falling back to main's .tabularium version field if no tag exists (true right now). - "Meaningful change" trigger: only re-comments when the PR's *derived classification* (type+breaking+channel) changes, not on every title edit -- tracked via a hidden HTML marker in the comment body, robust across opened/edited/reopened/synchronize/labeled/unlabeled. - Marking old suggestions outdated: GitHub's real minimizeComment GraphQL mutation with classifier: OUTDATED -- the same action available via the web UI's "..." menu -> "Hide comment" -> "Outdated". - Found and fixed a real trigger gap: the existing pull_request: block had no types:, defaulting to opened/synchronize/reopened -- a title-only edit never even re-ran CI. Widened to include edited/labeled/unlabeled (shared by all pull_request-triggered jobs, including the existing pr-title job, which also now re-validates on edited). Checked precedent before implementing: no sibling Tabularis plugin repo or tabularis itself has anything like this. A separate internal repo has a fuller PR-title-driven auto-tag/auto-release pipeline; decided against porting that whole pipeline here since it's a much larger behavioral change (replaces manual tagging entirely) with no Tabularis-org precedent -- this stays comment-only. Verified thoroughly before trusting the logic in CI: - Extracted the embedded classification regex and ran it in a real bash subshell (not zsh, which handles BASH_REMATCH differently) against 8 title cases -- all classified correctly, including a deliberately unparseable title correctly erroring. - Extracted the embedded version-arithmetic JS and unit-tested it standalone against 7 cases (beta-counter increment, stage transitions, graduation to stable from both beta and rc, stable->prerelease restart) -- all passed. - Wrote a full mock harness for the comment-orchestration logic (fake github.rest.issues.listComments/createComment and github.graphql) and ran 8 end-to-end scenarios covering: fresh suggestion, idempotent no-op on unchanged classification, minimize-and-repost on changed classification, silent on non-release-worthy titles, and the "no-release-needed" transition in both directions. This caught a real bug before it ever reached CI: the "already said none, still none" case incorrectly reposted because the idempotency check compared against a hardcoded string instead of the full classification -- fixed and reverified all 8 scenarios pass. - Confirmed the baseline resolves correctly against the actual current repo state: main now has real tags (v1.0.0-beta.1, v1.0.0-beta.2), so `git describe --tags` resolves directly against origin/main rather than the PR branch; the .tabularium fallback remains for the no-tags-yet case this repo has already moved past. - Both workflow YAML files re-validated after every edit. Also added contributor-facing docs (README's "Contributing: PR Titles & Versioning" section, cross-referenced from CLAUDE.md) so future maintainers understand the convention without reading the workflow YAML. Standard verification: cargo build/test (82/82)/clippy/fmt all pass, no Cargo.lock drift, markdownlint clean across the whole repo, both workflow files parse as valid YAML. Rebased onto main after #5 merged (adds the pr-title job and release validate job this PR builds on) — no functional changes beyond the rebase itself, CHANGELOG merge conflict resolved by keeping both entries.
aesslinger
force-pushed
the
ci/version-suggestion-comment
branch
from
August 11, 2026 17:44
6ae469b to
88dbd83
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A precursor to eventually automating tag/release creation. When a PR's title implies a version bump, CI now posts a comment suggesting the next tag/version — nothing is created automatically, purely informational.
Rebased onto current
mainnow that #5 (release-version validation,pr-titlejob) has merged — this PR builds directly on both.Design decisions (each resolved directly rather than assumed)
feat→minor,fix/refactor/perf→patch,docs/style/chore/test/ci/build→none,!/BREAKING CHANGE:→major).-beta.N/-rc.Nsuffix, a release-worthy PR just increments that stage's counter (1.0.0-beta.1→-beta.2), not a full patch/minor/major recompute — there's no shipped stable version yet to protect a SemVer contract against.semantic-release/release-pleasecontrol channel via labels or release-train branches, not embedded title syntax; no Tabularis repo does this either. Settled on a requiredprerelease:alpha|beta|rc|stablePR label. Missing label is a hard error — the job fails with a clear message rather than guessing a default channel.main—maincurrently has real tags (v1.0.0-beta.1,v1.0.0-beta.2), sogit describe --tagsresolves directly; the.tabulariumfallback remains for the (now past) no-tags-yet case.minimizeCommentGraphQL mutation withclassifier: OUTDATED— the same action available via the web UI's "..." menu → "Hide comment" → "Outdated".pull_request:block had notypes:, defaulting toopened/synchronize/reopened— a title-only edit never even re-ran CI. Widened to includeedited/labeled/unlabeled(shared by allpull_request-triggered jobs, including the existingpr-titlejob, which also now correctly re-validates on title edits).Checked precedent before implementing: no sibling Tabularis plugin repo or
tabularisitself has anything like this. A separate internal repo has a fuller PR-title-driven auto-tag/auto-release pipeline; decided against porting that whole pipeline here since it's a much larger behavioral change (replaces manual tagging entirely) with no Tabularis-org precedent — this PR stays comment-only.Testing — thorough, before trusting any of this in real CI
bashsubshell (not zsh, which handlesBASH_REMATCHdifferently — caught this the hard way) against 8 title cases. All classified correctly, including a deliberately unparseable title correctly erroring.github.rest.issues.listComments/createCommentandgithub.graphql) and ran 8 end-to-end scenarios: fresh suggestion, idempotent no-op on unchanged classification, minimize-and-repost on changed classification, silent on non-release-worthy titles, and the "no-release-needed" transition in both directions."none"instead of the full classification string. Fixed and reverified all 8 scenarios pass.What does NOT change
pr-titleandvalidate-manifest/release.ymlvalidatejobs are unchanged in behavior — only the sharedpull_request:trigger'stypes:list gains entries.Docs
Added a "Contributing: PR Titles & Versioning" section to the README (cross-referenced from
CLAUDE.md) so future contributors/maintainers understand the convention without reading the workflow YAML.Test plan
cargo build/test --lib --bins(82/82)/clippy/fmt --checkall passgit diff --exit-code Cargo.lock: no driftmarkdownlint-cli "**/*.md": clean