Skip to content

Add codeowner workflow check #3

Add codeowner workflow check

Add codeowner workflow check #3

name: Code Owners Approval Check
on:
pull_request:
branches:
- master
types: [opened, synchronize, reopened, ready_for_review]
pull_request_review:
types: [submitted, dismissed]
permissions: {}
jobs:
check-code-owners-approval:
runs-on: ubuntu-latest
if: github.base_ref == 'master'
permissions:
pull-requests: write
contents: read
steps:
- name: Check Code Owners Approval
id: check_approvals
uses: actions/github-script@v7
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const { owner, repo, number } = context.issue;
// Get pull request details
const { data: pr } = await github.rest.pulls.get({
owner,
repo,
pull_number: number
});
// Get CODEOWNERS file content
let codeowners;
try {
const { data } = await github.rest.repos.getContent({
owner,
repo,
path: '.github/CODEOWNERS',
});
codeowners = Buffer.from(data.content, 'base64').toString('utf8');
} catch (error) {
console.log('CODEOWNERS file not found in .github directory. Skipping check.');
return;
}
// Parse CODEOWNERS file
const codeownersLines = codeowners.split('\n').filter(line => line.trim() && !line.startsWith('#'));
const codeownersSet = new Set(codeownersLines.flatMap(line => {
const parts = line.split(/\s+/);
return parts.slice(1).filter(part => part.startsWith('@'));
}));
if (codeownersSet.size === 0) {
console.log('No code owners found. Skipping check.');
return;
}
// Get reviews
const { data: reviews } = await github.rest.pulls.listReviews({
owner,
repo,
pull_number: number
});
const approvals = new Set(
reviews
.filter(review => review.state === 'APPROVED')
.map(review => review.user.login)
);
const codeOwnerStatus = Array.from(codeownersSet).map(owner => ({
owner: owner.substring(1), // Remove '@' from the beginning
approved: approvals.has(owner.substring(1))
}));
const missingApprovals = codeOwnerStatus.filter(status => !status.approved);
if (missingApprovals.length > 0) {
core.setFailed(`Missing approvals from code owners: ${missingApprovals.map(status => status.owner).join(', ')}`);
} else {
console.log('All code owners have approved the pull request.');
}
core.setOutput('codeOwnerStatus', JSON.stringify(codeOwnerStatus));
- name: Update PR status
if: failure()
uses: actions/github-script@v7
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const { owner, repo, number } = context.issue;
const codeOwnerStatus = JSON.parse(process.env.CODE_OWNER_STATUS);
const statusList = codeOwnerStatus.map(status => {
const emoji = status.approved ? '✅' : '❌';
return `${emoji} ${status.owner}`;
}).join('\n');
const comment = `This pull request is missing approvals from one or more code owners.\n\nCode Owner Status:\n${statusList}`;
await github.rest.pulls.createReview({
owner,
repo,
pull_number: number,
event: 'COMMENT',
body: comment
});
env:
CODE_OWNER_STATUS: ${{ steps.check_approvals.outputs.codeOwnerStatus }}