Release to PyPI and Docker #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release to PyPI and Docker | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| bump: | |
| description: 'Version bump type' | |
| required: true | |
| type: choice | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| - custom | |
| default: 'patch' | |
| custom_version: | |
| description: 'Custom version (only if bump=custom, e.g., 0.2.0)' | |
| required: false | |
| type: string | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| publish-pypi: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| outputs: | |
| version: ${{ steps.new.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v5 | |
| - name: Set up Python | |
| run: uv python install 3.8 | |
| - name: Get current version | |
| id: current | |
| run: | | |
| CURRENT=$(grep '^__version__ = ' python/src/bioscript/__init__.py | cut -d'"' -f2) | |
| echo "version=${CURRENT}" >> $GITHUB_OUTPUT | |
| echo "Current version: ${CURRENT}" | |
| - name: Calculate new version | |
| id: new | |
| run: | | |
| CURRENT="${{ steps.current.outputs.version }}" | |
| IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT" | |
| case "${{ inputs.bump }}" in | |
| major) | |
| NEW_VERSION="$((MAJOR + 1)).0.0" | |
| ;; | |
| minor) | |
| NEW_VERSION="${MAJOR}.$((MINOR + 1)).0" | |
| ;; | |
| patch) | |
| NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" | |
| ;; | |
| custom) | |
| NEW_VERSION="${{ inputs.custom_version }}" | |
| ;; | |
| esac | |
| echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT | |
| echo "New version: ${NEW_VERSION}" | |
| - name: Bump version across repository | |
| run: | | |
| ./bump_version.sh "${{ steps.new.outputs.version }}" | |
| - name: Install dependencies | |
| run: | | |
| cd python | |
| uv sync --all-extras | |
| - name: Run tests | |
| run: | | |
| cd python | |
| uv run pytest | |
| - name: Build package | |
| run: | | |
| cd python | |
| uv build | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| packages-dir: python/dist/ | |
| password: ${{ secrets.PYPI_API_TOKEN }} | |
| - name: Commit version bump and tag | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add -A | |
| git commit -m "Bump version to ${{ steps.new.outputs.version }}" | |
| git tag "v${{ steps.new.outputs.version }}" | |
| git push origin main --tags | |
| build-docker: | |
| needs: publish-pypi | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| attestations: write | |
| id-token: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: main # Get the latest main with version bump | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract version from __init__.py | |
| id: version | |
| run: | | |
| VERSION="${{ needs.publish-pypi.outputs.version }}" | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "Using version: ${VERSION}" | |
| - name: Extract metadata for Docker | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=semver,pattern={{version}},value=v${{ steps.version.outputs.version }} | |
| type=semver,pattern={{major}}.{{minor}},value=v${{ steps.version.outputs.version }} | |
| type=semver,pattern={{major}},value=v${{ steps.version.outputs.version }} | |
| type=raw,value=${{ steps.version.outputs.version }} | |
| type=raw,value=latest | |
| - name: Build and push Docker image | |
| id: build | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./docker/Dockerfile | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Generate artifact attestation | |
| uses: actions/attest-build-provenance@v1 | |
| continue-on-error: true # Don't fail build if attestation fails | |
| with: | |
| subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| subject-digest: ${{ steps.build.outputs.digest }} | |
| push-to-registry: true |