Add Harper workflow for grammar and style checks #19
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: Harper | |
| on: | |
| pull_request: | |
| workflow_dispatch: | |
| jobs: | |
| harper: | |
| name: Grammar and Style Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Cache Cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-harper-${{ hashFiles('.github/workflows/harper.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-harper- | |
| - name: Install Harper CLI | |
| run: | | |
| if ! command -v harper-cli >/dev/null 2>&1; then | |
| cargo install --git https://github.com/Automattic/harper harper-cli --locked | |
| else | |
| echo "Harper CLI found in cache." | |
| fi | |
| - name: Generate Harper JSON Report | |
| run: | | |
| find docs src/pages -type f \( -name "*.md" -o -name "*.mdx" \) -print0 | \ | |
| xargs -0 harper-cli lint \ | |
| --user-dict-path ./.harper-dictionary.txt \ | |
| --format json \ | |
| > harper-report.json || true | |
| - name: Extract Spelling Candidates | |
| run: | | |
| python - <<'PY' | |
| import json | |
| with open("harper-report.json", encoding="utf-8") as f: | |
| reports = json.load(f) | |
| words = set() | |
| for report in reports: | |
| for lint in report.get("lints", []): | |
| if lint.get("kind") == "Spelling": | |
| word = lint.get("matched_text") | |
| if word: | |
| words.add(word) | |
| print("Suggested dictionary candidates:") | |
| for word in sorted(words, key=str.lower): | |
| print(word) | |
| PY | |
| - name: Check Selected Harper Rules | |
| run: | | |
| python - <<'PY' | |
| import json | |
| import sys | |
| with open("harper-report.json", encoding="utf-8") as f: | |
| reports = json.load(f) | |
| selected = [] | |
| for report in reports: | |
| file = report.get("file") | |
| for lint in report.get("lints", []): | |
| kind = lint.get("kind") | |
| rule = lint.get("rule") | |
| line_no = lint.get("line") | |
| message = lint.get("message") | |
| text = lint.get("matched_text") | |
| if kind in {"Spelling", "Grammar", "Repetition"}: | |
| selected.append( | |
| f"{file}:{line_no}: [{kind}::{rule}] {text!r} - {message}" | |
| ) | |
| if selected: | |
| print("Selected Harper lints found:") | |
| for item in selected: | |
| print(item) | |
| sys.exit(1) | |
| print("No selected Harper lints found.") | |
| PY |