Skip to content

Commit 7df5abb

Browse files
authored
ci: add github actions to upload sdist to pypi (#1270)
<!-- .github/pull_request_template.md --> ## πŸ“Œ Description add github actions to upload sdist to pypi ## πŸ” Related Issues <!-- Link any related issues here --> ## πŸš€ Pull Request Checklist Thank you for contributing to FlashInfer! Before we review your pull request, please make sure the following items are complete. ### βœ… Pre-commit Checks - [ ] I have installed `pre-commit` by running `pip install pre-commit` (or used your preferred method). - [ ] I have installed the hooks with `pre-commit install`. - [ ] I have run the hooks manually with `pre-commit run --all-files` and fixed any reported issues. > If you are unsure about how to set up `pre-commit`, see [the pre-commit documentation](https://pre-commit.com/). ## πŸ§ͺ Tests - [ ] Tests have been added or updated as needed. - [ ] All tests are passing (`unittest`, etc.). ## Reviewer Notes <!-- Optional: anything you'd like reviewers to focus on, concerns, etc. -->
1 parent 209b7b1 commit 7df5abb

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
name: Publish sdist to PyPI
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
tag:
7+
description: 'Tag (e.g., v1.2.3) to build and publish'
8+
required: true
9+
type: string
10+
11+
jobs:
12+
build-and-upload:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Validate tag format
16+
run: |
17+
if [[ ! "${{ inputs.tag }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(\.[a-z0-9]+)?$ ]]; then
18+
echo "Error: Tag '${{ inputs.tag }}' does not match the expected format (e.g., v1.2.3 or v1.2.3.post1)"
19+
exit 1
20+
fi
21+
echo "βœ“ Tag format is valid: ${{ inputs.tag }}"
22+
23+
- name: Check out tag
24+
uses: actions/checkout@v4
25+
with:
26+
ref: ${{ inputs.tag }}
27+
submodules: true
28+
29+
- name: Set up Python
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: '3.10'
33+
34+
- name: Verify tag matches version.txt (CRITICAL)
35+
run: |
36+
# Extract version from tag (remove 'v' prefix)
37+
TAG_VERSION="${{ inputs.tag }}"
38+
TAG_VERSION="${TAG_VERSION#v}"
39+
40+
# Check version.txt FIRST - this is the source of truth
41+
if [ ! -f "version.txt" ]; then
42+
echo "Error: version.txt file not found!"
43+
exit 1
44+
fi
45+
46+
VERSION_TXT=$(cat version.txt | tr -d '[:space:]')
47+
48+
if [ "$TAG_VERSION" != "$VERSION_TXT" ]; then
49+
echo "❌ CRITICAL ERROR: version.txt does not match tag!"
50+
echo " Tag version: $TAG_VERSION"
51+
echo " version.txt: $VERSION_TXT"
52+
echo ""
53+
echo "Please update version.txt to match the release version before creating a release."
54+
echo "The tag should be 'v$VERSION_TXT' (e.g., if version.txt contains '1.2.3', tag should be 'v1.2.3')"
55+
exit 1
56+
fi
57+
58+
echo "βœ“ version.txt matches tag version: $VERSION_TXT"
59+
60+
- name: Verify tag matches package version
61+
run: |
62+
# Extract version from tag (remove 'v' prefix)
63+
TAG_VERSION="${{ inputs.tag }}"
64+
TAG_VERSION="${TAG_VERSION#v}"
65+
66+
# Extract version from setup.py or pyproject.toml
67+
if [ -f "setup.py" ]; then
68+
PACKAGE_VERSION=$(python -c "import re; content = open('setup.py').read(); match = re.search(r'version\s*=\s*[\"']([^\"']+)[\"']', content); print(match.group(1) if match else '')")
69+
elif [ -f "pyproject.toml" ]; then
70+
PACKAGE_VERSION=$(python -c "import tomllib; data = tomllib.load(open('pyproject.toml', 'rb')); print(data.get('project', {}).get('version', '') or data.get('tool', {}).get('poetry', {}).get('version', ''))")
71+
else
72+
echo "Warning: Could not find version file (setup.py or pyproject.toml)"
73+
PACKAGE_VERSION=""
74+
fi
75+
76+
if [ -n "$PACKAGE_VERSION" ] && [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then
77+
echo "Error: Tag version ($TAG_VERSION) does not match package version ($PACKAGE_VERSION)"
78+
exit 1
79+
fi
80+
echo "βœ“ Package version check passed: $TAG_VERSION"
81+
82+
- name: Install build dependencies
83+
run: |
84+
python -m pip install --upgrade pip
85+
pip install build twine wheel
86+
87+
- name: Build sdist
88+
run: |
89+
echo "Building source distribution..."
90+
python -m build --sdist
91+
echo "βœ“ Build completed"
92+
ls -lh dist/
93+
94+
- name: Check sdist contents
95+
run: |
96+
echo "Verifying sdist contents..."
97+
tar -tzf dist/*.tar.gz | head -20
98+
echo "..."
99+
echo "βœ“ Sdist archive created successfully"
100+
101+
- name: Store build artifacts
102+
uses: actions/upload-artifact@v4
103+
with:
104+
name: python-package-distributions
105+
path: dist/
106+
retention-days: 7
107+
108+
- name: Test installation from sdist
109+
run: |
110+
echo "Testing installation from built sdist..."
111+
python -m venv test-env
112+
source test-env/bin/activate
113+
pip install dist/*.tar.gz
114+
python -c "import flashinfer; print(f'βœ“ Successfully imported flashinfer')"
115+
deactivate
116+
rm -rf test-env
117+
118+
- name: Check package with twine
119+
run: |
120+
echo "Running twine check..."
121+
twine check dist/*
122+
echo "βœ“ Package validation passed"
123+
124+
- name: Upload to PyPI
125+
env:
126+
TWINE_USERNAME: __token__
127+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
128+
run: |
129+
echo "Uploading to PyPI..."
130+
twine upload --verbose --non-interactive dist/*.tar.gz
131+
echo "βœ“ Successfully uploaded to PyPI"

0 commit comments

Comments
Β (0)