Skip to content

Commit c9669a3

Browse files
committed
Create generated docs sync PRs
1 parent e7d1dea commit c9669a3

1 file changed

Lines changed: 57 additions & 22 deletions

File tree

.github/workflows/generated-docs-sync.yaml

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,12 @@ jobs:
8686
path: ${{ runner.temp }}/generated-docs.patch
8787
if-no-files-found: error
8888

89-
push:
89+
create-sync-pr:
9090
needs: generate
91+
if: needs.generate.outputs.has_changes == 'true'
9192
runs-on: ubuntu-latest
9293
permissions:
93-
contents: write
94-
outputs:
95-
final_sha: ${{ steps.record_sha.outputs.final_sha }}
94+
contents: read
9695
steps:
9796
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
9897
with:
@@ -105,15 +104,21 @@ jobs:
105104
with:
106105
name: generated-docs-patch
107106
path: ${{ runner.temp }}
108-
# Use GITHUB_TOKEN intentionally so this sync commit does not fan out into
109-
# another push-triggered workflow run. Docs deployment is chained below.
110-
- name: Commit generated docs
111-
if: needs.generate.outputs.has_changes == 'true'
107+
# Use a narrowly-scoped GitHub App token so branch/PR events run normal
108+
# checks without granting the workflow permission to bypass main rules.
109+
- name: Create GitHub App token
110+
id: app-token
111+
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
112+
with:
113+
app-id: ${{ secrets.GENERATED_DOCS_APP_ID }}
114+
private-key: ${{ secrets.GENERATED_DOCS_APP_PRIVATE_KEY }}
115+
- name: Create or update generated docs PR
112116
env:
113-
GH_TOKEN: ${{ github.token }}
117+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
114118
TARGET_REPO: ${{ github.repository }}
115119
TARGET_REF: ${{ github.ref_name }}
116120
PATCH_PATH: ${{ runner.temp }}/generated-docs.patch
121+
SYNC_BRANCH: docs/generated-docs-sync
117122
run: |
118123
set -euo pipefail
119124
git apply --index --whitespace=nowarn "$PATCH_PATH"
@@ -123,25 +128,55 @@ jobs:
123128
git config user.name "github-actions[bot]"
124129
git config user.email "github-actions[bot]@users.noreply.github.com"
125130
git commit -m "docs: sync generated docs"
126-
git fetch origin "${TARGET_REF}"
127-
git rebase "origin/${TARGET_REF}"
128-
git push "https://x-access-token:${GH_TOKEN}@github.com/${TARGET_REPO}.git" "HEAD:${TARGET_REF}"
129-
- name: Record final revision
130-
id: record_sha
131-
env:
132-
DEFAULT_SHA: ${{ github.sha }}
133-
run: |
134-
if [ "${{ needs.generate.outputs.has_changes }}" = "true" ]; then
135-
echo "final_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
131+
132+
remote_url="https://x-access-token:${GH_TOKEN}@github.com/${TARGET_REPO}.git"
133+
remote_sha="$(git ls-remote --heads "$remote_url" "$SYNC_BRANCH" | awk '{print $1}')"
134+
if [ -n "$remote_sha" ]; then
135+
git push --force-with-lease="refs/heads/${SYNC_BRANCH}:${remote_sha}" \
136+
"$remote_url" \
137+
"HEAD:refs/heads/${SYNC_BRANCH}"
138+
else
139+
git push "$remote_url" "HEAD:refs/heads/${SYNC_BRANCH}"
140+
fi
141+
142+
pr_body="$(mktemp)"
143+
cat > "$pr_body" <<EOF
144+
Generated docs are out of sync with main.
145+
146+
This PR was created automatically after a push to ${TARGET_REF} at ${GITHUB_SHA}.
147+
EOF
148+
149+
target_owner="${TARGET_REPO%%/*}"
150+
existing_pr="$(
151+
gh pr list \
152+
--repo "$TARGET_REPO" \
153+
--base "$TARGET_REF" \
154+
--head "${target_owner}:${SYNC_BRANCH}" \
155+
--state open \
156+
--json number \
157+
--jq '.[0].number // empty'
158+
)"
159+
160+
if [ -n "$existing_pr" ]; then
161+
gh pr edit "$existing_pr" \
162+
--repo "$TARGET_REPO" \
163+
--title "Sync generated docs" \
164+
--body-file "$pr_body"
136165
else
137-
echo "final_sha=${DEFAULT_SHA}" >> "$GITHUB_OUTPUT"
166+
gh pr create \
167+
--repo "$TARGET_REPO" \
168+
--base "$TARGET_REF" \
169+
--head "${target_owner}:${SYNC_BRANCH}" \
170+
--title "Sync generated docs" \
171+
--body-file "$pr_body"
138172
fi
139173
140174
deploy-docs:
141-
needs: push
175+
needs: [generate, create-sync-pr]
176+
if: always() && needs.generate.result == 'success' && needs.generate.outputs.has_changes == 'false'
142177
uses: ./.github/workflows/docs-deploy.yaml
143178
with:
144-
checkout_ref: ${{ needs.push.outputs.final_sha }}
179+
checkout_ref: ${{ github.sha }}
145180
deploy_branch: dev
146181
secrets:
147182
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}

0 commit comments

Comments
 (0)