diff --git a/.github/workflows/close-solution-pr.yml b/.github/workflows/close-solution-pr.yml new file mode 100644 index 00000000..0ea48f07 --- /dev/null +++ b/.github/workflows/close-solution-pr.yml @@ -0,0 +1,33 @@ +name: Close solution PRs + +on: + pull_request: + types: [labeled] + +jobs: + close: + if: github.event.label.name == 'solution' + runs-on: ubuntu-slim + steps: + - name: Comment on PR + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: "👋 Thanks for working on the Gilded Rose kata!\n\nThis repository intentionally contains badly written code for learning purposes.\n\nWe don't accept refactored solutions as pull requests.\nPlease keep your solution in your fork.\n\nIf you intended to contribute documentation, tests, or a new language version, feel free to reopen and explain 🙂" + }) + + - name: Close PR + uses: actions/github-script@v7 + with: + script: | + github.rest.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number, + state: 'closed' + }) + diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 9d78f55e..6a54d5a9 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -24,20 +24,44 @@ jobs: uses: actions/github-script@v6 with: script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - 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." - }) - - name: Close PR if checkmark is missing - if: ${{ !contains(github.event.pull_request.body, '[X] I acknowledge') }} - uses: actions/github-script@v6 + - uses: actions/checkout@v3 + + - name: Check PR template via diff + id: check + uses: actions/github-script@v7 with: script: | - github.rest.pulls.update({ - pull_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - state: 'closed' - }) + const fs = require('fs'); + const path = require('path'); + const diff = require('diff'); + + 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