From d3f867904c671b5fdcf5dfde939e17667139213c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=89=E1=85=A1=E1=86=BC?= =?UTF-8?q?=E1=84=83=E1=85=AE?= Date: Sun, 8 Jun 2025 21:29:16 +0900 Subject: [PATCH 1/2] feat(breaking-pr-check): Refactored to breaking-pr-check and deleted index.js file --- .github/actions/breaking-pr-check/action.yml | 54 ++++++++++++- .github/actions/breaking-pr-check/index.js | 78 ------------------- .../workflows/semantic-breaking-change-pr.yml | 1 - 3 files changed, 52 insertions(+), 81 deletions(-) delete mode 100644 .github/actions/breaking-pr-check/index.js diff --git a/.github/actions/breaking-pr-check/action.yml b/.github/actions/breaking-pr-check/action.yml index f54443a4f433..d19fa72df98d 100644 --- a/.github/actions/breaking-pr-check/action.yml +++ b/.github/actions/breaking-pr-check/action.yml @@ -2,5 +2,55 @@ name: Validate Breaking Change PR description: Validate breaking change PR title and description runs: - using: node20 - main: index.js + using: 'composite' + steps: + - name: Check PR title and body using github-script + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const pr = context.payload.pull_request; + if (!pr) { + throw new Error("This action can only be run on pull_request events."); + } + + const owner = pr.base.repo.owner.login; + const repo = pr.base.repo.name; + const pull_number = pr.number; + + const { data: pullRequest } = await github.rest.pulls.get({ + owner, + repo, + pull_number, + }); + + function checkTitle(title) { + if (/^[a-z]+(\([a-z-]+\))?!: /.test(title)) { + throw new Error( + `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)) { + throw new Error( + `Breaking change PR body should start with "BREAKING CHANGE:". See https://typescript-eslint.io/maintenance/releases#2-merging-breaking-changes.`, + ); + } + + if (!secondLine) { + throw new Error( + `The description of breaking change is missing. See https://typescript-eslint.io/maintenance/releases#2-merging-breaking-changes.`, + ); + } + } + + checkTitle(pullRequest.title); + checkDescription(pullRequest.body ?? '', pullRequest.labels); diff --git a/.github/actions/breaking-pr-check/index.js b/.github/actions/breaking-pr-check/index.js deleted file mode 100644 index 2aa900456a9c..000000000000 --- a/.github/actions/breaking-pr-check/index.js +++ /dev/null @@ -1,78 +0,0 @@ -// @ts-check -/* eslint-disable jsdoc/no-types, @typescript-eslint/no-require-imports */ - -const core = require('@actions/core'); -const github = require('@actions/github'); - -async function getPullRequest() { - const token = process.env.GITHUB_TOKEN; - if (!token) { - throw new Error( - 'The GITHUB_TOKEN environment variable is required to run this action.', - ); - } - const client = github.getOctokit(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, - pull_number: pr.number, - repo, - }); - - return data; -} - -/** - * @param {string} title The PR title to check - */ -function checkTitle(title) { - if (/^[a-z]+(\([a-z-]+\))?!: /.test(title)) { - throw new Error( - `Do not use exclamation mark ('!') to indicate breaking change in the PR Title.`, - ); - } -} - -/** - * @param {string} body The body of the PR - * @param {any[]} labels The labels applied to the PR - */ -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)) { - throw new Error( - `Breaking change PR body should start with "BREAKING CHANGE:". See https://typescript-eslint.io/maintenance/releases#2-merging-breaking-changes.`, - ); - } - if (!secondLine) { - throw new Error( - `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 (/** @type {any} */ e) { - core.setFailed(e.message); - } -} - -run(); diff --git a/.github/workflows/semantic-breaking-change-pr.yml b/.github/workflows/semantic-breaking-change-pr.yml index dcae58270de1..46d4627b3fdc 100644 --- a/.github/workflows/semantic-breaking-change-pr.yml +++ b/.github/workflows/semantic-breaking-change-pr.yml @@ -15,7 +15,6 @@ jobs: 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 1897bf9fe77f743c2c9bb94b76c9fbe4978ef78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=89=E1=85=A1=E1=86=BC?= =?UTF-8?q?=E1=84=83=E1=85=AE?= Date: Sun, 8 Jun 2025 21:33:38 +0900 Subject: [PATCH 2/2] feat: change pr code --- .github/actions/breaking-pr-check/action.yml | 41 +++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/.github/actions/breaking-pr-check/action.yml b/.github/actions/breaking-pr-check/action.yml index d19fa72df98d..60f7f4673209 100644 --- a/.github/actions/breaking-pr-check/action.yml +++ b/.github/actions/breaking-pr-check/action.yml @@ -9,20 +9,24 @@ runs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const pr = context.payload.pull_request; - if (!pr) { - throw new Error("This action can only be run on pull_request events."); - } + async function getPullRequest() { + const pr = context.payload.pull_request; + if (!pr) { + throw new Error("This action can only be run on pull_request events."); + } - const owner = pr.base.repo.owner.login; - const repo = pr.base.repo.name; - const pull_number = pr.number; + const owner = pr.base.repo.owner.login; + const repo = pr.base.repo.name; + const pull_number = pr.number; - const { data: pullRequest } = await github.rest.pulls.get({ - owner, - repo, - pull_number, - }); + const { data } = await github.rest.pulls.get({ + owner, + repo, + pull_number, + }); + + return data; + } function checkTitle(title) { if (/^[a-z]+(\([a-z-]+\))?!: /.test(title)) { @@ -52,5 +56,14 @@ runs: } } - checkTitle(pullRequest.title); - checkDescription(pullRequest.body ?? '', pullRequest.labels); + async function run() { + const pr = await getPullRequest(); + checkTitle(pr.title); + checkDescription(pr.body ?? '', pr.labels); + } + + try { + await run(); + } catch (e) { + throw new Error(e.message ?? String(e)); + }