-
Notifications
You must be signed in to change notification settings - Fork 162
224 lines (195 loc) · 9.03 KB
/
Copy pathtriage-agent.yml
File metadata and controls
224 lines (195 loc) · 9.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
name: AI Triage - Label and Comment on New Issues
on:
issues:
types: [opened]
workflow_dispatch:
inputs:
issue_number:
description: 'Issue number to triage (manual run). e.g. 123'
required: true
permissions:
issues: write
contents: read
jobs:
label_and_comment:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Get issue data
id: get_issue
uses: actions/github-script@v6
with:
script: |
const eventName = context.eventName;
let issue;
if (eventName === 'workflow_dispatch') {
const inputs = context.payload.inputs || {};
const issueNumber = inputs.issue_number || inputs.issueNumber;
if (!issueNumber) core.setFailed('Input issue_number is required for manual run.');
const { data } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: parseInt(issueNumber, 10),
});
issue = data;
} else if (context.payload.issue) {
issue = context.payload.issue;
} else {
core.setFailed('No issue information found in the event payload.');
}
core.setOutput('id', String(issue.number));
core.setOutput('user', String((issue.user && issue.user.login) || ''));
core.setOutput('title', String(issue.title || ''));
core.setOutput('body', String(issue.body || ''));
const labelNames = (issue.labels || []).map(label => label.name);
core.setOutput('labels', JSON.stringify(labelNames));
- name: Start Triage Orchestration
id: start_orchestration
env:
PAYLOAD: >-
{
"authToken": "${{ secrets.GITHUB_TOKEN }}",
"repoId": "microsoft/vscode-java-pack",
"issueData": {
"id": ${{ steps.get_issue.outputs.id }},
"user": ${{ toJson(steps.get_issue.outputs.user) }},
"title": ${{ toJson(steps.get_issue.outputs.title) }},
"body": ${{ toJson(steps.get_issue.outputs.body) }},
"labels": ${{ steps.get_issue.outputs.labels }}
},
"mode": "DirectUpdate"
}
run: |
# Start the durable function orchestration
echo "Starting triage orchestration..."
echo "Payload size: $(echo "$PAYLOAD" | wc -c) bytes"
# Make the initial request to start orchestration
set +e # Don't exit on curl failure
response=$(curl \
--max-time 60 \
--connect-timeout 30 \
--fail-with-body \
--silent \
--show-error \
--write-out "HTTPSTATUS:%{http_code}" \
--header "Content-Type: application/json" \
--request POST \
--data "$PAYLOAD" \
${{ secrets.TRIAGE_START_ENDPOINT }} 2>&1)
curl_exit_code=$?
set -e # Re-enable exit on error
echo "Start orchestration curl exit code: $curl_exit_code"
# Check if curl command failed
if [ $curl_exit_code -ne 0 ]; then
echo "❌ Failed to start orchestration with exit code: $curl_exit_code"
echo "Response: $response"
exit 1
fi
# Extract HTTP status code and response body
http_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2)
response_body=$(echo "$response" | sed 's/HTTPSTATUS:[0-9]*$//')
echo "HTTP Status Code: $http_code"
# Validate HTTP status code
if [ -z "$http_code" ]; then
echo "❌ Failed to extract HTTP status code from response"
echo "Raw response: $response"
exit 1
fi
# Check if the orchestration started successfully
if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then
echo "✅ Triage orchestration started successfully"
echo "Response: $response_body"
# Extract instance ID from response (assuming JSON response with instanceId field)
instance_id=$(echo "$response_body" | grep -o '"instanceId":"[^"]*"' | cut -d'"' -f4)
if [ -z "$instance_id" ]; then
echo "❌ Failed to extract instance ID from response"
echo "Response body: $response_body"
exit 1
fi
echo "Instance ID: $instance_id"
echo "instance_id=$instance_id" >> $GITHUB_OUTPUT
else
echo "❌ Failed to start orchestration with status code: $http_code"
echo "Response: $response_body"
exit 1
fi
- name: Poll Orchestration Status
id: poll_status
run: |
# Poll the orchestration status until completion
instance_id="${{ steps.start_orchestration.outputs.instance_id }}"
echo "Polling status for instance: $instance_id"
max_attempts=120 # Maximum number of polling attempts (10 minutes with 5-second intervals)
attempt=0
while [ $attempt -lt $max_attempts ]; do
attempt=$((attempt + 1))
echo "Polling attempt $attempt/$max_attempts..."
# Make status check request
set +e # Don't exit on curl failure
# Safely replace the {instanceId} placeholder using bash parameter expansion
status_url="${{ secrets.TRIAGE_STATUS_ENDPOINT }}"
status_url="${status_url//\{instanceId\}/$instance_id}"
response=$(curl \
--max-time 30 \
--connect-timeout 15 \
--fail-with-body \
--silent \
--show-error \
--write-out "HTTPSTATUS:%{http_code}" \
--request GET \
"$status_url" 2>&1)
curl_exit_code=$?
set -e # Re-enable exit on error
if [ $curl_exit_code -ne 0 ]; then
echo "❌ Status check failed with exit code: $curl_exit_code"
echo "Response: $response"
sleep 5
continue
fi
# Extract HTTP status code and response body
http_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2)
response_body=$(echo "$response" | sed 's/HTTPSTATUS:[0-9]*$//')
echo "Status check HTTP code: $http_code"
if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then
echo "Status response: $response_body"
# Check if orchestration is complete (using runtimeStatus field from actual response schema)
runtime_status=$(echo "$response_body" | grep -o '"runtimeStatus":"[^"]*"' | cut -d'"' -f4)
if [ "$runtime_status" = "Completed" ] || [ "$runtime_status" = "completed" ]; then
echo "✅ Triage orchestration completed successfully"
# Extract and display output if available
output=$(echo "$response_body" | grep -o '"output":[^,}]*' | cut -d':' -f2-)
if [ "$output" != "null" ] && [ -n "$output" ]; then
echo "Orchestration output: $output"
fi
exit 0
elif [ "$runtime_status" = "Failed" ] || [ "$runtime_status" = "failed" ]; then
echo "❌ Triage orchestration failed"
echo "Final response: $response_body"
# Extract and display output for error details if available
output=$(echo "$response_body" | grep -o '"output":[^,}]*' | cut -d':' -f2-)
if [ "$output" != "null" ] && [ -n "$output" ]; then
echo "Error details: $output"
fi
exit 1
elif [ "$runtime_status" = "Running" ] || [ "$runtime_status" = "running" ] || [ "$runtime_status" = "Pending" ] || [ "$runtime_status" = "pending" ]; then
echo "Orchestration status: $runtime_status, waiting..."
# Display last updated time for better monitoring
last_updated=$(echo "$response_body" | grep -o '"lastUpdatedAt":"[^"]*"' | cut -d'"' -f4)
if [ -n "$last_updated" ]; then
echo "Last updated: $last_updated"
fi
sleep 5
else
echo "Unknown runtime status: $runtime_status, continuing to poll..."
echo "Full response: $response_body"
sleep 5
fi
else
echo "❌ Status check returned HTTP $http_code"
echo "Response: $response_body"
sleep 5
fi
done
echo "❌ Orchestration polling timed out after $max_attempts attempts"
exit 1