Skip to content

0.2.0 — HTTP stack on httpware; Python 3.10 dropped

Choose a tag to compare

@lesnik512 lesnik512 released this 08 Jun 08:13
· 72 commits to main since this release
21cf4d0

Breaking release. The provider HTTP stack is rebuilt on top of httpware 0.8.2 — a maintained sibling client framework — replacing the in-tree RetryingTransport + HttpClient plumbing that shipped in 0.1.x. Operator-visible behavior changes are listed below. Python 3.10 is no longer supported.

If you pin semvertag in CI and use Python 3.11+ already, you can skip straight to "Behavior changes" — the rest is internal.

What's new

  • HTTP stack on httpware. GitLabProvider holds a httpware.Client directly. httpware.Retry middleware replaces the hand-rolled RetryingTransport. httpware.PydanticDecoder decodes response bodies via response_model= — no more in-tree validator plumbing.
  • Smaller surface. Net ~600 LOC of HTTP plumbing deleted across the two migrations. semvertag/_transport.py and semvertag/providers/_http.py are gone; their tests deleted too.
  • Uniform error contract. httpware.ClientError covers transport failures, status errors, AND decode failures uniformly. semvertag's error tree (ConfigError/2, AuthError/3, ProviderAPIError/4) is unchanged at the CLI boundary — exit codes are stable.
  • httpware[pydantic]>=0.8.2 is a new transitive dependency. End users who install semvertag from PyPI pick it up automatically.

Breaking changes

Python 3.10 dropped

requires-python = ">=3.11,<4". semvertag 0.1.x supported 3.10; 0.2.0 does not. The bump is forced by httpware's own floor.

Migration: upgrade your CI runners and local development environment to Python 3.11 or newer. If you cannot, stay on semvertag==0.1.1.

Behavior changes from the new retry middleware

The 0.1.x RetryingTransport is gone; httpware.Retry takes over. These are the user-observable differences in CI logs:

Knob 0.1.x 0.2.0
Retryable statuses 408, 429, 500, 502, 503, 504 same
Methods retried all (transport-level) idempotent only — POST not retried
Backoff base 1.0 s, full-jitter 0.1 s, full-jitter
Max sleep per attempt implicit via 30 s wall cap 5 s
Total-attempt wall cap 30 s per request none; httpware.RetryBudget (10 deposits + 20% retry ratio) caps storms across requests instead
Retry-After combine max(server_hint, local_backoff) server hint honored verbatim, capped at max sleep

Net effect for a typical CI run: faster transient-failure recovery (backoff starts 10× shorter), create_tag (POST) now fails immediately on a 429 instead of retrying — operator must rerun the job. All other surfaces unchanged.

Error message wording

Provider error messages produced by decoder failures (malformed JSON, schema mismatch) now read "GitLab _ProjectResponse response could not be decoded: <pydantic error>" instead of the 0.1.x "shape invalid: ..." / "malformed JSON in response body" wording. Only matters if you grep stderr for specific substrings. Exception types (ProviderAPIError) and exit codes (4) are unchanged.

Migration

For most users, the migration is one line in CI config:

-  python-version: "3.10"
+  python-version: "3.11"

If you grep stderr or test output for the old retry/decode error wording, update the strings. If you depend on create_tag POSTs being retried automatically on 429, add an outer retry loop in your CI script (e.g., gh workflow rerun on failure).

The semvertag CLI surface, exit codes, environment variables (SEMVERTAG_*), and the templates/semvertag.yml GitLab CI Catalog descriptor are all unchanged.

See also

Two design+implementation cycles fed this release: