Skip to content

Commit 98262d8

Browse files
johnstcnCopilot
andauthored
ci: allow dispatching workflow triage via label (coder#20042)
Allows creating a task for an issue if a label 'traiage' is set. Requires membership of the `coder` org to run. Manual workflow_dispatch: https://github.com/coder/coder/actions/runs/18158719999/job/51684512634 --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent f4a6894 commit 98262d8

1 file changed

Lines changed: 72 additions & 13 deletions

File tree

.github/workflows/traiage.yaml

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
name: AI Triage Automation
22

33
on:
4+
issues:
5+
types:
6+
- labeled
47
workflow_dispatch:
58
inputs:
69
issue_url:
@@ -32,6 +35,7 @@ jobs:
3235
traiage:
3336
name: Triage GitHub Issue with Claude Code
3437
runs-on: ubuntu-latest
38+
if: github.event.label.name == 'traiage' || github.event_name == 'workflow_dispatch'
3539
timeout-minutes: 30
3640
env:
3741
CODER_URL: ${{ secrets.TRAIAGE_CODER_URL }}
@@ -43,17 +47,58 @@ jobs:
4347
actions: write
4448

4549
steps:
46-
- name: Checkout repository
47-
uses: actions/checkout@v4
48-
with:
49-
persist-credentials: false
50-
fetch-depth: 0
50+
- name: Get GitHub user ID
51+
id: github-user-id
52+
if: always()
53+
env:
54+
GITHUB_ACTOR: ${{ github.actor }}
55+
GITHUB_EVENT_NAME: ${{ github.event_name }}
56+
GITHUB_EVENT_USER_ID: ${{ github.event.sender.id }}
57+
GITHUB_EVENT_USER_LOGIN: ${{ github.event.sender.login }}
58+
GH_TOKEN: ${{ github.token }}
59+
run: |
60+
# For workflow_dispatch, use the actor who triggered it
61+
# For issues events, use the issue author
62+
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
63+
if ! GITHUB_USER_ID=$(gh api "users/${GITHUB_ACTOR}" --jq '.id'); then
64+
echo "::error::Failed to get GitHub user ID for actor ${GITHUB_ACTOR}"
65+
exit 1
66+
fi
67+
echo "Using workflow_dispatch actor: ${GITHUB_ACTOR} (ID: ${GITHUB_USER_ID})"
68+
echo "github_user_id=${GITHUB_USER_ID}" >> "${GITHUB_OUTPUT}"
69+
echo "github_username=${GITHUB_ACTOR}" >> "${GITHUB_OUTPUT}"
70+
exit 0
71+
elif [[ "${GITHUB_EVENT_NAME}" == "issues" ]]; then
72+
GITHUB_USER_ID=${GITHUB_EVENT_USER_ID}
73+
echo "Using issue author: ${GITHUB_EVENT_USER_LOGIN} (ID: ${GITHUB_USER_ID})"
74+
echo "github_user_id=${GITHUB_USER_ID}" >> "${GITHUB_OUTPUT}"
75+
echo "github_username=${GITHUB_EVENT_USER_LOGIN}" >> "${GITHUB_OUTPUT}"
76+
exit 0
77+
else
78+
echo "::error::Unsupported event type: ${GITHUB_EVENT_NAME}"
79+
exit 1
80+
fi
81+
82+
- name: Verify organization membership
83+
env:
84+
GITHUB_ORG: ${{ github.repository_owner }}
85+
GH_TOKEN: ${{ github.token }}
86+
GITHUB_USERNAME: ${{ steps.github-user-id.outputs.github_username }}
87+
GITHUB_USER_ID: ${{ steps.github-user-id.outputs.github_user_id }}
88+
run: |
89+
# Check if the actor is a member of the organization
90+
if ! gh api "orgs/${GITHUB_ORG}/members/${GITHUB_USERNAME}" --silent 2>/dev/null; then
91+
echo "::error title=Access Denied::User ${GITHUB_USERNAME} is not a member of the ${GITHUB_ORG} organization"
92+
echo "::error::You must be a member of the ${GITHUB_ORG} GitHub organization to run this workflow."
93+
exit 1
94+
fi
95+
echo "::notice::User ${GITHUB_USERNAME} verified as member of ${GITHUB_ORG} organization"
5196
5297
- name: Extract context key from issue
5398
id: extract-context
5499
env:
55100
ISSUE_URL: ${{ inputs.issue_url }}
56-
GITHUB_TOKEN: ${{ github.token }}
101+
GH_TOKEN: ${{ github.token }}
57102
run: |
58103
issue_number="$(gh issue view "${ISSUE_URL}" --json number --jq '.number')"
59104
context_key="gh-${issue_number}"
@@ -82,25 +127,30 @@ jobs:
82127
id: get-coder-username
83128
env:
84129
CODER_SESSION_TOKEN: ${{ secrets.TRAIAGE_CODER_SESSION_TOKEN }}
85-
GITHUB_USER_ID: ${{
86-
(github.event_name == 'workflow_dispatch' && github.actor_id)
87-
}}
130+
GH_TOKEN: ${{ github.token }}
131+
GITHUB_USER_ID: ${{ steps.github-user-id.outputs.github_user_id }}
88132
run: |
89-
[[ -z "${GITHUB_USER_ID}" || "${GITHUB_USER_ID}" == "null" ]] && echo "No GitHub actor ID found" && exit 1
90133
user_json=$(
91134
coder users list --github-user-id="${GITHUB_USER_ID}" --output=json
92135
)
93136
coder_username=$(jq -r 'first | .username' <<< "$user_json")
94137
[[ -z "${coder_username}" || "${coder_username}" == "null" ]] && echo "No Coder user with GitHub user ID ${GITHUB_USER_ID} found" && exit 1
95138
echo "coder_username=${coder_username}" >> "${GITHUB_OUTPUT}"
96139
140+
- name: Checkout repository
141+
uses: actions/checkout@v4
142+
with:
143+
persist-credentials: false
144+
fetch-depth: 0
145+
97146
# TODO(Cian): this is a good use-case for 'recipes'
98147
- name: Create Coder task
99148
id: create-task
100149
env:
101150
CODER_USERNAME: ${{ steps.get-coder-username.outputs.coder_username }}
102151
CONTEXT_KEY: ${{ steps.extract-context.outputs.context_key }}
103-
GITHUB_TOKEN: ${{ github.token }}
152+
GH_TOKEN: ${{ github.token }}
153+
GITHUB_REPOSITORY: ${{ github.repository }}
104154
ISSUE_URL: ${{ inputs.issue_url }}
105155
PREFIX: ${{ inputs.prefix }}
106156
RUN_ID: ${{ github.run_id }}
@@ -125,7 +175,11 @@ jobs:
125175
export TASK_NAME="${PREFIX}-${CONTEXT_KEY}-${RUN_ID}"
126176
echo "Creating task: $TASK_NAME"
127177
./scripts/traiage.sh create
128-
coder exp task status "${CODER_USERNAME}/$TASK_NAME" --watch
178+
if [[ "${ISSUE_URL}" == "https://github.com/${GITHUB_REPOSITORY}"* ]]; then
179+
gh issue comment "${ISSUE_URL}" --body "Task created: ${TASK_NAME}" --create-if-none --edit-last
180+
else
181+
echo "Skipping comment on other repo."
182+
fi
129183
echo "TASK_NAME=${CODER_USERNAME}/${TASK_NAME}" >> "${GITHUB_OUTPUT}"
130184
echo "TASK_NAME=${CODER_USERNAME}/${TASK_NAME}" >> "${GITHUB_ENV}"
131185
@@ -134,7 +188,11 @@ jobs:
134188
if: inputs.cleanup
135189
env:
136190
BUCKET_PREFIX: "gs://coder-traiage-outputs/traiage"
191+
CODER_USERNAME: ${{ steps.get-coder-username.outputs.coder_username }}
192+
TASK_NAME: ${{ steps.create-task.outputs.TASK_NAME }}
137193
run: |
194+
echo "Waiting for task to complete..."
195+
coder exp task status "${CODER_USERNAME}/$TASK_NAME" --watch
138196
echo "Creating archive for workspace: $TASK_NAME"
139197
./scripts/traiage.sh archive
140198
echo "archive_url=${BUCKET_PREFIX%%/}/$TASK_NAME.tar.gz" >> "${GITHUB_OUTPUT}"
@@ -145,8 +203,9 @@ jobs:
145203
env:
146204
ARCHIVE_URL: ${{ steps.create-archive.outputs.archive_url }}
147205
BUCKET_PREFIX: "gs://coder-traiage-outputs/traiage"
206+
CODER_USERNAME: ${{ steps.get-coder-username.outputs.coder_username }}
148207
CONTEXT_KEY: ${{ steps.extract-context.outputs.context_key }}
149-
GITHUB_TOKEN: ${{ github.token }}
208+
GH_TOKEN: ${{ github.token }}
150209
GITHUB_REPOSITORY: ${{ github.repository }}
151210
ISSUE_URL: ${{ inputs.issue_url }}
152211
TASK_NAME: ${{ steps.create-task.outputs.TASK_NAME }}

0 commit comments

Comments
 (0)