Skip to content

ci(release): token auth + idempotent publish, fix the red pypi deployment (#564)#567

Merged
MartinCastroAlvarez merged 1 commit into
mainfrom
chore/release-workflow-token-fallback
May 28, 2026
Merged

ci(release): token auth + idempotent publish, fix the red pypi deployment (#564)#567
MartinCastroAlvarez merged 1 commit into
mainfrom
chore/release-workflow-token-fallback

Conversation

@MartinCastroAlvarez
Copy link
Copy Markdown
Owner

Problem

The repo's Deployments widget shows the `pypi` environment as failed even though django-admin-react 1.0.0 and 1.0.1 are both live on PyPI:

  • The current `release.yml` only authenticates via OIDC Trusted Publishing.
  • PyPI doesn't yet have a Trusted Publisher configured for this repo (one-time owner step tracked in Publish v1.0.0 to PyPI — one-time owner OIDC setup blocks the release workflow #564).
  • Every `release: published` event therefore fires a deployment that fails at the upload step with `invalid-publisher`, then paints the widget red — even though I publish manually via `set -a; . ./.env; set +a && poetry publish`.

Change

Switch `release.yml` to token-based auth (the same path the maintainer uses locally) and make the publish step idempotent:

  1. Token auth. Use `pypa/gh-action-pypi-publish`'s `password:` input with `secrets.PYPI_API_TOKEN`. Drop the `id-token: write` permission (token auth doesn't need OIDC).
  2. Idempotency guard. Before uploading, query `pypi.org/pypi///json`. If the version is already on PyPI (manual publish already shipped it, or a previous workflow run partly succeeded), skip the upload and let the job — and the deployment — finish green. Defense-in-depth: `skip-existing: true` on the publish step still handles a race past the guard.
  3. TestPyPI mirror gets the same treatment via `TESTPYPI_API_TOKEN` (only used for `workflow_dispatch` dry runs).

Trusted Publishing remains the longer-term goal — when #564 is finally configured on PyPI's side we can revert to the OIDC variant in a single commit. This patch unblocks today.

One-time owner step

After merge, add the PyPI token to repo secrets so the workflow can actually upload:

  1. `./.env` → copy the value of `POETRY_PYPI_TOKEN_PYPI` (the `pypi-...` string).
  2. Repo Settings → Secrets and variables → Actions → New repository secret
    • Name: `PYPI_API_TOKEN`
    • Value: the token from step 1
  3. (Optional) same flow for `TESTPYPI_API_TOKEN` if you want green TestPyPI dry runs.

Once the secret is present, every future `v*` Release tag will:

  • Build wheel + sdist
  • Either upload to PyPI (if not already there) or skip (if you published manually first)
  • Mark the `pypi` Deployment green either way

Re-running for v1.0.1

After merging + adding the secret, you can also re-trigger the v1.0.1 deployment by re-running the failed Actions run (Actions → "release" → the v1.0.1 run → Re-run all jobs). The idempotency guard will detect 1.0.1 is already on PyPI, skip the upload, and the deployment will go green — same Release tag, no new artifact.

Diff

  • `.github/workflows/release.yml` — 79 +/-22

🤖 Generated with Claude Code

The OIDC Trusted Publisher path needs a one-time PyPI configuration that
hasn't yet been performed (per #564); meanwhile every release fires a
deployment to the `pypi` environment that fails with `invalid-publisher`,
so the repo widget paints red even when v1.0.x is actually live on PyPI.

Switch the workflow to the maintainer's working path — the same token in
`./.env` (`POETRY_PYPI_TOKEN_PYPI`) stored as `PYPI_API_TOKEN` in repo
secrets — and add an idempotency guard so the job is also a no-op (still
green) when the version has already been published manually.

- Token-based auth via `pypa/gh-action-pypi-publish` `password:` input.
  No `id-token: write` permission needed any more.
- `Is this version already on PyPI?` step queries
  `pypi.org/pypi/<pkg>/<version>/json`; if the version is already live the
  upload step is skipped. Defense-in-depth: `skip-existing: true` on the
  publish step still handles a race past the guard.
- Header rewritten: owner-setup section now documents the
  `PYPI_API_TOKEN` repo-secret requirement (one-time copy from `.env`).
- TestPyPI mirror gets the same treatment via `TESTPYPI_API_TOKEN`.

Trusted Publishing remains the longer-term goal (#564) — when the PyPI
Trusted Publisher is finally configured we can revert to the OIDC variant
in a single commit. Until then, this gets the deployment widget green on
every tag and ends the manual-only release path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MartinCastroAlvarez MartinCastroAlvarez merged commit efcac54 into main May 28, 2026
5 checks passed
@MartinCastroAlvarez MartinCastroAlvarez deleted the chore/release-workflow-token-fallback branch May 28, 2026 15:37
MartinCastroAlvarez added a commit that referenced this pull request May 28, 2026
Reverts the auth change from #567 (back to OIDC Trusted Publishing) while keeping the idempotency guard that actually fixes the red Deployments widget. No GitHub Secret needed; no long-lived token stored anywhere.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants