ci: classic auth via group-scoped TWINE_USERNAME/TWINE_PASSWORD, v0.1.4
Trusted Publishing OIDC is blocked for git.unturf.com — PyPI's GitLab
provider hardcodes the issuer to gitlab.com (no self-hosted instance
field in the Add publisher form). Until PyPI lights up self-hosted
GitLab support, classic API token auth is our path.
Auth source: TWINE_USERNAME=__token__ + TWINE_PASSWORD=<pypi-...> set
as group-level CI variables on python/. Both python/ago and
python/erldistpy inherit them automatically; engineering/ group gets
the same vars for make-post-sell + remarkbox.
What this commit changes:
- .gitlab-ci.yml pypi-twine stage drops the id_tokens block we
briefly tried (OIDC), uses latest twine (no <6 pin) — twine 6
reads TWINE_USERNAME/TWINE_PASSWORD env vars and prefers them
over the OIDC attempt
- pyproject.toml build-system requires drops the setuptools<77
cap (latest setuptools emits Metadata-Version 2.4 which twine 6
reads fine; locally verified)
- docs/PYPI-TRUSTED-PUBLISHING.md updated to note the issuer-
hardcoded blocker and the recipe to migrate later when it
unblocks (or if we mirror to gitlab.com)
This commit is contained in:
parent
049666b061
commit
dee08976ef
2 changed files with 25 additions and 18 deletions
|
|
@ -25,22 +25,20 @@ test:
|
|||
# ---------------------------------------------------------------------------
|
||||
# Ship to PyPI on tag pushes.
|
||||
#
|
||||
# Tag the commit (``git tag -a v0.0.1 -m 'release'`` then
|
||||
# ``git push --tags``) and CI builds sdist + wheel and uploads with
|
||||
# twine. Credentials come from GitLab CI variables ``TWINE_USERNAME``
|
||||
# (typically ``__token__``) and ``TWINE_PASSWORD`` (the PyPI API token).
|
||||
# Auth: TWINE_USERNAME + TWINE_PASSWORD env vars come from project-scoped
|
||||
# GitLab CI variables (Settings → CI/CD → Variables, masked + protected).
|
||||
# Standard values: TWINE_USERNAME=__token__ and TWINE_PASSWORD=<pypi-...>.
|
||||
#
|
||||
# Trusted Publishing OIDC would be cleaner but PyPI's GitLab provider is
|
||||
# hardcoded to gitlab.com — git.unturf.com self-hosted isn't supported.
|
||||
# See docs/PYPI-TRUSTED-PUBLISHING.md for the migration recipe whenever
|
||||
# PyPI adds custom-issuer support (or whenever we mirror to gitlab.com).
|
||||
# ---------------------------------------------------------------------------
|
||||
pypi-twine:
|
||||
stage: pypi-twine
|
||||
tags: ["build"]
|
||||
only:
|
||||
- tags
|
||||
# GitLab mints a short-lived OIDC ID token (audience=pypi) and injects
|
||||
# it as PYPI_ID_TOKEN. Twine v6+ auto-detects it and exchanges it with
|
||||
# PyPI for a scoped upload token. No long-lived secret on the runner.
|
||||
id_tokens:
|
||||
PYPI_ID_TOKEN:
|
||||
aud: pypi
|
||||
script:
|
||||
- python3 -m venv .venv
|
||||
- . .venv/bin/activate
|
||||
|
|
|
|||
|
|
@ -1,15 +1,24 @@
|
|||
# Migrating to PyPI Trusted Publishing (OIDC)
|
||||
|
||||
Today's auth path: classic API token in `/home/gitlab-runner/.pypirc`
|
||||
on `build.unturf.com`, used by twine 5.x. Works, but every project that
|
||||
ships from this runner shares one token, rotation is manual, and we're
|
||||
pinning `twine<6` + `setuptools<77` to keep the legacy fallback alive.
|
||||
**Status: BLOCKED for self-hosted git.unturf.com**
|
||||
|
||||
Trusted Publishing replaces that with short-lived OIDC tokens that
|
||||
GitLab mints per-job and PyPI exchanges for an upload-only API token.
|
||||
No long-lived secret on the runner. Per-project, audited per-pipeline.
|
||||
PyPI's GitLab Trusted Publisher provider has the issuer URL **hardcoded
|
||||
to `https://gitlab.com`**. There's no "Issuer URL" / "GitLab instance"
|
||||
field in the "Add publisher" form. Until PyPI ships support for custom
|
||||
GitLab issuers (or we mirror releases to gitlab.com), Trusted
|
||||
Publishing is off the table for our python/* repos.
|
||||
|
||||
## When to migrate
|
||||
Today's working auth path: project-scoped GitLab CI variables
|
||||
``TWINE_USERNAME=__token__`` + ``TWINE_PASSWORD=<pypi-...>`` (masked +
|
||||
protected). Twine 6 reads them as env vars and skips the OIDC attempt.
|
||||
Per-project tokens; can be rotated independently.
|
||||
|
||||
When PyPI lights up self-hosted GitLab support (track:
|
||||
https://github.com/pypi/warehouse/issues — search "self-hosted gitlab
|
||||
trusted publisher"), or if we move to gitlab.com, the recipe below
|
||||
applies.
|
||||
|
||||
## When to migrate (once unblocked)
|
||||
|
||||
Single coordinated change across all four python/* repos. Each repo
|
||||
needs its PyPI pending publisher set up *before* its CI YAML switches.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue