diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 60e28b9..8117c15 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -140,11 +140,15 @@ jobs: # Requires a trusted publishing policy on nuget.org (owner Reefact / repo first-class-errors / # workflow release.yml) for each published package, and the NUGET_USER secret set to the nuget.org # account username (profile name, not the email address). - # Everything from here on PUBLISHES and is skipped on a dry run. A tag push always publishes - # (inputs.* is empty on push events, so the event check short-circuits first); a manual dispatch - # publishes only with dry_run explicitly unticked. + # + # This login runs on EVERY trigger, INCLUDING a dry run: the OIDC token exchange is what validates the + # trusted-publishing policy, so rehearsing it here makes a dry run fail red when the policy or + # NUGET_USER is missing/misconfigured — instead of only ever finding out during a real release. It + # mints a short-lived, single-use key that a dry run never spends (the push below is skipped). Only the + # steps that actually PUBLISH — the push and the GitHub Release — are gated off on a dry run: a tag + # push always publishes (inputs.* is empty on push, so the event check short-circuits first); a manual + # dispatch publishes only with dry_run explicitly unticked. - name: NuGet login (OIDC) - if: github.event_name == 'push' || inputs.dry_run == false id: nuget-login uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1 with: diff --git a/maintainers/ReleaseDryRun.en.md b/maintainers/ReleaseDryRun.en.md index 7b77185..79e0fa5 100644 --- a/maintainers/ReleaseDryRun.en.md +++ b/maintainers/ReleaseDryRun.en.md @@ -12,8 +12,9 @@ provenance attestation, and the publish steps — otherwise runs *for the first time in production, on a tag, once*. The **manual dry run** lets you run that same pipeline **on demand**, all the way -through the provenance attestation, **without publishing anything**. It is a -rehearsal: you confirm the release machinery is healthy before it matters. +through the provenance attestation and the NuGet OIDC login, **without publishing +anything**. It is a rehearsal: you confirm the release machinery is healthy +before it matters. ## What it does — and does not do @@ -25,7 +26,7 @@ rehearsal: you confirm the release machinery is healthy before it matters. | Embed the SPDX SBOM | ✅ | ✅ | | Upload packages as workflow artifacts | ✅ | ✅ | | **Sign the provenance attestation** | ✅ | ✅ (see *Impacts*) | -| Log in to NuGet (OIDC) | ✅ | ⛔ skipped | +| **Log in to NuGet (OIDC)** | ✅ | ✅ (see *Impacts*) | | **Push to nuget.org** | ✅ | ⛔ skipped | | **Create the GitHub Release** | ✅ | ⛔ skipped | @@ -51,7 +52,7 @@ healthy. ## Impacts -A dry run is *almost* free of side effects, with one exception to be aware of: +A dry run is *almost* free of side effects, with two things to be aware of: - **It creates a real provenance attestation.** The `Attest build provenance` step runs in a dry run (on purpose — OIDC and attestation-permission failures @@ -63,6 +64,12 @@ A dry run is *almost* free of side effects, with one exception to be aware of: never mistaken for a real release; - run the manual dry run deliberately (before a real release, or after changing `release.yml`), not casually in a loop. +- **It performs the real NuGet OIDC login.** The trusted-publishing token + exchange runs in a dry run — that is the point: it validates the nuget.org + policy, so a dry run **fails red** if the trusted-publishing policy or the + `NUGET_USER` secret is missing or misconfigured. It mints a short-lived, + single-use API key that the dry run never spends (the push is skipped), so + nothing is published. - **Nothing is published.** No package reaches nuget.org, and no GitHub Release or git tag is created. - **The packed `.nupkg` / `.snupkg` are uploaded as workflow-run artifacts**, diff --git a/maintainers/ReleaseDryRun.fr.md b/maintainers/ReleaseDryRun.fr.md index 9850eda..bbbea78 100644 --- a/maintainers/ReleaseDryRun.fr.md +++ b/maintainers/ReleaseDryRun.fr.md @@ -13,9 +13,9 @@ ne tourne donc *pour la première fois qu'en production, sur un tag, une seule fois*. Le **dry run manuel** permet de lancer ce même pipeline **à la demande**, -jusqu'à l'attestation de provenance incluse, **sans rien publier**. C'est une -répétition : on vérifie que la machinerie de release est saine avant que ça ne -compte. +jusqu'à l'attestation de provenance et au login OIDC NuGet inclus, **sans rien +publier**. C'est une répétition : on vérifie que la machinerie de release est +saine avant que ça ne compte. ## Ce qu'il fait — et ne fait pas @@ -27,7 +27,7 @@ compte. | Embarquer le SBOM SPDX | ✅ | ✅ | | Uploader les packages en artefacts de run | ✅ | ✅ | | **Signer l'attestation de provenance** | ✅ | ✅ (voir *Impacts*) | -| Login NuGet (OIDC) | ✅ | ⛔ sauté | +| **Login NuGet (OIDC)** | ✅ | ✅ (voir *Impacts*) | | **Push vers nuget.org** | ✅ | ⛔ sauté | | **Créer la GitHub Release** | ✅ | ⛔ sauté | @@ -55,7 +55,7 @@ est sain. ## Impacts -Un dry run est *presque* sans effet de bord, avec une exception à connaître : +Un dry run est *presque* sans effet de bord, avec deux points à connaître : - **Il crée une vraie attestation de provenance.** L'étape `Attest build provenance` s'exécute pendant un dry run (volontairement — les échecs d'OIDC @@ -68,6 +68,12 @@ Un dry run est *presque* sans effet de bord, avec une exception à connaître : attestation jetable ne soit jamais confondue avec une vraie release ; - lance le dry run manuel de façon délibérée (avant une vraie release, ou après avoir modifié `release.yml`), pas en boucle par réflexe. +- **Il effectue le vrai login OIDC NuGet.** L'échange de jeton du trusted + publishing s'exécute pendant un dry run — c'est le but : il valide la policy + nuget.org, donc un dry run **échoue (rouge)** si la policy trusted-publishing + ou le secret `NUGET_USER` est absent ou mal configuré. Il génère une clé API + éphémère à usage unique que le dry run ne dépense jamais (le push est sauté), + donc rien n'est publié. - **Rien n'est publié.** Aucun package n'atteint nuget.org, et aucune GitHub Release ni aucun tag Git n'est créé. - **Les `.nupkg` / `.snupkg` produits sont uploadés en artefacts de run**, que