Skip to content

Monthly docs defragmentation #26

Monthly docs defragmentation

Monthly docs defragmentation #26

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 +%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"