add_commented_closed_issue_to_project.yml

 1name: "Surface closed issues someone's commented on"
 2
 3on:
 4  issue_comment:
 5    types:
 6      - created
 7
 8permissions:
 9  contents: read
10
11jobs:
12  add-to-project:
13    if: >
14      github.repository == 'zed-industries/zed' &&
15      github.event.issue.state == 'closed' &&
16      github.event.issue.pull_request == null &&
17      github.event.issue.type != null &&
18      github.event.issue.type.name == 'Bug' &&
19      github.event.comment.user.type != 'Bot'
20    runs-on: namespace-profile-2x4-ubuntu-2404
21    timeout-minutes: 5
22    steps:
23      - id: is-post-close-comment
24        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
25        with:
26          script: |
27            const closedAt = new Date(context.payload.issue.closed_at);
28            const commentedAt = new Date(context.payload.comment.created_at);
29            const diffSeconds = Math.abs(commentedAt - closedAt) / 1000;
30            if (diffSeconds <= 30) {
31              core.notice(`Skipping — comment was likely part of "Close with comment" (${diffSeconds}s gap)`);
32              return false;
33            }
34            return true;
35
36      - if: steps.is-post-close-comment.outputs.result == 'true'
37        id: get-app-token
38        uses: actions/create-github-app-token@bef1eaf1c0ac2b148ee2a0a74c65fbe6db0631f1 # v2.1.4
39        with:
40          app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }}
41          private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }}
42          owner: zed-industries
43
44      - if: steps.is-post-close-comment.outputs.result == 'true'
45        id: check-staff
46        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
47        with:
48          github-token: ${{ steps.get-app-token.outputs.token }}
49          script: |
50            try {
51              const response = await github.rest.teams.getMembershipForUserInOrg({
52                org: 'zed-industries',
53                team_slug: 'staff',
54                username: context.payload.comment.user.login
55              });
56              return response.data.state === 'active';
57            } catch (error) {
58              // 404 means user is not a member
59              if (error.status === 404) {
60                return false;
61              }
62              throw error;
63            }
64
65      - if: steps.is-post-close-comment.outputs.result == 'true' && steps.check-staff.outputs.result == 'true'
66        run: |
67          echo "::notice::Skipping issue #${{ github.event.issue.number }} - commenter is staff member"
68
69      # github-script outputs are JSON strings, so we compare against 'false' (string)
70      - if: steps.is-post-close-comment.outputs.result == 'true' && steps.check-staff.outputs.result == 'false'
71        run: |
72          echo "::notice::Adding issue #${{ github.event.issue.number }} to project (comment by ${{ github.event.comment.user.login }})"
73
74      - if: steps.is-post-close-comment.outputs.result == 'true' && steps.check-staff.outputs.result == 'false'
75        uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
76        with:
77          project-url: https://github.com/orgs/zed-industries/projects/73
78          github-token: ${{ steps.get-app-token.outputs.token }}