mirror of
https://github.com/esphome/esphome.git
synced 2025-07-29 14:46:40 +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);
|
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)
|
// Remove only users who have already submitted reviews (not just requested reviewers)
|
||||||
reviewedUsers.forEach(reviewer => {
|
reviewedUsers.forEach(reviewer => {
|
||||||
matchedOwners.delete(reviewer);
|
matchedOwners.delete(reviewer);
|
||||||
@ -192,7 +237,7 @@ jobs:
|
|||||||
const teamsList = Array.from(matchedTeams);
|
const teamsList = Array.from(matchedTeams);
|
||||||
|
|
||||||
if (reviewersList.length === 0 && teamsList.length === 0) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,31 +272,41 @@ jobs:
|
|||||||
console.log('All codeowners are already requested reviewers or have reviewed');
|
console.log('All codeowners are already requested reviewers or have reviewed');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a comment to the PR mentioning what happened (include all matched codeowners)
|
// Only add a comment if there are new codeowners to mention (not previously pinged)
|
||||||
const commentBody = createCommentBody(reviewersList, teamsList, fileMatches.size, true);
|
if (reviewersList.length > 0 || teamsList.length > 0) {
|
||||||
|
const commentBody = createCommentBody(reviewersList, teamsList, fileMatches.size, true);
|
||||||
|
|
||||||
await github.rest.issues.createComment({
|
await github.rest.issues.createComment({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
issue_number: pr_number,
|
issue_number: pr_number,
|
||||||
body: commentBody
|
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) {
|
} catch (error) {
|
||||||
if (error.status === 422) {
|
if (error.status === 422) {
|
||||||
console.log('Some reviewers may already be requested or unavailable:', error.message);
|
console.log('Some reviewers may already be requested or unavailable:', error.message);
|
||||||
|
|
||||||
// Try to add a comment even if review request failed
|
// Only try to add a comment if there are new codeowners to mention
|
||||||
const commentBody = createCommentBody(reviewersList, teamsList, fileMatches.size, false);
|
if (reviewersList.length > 0 || teamsList.length > 0) {
|
||||||
|
const commentBody = createCommentBody(reviewersList, teamsList, fileMatches.size, false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await github.rest.issues.createComment({
|
await github.rest.issues.createComment({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
issue_number: pr_number,
|
issue_number: pr_number,
|
||||||
body: commentBody
|
body: commentBody
|
||||||
});
|
});
|
||||||
} catch (commentError) {
|
console.log(`Added fallback comment mentioning ${reviewersList.length} users and ${teamsList.length} teams`);
|
||||||
console.log('Failed to add comment:', commentError.message);
|
} catch (commentError) {
|
||||||
|
console.log('Failed to add comment:', commentError.message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('No new codeowners to mention in fallback comment');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw error;
|
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}`
|
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) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +150,7 @@ jobs:
|
|||||||
body: commentBody
|
body: commentBody
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Successfully notified codeowners: ${mentionString}`);
|
console.log(`Successfully notified new codeowners: ${mentionString}`);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('Failed to process codeowner notifications:', error.message);
|
console.log('Failed to process codeowner notifications:', error.message);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user