Skip to content

Commit ede5178

Browse files
committed
fix tag
1 parent e58dfb4 commit ede5178

3 files changed

Lines changed: 34 additions & 66 deletions

File tree

‎copier_template_resources/git_tag.py‎

Lines changed: 24 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -7,71 +7,42 @@
77
# =====================================================================================================
88
import argparse
99
import subprocess
10-
import tomllib
11-
from pathlib import Path
12-
13-
14-
def extract_version(toml_path: Path | str) -> str:
15-
"""Load toml_path and return the version string.
16-
17-
Checks [project].version (PEP 621) first, then [tool.poetry].version. Raises KeyError if no version field is found.
18-
"""
19-
path = Path(toml_path)
20-
with path.open("rb") as f:
21-
data = tomllib.load(f)
22-
23-
project = data.get("project", {})
24-
if version := project.get("version"):
25-
return version
26-
27-
tool = data.get("tool", {})
28-
poetry = tool.get("poetry", {})
29-
if version := poetry.get("version"):
30-
return version
31-
32-
raise KeyError(f"No version field found in {path!r}")
3310

3411

3512
def ensure_tag_not_present(tag: str, remote: str) -> None:
36-
try:
37-
_ = subprocess.run( # noqa: S603 # this is trusted input, it's our own arguments being passed in
38-
["git", "ls-remote", "--exit-code", "--tags", remote, f"refs/tags/{tag}"], # noqa: S607 # if `git` isn't in PATH already, then there are bigger problems to solve
39-
check=True,
40-
stdout=subprocess.DEVNULL,
41-
stderr=subprocess.DEVNULL,
42-
)
13+
no_matching_refs_return_code = 2
14+
result = subprocess.run( # noqa: S603 # this is trusted input, it's our own arguments being passed in
15+
["git", "ls-remote", "--exit-code", "--tags", remote, f"refs/tags/{tag}"], # noqa: S607 # if `git` isn't in PATH already, then there are bigger problems to solve
16+
stdout=subprocess.DEVNULL,
17+
check=False,
18+
)
19+
if result.returncode == 0:
4320
raise Exception(f"Error: tag '{tag}' exists on remote '{remote}'") # noqa: TRY002 # not worth a custom exception
44-
except subprocess.CalledProcessError:
45-
# tag not present, continue
46-
return
21+
if (
22+
result.returncode != no_matching_refs_return_code
23+
): # anything else is a real error (bad remote, auth failure, network)
24+
raise Exception(f"git ls-remote exited with code {result.returncode} (remote={remote!r})") # noqa: TRY002 # not worth a custom exception
4725

4826

49-
def main():
27+
def main() -> None:
5028
parser = argparse.ArgumentParser(
51-
description=(
52-
"Extract the version from a pyproject.toml file, "
53-
"confirm that git tag v<version> is not present, or "
54-
"create and push the tag to a remote."
55-
)
29+
description=("Confirm that git tag v<version> is not present on a remote, or create and push the tag.")
5630
)
5731
_ = parser.add_argument(
58-
"file",
59-
nargs="?",
60-
default="pyproject.toml",
61-
help="Path to pyproject.toml (default: pyproject.toml)",
32+
"--version",
33+
required=True,
34+
help="Version string (e.g. 1.0.6 or v1.0.6); the tag will always be v<version>",
6235
)
63-
_ = parser.add_argument(
36+
mode = parser.add_mutually_exclusive_group(required=True)
37+
_ = mode.add_argument(
6438
"--confirm-tag-not-present",
6539
action="store_true",
66-
help=("Check that git tag v<version> is NOT present on the remote. If the tag exists, exit with an error."),
40+
help="Check that git tag v<version> is NOT present on the remote. If the tag exists, exit with an error.",
6741
)
68-
_ = parser.add_argument(
42+
_ = mode.add_argument(
6943
"--push-tag-to-remote",
7044
action="store_true",
71-
help=(
72-
"Create git tag v<version> locally and push it to the remote. "
73-
"Internally confirms the tag is not already present."
74-
),
45+
help="Create git tag v<version> locally and push it to the remote. Internally confirms the tag is not already present.",
7546
)
7647
_ = parser.add_argument(
7748
"--remote",
@@ -80,22 +51,16 @@ def main():
8051
)
8152
args = parser.parse_args()
8253

83-
ver = extract_version(args.file)
84-
85-
tag = f"v{ver}"
54+
tag = args.version if args.version.startswith("v") else f"v{args.version}"
8655

8756
if args.push_tag_to_remote:
8857
ensure_tag_not_present(tag, args.remote)
89-
_ = subprocess.run(["git", "tag", tag], check=True) # noqa: S603,S607 # this is trusted input, it's our own pyproject.toml file. and if `git` isn't in PATH, then there are larger problems anyway
90-
_ = subprocess.run(["git", "push", args.remote, tag], check=True) # noqa: S603,S607 # this is trusted input, it's our own pyproject.toml file. and if `git` isn't in PATH, then there are larger problems anyway
58+
_ = subprocess.run(["git", "tag", tag], check=True) # noqa: S603,S607 # this is trusted input, it's our own version string. and if `git` isn't in PATH, then there are larger problems anyway
59+
_ = subprocess.run(["git", "push", args.remote, tag], check=True) # noqa: S603,S607 # this is trusted input, it's our own version string. and if `git` isn't in PATH, then there are larger problems anyway
9160
return
9261

9362
if args.confirm_tag_not_present:
9463
ensure_tag_not_present(tag, args.remote)
95-
return
96-
97-
# Default behavior: just print the version
98-
print(ver) # noqa: T201 # specifically printing this out so CI pipelines can read the value from stdout
9964

10065

10166
if __name__ == "__main__":

‎template/.github/workflows/{% if not is_frozen_executable %}publish.yaml{% endif %}.jinja‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
- name: Extract package version
3434
id: extract-package-version
3535
run: |
36-
VERSION=$(python3 ./.github/workflows/git_tag.py)
36+
VERSION=$(python3 ./.github/workflows/extract_project_version.py pyproject.toml)
3737
echo "Extracted version: $VERSION"
3838
echo "package_version=$VERSION" >> $GITHUB_OUTPUT
3939

@@ -249,7 +249,9 @@ jobs:
249249
name: Create the git tag
250250
if: ${{ fromJSON(github.event.inputs.publish_to_primary) }}
251251
timeout-minutes: {% endraw %}{{ gha_medium_timeout_minutes }}{% raw %}
252-
needs: [ install-from-staging ]
252+
needs:
253+
- install-from-staging
254+
- get-values
253255
permissions:
254256
contents: write # needed to push the tag
255257
runs-on: {% endraw %}{{ gha_linux_runner }}{% raw %}
@@ -261,9 +263,9 @@ jobs:
261263
with:
262264
python-version: {% endraw %}{{ python_version }}{% raw %}
263265
- name: Confirm tag not already present
264-
run: python3 ./.github/workflows/git_tag.py --confirm-tag-not-present
266+
run: python3 ./.github/workflows/git_tag.py --version "${{ needs.get-values.outputs.package-version }}" --confirm-tag-not-present
265267
- name: Create tag
266-
run: python3 ./.github/workflows/git_tag.py --push-tag-to-remote
268+
run: python3 ./.github/workflows/git_tag.py --version "${{ needs.get-values.outputs.package-version }}" --push-tag-to-remote
267269

268270
publish-to-primary:
269271
name: Publish Python distribution to Primary Package Registry

‎template/.github/workflows/{% if not is_frozen_executable %}release.yaml{% endif %}.jinja‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ jobs:
8080
echo "version=$VERSION" >> $GITHUB_OUTPUT
8181
- name: Check version tag does not already exist
8282
run: |
83-
if python3 .github/workflows/git_tag.py --confirm-tag-not-present; then
83+
if python3 .github/workflows/git_tag.py --version "${{ steps.get-version.outputs.version }}" --confirm-tag-not-present; then
8484
echo "Tag v${{ steps.get-version.outputs.version }} does not exist yet."
8585
else
8686
if [ "${{ inputs.dry_run }}" = "true" ]; then
@@ -227,6 +227,7 @@ jobs:
227227
timeout-minutes: {% endraw %}{{ gha_medium_timeout_minutes }}{% raw %}
228228
needs:
229229
- install-from-staging
230+
- guard
230231
permissions:
231232
contents: write # needed to push the tag
232233
runs-on: {% endraw %}{{ gha_linux_runner }}{% raw %}
@@ -238,9 +239,9 @@ jobs:
238239
with:
239240
python-version: {% endraw %}{{ python_version }}{% raw %}
240241
- name: Confirm tag not already present
241-
run: python3 ./.github/workflows/git_tag.py --confirm-tag-not-present
242+
run: python3 ./.github/workflows/git_tag.py --version "${{ needs.guard.outputs.version }}" --confirm-tag-not-present
242243
- name: Create tag
243-
run: python3 ./.github/workflows/git_tag.py --push-tag-to-remote
244+
run: python3 ./.github/workflows/git_tag.py --version "${{ needs.guard.outputs.version }}" --push-tag-to-remote
244245

245246
publish-to-primary:
246247
name: Publish Python distribution to Primary Package Registry

0 commit comments

Comments
 (0)