mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-08-18 20:18:30 +00:00
fix(ci): identify team members by repository permission (#8822)
* fix(ci): identify team members by repository permission `author_association` is computed from what the caller can see, so GITHUB_TOKEN reports a private organization member as CONTRIBUTOR. Only 5 of GreptimeTeam's members have public membership, so the open-pull-request check skipped almost everyone it was written for. Use the repository permission of the author instead, which is viewer-independent. On error, apply the limit rather than skipping, so a token that cannot read permissions cannot silently disable the check again. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(ci): do not log repository permission levels Job logs are public. Resolving the author's permission is fine; printing the level is not. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Signed-off-by: Dennis Zhuang <killme2008@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -9,9 +9,8 @@ import { appendFileSync } from "node:fs";
|
||||
const MARKER = "<!-- pr-open-limit -->";
|
||||
// GITHUB_TOKEN can only edit comments authored by the Actions bot itself.
|
||||
const COMMENT_AUTHOR = "github-actions[bot]";
|
||||
// Associations that identify an organization member. Outside collaborators and
|
||||
// community contributors are out of scope.
|
||||
const MEMBER_ASSOCIATIONS = ["OWNER", "MEMBER"];
|
||||
// Repository permissions that mark someone as part of the team.
|
||||
const TEAM_PERMISSIONS = ["admin", "maintain", "write"];
|
||||
// Keep the comment readable for authors who are far over the limit.
|
||||
const MAX_LISTED_PRS = 10;
|
||||
|
||||
@@ -22,6 +21,29 @@ function summary(text) {
|
||||
console.log(text);
|
||||
}
|
||||
|
||||
// `author_association` cannot be used here: it is computed from what the caller
|
||||
// is allowed to see, so GITHUB_TOKEN reports a private organization member as
|
||||
// CONTRIBUTOR. Repository permission is viewer-independent.
|
||||
//
|
||||
// On error this returns true rather than false. A token that cannot read
|
||||
// permissions would otherwise make the whole check silently pass everyone.
|
||||
async function isTeamMember(octokit, owner, repo, username) {
|
||||
try {
|
||||
const { data } = await octokit.repos.getCollaboratorPermissionLevel({
|
||||
owner,
|
||||
repo,
|
||||
username,
|
||||
});
|
||||
// Never log the level itself: job logs are public.
|
||||
return TEAM_PERMISSIONS.includes(data.permission);
|
||||
} catch (error) {
|
||||
console.log(
|
||||
`Cannot read repository permission for \`${username}\` (HTTP ${error.status}); applying the limit anyway.`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function buildComment(author, total, limit, openPrs) {
|
||||
const listed = openPrs
|
||||
.slice(0, MAX_LISTED_PRS)
|
||||
@@ -69,7 +91,6 @@ async function upsertComment(octokit, params, body) {
|
||||
const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
|
||||
const prNumber = Number(process.env.PR_NUMBER);
|
||||
const author = process.env.PR_AUTHOR;
|
||||
const association = process.env.PR_AUTHOR_ASSOCIATION;
|
||||
const rawLimit = Number(process.env.MAX_OPEN_PRS);
|
||||
const limit = Number.isInteger(rawLimit) && rawLimit >= 0 ? rawLimit : 5;
|
||||
|
||||
@@ -78,13 +99,13 @@ async function upsertComment(octokit, params, body) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MEMBER_ASSOCIATIONS.includes(association)) {
|
||||
summary(`Skipping \`${author}\`: association is \`${association}\`, not an org member.`);
|
||||
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
|
||||
|
||||
if (!(await isTeamMember(octokit, owner, repo, author))) {
|
||||
summary(`Skipping \`${author}\`: not a team member.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
|
||||
|
||||
const allOpen = await octokit.paginate(octokit.pulls.list, {
|
||||
owner,
|
||||
repo,
|
||||
|
||||
Reference in New Issue
Block a user