Skip to content

Commit 45c9567

Browse files
author
yangxk1
committed
fix(CI): replace pypa/gh-action-pypi-publish with inline twine upload
The pypa/gh-action-pypi-publish action is blocked by Apache org's action allowlist policy. Replace it with inline shell steps that use PyPI's trusted publisher OIDC flow directly: mint a short-lived API token via the OIDC endpoint and upload with twine. The id-token: write permission is preserved so GitHub Actions still injects the OIDC credentials needed for the trusted publisher exchange.
1 parent da85682 commit 45c9567

1 file changed

Lines changed: 54 additions & 7 deletions

File tree

.github/workflows/python-wheel-workflow.yml

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,35 @@ jobs:
273273
run: |
274274
mkdir -p python/dist
275275
find dist -name "*" -type f -exec mv {} python/dist/ \;
276-
- name: Publish to Test PyPI
277-
uses: pypa/gh-action-pypi-publish@release/v1
276+
- name: Set up Python
277+
uses: actions/setup-python@v5
278278
with:
279-
repository-url: https://test.pypi.org/legacy/
280-
packages-dir: python/dist/
279+
python-version: "3.x"
280+
281+
- name: Publish to Test PyPI
282+
run: |
283+
set -euo pipefail
284+
pip install twine
285+
286+
# Mint a short-lived API token via PyPI Trusted Publisher (OIDC)
287+
OIDC_TOKEN=$(curl -sS \
288+
-H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
289+
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=testpypi" \
290+
| python3 -c "import sys, json; print(json.load(sys.stdin)['value'])")
291+
292+
PYPI_TOKEN=$(curl -sS -X POST \
293+
https://test.pypi.org/_/oidc/mint-token \
294+
-H "Content-Type: application/json" \
295+
-d "{\"token\": \"${OIDC_TOKEN}\"}" \
296+
| python3 -c "import sys, json; print(json.load(sys.stdin)['token'])")
297+
echo "::add-mask::${PYPI_TOKEN}"
298+
299+
twine upload \
300+
--repository-url https://test.pypi.org/legacy/ \
301+
--username __token__ \
302+
--password "${PYPI_TOKEN}" \
303+
--skip-existing \
304+
python/dist/*
281305
282306
upload_pypi:
283307
name: Publish (manual)
@@ -297,7 +321,30 @@ jobs:
297321
run: |
298322
mkdir -p python/dist
299323
find dist -name "*" -type f -exec mv {} python/dist/ \;
300-
- name: Publish to PyPI
301-
uses: pypa/gh-action-pypi-publish@release/2473ec6c6aa87f38946284d51289219fd0b87264
324+
- name: Set up Python
325+
uses: actions/setup-python@v5
302326
with:
303-
packages-dir: python/dist/
327+
python-version: "3.x"
328+
329+
- name: Publish to PyPI
330+
run: |
331+
set -euo pipefail
332+
pip install twine
333+
334+
# Mint a short-lived API token via PyPI Trusted Publisher (OIDC)
335+
OIDC_TOKEN=$(curl -sS \
336+
-H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
337+
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=pypi" \
338+
| python3 -c "import sys, json; print(json.load(sys.stdin)['value'])")
339+
340+
PYPI_TOKEN=$(curl -sS -X POST \
341+
https://pypi.org/_/oidc/mint-token \
342+
-H "Content-Type: application/json" \
343+
-d "{\"token\": \"${OIDC_TOKEN}\"}" \
344+
| python3 -c "import sys, json; print(json.load(sys.stdin)['token'])")
345+
echo "::add-mask::${PYPI_TOKEN}"
346+
347+
twine upload \
348+
--username __token__ \
349+
--password "${PYPI_TOKEN}" \
350+
python/dist/*

0 commit comments

Comments
 (0)