Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions scripts/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
VERSION_PATTERN = re.compile(r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$")
CARGO_VERSION_PATTERN = re.compile(r'(?m)^version = "([^"]+)"$')
README_PINNED_VERSION_PATTERN = re.compile(r"WTK_VERSION=\d+\.\d+\.\d+")
README_PINNED_ASSIGNMENT_PATTERN = re.compile(r"WTK_VERSION=\S+")
SEMANTIC_BUMP_CHOICES = ("major", "minor", "patch")


Expand Down Expand Up @@ -160,12 +161,25 @@ def update_version_files(target: Version) -> None:

readme = repo_root() / "README.md"
readme_text = readme.read_text()
readme_text, readme_count = README_PINNED_VERSION_PATTERN.subn(f"WTK_VERSION={target}", readme_text, count=1)
if readme_count != 1:
fail("failed to update README pinned install example")
readme_text = update_readme_pinned_install_versions(readme_text, target)
readme.write_text(readme_text)


def update_readme_pinned_install_versions(readme_text: str, target: Version) -> str:
pinned_assignments = README_PINNED_ASSIGNMENT_PATTERN.findall(readme_text)
if not pinned_assignments:
return readme_text

malformed = [assignment for assignment in pinned_assignments if not README_PINNED_VERSION_PATTERN.fullmatch(assignment)]
if malformed:
fail(f"README pinned install example is malformed: {malformed[0]}")

readme_text, readme_count = README_PINNED_VERSION_PATTERN.subn(f"WTK_VERSION={target}", readme_text)
if readme_count != len(pinned_assignments):
fail("failed to update README pinned install example")
return readme_text


def ensure_release_label() -> None:
labels_json = run(["gh", "label", "list", "--limit", "200", "--json", "name"], capture=True)
labels = json.loads(labels_json)
Expand Down
40 changes: 40 additions & 0 deletions tests/test_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,46 @@ def test_bumps_patch_from_cargo_version(self) -> None:
self.assertEqual(release.resolve_target_version("patch"), release.Version(1, 2, 4))


class UpdateReadmePinnedInstallVersionsTests(unittest.TestCase):
def test_leaves_readme_without_pinned_install_example_unchanged(self) -> None:
readme = """## Install

```bash
curl -fsSL https://raw.githubusercontent.com/nettee/worktree-kit/main/scripts/install.sh | sh
```
"""

self.assertEqual(
release.update_readme_pinned_install_versions(readme, release.Version(1, 2, 3)),
readme,
)

def test_updates_all_pinned_install_examples(self) -> None:
readme = """Install latest:
```bash
curl -fsSL https://example.test/install.sh | sh
```

Install pinned:
```bash
curl -fsSL https://example.test/install.sh | WTK_VERSION=0.1.0 sh
WTK_VERSION=0.1.0 sh scripts/install.sh
```
"""

self.assertEqual(
release.update_readme_pinned_install_versions(readme, release.Version(1, 2, 3)),
readme.replace("WTK_VERSION=0.1.0", "WTK_VERSION=1.2.3"),
)

def test_fails_on_malformed_pinned_install_example(self) -> None:
with mock.patch("sys.stderr"), self.assertRaises(SystemExit):
release.update_readme_pinned_install_versions(
"curl -fsSL https://example.test/install.sh | WTK_VERSION=latest sh\n",
release.Version(1, 2, 3),
)


class PrepareReleaseTests(unittest.TestCase):
def test_resolves_semantic_bump_after_syncing_base_branch(self) -> None:
events: list[str] = []
Expand Down
Loading