Skip to content

Commit 794f5bf

Browse files
potiukleeyspaul
authored andcommitted
Prefer gh auth over GitHub tokens for Breeze (#66255) (#67078)
* Breeze: Prefer gh auth over GitHub tokens * Respect dry run functionality * Add Breeze GitHub helper edge-case tests * Clarify Breeze GitHub token precedence * Simplify release management GitHub token resolution * Clarify GITHUB_TOKEN console print (cherry picked from commit 7fef6c1) Co-authored-by: Paul <leeyspaul@users.noreply.github.com>
1 parent 5988d58 commit 794f5bf

12 files changed

Lines changed: 291 additions & 64 deletions

dev/breeze/doc/images/output-commands.svg

Lines changed: 17 additions & 5 deletions
Loading
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
54d7d635ab887d0f556a9cebcab7f63f
1+
d4841617ec2b8d96643f6695adcb68d6
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
95bba676df9c9dccc5b0798fbc269f6e
1+
a35521c64446afe2657126bec1132254
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
a76fae2707fcab0cc46a68f1186c6a08
1+
ed465431e2702e05546a60b46dd16908

dev/breeze/src/airflow_breeze/commands/ci_commands.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
fix_ownership_using_docker,
5959
perform_environment_checks,
6060
)
61+
from airflow_breeze.utils.github import retrieve_github_token
6162
from airflow_breeze.utils.path_utils import AIRFLOW_HOME_PATH, AIRFLOW_ROOT_PATH
6263
from airflow_breeze.utils.run_utils import run_command
6364

@@ -776,16 +777,7 @@ def upgrade(
776777

777778
console_print("[info]Running upgrade of important CI environment.[/]")
778779

779-
# Resolve GitHub token: prefer --github-token / GITHUB_TOKEN env var, fall back to gh CLI
780-
if not github_token:
781-
gh_token_result = run_command(
782-
["gh", "auth", "token"],
783-
capture_output=True,
784-
text=True,
785-
check=False,
786-
)
787-
if gh_token_result.returncode == 0 and gh_token_result.stdout.strip():
788-
github_token = gh_token_result.stdout.strip()
780+
github_token = retrieve_github_token(github_token)
789781

790782
# Create a copy of the environment to pass to commands
791783
command_env = os.environ.copy()
@@ -795,7 +787,7 @@ def upgrade(
795787
console_print("[success]GitHub token set in environment.[/]")
796788
else:
797789
console_print(
798-
"[warning]Could not retrieve GitHub token from --github-token or gh CLI. "
790+
"[warning]Could not retrieve GitHub token from --github-token, gh CLI, or token env. "
799791
"Commands may fail if they require authentication.[/]"
800792
)
801793

dev/breeze/src/airflow_breeze/commands/issues_commands.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from airflow_breeze.utils.click_utils import BreezeGroup
3232
from airflow_breeze.utils.confirm import Answer, user_confirm
3333
from airflow_breeze.utils.console import console_print
34-
from airflow_breeze.utils.run_utils import run_command
34+
from airflow_breeze.utils.github import retrieve_github_token
3535
from airflow_breeze.utils.shared_options import get_dry_run
3636

3737

@@ -42,18 +42,7 @@ def issues_group():
4242

4343
def _resolve_github_token(github_token: str | None) -> str | None:
4444
"""Resolve GitHub token from option, environment, or gh CLI."""
45-
if github_token:
46-
return github_token
47-
gh_token_result = run_command(
48-
["gh", "auth", "token"],
49-
capture_output=True,
50-
text=True,
51-
check=False,
52-
dry_run_override=False,
53-
)
54-
if gh_token_result.returncode == 0:
55-
return gh_token_result.stdout.strip()
56-
return None
45+
return retrieve_github_token(github_token)
5746

5847

5948
def _get_collaborator_logins(repo) -> set[str]:

dev/breeze/src/airflow_breeze/commands/release_management_commands.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
fix_ownership_using_docker,
138138
perform_environment_checks,
139139
)
140+
from airflow_breeze.utils.github import retrieve_github_token
140141
from airflow_breeze.utils.helm_chart_utils import chart_version
141142
from airflow_breeze.utils.packages import (
142143
PackageSuspendedException,
@@ -2666,16 +2667,7 @@ class ProviderPRInfo(NamedTuple):
26662667
all_prs.update(prs)
26672668
provider_prs[provider_id] = filtered_prs
26682669
all_retrieved_prs.update(provider_prs[provider_id])
2669-
if not github_token:
2670-
# Get GitHub token from gh CLI and set it in environment copy
2671-
gh_token_result = run_command(
2672-
["gh", "auth", "token"],
2673-
capture_output=True,
2674-
text=True,
2675-
check=False,
2676-
)
2677-
if gh_token_result.returncode == 0:
2678-
github_token = gh_token_result.stdout.strip()
2670+
github_token = retrieve_github_token(github_token)
26792671
g = Github(github_token)
26802672
repo = g.get_repo("apache/airflow")
26812673
pull_requests: dict[int, PullRequest.PullRequest | Issue.Issue] = {}
@@ -4164,6 +4156,7 @@ def generate_issue_content(
41644156
excluded_prs = []
41654157
prs = [pr for pr in change_prs if pr is not None and pr not in excluded_prs]
41664158

4159+
github_token = retrieve_github_token(github_token) or ""
41674160
g = Github(github_token)
41684161
repo = g.get_repo("apache/airflow")
41694162
pull_requests: dict[int, PullRequestOrIssue] = {}

dev/breeze/src/airflow_breeze/commands/workflow_commands.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from airflow_breeze.utils.console import console_print
2929
from airflow_breeze.utils.custom_param_types import BetterChoice
3030
from airflow_breeze.utils.gh_workflow_utils import trigger_workflow_and_monitor
31-
from airflow_breeze.utils.run_utils import run_command
31+
from airflow_breeze.utils.github import run_gh_command
3232

3333
WORKFLOW_NAME_MAPS = {
3434
"publish-docs": "publish-docs-to-s3.yml",
@@ -127,24 +127,18 @@ def workflow_run_publish(
127127
)
128128
sys.exit(1)
129129
if os.environ.get("GITHUB_TOKEN", ""):
130-
console_print("\n[warning]Your authentication will use GITHUB_TOKEN environment variable.")
131130
console_print(
132-
"\nThis might not be what you want unless your token has "
133-
"sufficient permissions to trigger workflows."
134-
)
135-
console_print(
136-
"If you remove GITHUB_TOKEN, workflow_run will use the authentication you already "
137-
"set-up with `gh auth login`.\n"
131+
"\n[warning]GITHUB_TOKEN is set; Breeze will try your `gh auth login` first and only "
132+
"use this token as a fallback. The fallback token must have workflow-trigger scope."
138133
)
139134
console_print(
140135
f"[blue]Validating ref: {ref}[/blue]",
141136
)
142137

143138
if not skip_tag_validation:
144-
tag_result = run_command(
139+
tag_result = run_gh_command(
145140
["gh", "api", f"repos/apache/airflow/git/refs/tags/{ref}"],
146141
capture_output=True,
147-
check=False,
148142
)
149143

150144
stdout = tag_result.stdout.decode("utf-8")

dev/breeze/src/airflow_breeze/utils/gh_workflow_utils.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from airflow_breeze.global_constants import MIN_GH_VERSION
2727
from airflow_breeze.utils.console import console_print
28-
from airflow_breeze.utils.run_utils import run_command
28+
from airflow_breeze.utils.github import run_gh_command
2929

3030

3131
def tigger_workflow(workflow_name: str, repo: str, branch: str = "main", **kwargs):
@@ -50,7 +50,7 @@ def tigger_workflow(workflow_name: str, repo: str, branch: str = "main", **kwarg
5050
command.extend(["-f", f"{key}={value}"])
5151

5252
console_print(f"[blue]Running command: {' '.join(command)}[/blue]")
53-
result = run_command(command, capture_output=True, check=False)
53+
result = run_gh_command(command, capture_output=True)
5454

5555
if result.returncode != 0:
5656
console_print(f"[red]Error running workflow: {result.stderr}[/red]")
@@ -109,7 +109,7 @@ def get_workflow_run_id(workflow_name: str, repo: str) -> int:
109109
"databaseId",
110110
]
111111

112-
result = run_command(command, capture_output=True, check=False)
112+
result = run_gh_command(command, capture_output=True)
113113
if result.returncode != 0:
114114
console_print(f"[red]Error fetching workflow run ID: {result.stderr}[/red]")
115115
sys.exit(1)
@@ -139,7 +139,7 @@ def get_workflow_run_info(run_id: str, repo: str, fields: str) -> dict:
139139
make_sure_gh_is_installed()
140140
command = ["gh", "run", "view", run_id, "--json", fields, "--repo", repo]
141141

142-
result = run_command(command, capture_output=True, check=False)
142+
result = run_gh_command(command, capture_output=True)
143143
if result.returncode != 0:
144144
console_print(f"[red]Error fetching workflow run status: {result.stderr}[/red]")
145145
sys.exit(1)

0 commit comments

Comments
 (0)