Skip to content

Commit 32a837f

Browse files
authored
[CI] Harden GitHub automation inputs (#1761)
1 parent b5f1efd commit 32a837f

3 files changed

Lines changed: 47 additions & 7 deletions

File tree

.github/scripts/analyze_flaky_tests.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,28 @@ def list_workflow_runs(
106106
while len(runs) < num_runs:
107107
endpoint = (
108108
f"/repos/{repo}/actions/workflows/{workflow_name}/runs"
109-
f"?branch={branch}&status=completed&per_page={per_page}&page={page}"
109+
f"?branch={branch}&event=push&status=completed"
110+
f"&per_page={per_page}&page={page}"
110111
)
111112
data = gh_api(endpoint)
112113
if not data or "workflow_runs" not in data:
113114
break
114-
batch = data["workflow_runs"]
115-
if not batch:
115+
raw_batch = data["workflow_runs"]
116+
if not raw_batch:
116117
break
118+
# The API filters above are the primary boundary. Keep this fail-closed
119+
# check as defense in depth before downloading executable-repository
120+
# artifacts such as JUnit XML.
121+
batch = [
122+
run
123+
for run in raw_batch
124+
if run.get("event") == "push"
125+
and run.get("head_branch") == branch
126+
and (run.get("head_repository") or {}).get("full_name") == repo
127+
]
117128
runs.extend(batch)
118129
page += 1
119-
if len(batch) < per_page:
130+
if len(raw_batch) < per_page:
120131
break
121132

122133
return runs[:num_runs]

.github/tdbot/tdbot.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ def get_pr_info(repo: str, pr_number: int) -> dict:
8080
"--repo",
8181
repo,
8282
"--json",
83-
"headRefName,baseRefName,author,title,url,labels,mergeable,reviewDecision",
83+
"headRefName,baseRefName,author,title,url,labels,mergeable,reviewDecision,"
84+
"isCrossRepository",
8485
)
8586
return json.loads(result.stdout)
8687

@@ -113,6 +114,20 @@ def is_ghstack_pr(head_branch: str) -> bool:
113114
return bool(re.match(r"^gh/[^/]+/\d+/head$", head_branch))
114115

115116

117+
def reject_cross_repository_write(ctx: CommandContext, command: str) -> bool:
118+
"""Reject commands that would push through the base repository remote."""
119+
if ctx.pr_info.get("isCrossRepository") is False:
120+
return False
121+
post_comment(
122+
ctx.repo,
123+
ctx.pr_number,
124+
f"`{command}` cannot safely update a branch from a fork. "
125+
"Please perform the update in the fork and push it from an account "
126+
"that controls that repository.",
127+
)
128+
return True
129+
130+
116131
def find_ghstack_stack_top(repo: str, head_branch: str) -> int:
117132
"""Return the PR number at the top of the ghstack stack containing *head_branch*.
118133
@@ -279,6 +294,9 @@ def cmd_rebase(ctx: CommandContext, args: argparse.Namespace) -> None:
279294
)
280295
return
281296

297+
if reject_cross_repository_write(ctx, "rebase"):
298+
return
299+
282300
if is_ghstack_pr(head):
283301
_rebase_ghstack(ctx, args)
284302
else:
@@ -380,6 +398,9 @@ def cmd_lint(ctx: CommandContext, _args: argparse.Namespace) -> None:
380398
)
381399
return
382400

401+
if reject_cross_repository_write(ctx, "lint"):
402+
return
403+
383404
post_comment(
384405
ctx.repo,
385406
ctx.pr_number,

.github/workflows/pr-label.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,16 @@ jobs:
9191
**Note:** Matching is case-insensitive. Common variations (singular/plural) are supported.
9292
COMMENT_EOF
9393
sed -i 's/^ *//' /tmp/pr_comment.md
94-
sed -i "s/REASON_PLACEHOLDER/$reason/" /tmp/pr_comment.md
95-
sed -i "s|TITLE_PLACEHOLDER|$current_title|" /tmp/pr_comment.md
94+
COMMENT_REASON="$reason" COMMENT_TITLE="$current_title" python3 - <<'PY'
95+
import os
96+
from pathlib import Path
97+
98+
path = Path("/tmp/pr_comment.md")
99+
comment = path.read_text()
100+
comment = comment.replace("REASON_PLACEHOLDER", os.environ["COMMENT_REASON"])
101+
comment = comment.replace("TITLE_PLACEHOLDER", os.environ["COMMENT_TITLE"])
102+
path.write_text(comment)
103+
PY
96104
gh pr comment "$PR_NUMBER" --repo "$REPO" --body-file /tmp/pr_comment.md
97105
}
98106

0 commit comments

Comments
 (0)