diff --git a/.github/workflows/prepare-towncrier-release.yaml b/.github/workflows/prepare-towncrier-release.yaml index f81ed50..471fb11 100644 --- a/.github/workflows/prepare-towncrier-release.yaml +++ b/.github/workflows/prepare-towncrier-release.yaml @@ -77,6 +77,12 @@ jobs: - name: Install local release tool wheel if: inputs.local-tool-source run: uv pip install --python .venv/bin/python --no-deps "$RUNNER_TEMP/local-tool-dist/"*.whl + - name: Expose local release command + if: inputs.local-tool-source + run: | + mkdir -p "$RUNNER_TEMP/local-release-cli" + ln -s "$GITHUB_WORKSPACE/.venv/bin/release-creator" "$RUNNER_TEMP/local-release-cli/release-creator" + echo "$RUNNER_TEMP/local-release-cli" >>"$GITHUB_PATH" - id: prepare name: Build changelog uses: $/prepare-towncrier diff --git a/changelog.d/+local-release-command.bugfix.md b/changelog.d/+local-release-command.bugfix.md new file mode 100644 index 0000000..7051551 --- /dev/null +++ b/changelog.d/+local-release-command.bugfix.md @@ -0,0 +1 @@ +Expose the locally built release-creator command before it prepares its own changelog. diff --git a/tests/release_workflow/test_graph.py b/tests/release_workflow/test_graph.py index eba31b8..a8b7b01 100644 --- a/tests/release_workflow/test_graph.py +++ b/tests/release_workflow/test_graph.py @@ -3,6 +3,7 @@ import os import shutil import subprocess +import sys from pathlib import Path import yaml @@ -66,6 +67,41 @@ def test_prepare_builds_local_tool_once_with_locked_backends() -> None: ) +def test_prepare_exposes_local_command_without_shadowing_python(tmp_path: Path) -> None: + workflow = yaml.safe_load( + (Path(__file__).resolve().parents[2] / ".github/workflows/prepare-towncrier-release.yaml").read_text() + ) + steps = workflow["jobs"]["assemble"]["steps"] + expose = next(step for step in steps if step.get("name") == "Expose local release command") + assert expose["if"] == "inputs.local-tool-source" + assert steps.index(expose) > next( + index for index, step in enumerate(steps) if step.get("name") == "Install local release tool wheel" + ) + assert steps.index(expose) < next(index for index, step in enumerate(steps) if step.get("id") == "prepare") + command = tmp_path / ".venv/bin/release-creator" + command.parent.mkdir(parents=True) + command.symlink_to(sys.executable) + output = tmp_path / "github-path" + + result = subprocess.run( + ["bash", "-e", "-o", "pipefail", "-c", expose["run"]], + cwd=tmp_path, + env={**os.environ, "GITHUB_WORKSPACE": str(tmp_path), "RUNNER_TEMP": str(tmp_path), "GITHUB_PATH": str(output)}, + capture_output=True, + text=True, + check=False, + ) + + assert result.returncode == 0, result.stderr + overlay = Path(output.read_text().strip()) + assert (overlay / "release-creator").resolve() == command.resolve() + assert not (overlay / "python").exists() + assert ( + subprocess.run([str(overlay / "release-creator"), "--version"], check=False, capture_output=True).returncode + == 0 + ) + + def test_prepare_installs_hooks_while_building_changelog() -> None: workflow = yaml.safe_load( (Path(__file__).resolve().parents[2] / ".github/workflows/prepare-towncrier-release.yaml").read_text()