diff --git a/CHANGELOG.md b/CHANGELOG.md index e03fcfd..8e55852 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.21.1] - 2026-09-05 + +### Fixed + +- **`linear --version` reported `0.20.0` on a 0.21.0 install.** `__version__` + is bumped in the feature commit, not the release commit, and 0.21.0 shipped + without that bump — so every 0.21.0 install ran the right code and + self-reported the previous version. That silently breaks any "is this box up + to date?" check, including a fleet-wide `linear --version` sweep. No behavior + change beyond the version string. + ## [0.21.0] - 2026-09-05 ### Changed diff --git a/README.md b/README.md index 20fe67b..cefce59 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,13 @@ Use the same shell contract whether you're typing or a subagent is: query the qu Preferred (pinned tag + SHA-256 verify via `install.sh`): ```bash -curl -sSL https://raw.githubusercontent.com/phnx-labs/linear-cli/v0.21.0/install.sh | sh +curl -sSL https://raw.githubusercontent.com/phnx-labs/linear-cli/v0.21.1/install.sh | sh ``` Manual pin (same tag; no checksum — prefer `install.sh` above): ```bash -curl -o ~/.local/bin/linear https://raw.githubusercontent.com/phnx-labs/linear-cli/v0.21.0/linear +curl -o ~/.local/bin/linear https://raw.githubusercontent.com/phnx-labs/linear-cli/v0.21.1/linear chmod +x ~/.local/bin/linear ``` diff --git a/install.sh b/install.sh index a9f58c6..cac244a 100755 --- a/install.sh +++ b/install.sh @@ -6,9 +6,9 @@ set -eu REPO="phnx-labs/linear-cli" # Pin a release tag (not floating main). Override with LINEAR_CLI_VERSION / # LINEAR_CLI_SHA256 only when you deliberately install a different revision. -VERSION="${LINEAR_CLI_VERSION:-v0.21.0}" +VERSION="${LINEAR_CLI_VERSION:-v0.21.1}" # SHA-256 of the `linear` file at VERSION. Recomputed whenever VERSION bumps. -EXPECTED_SHA256="${LINEAR_CLI_SHA256:-d68fe508cb19460d0f2a517062a7a66646525539a11caedaa4a15ae5b3717cbe}" +EXPECTED_SHA256="${LINEAR_CLI_SHA256:-4055001dcdef84f21b30760a1a1e922dd4d0d7b4b9c936d3a6e5c4c143e7b465}" URL="https://raw.githubusercontent.com/${REPO}/${VERSION}/linear" pick_install_dir() { diff --git a/linear b/linear index 09ad808..32db094 100755 --- a/linear +++ b/linear @@ -66,7 +66,7 @@ _LOCK_CONTENDED_ERRNOS = tuple( if e is not None ) -__version__ = "0.20.0" +__version__ = "0.21.1" # Sentinel for "flag not supplied" — distinct from None, which means an explicit # clear (e.g. `--project none`). Lets update pre-resolve a field once and pass diff --git a/test_linear.py b/test_linear.py index 480e707..06732e6 100644 --- a/test_linear.py +++ b/test_linear.py @@ -2,6 +2,12 @@ """Regression tests for the `linear` CLI. The CLI is intentionally dependency-free, so tests use only stdlib unittest. + +Seeing a stale value for something you just edited in `linear`? macOS's system +python3 sets a global sys.pycache_prefix, and because `linear` has no .py +extension the cached name loses its separator (`linearcpython-39.pyc`), so the +usual invalidation is easy to miss when an edit doesn't change the file length. +Re-run with PYTHONDONTWRITEBYTECODE=1 before believing the result. """ import contextlib @@ -10,6 +16,7 @@ import io import json import os +import re import sys import tempfile import types @@ -550,6 +557,26 @@ def test_bulk_error_survives_tabs_and_newlines_in_the_assign_value(self): self.assertIn("matched no human", err) +class VersionMatchesChangelogTest(unittest.TestCase): + """`__version__` lives in `linear` and is bumped in the feature commit, not + the release commit, so it is easy to forget — 0.21.0 shipped self-reporting + 0.20.0, which made a fleet-wide `linear --version` sweep call every box + stale when it was in fact up to date.""" + + def test_version_matches_newest_released_changelog_entry(self): + changelog = Path(_HERE, "CHANGELOG.md").read_text() + # Released headings look like "## [0.21.1] - 2026-09-05"; + # "## [Unreleased]" has no version and is skipped by the pattern. + versions = re.findall(r"^## \[(\d+\.\d+\.\d+)\]", changelog, re.MULTILINE) + self.assertTrue(versions, "no released version headings found in CHANGELOG.md") + self.assertEqual( + linear_cli.__version__, versions[0], + f"__version__ is {linear_cli.__version__!r} but the newest CHANGELOG " + f"entry is {versions[0]!r}. Bump __version__ in `linear` when you add " + f"the CHANGELOG entry, not at release time.", + ) + + class BulkTsvFieldTest(unittest.TestCase): """Bulk --from-file output is a tab-separated record. Titles come from the caller's JSONL and from Linear, so neither may carry a raw tab/newline."""