From 6d1e632b78799bc5edc826f8afff9d56ca26d63c Mon Sep 17 00:00:00 2001 From: ben-fornefeld Date: Tue, 17 Mar 2026 11:46:38 -0700 Subject: [PATCH 1/2] docs: handle PR permission restrictions in sync workflow --- .github/workflows/sdk-reference-sync.yml | 9 ++++++++- scripts/create-sdk-reference-sync-pr.sh | 23 ++++++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/.github/workflows/sdk-reference-sync.yml b/.github/workflows/sdk-reference-sync.yml index 2f6a9cd0..f26f2879 100644 --- a/.github/workflows/sdk-reference-sync.yml +++ b/.github/workflows/sdk-reference-sync.yml @@ -134,7 +134,8 @@ jobs: if: steps.changes.outputs.changes == 'true' id: pr env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ secrets.SDK_REFERENCE_SYNC_PR_TOKEN != '' && secrets.SDK_REFERENCE_SYNC_PR_TOKEN || github.token }} + TOKEN_SOURCE: ${{ secrets.SDK_REFERENCE_SYNC_PR_TOKEN != '' && 'SDK_REFERENCE_SYNC_PR_TOKEN' || 'github.token' }} BASE_BRANCH: ${{ github.ref_name }} BRANCH_NAME: automation/sdk-reference-sync TRIGGER: ${{ steps.params.outputs.trigger }} @@ -179,6 +180,12 @@ jobs: fi echo "" >> $GITHUB_STEP_SUMMARY + if [[ "$PR_OPERATION" == "manual" ]]; then + echo "Automatic PR creation is blocked for \`github.token\` in this repository." >> $GITHUB_STEP_SUMMARY + echo "Enable the repository setting 'Allow GitHub Actions to create and approve pull requests' or add the \`SDK_REFERENCE_SYNC_PR_TOKEN\` secret for this workflow." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + fi + if [[ "$CHANGES" == "true" ]]; then echo "### Generated Files" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY diff --git a/scripts/create-sdk-reference-sync-pr.sh b/scripts/create-sdk-reference-sync-pr.sh index 9ecabbb5..441ab885 100644 --- a/scripts/create-sdk-reference-sync-pr.sh +++ b/scripts/create-sdk-reference-sync-pr.sh @@ -22,8 +22,9 @@ force="${FORCE:-false}" changed_files="${CHANGED_FILES:-0}" total_mdx_files="${TOTAL_MDX_FILES:-0}" workflow_name="${WORKFLOW_NAME:-}" -repository="${REPOSITORY:-}" -run_id="${RUN_ID:-}" +repository="${REPOSITORY:?REPOSITORY is required}" +run_id="${RUN_ID:?RUN_ID is required}" +token_source="${TOKEN_SOURCE:-github.token}" if [[ "$base_branch" == "$branch_name" ]]; then echo "Base branch and PR branch cannot be the same" >&2 @@ -45,6 +46,7 @@ if git diff --staged --quiet; then fi title="docs: sync SDK reference for ${sdk_name} ${sdk_version}" +compare_url="https://github.com/${repository}/compare/${base_branch}...${branch_name}?expand=1" git commit -m "$title" git push --force-with-lease origin "HEAD:${branch_name}" @@ -88,13 +90,24 @@ if [[ -n "$pr_info" ]]; then gh pr edit "$pr_number" --repo "$repository" --title "$title" --body-file "$body_file" >/dev/null operation="updated" else - pr_url="$(gh pr create \ + if ! pr_url="$(gh pr create \ --repo "$repository" \ --base "$base_branch" \ --head "$branch_name" \ --title "$title" \ - --body-file "$body_file")" - operation="created" + --body-file "$body_file" 2>&1)"; then + if [[ "$token_source" == "github.token" ]] && [[ "$pr_url" == *"GitHub Actions is not permitted to create or approve pull requests"* ]]; then + echo "Automatic PR creation is blocked for github.token in this repository." >&2 + echo "Enable the repository setting 'Allow GitHub Actions to create and approve pull requests' or configure the SDK_REFERENCE_SYNC_PR_TOKEN secret." >&2 + pr_url="$compare_url" + operation="manual" + else + echo "$pr_url" >&2 + exit 1 + fi + else + operation="created" + fi fi { From 71e91a6ad41bc6dffc11af5723ebd7c05154e19c Mon Sep 17 00:00:00 2001 From: ben-fornefeld Date: Tue, 17 Mar 2026 12:21:05 -0700 Subject: [PATCH 2/2] docs: use GitHub App token for sdk sync PRs --- .github/workflows/sdk-reference-sync.yml | 75 +++++++++------ scripts/create-sdk-reference-sync-pr.sh | 116 ----------------------- 2 files changed, 47 insertions(+), 144 deletions(-) delete mode 100644 scripts/create-sdk-reference-sync-pr.sh diff --git a/.github/workflows/sdk-reference-sync.yml b/.github/workflows/sdk-reference-sync.yml index f26f2879..64120dc3 100644 --- a/.github/workflows/sdk-reference-sync.yml +++ b/.github/workflows/sdk-reference-sync.yml @@ -29,6 +29,10 @@ on: schedule: - cron: "*/15 * * * *" +permissions: + contents: write + pull-requests: write + # prevent concurrent runs that could conflict concurrency: group: sdk-reference-${{ github.ref }} @@ -38,14 +42,19 @@ jobs: generate: runs-on: ubuntu-latest timeout-minutes: 30 - permissions: - contents: write - pull-requests: write steps: + - name: Generate GitHub App installation token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ vars.AUTOFIXER_APP_ID }} + private-key: ${{ secrets.AUTOFIXER_APP_SECRET }} + - name: Checkout docs repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: + token: ${{ steps.app-token.outputs.token }} fetch-depth: 0 - name: Setup Node.js @@ -133,22 +142,38 @@ jobs: - name: Commit changes and manage pull request if: steps.changes.outputs.changes == 'true' id: pr - env: - GH_TOKEN: ${{ secrets.SDK_REFERENCE_SYNC_PR_TOKEN != '' && secrets.SDK_REFERENCE_SYNC_PR_TOKEN || github.token }} - TOKEN_SOURCE: ${{ secrets.SDK_REFERENCE_SYNC_PR_TOKEN != '' && 'SDK_REFERENCE_SYNC_PR_TOKEN' || 'github.token' }} - BASE_BRANCH: ${{ github.ref_name }} - BRANCH_NAME: automation/sdk-reference-sync - TRIGGER: ${{ steps.params.outputs.trigger }} - SDK_NAME: ${{ steps.params.outputs.sdk }} - SDK_VERSION: ${{ steps.params.outputs.version }} - LIMIT_DISPLAY: ${{ steps.params.outputs.limit_display }} - FORCE: ${{ steps.params.outputs.force }} - CHANGED_FILES: ${{ steps.changes.outputs.changed_files }} - TOTAL_MDX_FILES: ${{ steps.changes.outputs.total_mdx_files }} - WORKFLOW_NAME: ${{ github.workflow }} - REPOSITORY: ${{ github.repository }} - RUN_ID: ${{ github.run_id }} - run: bash scripts/create-sdk-reference-sync-pr.sh + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ steps.app-token.outputs.token }} + branch: automation/sdk-reference-sync + delete-branch: true + add-paths: | + docs/sdk-reference + docs.json + author: github-actions[bot] + committer: github-actions[bot] + commit-message: docs: sync SDK reference for ${{ steps.params.outputs.sdk }} ${{ steps.params.outputs.version }} + title: docs: sync SDK reference for ${{ steps.params.outputs.sdk }} ${{ steps.params.outputs.version }} + body: | + ## Summary + This automated PR syncs generated SDK reference documentation. + + ## Trigger + - Source: `${{ steps.params.outputs.trigger }}` + - SDK: `${{ steps.params.outputs.sdk }}` + - Version: `${{ steps.params.outputs.version }}` + - Limit: `${{ steps.params.outputs.limit_display }}` + - Force: `${{ steps.params.outputs.force }}` + + ## Changes + - Updates generated reference files under `docs/sdk-reference/**` + - Updates `docs.json` navigation when generation changes the docs tree + - Changed files detected in this run: `${{ steps.changes.outputs.changed_files }}` + - Total tracked MDX reference files after generation: `${{ steps.changes.outputs.total_mdx_files }}` + + ## Run Details + - Workflow: `${{ github.workflow }}` + - Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - name: Summary env: @@ -160,8 +185,8 @@ jobs: CHANGES: ${{ steps.changes.outputs.changes }} CHANGED_FILES: ${{ steps.changes.outputs.changed_files }} TOTAL_MDX_FILES: ${{ steps.changes.outputs.total_mdx_files }} - PR_OPERATION: ${{ steps.pr.outputs.operation }} - PR_URL: ${{ steps.pr.outputs.url }} + PR_OPERATION: ${{ steps.pr.outputs.pull-request-operation }} + PR_URL: ${{ steps.pr.outputs.pull-request-url }} run: | echo "## SDK Reference Generation Complete" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY @@ -180,12 +205,6 @@ jobs: fi echo "" >> $GITHUB_STEP_SUMMARY - if [[ "$PR_OPERATION" == "manual" ]]; then - echo "Automatic PR creation is blocked for \`github.token\` in this repository." >> $GITHUB_STEP_SUMMARY - echo "Enable the repository setting 'Allow GitHub Actions to create and approve pull requests' or add the \`SDK_REFERENCE_SYNC_PR_TOKEN\` secret for this workflow." >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - fi - if [[ "$CHANGES" == "true" ]]; then echo "### Generated Files" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY diff --git a/scripts/create-sdk-reference-sync-pr.sh b/scripts/create-sdk-reference-sync-pr.sh deleted file mode 100644 index 441ab885..00000000 --- a/scripts/create-sdk-reference-sync-pr.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -if [[ -z "${GITHUB_OUTPUT:-}" ]]; then - echo "GITHUB_OUTPUT is required" >&2 - exit 1 -fi - -if [[ -z "${GH_TOKEN:-}" ]]; then - echo "GH_TOKEN is required" >&2 - exit 1 -fi - -base_branch="${BASE_BRANCH:?BASE_BRANCH is required}" -branch_name="${BRANCH_NAME:-automation/sdk-reference-sync}" -sdk_name="${SDK_NAME:-all}" -sdk_version="${SDK_VERSION:-latest}" -trigger="${TRIGGER:-unknown}" -limit_display="${LIMIT_DISPLAY:-5}" -force="${FORCE:-false}" -changed_files="${CHANGED_FILES:-0}" -total_mdx_files="${TOTAL_MDX_FILES:-0}" -workflow_name="${WORKFLOW_NAME:-}" -repository="${REPOSITORY:?REPOSITORY is required}" -run_id="${RUN_ID:?RUN_ID is required}" -token_source="${TOKEN_SOURCE:-github.token}" - -if [[ "$base_branch" == "$branch_name" ]]; then - echo "Base branch and PR branch cannot be the same" >&2 - exit 1 -fi - -git config user.name "github-actions[bot]" -git config user.email "github-actions[bot]@users.noreply.github.com" - -git switch -C "$branch_name" -git add docs/sdk-reference docs.json - -if git diff --staged --quiet; then - { - echo "operation=none" - echo "url=" - } >> "$GITHUB_OUTPUT" - exit 0 -fi - -title="docs: sync SDK reference for ${sdk_name} ${sdk_version}" -compare_url="https://github.com/${repository}/compare/${base_branch}...${branch_name}?expand=1" - -git commit -m "$title" -git push --force-with-lease origin "HEAD:${branch_name}" - -body_file="$(mktemp)" -trap 'rm -f "$body_file"' EXIT - -cat < "$body_file" -## Summary -This automated PR syncs generated SDK reference documentation. - -## Trigger -- Source: \`${trigger}\` -- SDK: \`${sdk_name}\` -- Version: \`${sdk_version}\` -- Limit: \`${limit_display}\` -- Force: \`${force}\` - -## Changes -- Updates generated reference files under \`docs/sdk-reference/**\` -- Updates \`docs.json\` navigation when generation changes the docs tree -- Changed files detected in this run: \`${changed_files}\` -- Total tracked MDX reference files after generation: \`${total_mdx_files}\` - -## Run Details -- Workflow: \`${workflow_name}\` -- Run: https://github.com/${repository}/actions/runs/${run_id} -EOF - -pr_info="$(gh pr list \ - --repo "$repository" \ - --base "$base_branch" \ - --head "$branch_name" \ - --state open \ - --json number,url \ - --jq '.[0]? | select(.) | [.number, .url] | @tsv')" - -if [[ -n "$pr_info" ]]; then - pr_number="${pr_info%%$'\t'*}" - pr_url="${pr_info#*$'\t'}" - gh pr edit "$pr_number" --repo "$repository" --title "$title" --body-file "$body_file" >/dev/null - operation="updated" -else - if ! pr_url="$(gh pr create \ - --repo "$repository" \ - --base "$base_branch" \ - --head "$branch_name" \ - --title "$title" \ - --body-file "$body_file" 2>&1)"; then - if [[ "$token_source" == "github.token" ]] && [[ "$pr_url" == *"GitHub Actions is not permitted to create or approve pull requests"* ]]; then - echo "Automatic PR creation is blocked for github.token in this repository." >&2 - echo "Enable the repository setting 'Allow GitHub Actions to create and approve pull requests' or configure the SDK_REFERENCE_SYNC_PR_TOKEN secret." >&2 - pr_url="$compare_url" - operation="manual" - else - echo "$pr_url" >&2 - exit 1 - fi - else - operation="created" - fi -fi - -{ - echo "operation=$operation" - echo "url=$pr_url" -} >> "$GITHUB_OUTPUT"