v1.2.2 #7
Workflow file for this run
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 Pipeline | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Release version (e.g., 1.0.0)' | |
| required: true | |
| type: string | |
| permissions: | |
| contents: read | |
| packages: write | |
| pages: write | |
| id-token: write | |
| concurrency: | |
| group: production-release-${{ github.event.release.tag_name || inputs.version }} | |
| cancel-in-progress: false | |
| jobs: | |
| config: | |
| name: Get Configuration | |
| runs-on: ubuntu-latest | |
| outputs: | |
| python-versions: ${{ steps.config.outputs.python-versions }} | |
| default-python-version: ${{ steps.config.outputs.default-python-version }} | |
| container-registry: ${{ steps.config.outputs.container-registry }} | |
| container-image: ${{ steps.config.outputs.container-image }} | |
| package-version: ${{ steps.config.outputs.package-version }} | |
| is-release: ${{ steps.config.outputs.is-release }} | |
| pypi-name: ${{ steps.config.outputs.pypi-name }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6.0.2 | |
| - name: Get project configuration | |
| id: config | |
| uses: ./.github/actions/get-config | |
| prod-containers: | |
| name: Build Production Containers | |
| needs: config | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ${{ fromJSON(needs.config.outputs.python-versions) }} | |
| env: | |
| SCAN_LEVEL: ${{ matrix.python-version == needs.config.outputs.default-python-version && 'full' || 'basic' }} | |
| PUSH_TO_REGISTRY: true | |
| permissions: | |
| contents: read | |
| packages: write | |
| security-events: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6.0.2 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| with: | |
| platforms: linux/amd64,linux/arm64 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ needs.config.outputs.container-registry }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Python and UV | |
| uses: ./.github/actions/setup-uv-cached | |
| with: | |
| cache-key: prod-${{ needs.config.outputs.package-version }}-py${{ matrix.python-version }} | |
| fail-on-cache-miss: false | |
| - name: Build package wheel | |
| run: make build | |
| - name: Build and scan container image | |
| env: | |
| REGISTRY: ${{ needs.config.outputs.container-registry }} | |
| IMAGE_NAME: ${{ needs.config.outputs.container-image }} | |
| VERSION: ${{ needs.config.outputs.package-version }} | |
| PYTHON_VERSION: ${{ matrix.python-version }} | |
| DEFAULT_PYTHON: ${{ needs.config.outputs.default-python-version }} | |
| run: | | |
| make container single push \ | |
| REGISTRY="$REGISTRY" \ | |
| IMAGE="$IMAGE_NAME" \ | |
| VERSION="$VERSION" \ | |
| PYTHON_VERSION="$PYTHON_VERSION" | |
| prod-manifests: | |
| name: Create Production Manifests | |
| needs: [config, prod-containers] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6.0.2 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ needs.config.outputs.container-registry }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create production tag manifests | |
| env: | |
| REGISTRY: ${{ needs.config.outputs.container-registry }} | |
| IMAGE: ${{ needs.config.outputs.container-image }} | |
| VERSION: ${{ needs.config.outputs.package-version }} | |
| DEFAULT_PYTHON: ${{ needs.config.outputs.default-python-version }} | |
| IS_RELEASE: "true" | |
| run: | | |
| # Get tags from Makefile target | |
| eval "$(make get-container-tags-env)" | |
| # Create primary tags (latest, version) | |
| if [[ -n "$primary_tags" ]]; then | |
| IFS=',' read -ra TAGS <<< "$primary_tags" | |
| for tag in "${TAGS[@]}"; do | |
| echo "Creating primary tag: $tag -> $VERSION-python$DEFAULT_PYTHON" | |
| docker buildx imagetools create \ | |
| -t "$REGISTRY/$IMAGE:$tag" \ | |
| "$REGISTRY/$IMAGE:$VERSION-python$DEFAULT_PYTHON" | |
| done | |
| fi | |
| # Create Python variant tags | |
| if [[ -n "$python_tags" ]]; then | |
| IFS=',' read -ra TAGS <<< "$python_tags" | |
| for tag in "${TAGS[@]}"; do | |
| py_ver=${tag#python} | |
| echo "Creating Python variant tag: $tag -> $VERSION-python$py_ver" | |
| docker buildx imagetools create \ | |
| -t "$REGISTRY/$IMAGE:$tag" \ | |
| "$REGISTRY/$IMAGE:$VERSION-python$py_ver" | |
| done | |
| fi | |
| prod-pypi: | |
| name: Publish to PyPI | |
| needs: config | |
| runs-on: ubuntu-latest | |
| environment: pypi | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6.0.2 | |
| - name: Setup Python and UV | |
| uses: ./.github/actions/setup-uv-cached | |
| with: | |
| cache-key: prod-pypi-${{ needs.config.outputs.package-version }} | |
| fail-on-cache-miss: false | |
| - name: Build package | |
| run: make build | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| print-hash: true | |
| verbose: true | |
| prod-docs: | |
| name: Deploy Production Documentation | |
| needs: config | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6.0.2 | |
| - name: Setup Python and UV | |
| uses: ./.github/actions/setup-uv-cached | |
| with: | |
| cache-key: prod-docs-${{ needs.config.outputs.package-version }} | |
| fail-on-cache-miss: false | |
| - name: Build documentation | |
| run: make ci-docs-build-for-pages | |
| - name: Upload Pages artifact | |
| id: upload | |
| uses: actions/upload-pages-artifact@v4 | |
| with: | |
| path: docs/site | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 | |
| container-cleanup: | |
| name: Cleanup Old Container Images | |
| needs: [config, prod-manifests] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| packages: write | |
| steps: | |
| - name: Delete untagged container images | |
| uses: actions/delete-package-versions@v5 | |
| with: | |
| package-name: ${{ github.event.repository.name }} | |
| package-type: container | |
| min-versions-to-keep: 0 | |
| delete-only-untagged-versions: true | |
| github-assets: | |
| name: Upload GitHub Release Assets | |
| needs: [config, prod-containers, prod-pypi] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6.0.2 | |
| - name: Setup Python and UV | |
| uses: ./.github/actions/setup-uv-cached | |
| with: | |
| cache-key: prod-assets-${{ needs.config.outputs.package-version }} | |
| fail-on-cache-miss: false | |
| - name: Build package | |
| run: make build | |
| - name: Generate SBOM | |
| run: make sbom | |
| - name: Upload release assets | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="${{ needs.config.outputs.package-version }}" | |
| RELEASE_TAG="v$VERSION" | |
| # Upload wheel and source distribution | |
| gh release upload "$RELEASE_TAG" dist/*.whl dist/*.tar.gz --clobber | |
| # Upload SBOM if it exists | |
| if [[ -f "sbom.json" ]]; then | |
| gh release upload "$RELEASE_TAG" sbom.json --clobber | |
| fi |