Autolabel staff's pull requests (#48576)

Lena created

Modifying the existing github workflow here instead of adding a new one
because we're already triggering on the same thing (new PR opened) and
checking the same thing (staff team membership) but throwing away the
result. Another CI job doing largely the same checks seemed unnecessary.

Release Notes:

- N/A

Change summary

.github/workflows/pr_labeler.yml | 65 +++++++++++++++++++--------------
1 file changed, 37 insertions(+), 28 deletions(-)

Detailed changes

.github/workflows/first_contribution_labeler.yml → .github/workflows/pr_labeler.yml 🔗

@@ -1,4 +1,6 @@
-name: First Contribution Labeler
+# Labels pull requests by author: 'staff' for staff team members,
+# 'first contribution' for first-time external contributors.
+name: PR Labeler
 
 on:
   pull_request_target:
@@ -8,7 +10,7 @@ permissions:
   contents: read
 
 jobs:
-  label_first_contribution:
+  check-authorship-and-label:
     if: github.repository == 'zed-industries/zed'
     runs-on: namespace-profile-2x4-ubuntu-2404
     timeout-minutes: 5
@@ -20,58 +22,65 @@ jobs:
           private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }}
           owner: zed-industries
 
-      - id: check-and-label
+      - id: apply-authorship-label
         uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
         with:
           github-token: ${{ steps.get-app-token.outputs.token }}
           script: |
-            const LABEL_NAME = 'first contribution';
+            const STAFF_LABEL = 'staff';
+            const FIRST_CONTRIBUTION_LABEL = 'first contribution';
+            const STAFF_TEAM_SLUG = 'staff';
 
             const pr = context.payload.pull_request;
             const author = pr.user.login;
 
             // Skip bots (they shouldn't have FIRST_TIME* association anyway, but just in case)
             if (author.endsWith('[bot]')) {
-              console.log(`Skipping bot: ${author}`);
+              console.log(`Skipping bot author: ${author}`);
               return;
             }
 
-            // Check if this is a first-time contributor.
-            // 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(`Author ${author} has association '${association}', not a first-time contributor`);
-              return;
-            }
-
-            // Skip staff members
+            let isStaff = false;
             try {
               const response = await github.rest.teams.getMembershipForUserInOrg({
                 org: 'zed-industries',
-                team_slug: 'staff',
+                team_slug: STAFF_TEAM_SLUG,
                 username: author
               });
-              if (response.data.state === 'active') {
-                console.log(`Skipping staff member: ${author}`);
-                return;
-              }
+              isStaff = response.data.state === 'active';
             } catch (error) {
               if (error.status !== 404) {
                 throw error;
               }
-              // 404 means user is not a staff member, continue
+            }
+
+            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;
+            }
+
+            // 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: [LABEL_NAME]
+              labels: [FIRST_CONTRIBUTION_LABEL]
             });
-
-            console.log(`Applied '${LABEL_NAME}' label to PR #${pr.number} by ${author}`);
+            console.log(`PR #${pr.number} by ${author}: labeled '${FIRST_CONTRIBUTION_LABEL}' (association: '${association}')`);