|
1 | 1 | name: Docs Quality |
| 2 | + |
2 | 3 | on: |
3 | 4 | pull_request: |
4 | | - workflow_dispatch: |
| 5 | + paths: |
| 6 | + - "docs/**/*.md" |
| 7 | + - "docs/**/*.mdx" |
| 8 | + - "_typos.toml" |
| 9 | + - ".github/workflows/docs-quality.yml" |
| 10 | + push: |
| 11 | + branches: [main] |
| 12 | + workflow_dispatch: {} |
| 13 | + |
| 14 | +permissions: |
| 15 | + contents: read |
| 16 | + |
5 | 17 | jobs: |
6 | 18 | typos: |
7 | 19 | name: Spelling (typos-cli) |
8 | 20 | runs-on: ubuntu-latest |
9 | 21 | steps: |
10 | | - - name: Checkout |
11 | | - uses: actions/checkout@v6 |
| 22 | + - uses: actions/checkout@v4 |
12 | 23 | - uses: crate-ci/typos@master |
13 | 24 |
|
14 | 25 | harper: |
15 | | - name: Grammar and Style Check |
| 26 | + name: Grammar & headings (Harper) |
16 | 27 | runs-on: ubuntu-latest |
17 | 28 | continue-on-error: true |
18 | 29 | steps: |
19 | | - - name: Checkout |
20 | | - uses: actions/checkout@v6 |
21 | | - - name: Restore Harper CLI cache |
| 30 | + - uses: actions/checkout@v4 |
| 31 | + |
| 32 | + - name: Cache harper-cli binary |
22 | 33 | id: cache-harper |
23 | | - uses: actions/cache/restore@v4 |
| 34 | + uses: actions/cache@v4 |
24 | 35 | with: |
25 | | - path: | |
26 | | - ~/.cargo/bin/harper-cli |
27 | | - ~/.cargo/registry |
28 | | - ~/.cargo/git |
29 | | - key: ${{ runner.os }}-harper-cli |
| 36 | + path: ~/.cargo/bin/harper-cli |
| 37 | + key: harper-cli-${{ runner.os }}-v1 |
30 | 38 | restore-keys: | |
31 | | - ${{ runner.os }}-harper-cli |
| 39 | + harper-cli-${{ runner.os }}- |
32 | 40 | - name: Report cache status |
33 | 41 | run: | |
34 | 42 | echo "cache-hit output: '${{ steps.cache-harper.outputs.cache-hit }}'" |
35 | | - ls -la ~/.cargo/bin/ 2>&1 || echo "~/.cargo/bin does not exist" |
36 | | - if [ -x ~/.cargo/bin/harper-cli ]; then |
37 | | - echo "RESULT: harper-cli binary present and executable" |
38 | | - ~/.cargo/bin/harper-cli --version || true |
| 43 | + if [ -f ~/.cargo/bin/harper-cli ]; then |
| 44 | + echo "harper-cli binary present at ~/.cargo/bin/harper-cli" |
39 | 45 | else |
40 | | - echo "RESULT: harper-cli binary NOT present -- full reinstall will run" |
| 46 | + echo "harper-cli binary NOT present -- will build from source" |
41 | 47 | fi |
42 | | - - name: Install Harper CLI |
| 48 | + - name: Install harper-cli |
43 | 49 | if: steps.cache-harper.outputs.cache-hit != 'true' |
44 | 50 | run: cargo install --locked --git https://github.com/Automattic/harper.git harper-cli |
| 51 | + |
45 | 52 | - name: Lint docs with Harper |
46 | 53 | run: | |
47 | 54 | set -uo pipefail |
48 | | - ONLY_RULES=( |
49 | | - UseTitleCase |
50 | | - RepeatedWords |
| 55 | + IGNORED_RULES=( |
| 56 | + SpellCheck |
| 57 | + OrthographicConsistency |
| 58 | + ProperNouns |
| 59 | + CompaniesProductsAndTrademarks |
| 60 | + GoogleNames MicrosoftNames AmazonNames AzureNames MetaNames |
| 61 | + LongSentences Hedging FillerWords |
| 62 | + ExpandStandardInputAndOutput ExpandTimeShorthands ExpandMemoryShorthands |
| 63 | + ExpandDirectory ExpandArgument ExpandParameter ExpandPointer |
| 64 | + ExpandDependencies ExpandControl ExpandAlgorithm ExpandAlloc |
| 65 | + ExpandDecl ExpandVulnerability |
51 | 66 | ) |
52 | | - ONLY_ARG="--only $(IFS=,; echo "${ONLY_RULES[*]}")" |
| 67 | + IGNORE_ARGS=() |
| 68 | + for r in "${IGNORED_RULES[@]}"; do IGNORE_ARGS+=(--ignore "$r"); done |
53 | 69 | out="$(mktemp)" |
54 | 70 | total=0 |
55 | 71 | bad=0 |
56 | 72 | while IFS= read -r -d '' file; do |
57 | 73 | total=$((total+1)) |
58 | 74 | echo "::group::$file" |
59 | | - if harper_out="$(harper-cli lint $ONLY_ARG "$file" 2>&1)"; then |
60 | | - echo "no issues" |
| 75 | + if harper-cli lint "${IGNORE_ARGS[@]}" "$file" 2>&1 | tee -a "$out"; then |
| 76 | + : |
61 | 77 | else |
62 | 78 | bad=$((bad+1)) |
63 | | - echo "$harper_out" |
64 | | - echo "$harper_out" >> "$out" |
65 | 79 | fi |
66 | 80 | echo "::endgroup::" |
67 | | - done < <( |
68 | | - find docs src/pages \ |
69 | | - -type f \( -name "*.md" -o -name "*.mdx" \) \ |
70 | | - -print0 2>/dev/null |
71 | | - ) |
| 81 | + done < <(find docs \( -name '*.md' -o -name '*.mdx' \) -print0) |
| 82 | + titlecase=$(grep -c 'Capitalization::UseTitleCase' "$out" || true) |
72 | 83 | { |
73 | 84 | echo "### Harper summary" |
74 | 85 | echo "- Files scanned: $total" |
75 | 86 | echo "- Files with issues: $bad" |
| 87 | + echo "- Heading (UseTitleCase) violations: $titlecase" |
76 | 88 | echo "" |
77 | 89 | echo "### Violations by rule" |
78 | 90 | echo '```' |
79 | | - grep -oE '\[[A-Za-z]+::[A-Za-z]+\]' "$out" | sort | uniq -c | sort -rn || true |
| 91 | + grep -oE '\[[A-Za-z]+::[A-Za-z]+\]' "$out" | sort | uniq -c | sort -rn |
80 | 92 | echo '```' |
81 | 93 | } >> "$GITHUB_STEP_SUMMARY" |
82 | | -
|
83 | | - echo "== Harper: $bad/$total files with issues ==" |
| 94 | + echo "== Harper: $bad/$total files with issues; $titlecase UseTitleCase violations ==" |
84 | 95 | [ "$bad" -eq 0 ] |
85 | | -
|
86 | | - - name: Save Harper CLI cache |
87 | | - if: always() && steps.cache-harper.outputs.cache-hit != 'true' |
88 | | - uses: actions/cache/save@v4 |
89 | | - with: |
90 | | - path: | |
91 | | - ~/.cargo/bin/harper-cli |
92 | | - ~/.cargo/registry |
93 | | - ~/.cargo/git |
94 | | - key: ${{ runner.os }}-harper-cli |
|
0 commit comments