Skip to content

Commit 3e5482b

Browse files
authored
fix: support core metadata 2.5 publishing (#4452)
## Summary - refresh Python package publishing tooling - validate distribution artifacts before upload - support retrying publication from an existing published release tag - advance the package version and changelog ## Validation - workflow linting - version and lockfile checks - package build and metadata validation (authored by codex)
1 parent 94e0204 commit 3e5482b

5 files changed

Lines changed: 55 additions & 19 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ on:
44
release:
55
types:
66
- published
7+
workflow_dispatch:
8+
inputs:
9+
tag:
10+
description: Published release tag whose failed package upload should be retried
11+
required: true
12+
type: string
713

814
permissions:
915
contents: read
@@ -21,10 +27,25 @@ jobs:
2127
# Skip opencv wheel releases (tagged 'opencv-*') produced by the
2228
# build-opencv-wheels workflow - those aren't package releases and would
2329
# otherwise trigger a spurious PyPI publish failure.
24-
if: ${{ !startsWith(github.event.release.tag_name, 'opencv-') }}
30+
if: ${{ !startsWith(inputs.tag || github.event.release.tag_name, 'opencv-') }}
2531
runs-on: ubuntu-latest
2632
steps:
33+
- name: Validate manual release tag
34+
if: github.event_name == 'workflow_dispatch'
35+
env:
36+
GH_TOKEN: ${{ github.token }}
37+
TAG: ${{ inputs.tag }}
38+
run: |
39+
PUBLISHED_TAG=$(gh api "repos/${GITHUB_REPOSITORY}/releases/tags/${TAG}" \
40+
--jq 'select(.draft == false) | .tag_name')
41+
if [[ "$PUBLISHED_TAG" != "$TAG" ]]; then
42+
echo "Tag '$TAG' does not identify a published GitHub release"
43+
exit 1
44+
fi
45+
2746
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
47+
with:
48+
ref: refs/tags/${{ inputs.tag || github.event.release.tag_name }}
2849

2950
- name: Install uv
3051
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
@@ -34,12 +55,9 @@ jobs:
3455
- name: Set up Python
3556
run: uv python install
3657

37-
- name: Install dependencies
38-
run: uv sync --locked --only-group release --no-install-project
39-
4058
- name: Validate version matches release tag
4159
env:
42-
TAG: ${{ github.event.release.tag_name }}
60+
TAG: ${{ inputs.tag || github.event.release.tag_name }}
4361
run: |
4462
PKG_VERSION=$(uv run --script - <<'PYEOF'
4563
# /// script
@@ -59,12 +77,21 @@ jobs:
5977
id: build
6078
run: uv build
6179

80+
- name: Validate artifact
81+
id: validate
82+
run: uvx --from twine==7.0.0 twine check dist/*
83+
6284
- name: Publish package
63-
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
85+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
86+
with:
87+
skip-existing: ${{ github.event_name == 'workflow_dispatch' }}
6488

65-
# Best-effort: attempt Azure upload even if PyPI fails, but only if build succeeded.
89+
# Best-effort: attempt Azure upload even if PyPI fails, but only for a valid artifact.
6690
- name: Create .pypirc for Azure Artifacts
67-
if: always() && steps.build.outcome == 'success'
91+
if: >-
92+
always() &&
93+
steps.build.outcome == 'success' &&
94+
steps.validate.outcome == 'success'
6895
run: |
6996
cat <<EOF > ~/.pypirc
7097
[distutils]
@@ -78,10 +105,13 @@ jobs:
78105
EOF
79106
80107
- name: Publish package to Azure Artifacts
81-
if: always() && steps.build.outcome == 'success'
108+
if: >-
109+
always() &&
110+
steps.build.outcome == 'success' &&
111+
steps.validate.outcome == 'success'
82112
run: |
83113
EXIT_CODE=0
84-
uv run --no-sync twine upload -r azure dist/* || EXIT_CODE=$?
114+
uvx --from twine==7.0.0 twine upload -r azure dist/* || EXIT_CODE=$?
85115
if [[ $EXIT_CODE -eq 0 ]]; then
86116
echo "Successfully published to Azure Artifacts (or already existed)"
87117
else

‎CHANGELOG.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 0.27.1
2+
3+
### Fixes
4+
5+
- **Support Core Metadata 2.5 package publishing**: Upgrade the PyPI publishing action and Twine release tooling so artifacts produced by Hatchling 1.32 and later pass metadata validation. Release workflows now validate artifacts before upload and can safely retry a failed upload from an existing published GitHub release tag without moving or recreating that tag.
6+
17
## 0.27.0
28

39
### Enhancements

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ lint = [
188188
"ruff>=0.15.0, <1.0.0",
189189
]
190190
release = [
191-
"twine>=6.0.0, <7.0.0",
191+
"twine>=7.0.0, <8.0.0",
192192
]
193193

194194
[tool.uv]

‎unstructured/__version__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.27.0" # pragma: no cover
1+
__version__ = "0.27.1" # pragma: no cover

‎uv.lock‎

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)