Skip to content

ci(release): TestPyPI via Trusted Publishing (OIDC), drop TEST_PYPI_TOKEN#295

Merged
fede-kamel merged 1 commit into
mainfrom
chore/testpypi-trusted-publishing
May 30, 2026
Merged

ci(release): TestPyPI via Trusted Publishing (OIDC), drop TEST_PYPI_TOKEN#295
fede-kamel merged 1 commit into
mainfrom
chore/testpypi-trusted-publishing

Conversation

@fede-kamel
Copy link
Copy Markdown
Contributor

Problem

Every release logged this from the test-pypi-publish job:

403 Invalid or non-existent authentication information.
HTTPError: 403 Forbidden from https://test.pypi.org/legacy/

It was only non-fatal because the job is continue-on-error. Root cause: the
TEST_PYPI_TOKEN secret is invalid/stale, and the prod PYPI_TOKEN can't be reused —
TestPyPI is a separate index with separate accounts/tokens.

Fix — Trusted Publishing (OIDC)

Best practice per PyPA/PyPI: stop using long-lived tokens. The TestPyPI step now uses
pypa/gh-action-pypi-publish (pinned to v1.14.0 /
cef221092ed1bacb1cc03d23a2d87d1d172e277b) with OIDC:

  • job requests id-token: write → a short-lived token scoped to repo + testpypi
    environment is minted per run; nothing to leak, expire, or rotate
  • skip-existing: true tolerates re-runs over an already-uploaded version
  • stays continue-on-error so a TestPyPI hiccup never blocks the prod publish
  • TEST_PYPI_TOKEN secret is no longer referenced (safe to delete from the testpypi
    environment)

⚠️ One-time setup required (test.pypi.org)

Before the next release, register a Trusted Publisher (Account → Publishing → "Add a
pending publisher"):

field value
PyPI Project Name locus-sdk
Owner oracle-samples
Repository name locus
Workflow name _release.yml
Environment name testpypi

Until that's added, the step will still fail — but harmlessly (continue-on-error), exactly
as today.

Scope

Production PyPI publish is unchanged (still token-based and working). It can migrate to
OIDC as a follow-up once its trusted publisher is registered on pypi.org — deliberately not
done here to avoid any risk to a working release path.

…OKEN

The TestPyPI step authenticated with a long-lived TEST_PYPI_TOKEN secret that
is invalid/stale — every release logged `403 Invalid or non-existent
authentication information` from test.pypi.org (non-fatal only because the job
is continue-on-error). The prod PyPI token can't be reused: TestPyPI is a
separate index with separate accounts.

Switch the TestPyPI publish to PyPI Trusted Publishing (OIDC) via
pypa/gh-action-pypi-publish, pinned to v1.14.0. The job now requests
`id-token: write` and mints a short-lived, repo+environment-scoped token per
run — no secret to leak, expire, or rotate. `skip-existing: true` tolerates
re-runs; the step stays continue-on-error so a TestPyPI hiccup never blocks the
prod publish.

One-time setup required on test.pypi.org (Account → Publishing → add a pending
publisher): owner=oracle-samples, repo=locus, workflow=_release.yml,
environment=testpypi. The prod PyPI publish job is unchanged (still token-based)
and can migrate to OIDC as a follow-up once its trusted publisher is registered
on pypi.org.

Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label May 30, 2026
@fede-kamel fede-kamel merged commit 428d845 into main May 30, 2026
10 checks passed
@fede-kamel fede-kamel deleted the chore/testpypi-trusted-publishing branch May 30, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant