Skip to content

Manual Spellcheck Review & Approval #164

Manual Spellcheck Review & Approval

Manual Spellcheck Review & Approval #164

Workflow file for this run

name: Manual Spellcheck Review & Approval
on:
workflow_dispatch: # Runs only when manually triggered
permissions:
contents: write # Needed to push changes after approval
jobs:
spellcheck_review:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Dependencies
run: |
pip install codespell
pip install fuzzywuzzy[speedup]
pip install sentence-splitter
- name: Verify Spellcheck Ignore List Exists
run: |
if [ ! -f .github/spellcheck-ignore.txt ]; then
echo "Error: spellcheck-ignore.txt not found!" && exit 1
fi
- name: Run Spellcheck and Generate Corrections
run: |
set -e # Exit on error
python3 <<EOF
import re
import os
import subprocess
from fuzzywuzzy import process
from sentence_splitter import SentenceSplitter
# Load ignore list with correct case preservation
ignore_list = {}
ignore_file = ".github/spellcheck-ignore.txt"
if os.path.exists(ignore_file):
with open(ignore_file, "r", encoding="utf-8") as f:
ignore_list = {word.strip().lower(): word.strip() for word in f.readlines()}
# Context phrases to prioritize in spellcheck corrections
context_phrases = {
"identity provider": ["identiy provider", "identify provider"],
"access token": ["access toekn", "acess token"],
"user authentication": ["user authentification", "user authenthication"],
"API gateway": ["API getway", "API gatway"]
}
# Function to check if a word is inside a Markdown link
def is_inside_markdown_link(line, original):
return bool(re.search(r'\[.*?\]\(.*' + re.escape(original) + r'.*\)', line))
# Function to check if a word is in a title or hint block
def is_in_title_or_hint(line):
return bool(re.search(r'{% (tab title|hint style)=', line))
# Run codespell and capture output
result = subprocess.run([
"codespell",
"--ignore-words=.github/spellcheck-ignore.txt",
"--skip=.git,*.lock,*.json,*.yaml,*.yml,*.css,*.html",
"--quiet-level=2"
], capture_output=True, text=True, check=False)
spellcheck_output = result.stdout.strip()
if not spellcheck_output:
print("✅ No spelling corrections found. Exiting.")
exit(0)
# Save corrections for manual review
os.makedirs(".github/corrections", exist_ok=True)
corrections_path = ".github/corrections/corrections.txt"
with open(corrections_path, "w", encoding="utf-8") as f:
for line in spellcheck_output.splitlines():
match = re.match(r"(.*):(\d+): (\S+) ==> (\S+)", line)
if match:
file_path, line_number, original, suggestion = match.groups()
# Read the full line for context
with open(file_path, "r", encoding="utf-8") as file:
lines = file.readlines()
context_line = lines[int(line_number) - 1].strip() if 0 <= int(line_number) - 1 < len(lines) else ""
# ✅ Ignore words inside Markdown links
if is_inside_markdown_link(context_line, original):
continue
# ✅ Use case-sensitive ignore words if 90% match
best_match, score = process.extractOne(original, ignore_list.keys()) if ignore_list else (None, 0)
if score >= 90:
suggestion = ignore_list[best_match] # Replace with exact capitalization from ignore list
# ✅ Replace entire phrase if a context match is found
for correct_phrase, wrong_variants in context_phrases.items():
for wrong_phrase in wrong_variants:
if wrong_phrase in context_line:
suggestion = correct_phrase # Replace entire phrase
# ✅ Prevent punctuation modifications
if suggestion.endswith((",", ".", ";")) and not original.endswith((",", ".", ";")):
suggestion = suggestion.rstrip(",.;")
f.write(f"File: {file_path}, Line: {line_number}\n")
f.write(f"**Original:** {original}\n")
f.write(f"**Suggested:** {suggestion}\n")
f.write("Approve? (yes/no)\n\n")
print(f"✅ {len(spellcheck_output.splitlines())} corrections generated. Review in `corrections.txt` and upload the approved version.")
EOF
- name: Upload Corrections for Review
uses: actions/upload-artifact@v4
with:
name: corrections_review
path: .github/corrections/corrections.txt
- name: Wait for Review and Approval
run: echo "⏳ Please review and approve the corrections. Re-upload `corrections.txt` when ready."
apply_approved_corrections:
needs: spellcheck_review
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Download Reviewed Corrections
uses: actions/download-artifact@v4
with:
name: corrections_review
path: .github/corrections/
- name: Apply Approved Corrections
run: |
python3 .github/scripts/apply_corrections.py || { echo "❌ Failed to apply corrections!"; exit 1; }
- name: Commit and Push Changes
env:
GITHUB_TOKEN: ${{ secrets.PAT_GITHUB_ACTIONS }}
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
if git diff --quiet; then
echo "No changes detected after approval. Exiting."
exit 0
fi
git checkout -b spellcheck-approved-fixes
git add .
git commit -m "✅ Spellcheck & Grammar Fixes (Manually Approved)"
git push origin spellcheck-approved-fixes
gh pr create --base main --head spellcheck-approved-fixes --title "Spellcheck & Grammar Fixes (Approved)" --body "This PR contains manually approved spellcheck and grammar fixes."