mirror of
https://github.com/esphome/esphome.git
synced 2025-07-28 22:26:36 +00:00
[CI] Only mention codeowners once (#9727)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
2540e7edb2
commit
e5aed29231
95
.github/workflows/codeowner-review-request.yml
vendored
95
.github/workflows/codeowner-review-request.yml
vendored
@ -178,6 +178,51 @@ jobs:
|
||||
reviewedUsers.add(review.user.login);
|
||||
});
|
||||
|
||||
// Check for previous comments from this workflow to avoid duplicate pings
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr_number
|
||||
});
|
||||
|
||||
const previouslyPingedUsers = new Set();
|
||||
const previouslyPingedTeams = new Set();
|
||||
|
||||
// Look for comments from github-actions bot that contain codeowner pings
|
||||
const workflowComments = comments.filter(comment =>
|
||||
comment.user.type === 'Bot' &&
|
||||
comment.user.login === 'github-actions[bot]' &&
|
||||
comment.body.includes("I've automatically requested reviews from codeowners")
|
||||
);
|
||||
|
||||
// Extract previously mentioned users and teams from workflow comments
|
||||
for (const comment of workflowComments) {
|
||||
// Match @username patterns (not team mentions)
|
||||
const userMentions = comment.body.match(/@([a-zA-Z0-9_.-]+)(?![/])/g) || [];
|
||||
userMentions.forEach(mention => {
|
||||
const username = mention.slice(1); // remove @
|
||||
previouslyPingedUsers.add(username);
|
||||
});
|
||||
|
||||
// Match @org/team patterns
|
||||
const teamMentions = comment.body.match(/@[a-zA-Z0-9_.-]+\/([a-zA-Z0-9_.-]+)/g) || [];
|
||||
teamMentions.forEach(mention => {
|
||||
const teamName = mention.split('/')[1];
|
||||
previouslyPingedTeams.add(teamName);
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Found ${previouslyPingedUsers.size} previously pinged users and ${previouslyPingedTeams.size} previously pinged teams`);
|
||||
|
||||
// Remove users who have already been pinged in previous workflow comments
|
||||
previouslyPingedUsers.forEach(user => {
|
||||
matchedOwners.delete(user);
|
||||
});
|
||||
|
||||
previouslyPingedTeams.forEach(team => {
|
||||
matchedTeams.delete(team);
|
||||
});
|
||||
|
||||
// Remove only users who have already submitted reviews (not just requested reviewers)
|
||||
reviewedUsers.forEach(reviewer => {
|
||||
matchedOwners.delete(reviewer);
|
||||
@ -192,7 +237,7 @@ jobs:
|
||||
const teamsList = Array.from(matchedTeams);
|
||||
|
||||
if (reviewersList.length === 0 && teamsList.length === 0) {
|
||||
console.log('No eligible reviewers found (all may already be requested or reviewed)');
|
||||
console.log('No eligible reviewers found (all may already be requested, reviewed, or previously pinged)');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -227,31 +272,41 @@ jobs:
|
||||
console.log('All codeowners are already requested reviewers or have reviewed');
|
||||
}
|
||||
|
||||
// Add a comment to the PR mentioning what happened (include all matched codeowners)
|
||||
const commentBody = createCommentBody(reviewersList, teamsList, fileMatches.size, true);
|
||||
// Only add a comment if there are new codeowners to mention (not previously pinged)
|
||||
if (reviewersList.length > 0 || teamsList.length > 0) {
|
||||
const commentBody = createCommentBody(reviewersList, teamsList, fileMatches.size, true);
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr_number,
|
||||
body: commentBody
|
||||
});
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr_number,
|
||||
body: commentBody
|
||||
});
|
||||
console.log(`Added comment mentioning ${reviewersList.length} users and ${teamsList.length} teams`);
|
||||
} else {
|
||||
console.log('No new codeowners to mention in comment (all previously pinged)');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.status === 422) {
|
||||
console.log('Some reviewers may already be requested or unavailable:', error.message);
|
||||
|
||||
// Try to add a comment even if review request failed
|
||||
const commentBody = createCommentBody(reviewersList, teamsList, fileMatches.size, false);
|
||||
// Only try to add a comment if there are new codeowners to mention
|
||||
if (reviewersList.length > 0 || teamsList.length > 0) {
|
||||
const commentBody = createCommentBody(reviewersList, teamsList, fileMatches.size, false);
|
||||
|
||||
try {
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr_number,
|
||||
body: commentBody
|
||||
});
|
||||
} catch (commentError) {
|
||||
console.log('Failed to add comment:', commentError.message);
|
||||
try {
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr_number,
|
||||
body: commentBody
|
||||
});
|
||||
console.log(`Added fallback comment mentioning ${reviewersList.length} users and ${teamsList.length} teams`);
|
||||
} catch (commentError) {
|
||||
console.log('Failed to add comment:', commentError.message);
|
||||
}
|
||||
} else {
|
||||
console.log('No new codeowners to mention in fallback comment');
|
||||
}
|
||||
} else {
|
||||
throw error;
|
||||
|
45
.github/workflows/issue-codeowner-notify.yml
vendored
45
.github/workflows/issue-codeowner-notify.yml
vendored
@ -92,10 +92,49 @@ jobs:
|
||||
mention !== `@${issueAuthor}`
|
||||
);
|
||||
|
||||
const allMentions = [...filteredUserOwners, ...teamOwners];
|
||||
// Check for previous comments from this workflow to avoid duplicate pings
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: issue_number
|
||||
});
|
||||
|
||||
const previouslyPingedUsers = new Set();
|
||||
const previouslyPingedTeams = new Set();
|
||||
|
||||
// Look for comments from github-actions bot that contain codeowner pings for this component
|
||||
const workflowComments = comments.filter(comment =>
|
||||
comment.user.type === 'Bot' &&
|
||||
comment.user.login === 'github-actions[bot]' &&
|
||||
comment.body.includes(`component: ${componentName}`) &&
|
||||
comment.body.includes("you've been identified as a codeowner")
|
||||
);
|
||||
|
||||
// Extract previously mentioned users and teams from workflow comments
|
||||
for (const comment of workflowComments) {
|
||||
// Match @username patterns (not team mentions)
|
||||
const userMentions = comment.body.match(/@([a-zA-Z0-9_.-]+)(?![/])/g) || [];
|
||||
userMentions.forEach(mention => {
|
||||
previouslyPingedUsers.add(mention); // Keep @ prefix for easy comparison
|
||||
});
|
||||
|
||||
// Match @org/team patterns
|
||||
const teamMentions = comment.body.match(/@[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+/g) || [];
|
||||
teamMentions.forEach(mention => {
|
||||
previouslyPingedTeams.add(mention);
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Found ${previouslyPingedUsers.size} previously pinged users and ${previouslyPingedTeams.size} previously pinged teams for component ${componentName}`);
|
||||
|
||||
// Remove previously pinged users and teams
|
||||
const newUserOwners = filteredUserOwners.filter(mention => !previouslyPingedUsers.has(mention));
|
||||
const newTeamOwners = teamOwners.filter(mention => !previouslyPingedTeams.has(mention));
|
||||
|
||||
const allMentions = [...newUserOwners, ...newTeamOwners];
|
||||
|
||||
if (allMentions.length === 0) {
|
||||
console.log('No codeowners to notify (issue author is the only codeowner)');
|
||||
console.log('No new codeowners to notify (all previously pinged or issue author is the only codeowner)');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -111,7 +150,7 @@ jobs:
|
||||
body: commentBody
|
||||
});
|
||||
|
||||
console.log(`Successfully notified codeowners: ${mentionString}`);
|
||||
console.log(`Successfully notified new codeowners: ${mentionString}`);
|
||||
|
||||
} catch (error) {
|
||||
console.log('Failed to process codeowner notifications:', error.message);
|
||||
|
Loading…
x
Reference in New Issue
Block a user