Skip to content

Update spellcheck to run only on changed files #4167

Update spellcheck to run only on changed files

Update spellcheck to run only on changed files #4167

Workflow file for this run

name: Check spelling
on:
pull_request:
push:
branches:
- main
jobs:
pyspelling:
runs-on: ubuntu-20.04
steps:
- name: Check for skip label and get changed files
id: check-files
uses: actions/github-script@v6
with:
script: |
let skipCheck = false;
let changedFiles = [];
if (context.eventName === 'pull_request') {
// Check for skip label
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
skipCheck = labels.some(label => label.name === 'skip-spell-check');
if (!skipCheck) {
// Get changed files in PR
const { data: files } = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
changedFiles = files
.filter(file => file.filename.match(/\.(py|rst|md)$/))
.map(file => file.filename);
}
} else {
// For push events, we'll still need to use git diff
// We'll handle this after checkout
}
core.setOutput('skip', skipCheck.toString());
core.setOutput('files', changedFiles.join('\n'));
core.setOutput('is-pr', (context.eventName === 'pull_request').toString());
- uses: actions/checkout@v4
if: steps.check-files.outputs.skip != 'true'
with:
fetch-depth: 0
- name: Get changed files for push event
if: |
steps.check-files.outputs.skip != 'true' &&
steps.check-files.outputs.is-pr != 'true'
id: push-files
run: |
CHANGED_FILES=$(git diff --name-only HEAD^..HEAD -- '*.py' '*.rst' '*.md')
echo "files<<EOF" >> $GITHUB_OUTPUT
echo "$CHANGED_FILES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Check if relevant files changed
if: steps.check-files.outputs.skip != 'true'
id: check
run: |
if [ "${{ steps.check-files.outputs.is-pr }}" == "true" ]; then
FILES="${{ steps.check-files.outputs.files }}"
else
FILES="${{ steps.push-files.outputs.files }}"
fi
if [ -z "$FILES" ]; then
echo "skip=true" >> $GITHUB_OUTPUT
echo "No relevant files changed (*.py, *.rst, *.md), skipping spell check"
else
echo "skip=false" >> $GITHUB_OUTPUT
echo "Found changed files to check:"
echo "$FILES"
fi
- uses: actions/setup-python@v4
if: |
steps.check-files.outputs.skip != 'true' &&
steps.check.outputs.skip != 'true'
with:
python-version: '3.9'
cache: 'pip'
- name: Install dependencies
if: |
steps.check-files.outputs.skip != 'true' &&
steps.check.outputs.skip != 'true'
run: |
pip install pyspelling
sudo apt-get install aspell aspell-en
- name: Run spell check on each file
if: |
steps.check-files.outputs.skip != 'true' &&
steps.check.outputs.skip != 'true'
run: |
if [ "${{ steps.check-files.outputs.is-pr }}" == "true" ]; then
mapfile -t FILES <<< "${{ steps.check-files.outputs.files }}"
else
mapfile -t FILES <<< "${{ steps.push-files.outputs.files }}"
fi
# Check each file individually
FINAL_EXIT_CODE=0
SPELLCHECK_LOG=""
for file in "${FILES[@]}"; do
if [ -n "$file" ]; then
echo "Checking spelling in $file"
python3 -c "import yaml; config = yaml.safe_load(open('.pyspelling.yml')); new_matrix = [matrix.copy() for matrix in config['matrix'] if (('python' in matrix['name'].lower() and '$file'.endswith('.py')) or ('rest' in matrix['name'].lower() and '$file'.endswith('.rst')) or ('markdown' in matrix['name'].lower() and '$file'.endswith('.md'))) and not matrix.update({'sources': ['$file']})]; config['matrix'] = new_matrix; yaml.dump(config, open('temp_config.yml', 'w'))"
OUTPUT=$(pyspelling -c temp_config.yml 2>&1) || {
FINAL_EXIT_CODE=1
SPELLCHECK_LOG+="### $file\n$OUTPUT\n\n"
}
fi
done
if [ $FINAL_EXIT_CODE -ne 0 ]; then
echo "spell_failed=true" >> $GITHUB_OUTPUT
echo "spell_log<<EOF" >> $GITHUB_OUTPUT
echo "$SPELLCHECK_LOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
exit 1
fi
- name: Check for existing comment
if: |
failure() &&
steps.spellcheck.outputs.spell_failed == 'true' &&
github.event_name == 'pull_request'
uses: actions/github-script@v6
id: find-comment
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Spellcheck has failed')
);
return botComment ? botComment.id : '';
result-encoding: string
- name: Post or update spell check comment
if: |
failure() &&
steps.spellcheck.outputs.spell_failed == 'true' &&
github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const message = `Spellcheck has failed. Please review the log and address the issues.
Here are a few tips:
- All PyTorch API objects must be in double backticks or use an intersphinx directive. Example: \`\`torch.nn\`\`, :func:\`torch.load\`.
- Consult en-wordlist.txt for spellings of some of the words. You can add a word to en-wordlist.txt if:
1) It's a common abbreviation, like RNN.
2) It's a word widely accepted in the industry.
- Please do not add words like \`dtype\`, \`torch.nn.Transformer\` to pass spellcheck. Instead wrap it in double backticks or use an intersphinx directive.
Spell check log:
\`\`\`
${process.env.SPELL_LOG}
\`\`\``;
const commentId = '${{ steps.find-comment.outputs.result }}';
if (commentId) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: parseInt(commentId),
body: message
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: message
});
}
env:
SPELL_LOG: ${{ steps.spellcheck.outputs.spell_log }}