From a0cf770a6b50069607976b69d067d3727d4bbcb2 Mon Sep 17 00:00:00 2001 From: Maurice Dauer Date: Tue, 20 Jan 2026 10:59:53 +0100 Subject: [PATCH] Add 'Notify Owners' workflow --- .github/owners.json | 3 ++ .github/scripts/owners.js | 71 ++++++++++++++++++++++++++++++++++++ .github/workflows/owners.yml | 23 ++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 .github/owners.json create mode 100644 .github/scripts/owners.js create mode 100644 .github/workflows/owners.yml diff --git a/.github/owners.json b/.github/owners.json new file mode 100644 index 00000000..44e52e34 --- /dev/null +++ b/.github/owners.json @@ -0,0 +1,3 @@ +{ + "nss": ["@dennisjackson"] +} diff --git a/.github/scripts/owners.js b/.github/scripts/owners.js new file mode 100644 index 00000000..63ae6472 --- /dev/null +++ b/.github/scripts/owners.js @@ -0,0 +1,71 @@ +module.exports = async ({ github, context, core }) => { + const path = require("path"); + const owners = require( + path.join(process.env.GITHUB_WORKSPACE, ".github", "owners.json"), + ); + + const pullNumber = context.payload.pull_request?.number; + const listFiles = await github.rest.pulls.listFiles({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: pullNumber, + }); + + const modifiedModules = new Set(); + for (const file of listFiles.data) { + const filename = file.filename; + if (filename.startsWith("modules/")) { + modifiedModules.add(filename.split("/")[1]); + } + } + + if (modifiedModules.size === 0) { + core.info("No modules were modified"); + return; + } + + const commentParts = [ + "", + "A review is required from the following owners:", + ]; + for (const modifiedModule of modifiedModules) { + if (owners[modifiedModule]) { + commentParts.push( + `- ${modifiedModule}: ${owners[modifiedModule].join(", ")}`, + ); + } + } + + if (commentParts.length === 2) { + core.info("Modules were modified, but no owners were found"); + return; + } + + const listComments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pullNumber, + }); + const comment = listComments.data.find( + (comment) => + comment.user.login === "github-actions[bot]" && + comment.body.startsWith(commentParts[0]), + ); + if (comment) { + core.info("Updating existing comment"); + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: comment.id, + body: commentParts.join("\n"), + }); + } else { + core.info("Creating new comment"); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pullNumber, + body: commentParts.join("\n"), + }); + } +}; diff --git a/.github/workflows/owners.yml b/.github/workflows/owners.yml new file mode 100644 index 00000000..d0dede2e --- /dev/null +++ b/.github/workflows/owners.yml @@ -0,0 +1,23 @@ +name: Notify Owners + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + pull-requests: write + contents: read + +jobs: + notify-owners: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Notify Owners + uses: actions/github-script@v7 + with: + script: | + const script = require('./.github/scripts/owners.js'); + await script({ github, context, core });