Add --token-from-gh authentication option

This commit is contained in:
Duncan Ogilvie
2026-04-26 13:42:14 +02:00
parent 4c1f21a306
commit f4117990b2
4 changed files with 121 additions and 4 deletions

View File

@@ -167,6 +167,12 @@ def parse_args(args=None):
dest="token_fine",
help="fine-grained personal access token (github_pat_....), or path to token (file://...)",
) # noqa
parser.add_argument(
"--token-from-gh",
action="store_true",
dest="token_from_gh",
help="read token from GitHub CLI (gh auth token)",
)
parser.add_argument(
"-q",
"--quiet",
@@ -537,8 +543,14 @@ def get_auth(args, encode=True, for_git_cli=False):
raise Exception(
"Fine-grained token supplied does not look like a GitHub PAT"
)
elif args.token_classic:
if args.token_classic.startswith(FILE_URI_PREFIX):
elif args.token_classic or args.token_from_gh:
if args.token_from_gh:
if args.as_app:
raise Exception(
"--token-from-gh cannot be used with --as-app; provide the app token with --token instead"
)
args.token_classic = read_token_from_gh_cli(args)
elif args.token_classic.startswith(FILE_URI_PREFIX):
args.token_classic = read_file_contents(args.token_classic)
if not args.as_app:
@@ -580,6 +592,38 @@ def read_file_contents(file_uri):
return open(file_uri[len(FILE_URI_PREFIX) :], "rt").readline().strip()
def read_token_from_gh_cli(args):
cached_token = getattr(args, "_token_from_gh_value", None)
if cached_token:
return cached_token
command = ["gh", "auth", "token"]
if args.github_host:
command.extend(["--hostname", get_github_host(args)])
try:
token = subprocess.check_output(command, stderr=subprocess.PIPE).decode(
"utf-8"
).strip()
except FileNotFoundError:
raise Exception(
"Unable to read token from GitHub CLI: 'gh' executable not found"
)
except subprocess.CalledProcessError as e:
stderr = e.stderr.decode("utf-8", errors="replace").strip()
if stderr:
raise Exception(
"Unable to read token from GitHub CLI: {0}".format(stderr)
)
raise Exception("Unable to read token from GitHub CLI")
if not token:
raise Exception("Unable to read token from GitHub CLI: token was empty")
args._token_from_gh_value = token
return token
def get_github_repo_url(args, repository):
if repository.get("is_gist"):
if args.prefer_ssh: