Skip to content

Start the versioned history at 0.1.0, and enforce version sync in CI - #5

Merged
FZ2000 merged 1 commit into
mainfrom
release/v0.1.0
Jul 31, 2026
Merged

Start the versioned history at 0.1.0, and enforce version sync in CI#5
FZ2000 merged 1 commit into
mainfrom
release/v0.1.0

Conversation

@FZ2000

@FZ2000 FZ2000 commented Jul 31, 2026

Copy link
Copy Markdown
Owner

This repository is a fresh public start with no prior releases. The
CHANGELOG carried 0.1.0, 0.2.0 and 0.3.0 sections describing development
that happened elsewhere, complete with release dates, while git tag was
empty and nothing had ever been published. Anyone reading it would
reasonably conclude three releases existed and go looking for them.

So: the retrospective sections are gone and the versioned history starts
at 0.1.0, describing what the tool is rather than a diff against a
history this repo does not have. __version__ and CITATION.cff follow.

Hardcoded versions elsewhere were stale too, each fixed and each now
covered by the check below: the README status badge said "v0.3.x", the
getting-started sample output printed da-cli 0.3.0, the bug-report
template's placeholder was 0.3.0, and AGENTS.md referenced upgrading
"from v0.2.x" — an upgrade path that has never existed.

ENFORCING "PYPI AND THE TAG ALWAYS AGREE"

The chain is single-source already:

dacli/constants.py  __version__
  -> pyproject.toml   version = { attr = "dacli.__version__" }
    -> the wheel and sdist
      -> what PyPI shows
and at release time, the tag `v{__version__}`

but it is only as strong as its hand-maintained links, and there are
four: CITATION.cff carries a literal, the CHANGELOG needs a matching
section, docs/reference/cli.md embeds the version (generated, but the
generated file is committed and can be stale), and prose quotes it in
sample output. All four had drifted at some point.

tools/check_version_sync.py asserts every one of them, and additionally
scans tracked files for prose quoting a different da-cli version. It
runs in the lint job on every push, and the release workflow runs the
same script with --tag "$GITHUB_REF_NAME" before it builds anything —
one definition of "in sync" rather than two that can drift apart.

The tag check is the one that actually matters: without it you can push a
tag whose wheel reports a different version, and PyPI will not let you
re-upload a filename to correct it. The release workflow's previous
inline shell guard is replaced by this, so there is now a single
implementation.

Verified by breaking it four ways and confirming each is caught:

tag 'v0.9.9' does not match dacli.version (expected 'v0.1.0')
CITATION.cff version is '9.9.9', expected '0.1.0'
CHANGELOG.md has no '## 0.1.0' section
docs/reference/cli.md says version 0.3.0; run tools/gen_cli_docs.py

It also refuses to pass when run outside a git work tree, rather than
scanning nothing and reporting success — the same failure mode the
discoverability checker had, and the reason that one now fails loudly too.

Cassette fixtures still record da-cli/0.3.0 in their captured
User-Agent and are deliberately exempt: they are a record of a request as
it was actually made, and the replay matcher keys on method, scheme,
host, path and query — not headers. Confirmed by running them.

SECURITY.md's supported-versions table said "latest main / older tags",
which meant nothing with no tags. It now states plainly that fixes land
on main and ship in the next release, and that there is no backport
branch — a promise this project cannot keep is worse than an honest no.

This repository is a fresh public start with no prior releases. The
CHANGELOG carried 0.1.0, 0.2.0 and 0.3.0 sections describing development
that happened elsewhere, complete with release dates, while `git tag` was
empty and nothing had ever been published. Anyone reading it would
reasonably conclude three releases existed and go looking for them.

So: the retrospective sections are gone and the versioned history starts
at **0.1.0**, describing what the tool is rather than a diff against a
history this repo does not have. `__version__` and CITATION.cff follow.

Hardcoded versions elsewhere were stale too, each fixed and each now
covered by the check below: the README status badge said "v0.3.x", the
getting-started sample output printed `da-cli 0.3.0`, the bug-report
template's placeholder was `0.3.0`, and AGENTS.md referenced upgrading
"from v0.2.x" — an upgrade path that has never existed.

ENFORCING "PYPI AND THE TAG ALWAYS AGREE"

The chain is single-source already:

    dacli/constants.py  __version__
      -> pyproject.toml   version = { attr = "dacli.__version__" }
        -> the wheel and sdist
          -> what PyPI shows
    and at release time, the tag `v{__version__}`

but it is only as strong as its hand-maintained links, and there are
four: CITATION.cff carries a literal, the CHANGELOG needs a matching
section, docs/reference/cli.md embeds the version (generated, but the
generated file is committed and can be stale), and prose quotes it in
sample output. All four had drifted at some point.

`tools/check_version_sync.py` asserts every one of them, and additionally
scans tracked files for prose quoting a *different* da-cli version. It
runs in the `lint` job on every push, and the release workflow runs the
same script with `--tag "$GITHUB_REF_NAME"` before it builds anything —
one definition of "in sync" rather than two that can drift apart.

The tag check is the one that actually matters: without it you can push a
tag whose wheel reports a different version, and PyPI will not let you
re-upload a filename to correct it. The release workflow's previous
inline shell guard is replaced by this, so there is now a single
implementation.

Verified by breaking it four ways and confirming each is caught:

  tag 'v0.9.9' does not match dacli.__version__ (expected 'v0.1.0')
  CITATION.cff version is '9.9.9', expected '0.1.0'
  CHANGELOG.md has no '## 0.1.0' section
  docs/reference/cli.md says version 0.3.0; run tools/gen_cli_docs.py

It also refuses to pass when run outside a git work tree, rather than
scanning nothing and reporting success — the same failure mode the
discoverability checker had, and the reason that one now fails loudly too.

Cassette fixtures still record `da-cli/0.3.0` in their captured
User-Agent and are deliberately exempt: they are a record of a request as
it was actually made, and the replay matcher keys on method, scheme,
host, path and query — not headers. Confirmed by running them.

SECURITY.md's supported-versions table said "latest main / older tags",
which meant nothing with no tags. It now states plainly that fixes land
on main and ship in the next release, and that there is no backport
branch — a promise this project cannot keep is worse than an honest no.
@FZ2000
FZ2000 merged commit 284591b into main Jul 31, 2026
24 checks passed
@FZ2000
FZ2000 deleted the release/v0.1.0 branch July 31, 2026 05:12
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