mirror of
https://github.com/zed-industries/zed.git
synced 2026-05-30 20:24:08 +00:00
Merge community_champion_auto_labeler into pr_labeler (#57898)
Self-Review Checklist: - [X] I've reviewed my own diff for quality, security, and reliability - [n/a] Unsafe blocks (if any) have justifying comments - [n/a] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [n/a] Tests cover the new/changed behavior - [n/a] Performance impact has been considered and is acceptable Release Notes: - N/A
This commit is contained in:
parent
d139a871db
commit
5abe4bcbc6
3 changed files with 247 additions and 263 deletions
|
|
@ -1,113 +0,0 @@
|
|||
name: Community Champion Auto Labeler
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
label_community_champion:
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on: namespace-profile-2x4-ubuntu-2404
|
||||
steps:
|
||||
- name: Check if author is a community champion and apply label
|
||||
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
|
||||
env:
|
||||
COMMUNITY_CHAMPIONS: |
|
||||
0x2CA
|
||||
5brian
|
||||
5herlocked
|
||||
abdelq
|
||||
afgomez
|
||||
AidanV
|
||||
akbxr
|
||||
AlvaroParker
|
||||
amtoaer
|
||||
artemevsevev
|
||||
bajrangCoder
|
||||
bcomnes
|
||||
Be-ing
|
||||
blopker
|
||||
bnjjj
|
||||
bobbymannino
|
||||
CharlesChen0823
|
||||
chbk
|
||||
davewa
|
||||
davidbarsky
|
||||
ddoemonn
|
||||
djsauble
|
||||
errmayank
|
||||
fantacell
|
||||
fdncred
|
||||
findrakecil
|
||||
FloppyDisco
|
||||
gko
|
||||
huacnlee
|
||||
imumesh18
|
||||
injust
|
||||
jacobtread
|
||||
jansol
|
||||
jeffreyguenther
|
||||
jenslys
|
||||
jongretar
|
||||
lemorage
|
||||
lingyaochu
|
||||
lnay
|
||||
marcocondrache
|
||||
marius851000
|
||||
mikebronner
|
||||
ognevny
|
||||
PKief
|
||||
playdohface
|
||||
RemcoSmitsDev
|
||||
rgbkrk
|
||||
romaninsh
|
||||
rxptr
|
||||
Simek
|
||||
someone13574
|
||||
sourcefrog
|
||||
suxiaoshao
|
||||
Takk8IS
|
||||
tartarughina
|
||||
thedadams
|
||||
tidely
|
||||
timvermeulen
|
||||
valentinegb
|
||||
versecafe
|
||||
vitallium
|
||||
WhySoBad
|
||||
ya7010
|
||||
Zertsov
|
||||
with:
|
||||
script: |
|
||||
const communityChampions = process.env.COMMUNITY_CHAMPIONS
|
||||
.split('\n')
|
||||
.map(handle => handle.trim().toLowerCase())
|
||||
.filter(handle => handle.length > 0);
|
||||
|
||||
let author;
|
||||
if (context.eventName === 'issues') {
|
||||
author = context.payload.issue.user.login;
|
||||
} else if (context.eventName === 'pull_request_target') {
|
||||
author = context.payload.pull_request.user.login;
|
||||
}
|
||||
|
||||
if (!author || !communityChampions.includes(author.toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const issueNumber = context.payload.issue?.number || context.payload.pull_request?.number;
|
||||
|
||||
try {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issueNumber,
|
||||
labels: ['community champion']
|
||||
});
|
||||
|
||||
console.log(`Applied 'community champion' label to #${issueNumber} by ${author}`);
|
||||
} catch (error) {
|
||||
console.error(`Failed to apply label: ${error.message}`);
|
||||
}
|
||||
247
.github/workflows/pr_issue_labeler.yml
vendored
Normal file
247
.github/workflows/pr_issue_labeler.yml
vendored
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
# Labels pull requests by author:
|
||||
# - 'community champion' for community champions
|
||||
# - 'bot' for bot accounts
|
||||
# - 'staff' for staff team members
|
||||
# - 'guild' for guild members
|
||||
# - 'first contribution' for first-time external contributors
|
||||
# Labels issues by author:
|
||||
# - 'community champion' for community champions
|
||||
|
||||
name: PR Issue Labeler
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-authorship-and-label:
|
||||
if: github.repository == 'zed-industries/zed'
|
||||
runs-on: namespace-profile-2x4-ubuntu-2404
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- id: get-app-token
|
||||
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
|
||||
with:
|
||||
app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }}
|
||||
private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }}
|
||||
owner: zed-industries
|
||||
|
||||
- id: apply-authorship-label
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
with:
|
||||
github-token: ${{ steps.get-app-token.outputs.token }}
|
||||
script: |
|
||||
const BOT_LABEL = 'bot';
|
||||
const STAFF_LABEL = 'staff';
|
||||
const STAFF_TEAM_SLUG = 'staff';
|
||||
const FIRST_CONTRIBUTION_LABEL = 'first contribution';
|
||||
const GUILD_LABEL = 'guild';
|
||||
const GUILD_MEMBERS = [
|
||||
'11happy',
|
||||
'AidanV',
|
||||
'AmaanBilwar',
|
||||
'MostlyKIGuess',
|
||||
'OmChillure',
|
||||
'Palanikannan1437',
|
||||
'Shivansh-25',
|
||||
'SkandaBhat',
|
||||
'TwistingTwists',
|
||||
'YEDASAVG',
|
||||
'Ziqi-Yang',
|
||||
'alanpjohn',
|
||||
'arjunkomath',
|
||||
'austincummings',
|
||||
'ayushk-1801',
|
||||
'criticic',
|
||||
'dongdong867',
|
||||
'emamulandalib',
|
||||
'eureka928',
|
||||
'feitreim',
|
||||
'iam-liam',
|
||||
'iksuddle',
|
||||
'ishaksebsib',
|
||||
'lingyaochu',
|
||||
'loadingalias',
|
||||
'marcocondrache',
|
||||
'mchisolm0',
|
||||
'nairadithya',
|
||||
'nihalxkumar',
|
||||
'notJoon',
|
||||
'polyesterswing',
|
||||
'prayanshchh',
|
||||
'razeghi71',
|
||||
'sarmadgulzar',
|
||||
'seanstrom',
|
||||
'th0jensen',
|
||||
'tommyming',
|
||||
'transitoryangel',
|
||||
'virajbhartiya',
|
||||
];
|
||||
const COMMUNITY_CHAMPION_LABEL = 'community champion';
|
||||
const COMMUNITY_CHAMPIONS = [
|
||||
'0x2CA',
|
||||
'5brian',
|
||||
'5herlocked',
|
||||
'abdelq',
|
||||
'afgomez',
|
||||
'AidanV',
|
||||
'akbxr',
|
||||
'AlvaroParker',
|
||||
'amtoaer',
|
||||
'artemevsevev',
|
||||
'bajrangCoder',
|
||||
'bcomnes',
|
||||
'Be-ing',
|
||||
'blopker',
|
||||
'bnjjj',
|
||||
'bobbymannino',
|
||||
'CharlesChen0823',
|
||||
'chbk',
|
||||
'davewa',
|
||||
'davidbarsky',
|
||||
'ddoemonn',
|
||||
'djsauble',
|
||||
'errmayank',
|
||||
'fantacell',
|
||||
'fdncred',
|
||||
'findrakecil',
|
||||
'FloppyDisco',
|
||||
'gko',
|
||||
'huacnlee',
|
||||
'imumesh18',
|
||||
'injust',
|
||||
'jacobtread',
|
||||
'jansol',
|
||||
'jeffreyguenther',
|
||||
'jenslys',
|
||||
'jongretar',
|
||||
'lemorage',
|
||||
'lingyaochu',
|
||||
'lnay',
|
||||
'marcocondrache',
|
||||
'marius851000',
|
||||
'mikebronner',
|
||||
'ognevny',
|
||||
'PKief',
|
||||
'playdohface',
|
||||
'RemcoSmitsDev',
|
||||
'rgbkrk',
|
||||
'romaninsh',
|
||||
'rxptr',
|
||||
'Simek',
|
||||
'someone13574',
|
||||
'sourcefrog',
|
||||
'suxiaoshao',
|
||||
'Takk8IS',
|
||||
'tartarughina',
|
||||
'thedadams',
|
||||
'tidely',
|
||||
'timvermeulen',
|
||||
'valentinegb',
|
||||
'versecafe',
|
||||
'vitallium',
|
||||
'WhySoBad',
|
||||
'ya7010',
|
||||
'Zertsov',
|
||||
];
|
||||
|
||||
const pr = context.payload.pull_request;
|
||||
const issue = context.payload.issue;
|
||||
const target = pr || issue;
|
||||
const author = target.user.login;
|
||||
|
||||
const listIncludesAuthor = (members, author) => {
|
||||
const authorLower = author.toLowerCase();
|
||||
return members.some((member) => member.toLowerCase() === authorLower);
|
||||
};
|
||||
|
||||
const isStaffMember = async (author) => {
|
||||
try {
|
||||
const response = await github.rest.teams.getMembershipForUserInOrg({
|
||||
org: 'zed-industries',
|
||||
team_slug: STAFF_TEAM_SLUG,
|
||||
username: author
|
||||
});
|
||||
return response.data.state === 'active';
|
||||
} catch (error) {
|
||||
if (error.status !== 404) {
|
||||
throw error;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const getIssueLabels = () => {
|
||||
if (listIncludesAuthor(COMMUNITY_CHAMPIONS, author)) {
|
||||
return [COMMUNITY_CHAMPION_LABEL];
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
|
||||
const getPullRequestLabels = async () => {
|
||||
if (target.user.type === 'Bot') {
|
||||
return [BOT_LABEL];
|
||||
}
|
||||
|
||||
if (await isStaffMember(author)) {
|
||||
return [STAFF_LABEL];
|
||||
}
|
||||
|
||||
// External contributors
|
||||
|
||||
const labelsToAdd = [];
|
||||
|
||||
if (listIncludesAuthor(COMMUNITY_CHAMPIONS, author)) {
|
||||
labelsToAdd.push(COMMUNITY_CHAMPION_LABEL);
|
||||
}
|
||||
|
||||
if (listIncludesAuthor(GUILD_MEMBERS, author)) {
|
||||
labelsToAdd.push(GUILD_LABEL);
|
||||
}
|
||||
|
||||
// We use inverted logic here due to a suspected GitHub bug where first-time contributors
|
||||
// get 'NONE' instead of 'FIRST_TIME_CONTRIBUTOR' or 'FIRST_TIMER'.
|
||||
// https://github.com/orgs/community/discussions/78038
|
||||
// This will break if GitHub ever adds new associations.
|
||||
const association = pr.author_association;
|
||||
const knownAssociations = ['CONTRIBUTOR', 'COLLABORATOR', 'MEMBER', 'OWNER', 'MANNEQUIN'];
|
||||
|
||||
if (knownAssociations.includes(association)) {
|
||||
console.log(`PR #${pr.number} by ${author}: not a first-time contributor (association: '${association}')`);
|
||||
} else {
|
||||
labelsToAdd.push(FIRST_CONTRIBUTION_LABEL);
|
||||
}
|
||||
|
||||
return labelsToAdd;
|
||||
};
|
||||
|
||||
const labelsToAdd = pr ? await getPullRequestLabels() : getIssueLabels();
|
||||
|
||||
if (labelsToAdd.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: target.number,
|
||||
labels: labelsToAdd
|
||||
});
|
||||
|
||||
const targetType = pr ? 'PR' : 'issue';
|
||||
const labels = labelsToAdd.map((label) => `'${label}'`).join(', ');
|
||||
console.log(`${targetType} #${target.number} by ${author}: labeled ${labels}`);
|
||||
} catch (error) {
|
||||
if (pr) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.error(`Failed to label issue #${target.number}: ${error.message}`);
|
||||
}
|
||||
150
.github/workflows/pr_labeler.yml
vendored
150
.github/workflows/pr_labeler.yml
vendored
|
|
@ -1,150 +0,0 @@
|
|||
# Labels pull requests by author: 'bot' for bot accounts, 'staff' for
|
||||
# staff team members, 'guild' for guild members, 'first contribution' for
|
||||
# first-time external contributors.
|
||||
name: PR Labeler
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-authorship-and-label:
|
||||
if: github.repository == 'zed-industries/zed'
|
||||
runs-on: namespace-profile-2x4-ubuntu-2404
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- id: get-app-token
|
||||
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
|
||||
with:
|
||||
app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }}
|
||||
private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }}
|
||||
owner: zed-industries
|
||||
|
||||
- id: apply-authorship-label
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
with:
|
||||
github-token: ${{ steps.get-app-token.outputs.token }}
|
||||
script: |
|
||||
const BOT_LABEL = 'bot';
|
||||
const STAFF_LABEL = 'staff';
|
||||
const GUILD_LABEL = 'guild';
|
||||
const FIRST_CONTRIBUTION_LABEL = 'first contribution';
|
||||
const STAFF_TEAM_SLUG = 'staff';
|
||||
const GUILD_MEMBERS = [
|
||||
'11happy',
|
||||
'AidanV',
|
||||
'AmaanBilwar',
|
||||
'MostlyKIGuess',
|
||||
'OmChillure',
|
||||
'Palanikannan1437',
|
||||
'Shivansh-25',
|
||||
'SkandaBhat',
|
||||
'TwistingTwists',
|
||||
'YEDASAVG',
|
||||
'Ziqi-Yang',
|
||||
'alanpjohn',
|
||||
'arjunkomath',
|
||||
'austincummings',
|
||||
'ayushk-1801',
|
||||
'criticic',
|
||||
'dongdong867',
|
||||
'emamulandalib',
|
||||
'eureka928',
|
||||
'feitreim',
|
||||
'iam-liam',
|
||||
'iksuddle',
|
||||
'ishaksebsib',
|
||||
'lingyaochu',
|
||||
'loadingalias',
|
||||
'marcocondrache',
|
||||
'mchisolm0',
|
||||
'nairadithya',
|
||||
'nihalxkumar',
|
||||
'notJoon',
|
||||
'polyesterswing',
|
||||
'prayanshchh',
|
||||
'razeghi71',
|
||||
'sarmadgulzar',
|
||||
'seanstrom',
|
||||
'th0jensen',
|
||||
'tommyming',
|
||||
'transitoryangel',
|
||||
'virajbhartiya',
|
||||
];
|
||||
|
||||
const pr = context.payload.pull_request;
|
||||
const author = pr.user.login;
|
||||
|
||||
if (pr.user.type === 'Bot') {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
labels: [BOT_LABEL]
|
||||
});
|
||||
console.log(`PR #${pr.number} by ${author}: labeled '${BOT_LABEL}' (user type: '${pr.user.type}')`);
|
||||
return;
|
||||
}
|
||||
|
||||
let isStaff = false;
|
||||
try {
|
||||
const response = await github.rest.teams.getMembershipForUserInOrg({
|
||||
org: 'zed-industries',
|
||||
team_slug: STAFF_TEAM_SLUG,
|
||||
username: author
|
||||
});
|
||||
isStaff = response.data.state === 'active';
|
||||
} catch (error) {
|
||||
if (error.status !== 404) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
if (isStaff) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
labels: [STAFF_LABEL]
|
||||
});
|
||||
console.log(`PR #${pr.number} by ${author}: labeled '${STAFF_LABEL}' (staff team member)`);
|
||||
return;
|
||||
}
|
||||
|
||||
const authorLower = author.toLowerCase();
|
||||
const isGuildMember = GUILD_MEMBERS.some(
|
||||
(member) => member.toLowerCase() === authorLower
|
||||
);
|
||||
if (isGuildMember) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
labels: [GUILD_LABEL]
|
||||
});
|
||||
console.log(`PR #${pr.number} by ${author}: labeled '${GUILD_LABEL}' (guild member)`);
|
||||
// No early return: guild members can also get 'first contribution'
|
||||
}
|
||||
|
||||
// We use inverted logic here due to a suspected GitHub bug where first-time contributors
|
||||
// get 'NONE' instead of 'FIRST_TIME_CONTRIBUTOR' or 'FIRST_TIMER'.
|
||||
// https://github.com/orgs/community/discussions/78038
|
||||
// This will break if GitHub ever adds new associations.
|
||||
const association = pr.author_association;
|
||||
const knownAssociations = ['CONTRIBUTOR', 'COLLABORATOR', 'MEMBER', 'OWNER', 'MANNEQUIN'];
|
||||
|
||||
if (knownAssociations.includes(association)) {
|
||||
console.log(`PR #${pr.number} by ${author}: not a first-time contributor (association: '${association}')`);
|
||||
return;
|
||||
}
|
||||
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
labels: [FIRST_CONTRIBUTION_LABEL]
|
||||
});
|
||||
console.log(`PR #${pr.number} by ${author}: labeled '${FIRST_CONTRIBUTION_LABEL}' (association: '${association}')`);
|
||||
Loading…
Add table
Add a link
Reference in a new issue