Skip to content

Commit 00a4a3b

Browse files
committed
Add extra validation for hotfix releases
1 parent ffcaf31 commit 00a4a3b

File tree

2 files changed

+56
-23
lines changed

2 files changed

+56
-23
lines changed

.github/workflows/prepare-release.yml

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ on:
1111
description: |
1212
The git commit, branch, or tag to release from.
1313
required: true
14+
hotfix:
15+
description: |
16+
Whether this is a hotfix release.
17+
required: false
18+
default: false
1419

1520
permissions:
1621
contents: write
@@ -20,6 +25,7 @@ permissions:
2025

2126
env:
2227
RELEASE_VERSION: ${{ inputs.version }}
28+
HOTFIX_RELEASE: ${{ inputs.hotfix }}
2329

2430
jobs:
2531
prepare-release:
@@ -34,6 +40,18 @@ jobs:
3440
with:
3541
ref: ${{ inputs.ref }}
3642

43+
- name: Install Python
44+
uses: actions/setup-python@v4
45+
with:
46+
python-version: "3.9"
47+
48+
- name: Install release script dependencies
49+
run: pip install -r scripts/release/requirements.txt
50+
51+
- name: Validate version
52+
run: |
53+
python scripts/release/validate-version.py "$RELEASE_VERSION"
54+
3755
- name: Validate release precondition
3856
env:
3957
RELEASE_VERSION: ${{ inputs.version }}
@@ -84,18 +102,6 @@ jobs:
84102
git config user.name "$GITHUB_ACTOR"
85103
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
86104
87-
- name: Install Python
88-
uses: actions/setup-python@v4
89-
with:
90-
python-version: "3.9"
91-
92-
- name: Install release script dependencies
93-
run: pip install -r scripts/release/requirements.txt
94-
95-
- name: Validate version
96-
run: |
97-
python scripts/release/validate-version.py "$RELEASE_VERSION"
98-
99105
- name: Create release branch
100106
run: |
101107
git switch -c rc/$RELEASE_VERSION

scripts/release/validate-version.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,47 @@
11
import semantic_version # type: ignore
2-
from typing import Literal
2+
from typing import Literal, TYPE_CHECKING
3+
from subprocess import run
34

4-
def main(args : list[str]) -> Literal[1, 0]:
5-
if len(args) != 2:
6-
print("Error: incorrect number of arguments", file=sys.stderr)
7-
print(f"Usage: {args[0]} <version>", file=sys.stderr)
8-
return 1
5+
if TYPE_CHECKING:
6+
from argparse import Namespace
7+
8+
def get_release_version_of_ref() -> semantic_version.Version:
9+
cp = run(["git", "rev-parse", "--abbrev-ref", "HEAD"], capture_output=True, text=True)
10+
if cp.returncode != 0:
11+
raise RuntimeError("Failed to get current branch name")
12+
branch_name = cp.stdout.strip()
13+
ns, version_str = branch_name.split("/")
14+
if ns != "rc":
15+
raise RuntimeError("Not on a release branch!")
16+
17+
try:
18+
return semantic_version.Version(version_str) # type: ignore
19+
except ValueError as e:
20+
raise RuntimeError(f"Invalid version string: {e}")
921

22+
def main(args :'Namespace') -> Literal[1, 0]:
1023
try:
11-
semantic_version.Version.parse(args[1]) # type: ignore
24+
release_version = semantic_version.Version(args.version) # type: ignore
25+
if args.hotfix:
26+
branch_release_version = get_release_version_of_ref()
27+
expected_version = branch_release_version.next_patch()
28+
if release_version != expected_version:
29+
print(f"Error: Hotfix version `{release_version}` does not iterate on {branch_release_version}. Expected `{expected_version}`. ", file=stderr)
30+
return 1
1231
return 0
1332
except ValueError as e:
14-
print(f"Error: invalid version: {e}", file=sys.stderr)
33+
print(f"Error: invalid version: {e}", file=stderr)
34+
return 1
35+
except RuntimeError as e:
36+
print(f"Error: {e}", file=stderr)
1537
return 1
16-
1738

1839
if __name__ == '__main__':
19-
import sys
20-
sys.exit(main(sys.argv))
40+
from sys import stderr, exit
41+
import argparse
42+
43+
parser = argparse.ArgumentParser(description="Validate a version string")
44+
parser.add_argument("version", help="The version string to validate")
45+
parser.add_argument('--hotfix', action='store_true', help="Whether the release is to hotfix an existing release.")
46+
47+
exit(main(parser.parse_args()))

0 commit comments

Comments
 (0)