1
0
Эх сурвалжийг харах

ci: skip issue actions for team authors (#34556)

Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
opencode-agent[bot] 1 сар өмнө
parent
commit
ba41dadc91

+ 26 - 2
.github/workflows/compliance-close.yml

@@ -35,13 +35,37 @@ jobs:
             const now = Date.now();
             const twoHours = 2 * 60 * 60 * 1000;
             const orgMemberAssociations = new Set(['OWNER', 'MEMBER']);
+            const agentLogin = 'opencode-agent[bot]';
+            const { data: file } = await github.rest.repos.getContent({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              path: '.github/TEAM_MEMBERS',
+              ref: 'dev',
+            });
+            const teamMembers = new Set(
+              Buffer.from(file.content, 'base64')
+                .toString()
+                .split('\n')
+                .map((line) => line.trim().toLowerCase())
+                .filter(Boolean)
+            );
+
+            function isExempt(item) {
+              const login = item.user?.login?.toLowerCase();
+              return (
+                login === agentLogin ||
+                orgMemberAssociations.has(item.author_association) ||
+                (login && teamMembers.has(login))
+              );
+            }
 
             for (const item of items) {
               const isPR = !!item.pull_request;
               const kind = isPR ? 'PR' : 'issue';
+              const login = item.user?.login;
 
-              if (orgMemberAssociations.has(item.author_association)) {
-                core.info(`Skipping ${kind} #${item.number}; author association is ${item.author_association}`);
+              if (isExempt(item)) {
+                core.info(`Skipping ${kind} #${item.number}; author ${login || 'unknown'} is exempt`);
                 try {
                   await github.rest.issues.removeLabel({
                     owner: context.repo.owner,

+ 38 - 0
.github/workflows/duplicate-issues.yml

@@ -17,12 +17,31 @@ jobs:
         with:
           fetch-depth: 1
 
+      - name: Check exempt issue author
+        id: author
+        run: |
+          LOGIN="${{ github.event.issue.user.login }}"
+          ASSOCIATION="${{ github.event.issue.author_association }}"
+
+          if [ "$LOGIN" = "opencode-agent[bot]" ] ||
+             [ "$ASSOCIATION" = "OWNER" ] ||
+             [ "$ASSOCIATION" = "MEMBER" ] ||
+             grep -qxiF "$LOGIN" .github/TEAM_MEMBERS; then
+            echo "skip=true" >> "$GITHUB_OUTPUT"
+            echo "Skipping issue automation for exempt author: $LOGIN ($ASSOCIATION)"
+          else
+            echo "skip=false" >> "$GITHUB_OUTPUT"
+          fi
+
       - uses: ./.github/actions/setup-bun
+        if: steps.author.outputs.skip != 'true'
 
       - name: Install opencode
+        if: steps.author.outputs.skip != 'true'
         run: curl -fsSL https://opencode.ai/install | bash
 
       - name: Check duplicates and compliance
+        if: steps.author.outputs.skip != 'true'
         env:
           OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -132,12 +151,31 @@ jobs:
         with:
           fetch-depth: 1
 
+      - name: Check exempt issue author
+        id: author
+        run: |
+          LOGIN="${{ github.event.issue.user.login }}"
+          ASSOCIATION="${{ github.event.issue.author_association }}"
+
+          if [ "$LOGIN" = "opencode-agent[bot]" ] ||
+             [ "$ASSOCIATION" = "OWNER" ] ||
+             [ "$ASSOCIATION" = "MEMBER" ] ||
+             grep -qxiF "$LOGIN" .github/TEAM_MEMBERS; then
+            echo "skip=true" >> "$GITHUB_OUTPUT"
+            echo "Skipping issue automation for exempt author: $LOGIN ($ASSOCIATION)"
+          else
+            echo "skip=false" >> "$GITHUB_OUTPUT"
+          fi
+
       - uses: ./.github/actions/setup-bun
+        if: steps.author.outputs.skip != 'true'
 
       - name: Install opencode
+        if: steps.author.outputs.skip != 'true'
         run: curl -fsSL https://opencode.ai/install | bash
 
       - name: Recheck compliance
+        if: steps.author.outputs.skip != 'true'
         env:
           OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

+ 19 - 0
.github/workflows/triage.yml

@@ -16,13 +16,32 @@ jobs:
         with:
           fetch-depth: 1
 
+      - name: Check exempt issue author
+        id: author
+        run: |
+          LOGIN="${{ github.event.issue.user.login }}"
+          ASSOCIATION="${{ github.event.issue.author_association }}"
+
+          if [ "$LOGIN" = "opencode-agent[bot]" ] ||
+             [ "$ASSOCIATION" = "OWNER" ] ||
+             [ "$ASSOCIATION" = "MEMBER" ] ||
+             grep -qxiF "$LOGIN" .github/TEAM_MEMBERS; then
+            echo "skip=true" >> "$GITHUB_OUTPUT"
+            echo "Skipping issue automation for exempt author: $LOGIN ($ASSOCIATION)"
+          else
+            echo "skip=false" >> "$GITHUB_OUTPUT"
+          fi
+
       - name: Setup Bun
+        if: steps.author.outputs.skip != 'true'
         uses: ./.github/actions/setup-bun
 
       - name: Install opencode
+        if: steps.author.outputs.skip != 'true'
         run: curl -fsSL https://opencode.ai/install | bash
 
       - name: Triage issue
+        if: steps.author.outputs.skip != 'true'
         env:
           OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

+ 19 - 0
script/github/close-issues.ts

@@ -11,10 +11,20 @@ if (!token) {
 }
 
 const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000)
+const agentLogin = "opencode-agent[bot]"
+const teamMembers = new Set(
+  (await Bun.file(new URL("../../.github/TEAM_MEMBERS", import.meta.url)).text())
+    .split("\n")
+    .map((line) => line.trim().toLowerCase())
+    .filter(Boolean),
+)
+const teamAssociations = new Set(["OWNER", "MEMBER"])
 
 type Issue = {
   number: number
   updated_at: string
+  author_association: string
+  user: { login: string } | null
 }
 
 const headers = {
@@ -24,6 +34,11 @@ const headers = {
   "X-GitHub-Api-Version": "2022-11-28",
 }
 
+function shouldSkip(i: Issue) {
+  const login = i.user?.login.toLowerCase()
+  return login === agentLogin || (login ? teamMembers.has(login) : false) || teamAssociations.has(i.author_association)
+}
+
 async function close(num: number) {
   const base = `https://api.github.com/repos/${repo}/issues/${num}`
 
@@ -63,6 +78,10 @@ async function main() {
     for (const i of all) {
       const updated = new Date(i.updated_at)
       if (updated < cutoff) {
+        if (shouldSkip(i)) {
+          console.log(`Skipping stale issue #${i.number}; author ${i.user?.login ?? "unknown"} is exempt`)
+          continue
+        }
         stale.push(i.number)
       } else {
         console.log(`\nFound fresh issue #${i.number}, stopping`)