Skip to content

Release 0.4.102 for direct #113

Release 0.4.102 for direct

Release 0.4.102 for direct #113

Workflow file for this run

name: Publish to PyPI
run-name: Release ${{ inputs.release_tag || github.ref_name }} for ${{ inputs.release_plan || 'direct' }}
on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+*'
workflow_dispatch:
inputs:
release_tag:
description: 'Existing immutable SDK release tag; empty permits a build-only run'
required: false
type: string
default: ''
release_plan:
description: 'Immutable release-plan tag initiating this recovery run'
required: false
type: string
default: 'direct'
publish:
description: 'Publish the exact release tag to PyPI'
required: false
type: boolean
default: false
dry_run:
description: 'Legacy TestPyPI dry-run guard'
required: false
type: boolean
default: true
permissions:
contents: read
concurrency:
group: release-${{ inputs.release_tag || github.ref_name }}
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
outputs:
release_tag: ${{ steps.release_source.outputs.tag }}
release_commit: ${{ steps.release_source.outputs.commit }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
ref: >-
${{ github.event_name == 'workflow_dispatch' && inputs.release_tag != ''
&& format('refs/tags/{0}', inputs.release_tag) || github.ref }}
- name: Resolve exact release identity
id: release_source
env:
REQUESTED_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }}
PUBLISH_REQUESTED: ${{ github.event_name == 'push' || inputs.publish }}
run: |
set -euo pipefail
package_version="$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')"
head_commit="$(git rev-parse HEAD)"
if [ "$PUBLISH_REQUESTED" = true ]; then
if [[ ! "$REQUESTED_TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?$ ]]; then
printf 'release tag must be an exact SDK SemVer: %s\n' "$REQUESTED_TAG" >&2
exit 1
fi
if [ "$REQUESTED_TAG" != "$package_version" ]; then
printf 'release tag %s does not match package version %s\n' "$REQUESTED_TAG" "$package_version" >&2
exit 1
fi
tag_commit="$(git rev-list -n 1 "$REQUESTED_TAG")"
if [ "$tag_commit" != "$head_commit" ]; then
printf 'release tag %s points to %s, not checkout commit %s\n' \
"$REQUESTED_TAG" "$tag_commit" "$head_commit" >&2
exit 1
fi
else
REQUESTED_TAG="$package_version"
fi
{
printf 'tag=%s\n' "$REQUESTED_TAG"
printf 'commit=%s\n' "$head_commit"
} >> "$GITHUB_OUTPUT"
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install build tools
run: pip install build twine
- name: Build package
run: python -m build
- name: Check package
run: twine check dist/*
- name: Smoke test built package
run: python scripts/smoke-built-package.py
- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
name: dist
path: dist/
publish:
needs: build
runs-on: ubuntu-latest
if: >-
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) ||
(github.event_name == 'workflow_dispatch' && inputs.publish)
environment: pypi
permissions:
contents: write
steps:
- uses: actions/checkout@v6
- uses: actions/download-artifact@v8
with:
name: dist
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_TOKEN }}
print-hash: true
skip-existing: true
- name: Create the source GitHub Release
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ needs.build.outputs.release_tag }}
run: |
if ! gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
arguments=(--verify-tag --generate-notes --title "$RELEASE_TAG")
if [[ "$RELEASE_TAG" == *-* ]]; then
arguments+=(--prerelease)
fi
gh release create "$RELEASE_TAG" "${arguments[@]}"
fi
verify-docs-release-audit:
needs: [build, publish]
runs-on: ubuntu-latest
if: >-
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) ||
(github.event_name == 'workflow_dispatch' && inputs.publish)
steps:
- uses: actions/checkout@v6
with:
ref: ${{ needs.build.outputs.release_tag }}
- name: Verify live docs release audit after PyPI publish
env:
DOCS_RELEASE_AUDIT_ARTIFACT: sdk-python
DOCS_RELEASE_AUDIT_VERSION: ${{ needs.build.outputs.release_tag }}
DOCS_RELEASE_AUDIT_EVIDENCE: docs-release-audit-evidence.json
DOCS_RELEASE_AUDIT_HANDOFF: docs-release-audit-handoff.json
DOCS_RELEASE_AUDIT_ENFORCEMENT: advisory
run: scripts/ci/check-docs-release-audit.sh
- name: Upload docs release audit evidence
if: always()
uses: actions/upload-artifact@v7
with:
name: docs-release-audit-evidence
path: |
docs-release-audit-evidence.json
docs-release-audit-handoff.json
if-no-files-found: warn
publish-test:
needs: build
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && !inputs.dry_run && !inputs.publish
environment: test-pypi
steps:
- uses: actions/download-artifact@v8
with:
name: dist
path: dist/
- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.TEST_PYPI_TOKEN }}
repository-url: https://test.pypi.org/legacy/
print-hash: true