mirror of
https://github.com/esphome/esphome.git
synced 2025-07-29 06:36:45 +00:00
[CI] New workflow to mention codeowners on issues (#9658)
This commit is contained in:
parent
f8146bd340
commit
e189add8a3
119
.github/workflows/issue-codeowner-notify.yml
vendored
Normal file
119
.github/workflows/issue-codeowner-notify.yml
vendored
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# This workflow automatically notifies codeowners when an issue is labeled with component labels.
|
||||||
|
# It reads the CODEOWNERS file to find the maintainers for the labeled components
|
||||||
|
# and posts a comment mentioning them to ensure they're aware of the issue.
|
||||||
|
|
||||||
|
name: Notify Issue Codeowners
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [labeled]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
notify-codeowners:
|
||||||
|
name: Run
|
||||||
|
if: ${{ startsWith(github.event.label.name, format('component{0} ', ':')) }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Notify codeowners for component issues
|
||||||
|
uses: actions/github-script@v7.0.1
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const owner = context.repo.owner;
|
||||||
|
const repo = context.repo.repo;
|
||||||
|
const issue_number = context.payload.issue.number;
|
||||||
|
const labelName = context.payload.label.name;
|
||||||
|
|
||||||
|
console.log(`Processing issue #${issue_number} with label: ${labelName}`);
|
||||||
|
|
||||||
|
// Extract component name from label
|
||||||
|
const componentName = labelName.replace('component: ', '');
|
||||||
|
console.log(`Component: ${componentName}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch CODEOWNERS file from root
|
||||||
|
const { data: codeownersFile } = await github.rest.repos.getContent({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
path: 'CODEOWNERS'
|
||||||
|
});
|
||||||
|
const codeownersContent = Buffer.from(codeownersFile.content, 'base64').toString('utf8');
|
||||||
|
|
||||||
|
// Parse CODEOWNERS file to extract component mappings
|
||||||
|
const codeownersLines = codeownersContent.split('\n')
|
||||||
|
.map(line => line.trim())
|
||||||
|
.filter(line => line && !line.startsWith('#'));
|
||||||
|
|
||||||
|
let componentOwners = null;
|
||||||
|
|
||||||
|
for (const line of codeownersLines) {
|
||||||
|
const parts = line.split(/\s+/);
|
||||||
|
if (parts.length < 2) continue;
|
||||||
|
|
||||||
|
const pattern = parts[0];
|
||||||
|
const owners = parts.slice(1);
|
||||||
|
|
||||||
|
// Look for component patterns: esphome/components/{component}/*
|
||||||
|
const componentMatch = pattern.match(/^esphome\/components\/([^\/]+)\/\*$/);
|
||||||
|
if (componentMatch && componentMatch[1] === componentName) {
|
||||||
|
componentOwners = owners;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!componentOwners) {
|
||||||
|
console.log(`No codeowners found for component: ${componentName}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Found codeowners for '${componentName}': ${componentOwners.join(', ')}`);
|
||||||
|
|
||||||
|
// Separate users and teams
|
||||||
|
const userOwners = [];
|
||||||
|
const teamOwners = [];
|
||||||
|
|
||||||
|
for (const owner of componentOwners) {
|
||||||
|
const cleanOwner = owner.startsWith('@') ? owner.slice(1) : owner;
|
||||||
|
if (cleanOwner.includes('/')) {
|
||||||
|
// Team mention (org/team-name)
|
||||||
|
teamOwners.push(`@${cleanOwner}`);
|
||||||
|
} else {
|
||||||
|
// Individual user
|
||||||
|
userOwners.push(`@${cleanOwner}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove issue author from mentions to avoid self-notification
|
||||||
|
const issueAuthor = context.payload.issue.user.login;
|
||||||
|
const filteredUserOwners = userOwners.filter(mention =>
|
||||||
|
mention !== `@${issueAuthor}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const allMentions = [...filteredUserOwners, ...teamOwners];
|
||||||
|
|
||||||
|
if (allMentions.length === 0) {
|
||||||
|
console.log('No codeowners to notify (issue author is the only codeowner)');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create comment body
|
||||||
|
const mentionString = allMentions.join(', ');
|
||||||
|
const commentBody = `👋 Hey ${mentionString}!\n\nThis issue has been labeled with \`component: ${componentName}\` and you've been identified as a codeowner of this component. Please take a look when you have a chance!\n\nThanks for maintaining this component! 🙏`;
|
||||||
|
|
||||||
|
// Post comment
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: issue_number,
|
||||||
|
body: commentBody
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Successfully notified codeowners: ${mentionString}`);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Failed to process codeowner notifications:', error.message);
|
||||||
|
console.error(error);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user