Monthly docs defragmentation #17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Monthly docs defragmentation | |
| on: | |
| schedule: | |
| - cron: "0 0 1 * *" # 1st of each month, midnight UTC | |
| workflow_dispatch: | |
| jobs: | |
| defrag: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "24" | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Install dependencies | |
| run: pnpm install | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| BRANCH="defrag-docs-$(date +%s)" | |
| git checkout -b "$BRANCH" | |
| echo "BRANCH=$BRANCH" >> "$GITHUB_ENV" | |
| # --------------------------------------------------------------- | |
| # Phase 1: Formatting (deterministic, no LLM) | |
| # --------------------------------------------------------------- | |
| - name: "Phase 1: Format docs" | |
| run: node scripts/format-docs.mjs 2>&1 | tee format-output.txt | |
| - name: Commit formatting changes | |
| run: | | |
| if [ -n "$(git status --porcelain docs/)" ]; then | |
| git add docs/ | |
| git commit -m "chore(defrag): phase 1 — formatting | |
| Mechanical fixes: trailing newlines, smart quotes, | |
| trailing whitespace, code block language tags. | |
| $(tail -10 format-output.txt)" | |
| else | |
| echo "No formatting changes" | |
| fi | |
| # --------------------------------------------------------------- | |
| # Phase 2: Content (LLM-powered, style-guided, size-limited) | |
| # --------------------------------------------------------------- | |
| - name: "Phase 2: Content defragmentation" | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: node scripts/defrag-docs.mjs 2>&1 | tee defrag-output.txt | |
| - name: Commit content changes | |
| run: | | |
| if [ -n "$(git status --porcelain docs/)" ]; then | |
| git add docs/ | |
| git commit -m "chore(defrag): phase 2 — content | |
| Terminology normalization, deduplication, cross-reference | |
| suggestions. Max 10 changed lines per diff hunk. | |
| $(tail -20 defrag-output.txt)" | |
| else | |
| echo "No content changes" | |
| fi | |
| # --------------------------------------------------------------- | |
| # Phase 3: Link repair (source-validated, no build needed) | |
| # --------------------------------------------------------------- | |
| - name: "Phase 3: Fix links" | |
| run: node scripts/fix-links.mjs 2>&1 | tee links-output.txt | |
| - name: Commit link fixes | |
| run: | | |
| if [ -n "$(git status --porcelain docs/)" ]; then | |
| git add docs/ | |
| git commit -m "chore(defrag): phase 3 — link repair | |
| Auto-fixed broken internal links validated against source files. | |
| Extension removals, path corrections, broken anchor cleanup. | |
| $(tail -15 links-output.txt)" | |
| else | |
| echo "No link fixes needed" | |
| fi | |
| # --------------------------------------------------------------- | |
| # Verify build after all phases | |
| # --------------------------------------------------------------- | |
| - name: Build site | |
| run: pnpm run build | |
| # --------------------------------------------------------------- | |
| # Create PR | |
| # --------------------------------------------------------------- | |
| - name: Create PR if changes exist | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Check if we have any commits beyond the initial checkout | |
| COMMIT_COUNT=$(git rev-list --count origin/main..HEAD) | |
| if [ "$COMMIT_COUNT" -eq 0 ]; then | |
| echo "No changes to submit" | |
| exit 0 | |
| fi | |
| git push origin "$BRANCH" | |
| FORMAT_SUMMARY=$(sed -n '/=== Summary ===/,$ p' format-output.txt 2>/dev/null || echo "No formatting output") | |
| DEFRAG_SUMMARY=$(sed -n '/=== Summary ===/,$ p' defrag-output.txt 2>/dev/null || echo "No defrag output") | |
| LINKS_SUMMARY=$(sed -n '/=== Summary ===/,$ p' links-output.txt 2>/dev/null || echo "No link repair output") | |
| gh pr create \ | |
| --title "chore: monthly docs defragmentation" \ | |
| --body "$(cat <<EOF | |
| ## Monthly docs defragmentation | |
| Automated review and cleanup of documentation pages. | |
| Each phase is a separate commit for easier review. | |
| ### Phase 1: Formatting (mechanical) | |
| Trailing newlines, smart quotes, whitespace, code block language tags. | |
| **Reviewers can skim this commit.** | |
| <details><summary>Phase 1 summary</summary> | |
| \`\`\` | |
| ${FORMAT_SUMMARY} | |
| \`\`\` | |
| </details> | |
| ### Phase 2: Content (LLM-generated) | |
| Terminology normalization per style guide, deduplication (max 10 lines per diff hunk), cross-reference suggestions. | |
| **Review this commit carefully.** | |
| <details><summary>Phase 2 summary</summary> | |
| \`\`\` | |
| ${DEFRAG_SUMMARY} | |
| \`\`\` | |
| </details> | |
| ### Phase 3: Link repair (source-validated) | |
| Auto-fixes broken internal links by validating against source files. | |
| Fixes extension removal (.md/.mdx), path corrections, and broken relative links. | |
| **Reviewers can skim this commit.** | |
| <details><summary>Phase 3 summary</summary> | |
| \`\`\` | |
| ${LINKS_SUMMARY} | |
| \`\`\` | |
| </details> | |
| ### Skipped changes | |
| Files with diff hunks >10 lines were skipped and filed as a GitHub issue for manual review. | |
| ### Review notes | |
| - The build has been verified to pass after all phases | |
| - Check for \`[TODO: link to X]\` markers that need resolution | |
| - Check for \`<!-- TODO: deduplicate -->\` comments flagging large removals | |
| - Check workflow output for unfixable links that need manual attention | |
| --- | |
| *This PR was automatically created by the monthly defragmentation workflow.* | |
| EOF | |
| )" \ | |
| --base main \ | |
| --head "$BRANCH" |