From 7ed616940aa6e234421bcc5256254f0a764e3658 Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Mon, 6 May 2024 19:24:51 +0900 Subject: [PATCH 1/3] chore: add breaking change pr check ci --- .github/actions/breaking-pr-check/action.yml | 6 ++ .github/actions/breaking-pr-check/index.js | 60 +++++++++++++++++++ .../workflows/semantic-breaking-change-pr.yml | 21 +++++++ 3 files changed, 87 insertions(+) create mode 100644 .github/actions/breaking-pr-check/action.yml create mode 100644 .github/actions/breaking-pr-check/index.js create mode 100644 .github/workflows/semantic-breaking-change-pr.yml 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..9e68c9d57dfe --- /dev/null +++ b/.github/actions/breaking-pr-check/index.js @@ -0,0 +1,60 @@ +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 (/!/.test(title)) { + raiseError(`Do not use exclamation mark ('!') in your 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:"`); + } + if (!secondLine) { + raiseError(`The description of breaking change is missing.`); + } +} + +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 }} From 3adf01625e18717bf2b12f5fc5c5e6544e5d6c10 Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Tue, 7 May 2024 20:04:47 +0900 Subject: [PATCH 2/3] apply review --- .github/actions/breaking-pr-check/index.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/actions/breaking-pr-check/index.js b/.github/actions/breaking-pr-check/index.js index 9e68c9d57dfe..129a4f77b1e9 100644 --- a/.github/actions/breaking-pr-check/index.js +++ b/.github/actions/breaking-pr-check/index.js @@ -28,8 +28,10 @@ async function getPullRequest() { } function checkTitle(title) { - if (/!/.test(title)) { - raiseError(`Do not use exclamation mark ('!') in your PR Title.`); + if (/^[a-z]+(\([a-z]+\))?!: /.test(title)) { + raiseError( + `Do not use exclamation mark ('!') to indicate breaking change in the PR Title.`, + ); } } @@ -40,10 +42,14 @@ function checkDescription(body, labels) { const [firstLine, secondLine] = body.split(/\r?\n/); if (!firstLine || !/^BREAKING CHANGE:/.test(firstLine)) { - raiseError(`Breaking change PR body should start with "BREAKING CHANGE:"`); + 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.`); + raiseError( + `The description of breaking change is missing. See https://typescript-eslint.io/maintenance/releases#2-merging-breaking-changes.`, + ); } } From cde7ec408fdd2b7a716c1b54e8062ddcefc18219 Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Sat, 11 May 2024 20:14:37 +0900 Subject: [PATCH 3/3] apply review --- .github/actions/breaking-pr-check/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/breaking-pr-check/index.js b/.github/actions/breaking-pr-check/index.js index 129a4f77b1e9..f8e590c2f192 100644 --- a/.github/actions/breaking-pr-check/index.js +++ b/.github/actions/breaking-pr-check/index.js @@ -28,7 +28,7 @@ async function getPullRequest() { } function checkTitle(title) { - if (/^[a-z]+(\([a-z]+\))?!: /.test(title)) { + if (/^[a-z]+(\([a-z-]+\))?!: /.test(title)) { raiseError( `Do not use exclamation mark ('!') to indicate breaking change in the PR Title.`, );