diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50a158b..f909b7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,5 @@ name: "CI" + on: push: branches: @@ -11,7 +12,7 @@ on: - "docs/**" - "README.md" - "LICENSE" - pull_request: + workflow_call: jobs: build: @@ -43,3 +44,7 @@ jobs: - name: Test Site run: bash tools/test.sh + + check-commit: + needs: build + uses: ./.github/workflows/commitlint.yml diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index c9c48c3..ac8726f 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -1,5 +1,6 @@ name: Lint Commit Messages -on: pull_request + +on: workflow_call jobs: commitlint: diff --git a/.github/workflows/pr-filter.yml b/.github/workflows/pr-filter.yml index b6bcd00..fe393a2 100644 --- a/.github/workflows/pr-filter.yml +++ b/.github/workflows/pr-filter.yml @@ -1,22 +1,33 @@ -name: Block Invalid PR +name: PR Filter on: pull_request_target: - types: [opened, reopened, edited] + types: [opened, reopened] jobs: check-template: runs-on: ubuntu-latest permissions: pull-requests: write + steps: - name: Checkout Code uses: actions/checkout@v4 - name: Check PR Content + id: intercept uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} + result-encoding: string script: | const script = require('.github/workflows/scripts/pr-filter.js'); - await script({ github, context }); + return await script({ github, context }); + + - name: Abort due to invalid PR + if: ${{ steps.intercept.outputs.result != 'true' }} + run: exit 1 + + test: + needs: check-template + uses: ./.github/workflows/ci.yml diff --git a/.github/workflows/scripts/pr-filter.js b/.github/workflows/scripts/pr-filter.js index e720630..f4190dd 100644 --- a/.github/workflows/scripts/pr-filter.js +++ b/.github/workflows/scripts/pr-filter.js @@ -1,30 +1,25 @@ -function noTypes(markdown) { - if (/## Type of change/.test(markdown) && /- \[x\]/i.test(markdown)) { - return false; - } - return true; +function hasTypes(markdown) { + return /## Type of change/.test(markdown) && /-\s*\[x\]/i.test(markdown); } -function noDescription(markdown) { +function hasDescription(markdown) { return ( - /## Description/.test(markdown) === false || - /## Description\s*\n\s*## \w+/.test(markdown) || - /## Description\s*\n\s*$/.test(markdown) + /## Description/.test(markdown) && + !/## Description\s*\n\s*(##|\s*$)/.test(markdown) ); } module.exports = async ({ github, context }) => { const pr = context.payload.pull_request; - - if (pr.labels.length > 0) { - // Skip if the PR is already labeled (typically created by a deps-bot.) - return; - } - const body = pr.body === null ? '' : pr.body.trim(); const markdown = body.replace(//g, ''); + const action = context.payload.action; - if (body === '' || noTypes(markdown) || noDescription(markdown)) { + const isValid = + pr.labels.length > 0 || // PR create by Dependabot would have labels + (markdown !== '' && hasTypes(markdown) && hasDescription(markdown)); + + if (!isValid) { await github.rest.pulls.update({ ...context.repo, pull_number: pr.number, @@ -34,7 +29,9 @@ module.exports = async ({ github, context }) => { await github.rest.issues.createComment({ ...context.repo, issue_number: pr.number, - body: "Oops, it seems you've submitted an invalid pull request. No worries, we'll close it for you." + body: `Oops, it seems you've ${action} an invalid pull request. No worries, we'll close it for you.` }); } + + return isValid; };