Skip to content

Commit 72c3420

Browse files
Add pre-release workflow
1 parent d4a83d3 commit 72c3420

File tree

2 files changed

+152
-3
lines changed

2 files changed

+152
-3
lines changed

.github/workflows/prerelease.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Pre-release Python Package
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version_type:
7+
description: "Version type to increment"
8+
required: true
9+
type: choice
10+
options:
11+
- patch
12+
- minor
13+
- major
14+
default: "patch"
15+
prerelease_type:
16+
description: "Pre-release type"
17+
required: true
18+
type: choice
19+
options:
20+
- rc
21+
- alpha
22+
- beta
23+
default: "rc"
24+
25+
jobs:
26+
deploy:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
- name: Set up Python
32+
uses: actions/setup-python@v5
33+
with:
34+
python-version: "3.11"
35+
36+
- name: Install Poetry
37+
uses: abatilo/actions-poetry@v3
38+
39+
- name: Install dependencies
40+
run: poetry install --extras "batch-engine"
41+
42+
- name: Run tests
43+
run: poetry run pytest
44+
45+
- name: Get current version
46+
id: version
47+
run: |
48+
CURRENT_VERSION=$(poetry version -s)
49+
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
50+
51+
- name: Calculate new version
52+
id: new_version
53+
run: |
54+
CURRENT_VERSION=${{ steps.version.outputs.current_version }}
55+
VERSION_TYPE=${{ github.event.inputs.version_type }}
56+
PRERELEASE_TYPE=${{ github.event.inputs.prerelease_type }}
57+
NEW_VERSION=$(poetry run python scripts/version.py "$CURRENT_VERSION" "$VERSION_TYPE" "$PRERELEASE_TYPE")
58+
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
59+
60+
- name: Update version
61+
run: |
62+
poetry version ${{ steps.new_version.outputs.new_version }}
63+
64+
- name: Create and push tag
65+
run: |
66+
git config --local user.email "action@github.com"
67+
git config --local user.name "GitHub Action"
68+
git add pyproject.toml
69+
git commit -m "chore: pre-release v${{ steps.new_version.outputs.new_version }}"
70+
git tag -a "v${{ steps.new_version.outputs.new_version }}" -m "Pre-release v${{ steps.new_version.outputs.new_version }}"
71+
git push origin HEAD:${{ github.ref_name }}
72+
git push origin "v${{ steps.new_version.outputs.new_version }}"
73+
74+
- name: Build package
75+
run: poetry build
76+
77+
- name: Publish to PyPI
78+
env:
79+
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
80+
run: poetry publish --username __token__ --password $PYPI_API_TOKEN

scripts/version.py

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Literal
55

66
VersionType = Literal["patch", "minor", "major"]
7+
PrereleaseType = Literal["rc", "alpha", "beta"]
78

89

910
def bump_version(current_version: str, version_type: VersionType) -> str:
@@ -31,21 +32,89 @@ def bump_version(current_version: str, version_type: VersionType) -> str:
3132
return str(new_version)
3233

3334

35+
def bump_prerelease(
36+
current_version: str,
37+
prerelease_type: PrereleaseType,
38+
version_bump: VersionType = "patch",
39+
) -> str:
40+
"""
41+
Bump to a pre-release version.
42+
43+
If current version is stable (e.g., "1.2.3"), bumps to next version with pre-release.
44+
If current version is already a pre-release, increments the pre-release number.
45+
46+
Args:
47+
current_version: Current version string (e.g., "1.2.3" or "1.2.4-rc1")
48+
prerelease_type: Type of pre-release ("rc", "alpha", "beta")
49+
version_bump: Version component to bump if starting from stable ("patch", "minor", "major")
50+
51+
Returns:
52+
New pre-release version string (format: X.Y.Z-rc1)
53+
"""
54+
version = semver.VersionInfo.parse(current_version)
55+
56+
# If already a pre-release, increment it
57+
if version.prerelease:
58+
# Parse existing prerelease to increment number
59+
import re
60+
61+
match = re.match(r"([a-z]+)(\d+)", version.prerelease)
62+
if match:
63+
prefix, num = match.groups()
64+
new_prerelease = f"{prefix}{int(num) + 1}"
65+
else:
66+
raise ValueError("Invalid pre-release format")
67+
68+
new_version = version.replace(prerelease=new_prerelease)
69+
else:
70+
# Bump to next version with pre-release identifier
71+
if version_bump == "patch":
72+
new_version = version.bump_patch()
73+
elif version_bump == "minor":
74+
new_version = version.bump_minor()
75+
elif version_bump == "major":
76+
new_version = version.bump_major()
77+
else:
78+
raise ValueError(f"Invalid version type: {version_bump}")
79+
80+
# Add pre-release identifier
81+
new_version = new_version.replace(prerelease=f"{prerelease_type}1")
82+
83+
return str(new_version)
84+
85+
3486
def main():
35-
if len(sys.argv) != 3:
36-
print("Usage: python version.py <current_version> <version_type>")
87+
if len(sys.argv) < 3:
88+
print(
89+
"Usage: python version.py <current_version> <version_type> [prerelease_type]"
90+
)
91+
print(" version_type: patch, minor, major")
92+
print(" prerelease_type (optional): rc, alpha, beta")
3793
sys.exit(1)
3894

3995
current_version = sys.argv[1]
4096
version_type_str = sys.argv[2]
97+
prerelease_type_str = sys.argv[3] if len(sys.argv) > 3 else None
4198

4299
try:
43100
if version_type_str not in ("patch", "minor", "major"):
44101
raise ValueError(
45102
f"Invalid version type: {version_type_str}. Must be one of: patch, minor, major"
46103
)
47104
version_type: VersionType = version_type_str # type: ignore
48-
new_version = bump_version(current_version, version_type)
105+
106+
if prerelease_type_str:
107+
if prerelease_type_str not in ("rc", "alpha", "beta"):
108+
raise ValueError(
109+
f"Invalid prerelease type: {prerelease_type_str}. Must be one of: rc, alpha, beta"
110+
)
111+
prerelease_type: PrereleaseType = prerelease_type_str # type: ignore
112+
new_version = bump_prerelease(
113+
current_version, prerelease_type, version_type
114+
)
115+
else:
116+
new_version = bump_version(current_version, version_type)
117+
49118
print(new_version)
50119
except Exception as e:
51120
print(f"Error: {e}", file=sys.stderr)

0 commit comments

Comments
 (0)