Step-by-step guide to publishing Readability.German to nuget.org. Written for a first-time
publisher — follow it top to bottom.
Publishing is automated via GitHub Actions using Trusted Publishing (OIDC): no long-lived API
key is generated or stored anywhere. The workflow requests a short-lived (1-hour) credential from
nuget.org at push time, using GitHub's identity as proof. There's a manual dotnet nuget push
fallback at the bottom for emergencies.
- Sign in (or create an account) at nuget.org.
- Make sure two-factor authentication is enabled — nuget.org requires it to publish.
Trusted Publishing policies are tied to a specific GitHub repo, so the repo has to exist first:
git push -u origin main(Target: https://github.com/taskinkemal/Readability.German, already created and empty.)
Do this after the repo above is pushed, and after .github/workflows/release.yml exists
in it (the policy references the workflow file by name).
- Sign in to nuget.org → click your username (top right) → Trusted Publishing.
- Click Add a new policy (or "Add federated credential").
- Fill in:
- Repository Owner:
taskinkemal - Repository:
Readability.German - Workflow File:
release.yml— the file name only, not.github/workflows/release.yml. - Environment: leave blank (the release workflow doesn't use a GitHub Actions
environment:gate).
- Repository Owner:
- Save.
The policy starts in a 7-day provisional state — this is a nuget.org anti-resurrection-attack safeguard for repos it hasn't seen a successful publish from yet. It becomes permanent automatically the first time the workflow successfully publishes. If 7 days pass with no publish, the provisional window just needs restarting (same page) — nothing is lost.
No API key, no GitHub secret, nothing to rotate. That's the entire one-time setup.
The tag is the single source of truth for the version number.
-
Update
Version(andAssemblyVersion/FileVersion/InformationalVersionper §7.1 of REQUIREMENTS.md —AssemblyVersionstays<major>.0.0.0) insrc/Readability.German/Readability.German.csprojif this is a new version, and note the change in your commit if there's a CHANGELOG. -
Commit and push to
main. -
Tag the release and push the tag:
git tag v1.0.0 git push origin v1.0.0
-
Pushing a tag matching
v*.*.*triggers.github/workflows/release.yml, which:- builds and runs the full test suite (the release fails closed — if tests fail, nothing is published);
- runs
dotnet pack -c Release; - requests a short-lived nuget.org API key via OIDC (
NuGet/login); - runs
dotnet nuget pushwith--skip-duplicate; - attaches the
.nupkg/.snupkgto a GitHub Release.
-
Watch the Actions tab on GitHub until the workflow finishes. Once it's green, confirm the new version appears at nuget.org/packages/Readability.German (indexing can take a few minutes).
A version published to nuget.org can never be replaced or overwritten — only unlisted. Before
tagging v1.0.0, rehearse the entire flow with a preview version so a mistake doesn't burn the
real version number:
git tag v1.0.0-preview.1
git push origin v1.0.0-preview.1Confirm the workflow goes green end-to-end and the preview package looks right on nuget.org (run
through the scratch-app smoke test in REQUIREMENTS.md §12 — install the preview package into a new
dotnet new console app and call GermanReadability.Analyze on a sample paragraph). Only tag
v1.0.0 once that's clean.
If GitHub Actions is unavailable and you need to publish directly from your machine, Trusted Publishing is CI-only (it relies on GitHub issuing the OIDC token) — you can't use it from a local shell. Instead, generate a temporary, narrowly-scoped classic API key for one-off use:
-
nuget.org → username → API Keys → Create.
-
Scope it to push new packages and package versions, glob pattern
Readability.German*, with the shortest expiry nuget.org allows (a day is enough). -
Pack and push locally:
dotnet pack -c Release -o ./artifacts dotnet nuget push ./artifacts/*.nupkg --api-key <the-temporary-key> --source https://api.nuget.org/v3/index.json --skip-duplicate
-
Delete the API key from nuget.org immediately after use. Don't let it linger — the whole point of Trusted Publishing is to not have standing credentials.