Skip to content

Release Matching Python Tags #36

Release Matching Python Tags

Release Matching Python Tags #36

name: Release Matching Python Tags
# This workflow intentionally does not use workflow_dispatch inputs to comply with policy.
# To control which tags to release, create a one-line file at
# .github/release/python-tag-filter.txt (e.g., 3.13.*). If absent/empty, it
# derives a filter from the latest version (e.g., 3.13.*).
on:
# Inputs must be empty to comply with policy
workflow_dispatch: {}
push:
paths:
- .github/release/python-tag-filter.txt
permissions:
contents: write # Required for release workflow to push manifest and assets
actions: write # Required for calling reusable workflows
jobs:
get-tags:
runs-on: ubuntu-latest
outputs:
tags_json: ${{ steps.collect.outputs.tags_json }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install Python dependencies
run: |
pip install --upgrade pip
pip install poetry
poetry install --no-interaction --no-ansi
- name: Get Python tags matching filter
id: collect
run: |
# Optional file-based filter override to keep functionality without inputs
filter_file=".github/release/python-tag-filter.txt"
if [ -f "$filter_file" ]; then
FILTER=$( (grep -vE '^\s*(#|$)' "$filter_file" | head -n1 | tr -d '\r') || true )
if [ -n "$FILTER" ]; then
echo "Using filter from $filter_file: $FILTER"
else
unset FILTER
fi
fi
if [ -z "${FILTER:-}" ]; then
LATEST=$(poetry run python .github/scripts/get_python_version.py --latest)
echo "No filter supplied, fetched latest tag: $LATEST"
# Convert latest version like 3.13.3 to 3.13.*
FILTER=$(echo "$LATEST" | sed -E 's/\.[0-9]+$/.*/')
echo "Derived filter: $FILTER"
fi
TAGS=$(poetry run python .github/scripts/get_python_version.py --list --filter "$FILTER")
echo "Raw tags found:"
echo "$TAGS"
TAGS_JSON=$(echo "$TAGS" | jq -R -s -c 'split("\n") | map(select(length > 0))')
echo "Tags JSON for matrix:"
echo "$TAGS_JSON"
echo "tags_json=$TAGS_JSON" >> "$GITHUB_OUTPUT"
build-and-release-matrix:
needs: get-tags
strategy:
fail-fast: false # Allow other builds to continue even if a sibling fails
max-parallel: 12 # Increased parallelism for faster throughput
matrix:
tag: ${{ fromJson(needs.get-tags.outputs.tags_json) }}
platform-version: ['24.04', '22.04']
arch: ['s390x', 'ppc64le']
uses: ./.github/workflows/reusable-build-and-release-python-versions.yml
with:
arch: ${{ matrix.arch }}
tag: ${{ matrix.tag }}
platform-version: ${{ matrix['platform-version'] }}
runner-label: ${{ format('ubuntu-{0}-{1}', matrix['platform-version'], matrix.arch) }}
release-assets:
needs: [build-and-release-matrix, get-tags]
if: always() && !cancelled()
permissions:
contents: write
actions: read
strategy:
fail-fast: false
matrix:
tag: ${{ fromJson(needs.get-tags.outputs.tags_json) }}
uses: ./.github/workflows/reusable-release-python-tar.yml
with:
tag: ${{ matrix.tag }}
secrets:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
update-manifests:
needs: release-assets
if: always() && needs.release-assets.result != 'skipped' && needs.release-assets.result != 'cancelled'
runs-on: ubuntu-latest
permissions:
contents: write
actions: read
concurrency:
group: manifests-${{ github.ref }} # Shared with release-latest so manifest pushes serialize
cancel-in-progress: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Download partial manifest artifacts # Pull manifest-part-* artifacts from successful release jobs
continue-on-error: true # Some matrix legs may fail and omit artifacts
uses: actions/download-artifact@v4
with:
path: manifest-parts
pattern: manifest-part-*
merge-multiple: true
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry install --no-interaction --no-ansi
- name: Apply partial manifests # Convert partial JSON blobs into tracked versions-manifests/*.json
run: |
poetry run python .github/scripts/apply_partial_manifests.py \
--partials-dir manifest-parts \
--manifest-dir versions-manifests
- name: Commit manifest updates
id: commit_manifests
run: |
if git status --porcelain -- versions-manifests | grep .; then
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add versions-manifests/*.json
git commit -m "Apply manifest partials [skip ci]"
echo "committed=true" >> "$GITHUB_OUTPUT"
else
echo "No manifest changes detected"
echo "committed=false" >> "$GITHUB_OUTPUT"
fi
- name: Push manifest updates
if: steps.commit_manifests.outputs.committed == 'true'
run: |
# Keep locally generated manifest files when resolving conflicts
git pull --rebase --strategy=recursive --strategy-option=ours
git push