Files
Giles Odigwe 1109cf778b Python: resolve release tags against real package directories (#7795)
* Make python-release tag handling more robust

Pass the release tag through the step env block and reference it as a
quoted shell variable, and validate the package name derived from the
tag before using it as a directory path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 73f2e039-3ff4-4a5a-a8f8-253b0bfa94f3

* Resolve release tags against real package directories

Package names can contain hyphens and can use underscores where the tag
uses hyphens, so splitting the tag on the first hyphen picked the wrong
directory. Resolve the name against the actual packages/ listing instead,
and handle the python-<version> workspace tag explicitly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 73f2e039-3ff4-4a5a-a8f8-253b0bfa94f3

* Require a real version component in release tags

Selecting the workspace build on the absence of a hyphen meant a
malformed tag such as python-devui built and uploaded the whole
workspace. Match the suffix against the supported version formats
instead, and reject tags that are neither shape.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 73f2e039-3ff4-4a5a-a8f8-253b0bfa94f3

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 73f2e039-3ff4-4a5a-a8f8-253b0bfa94f3
2026-08-21 01:29:30 +00:00

132 lines
4.5 KiB
YAML

name: Python - Build Release Assets
on:
release:
types: [published]
permissions:
contents: write
id-token: write
env:
# Configure a constant location for the uv cache
UV_CACHE_DIR: /tmp/.uv-cache
jobs:
python-build-assets:
if: github.event_name == 'release' && startsWith(github.event.release.tag_name, 'python-')
name: Python Build Assets and add to Release
runs-on: ubuntu-latest
environment: "integration"
env:
UV_PYTHON: "3.13"
defaults:
run:
working-directory: python
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up python and install the project
id: python-setup
uses: ./.github/actions/python-setup
with:
python-version: ${{ matrix.python-version }}
os: ${{ runner.os }}
env:
# Configure a constant location for the uv cache
UV_CACHE_DIR: /tmp/.uv-cache
- name: Resolve the package to build
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: |
set -euo pipefail
TAG="$TAG_NAME"
# Release tags are either python-<version> for the whole workspace, or
# python-<package>-<version> for a single package. Package names may
# themselves contain hyphens (hosting-a2a, azure-ai-search), so the
# package part cannot be found by splitting on the first hyphen.
#
# Versions follow the lifecycle patterns in the python-package-management
# skill: X.Y.Z, X.Y.ZaYYMMDD, X.Y.ZbYYMMDD, X.Y.ZrcN, each optionally
# carrying a .N or .postN re-cut suffix.
VERSION_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+([ab][0-9]+|rc[0-9]+)?(\.[0-9]+|\.post[0-9]+)?$'
REST="${TAG#python-}"
if [[ -z "$REST" ]]; then
echo "Error: tag '$TAG' has no version or package component"
exit 1
fi
if [[ "$REST" =~ $VERSION_PATTERN ]]; then
# python-<version>: build every workspace package plus the root meta package.
PACKAGE="all"
echo "Resolved tag '$TAG' to the full workspace build"
else
# python-<package>-<version>: split off the trailing version component and
# require it to be a real version, so a malformed tag fails here rather
# than being mistaken for another kind of release.
CANDIDATE="${REST%-*}"
VERSION="${REST##*-}"
if [[ "$CANDIDATE" == "$REST" || -z "$CANDIDATE" ]]; then
echo "Error: tag '$TAG' is neither python-<version> nor python-<package>-<version>"
exit 1
fi
if [[ ! "$VERSION" =~ $VERSION_PATTERN ]]; then
echo "Error: tag '$TAG' does not end in a supported version"
echo "Derived version: '$VERSION'"
exit 1
fi
# Resolve the package part against the real package directories. Tags use
# hyphens even where the directory uses underscores
# (python-github-copilot -> github_copilot).
PACKAGE=""
for dir in packages/*/; do
name="${dir#packages/}"
name="${name%/}"
if [[ "$name" == "$CANDIDATE" || "${name//_/-}" == "$CANDIDATE" ]]; then
PACKAGE="$name"
break
fi
done
if [[ -z "$PACKAGE" ]]; then
echo "Error: tag '$TAG' does not map to a directory in packages/"
echo "Derived package name: '$CANDIDATE'"
echo "Available packages: $(ls packages/)"
exit 1
fi
echo "Resolved tag '$TAG' to package '$PACKAGE'"
fi
echo "PACKAGE=$PACKAGE" >> "$GITHUB_ENV"
- name: Check version
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: |
echo "Building and uploading Python release: $TAG_NAME"
if [[ "$PACKAGE" == "all" ]]; then
echo "Build scope: all workspace packages and the root meta package"
else
echo "Build scope: packages/$PACKAGE"
fi
- name: Build the package
run: |
set -euo pipefail
if [[ "$PACKAGE" == "all" ]]; then
uv run poe build
else
uv run poe --directory "packages/$PACKAGE" build
fi
- name: Release
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
with:
files: |
python/dist/*