From: Yuri Weinstein Date: Tue, 21 Jul 2026 16:50:21 +0000 (-0700) Subject: script/ptl-tool: fail fast and cleanly on invalid Redmine/GitHub credentials X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8bb99f9aeea175d43e997054095d991797bac07f;p=ceph.git script/ptl-tool: fail fast and cleanly on invalid Redmine/GitHub credentials Invalid credentials were handled inconsistently: - A missing GitHub/Redmine token was caught with a clear error at startup, but an invalid or expired one was not: the Redmine client is constructed lazily by python-redmine, so a bad ~/.redmine_key was never actually exercised until manage_qa_tracker() called R.project.get() -- which runs *after* PRs have been merged and the integration branch/tag has already been pushed to ceph-ci. The result was an unhandled traceback well after real side effects had already happened, with no actionable message. - post_consolidated_review() posted the consolidated audit review to GitHub without checking the response status at all, so a bad or under-scoped token would fail silently there while every other GitHub write call in the file already checks status_code. Fix both: - Immediately after constructing the Redmine client, make a cheap R.user.get('current') call and catch AuthError/ForbiddenError, exiting with a clear message before any merging or pushing happens. - Check the response status in post_consolidated_review() and log an error on failure, matching the pattern already used by the other GitHub POST call sites in this file. Verified with py_compile plus live --dry-run runs against tracker.ceph.com: a deliberately invalid PTL_TOOL_REDMINE_API_KEY now exits 1 immediately with a clear message and no git side effects, while a valid key proceeds exactly as before. Signed-off-by: Yuri Weinstein --- diff --git a/src/script/ptl-tool.py b/src/script/ptl-tool.py index 7b54dbe63f9f..d2afee6a6479 100755 --- a/src/script/ptl-tool.py +++ b/src/script/ptl-tool.py @@ -356,7 +356,11 @@ class AuditReport: payload['event'] = 'COMMENT' endpoint = f"https://api.github.com/repos/{BASE_PROJECT}/{BASE_REPO}/pulls/{pr}/reviews" - session.post(endpoint, auth=GithubBearerAuth(), json=payload) + r = session.post(endpoint, auth=GithubBearerAuth(), json=payload) + if r.status_code in (200, 201): + log.info(f"Successfully posted consolidated review to PR #{pr}") + else: + log.error(f"Failed to post consolidated review to PR #{pr}: {r.status_code} {r.text}") class GithubBearerAuth(requests.auth.AuthBase): def __call__(self, r): @@ -1954,6 +1958,14 @@ def build_branch(args): if args.create_qa or args.update_qa or args.audit or args.final_merge or args.qe_label: log.info("connecting to %s", REDMINE_ENDPOINT) R = Redmine(REDMINE_ENDPOINT, username=REDMINE_USER, key=REDMINE_API_KEY) + try: + R.user.get('current') + except (redminelib.exceptions.AuthError, redminelib.exceptions.ForbiddenError) as e: + raise SystemExit( + f"Redmine authentication failed against {REDMINE_ENDPOINT}: {e}\n" + "Check that ~/.redmine_key (or PTL_TOOL_REDMINE_API_KEY) contains a valid, " + "unexpired API key. Failing now, before any PRs are merged or branches pushed." + ) log.debug("connected") prs = args.prs