blob: 229f8347d43e9cc842e3771f09b839644decb7c1 [file] [log] [blame]
---
# SPDX-FileCopyrightText: 2026 The Linux Foundation
# SPDX-License-Identifier: Apache-2.0
name: PyPI Publish
description: "Build and publish Python packages to PyPI on SemVer release tags"
inputs:
pypi-index:
description: "PyPI repository name to publish to"
required: false
default: "pypi"
pypi-username:
description: "PyPI username"
required: true
pypi-password:
description: "PyPI password or API token"
required: true
module-dirs:
description: "Pipe-separated list of directories containing Python modules to publish"
required: false
default: "."
prep-commands:
description: "Commands to run before building"
required: false
default: ""
runs:
using: "composite"
steps:
- name: Get and verify SemVer release tag
id: tag-check
shell: bash
run: |
set -eu -o pipefail
TAG=$(git tag --points-at HEAD | head -n1 || true)
if [ -z "$TAG" ]; then
echo "No git tag on HEAD, skipping publish"
echo "is-release=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# Match vX.Y.Z or X.Y.Z (SemVer release, no pre-release suffix)
if [[ "$TAG" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Found SemVer release tag: $TAG"
echo "is-release=true" >> "$GITHUB_OUTPUT"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
else
echo "Tag '$TAG' is not a SemVer release version, skipping publish"
echo "is-release=false" >> "$GITHUB_OUTPUT"
fi
- name: Run prep commands
if: steps.tag-check.outputs.is-release == 'true' && inputs.prep-commands != ''
shell: bash
run: |
set -eu -o pipefail
echo "Running prep commands..."
${{ inputs.prep-commands }}
- name: Build and publish packages
if: steps.tag-check.outputs.is-release == 'true'
shell: bash
env:
TWINE_USERNAME: ${{ inputs.pypi-username }}
TWINE_PASSWORD: ${{ inputs.pypi-password }}
run: |
set -eu -o pipefail
echo "Installing build dependencies..."
pip install --upgrade pip setuptools wheel twine build
IFS='|' read -ra DIRS <<< "${{ inputs.module-dirs }}"
for dir in "${DIRS[@]}"; do
dir=$(echo "$dir" | xargs) # trim whitespace
echo "::group::Publishing module in: $dir"
if [ ! -f "$dir/setup.py" ]; then
echo "ERROR: setup.py not found in $dir"
exit 1
fi
echo "Building source distribution..."
cd "$dir"
python3 -m build
echo "Uploading to PyPI repository: ${{ inputs.pypi-index }}"
twine upload -r "${{ inputs.pypi-index }}" dist/*
cd "$GITHUB_WORKSPACE"
echo "::endgroup::"
done