REST API for managing trusted publishers#19909
Open
thatch wants to merge 2 commits into
Open
Conversation
Add POST/GET/DELETE endpoints under /danger-api/projects/{name}/trusted-publishers
authenticated by a project-owner API token (macaroon), supporting all four
providers: GitHub, GitLab, Google, and ActiveState.
Also adds bin/configure-trusted-publisher, a standalone CLI that reads credentials
from ~/.pypirc like twine, auto-detects the provider and repo from the current git
checkout, and lets you select a workflow file interactively.
Closes pypi#14456
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s, hide token in dry-run - Try "upstream" remote before falling back to "origin" - Add -n as an alias for --dry-run - Replace the real token with <YOUR-API-TOKEN> in dry-run curl output; add --show-token flag (with a warning in the help text) to opt back in Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jaraco
approved these changes
May 18, 2026
Contributor
jaraco
left a comment
There was a problem hiding this comment.
Looks good to me. I'm fairly confident this will have the intended effect of making it possible to bulk enable trusted publishing across any number of repos.
Comment on lines
+69
to
+88
| def _resolve_token(args: argparse.Namespace) -> str: | ||
| """Resolve API token from CLI arg, env var, or .pypirc.""" | ||
| if args.token: | ||
| return args.token | ||
|
|
||
| token = os.environ.get("PYPI_TOKEN") | ||
| if token: | ||
| return token | ||
|
|
||
| config = _read_pypirc(getattr(args, "config_file", None), args.repository) | ||
| token = config.get("password") | ||
| if token: | ||
| return token | ||
|
|
||
| print( | ||
| "Error: No API token found.\n" | ||
| "Provide via --token, PYPI_TOKEN env var, or ~/.pypirc [pypi] password field.", | ||
| file=sys.stderr, | ||
| ) | ||
| sys.exit(1) |
Contributor
There was a problem hiding this comment.
I keep my token safely stored encrypted using keyring (here's how twine does it). Ideally, this script would provide that as an option (or maybe I just pass in --token $(keyring get ...)).
Author
There was a problem hiding this comment.
My hope is that this script either becomes part of twine, or its own project, and we can sort that out there. It's a demo here because without an api client it's kind of hard to show that it works :)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add POST/GET/DELETE endpoints under /danger-api/projects/{name}/trusted-publishers
authenticated by a project-owner API token (macaroon), supporting all four
providers: GitHub, GitLab, Google, and ActiveState.
Also adds bin/configure-trusted-publisher, a standalone CLI that reads credentials
from ~/.pypirc like twine, auto-detects the provider and repo from the current git
checkout, and lets you select a workflow file interactively.
Closes #14456
The configure-trusted-publisher script should go into its own project (but that should be owned by pypa, not me). Comments welcome on whether this is "danger-api"-worthy. I'll test manually more once the basic idea is validated.