Skip to content

Release

Release #12

Workflow file for this run

name: Release
on:
push:
tags:
- 'v*-rc*' # RC versions (e.g., v0.3.1-rc1) → Production PyPI
- 'v*' # Final versions (e.g., v0.3.1) → Test PyPI first, then manual production
workflow_dispatch:
inputs:
environment:
description: 'Deploy to environment'
required: true
default: 'test'
type: choice
options:
- test
- production
jobs:
build:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: latest
virtualenvs-create: true
virtualenvs-in-project: true
- name: Install dependencies
run: poetry install --with dev
- name: Get version
id: version
run: |
# Build first to trigger dynamic versioning
poetry build
# Extract version from built wheel filename
VERSION=$(ls dist/*.whl | head -1 | sed 's/.*-\([0-9][^-]*\)-.*/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
- name: Run tests
run: poetry run python scripts/run_tests.py --layer smoke --layer unit
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist-${{ steps.version.outputs.version }}
path: dist/
deploy-test:
needs: build
runs-on: ubuntu-latest
if: (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'test') || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-rc'))
environment: test-pypi
permissions:
id-token: write
contents: read
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: dist-${{ needs.build.outputs.version }}
path: dist/
- name: Publish to Test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
- name: Test installation from Test PyPI
run: |
sleep 60 # Wait for package to be available
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ memfuse==${{ needs.build.outputs.version }}
python -c "import memfuse; print(f'Installed version: {memfuse.__version__}')"
deploy-production:
needs: [build]
runs-on: ubuntu-latest
if: (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'production') || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && contains(github.ref, '-rc'))
environment: production-pypi
permissions:
id-token: write
contents: read
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: dist-${{ needs.build.outputs.version }}
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
create-release:
needs: [build, deploy-production]
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'production'
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Generate changelog
id: changelog
run: |
# Get the previous tag
PREV_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "")
if [ -n "$PREV_TAG" ]; then
echo "## Changes since $PREV_TAG" > changelog.md
git log --pretty=format:"- %s (%h)" $PREV_TAG..HEAD >> changelog.md
else
echo "## Initial Release" > changelog.md
fi
cat changelog.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ github.ref_name }}
name: Release ${{ github.ref_name }}
body_path: changelog.md
draft: false
prerelease: false