diff --git a/.github/actions/breaking-pr-check/action.yml b/.github/actions/breaking-pr-check/action.yml new file mode 100644 index 000000000000..f54443a4f433 --- /dev/null +++ b/.github/actions/breaking-pr-check/action.yml @@ -0,0 +1,6 @@ +name: Validate Breaking Change PR +description: Validate breaking change PR title and description + +runs: + using: node20 + main: index.js diff --git a/.github/actions/breaking-pr-check/index.js b/.github/actions/breaking-pr-check/index.js new file mode 100644 index 000000000000..f8e590c2f192 --- /dev/null +++ b/.github/actions/breaking-pr-check/index.js @@ -0,0 +1,66 @@ +const core = require('@actions/core'); +const github = require('@actions/github'); + +function raiseError(message) { + throw new Error(message); +} + +async function getPullRequest() { + const client = github.getOctokit(process.env.GITHUB_TOKEN); + + const pr = github.context.payload.pull_request; + if (!pr) { + throw new Error( + "This action can only be invoked in `pull_request_target` or `pull_request` events. Otherwise the pull request can't be inferred.", + ); + } + + const owner = pr.base.user.login; + const repo = pr.base.repo.name; + + const { data } = await client.rest.pulls.get({ + owner, + repo, + pull_number: pr.number, + }); + + return data; +} + +function checkTitle(title) { + if (/^[a-z]+(\([a-z-]+\))?!: /.test(title)) { + raiseError( + `Do not use exclamation mark ('!') to indicate breaking change in the PR Title.`, + ); + } +} + +function checkDescription(body, labels) { + if (!labels.some(label => label.name === 'breaking change')) { + return; + } + const [firstLine, secondLine] = body.split(/\r?\n/); + + if (!firstLine || !/^BREAKING CHANGE:/.test(firstLine)) { + raiseError( + `Breaking change PR body should start with "BREAKING CHANGE:". See https://typescript-eslint.io/maintenance/releases#2-merging-breaking-changes.`, + ); + } + if (!secondLine) { + raiseError( + `The description of breaking change is missing. See https://typescript-eslint.io/maintenance/releases#2-merging-breaking-changes.`, + ); + } +} + +async function run() { + const pullRequest = await getPullRequest(); + try { + checkTitle(pullRequest.title); + checkDescription(pullRequest.body, pullRequest.labels); + } catch (e) { + core.setFailed(e.message); + } +} + +run(); diff --git a/.github/workflows/semantic-breaking-change-pr.yml b/.github/workflows/semantic-breaking-change-pr.yml new file mode 100644 index 000000000000..dcae58270de1 --- /dev/null +++ b/.github/workflows/semantic-breaking-change-pr.yml @@ -0,0 +1,21 @@ +name: Semantic Breaking Change PR + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + - labeled + - unlabeled + +jobs: + main: + name: Validate Breaking Change PR + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare-install + - uses: ./.github/actions/breaking-pr-check + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy