chore: import upstream snapshot with attribution
This commit is contained in:
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
# Authorizes a `/merge` slash command by the commenter's repo access.
|
||||
#
|
||||
# `/merge` only enables auto-merge / direct-merges an already-mergeable
|
||||
# PR -- branch protection still blocks red or unreviewed PRs -- so the
|
||||
# bar is repo write access, not the stricter MAINTAINER set that gates
|
||||
# the maintainer-only waivers. This keeps `/merge` usable by the whole
|
||||
# team while blocking outside contributors and drive-by accounts.
|
||||
#
|
||||
# The job-level `if` already pre-filters on author_association as a
|
||||
# cheap first pass; this is the authoritative check, because an org
|
||||
# MEMBER does not necessarily have write on this specific repo. The
|
||||
# permission API resolves effective access (team grants, etc.).
|
||||
#
|
||||
# Env in: GH_TOKEN, REPO, AUTHOR, PR
|
||||
# Out: authorized=true|false on $GITHUB_OUTPUT. On false, posts a
|
||||
# reply comment explaining the rejection.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Effective permission for the commenter: admin|maintain|write|triage|read|none
|
||||
set +e
|
||||
PERM=$(gh api "repos/$REPO/collaborators/$AUTHOR/permission" --jq '.permission' 2>/dev/null)
|
||||
RC=$?
|
||||
set -e
|
||||
|
||||
if [[ $RC -ne 0 ]]; then
|
||||
# 403/404 => not a collaborator with resolvable permission.
|
||||
PERM="none"
|
||||
fi
|
||||
|
||||
case "$PERM" in
|
||||
admin|maintain|write)
|
||||
echo "authorized=true" >> "$GITHUB_OUTPUT"
|
||||
echo "Authorized: @$AUTHOR has '$PERM' access."
|
||||
;;
|
||||
*)
|
||||
echo "authorized=false" >> "$GITHUB_OUTPUT"
|
||||
echo "::notice::@$AUTHOR has '$PERM' access; /merge requires write."
|
||||
gh pr comment "$PR" --repo "$REPO" \
|
||||
--body ":no_entry: \`/merge\` from @$AUTHOR ignored -- it requires write access to this repository."
|
||||
;;
|
||||
esac
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
# Single source of truth for the Merge Ready outcome. Downstream steps
|
||||
# just consume `state`, `short_desc`, and `long_desc`.
|
||||
#
|
||||
# The gate is green iff every required check is green on its own merits. There is
|
||||
# no CI bypass: to land despite red required checks, fix or delete the failing
|
||||
# test, or have a repo admin use GitHub's native "merge without waiting for
|
||||
# requirements" affordance. (Fork PRs still need a maintainer's approving review
|
||||
# to merge -- that is enforced by the separate `Maintainer Approval` check, not
|
||||
# here. No CI suite needs secrets on a fork PR anymore, so there is no
|
||||
# e2e-specific approval gate.)
|
||||
#
|
||||
# CI eval | state | meaning
|
||||
# ---------+----------+----------------------------
|
||||
# success | success | all required checks green
|
||||
# failure | failure | a required check is red
|
||||
#
|
||||
# Env in: EVAL, FAILED
|
||||
# Out: state, short_desc, long_desc on $GITHUB_OUTPUT
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ "$EVAL" == "success" ]]; then
|
||||
STATE=success
|
||||
SHORT="All required checks green"
|
||||
LONG=":white_check_mark: gate is green, merging now."
|
||||
else
|
||||
STATE=failure
|
||||
SHORT="Required checks not all green"
|
||||
LONG=$':hourglass: gate not green yet. Required checks not satisfied:\n\n'"$FAILED"$'\nThe merge will fire once these turn green.'
|
||||
fi
|
||||
|
||||
# GitHub commit-status descriptions max out at 140 chars.
|
||||
if [[ ${#SHORT} -gt 140 ]]; then
|
||||
SHORT="${SHORT:0:137}..."
|
||||
fi
|
||||
|
||||
echo "state=$STATE" >> "$GITHUB_OUTPUT"
|
||||
echo "short_desc=$SHORT" >> "$GITHUB_OUTPUT"
|
||||
{
|
||||
echo "long_desc<<_LONG_EOF_"
|
||||
printf '%s' "$LONG"
|
||||
echo
|
||||
echo "_LONG_EOF_"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
echo "Computed gate: state=$STATE | $SHORT"
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
# Handles `/merge` slash commands. Tries `gh pr merge --auto` first
|
||||
# (queues until protection passes); falls back to a direct merge when
|
||||
# `--auto` is rejected because the PR is already in `clean status` or
|
||||
# the base moved underneath us. Always posts a reply comment.
|
||||
#
|
||||
# Env in: GH_TOKEN, REPO, PR, AUTHOR, GATE
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
set +e
|
||||
MERGE_OUT=$(gh pr merge "$PR" --repo "$REPO" --squash --auto --delete-branch 2>&1)
|
||||
MERGE_RC=$?
|
||||
MODE="auto-merge enabled (squash, delete branch)"
|
||||
|
||||
if [[ $MERGE_RC -ne 0 ]] \
|
||||
&& echo "$MERGE_OUT" | grep -qE "clean status|Base branch was modified"; then
|
||||
echo "::notice::--auto rejected ($MERGE_OUT); retrying direct merge."
|
||||
MERGE_OUT=$(gh pr merge "$PR" --repo "$REPO" --squash --delete-branch 2>&1)
|
||||
MERGE_RC=$?
|
||||
MODE="merged directly (squash, delete branch)"
|
||||
fi
|
||||
set -e
|
||||
echo "$MERGE_OUT"
|
||||
|
||||
if [[ $MERGE_RC -eq 0 ]]; then
|
||||
BODY=":robot: \`/merge\` from @$AUTHOR, $MODE. $GATE"
|
||||
else
|
||||
# Race: an earlier auto-merge may have fired between the /merge
|
||||
# command and our attempt. Confirm friendlier.
|
||||
PR_STATE=$(gh pr view "$PR" --repo "$REPO" --json state --jq '.state' 2>/dev/null || echo "")
|
||||
if [[ "$PR_STATE" == "MERGED" ]]; then
|
||||
BODY=":white_check_mark: \`/merge\` from @$AUTHOR -- PR is already merged."
|
||||
else
|
||||
BODY=$(printf ':warning: `/merge` from @%s, could not enable auto-merge. `gh pr merge` output:\n```\n%s\n```' "$AUTHOR" "$MERGE_OUT")
|
||||
fi
|
||||
fi
|
||||
gh pr comment "$PR" --repo "$REPO" --body "$BODY"
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# Enables GitHub auto-merge when the `automerge` label is added.
|
||||
# Queues until branch protection (the Merge Ready status) goes green;
|
||||
# GitHub fires the merge automatically once it does, so a single call
|
||||
# is sufficient.
|
||||
#
|
||||
# Env in: GH_TOKEN, REPO, PR
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
set +e
|
||||
MERGE_OUT=$(gh pr merge "$PR" --repo "$REPO" --squash --auto --delete-branch 2>&1)
|
||||
MERGE_RC=$?
|
||||
set -e
|
||||
echo "$MERGE_OUT"
|
||||
|
||||
if [[ $MERGE_RC -eq 0 ]]; then
|
||||
echo "::notice::Auto-merge enabled via 'automerge' label."
|
||||
else
|
||||
echo "::warning::Could not enable auto-merge via 'automerge' label: $MERGE_OUT"
|
||||
fi
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env bash
|
||||
# Iterates `REQUIRED` (defined in required.sh) against the actual
|
||||
# check-runs on the PR head SHA. When GitHub has multiple check-runs
|
||||
# with the same name on the same SHA (for example after re-running PR
|
||||
# Template on an edited description), the newest run wins.
|
||||
# Each check counts as green when:
|
||||
# - conclusion=success, OR
|
||||
# - conclusion=skipped AND name is in ALLOW_SKIP, OR
|
||||
# - the check is missing AND name is in ALLOW_SKIP AND its owning
|
||||
# workflow either never ran for this SHA (path-ignored), or its
|
||||
# newest run succeeded (the absent check was conditionally excluded
|
||||
# from that run's job matrix), or its newest run was skipped (the
|
||||
# whole workflow was gated off, e.g. a fork/draft PR) — see
|
||||
# workflow_run_outcome.
|
||||
#
|
||||
# A missing ALLOW_SKIP check is NOT green only while its workflow's
|
||||
# newest run is still in flight / cancelled / failed: the check could
|
||||
# still be pending or was lost, so the gate must wait. Inferring "skip"
|
||||
# from mere absence let PR #2218 merge while an E2E shard was cancelled
|
||||
# and re-running. Trusting a *succeeded* run keeps path-filtered jobs
|
||||
# (e.g. CI's dynamically-selected Pytest shards on a docs/deploy-only
|
||||
# PR) from blocking the gate; trusting a *skipped* run keeps fork/draft
|
||||
# PRs — whose entire e2e workflow is gated off — from wedging it.
|
||||
#
|
||||
# Env in: GH_TOKEN, REPO, SHA
|
||||
# Out: failed=<markdown bullet list of failed names> on $GITHUB_OUTPUT
|
||||
# Exit: 0 if all green, 1 if any red.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
HERE=$(dirname "$0")
|
||||
# shellcheck disable=SC1091
|
||||
source "$HERE/required.sh"
|
||||
|
||||
CHECKS=$(gh api "repos/$REPO/commits/$SHA/check-runs" --paginate \
|
||||
--jq '.check_runs[] | "\(.name)\t\(.status)\t\(.conclusion // "null")\t\(.completed_at // .started_at // "")"')
|
||||
|
||||
# Per-workflow run state for this SHA (one row per run:
|
||||
# name<TAB>status<TAB>conclusion<TAB>created_at). Used to classify a
|
||||
# *missing* required check via workflow_run_outcome below.
|
||||
WORKFLOW_RUNS=$(gh api "repos/$REPO/actions/runs?head_sha=$SHA&per_page=100" --paginate \
|
||||
--jq '.workflow_runs[] | [.name, .status, (.conclusion // "null"), (.created_at // "")] | @tsv')
|
||||
|
||||
# Classify the newest run of a workflow for this SHA:
|
||||
# "none" — no run at all. The workflow was gated out by
|
||||
# on.pull_request.paths-ignore, so its checks are
|
||||
# legitimately absent.
|
||||
# "success" — newest run completed successfully. A check that is still
|
||||
# absent was conditionally excluded from that run's job
|
||||
# matrix (e.g. CI dynamically path-filters its Pytest
|
||||
# shards); the green workflow vouches the job wasn't needed.
|
||||
# "skipped" — newest run completed with conclusion=skipped: every job's
|
||||
# `if:` was false, so the run did no work (e2e fork guard on
|
||||
# a fork PR, e2e-ui `!draft` on a draft PR). A definitive
|
||||
# skip, not a transient, so absent ALLOW_SKIP checks pass.
|
||||
# "other" — in progress, queued, cancelled, or failed. An absent
|
||||
# check may still be pending or was lost, so the gate must
|
||||
# wait rather than treat the gap as a skip (the #2218 race,
|
||||
# where an E2E shard was cancelled and re-running at the
|
||||
# moment the gate evaluated).
|
||||
workflow_run_outcome() {
|
||||
local wf="$1" row status concl
|
||||
row=$(printf '%s\n' "$WORKFLOW_RUNS" | awk -F'\t' -v w="$wf" '$1 == w' \
|
||||
| sort -t $'\t' -k4,4 | tail -n 1)
|
||||
if [[ -z "$row" ]]; then
|
||||
echo "none"
|
||||
return
|
||||
fi
|
||||
status=$(printf '%s' "$row" | cut -f2)
|
||||
concl=$(printf '%s' "$row" | cut -f3)
|
||||
if [[ "$status" == "completed" && "$concl" == "success" ]]; then
|
||||
echo "success"
|
||||
elif [[ "$status" == "completed" && "$concl" == "skipped" ]]; then
|
||||
echo "skipped"
|
||||
else
|
||||
echo "other"
|
||||
fi
|
||||
}
|
||||
|
||||
FAIL=0
|
||||
FAILED_LINES=""
|
||||
for n in "${REQUIRED[@]}"; do
|
||||
ROW=$(echo "$CHECKS" | awk -F'\t' -v n="$n" '$1 == n {print}' | sort -t $'\t' -k4,4 | tail -n 1)
|
||||
if [[ -z "$ROW" ]]; then
|
||||
if is_allow_skip "$n"; then
|
||||
wf=$(workflow_for "$n")
|
||||
outcome="none"
|
||||
[[ -n "$wf" ]] && outcome=$(workflow_run_outcome "$wf")
|
||||
if [[ "$outcome" == "other" ]]; then
|
||||
echo "NOT GREEN: $n (workflow '$wf' has not succeeded and the check is missing -- pending/cancelled, not a skip)"
|
||||
FAILED_LINES+="- \`$n\` (workflow ran but has not succeeded and the check is missing -- still pending or cancelled)"$'\n'
|
||||
FAIL=1
|
||||
continue
|
||||
fi
|
||||
# outcome is "none" (workflow path-skipped), "success" (job
|
||||
# conditionally excluded from a green run), or "skipped" (whole
|
||||
# workflow gated off, e.g. fork/draft PR) — all legitimate.
|
||||
echo "OK : $n (skipped: path-ignored, conditionally-excluded, or fork/draft-gated)"
|
||||
continue
|
||||
fi
|
||||
echo "MISSING : $n"
|
||||
FAILED_LINES+="- \`$n\` (not yet started or not configured on this commit)"$'\n'
|
||||
FAIL=1
|
||||
continue
|
||||
fi
|
||||
STATUS=$(echo "$ROW" | cut -f2)
|
||||
CONCL=$(echo "$ROW" | cut -f3)
|
||||
if [[ "$STATUS" != "completed" ]]; then
|
||||
echo "NOT GREEN: $n (status=$STATUS, conclusion=$CONCL)"
|
||||
FAILED_LINES+="- \`$n\` (still running, status=$STATUS)"$'\n'
|
||||
FAIL=1
|
||||
elif [[ "$CONCL" == "skipped" ]] && is_allow_skip "$n"; then
|
||||
echo "OK : $n (skipped via path filter)"
|
||||
elif [[ "$CONCL" != "success" ]]; then
|
||||
echo "NOT GREEN: $n (status=$STATUS, conclusion=$CONCL)"
|
||||
FAILED_LINES+="- \`$n\` (conclusion=$CONCL)"$'\n'
|
||||
FAIL=1
|
||||
else
|
||||
echo "OK : $n"
|
||||
fi
|
||||
done
|
||||
|
||||
{
|
||||
echo "failed<<_FAILED_EOF_"
|
||||
printf '%s' "$FAILED_LINES"
|
||||
echo "_FAILED_EOF_"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
if [[ $FAIL -eq 1 ]]; then
|
||||
echo ""
|
||||
echo "Required checks are not all green on $SHA."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All required checks green on $SHA."
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
# Loads the maintainer set from .github/MAINTAINER at main's tip.
|
||||
#
|
||||
# Always main, never the PR head SHA: otherwise a PR could edit
|
||||
# MAINTAINER to grant itself a maintainer-gated waiver (e.g.
|
||||
# skip-security-scan, skip-e2e-ui-test) without being merged.
|
||||
# Defense-in-depth: a PR could still edit *this* workflow to drop
|
||||
# `?ref=main`, so the remaining defense is `required_pull_request_reviews`
|
||||
# in branch protection.
|
||||
#
|
||||
# MAINTAINER format: one bare username per line, with comments (`#`)
|
||||
# and blank lines ignored.
|
||||
#
|
||||
# Env in: GH_TOKEN, REPO
|
||||
# Out: `list=<space-separated usernames>` on $GITHUB_OUTPUT (empty
|
||||
# when MAINTAINER is missing or empty).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
set +e
|
||||
CONTENT_B64=$(gh api "repos/$REPO/contents/.github/MAINTAINER?ref=main" --jq '.content' 2>/dev/null)
|
||||
RC=$?
|
||||
set -e
|
||||
|
||||
if [[ $RC -ne 0 || -z "$CONTENT_B64" ]]; then
|
||||
echo "list=" >> "$GITHUB_OUTPUT"
|
||||
echo "::warning::.github/MAINTAINER not found on main; maintainer-gated waivers cannot be effective until the file is merged."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
CONTENT=$(echo "$CONTENT_B64" | base64 -d)
|
||||
|
||||
# `grep -v` exits 1 on no matches; wrap so the pipeline stays 0 under
|
||||
# pipefail and we reach the empty-list branch.
|
||||
USERS=$(echo "$CONTENT" | sed -E 's/#.*$//' | tr -s '[:space:]' '\n' | { grep -v '^$' || true; } | tr '\n' ' ')
|
||||
USERS="${USERS% }"
|
||||
|
||||
if [[ -z "${USERS// /}" ]]; then
|
||||
echo "list=" >> "$GITHUB_OUTPUT"
|
||||
echo "::warning::.github/MAINTAINER on main has no entries; maintainer-gated waivers cannot be effective."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "list=$USERS" >> "$GITHUB_OUTPUT"
|
||||
echo "Loaded maintainers from MAINTAINER@main: $USERS"
|
||||
@@ -0,0 +1,85 @@
|
||||
# Sourced by evaluate-checks.sh. These checks gate every PR. e2e, e2e-ui, and
|
||||
# integration are mock-LLM (no secrets) and run on ALL PRs -- same-repo and fork
|
||||
# -- directly, like CI. They are in ALLOW_SKIP too because they are legitimately
|
||||
# absent in some runs: draft PRs (empty matrix) and path-ignored PRs (the
|
||||
# workflow doesn't run). The real-gateway e2e-ui tests run nightly only and are
|
||||
# NOT PR checks, so they are not listed here.
|
||||
# Generated file -- do not hand-edit; it is replaced wholesale on every sync.
|
||||
|
||||
REQUIRED=(
|
||||
"Pre-commit checks"
|
||||
"Docker build"
|
||||
"Pytest (runtime-harnesses)"
|
||||
"Pytest (runtime-policies)"
|
||||
"Pytest (runtime-core)"
|
||||
"Pytest (inner-terminal)"
|
||||
"Pytest (inner-env)"
|
||||
"Pytest (inner-tracing)"
|
||||
"Pytest (inner-rest)"
|
||||
"Pytest (tools)"
|
||||
"Pytest (repl-sdk)"
|
||||
"Pytest (server-responses)"
|
||||
"Pytest (server-rest)"
|
||||
"Pytest (spec-llms)"
|
||||
"Pytest (runner-app)"
|
||||
"Pytest (stores)"
|
||||
"Pytest (misc)"
|
||||
"Pytest (databricks)"
|
||||
"E2E Tests (shard 0/4)"
|
||||
"E2E Tests (shard 1/4)"
|
||||
"E2E Tests (shard 2/4)"
|
||||
"E2E Tests (shard 3/4)"
|
||||
"E2E UI Tests (shard 0/3)"
|
||||
"E2E UI Tests (shard 1/3)"
|
||||
"E2E UI Tests (shard 2/3)"
|
||||
"Integration (claude-sdk)"
|
||||
"Integration (openai-agents)"
|
||||
"Integration (codex)"
|
||||
)
|
||||
|
||||
ALLOW_SKIP=(
|
||||
"Docker build"
|
||||
"Pytest (runtime-harnesses)"
|
||||
"Pytest (runtime-policies)"
|
||||
"Pytest (runtime-core)"
|
||||
"Pytest (inner-terminal)"
|
||||
"Pytest (inner-env)"
|
||||
"Pytest (inner-tracing)"
|
||||
"Pytest (inner-rest)"
|
||||
"Pytest (tools)"
|
||||
"Pytest (repl-sdk)"
|
||||
"Pytest (server-responses)"
|
||||
"Pytest (server-rest)"
|
||||
"Pytest (spec-llms)"
|
||||
"Pytest (runner-app)"
|
||||
"Pytest (stores)"
|
||||
"Pytest (misc)"
|
||||
"Pytest (databricks)"
|
||||
"E2E Tests (shard 0/4)"
|
||||
"E2E Tests (shard 1/4)"
|
||||
"E2E Tests (shard 2/4)"
|
||||
"E2E Tests (shard 3/4)"
|
||||
"E2E UI Tests (shard 0/3)"
|
||||
"E2E UI Tests (shard 1/3)"
|
||||
"E2E UI Tests (shard 2/3)"
|
||||
"Integration (claude-sdk)"
|
||||
"Integration (openai-agents)"
|
||||
"Integration (codex)"
|
||||
)
|
||||
|
||||
is_allow_skip() { printf '%s\n' "${ALLOW_SKIP[@]}" | grep -qxF "$1"; }
|
||||
|
||||
# Maps an ALLOW_SKIP check to the workflow that produces it, so
|
||||
# evaluate-checks.sh can tell a genuine skip (a CI Pytest shard path-skip, or a
|
||||
# draft/path-ignored run) from a check that is merely absent because its
|
||||
# workflow is still queued or re-running.
|
||||
workflow_for() {
|
||||
case "$1" in
|
||||
"Docker build") echo "Docker build" ;;
|
||||
"Pytest ("*) echo "CI" ;;
|
||||
"E2E Tests (shard "*) echo "E2E Tests" ;;
|
||||
"E2E UI Tests (shard "*) echo "E2E UI Tests" ;;
|
||||
"Integration ("*) echo "Integration Tests" ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
Reference in New Issue
Block a user