Skip to content

fix: keep autocomplete artifact version stamp correct at tag time - #25

Merged
lhotovy merged 1 commit into
mainfrom
fix/tag-version-stamp-hygiene
Jul 16, 2026
Merged

fix: keep autocomplete artifact version stamp correct at tag time#25
lhotovy merged 1 commit into
mainfrom
fix/tag-version-stamp-hygiene

Conversation

@gtchax

@gtchax gtchax commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Fixes #24.

Problem

artifacts/autocomplete-types.ts is committed so consumers can fetch it at a tagged ref, but it was only ever corrected by a follow-up push to main. The v0.8.0 tag was cut at the bump commit (ada2251), and the regeneration commit (ea13b0d) landed after it:

ea13b0d  🤖 Auto-generate autocomplete types [skip ci]   <-- main only, stamped 0.8.0
ada2251  Bump version to 0.8.0                           <-- v0.8.0 tag, stamped 0.7.0

Tags are immutable, so that fixup can never reach v0.8.0 — it ships the 0.8.0 method set labelled SDK_VERSION = "0.7.0". This is what blocked pinning the runtime fetch to a tag in automators-com/loop#2825.

It's a race rather than a systematic off-by-one: v0.7.0 happens to be self-consistent. It breaks whenever the bump and the regeneration land in separate commits with the tag cut between them, which means a future release could come out clean by luck and mask the bug.

Fix

Make the stamp correct at tag time instead of repairing it afterwards.

  • --check in the generator — regenerates in memory, diffs against the committed file, exits 1 with the diff if stale. One source of truth for both guards below.
  • PR verify job (generate-autocomplete.yml) — a bump that forgets to regenerate now fails review, forcing the artifact into the same commit the tag will point at.
  • Release guard (python-publish.yml) — verifies before building. It runs in release-build, which pypi-publish needs, so a mislabeled artifact can never reach PyPI.
  • Dropped the release: published trigger from the generate job — it regenerated from a detached tag checkout and pushed to the branch, so it could never move the tag it was meant to fix.

Also fixed get_version() to resolve pyproject.toml against the repo root rather than CWD; it would silently stamp unknown when run from elsewhere, and --check now hard-fails on that instead.

0.8.1

Bumped to publish a correctly stamped tag, since v0.8.0 can't be corrected in place. The method set is unchanged from 0.8.0 — 89 methods both sides; the entire artifact diff is the two stamp lines:

-// Generated from version 0.8.0      +// Generated from version 0.8.1
-export const SDK_VERSION = "0.8.0";  +export const SDK_VERSION = "0.8.1";

Verification

  • --check exits 1 on a simulated stale artifact (bumped pyproject, un-regenerated file) and prints the offending diff; exits 0 on a clean tree.
  • Generator is byte-for-byte reproducible against the committed artifact, so the guard won't produce false failures.
  • 68 unit tests pass.

Leaves open whether to retag/yank 0.8.0 — it's a published release, so that's a judgement call rather than something to fold into this PR.

🤖 Generated with Claude Code

artifacts/autocomplete-types.ts is committed so consumers can fetch it at a
tagged ref, but it was only ever corrected by a follow-up push to main. The
v0.8.0 tag was cut at the version-bump commit and the regenerated artifact
landed after it, so that tag permanently carries the 0.8.0 method set stamped
0.7.0. Tags are immutable, so the fixup can never reach it.

Add --check to the generator (regenerate in memory, diff against the committed
file, exit 1 with the diff if stale) and wire it in two places:

- generate-autocomplete.yml gains a verify job on PRs, so a bump that forgets
  to regenerate fails review instead of being repaired after tagging.
- python-publish.yml verifies before building, so a mislabeled artifact can
  never be published. It runs in release-build, which pypi-publish needs.

Also drop the release:published trigger from the generate job. It regenerated
from a detached tag checkout and pushed to the branch, which could never move
the tag it was meant to fix.

Bump to 0.8.1 to publish a correctly stamped tag; the method set is unchanged
from 0.8.0 (89 methods), only the version stamp differs.

Fixes #24

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gtchax

gtchax commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up once this merges: tag v0.8.1 at the merge commit — bare tag only, no GitHub release.

Deliberately not cutting a release: the release: published event triggers python-publish.yml → PyPI, and 0.8.1 carries zero functional change from 0.8.0 (89 methods, byte-identical apart from the two version-stamp lines). A PyPI publish would be a no-op release, and it's irreversible — PyPI won't allow re-uploading a version. A bare tag is all automators-com/loop#2825 needs, since it fetches artifacts/autocomplete-types.ts at a tagged ref.

Worth a reviewer's eye on two judgement calls in here:

  1. Dropping the release: published trigger from the generate job. It regenerated from a detached tag checkout and pushed to the branch — it could never move the tag it was meant to fix, so it was a no-op at best. Shout if it was load-bearing for something I've missed.
  2. v0.8.0 is left as-is — still published, still mislabeled. Retagging or yanking a released version felt like a call to make deliberately rather than fold into this PR. Fixing forward via 0.8.1 sidesteps it, but 0.8.0 stays a trap for anyone who pins to it.

@lhotovy
lhotovy merged commit 793e15a into main Jul 16, 2026
6 checks passed
AminChirazi added a commit that referenced this pull request Jul 28, 2026
Version 0.8.1 -> 0.9.0. A minor bump rather than a patch: this adds surface,
it does not fix anything.

Also completes the previous commit, which had a real gap. Every other resource
is reachable BOTH as `client.sets.get_sets()` and as `client.get_sets()`, but
plans and masking policies were only wired as properties. Two consequences:
they read differently from every other resource, and - the part that actually
matters - `artifacts/autocomplete-types.ts` is generated from the facade, so
they were invisible to the editor autocomplete that ships to users. The
artifact went from 89 methods to 98 once the facade methods existed.

The artifact is regenerated here rather than left to a follow-up push, which
is the hygiene #25 established: it is committed so consumers can fetch it at a
tagged ref, and a tag cut at the bump commit permanently carries whatever
artifact was in the tree at that moment.

69 tests pass, 24 skipped. `ruff check --select F,E9` reports 7 findings across
the package, identical to the count on main - all pre-existing, none from this
change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

[Bug] v0.8.0 tag ships autocomplete-types.ts stamped 0.7.0

2 participants