Skip to content

Commit 5bb7c19

Browse files
committed
ci(docs-sync): auto-open PR instead of warn-and-skip on conflict
1 parent bd15790 commit 5bb7c19

2 files changed

Lines changed: 268 additions & 42 deletions

File tree

.github/workflows/showcase_docs-sync.yml

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,31 @@ jobs:
8383
app-id: 1108748
8484
private-key: ${{ secrets.DEVOPS_BOT_PRIVATE_KEY }}
8585

86-
# Create PR and auto-merge via devops bot (bypasses branch protection)
87-
- name: Create and merge PR for clean transforms
86+
# Create PR. For action=auto_push (no review items) the PR is
87+
# auto-merged via the devops bot (bypasses branch protection). For
88+
# action=push_and_pr the sync script has already written best-effort
89+
# 3-way merged content to disk — this step commits it and opens a PR
90+
# tagged [NEEDS REVIEW]. Auto-merge is DISABLED for needs-review PRs
91+
# so a human reconciles any upstream-wins overrides.
92+
- name: Create PR for docs sync
8893
id: push
8994
if: steps.sync.outputs.action == 'auto_push' || steps.sync.outputs.action == 'push_and_pr'
9095
env:
9196
GH_TOKEN: ${{ steps.bot-token.outputs.token }}
97+
ACTION: ${{ steps.sync.outputs.action }}
98+
REVIEW_ITEMS_FILE: ${{ steps.sync.outputs.review_items_file }}
9299
run: |
93100
git config user.name "copilotkit-devops-bot[bot]"
94101
git config user.email "copilotkit-devops-bot[bot]@users.noreply.github.com"
95102
96103
SHORT_SHA=$(git rev-parse --short origin/main)
97-
BRANCH="docs-sync/auto/${SHORT_SHA}-$(date +%s)"
104+
if [ "$ACTION" = "push_and_pr" ]; then
105+
BRANCH="docs-sync/needs-review/${SHORT_SHA}-$(date +%s)"
106+
COMMIT_SUBJECT="chore: docs sync from main — needs review ($(date +%Y-%m-%d))"
107+
else
108+
BRANCH="docs-sync/auto/${SHORT_SHA}-$(date +%s)"
109+
COMMIT_SUBJECT="chore: auto-sync docs from main ($(date +%Y-%m-%d))"
110+
fi
98111
99112
git checkout -b "$BRANCH"
100113
git add showcase/shell/src/content/ showcase/shell/.docs-sync-sha
@@ -109,27 +122,76 @@ jobs:
109122
exit 0
110123
fi
111124
112-
git commit --no-verify -m "chore: auto-sync docs from main ($(date +%Y-%m-%d))"
125+
git commit --no-verify -m "$COMMIT_SUBJECT"
113126
114127
# Override git credential to use bot token (checkout configured GITHUB_TOKEN)
115128
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git"
116129
git push origin "$BRANCH"
117130
118-
PR_URL=$(gh pr create \
119-
--title "chore: auto-sync docs from main (${SHORT_SHA})" \
120-
--body "Automated docs sync. Clean transforms only." \
121-
--base "$SHOWCASE_BRANCH" \
122-
--head "$BRANCH")
123-
124-
echo "Created PR: $PR_URL"
125-
echo "files_changed=${CHANGED}" >> "$GITHUB_OUTPUT"
126-
echo "pr_url=${PR_URL}" >> "$GITHUB_OUTPUT"
127-
# Only set pr_opened=true after the PR URL is captured. Any earlier
128-
# failure (push, gh pr create) will leave this unset so downstream
129-
# alerts fall through to failure() instead of a falsely-benign path.
130-
echo "pr_opened=true" >> "$GITHUB_OUTPUT"
131-
132-
gh pr merge "$PR_URL" --merge
131+
if [ "$ACTION" = "push_and_pr" ]; then
132+
# Build the PR body from review-items.txt plus a clear callout.
133+
REVIEW_ITEMS_CONTENT="(no review-items file produced)"
134+
if [ -n "${REVIEW_ITEMS_FILE:-}" ] && [ -f "$REVIEW_ITEMS_FILE" ]; then
135+
REVIEW_ITEMS_CONTENT=$(cat "$REVIEW_ITEMS_FILE")
136+
fi
137+
PR_BODY_FILE=$(mktemp)
138+
{
139+
echo ":warning: **Docs sync — MANUAL REVIEW REQUIRED**"
140+
echo ""
141+
echo "This PR was auto-opened because the docs-sync script detected"
142+
echo "showcase-local modifications overlapping with upstream changes."
143+
echo ""
144+
echo "The script attempted a best-effort 3-way merge:"
145+
echo ""
146+
echo "- Where \`git merge-file\` produced a clean merge, the merged content was written."
147+
echo "- Where \`git merge-file\` produced conflict markers, **upstream content was written as-is** and showcase-local modifications were overridden. **Manual review required.**"
148+
echo ""
149+
echo "### Review items"
150+
echo ""
151+
echo '```'
152+
echo "$REVIEW_ITEMS_CONTENT"
153+
echo '```'
154+
echo ""
155+
echo "### Source"
156+
echo ""
157+
echo "- Upstream ref: [\`${SHORT_SHA}\`](https://github.com/${{ github.repository }}/commit/${SHORT_SHA})"
158+
echo "- Workflow run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
159+
echo ""
160+
echo "**Review before merging.** Auto-merge is intentionally disabled"
161+
echo "for \`needs-review\` PRs — confirm the upstream-wins sections"
162+
echo "preserve any intentional showcase-local divergence you want to"
163+
echo "keep, then merge manually."
164+
} > "$PR_BODY_FILE"
165+
166+
PR_URL=$(gh pr create \
167+
--title "docs-sync(needs-review): sync from main (${SHORT_SHA}) [NEEDS REVIEW]" \
168+
--body-file "$PR_BODY_FILE" \
169+
--base "$SHOWCASE_BRANCH" \
170+
--head "$BRANCH")
171+
172+
echo "Created NEEDS-REVIEW PR: $PR_URL"
173+
echo "files_changed=${CHANGED}" >> "$GITHUB_OUTPUT"
174+
echo "pr_url=${PR_URL}" >> "$GITHUB_OUTPUT"
175+
# Only set after URL captured — error paths leave this unset so
176+
# downstream alerts fall through to failure().
177+
echo "pr_opened=true" >> "$GITHUB_OUTPUT"
178+
echo "needs_review=true" >> "$GITHUB_OUTPUT"
179+
# Intentionally no `gh pr merge` — human must review & merge.
180+
else
181+
PR_URL=$(gh pr create \
182+
--title "chore: auto-sync docs from main (${SHORT_SHA})" \
183+
--body "Automated docs sync. Clean transforms / clean 3-way merges only." \
184+
--base "$SHOWCASE_BRANCH" \
185+
--head "$BRANCH")
186+
187+
echo "Created PR: $PR_URL"
188+
echo "files_changed=${CHANGED}" >> "$GITHUB_OUTPUT"
189+
echo "pr_url=${PR_URL}" >> "$GITHUB_OUTPUT"
190+
echo "pr_opened=true" >> "$GITHUB_OUTPUT"
191+
echo "needs_review=false" >> "$GITHUB_OUTPUT"
192+
193+
gh pr merge "$PR_URL" --merge
194+
fi
133195
134196
# Build all Slack payloads via jq into tmpfiles. This guarantees any
135197
# review-item filename containing ", \, or control chars is safely
@@ -174,13 +236,16 @@ jobs:
174236
--arg items "$REVIEW_ITEMS" \
175237
--arg pr_url "${PR_URL:-}" \
176238
--arg run_url "$RUN_URL" \
177-
'{text: (":warning: *Docs sync*: files needing manual review\n```" + $items + "```\nReview: " + $pr_url + "\n<" + $run_url + "|View run>")}' \
239+
'{text: (":warning: *Docs sync*: auto-opened *NEEDS REVIEW* PR (best-effort 3-way merge; upstream-wins where conflicts) — human must review + merge\n```" + $items + "```\nReview: " + $pr_url + "\n<" + $run_url + "|View run>")}' \
178240
> slack-payloads/review-with-pr.json
179241
242+
# Fallback path: review items flagged but no PR opened (e.g. 3-way
243+
# merge produced bit-for-bit identical content to what's already on
244+
# disk so nothing to commit). Keep an alert so it's visible.
180245
jq -n \
181246
--arg items "$REVIEW_ITEMS" \
182247
--arg run_url "$RUN_URL" \
183-
'{text: (":warning: *Docs sync*: files needing manual review (no auto-PR opened)\n```" + $items + "```\n<" + $run_url + "|View run>")}' \
248+
'{text: (":warning: *Docs sync*: review items flagged but produced no diff (no PR opened)\n```" + $items + "```\n<" + $run_url + "|View run>")}' \
184249
> slack-payloads/review-no-pr.json
185250
186251
# failure alert
@@ -200,7 +265,7 @@ jobs:
200265
201266
- name: Notify Slack (auto-sync)
202267
id: notify-auto-sync
203-
if: always() && steps.push.outcome == 'success' && steps.push.outputs.files_changed != '0'
268+
if: always() && steps.push.outcome == 'success' && steps.push.outputs.files_changed != '0' && steps.push.outputs.needs_review != 'true'
204269
uses: slackapi/slack-github-action@v2.1.0
205270
with:
206271
webhook: ${{ secrets.SLACK_WEBHOOK_OSS_ALERTS }}
@@ -209,7 +274,7 @@ jobs:
209274

210275
- name: Notify Slack (merge failed)
211276
id: notify-merge-failed
212-
if: failure() && steps.push.outputs.pr_opened == 'true'
277+
if: failure() && steps.push.outputs.pr_opened == 'true' && steps.push.outputs.needs_review != 'true'
213278
uses: slackapi/slack-github-action@v2.1.0
214279
with:
215280
webhook: ${{ secrets.SLACK_WEBHOOK_OSS_ALERTS }}

0 commit comments

Comments
 (0)