-
Notifications
You must be signed in to change notification settings - Fork 0
206 lines (176 loc) · 8.47 KB
/
Copy pathpython-publish.yml
File metadata and controls
206 lines (176 loc) · 8.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
name: Python Package Version Bump, Build and Publish to PyPI
on:
workflow_dispatch:
inputs:
release_type:
description: 'Release type (patch, minor, major)'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
version_override:
description: 'Override version (leave empty to auto-increment)'
required: false
type: string
publish_to_pypi:
description: 'Publish to PyPI'
required: true
default: false
type: boolean
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write # Needed to create branches and PRs
pull-requests: write # Needed to create pull requests
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # We need the full history for versioning
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build hatch semver wheel twine packaging
- name: Set Git identity
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
- name: Update version based on release type
id: version
run: |
cd python
# Get current version from pyproject.toml
CURRENT_VERSION=$(grep -m 1 'version = ' pyproject.toml | cut -d'"' -f2 || echo "0.0.0")
echo "Current version: $CURRENT_VERSION"
if [ -n "${{ github.event.inputs.version_override }}" ]; then
# Use the manually specified version
NEW_VERSION="${{ github.event.inputs.version_override }}"
echo "Using manual version override: $NEW_VERSION"
else
# Calculate new version based on release type
RELEASE_TYPE="${{ github.event.inputs.release_type }}"
if [ "$RELEASE_TYPE" == "patch" ]; then
NEW_VERSION=$(python -c "import semver; print(semver.VersionInfo.parse('$CURRENT_VERSION').bump_patch())")
elif [ "$RELEASE_TYPE" == "minor" ]; then
NEW_VERSION=$(python -c "import semver; print(semver.VersionInfo.parse('$CURRENT_VERSION').bump_minor())")
elif [ "$RELEASE_TYPE" == "major" ]; then
NEW_VERSION=$(python -c "import semver; print(semver.VersionInfo.parse('$CURRENT_VERSION').bump_major())")
else
NEW_VERSION="$CURRENT_VERSION"
fi
echo "Calculated new $RELEASE_TYPE version: $NEW_VERSION"
fi
# Check PyPI for existing versions
echo "Checking PyPI for existing package versions..."
if pip install browserstate==invalid_version 2>&1 | grep -q "browserstate"; then
# Package exists, get latest version
PYPI_VERSION=$(pip index versions browserstate 2>/dev/null | grep browserstate | sed 's/.*(\(.*\))/\1/' | sed 's/, /\n/g' | head -n1 || echo "0.0.0")
echo "Latest version on PyPI: $PYPI_VERSION"
# Compare versions using Python's packaging module
VERSION_COMPARE=$(python -c "from packaging import version; print(version.parse('$NEW_VERSION') > version.parse('$PYPI_VERSION'))")
if [ "$VERSION_COMPARE" != "True" ]; then
# Current version on PyPI is the same or newer
NEW_VERSION=$(python -c "from packaging import version; import semver; v = semver.VersionInfo.parse('$PYPI_VERSION'); print(v.bump_patch())")
echo "⚠️ Version conflict detected! Automatically bumping to $NEW_VERSION"
fi
else
echo "Package not found on PyPI, using version $NEW_VERSION"
fi
# Update version in pyproject.toml
sed -i "s/version = \"$CURRENT_VERSION\"/version = \"$NEW_VERSION\"/" pyproject.toml
# Set output variable for later steps
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
- name: Build package
run: |
cd python
python -m build
echo "Package built successfully. Output in dist/ directory."
- name: Create branch for version update
run: |
# Create a new branch for the version update
BRANCH_NAME="python-version-${{ steps.version.outputs.new_version }}"
git checkout -b $BRANCH_NAME
# Add and commit changes
git add python/pyproject.toml
git commit -m "Bump Python package version to ${{ steps.version.outputs.new_version }}"
# Push the branch
git push -u origin $BRANCH_NAME
echo "branch_name=$BRANCH_NAME" >> $GITHUB_ENV
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "Bump Python package version to ${{ steps.version.outputs.new_version }}"
title: "Bump Python package version to ${{ steps.version.outputs.new_version }}"
body: |
This PR updates the Python package version to ${{ steps.version.outputs.new_version }}
### Installation Instructions
```bash
pip install git+https://github.com/browserstate-org/browserstate@python-v${{ steps.version.outputs.new_version }}#subdirectory=python
# Or with uv
uv pip install git+https://github.com/browserstate-org/browserstate@python-v${{ steps.version.outputs.new_version }}#subdirectory=python
```
branch: ${{ env.branch_name }}
base: main
labels: python,version-bump,automated-pr
- name: Create tag
run: |
# Only create tag if we haven't already tagged this version
if ! git rev-parse "python-v${{ steps.version.outputs.new_version }}" >/dev/null 2>&1; then
TAG_NAME="python-v${{ steps.version.outputs.new_version }}"
git tag $TAG_NAME
git push origin $TAG_NAME
else
echo "Tag python-v${{ steps.version.outputs.new_version }} already exists, skipping tag creation"
fi
- name: Publish to PyPI
if: ${{ github.event.inputs.publish_to_pypi == 'true' }}
env:
TWINE_USERNAME: "__token__"
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
set -e # Exit immediately if a command exits with a non-zero status
cd python
# Verify distribution files exist
if [ ! "$(ls -A dist)" ]; then
echo "❌ Error: No distribution files found in dist/ directory"
exit 1
fi
# Check PyPI for existing versions
echo "🔍 Checking if version already exists on PyPI..."
if pip install "browserstate==${{ steps.version.outputs.new_version }}" 2>/dev/null; then
echo "⚠️ Version ${{ steps.version.outputs.new_version }} already exists on PyPI."
echo "❌ Skipping upload to prevent conflicts. Please bump the version manually."
exit 1
fi
# Validate the package before uploading
echo "🔍 Validating the package before uploading..."
twine check dist/*
# Upload to PyPI with proper error handling
echo "📦 Uploading to PyPI..."
if ! python -m twine upload dist/*; then
echo "❌ Failed to upload package to PyPI"
exit 1
fi
echo "🚀 Package published to PyPI successfully!"
- name: Update installation instructions
run: |
echo "::notice::Python package version ${{ steps.version.outputs.new_version }} built successfully!"
echo "::notice::Pull request created to update version in main branch"
if [ "${{ github.event.inputs.publish_to_pypi }}" == "true" ]; then
echo "::notice::📦 Package published to PyPI!"
echo "::notice::Installation Instructions:"
echo "::notice::pip install browserstate==${{ steps.version.outputs.new_version }}"
echo "::notice::uv pip install browserstate==${{ steps.version.outputs.new_version }}"
else
echo "::notice::Installation Instructions from GitHub:"
echo "::notice::pip install git+https://github.com/browserstate-org/browserstate@python-v${{ steps.version.outputs.new_version }}#subdirectory=python"
echo "::notice::uv pip install git+https://github.com/browserstate-org/browserstate@python-v${{ steps.version.outputs.new_version }}#subdirectory=python"
fi