Skip to content

Publish to PyPI

Publish to PyPI #20

Workflow file for this run

name: Publish to PyPI
on:
release:
types: [published]
workflow_dispatch: # Enable manual trigger.
jobs:
build-and-publish:
runs-on: ubuntu-latest
permissions:
id-token: write # Mandatory for OIDC.
contents: read
steps:
- name: Checkout (official GitHub action)
uses: actions/checkout@v4
with:
# Important for versioning plugins:
fetch-depth: 0
- name: Install uv (official Astral action)
uses: astral-sh/setup-uv@v5
with:
version: "0.9.5"
enable-cache: true
python-version: "3.12"
- name: Set up Python (using uv)
run: uv python install
- name: Install all dependencies
run: uv sync --all-extras
- name: Run tests
run: uv run pytest
- name: Verify pyproject.toml is correct
run: |
# Verify pyproject.toml has the correct package name
if ! grep -q 'name = "python-package-folder"' pyproject.toml; then
echo "Error: pyproject.toml does not have correct package name 'python-package-folder'"
echo "Current content:"
grep '^name =' pyproject.toml || echo "No name field found"
exit 1
fi
# Verify packages points to the correct location
if ! grep -q 'packages = \["src/python_package_folder"\]' pyproject.toml; then
echo "Error: pyproject.toml does not have correct packages configuration"
echo "Current packages:"
grep -A 1 '\[tool.hatch.build.targets.wheel\]' pyproject.toml || echo "No packages found"
exit 1
fi
echo "✓ pyproject.toml is correct"
- name: Clean dist directory
run: |
# Remove any existing distribution files to prevent publishing test artifacts
rm -rf dist/
echo "✓ Cleaned dist/ directory"
- name: Build package
run: uv build
- name: Verify distribution files
run: |
# List all distribution files that will be published
echo "Distribution files to be published:"
ls -la dist/ || (echo "No dist/ directory found" && exit 1)
# Check for unexpected files (exclude .gitignore and expected package files)
UNEXPECTED_FILES=0
for file in dist/*.whl dist/*.tar.gz; do
if [ -f "$file" ]; then
filename=$(basename "$file")
# Check if file starts with python_package_folder (package directory name)
if [[ ! "$filename" =~ ^python_package_folder- ]]; then
echo "Error: Found unexpected distribution file: $filename"
UNEXPECTED_FILES=$((UNEXPECTED_FILES + 1))
fi
fi
done
if [ $UNEXPECTED_FILES -gt 0 ]; then
echo "Error: Found $UNEXPECTED_FILES unexpected distribution file(s)"
echo "Files in dist/:"
ls -la dist/
exit 1
fi
# Verify at least one expected file exists
if ! ls dist/python_package_folder-*.whl dist/python_package_folder-*.tar.gz 2>/dev/null | grep -q .; then
echo "Error: No python_package_folder distribution files found"
echo "Files in dist/:"
ls -la dist/
exit 1
fi
echo "✓ Only python_package_folder distribution files found"
- name: Publish to PyPI
run: uv publish --trusted-publishing always
# Although uv is newer and faster, the "official" publishing option is the one from PyPA,
# which uses twine. If desired, replace `uv publish` with:
# uses: pypa/gh-action-pypi-publish@release/v1