GitHub-Action: Try to detect “accidental solution PRs” and tag them (only)

This commit is contained in:
Peter Fichtner (pfichtner) 2026-02-05 20:54:10 +01:00
parent 90e32d8c16
commit 1070625668

View File

@ -9,31 +9,55 @@ jobs:
# we could check owner and name if: github.repository == 'emilybache/GildedRose-Refactoring-Kata' # we could check owner and name if: github.repository == 'emilybache/GildedRose-Refactoring-Kata'
# but checking owner is enough/better/more stable # but checking owner is enough/better/more stable
# Only run from the base repository # Only run from the base repository
if: github.repository_owner == 'emilybache' if: github.repository_owner == 'emilybache' || env.FORK_TESTING == 'true'
runs-on: ubuntu-latest runs-on: ubuntu-slim
permissions: permissions:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- name: Comment if checkmark is missing - name: Determine if PR is a solution
if: ${{ !contains(github.event.pull_request.body, '[X] I acknowledge') }} id: check
uses: actions/github-script@v6 uses: actions/github-script@v7
with: with:
script: | script: |
github.rest.issues.createComment({ - uses: actions/checkout@v3
issue_number: context.issue.number,
owner: context.repo.owner, - name: Check PR template via diff
repo: context.repo.repo, id: check
body: "Please don't submit a Pull Request containing a Kata solution to the original repo from Emily Bache. If you are instead trying to add an improvement, please resubmit this PR and check the `[X]` box in the PR template." uses: actions/github-script@v7
})
- name: Close PR if checkmark is missing
if: ${{ !contains(github.event.pull_request.body, '[X] I acknowledge') }}
uses: actions/github-script@v6
with: with:
script: | script: |
github.rest.pulls.update({ const fs = require('fs');
pull_number: context.issue.number, const path = require('path');
owner: context.repo.owner, const diff = require('diff');
repo: context.repo.repo,
state: 'closed' const prBody = context.payload.pull_request.body || "";
})
// Read the PR template
const templatePath = path.join(process.env.GITHUB_WORKSPACE, ".github/pull_request_template.md");
const template = fs.readFileSync(templatePath, "utf8");
// Transform unchecked boxes to checked boxes
const transformedTemplate = template.replace(/- \[ \]/g, '- [x]');
const normalize = text => text.replace(/\r\n/g, '\n').trim();
const bodyNormalized = normalize(prBody);
const templateNormalized = normalize(transformedTemplate);
// Compute line diff
const changes = diff.diffLines(templateNormalized, bodyNormalized);
// Filter out lines that are identical
const diffLines = changes.filter(c => c.added || c.removed).map(c => c.value.trim()).filter(Boolean);
// Check if diff is empty or only contains the last line of the template
const lastLine = normalize(transformedTemplate.split('\n').slice(-1)[0]);
const isSuspect = diffLines.length === 0 || (diffLines.length === 1 && diffLines[0] === lastLine);
return { is_suspect: isSuspect };
- name: Add solution label
if: steps.check.outputs.is_suspect == 'true'
uses: actions-ecosystem/action-add-labels@v1
with:
labels: solution