From f8b7985dbe6c4018d5ec7df1e1a4d7e6961ab4a3 Mon Sep 17 00:00:00 2001 From: JayaShakthi97 Date: Wed, 1 Oct 2025 11:36:44 +0530 Subject: [PATCH 1/3] Add change set checker workflow --- .github/workflows/check-changeset.yml | 167 ++++++++++++++++++++++++++ .github/workflows/receive-pr.yml | 46 +++++++ 2 files changed, 213 insertions(+) create mode 100644 .github/workflows/check-changeset.yml create mode 100644 .github/workflows/receive-pr.yml diff --git a/.github/workflows/check-changeset.yml b/.github/workflows/check-changeset.yml new file mode 100644 index 00000000..bb94534f --- /dev/null +++ b/.github/workflows/check-changeset.yml @@ -0,0 +1,167 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). +# +# WSO2 LLC. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# -------------------------------------------------------------------------------------- + +# This workflow will check if a submitted PR has changesets. + +name: đŸĻ‹ Check for Changeset + +on: + workflow_run: + workflows: ["📩 Receive PR"] + types: + - completed + +env: + GH_TOKEN: ${{ secrets.RELEASE_BOT_TOKEN }} + IS_RELEASE_MODE: false + +jobs: + check-changeset: + runs-on: ubuntu-latest + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + steps: + - name: đŸ“Ĩ Download PR Number Artifact + uses: actions/download-artifact@v4 + with: + name: pr-number + github-token: ${{ env.GH_TOKEN }} + repository: ${{ github.repository }} + run-id: ${{ github.event.workflow_run.id }} + + - name: 📝 Display PR Number + run: cat ./PR_NUMBER + + - name: đŸ’Ŧ Remove Existing Changeset Comment + uses: actions/github-script@v3.1.0 + with: + github-token: ${{ env.GH_TOKEN }} + script: | + const fs = require('fs'); + const PR_NUMBER = Number(fs.readFileSync('./PR_NUMBER', 'utf8').trim()); + const REPO_OWNER = context.repo.owner; + const REPO_NAME = context.repo.repo; + + // Fetch all comments on the pull request. + const comments = await github.issues.listComments({ + owner: REPO_OWNER, + repo: REPO_NAME, + issue_number: PR_NUMBER, + }); + + console.log("COMMENTS_URL: https://api.github.com/repos/" + REPO_NAME + "/issues/" + PR_NUMBER + "/comments"); + + for (const comment of comments.data) { + console.log("COMMENT_OWNER: " + comment.user.login); + + // Identify the changeset comment by its heading. + if (comment.body.includes("đŸĻ‹ Changeset detected") || comment.body.includes("âš ī¸ No Changeset found") || comment.body.includes("❌ Invalid Changeset detected")) { + console.log("COMMENT_ID_TO_DELETE: " + comment.id); + + // Remove the changeset comment using the comment ID. + await github.issues.deleteComment({ + owner: REPO_OWNER, + repo: REPO_NAME, + comment_id: comment.id, + }); + } + } + + - name: đŸ’Ŧ Add Changeset Comment + uses: actions/github-script@v3.1.0 + with: + github-token: ${{ env.GH_TOKEN }} + script: | + const fs = require('fs'); + const PR_NUMBER = Number(fs.readFileSync('./PR_NUMBER', 'utf8').trim()); + const REPO_OWNER = context.repo.owner; + const REPO_NAME = context.repo.repo; + const IS_RELEASE_MODE = process.env.IS_RELEASE_MODE === 'true'; + + const files = await github.pulls.listFiles({ + owner: REPO_OWNER, + repo: REPO_NAME, + pull_number: PR_NUMBER, + }); + + const CHANGED_FILES = files.data.map(file => file.filename); + console.log("CHANGED_FILES_URL: https://api.github.com/repos/" + REPO_NAME + "/pulls/" + PR_NUMBER + "/files"); + console.log("CHANGED_FILES:", CHANGED_FILES); + + const CHANGESET_FILES = CHANGED_FILES.filter(filename => /^\.changeset\/.*\.md$/.test(filename)); + const CHANGES_COUNT = CHANGESET_FILES.length; + console.log("CHANGES_COUNT:", CHANGES_COUNT); + console.log("IS_RELEASE_MODE:", IS_RELEASE_MODE); + + let invalidChangesets = []; + + // Check for major/minor changesets in release mode (master branch) + if (IS_RELEASE_MODE && CHANGES_COUNT > 0) { + for (const changesetFile of CHANGESET_FILES) { + try { + const fileResponse = await github.repos.getContent({ + owner: REPO_OWNER, + repo: REPO_NAME, + path: changesetFile, + ref: `refs/pull/${PR_NUMBER}/head` + }); + + const content = Buffer.from(fileResponse.data.content, 'base64').toString('utf8'); + console.log("CHANGESET_CONTENT:", changesetFile, content); + + // Parse changeset frontmatter to check for major/minor releases + const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/); + if (frontmatterMatch) { + const frontmatter = frontmatterMatch[1]; + if (frontmatter.includes(': major') || frontmatter.includes(': minor')) { + invalidChangesets.push({ + file: changesetFile, + type: frontmatter.includes(': major') ? 'major' : 'minor' + }); + } + } + } catch (error) { + console.log("Error reading changeset file:", changesetFile, error.message); + } + } + } + + let COMMENT; + if (CHANGES_COUNT > 0) { + if (IS_RELEASE_MODE && invalidChangesets.length > 0) { + console.log("Invalid changesets detected in release mode:", invalidChangesets); + const invalidFiles = invalidChangesets.map(cs => `- \`${cs.file}\` (${cs.type})`).join('\n'); + COMMENT = `

❌ Invalid Changeset detected

🚀 WSO2 Identity Server release mode is currently activated!

The following changesets contain major/minor versions, but the master branch only allows patch releases:

\n${invalidFiles}\n

📋 Action Required:

📚 Refer Release Documentation to learn about our release strategy.

`; + } else { + console.log("Changeset detected"); + COMMENT = `

đŸĻ‹ Changeset detected

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

`; + } + } else { + console.log("No changeset detected"); + COMMENT = `

âš ī¸ No Changeset found

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go.

If these changes should result in a version bump, you need to add a changeset.

Refer Release Documentation to learn how to add a changeset.`; + } + + await github.issues.createComment({ + owner: REPO_OWNER, + repo: REPO_NAME, + issue_number: PR_NUMBER, + body: COMMENT, + }); diff --git a/.github/workflows/receive-pr.yml b/.github/workflows/receive-pr.yml new file mode 100644 index 00000000..e5b00e76 --- /dev/null +++ b/.github/workflows/receive-pr.yml @@ -0,0 +1,46 @@ +# ------------------------------------------------------------------------------------- +# +# Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). +# +# WSO2 LLC. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# -------------------------------------------------------------------------------------- + +# This workflow will receive a PR and save the PR number for later use. + +name: 📩 Receive PR + +on: + pull_request: + branches: [main] + +jobs: + save-pr-information: + runs-on: ubuntu-latest + steps: + - name: âŦ‡ī¸ Checkout + uses: actions/checkout@v4 + + - name: â„šī¸ Display PR Information + run: echo "PR Number \#${{github.event.number}}" + + - name: 💾 Save PR Number for Later Use + run: echo "${{github.event.number}}" > PR_NUMBER + + - name: đŸ“Ļ Upload PR Number as Artifact + uses: actions/upload-artifact@v4 + with: + name: pr-number + path: PR_NUMBER From aee3f0b6f79a72dd8a7e73f656ca0d4fd338563e Mon Sep 17 00:00:00 2001 From: JayaShakthi97 Date: Wed, 1 Oct 2025 11:39:34 +0530 Subject: [PATCH 2/3] Add change set checker workflow --- .github/workflows/check-changeset.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-changeset.yml b/.github/workflows/check-changeset.yml index bb94534f..7e95bb88 100644 --- a/.github/workflows/check-changeset.yml +++ b/.github/workflows/check-changeset.yml @@ -29,7 +29,7 @@ on: - completed env: - GH_TOKEN: ${{ secrets.RELEASE_BOT_TOKEN }} + GH_TOKEN: ${{ secrets.ASGARDEO_GITHUB_BOT_TOKEN }} IS_RELEASE_MODE: false jobs: From d8e5c475358ce96f82e3afe493b9320f1b3fe08b Mon Sep 17 00:00:00 2001 From: JayaShakthi97 Date: Wed, 1 Oct 2025 11:40:38 +0530 Subject: [PATCH 3/3] Update `actions/github-script` to v7 --- .github/workflows/check-changeset.yml | 196 +++++++++++++------------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/.github/workflows/check-changeset.yml b/.github/workflows/check-changeset.yml index 7e95bb88..90e0cbe0 100644 --- a/.github/workflows/check-changeset.yml +++ b/.github/workflows/check-changeset.yml @@ -51,117 +51,117 @@ jobs: run: cat ./PR_NUMBER - name: đŸ’Ŧ Remove Existing Changeset Comment - uses: actions/github-script@v3.1.0 + uses: actions/github-script@v7 with: github-token: ${{ env.GH_TOKEN }} script: | - const fs = require('fs'); - const PR_NUMBER = Number(fs.readFileSync('./PR_NUMBER', 'utf8').trim()); - const REPO_OWNER = context.repo.owner; - const REPO_NAME = context.repo.repo; - - // Fetch all comments on the pull request. - const comments = await github.issues.listComments({ + const fs = require('fs'); + const PR_NUMBER = Number(fs.readFileSync('./PR_NUMBER', 'utf8').trim()); + const REPO_OWNER = context.repo.owner; + const REPO_NAME = context.repo.repo; + + const comments = await github.rest.issues.listComments({ + owner: REPO_OWNER, + repo: REPO_NAME, + issue_number: PR_NUMBER, + }); + + console.log("COMMENTS_URL: https://api.github.com/repos/" + REPO_NAME + "/issues/" + PR_NUMBER + "/comments"); + + for (const comment of comments.data) { + console.log("COMMENT_OWNER: " + comment.user.login); + + if ( + comment.body.includes("đŸĻ‹ Changeset detected") || + comment.body.includes("âš ī¸ No Changeset found") || + comment.body.includes("❌ Invalid Changeset detected") + ) { + console.log("COMMENT_ID_TO_DELETE: " + comment.id); + + await github.rest.issues.deleteComment({ owner: REPO_OWNER, repo: REPO_NAME, - issue_number: PR_NUMBER, - }); - - console.log("COMMENTS_URL: https://api.github.com/repos/" + REPO_NAME + "/issues/" + PR_NUMBER + "/comments"); - - for (const comment of comments.data) { - console.log("COMMENT_OWNER: " + comment.user.login); - - // Identify the changeset comment by its heading. - if (comment.body.includes("đŸĻ‹ Changeset detected") || comment.body.includes("âš ī¸ No Changeset found") || comment.body.includes("❌ Invalid Changeset detected")) { - console.log("COMMENT_ID_TO_DELETE: " + comment.id); - - // Remove the changeset comment using the comment ID. - await github.issues.deleteComment({ - owner: REPO_OWNER, - repo: REPO_NAME, - comment_id: comment.id, - }); - } + comment_id: comment.id, + }); } + } - name: đŸ’Ŧ Add Changeset Comment - uses: actions/github-script@v3.1.0 + uses: actions/github-script@v7 with: github-token: ${{ env.GH_TOKEN }} script: | - const fs = require('fs'); - const PR_NUMBER = Number(fs.readFileSync('./PR_NUMBER', 'utf8').trim()); - const REPO_OWNER = context.repo.owner; - const REPO_NAME = context.repo.repo; - const IS_RELEASE_MODE = process.env.IS_RELEASE_MODE === 'true'; - - const files = await github.pulls.listFiles({ - owner: REPO_OWNER, - repo: REPO_NAME, - pull_number: PR_NUMBER, - }); - - const CHANGED_FILES = files.data.map(file => file.filename); - console.log("CHANGED_FILES_URL: https://api.github.com/repos/" + REPO_NAME + "/pulls/" + PR_NUMBER + "/files"); - console.log("CHANGED_FILES:", CHANGED_FILES); - - const CHANGESET_FILES = CHANGED_FILES.filter(filename => /^\.changeset\/.*\.md$/.test(filename)); - const CHANGES_COUNT = CHANGESET_FILES.length; - console.log("CHANGES_COUNT:", CHANGES_COUNT); - console.log("IS_RELEASE_MODE:", IS_RELEASE_MODE); - - let invalidChangesets = []; - - // Check for major/minor changesets in release mode (master branch) - if (IS_RELEASE_MODE && CHANGES_COUNT > 0) { - for (const changesetFile of CHANGESET_FILES) { - try { - const fileResponse = await github.repos.getContent({ - owner: REPO_OWNER, - repo: REPO_NAME, - path: changesetFile, - ref: `refs/pull/${PR_NUMBER}/head` - }); - - const content = Buffer.from(fileResponse.data.content, 'base64').toString('utf8'); - console.log("CHANGESET_CONTENT:", changesetFile, content); - - // Parse changeset frontmatter to check for major/minor releases - const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/); - if (frontmatterMatch) { - const frontmatter = frontmatterMatch[1]; - if (frontmatter.includes(': major') || frontmatter.includes(': minor')) { - invalidChangesets.push({ - file: changesetFile, - type: frontmatter.includes(': major') ? 'major' : 'minor' - }); - } - } - } catch (error) { - console.log("Error reading changeset file:", changesetFile, error.message); - } + const fs = require('fs'); + const PR_NUMBER = Number(fs.readFileSync('./PR_NUMBER', 'utf8').trim()); + const REPO_OWNER = context.repo.owner; + const REPO_NAME = context.repo.repo; + const IS_RELEASE_MODE = process.env.IS_RELEASE_MODE === 'true'; + + const files = await github.rest.pulls.listFiles({ + owner: REPO_OWNER, + repo: REPO_NAME, + pull_number: PR_NUMBER, + }); + + const CHANGED_FILES = files.data.map(file => file.filename); + console.log("CHANGED_FILES_URL: https://api.github.com/repos/" + REPO_NAME + "/pulls/" + PR_NUMBER + "/files"); + console.log("CHANGED_FILES:", CHANGED_FILES); + + const CHANGESET_FILES = CHANGED_FILES.filter(filename => /^\.changeset\/.*\.md$/.test(filename)); + const CHANGES_COUNT = CHANGESET_FILES.length; + console.log("CHANGES_COUNT:", CHANGES_COUNT); + console.log("IS_RELEASE_MODE:", IS_RELEASE_MODE); + + let invalidChangesets = []; + + if (IS_RELEASE_MODE && CHANGES_COUNT > 0) { + for (const changesetFile of CHANGESET_FILES) { + try { + const fileResponse = await github.rest.repos.getContent({ + owner: REPO_OWNER, + repo: REPO_NAME, + path: changesetFile, + ref: `refs/pull/${PR_NUMBER}/head` + }); + + const content = Buffer.from(fileResponse.data.content, 'base64').toString('utf8'); + console.log("CHANGESET_CONTENT:", changesetFile, content); + + const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/); + if (frontmatterMatch) { + const frontmatter = frontmatterMatch[1]; + if (frontmatter.includes(': major') || frontmatter.includes(': minor')) { + invalidChangesets.push({ + file: changesetFile, + type: frontmatter.includes(': major') ? 'major' : 'minor' + }); + } } + } catch (error) { + console.log("Error reading changeset file:", changesetFile, error.message); + } } - - let COMMENT; - if (CHANGES_COUNT > 0) { - if (IS_RELEASE_MODE && invalidChangesets.length > 0) { - console.log("Invalid changesets detected in release mode:", invalidChangesets); - const invalidFiles = invalidChangesets.map(cs => `- \`${cs.file}\` (${cs.type})`).join('\n'); - COMMENT = `

❌ Invalid Changeset detected

🚀 WSO2 Identity Server release mode is currently activated!

The following changesets contain major/minor versions, but the master branch only allows patch releases:

\n${invalidFiles}\n

📋 Action Required:

📚 Refer Release Documentation to learn about our release strategy.

`; - } else { - console.log("Changeset detected"); - COMMENT = `

đŸĻ‹ Changeset detected

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

`; - } + } + + let COMMENT; + if (CHANGES_COUNT > 0) { + if (IS_RELEASE_MODE && invalidChangesets.length > 0) { + console.log("Invalid changesets detected in release mode:", invalidChangesets); + const invalidFiles = invalidChangesets.map(cs => `- \`${cs.file}\` (${cs.type})`).join('\n'); + COMMENT = `

❌ Invalid Changeset detected

🚀 WSO2 Identity Server release mode is currently activated!

The following changesets contain major/minor versions, but the master branch only allows patch releases:

\n${invalidFiles}\n

📋 Action Required:

📚 Refer Release Documentation to learn about our release strategy.

`; } else { - console.log("No changeset detected"); - COMMENT = `

âš ī¸ No Changeset found

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go.

If these changes should result in a version bump, you need to add a changeset.

Refer Release Documentation to learn how to add a changeset.`; + console.log("Changeset detected"); + COMMENT = `

đŸĻ‹ Changeset detected

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

`; } + } else { + console.log("No changeset detected"); + COMMENT = `

âš ī¸ No Changeset found

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go.

If these changes should result in a version bump, you need to add a changeset.

Refer Release Documentation to learn how to add a changeset.`; + } + + await github.rest.issues.createComment({ + owner: REPO_OWNER, + repo: REPO_NAME, + issue_number: PR_NUMBER, + body: COMMENT, + }); - await github.issues.createComment({ - owner: REPO_OWNER, - repo: REPO_NAME, - issue_number: PR_NUMBER, - body: COMMENT, - });