From 76c72b02e2ed54583636cbfad7b07f4ece5e9219 Mon Sep 17 00:00:00 2001 From: Evelyn Chen Date: Thu, 27 Aug 2026 18:17:27 +0000 Subject: [PATCH] Fetch PR body inside checker Authored-By: Codex (GPT-5) --- README.md | 7 +++---- action.yaml | 6 ++---- check.sh | 18 +++++++++++++++--- tests/bin/curl | 31 +++++++++++++++++++++++++------ tests/run | 31 +++++++++++++++++++++++++++---- 5 files changed, 72 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 677a639..080ab96 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,6 @@ jobs: head-branch: ${{ github.head_ref }} pr-title: ${{ github.event.pull_request.title }} pr-author: ${{ github.event.pull_request.user.login }} - pr-body: ${{ github.event.pull_request.body }} server-url: ${{ github.server_url }} token: ${{ github.token }} base-sha: ${{ github.event.pull_request.base.sha }} @@ -53,7 +52,6 @@ job — the step still fails, but the job cannot block the PR. | `head-branch` | yes | Head branch name — `github.head_ref` | | `pr-title` | yes | PR title — `github.event.pull_request.title` | | `pr-author` | no | PR author login — `github.event.pull_request.user.login`; `dfritz` is exempt | -| `pr-body` | yes | PR description — `github.event.pull_request.body` | | `server-url` | yes | Gitea server URL — `github.server_url` | | `token` | yes | Gitea Actions token — `github.token` | | `base-sha` | yes | Base commit — `github.event.pull_request.base.sha` | @@ -75,8 +73,9 @@ The check validates four things for every non-break-glass Agent PR: `Fixes bug-` automation token and the matching navigable `https://agenthub.fritzlab.net/bug-` URL. Every PR has a separate `## Attribution` section containing the canonical `Authored-By` - product/model watermark. The action asks Gitea to render the body with a - bounded 5-second connection and 15-second total wait, then checks visible + product/model watermark. The action loads the body from Gitea by repository + and PR number, then asks Gitea to render it; both calls have a bounded + 5-second connection and 15-second total wait. It then checks visible `

` sections outside collapsed `
` content. Fenced, commented, scripted, or collapsed copies do not satisfy the visible provenance contract. diff --git a/action.yaml b/action.yaml index 4208d19..a052959 100644 --- a/action.yaml +++ b/action.yaml @@ -26,9 +26,6 @@ inputs: dfritz is exempt from all checks. required: false default: '' - pr-body: - description: PR description — github.event.pull_request.body. - required: true server-url: description: Gitea server URL — github.server_url. required: true @@ -51,9 +48,10 @@ runs: HEAD_BRANCH: ${{ inputs.head-branch }} PR_TITLE: ${{ inputs.pr-title }} PR_AUTHOR: ${{ inputs.pr-author }} - PR_BODY: ${{ inputs.pr-body }} GITEA_SERVER_URL: ${{ inputs.server-url }} GITEA_TOKEN: ${{ inputs.token }} + GITEA_REPOSITORY: ${{ github.repository }} + GITEA_PR_NUMBER: ${{ github.event.pull_request.number }} BASE_SHA: ${{ inputs.base-sha }} HEAD_SHA: ${{ inputs.head-sha }} run: bash "${{ github.action_path }}/check.sh" diff --git a/check.sh b/check.sh index 391c571..ed81cea 100755 --- a/check.sh +++ b/check.sh @@ -7,11 +7,12 @@ set -euo pipefail BRANCH="${HEAD_BRANCH:-}" TITLE="${PR_TITLE:-}" AUTHOR="${PR_AUTHOR:-}" -BODY="${PR_BODY:-}" BASE="${BASE_SHA:-}" HEAD="${HEAD_SHA:-}" SERVER_URL="${GITEA_SERVER_URL:-}" TOKEN="${GITEA_TOKEN:-}" +REPOSITORY="${GITEA_REPOSITORY:-}" +PR_NUMBER="${GITEA_PR_NUMBER:-}" # Break-glass: dfritz is exempt from all naming checks. if [ "${AUTHOR}" = "dfritz" ]; then @@ -26,8 +27,19 @@ BRANCH_BUG="" # Gitea's renderer is the visibility contract. Validate its output instead of # maintaining a second Markdown parser in this action. RENDERED_BODY="" -if [ -z "${SERVER_URL}" ] || [ -z "${TOKEN}" ]; then - echo "FAIL[check-naming]: server-url and token are required to render the PR body" +BODY="" +if [ -z "${SERVER_URL}" ] || [ -z "${TOKEN}" ] || + ! printf '%s' "${REPOSITORY}" | grep -qE '^[[:alnum:]_.-]+/[[:alnum:]_.-]+$' || + ! printf '%s' "${PR_NUMBER}" | grep -qE '^[1-9][0-9]*$'; then + echo "FAIL[check-naming]: server-url, token, repository, and PR number are required to load the PR body" + FAILED=1 +elif ! BODY=$(curl --fail --silent --show-error \ + --connect-timeout 5 \ + --max-time 15 \ + --header "Authorization: token ${TOKEN}" \ + "${SERVER_URL%/}/api/v1/repos/${REPOSITORY}/pulls/${PR_NUMBER}" | + jq -er '.body | if type == "string" then . else error("body is not a string") end'); then + echo "FAIL[check-naming]: Gitea could not load the PR body" FAILED=1 elif ! RENDERED_BODY=$(printf '%s' "${BODY}" | jq -Rs '{Text: ., Mode: "gfm"}' | diff --git a/tests/bin/curl b/tests/bin/curl index afb5208..f28204e 100755 --- a/tests/bin/curl +++ b/tests/bin/curl @@ -4,6 +4,7 @@ set -euo pipefail connect_timeout=0 total_timeout=0 +url="" while [ "$#" -gt 0 ]; do case "$1" in --connect-timeout) @@ -16,20 +17,38 @@ while [ "$#" -gt 0 ]; do total_timeout=1 shift 2 ;; + --header|--data-binary) + shift 2 + ;; + http*) + url="$1" + shift + ;; *) shift ;; esac done [ "${connect_timeout}" -eq 1 ] && [ "${total_timeout}" -eq 1 ] || exit 2 -if printf '%s\n' "${PR_BODY}" | grep -Fq '[[stall-renderer]]'; then - exit 28 -fi - -if printf '%s\n' "${PR_BODY}" | grep -Fq '