Monthly docs defragmentation #29
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 2a: Sentence formatting (LLM, narrowly scoped) | |
| # --------------------------------------------------------------- | |
| - name: "Phase 2a: Sentence formatting" | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| run: node scripts/defrag-sentence.mjs 2>&1 | tee sentence-output.txt | |
| - name: Commit sentence formatting changes | |
| run: | | |
| if [ -n "$(git status --porcelain docs/)" ]; then | |
| git add docs/ | |
| git commit -m "chore(defrag): phase 2a — sentence formatting | |
| One sentence per line, contraction expansion. | |
| $(tail -10 sentence-output.txt)" | |
| else | |
| echo "No sentence formatting changes" | |
| fi | |
| # --------------------------------------------------------------- | |
| # Phase 2b: Terminology normalization (LLM, narrowly scoped) | |
| # --------------------------------------------------------------- | |
| - name: "Phase 2b: Terminology normalization" | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| run: node scripts/defrag-terminology.mjs 2>&1 | tee terminology-output.txt | |
| - name: Commit terminology changes | |
| run: | | |
| if [ -n "$(git status --porcelain docs/)" ]; then | |
| git add docs/ | |
| git commit -m "chore(defrag): phase 2b — terminology | |
| Proper noun capitalization, hyphenation. | |
| $(tail -10 terminology-output.txt)" | |
| else | |
| echo "No terminology changes" | |
| fi | |
| # --------------------------------------------------------------- | |
| # Phase 3: Link repair (source-validated, no LLM) | |
| # --------------------------------------------------------------- | |
| - 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 editing phases | |
| # --------------------------------------------------------------- | |
| - name: Build site | |
| run: pnpm run build | |
| # --------------------------------------------------------------- | |
| # Phase 4: Cross-page analysis (LLM, opens issue, no file edits) | |
| # --------------------------------------------------------------- | |
| - name: "Phase 4: Cross-page analysis" | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: node scripts/defrag-analysis.mjs 2>&1 | tee analysis-output.txt | |
| # --------------------------------------------------------------- | |
| # Create PR if any editing phases made changes | |
| # --------------------------------------------------------------- | |
| - 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 output") | |
| SENTENCE_SUMMARY=$(sed -n '/=== Summary ===/,$ p' sentence-output.txt 2>/dev/null || echo "No output") | |
| TERMINOLOGY_SUMMARY=$(sed -n '/=== Summary ===/,$ p' terminology-output.txt 2>/dev/null || echo "No output") | |
| LINKS_SUMMARY=$(sed -n '/=== Summary ===/,$ p' links-output.txt 2>/dev/null || echo "No 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. | |
| <details><summary>Summary</summary> | |
| \`\`\` | |
| ${FORMAT_SUMMARY} | |
| \`\`\` | |
| </details> | |
| ### Phase 2a: Sentence formatting (LLM) | |
| One sentence per line, contraction expansion. No other changes. | |
| <details><summary>Summary</summary> | |
| \`\`\` | |
| ${SENTENCE_SUMMARY} | |
| \`\`\` | |
| </details> | |
| ### Phase 2b: Terminology (LLM) | |
| Proper noun capitalization, hyphenation. No other changes. | |
| <details><summary>Summary</summary> | |
| \`\`\` | |
| ${TERMINOLOGY_SUMMARY} | |
| \`\`\` | |
| </details> | |
| ### Phase 3: Link repair (source-validated) | |
| Auto-fixes broken internal links. | |
| <details><summary>Summary</summary> | |
| \`\`\` | |
| ${LINKS_SUMMARY} | |
| \`\`\` | |
| </details> | |
| ### Phase 4: Cross-page analysis | |
| Structural issues (redundancy, missing cross-references, content relocations) were filed as a separate GitHub issue for interactive resolution. | |
| --- | |
| *This PR was automatically created by the monthly defragmentation workflow.* | |
| EOF | |
| )" \ | |
| --base main \ | |
| --head "$BRANCH" |