Skip to content

Commit 0a76e8d

Browse files
author
Sam
committed
Add GitHub workflows for automated and manual PyPI publishing; update user-agent test to use regex matcher
1 parent c50e873 commit 0a76e8d

3 files changed

Lines changed: 262 additions & 1 deletion

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
name: Manual Release to PyPI
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
bump_type:
7+
description: 'Version bump type'
8+
required: true
9+
default: 'patch'
10+
type: choice
11+
options:
12+
- patch
13+
- minor
14+
- major
15+
prerelease:
16+
description: 'Is this a pre-release?'
17+
required: false
18+
default: false
19+
type: boolean
20+
21+
permissions:
22+
contents: write
23+
24+
jobs:
25+
release:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- name: Checkout code
29+
uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 0
32+
token: ${{ secrets.GITHUB_TOKEN }}
33+
34+
- name: Set up Python
35+
uses: actions/setup-python@v5
36+
with:
37+
python-version: '3.11'
38+
39+
- name: Install dependencies
40+
run: |
41+
python -m pip install --upgrade pip
42+
pip install build twine
43+
pip install -e .
44+
45+
- name: Run tests
46+
run: python -m unittest discover -s tests -v
47+
48+
- name: Configure git
49+
run: |
50+
git config user.name "github-actions[bot]"
51+
git config user.email "github-actions[bot]@users.noreply.github.com"
52+
53+
- name: Get current version
54+
id: get_version
55+
run: |
56+
VERSION=$(python -c "import re; content=open('setup.py').read(); print(re.search(r\"version='([^']+)'\", content).group(1))")
57+
echo "current_version=$VERSION" >> $GITHUB_OUTPUT
58+
59+
- name: Bump version
60+
id: bump_version
61+
run: |
62+
CURRENT_VERSION="${{ steps.get_version.outputs.current_version }}"
63+
BUMP_TYPE="${{ inputs.bump_type }}"
64+
65+
# Remove any suffix for calculation
66+
BASE_VERSION=$(echo "$CURRENT_VERSION" | sed -E 's/(-[a-zA-Z0-9]+)?$//')
67+
68+
# Split into major.minor.patch
69+
IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE_VERSION"
70+
71+
# Bump based on type
72+
case $BUMP_TYPE in
73+
major)
74+
MAJOR=$((MAJOR + 1))
75+
MINOR=0
76+
PATCH=0
77+
;;
78+
minor)
79+
MINOR=$((MINOR + 1))
80+
PATCH=0
81+
;;
82+
patch)
83+
PATCH=$((PATCH + 1))
84+
;;
85+
esac
86+
87+
NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}"
88+
89+
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
90+
echo "Bumping version from $CURRENT_VERSION to $NEW_VERSION"
91+
92+
- name: Update version in files
93+
run: |
94+
NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
95+
96+
# Update setup.py
97+
sed -i "s/version='[^']*'/version='$NEW_VERSION'/" setup.py
98+
99+
# Update __init__.py
100+
sed -i "s/__version__ = '[^']*'/__version__ = '$NEW_VERSION'/" ujeebu_python/__init__.py
101+
102+
# Show changes
103+
echo "Updated version to $NEW_VERSION"
104+
git diff
105+
106+
- name: Commit version bump
107+
run: |
108+
NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
109+
git add setup.py ujeebu_python/__init__.py
110+
git commit -m "Bump version to $NEW_VERSION"
111+
git push
112+
113+
- name: Create and push tag
114+
run: |
115+
NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
116+
git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION"
117+
git push origin "v$NEW_VERSION"
118+
119+
- name: Build package
120+
run: python -m build
121+
122+
- name: Publish to PyPI
123+
env:
124+
TWINE_USERNAME: __token__
125+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
126+
run: twine upload dist/*
127+
128+
- name: Create GitHub Release
129+
uses: softprops/action-gh-release@v1
130+
with:
131+
tag_name: v${{ steps.bump_version.outputs.new_version }}
132+
name: Release v${{ steps.bump_version.outputs.new_version }}
133+
generate_release_notes: true
134+
draft: false
135+
prerelease: ${{ inputs.prerelease }}
136+
files: |
137+
dist/*
138+
env:
139+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
140+

.github/workflows/publish.yml

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
publish:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
token: ${{ secrets.GITHUB_TOKEN }}
20+
21+
- name: Set up Python
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: '3.11'
25+
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install build twine
30+
pip install -e .
31+
32+
- name: Run tests
33+
run: python -m unittest discover -s tests -v
34+
35+
- name: Configure git
36+
run: |
37+
git config user.name "github-actions[bot]"
38+
git config user.email "github-actions[bot]@users.noreply.github.com"
39+
40+
- name: Get current version
41+
id: get_version
42+
run: |
43+
VERSION=$(python -c "import re; content=open('setup.py').read(); print(re.search(r\"version='([^']+)'\", content).group(1))")
44+
echo "current_version=$VERSION" >> $GITHUB_OUTPUT
45+
46+
- name: Bump version
47+
id: bump_version
48+
run: |
49+
CURRENT_VERSION="${{ steps.get_version.outputs.current_version }}"
50+
51+
# Extract version parts (handles versions like 0.1.4-beta)
52+
BASE_VERSION=$(echo "$CURRENT_VERSION" | sed -E 's/(-[a-zA-Z0-9]+)?$//')
53+
SUFFIX=$(echo "$CURRENT_VERSION" | grep -oE '\-[a-zA-Z0-9]+$' || echo "")
54+
55+
# Split into major.minor.patch
56+
IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE_VERSION"
57+
58+
# Bump patch version
59+
NEW_PATCH=$((PATCH + 1))
60+
NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}${SUFFIX}"
61+
62+
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
63+
echo "Bumping version from $CURRENT_VERSION to $NEW_VERSION"
64+
65+
- name: Update version in files
66+
run: |
67+
NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
68+
69+
# Update setup.py
70+
sed -i "s/version='[^']*'/version='$NEW_VERSION'/" setup.py
71+
72+
# Update __init__.py
73+
sed -i "s/__version__ = '[^']*'/__version__ = '$NEW_VERSION'/" ujeebu_python/__init__.py
74+
75+
# Show changes
76+
echo "Updated version to $NEW_VERSION"
77+
git diff
78+
79+
- name: Commit version bump
80+
run: |
81+
NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
82+
git add setup.py ujeebu_python/__init__.py
83+
git commit -m "Bump version to $NEW_VERSION [skip ci]"
84+
git push
85+
86+
- name: Create and push tag
87+
run: |
88+
NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
89+
git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION"
90+
git push origin "v$NEW_VERSION"
91+
92+
- name: Build package
93+
run: python -m build
94+
95+
- name: Publish to PyPI
96+
env:
97+
TWINE_USERNAME: __token__
98+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
99+
run: twine upload dist/*
100+
101+
- name: Create GitHub Release
102+
uses: softprops/action-gh-release@v1
103+
with:
104+
tag_name: v${{ steps.bump_version.outputs.new_version }}
105+
name: Release v${{ steps.bump_version.outputs.new_version }}
106+
body: |
107+
## Release v${{ steps.bump_version.outputs.new_version }}
108+
109+
This release was automatically generated.
110+
111+
### Installation
112+
```bash
113+
pip install ujeebu_python==${{ steps.bump_version.outputs.new_version }}
114+
```
115+
draft: false
116+
prerelease: ${{ contains(steps.bump_version.outputs.new_version, 'beta') || contains(steps.bump_version.outputs.new_version, 'alpha') }}
117+
files: |
118+
dist/*
119+
env:
120+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121+

tests/test_ujeebu_python.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ def test_account_user_agent(self, mock_get):
468468
self.client.account()
469469

470470
call_args = mock_get.call_args
471-
self.assertEqual(call_args.kwargs['headers']['user-agent'], 'Ujeebu-Python/0.1.4-beta')
471+
self.assertRegex(call_args.kwargs['headers']['user-agent'], r'^Ujeebu-Python/.+')
472472

473473

474474
if __name__ == '__main__':

0 commit comments

Comments
 (0)