Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:25:58.159Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

pr_issue_labeler.yml

239 lines · 8.1 KB · yaml
1# Labels pull requests by author:
2#  - 'community champion' for community champions
3#  - 'bot' for bot accounts
4#  - 'staff' for staff team members
5#  - 'guild' for guild members
6#  - 'first contribution' for first-time external contributors
7# Labels issues by author:
8#  - 'community champion' for community champions
9
10name: PR Issue Labeler
11
12on:
13  issues:
14    types: [opened]
15  # zizmor: ignore[dangerous-triggers]
16  # Fork PRs must be labeled, but this workflow only passes GitHub-provided event
17  # metadata to a pinned action; it never checks out or executes PR code.
18  pull_request_target:
19    types: [opened]
20
21permissions:
22  contents: read
23
24jobs:
25  check-authorship-and-label:
26    if: github.repository == 'zed-industries/zed'
27    runs-on: namespace-profile-2x4-ubuntu-2404
28    timeout-minutes: 5
29    steps:
30      - id: get-app-token
31        uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
32        with:
33          app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }}
34          private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }}
35          owner: zed-industries
36          repositories: zed
37          permission-issues: write
38          permission-members: read
39          permission-pull-requests: write
40
41      - id: apply-authorship-label
42        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
43        with:
44          github-token: ${{ steps.get-app-token.outputs.token }}
45          script: |
46            const BOT_LABEL = 'bot';
47            const STAFF_LABEL = 'staff';
48            const STAFF_TEAM_SLUG = 'staff';
49            const FIRST_CONTRIBUTION_LABEL = 'first contribution';
50            const GUILD_LABEL = 'guild';
51            // Guild cohort members are outside collaborators holding this custom
52            // repository role, not members of an org team.
53            const GUILD_ROLE_NAME = 'Guild Assign issues/PRs';
54            const COMMUNITY_CHAMPION_LABEL = 'community champion';
55            const COMMUNITY_CHAMPIONS = [
56              '0x2CA',
57              '5brian',
58              '5herlocked',
59              'abdelq',
60              'afgomez',
61              'AidanV',
62              'akbxr',
63              'AlvaroParker',
64              'amtoaer',
65              'artemevsevev',
66              'bajrangCoder',
67              'bcomnes',
68              'Be-ing',
69              'blopker',
70              'bnjjj',
71              'bobbymannino',
72              'CharlesChen0823',
73              'chbk',
74              'davewa',
75              'davidbarsky',
76              'ddoemonn',
77              'djsauble',
78              'errmayank',
79              'fantacell',
80              'fdncred',
81              'findrakecil',
82              'FloppyDisco',
83              'gko',
84              'huacnlee',
85              'imumesh18',
86              'injust',
87              'jacobtread',
88              'jansol',
89              'jeffreyguenther',
90              'jenslys',
91              'jongretar',
92              'KyleBarton',
93              'lemorage',
94              'lingyaochu',
95              'lnay',
96              'marcocondrache',
97              'marius851000',
98              'mikebronner',
99              'ognevny',
100              'PKief',
101              'playdohface',
102              'RemcoSmitsDev',
103              'rgbkrk',
104              'romaninsh',
105              'rxptr',
106              'Simek',
107              'someone13574',
108              'sourcefrog',
109              'suxiaoshao',
110              'Takk8IS',
111              'tartarughina',
112              'thedadams',
113              'tidely',
114              'timvermeulen',
115              'valentinegb',
116              'versecafe',
117              'vitallium',
118              'WhySoBad',
119              'ya7010',
120              'Zertsov',
121            ];
122
123            const pr = context.payload.pull_request;
124            const issue = context.payload.issue;
125            const target = pr || issue;
126            const author = target.user.login;
127
128            const listIncludesAuthor = (members, author) => {
129              const authorLower = author.toLowerCase();
130              return members.some((member) => member.toLowerCase() === authorLower);
131            };
132
133            const isTeamMember = async (teamSlug, author) => {
134              try {
135                const response = await github.rest.teams.getMembershipForUserInOrg({
136                  org: 'zed-industries',
137                  team_slug: teamSlug,
138                  username: author
139                });
140                return response.data.state === 'active';
141              } catch (error) {
142                if (error.status !== 404) {
143                  throw error;
144                }
145                return false;
146              }
147            };
148
149            const isStaffMember = (author) => isTeamMember(STAFF_TEAM_SLUG, author);
150
151            const isGuildMember = async (author) => {
152              try {
153                const response = await github.rest.repos.getCollaboratorPermissionLevel({
154                  owner: 'zed-industries',
155                  repo: 'zed',
156                  username: author
157                });
158                // role_name is the effective (highest) role; for cohort outside
159                // collaborators that is the custom role. Built-in roles come back
160                // lowercased and won't match.
161                return (response.data.role_name || '').toLowerCase() === GUILD_ROLE_NAME.toLowerCase();
162              } catch (error) {
163                if (error.status !== 404) {
164                  throw error;
165                }
166                return false;
167              }
168            };
169
170            const getIssueLabels = () => {
171              if (listIncludesAuthor(COMMUNITY_CHAMPIONS, author)) {
172                return [COMMUNITY_CHAMPION_LABEL];
173              }
174
175              return [];
176            };
177
178            const getPullRequestLabels = async () => {
179              if (target.user.type === 'Bot') {
180                return [BOT_LABEL];
181              }
182
183              if (await isStaffMember(author)) {
184                return [STAFF_LABEL];
185              }
186
187              // External contributors
188
189              const labelsToAdd = [];
190
191              if (listIncludesAuthor(COMMUNITY_CHAMPIONS, author)) {
192                labelsToAdd.push(COMMUNITY_CHAMPION_LABEL);
193              }
194
195              if (await isGuildMember(author)) {
196                labelsToAdd.push(GUILD_LABEL);
197              }
198
199              // We use inverted logic here due to a suspected GitHub bug where first-time contributors
200              // get 'NONE' instead of 'FIRST_TIME_CONTRIBUTOR' or 'FIRST_TIMER'.
201              // https://github.com/orgs/community/discussions/78038
202              // This will break if GitHub ever adds new associations.
203              const association = pr.author_association;
204              const knownAssociations = ['CONTRIBUTOR', 'COLLABORATOR', 'MEMBER', 'OWNER', 'MANNEQUIN'];
205
206              if (knownAssociations.includes(association)) {
207                console.log(`PR #${pr.number} by ${author}: not a first-time contributor (association: '${association}')`);
208              } else {
209                labelsToAdd.push(FIRST_CONTRIBUTION_LABEL);
210              }
211
212              return labelsToAdd;
213            };
214
215            const labelsToAdd = pr ? await getPullRequestLabels() : getIssueLabels();
216
217            if (labelsToAdd.length === 0) {
218              return;
219            }
220
221            try {
222              await github.rest.issues.addLabels({
223                owner: context.repo.owner,
224                repo: context.repo.repo,
225                issue_number: target.number,
226                labels: labelsToAdd
227              });
228
229              const targetType = pr ? 'PR' : 'issue';
230              const labels = labelsToAdd.map((label) => `'${label}'`).join(', ');
231              console.log(`${targetType} #${target.number} by ${author}: labeled ${labels}`);
232            } catch (error) {
233              if (pr) {
234                throw error;
235              }
236
237              console.error(`Failed to label issue #${target.number}: ${error.message}`);
238            }
239
Served at tenant.openagents/omega Member data and write actions are omitted.