Skip to content

Commit 8288f90

Browse files
authored
Merge pull request #44470 from github/repo-sync
Repo sync
2 parents 5559346 + 3bb0e43 commit 8288f90

18 files changed

Lines changed: 1509 additions & 28 deletions

File tree

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
name: 'Sync Copilot SDK docs'
2+
3+
on:
4+
# Event-driven sync — triggered by copilot-sdk when docs/ changes are pushed
5+
repository_dispatch:
6+
types: [sync-sdk-docs]
7+
8+
# Manual trigger for on-demand syncs and testing
9+
workflow_dispatch:
10+
inputs:
11+
dry_run:
12+
description: 'Dry run — run normalization but skip push and PR creation'
13+
required: false
14+
default: 'false'
15+
type: boolean
16+
source_ref:
17+
description: 'copilot-sdk ref to sync from (branch, tag, or SHA). Defaults to main.'
18+
required: false
19+
default: 'main'
20+
type: string
21+
22+
# PR validation — dry-run only, verifies scripts work on CI
23+
pull_request:
24+
types: [opened, synchronize, reopened]
25+
paths:
26+
- '.github/workflows/sync-sdk-docs.yml'
27+
- 'src/scripts/sync-sdk-docs/**'
28+
29+
concurrency:
30+
group: sync-sdk-docs-${{ github.event_name }}
31+
cancel-in-progress: true
32+
33+
permissions:
34+
contents: write
35+
pull-requests: write
36+
37+
jobs:
38+
sync-docs:
39+
name: 'Sync SDK docs'
40+
if: github.repository == 'github/docs-internal'
41+
runs-on: ubuntu-latest
42+
env:
43+
SDK_DOCS_TARGET: content/copilot/how-tos/copilot-sdk
44+
SYNC_BRANCH: sdk-docs/auto-sync
45+
ASSETS_TARGET: assets/images/help/copilot/copilot-sdk
46+
SOURCE_REF: ${{ inputs.source_ref || 'main' }}
47+
48+
steps:
49+
- name: Checkout docs-internal
50+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
51+
52+
- name: Fetch SDK docs from copilot-sdk
53+
env:
54+
GH_TOKEN: ${{ secrets.DOCS_BOT_PAT_BASE }}
55+
run: |
56+
set -e
57+
tmp=$(mktemp -d)
58+
echo "Cloning copilot-sdk@$SOURCE_REF (sparse: docs/ only)..."
59+
git clone --depth 1 --branch "$SOURCE_REF" --filter=blob:none --sparse \
60+
"https://x-access-token:${GH_TOKEN}@github.com/github/copilot-sdk.git" "$tmp" 2>&1 | tail -1
61+
cd "$tmp" && git sparse-checkout set docs 2>/dev/null
62+
SDK_SHA=$(git -C "$tmp" rev-parse HEAD)
63+
echo "SDK_SHA=$SDK_SHA" >> "$GITHUB_ENV"
64+
echo "SDK_TMP=$tmp" >> "$GITHUB_ENV"
65+
echo "Fetched copilot-sdk@${SDK_SHA::7}"
66+
67+
- name: Setup Node.js
68+
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
69+
with:
70+
node-version: 22
71+
cache: npm
72+
73+
- name: Install dependencies
74+
run: npm ci
75+
76+
- name: Install mermaid-cli
77+
run: npm install -g @mermaid-js/mermaid-cli@11
78+
79+
- name: Clean existing SDK docs
80+
run: |
81+
rm -rf "$SDK_DOCS_TARGET"
82+
83+
- name: Copy SDK docs
84+
run: |
85+
mkdir -p "$SDK_DOCS_TARGET"
86+
rsync -av --exclude='.validation/' "$SDK_TMP/docs/" "$SDK_DOCS_TARGET/"
87+
echo "Copied $(find "$SDK_DOCS_TARGET" -name '*.md' | wc -l | tr -d ' ') markdown files"
88+
89+
- name: Normalize content
90+
run: |
91+
npx tsx src/scripts/sync-sdk-docs/normalize-sdk-docs.ts \
92+
--content-dir content \
93+
--sdk-docs-dir "$SDK_DOCS_TARGET"
94+
95+
- name: Convert Mermaid diagrams to PNG
96+
env:
97+
PUPPETEER_CHROMIUM_REVISION: ''
98+
run: |
99+
# Puppeteer needs --no-sandbox on GitHub Actions runners
100+
echo '{ "args": ["--no-sandbox", "--disable-setuid-sandbox"] }' > /tmp/puppeteer-config.json
101+
npx tsx src/scripts/sync-sdk-docs/convert-mermaid.ts \
102+
--sdk-docs-dir "$SDK_DOCS_TARGET" \
103+
--assets-dir "$ASSETS_TARGET" \
104+
--repo-root . \
105+
--puppeteer-config /tmp/puppeteer-config.json
106+
107+
- name: Remove stale SDK assets
108+
run: |
109+
if [ ! -d "$ASSETS_TARGET" ]; then
110+
echo "No assets directory — nothing to clean."
111+
exit 0
112+
fi
113+
# Collect image filenames referenced in the current SDK docs
114+
REFERENCED=$(grep -roh '/assets/images/help/copilot/copilot-sdk/[^)]*' "$SDK_DOCS_TARGET" \
115+
| sed 's|.*/||' | sort -u)
116+
STALE=0
117+
for file in "$ASSETS_TARGET"/*.png; do
118+
[ -f "$file" ] || continue
119+
BASENAME=$(basename "$file")
120+
if ! echo "$REFERENCED" | grep -qxF "$BASENAME"; then
121+
echo " STALE: $BASENAME"
122+
rm "$file"
123+
STALE=$((STALE + 1))
124+
fi
125+
done
126+
echo "Removed $STALE stale asset(s)."
127+
128+
- name: Lint SDK content (non-blocking)
129+
continue-on-error: true
130+
run: |
131+
SDK_FILES=$(find "$SDK_DOCS_TARGET" -name '*.md' | tr '\n' ' ')
132+
if [ -z "$SDK_FILES" ]; then
133+
echo "No SDK markdown files to lint."
134+
exit 0
135+
fi
136+
echo "Linting $(echo "$SDK_FILES" | wc -w | tr -d ' ') SDK files..."
137+
if npm run lint-content -- --paths $SDK_FILES; then
138+
echo "✅ Content linter passed — no issues found."
139+
else
140+
echo ""
141+
echo "⚠️ Content linter found issues (see above)."
142+
echo "These will appear as CI failures on the generated PR."
143+
echo "Fix them in the copilot-sdk source docs or update the normalize script."
144+
fi
145+
146+
- name: Show diff summary
147+
run: |
148+
git add -A
149+
if git diff --cached --quiet; then
150+
echo "No changes detected."
151+
echo "has_changes=false" >> "$GITHUB_ENV"
152+
else
153+
echo "has_changes=true" >> "$GITHUB_ENV"
154+
echo "Changes detected:"
155+
git diff --cached --stat
156+
fi
157+
158+
# --- PR-only: upload artifacts for review ---
159+
- name: Upload normalized docs (PR validation)
160+
if: github.event_name == 'pull_request'
161+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
162+
with:
163+
name: normalized-sdk-docs
164+
path: |
165+
${{ env.SDK_DOCS_TARGET }}
166+
${{ env.ASSETS_TARGET }}
167+
retention-days: 7
168+
169+
# --- Push and PR (only on schedule/dispatch, not dry-run, and changes exist) ---
170+
- name: Commit and push
171+
if: >-
172+
env.has_changes == 'true'
173+
&& github.event_name != 'pull_request'
174+
&& inputs.dry_run != 'true'
175+
env:
176+
GH_TOKEN: ${{ secrets.DOCS_BOT_PAT_BASE }}
177+
run: |
178+
git config user.name "github-actions[bot]"
179+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
180+
181+
# Fetch the sync branch if it exists so force-with-lease knows the remote state
182+
git fetch origin "$SYNC_BRANCH" 2>/dev/null || true
183+
184+
git checkout -B "$SYNC_BRANCH"
185+
git commit -m "Sync Copilot SDK docs from copilot-sdk@${SDK_SHA::7}
186+
187+
Source commit: https://github.com/github/copilot-sdk/commit/$SDK_SHA
188+
189+
This commit was automatically generated by the sync-sdk-docs workflow."
190+
191+
git push --force-with-lease origin "$SYNC_BRANCH"
192+
193+
- name: Create or update pull request
194+
if: >-
195+
env.has_changes == 'true'
196+
&& github.event_name != 'pull_request'
197+
&& inputs.dry_run != 'true'
198+
env:
199+
GH_TOKEN: ${{ secrets.DOCS_BOT_PAT_BASE }}
200+
run: |
201+
PR_TITLE="Sync Copilot SDK docs (auto-generated)"
202+
PR_BODY="## Summary
203+
204+
This PR syncs documentation from [\`github/copilot-sdk/docs\`](https://github.com/github/copilot-sdk/tree/main/docs) to \`content/copilot/how-tos/copilot-sdk/\`.
205+
206+
**Source commit:** https://github.com/github/copilot-sdk/commit/$SDK_SHA
207+
208+
### What this PR does
209+
- Copies SDK documentation from \`copilot-sdk\`
210+
- Adds YAML frontmatter for docs.github.com publishing
211+
- Converts internal links to AUTOTITLE format
212+
- Converts Mermaid diagrams to PNG images
213+
- Normalizes code fence languages and list formatting
214+
215+
> [!NOTE]
216+
> This PR is auto-generated. Do not edit it directly — make changes in the [copilot-sdk docs](https://github.com/github/copilot-sdk/tree/main/docs) instead.
217+
218+
---
219+
_Generated by the [sync-sdk-docs](https://github.com/github/docs-internal/actions/workflows/sync-sdk-docs.yml) workflow._"
220+
221+
EXISTING_PR=$(gh pr list --head "$SYNC_BRANCH" --json number --jq '.[0].number' 2>/dev/null || true)
222+
223+
if [ -n "$EXISTING_PR" ]; then
224+
echo "Updating existing PR #$EXISTING_PR"
225+
gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
226+
gh pr comment "$EXISTING_PR" --body "🔄 Updated with changes from [\`${SDK_SHA::7}\`](https://github.com/github/copilot-sdk/commit/$SDK_SHA)."
227+
else
228+
echo "Creating new PR"
229+
gh pr create \
230+
--title "$PR_TITLE" \
231+
--body "$PR_BODY" \
232+
--base main \
233+
--head "$SYNC_BRANCH" \
234+
--label "copilot-sdk-docs,workflow-generated"
235+
fi
236+
237+
- name: Cleanup
238+
if: always()
239+
run: rm -rf "$SDK_TMP"
240+
241+
- uses: ./.github/actions/slack-alert
242+
if: ${{ failure() && github.event_name != 'workflow_dispatch' }}
243+
with:
244+
slack_channel_id: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }}
245+
slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
246+
247+
- uses: ./.github/actions/create-workflow-failure-issue
248+
if: ${{ failure() && github.event_name != 'workflow_dispatch' }}
249+
with:
250+
token: ${{ secrets.DOCS_BOT_PAT_BASE }}

0 commit comments

Comments
 (0)