Skip to content

Commit

Permalink
meta: request reviews from github actions
Browse files Browse the repository at this point in the history
  • Loading branch information
avivkeller committed Jun 1, 2024
1 parent 177b8b9 commit ab7be7e
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 18 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/handle-pr-open.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Handle PRs

on:
pull_request_target:
types: [opened]

permissions:
contents: read
pull-requests: write
issues: write

jobs:
main:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
name: Checkout default branch
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
name: Make initial comment
with:
script: |
const initialCommentBuilder = require('${{ github.workspace }}/tools/actions/pr-open.js');
await initialCommentBuilder(github, context);
18 changes: 0 additions & 18 deletions .github/workflows/label-pr.yml

This file was deleted.

91 changes: 91 additions & 0 deletions tools/actions/pr-open.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
'use strict';

module.exports = async (client, context) => {
function globToRegex(glob) {
const patterns = {
'*': '([^\\/]+)',
'**': '(.+\\/)?([^\\/]+)',
'**/': '(.+\\/)',
};

const escapedGlob = glob.replace(/\./g, '\\.').replace(/\*\*$/g, '(.+)');
const regexString = '^(' + escapedGlob.replace(/\*\*\/|\*\*|\*/g, (match) => patterns[match] || '') + ')$';
return new RegExp(regexString);
}

class CodeOwners {
constructor(fileContent) {
this.owners = fileContent.split('\n').map((line) => line.trim())
.filter((line) => line && !line.startsWith('#'))
.map((line) => {
const [path, ...owners] = line.split(/\s+/);
return { path: globToRegex(path), owners };
});
}

getOwners(filePath) {
const normalizedPath = filePath.startsWith('/') ? filePath : `/${filePath}`;
return this.owners
.filter(({ path }) => path.test(normalizedPath))
.flatMap(({ owners }) => owners);
}
}

async function getChangedFiles(base, head) {
const { data } = await client.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base,
head,
});
return data.files.map((file) => file.filename);
}

async function getCodeOwners() {
const { data } = await client.rest.repos.getContent({
owner: context.repo.owner,
repo: context.repo.repo,
path: '.github/CODEOWNERS',
});

const content = Buffer.from(data.content, 'base64').toString('utf8');
return new CodeOwners(content);
}

async function makeInitialComment(changedFiles) {
const codeOwners = await getCodeOwners();

const owners = new Set();
changedFiles.forEach((file) => {
codeOwners.getOwners(file).forEach((owner) => owners.add(owner));
});

const ownersList = Array.from(owners).map((owner) => `- ${owner}`).join('\n');

const body =
'Hi 👋! Thank you for submitting this pull-request!\n\n' +
'According to the CODEOWNERS file, the following people are responsible for' +
"reviewing changes to the files you've modified:\n\n" +
ownersList + '\n\n' +
'They, along with other project maintainers, will be notified of your pull request.' +
'Please be patient and wait for them to review your changes.\n\n' +
"If you have any questions, please don't hesitate to ask!";

return client.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: body,
});
}

const base = context.payload.pull_request?.base?.sha;
const head = context.payload.pull_request?.head?.sha;

if (!base || !head) {
throw new Error('Cannot get base or head commit');
}

const changedFiles = await getChangedFiles(base, head);
await makeInitialComment(changedFiles);
};

0 comments on commit ab7be7e

Please sign in to comment.