From 3ff6b22047c2c98d0a6e2e0bd78ae08938e876d4 Mon Sep 17 00:00:00 2001 From: Xavier Challe Date: Thu, 28 May 2026 16:37:32 +0200 Subject: [PATCH] ci(release): publish to public PyPI through JFrog OIDC only Stop using the long-lived PYPI_PUBLIC_API_TOKEN secret and stop the parallel push to `vault-pypi-prod-green`. Releases now go to a single destination: `vault-pypi-prod-public` via JFrog OIDC. JFrog forwards them to public PyPI through the `pypi-ledgerhq` push integration configured in the cybersec PyPI webhook (cybersec-pypi-prd). Why single-push (and not dual-push to prod-green + prod-public): - All local repos have `priority_resolution = true` and JFrog resolves repos in alphabetical order inside `virtual-pypi-prod-green`, so `vault-pypi-prod-green` sits in front of `vault-pypi-prod-public`. As soon as a package name exists in `prod-green`, JFrog stops there and never inspects `prod-public`, no matter what newer versions live there. Dual-push turns any partial failure or asymmetric cleanup into a silent split-brain: PyPI public serves the new version while internal consumers via the virtual continue to see the old one. - The vault project's `virtual-pypi-prod-green` already aggregates `vault-pypi-prod-public`, so internal consumers keep installing through the same virtual without changing anything. - Single source of truth per package, no atomicity issue between two publish steps, no storage duplication, and DELETE is never needed (consistent with the AGENTS.md DELETE policy on CI/CD bindings). Why removing the PyPI secret: - Removes a high-value, long-lived secret from this repository. - Centralizes publishing on JFrog OIDC, consistent with the other Ledger libraries publishing under the cybersec PyPI webhook. Migration note (before this lands): - Past releases pushed `python-erc7730` artifacts into `vault-pypi-prod-green`. Those old versions will shadow any new release in `vault-pypi-prod-public` for internal consumers, because of Priority Resolution + alphabetical order. The legacy versions in `vault-pypi-prod-green` must be moved to (or republished into) `vault-pypi-prod-public`, or removed, before the first release on the new workflow. This is a one-time admin op on JFrog, not done by CI. Follow-up: - Once a release has been published successfully via this new path, the PYPI_PUBLIC_API_TOKEN secret can be removed from the repo. Co-authored-by: Cursor --- .github/workflows/release.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 192a81be..ef61b0aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,20 +41,14 @@ jobs: timeout-minutes: 10 run: pdm build - - name: Upload library artifacts to Ledger Artifactory repository + - name: Publish library artifacts to public PyPI via Ledger Artifactory timeout-minutes: 10 env: - PDM_PUBLISH_REPO: https://jfrog.ledgerlabs.net/artifactory/api/pypi/vault-pypi-prod-green + PDM_PUBLISH_REPO: https://jfrog.ledgerlabs.net/artifactory/api/pypi/vault-pypi-prod-public PDM_PUBLISH_USERNAME: ${{ steps.jfrog-login.outputs.oidc-user }} PDM_PUBLISH_PASSWORD: ${{ steps.jfrog-login.outputs.oidc-token }} run: pdm publish --no-build - - name: Upload library artifacts to PyPI - timeout-minutes: 10 - env: - PDM_PUBLISH_PASSWORD: ${{ secrets.PYPI_PUBLIC_API_TOKEN }} - run: pdm publish --no-build - - name: Generate library build attestations timeout-minutes: 10 uses: LedgerHQ/actions-security/actions/attest@actions/attest-1