Skip to content

ci(release): release a breaking change at once instead of waiting for the cadence - #3408

Merged
vitali87 merged 4 commits into
mainfrom
claude/release-on-breaking-change
Oct 20, 2026
Merged

vitali87 merged 4 commits into
mainfrom
claude/release-on-breaking-change

Conversation

@vitali87

@vitali87 vitali87 commented Oct 20, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • A breaking change label now publishes a release, like a security fix. Until now the label only raised the minor number. The bump's tag went out over GITHUB_TOKEN as an interim tag, and the release waited for the 50-version cadence, so 0.2.0 had to be released by hand. Now version-bump.yml's decide step sets release=true whenever a PR labelled breaking change is in the unreleased range.
  • A deferred breaking release still ships. If CI isn't green within the gate's window, the release is deferred and the next run scans from behind the deferred tag. The label is now read across that whole range for the release, but still only since the newest bump for the version number. So the next bump releases without raising the minor number a second time. A breaking change merged together with a hand-set version is released the same way.
  • Docs updated to the new rule: docs/contributing.md, the README version table, docs/getting-started/installation.md, and the label's description in .github/labels.yml.

Demo

No user-visible change: this only changes when the version-bump workflow decides to publish a release.

Type of Change

  • Bug fix
  • New feature
  • Performance improvement
  • Refactoring (no functional changes)
  • Documentation
  • CI/CD or tooling
  • Dependencies

Related Issues

Related to #3407: merging it today would tag 0.3.0 without releasing it.

Test Plan

  • Unit tests pass (make test-parallel or uv run pytest -n auto -m "not integration")
  • New tests added
  • Integration tests pass (make test-integration, requires Docker)
  • Manual testing (describe below)

Ran test_version_bump_serialization.py, test_version_bump_rollover.py, test_release_ci_gate.py and test_release_news_derivation.py (153 passed), plus test_generated_docs_are_current.py, test_generate_readme.py and test_validate_labels.py (67 passed). I did not run the full suite: the change only touches the workflow, docs and these tests. The existing test that asserted "A breaking change waits for the cadence" now asserts a release. There are two new tests: a deferred breaking release ships on the next bump, and a breaking change behind a hand-set version still ships. All three fail against the old workflow and pass with this change.

Checklist

  • PR title follows Conventional Commits format
  • All pre-commit checks pass (make pre-commit): I ran ruff check, ruff format --check, scripts/validate_labels.py and scripts/hooks/generate_readme.py (no change) directly, not through make pre-commit.
  • No hardcoded strings in non-config/non-constants files
  • No # type: ignore, cast(), Any, or object type hints
  • New comments and docstrings explain why, not what (see Comment Policy)

Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Xdebug trace conversion now supports gzip-compressed .xt.gz files.
    • Compressed traces are validated for corruption, truncation, and size limits with clear errors.
  • Release Process

    • Breaking changes now trigger an immediate release, alongside security fixes.
    • Deferred breaking changes are released at the next eligible version without being counted twice.
    • Regular GitHub Releases and PyPI publications continue every 50th version.
  • Documentation

    • Updated release, installation, and tracing guidance covers breaking-change versioning and compressed Xdebug traces.
  • Tests

    • Expanded coverage for breaking-change releases and compressed Xdebug trace conversion.

… the cadence

A `breaking change` label raised the minor number but published nothing: the
bump's tag went out over GITHUB_TOKEN as an interim tag, and the release
waited for the 50-version cadence like any other change, so 0.2.0 had to be
released by hand.

The decide step now releases whenever a pull request labelled `breaking
change` is anywhere in the unreleased range, like a security fix. The bump
type still counts the label only since the newest bump, so a deferred
breaking release ships on the next bump without bumping the number again,
and a breaking change merged with a hand-set version still ships.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vJuBD56koVwEaSaTM3nQ7
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T07:20:11.899563Z 450ee11 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: vitali87/code-graph-rag/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Advanced
  • Run ID: 83fd9579-5f1f-423d-86c9-5ebd06f7d4d1
📥 Commits

Reviewing files that changed from the base of the PR and between 450ee11 and 553fcae.

📒 Files selected for processing: 7
  • codebase_rag/constants/trace.py
  • codebase_rag/tests/test_dynamic_trace_cli.py
  • codebase_rag/tests/test_dynamic_trace_xdebug.py
  • codebase_rag/trace/cli.py
  • codebase_rag/trace/pprof.py
  • codebase_rag/trace/xdebug.py
  • docs/guide/dynamic-tracing.md

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Walkthrough

The pull request changes breaking-change release selection and adds gzip-compressed Xdebug trace conversion with bounded decompression, error handling, tests, and documentation.

Changes: Breaking-change releases

Layer / File(s) Summary
Track and release breaking changes
.github/workflows/version-bump.yml, codebase_rag/tests/test_version_bump_serialization.py, .github/labels.yml, README.md, docs/contributing.md, docs/getting-started/installation.md
The workflow tracks unreleased breaking changes separately from counted breaking bumps. It triggers releases for unreleased breaking changes or security fixes. Tests and documentation cover immediate, deferred, and manually versioned cases.

Compressed Xdebug traces

Layer / File(s) Summary
Decompress and convert Xdebug traces
codebase_rag/constants/trace.py, codebase_rag/trace/pprof.py, codebase_rag/trace/xdebug.py
Xdebug conversion reads plain and gzip-compressed traces through shared decompression logic. The logic applies a decompressed-size limit and Xdebug-specific format errors.
Validate compressed trace support
codebase_rag/trace/cli.py, codebase_rag/tests/test_dynamic_trace_cli.py, codebase_rag/tests/test_dynamic_trace_xdebug.py, docs/guide/dynamic-tracing.md
The CLI recognizes .xt and .xt.gz inputs. Tests cover successful conversion, invalid and truncated gzip data, equivalent plain and compressed results, and the decompression limit. Documentation describes direct conversion and the 256 MiB limit.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant CLI as _convert_profile
  participant Xdebug as convert_xdebug_trace
  participant Decompressor as _decompress
  CLI->>Xdebug: Route .xt or .xt.gz input
  Xdebug->>Decompressor: Decompress gzip input with Xdebug error templates
  Decompressor-->>Xdebug: Return trace bytes
  Xdebug-->>CLI: Return converted trace records
Loading

Suggested reviewers: claude

Merge Risk: ⚪ Minimal · up to 553fc

Compressed Xdebug traces can now be converted directly, within the documented 256 MiB decompression limit. Breaking-change releases now publish immediately. No outstanding defects were found, and the change appears ready to merge.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main workflow change and follows Conventional Commits format.
Description check Passed The description is complete and relevant. It covers the change, user-visible impact, change type, related issue, tests run, limitations, and checklist status.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 450ee11e92

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/version-bump.yml Resolved
@greptile-apps

greptile-apps Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] This PR appears safe to merge.

Summary

Breaking changes now trigger a release without waiting for the 50-version cadence.

  • Breaking-change versions now ship without waiting for the release cadence.

No actionable issues found. Tests were inspected but not run.

Reviews (1) · Last reviewed commit: "ci(release): release a breaking change a..." · Reviewed by Greptile

Xdebug >= 3.1 built with zlib defaults to xdebug.use_compression=1 and
writes run.xt.gz instead of run.xt. The GitHub ubuntu runner image's
Xdebug now does this, so the live Xdebug tests (which glob run.xt*) hand
convert_xdebug_trace a gzip file; it read the bytes as text, found no
"File format: 4" header and raised TraceFormatError, failing every PR's
ubuntu unit shards and the base-install job. Real users with a
zlib-enabled Xdebug hit the same error.

convert_xdebug_trace now sniffs the gzip magic bytes and decompresses
such traces; plain traces read as before, and a truncated or corrupt
gzip stream is a TraceFormatError naming the file instead of a bare
EOFError. `cgr trace convert` routed .xt.gz to the pprof converter by
its gzip magic, so the Xdebug suffix check (.xt or .xt.gz) now runs
before that sniff. The PHP tracing guide mentions the .xt.gz name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
A .xt.gz trace was read with gzip.open(...).read(), so a small, highly
compressible file inflated whole into memory. Reuse the bounded chunked
inflater that gzipped pprof profiles already go through (#2263), with
Xdebug-worded errors; past the cap the error says to gunzip a genuine
trace and convert the .xt file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
The ubuntu runner image's Xdebug now writes gzip-compressed run.xt.gz
traces, so the two live tests in test_dynamic_trace_xdebug.py fail on
every PR, and the ubuntu shards, base install and SonarCloud with them.
#3409 reads such traces; its commits are taken whole so this merge is a
no-op once main carries them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vJuBD56koVwEaSaTM3nQ7

Copy link
Copy Markdown
Owner Author

CI on 450ee11 was red for a reason outside this PR:

  • Red checks: Unit Tests (ubuntu-latest, py3.12/py3.13, shard 1/2), Unit Tests (base install) and SonarCloud Analysis. Sonar Zero Issues Gate and All Checks Pass were red only because they follow SonarCloud.
  • The cause: each of these jobs failed only on two live tests in test_dynamic_trace_xdebug.py, with run.xt.gz is not an Xdebug computerized trace. The ubuntu runner image's Xdebug now writes gzip-compressed traces, so every open PR fails the same way. This PR touches only the version-bump workflow, docs and their tests.
  • The fix: I merged fix(trace): read gzip-compressed Xdebug traces #3409's two commits (ea4668b, 21f0d84) unchanged into this branch in 553fcae. That merge becomes a no-op once fix(trace): read gzip-compressed Xdebug traces #3409 lands on main. The old converter raises the same error on fix(trace): read gzip-compressed Xdebug traces #3409's gzip-trace test, and the merged code passes it. The release and trace tests pass locally (182 passed; the two live PHP tests skip here because this container's PHP has no Xdebug).

Generated by Claude Code

@sonarqubecloud

Copy link
Copy Markdown

@vitali87
vitali87 merged commit 346b85d into main Oct 20, 2026
39 checks passed
@vitali87
vitali87 deleted the claude/release-on-breaking-change branch October 20, 2026 15:11
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
vitali87 pushed a commit that referenced this pull request Oct 20, 2026
No conflicts. Brings in #3409 (via #3408) so the live Xdebug tests read gzip traces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MgsnsA3jM14E4ai22xnhy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants