gather_context |
| GH_TOKEN |
EVENT_NAME |
PR_NUMBER_INPUT |
DRY_RUN_INPUT |
PR_JSON_PAYLOAD |
${{ secrets.DOCS_BOT_PAT_BASE }} |
${{ github.event_name }} |
${{ github.event.inputs.pr_number }} |
${{ github.event.inputs.dry_run }} |
${{ toJson(github.event.pull_request) }} |
|
set -e
skip() { echo "should_run=false" >> "$GITHUB_OUTPUT"; echo "ℹ️ $1"; exit 0; }
# ── 1. Resolve the PR ──────────────────────────────────────────────
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
PR_NUM="$PR_NUMBER_INPUT"
PR_JSON=$(gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUM")
MERGED=$(echo "$PR_JSON" | jq -r '.merged')
if [[ "$MERGED" != "true" ]]; then
skip "PR #$PR_NUM has not been merged. Skipping."
fi
else
PR_JSON="$PR_JSON_PAYLOAD"
MERGED=$(echo "$PR_JSON" | jq -r '.merged')
BASE_REF=$(echo "$PR_JSON" | jq -r '.base.ref')
if [[ "$MERGED" != "true" || "$BASE_REF" != "main" ]]; then
skip "PR not merged to main. Skipping."
fi
PR_NUM=$(echo "$PR_JSON" | jq -r '.number')
fi
PR_AUTHOR=$(echo "$PR_JSON" | jq -r '.user.login')
PR_TITLE=$(echo "$PR_JSON" | jq -r '.title')
PR_BODY=$(echo "$PR_JSON" | jq -r '.body // ""')
PR_URL=$(echo "$PR_JSON" | jq -r '.html_url')
# ── 2. Check if PR author is in the team ──────────────────────────
CONTENT=$(gh api repos/github/docs-content/contents/.github/github-to-slack.json \
--jq '.content') || { echo "::error::Could not fetch github-to-slack.json"; exit 1; }
MAPPING=$(echo "$CONTENT" | base64 -d)
if ! echo "$MAPPING" | jq -e --arg user "$PR_AUTHOR" 'has($user)' > /dev/null 2>&1; then
skip "PR author @$PR_AUTHOR is not in the team mapping. Skipping."
fi
# ── 3. Extract linked docs-content issue from PR body ─────────────
ISSUE_NUM=$(echo "$PR_BODY" | grep -oiE '(close[sd]?|fix(e[sd])?|resolve[sd]?):?\s+github/docs-content#[0-9]+' | grep -oE '[0-9]+$' | head -1)
if [[ -z "$ISSUE_NUM" ]]; then
ISSUE_NUM=$(echo "$PR_BODY" | grep -oiE '(close[sd]?|fix(e[sd])?|resolve[sd]?):?\s+https://github\.com/github/docs-content/issues/[0-9]+' | grep -oE '[0-9]+$' | head -1)
fi
if [[ -z "$ISSUE_NUM" ]]; then
skip "No linked docs-content issue found. Skipping."
fi
# ── 4. Fetch the docs-content issue and check for parent ──────────
ISSUE_JSON=$(gh api "repos/github/docs-content/issues/$ISSUE_NUM") || skip "Could not fetch docs-content issue #$ISSUE_NUM. Skipping."
NODE_ID=$(echo "$ISSUE_JSON" | jq -r '.node_id')
PARENT_JSON=$(gh api graphql -f query='
query($nodeId: ID!) {
node(id: $nodeId) {
... on Issue {
parent {
number
title
body
url
author { login }
assignees(first: 10) {
nodes { login }
}
repository {
nameWithOwner
}
}
}
}
}' -f nodeId="$NODE_ID" --jq '.data.node.parent') || skip "GraphQL parent query failed. Skipping."
if [[ "$PARENT_JSON" == "null" || -z "$PARENT_JSON" ]]; then
skip "docs-content issue has no parent issue. Skipping."
fi
# ── 5. Check for existing open changelog PRs ──────────────────────
EXISTING=$(gh api "search/issues?q=is:pr+is:open+label:changelog-agent+repo:github/docs-content" \
--jq '.total_count')
if [[ "$EXISTING" -gt 0 ]]; then
skip "Open changelog PR already exists. Skipping."
fi
# ── 6. Gather reviewers and changed files ─────────────────────────
APPROVED_REVIEWERS=$(gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUM/reviews" \
--jq "[.[] | select(.state == \"APPROVED\" and .user.type != \"Bot\" and .user.login != \"$PR_AUTHOR\") | .user.login] | unique | join(\",\")")
CHANGED_FILES=$(gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUM/files?per_page=100" \
--jq '[.[].filename] | join(",")')
# ── 7. Read existing changelog examples (first 3 entries) ─────────
CHANGELOG_EXAMPLES=""
CHANGELOG_RAW=$(gh api repos/github/docs-content/contents/docs-content-docs/docs-content-workflows/changelog-internal.md \
--jq '.content' | base64 -d 2>/dev/null) || true
if [[ -n "$CHANGELOG_RAW" ]]; then
CHANGELOG_EXAMPLES=$(echo "$CHANGELOG_RAW" | awk '
/^\*\*[0-9]/ { count++; if (count > 3) exit; capturing=1 }
capturing { print }
')
fi
# ── 8. Build context JSON for the agent ───────────────────────────
DRY_RUN="false"
if [[ "$EVENT_NAME" == "workflow_dispatch" && "$DRY_RUN_INPUT" == "true" ]]; then
DRY_RUN="true"
fi
mkdir -p /tmp/gh-aw/agent
jq -n \
--arg pr_number "$PR_NUM" \
--arg pr_title "$PR_TITLE" \
--arg pr_body "$PR_BODY" \
--arg pr_author "$PR_AUTHOR" \
--arg pr_url "$PR_URL" \
--arg changed_files "$CHANGED_FILES" \
--arg approved_reviewers "$APPROVED_REVIEWERS" \
--arg issue_num "$ISSUE_NUM" \
--arg issue_title "$(echo "$ISSUE_JSON" | jq -r '.title')" \
--arg issue_body "$(echo "$ISSUE_JSON" | jq -r '.body // ""')" \
--arg parent_number "$(echo "$PARENT_JSON" | jq -r '.number')" \
--arg parent_title "$(echo "$PARENT_JSON" | jq -r '.title')" \
--arg parent_body "$(echo "$PARENT_JSON" | jq -r '.body // ""')" \
--arg parent_url "$(echo "$PARENT_JSON" | jq -r '.url')" \
--arg parent_author "$(echo "$PARENT_JSON" | jq -r '.author.login // ""')" \
--arg parent_assignees "$(echo "$PARENT_JSON" | jq -r '[.assignees.nodes[].login] | join(",")')" \
--arg parent_repo "$(echo "$PARENT_JSON" | jq -r '.repository.nameWithOwner')" \
--arg changelog_examples "$CHANGELOG_EXAMPLES" \
--arg dry_run "$DRY_RUN" \
'{
pr: {
number: ($pr_number | tonumber),
title: $pr_title,
body: $pr_body,
author: $pr_author,
url: $pr_url,
changed_files: ($changed_files | split(",")),
approved_reviewers: (if $approved_reviewers == "" then [] else ($approved_reviewers | split(",")) end)
},
docs_content_issue: {
number: ($issue_num | tonumber),
title: $issue_title,
body: $issue_body
},
parent_issue: {
number: ($parent_number | tonumber),
title: $parent_title,
body: $parent_body,
url: $parent_url,
author: $parent_author,
assignees: (if $parent_assignees == "" then [] else ($parent_assignees | split(",")) end),
repo: $parent_repo
},
changelog_examples: $changelog_examples,
dry_run: ($dry_run == "true")
}' > /tmp/gh-aw/agent/context.json
# ── Outputs ───────────────────────────────────────────────────────
echo "should_run=true" >> "$GITHUB_OUTPUT"
echo "pr_number=$PR_NUM" >> "$GITHUB_OUTPUT"
echo "dry_run=$DRY_RUN" >> "$GITHUB_OUTPUT"
|