Skip to content

Monthly docs defragmentation #12

Monthly docs defragmentation

Monthly docs defragmentation #12

Workflow file for this run

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 +%Y%m%d)"
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 }}
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. Changes capped at 10 net removed lines per file.
$(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 (capped at 10 lines removed per file), 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 where the LLM suggested removing >10 lines are listed in the workflow output.
These need manual review and may warrant separate issues.
### 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"