-
Notifications
You must be signed in to change notification settings - Fork 45
229 lines (216 loc) Β· 9.95 KB
/
issue-notify.yml
File metadata and controls
229 lines (216 loc) Β· 9.95 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
225
226
227
228
229
name: Issue Notification
on:
workflow_call:
inputs:
category:
required: true
type: string
confidence:
required: true
type: string
severity:
required: true
type: string
justification:
required: true
type: string
summary_for_maintainers:
required: true
type: string
relevant_files:
required: true
type: string
keywords:
required: true
type: string
code_analysis:
required: false
type: string
default: ''
engineer_guidance:
required: false
type: string
default: ''
issue_number:
required: true
type: string
issue_title:
required: true
type: string
issue_url:
required: true
type: string
issue_author:
required: true
type: string
secrets:
TEAMS_WEBHOOK_URL:
required: true
permissions:
contents: read
jobs:
send-notification:
runs-on: ubuntu-latest
steps:
- name: Send Teams Channel notification
env:
INPUT_CATEGORY: ${{ inputs.category }}
INPUT_SEVERITY: ${{ inputs.severity }}
INPUT_CONFIDENCE: ${{ inputs.confidence }}
INPUT_ISSUE_NUMBER: ${{ inputs.issue_number }}
INPUT_ISSUE_TITLE: ${{ inputs.issue_title }}
INPUT_ISSUE_AUTHOR: ${{ inputs.issue_author }}
INPUT_ISSUE_URL: ${{ inputs.issue_url }}
INPUT_KEYWORDS: ${{ inputs.keywords }}
INPUT_RELEVANT_FILES: ${{ inputs.relevant_files }}
INPUT_SUMMARY: ${{ inputs.summary_for_maintainers }}
INPUT_CODE_ANALYSIS: ${{ inputs.code_analysis }}
INPUT_ENGINEER_GUIDANCE: ${{ inputs.engineer_guidance }}
INPUT_JUSTIFICATION: ${{ inputs.justification }}
TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }}
run: |
CATEGORY="$INPUT_CATEGORY"
SEVERITY="$INPUT_SEVERITY"
# Set emoji and action based on category
case "$CATEGORY" in
FEATURE_REQUEST)
EMOJI="π‘"
CATEGORY_DISPLAY="Feature Request"
ACTION="Evaluate against roadmap. If approved, create ADO work item."
;;
BUG)
EMOJI="π"
CATEGORY_DISPLAY="Bug"
ACTION="Validate bug, reproduce if possible, assign to developer."
;;
DISCUSSION)
EMOJI="π¬"
CATEGORY_DISPLAY="Discussion"
ACTION="Respond with guidance. Re-classify if needed."
;;
BREAK_FIX)
EMOJI="π¨"
CATEGORY_DISPLAY="Break/Fix (Regression)"
ACTION="URGENT: Assign to senior dev, create P0/P1 ADO item."
;;
*)
EMOJI="β"
CATEGORY_DISPLAY="Unknown"
ACTION="Review and manually classify this issue."
;;
esac
# Parse and format code analysis from JSON into readable text
CODE_ANALYSIS_RAW="$INPUT_CODE_ANALYSIS"
if [ -n "$CODE_ANALYSIS_RAW" ]; then
# Try to parse as JSON and extract structured fields
CODE_ANALYSIS=$(echo "$CODE_ANALYSIS_RAW" | jq -r '
[
(if .is_bug then "<b>Verdict:</b> " + (.is_bug | @html) else empty end),
(if .root_cause then "<b>Root Cause:</b> " + (.root_cause | @html) else empty end),
(if .affected_components and (.affected_components | length) > 0
then "<b>Affected Components:</b><br>" + ([.affected_components[] | " β’ " + (. | @html)] | join("<br>"))
else empty end),
(if .evidence_and_context then "<b>Evidence & Context:</b> " + (.evidence_and_context | @html) else empty end),
(if .recommended_fixes and (.recommended_fixes | length) > 0
then "<b>Recommended Fixes:</b><br>" + ([.recommended_fixes | to_entries[] | " " + ((.key + 1) | tostring) + ". " + (.value | @html)] | join("<br>"))
else empty end),
(if .code_locations and (.code_locations | length) > 0
then "<b>Code Locations:</b><br>" + ([.code_locations[] | " β’ " + (. | @html)] | join("<br>"))
else empty end),
(if .risk_assessment then "<b>Risk Assessment:</b> " + (.risk_assessment | @html) else empty end)
] | join("<br><br>")
' 2>/dev/null || echo "$CODE_ANALYSIS_RAW" | sed 's/&/\&/g; s/</\</g; s/>/\>/g')
else
CODE_ANALYSIS="N/A β classification did not require code analysis."
fi
# Parse and format engineer guidance from JSON into readable text
ENGINEER_GUIDANCE_RAW="$INPUT_ENGINEER_GUIDANCE"
if [ -n "$ENGINEER_GUIDANCE_RAW" ]; then
ENGINEER_GUIDANCE=$(echo "$ENGINEER_GUIDANCE_RAW" | jq -r '
[
(if .technical_assessment then "<b>Technical Assessment:</b> " + (.technical_assessment | @html) else empty end),
(if .verdict then "<b>Verdict:</b> " + (.verdict | @html) else empty end),
(if .effort_estimate then "Effort Estimate: " + (.effort_estimate | @html) else empty end),
(if .affected_files and (.affected_files | length) > 0
then "<b>Affected Files:</b><br>" + ([.affected_files[] | " β’ " + (. | @html)] | join("<br>"))
else empty end),
(if .implementation_approach then "<b>Implementation Approach:</b> " + (.implementation_approach | @html) else empty end),
(if .risks_and_tradeoffs then "<b>Risks & Tradeoffs:</b> " + (.risks_and_tradeoffs | @html) else empty end),
(if .suggested_response then "<b>Suggested Response to User:</b><br>" + (.suggested_response | @html) else empty end),
(if .related_considerations and (.related_considerations | length) > 0
then "<b>Related Considerations:</b><br>" + ([.related_considerations | to_entries[] | " " + ((.key + 1) | tostring) + ". " + (.value | @html)] | join("<br>"))
else empty end)
] | join("<br><br>")
' 2>/dev/null || echo "$ENGINEER_GUIDANCE_RAW" | sed 's/&/\&/g; s/</\</g; s/>/\>/g')
else
ENGINEER_GUIDANCE=""
fi
# Set severity color indicator
case "$SEVERITY" in
critical) SEV_INDICATOR="π΄" ;;
high) SEV_INDICATOR="π " ;;
medium) SEV_INDICATOR="π‘" ;;
*) SEV_INDICATOR="π’" ;;
esac
# Build well-formatted HTML message using jq for proper JSON escaping
jq -n \
--arg emoji "$EMOJI" \
--arg category_display "$CATEGORY_DISPLAY" \
--arg severity "$SEVERITY" \
--arg sev_indicator "$SEV_INDICATOR" \
--arg confidence "$INPUT_CONFIDENCE" \
--arg issue_num "$INPUT_ISSUE_NUMBER" \
--arg issue_title "$INPUT_ISSUE_TITLE" \
--arg issue_author "$INPUT_ISSUE_AUTHOR" \
--arg issue_url "$INPUT_ISSUE_URL" \
--arg keywords "$INPUT_KEYWORDS" \
--arg relevant_files "$INPUT_RELEVANT_FILES" \
--arg summary "$INPUT_SUMMARY" \
--arg code_analysis "$CODE_ANALYSIS" \
--arg engineer_guidance "$ENGINEER_GUIDANCE" \
--arg justification "$INPUT_JUSTIFICATION" \
--arg action "$ACTION" \
--arg repo_url "https://github.com/microsoft/mssql-python" \
'{
"text": (
"<h2>" + $emoji + " mssql-python Issue Triage</h2>" +
"<p><b>" + $category_display + "</b> | " +
$sev_indicator + " Severity: <b>" + $severity + "</b> | " +
"Confidence: <b>" + $confidence + "%</b></p>" +
"<hr>" +
"<p>" +
"π <b>Issue:</b> <a href=\"" + $issue_url + "\">#" + $issue_num + " β " + ($issue_title | @html) + "</a><br>" +
"π€ <b>Author:</b> @" + ($issue_author | @html) + "<br>" +
"π·οΈ <b>Keywords:</b> " + ($keywords | @html) + "<br>" +
"π <b>Relevant Files:</b> " + ($relevant_files | @html) + "<br>" +
"π¬ <b>Justification:</b> " + ($justification | @html) +
"</p>" +
"<hr>" +
"<h3>π Analysis</h3>" +
"<p>" + ($summary | @html) + "</p>" +
"<h3>π Code Analysis</h3>" +
"<p>" + $code_analysis + "</p>" +
(if $engineer_guidance != "" then
"<h3>π‘ Engineer Guidance</h3>" +
"<p>" + $engineer_guidance + "</p>"
else "" end) +
"<hr>" +
"<p>β‘ <b>Action Required:</b> " + $action + "</p>" +
"<p><i>β οΈ AI-generated analysis β verified against source code but may contain inaccuracies. Review before acting.</i></p>" +
"<p><a href=\"" + $issue_url + "\">π View Issue</a>" +
" | " +
"<a href=\"" + $repo_url + "\">π View Repository</a></p>"
)
}' > /tmp/teams_payload.json
echo "Sending notification to Teams Channel..."
HTTP_STATUS=$(curl -s -o /tmp/teams_response.txt -w "%{http_code}" \
-H "Content-Type: application/json" \
-d @/tmp/teams_payload.json \
"$TEAMS_WEBHOOK_URL")
echo "Teams API response: $HTTP_STATUS"
cat /tmp/teams_response.txt
if [ "$HTTP_STATUS" -lt 200 ] || [ "$HTTP_STATUS" -ge 300 ]; then
echo "::error::Failed to send Teams notification. HTTP status: $HTTP_STATUS"
exit 1
fi
echo "β
Teams Channel notification sent successfully"