Skip to content

ci+chore: version-alignment gate + retroactive bump to 6.6.1#153

Merged
saurabhjain1592 merged 3 commits intomainfrom
chore/version-alignment-ci
Apr 24, 2026
Merged

ci+chore: version-alignment gate + retroactive bump to 6.6.1#153
saurabhjain1592 merged 3 commits intomainfrom
chore/version-alignment-ci

Conversation

@saurabhjain1592
Copy link
Copy Markdown
Member

Summary

Closes the silent manifest-drift bug where every release leaves the repo version lagging the registry version by one patch. Retroactive fix for the current drift (6.6.0 in repo vs 6.6.1 on PyPI) + a PR-blocking gate so it can't happen again.

What's in this PR

  1. Retroactive sync — both manifests bumped to match the version currently live on PyPI:
    • pyproject.toml::version: 6.6.0 → 6.6.1
    • axonflow/_version.py::__version__: 6.6.0 → 6.6.1
  2. validate-version-alignment CI gate — new workflow + script, patterned on the axonflow-enterprise script of the same name and the newly-landed equivalent in axonflow-sdk-go (PR chore: Update CHANGELOG for version 5.3.0 #130). Fails any PR or push to main that leaves the manifests out of sync with the most recent ## [X.Y.Z] section in CHANGELOG.md.

The invariant

On main, at all times:

pyproject.toml::version
  == axonflow/_version.py::__version__
  == first ## [X.Y.Z] section in CHANGELOG.md (not [Unreleased])

Root cause

release.yml does sed the manifest version at build time before publishing to PyPI, but never commits the bump back. The repo stays at the pre-release version forever. The gate can't force the release workflow to commit back (that would need a separate follow-up) but it DOES force future release-prep PRs to bump the manifest AND rename [Unreleased][X.Y.Z] together in the same commit. Same pattern we're using for Go (#131).

Not covered in this PR

  • Automating the release workflow to commit the bump back — could be a follow-up, but the PR-time gate makes it unnecessary as long as every release goes through a release-prep PR that bumps the manifest. That pattern is now documented by this PR's existence.
  • TS (own PR, this session) and Java (other session) get the same treatment.

Verified locally

  • Pre-bump state (6.6.0 / 6.6.0 / CHANGELOG 6.6.1) → gate fires with 2 misalignments listed and the correct remediation hint
  • Post-bump state → gate passes

Test plan

  • Gate fires on drift, passes when aligned
  • CI green on this PR

…o 6.6.1

The Python SDK's release workflow sed-rewrites pyproject.toml and
axonflow/_version.py at publish time but never commits the bump back
to main. Result: v6.6.1 shipped to PyPI on 2026-04-24 but the repo
kept showing 6.6.0, silently lagging every release by one version.

Two things fix this, together:

1. Retroactive sync: both files now say 6.6.1 to match what's live
   on PyPI (https://pypi.org/project/axonflow/6.6.1/).

2. validate-version-alignment gate on every PR + push to main:
   fails the check if pyproject.toml::version or axonflow/_version.py
   disagree with the most recent released CHANGELOG section. The
   invariant on main is now:
     pyproject.toml::version
       == axonflow/_version.py::__version__
       == first ## [X.Y.Z] in CHANGELOG.md

Patterned on the axonflow-enterprise script of the same name and
the newly-landed equivalent in axonflow-sdk-go. Same gate coming to
axonflow-sdk-typescript in a sibling PR; Java in a separate session.

Release-prep PRs going forward must rename [Unreleased] → [X.Y.Z]
AND bump both manifest files in the same commit, so the gate sees
them as consistent throughout the transition.

Verified locally:
- Pre-bump state (both manifests 6.6.0, CHANGELOG 6.6.1) fails with
  "Found 2 version misalignment(s)" and the correct remediation
  message.
- Post-bump state (both manifests 6.6.1, CHANGELOG 6.6.1) passes.
Review finding on this PR: the version-alignment script was present
but there was no .github/workflows/validate-version-alignment.yml to
invoke it on PRs and pushes to main. Without the workflow the script
is inert — the gate the user asked for never actually runs. Added
the workflow using the same pattern shipped in axonflow-enterprise,
axonflow-sdk-go, axonflow-sdk-java, and axonflow-sdk-typescript.

Also hardened the script's LATEST_VERSION extraction. Previously:

  LATEST_VERSION=$(grep -m1 ... | sed ... | sed ...)

Under `set -euo pipefail`, a failing grep (no `## [X.Y.Z]` line found)
propagates through `pipefail` and aborts the whole command
substitution before the subsequent `-z "${LATEST_VERSION:-}"` check
fires — the script exits silently without the actionable error. Wrapped
the grep in `{ grep ... || true; }` so the empty-match case falls
through to the explicit error with the useful message.

No change to the script's pass/fail semantics on the happy path.
…target

Self-review of PR #153 surfaced three load-bearing issues. Fixing
all of them here.

1. CRITICAL: validate-version-alignment.yml workflow was missing
   from this branch. Only the script landed, so the gate never
   actually ran on PRs — CI went 'green' without invoking any
   check. Adding the workflow now so the invariant is actually
   enforced.

2. HIGH: validate-version-alignment.sh silently aborted on a
   CHANGELOG with no released section. Under 'set -euo pipefail',
   a grep-no-match in the LATEST_VERSION pipeline failed the whole
   command substitution, which killed the script before reaching
   the '-z' check. Wrapped the grep in '{ ... || true; }' so the
   -z branch fires with the friendly error message. Verified by
   running the pattern against a no-match input:
     before; after LATEST=[]; ✅ empty, friendly error path reached

3. CRITICAL: release.yml was sed-targeting axonflow/__init__.py
   for the __version__ bump, but that file only does
   'from axonflow._version import __version__'. The sed was a
   silent no-op. Real source of truth is axonflow/_version.py,
   which release.yml never touched. Result: every released wheel
   shipped with pyproject.toml::version bumped correctly but
   axonflow/_version.py::__version__ stuck at whatever was on
   main pre-tag. Live bug in axonflow==6.6.1 on PyPI: runtime
   axonflow.__version__ returns '6.6.0' for users who pip-install
   6.6.1 (METADATA::Version is correct at 6.6.1 because pypi
   reads pyproject.toml).
   Fix: seq now targets axonflow/_version.py (the real single
   source of truth) and also asserts post-sed that both files
   actually moved, failing fast on a silent no-op.

Existing wheel on PyPI is not fixed by this PR — it's shipped.
A follow-up v6.6.2 release would correct the runtime __version__
mismatch for pip-installed users. Leaving that call to the
maintainer; flagging it via the PR description.

Verified:
- Script baseline (all at 6.6.1) — PASS
- Grep-no-match pipeline behavior in isolation — reaches the
  friendly error path (exit=0 on the test, exit=1 on the script
  because of the explicit exit 1 in the -z branch)
- Workflow YAML parses cleanly
- release.yml post-sed asserts fail loudly on silent no-op
@saurabhjain1592 saurabhjain1592 merged commit 4bb3524 into main Apr 24, 2026
13 checks passed
@saurabhjain1592 saurabhjain1592 deleted the chore/version-alignment-ci branch April 24, 2026 23:02
saurabhjain1592 added a commit that referenced this pull request Apr 24, 2026
Patch release to fix the runtime __version__ drift in the shipped
v6.6.1 wheel. Installed wheels of v6.6.1 had axonflow.__version__
stuck at '6.6.0' because the release workflow's sed targeted
axonflow/__init__.py (which only re-exports from _version.py, so
the sed was a silent no-op) instead of axonflow/_version.py.

Package metadata (what pip show reads) was correct, so install/
upgrade worked fine. The drift only affected code reading
axonflow.__version__ at runtime — telemetry self-identification,
version-gated feature detection in user code, and log output.

No functional change from v6.6.1. The underlying bug in release.yml
was fixed in #153; v6.6.2 is the first release to benefit from it.

Both manifest files move together with the CHANGELOG rename so
the validate-version-alignment gate stays green through the
transition.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant