Skip to content

Commit d7e7e40

Browse files
committed
Add issue triage and Teams notification workflows
1 parent 064f543 commit d7e7e40

2 files changed

Lines changed: 511 additions & 0 deletions

File tree

.github/workflows/issue-notify.yml

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
name: Issue Notification
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
category:
7+
required: true
8+
type: string
9+
confidence:
10+
required: true
11+
type: string
12+
severity:
13+
required: true
14+
type: string
15+
justification:
16+
required: true
17+
type: string
18+
summary_for_maintainers:
19+
required: true
20+
type: string
21+
relevant_files:
22+
required: true
23+
type: string
24+
keywords:
25+
required: true
26+
type: string
27+
code_analysis:
28+
required: false
29+
type: string
30+
default: ''
31+
issue_number:
32+
required: true
33+
type: string
34+
issue_title:
35+
required: true
36+
type: string
37+
issue_url:
38+
required: true
39+
type: string
40+
issue_author:
41+
required: true
42+
type: string
43+
secrets:
44+
TEAMS_WEBHOOK_URL:
45+
required: true
46+
47+
jobs:
48+
send-notification:
49+
runs-on: ubuntu-latest
50+
steps:
51+
- name: Send Teams Channel notification
52+
env:
53+
INPUT_CATEGORY: ${{ inputs.category }}
54+
INPUT_SEVERITY: ${{ inputs.severity }}
55+
INPUT_CONFIDENCE: ${{ inputs.confidence }}
56+
INPUT_ISSUE_NUMBER: ${{ inputs.issue_number }}
57+
INPUT_ISSUE_TITLE: ${{ inputs.issue_title }}
58+
INPUT_ISSUE_AUTHOR: ${{ inputs.issue_author }}
59+
INPUT_ISSUE_URL: ${{ inputs.issue_url }}
60+
INPUT_KEYWORDS: ${{ inputs.keywords }}
61+
INPUT_RELEVANT_FILES: ${{ inputs.relevant_files }}
62+
INPUT_SUMMARY: ${{ inputs.summary_for_maintainers }}
63+
INPUT_CODE_ANALYSIS: ${{ inputs.code_analysis }}
64+
INPUT_ACTION_TEXT: ${{ inputs.justification }}
65+
TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }}
66+
run: |
67+
CATEGORY="$INPUT_CATEGORY"
68+
SEVERITY="$INPUT_SEVERITY"
69+
70+
# Set emoji and action based on category
71+
case "$CATEGORY" in
72+
FEATURE_REQUEST)
73+
EMOJI="💡"
74+
CATEGORY_DISPLAY="Feature Request"
75+
ACTION="Evaluate against roadmap. If approved, create ADO work item."
76+
;;
77+
BUG)
78+
EMOJI="🐛"
79+
CATEGORY_DISPLAY="Bug"
80+
ACTION="Validate bug, reproduce if possible, assign to developer."
81+
;;
82+
DISCUSSION)
83+
EMOJI="💬"
84+
CATEGORY_DISPLAY="Discussion"
85+
ACTION="Respond with guidance. Re-classify if needed."
86+
;;
87+
BREAK_FIX)
88+
EMOJI="🚨"
89+
CATEGORY_DISPLAY="Break/Fix (Regression)"
90+
ACTION="URGENT: Assign to senior dev, create P0/P1 ADO item."
91+
;;
92+
*)
93+
EMOJI="❓"
94+
CATEGORY_DISPLAY="Unknown"
95+
ACTION="Review and manually classify this issue."
96+
;;
97+
esac
98+
99+
# Truncate code analysis if too long
100+
CODE_ANALYSIS="$INPUT_CODE_ANALYSIS"
101+
if [ ${#CODE_ANALYSIS} -gt 1500 ]; then
102+
CODE_ANALYSIS="${CODE_ANALYSIS:0:1500}... (see Actions log for full analysis)"
103+
fi
104+
if [ -z "$CODE_ANALYSIS" ]; then
105+
CODE_ANALYSIS="N/A — classification did not require code analysis."
106+
fi
107+
108+
# Build Adaptive Card payload using jq for proper JSON escaping
109+
jq -n \
110+
--arg emoji "$EMOJI" \
111+
--arg category "$CATEGORY" \
112+
--arg category_display "$CATEGORY_DISPLAY" \
113+
--arg severity "$SEVERITY" \
114+
--arg confidence "$INPUT_CONFIDENCE" \
115+
--arg issue_num "$INPUT_ISSUE_NUMBER" \
116+
--arg issue_title "$INPUT_ISSUE_TITLE" \
117+
--arg issue_author "$INPUT_ISSUE_AUTHOR" \
118+
--arg issue_url "$INPUT_ISSUE_URL" \
119+
--arg keywords "$INPUT_KEYWORDS" \
120+
--arg relevant_files "$INPUT_RELEVANT_FILES" \
121+
--arg summary "$INPUT_SUMMARY" \
122+
--arg code_analysis "$CODE_ANALYSIS" \
123+
--arg action "$ACTION" \
124+
'{
125+
"type": "message",
126+
"attachments": [
127+
{
128+
"contentType": "application/vnd.microsoft.card.adaptive",
129+
"content": {
130+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
131+
"type": "AdaptiveCard",
132+
"version": "1.4",
133+
"body": [
134+
{
135+
"type": "TextBlock",
136+
"size": "large",
137+
"weight": "bolder",
138+
"text": ($emoji + " mssql-python Issue Triage"),
139+
"wrap": true,
140+
"style": "heading"
141+
},
142+
{
143+
"type": "ColumnSet",
144+
"columns": [
145+
{
146+
"type": "Column",
147+
"width": "auto",
148+
"items": [
149+
{
150+
"type": "TextBlock",
151+
"text": $category_display,
152+
"weight": "bolder",
153+
"color": (if $category == "BREAK_FIX" then "attention"
154+
elif $category == "BUG" then "warning"
155+
else "default" end),
156+
"size": "medium"
157+
}
158+
]
159+
},
160+
{
161+
"type": "Column",
162+
"width": "auto",
163+
"items": [
164+
{
165+
"type": "TextBlock",
166+
"text": ("Severity: " + $severity),
167+
"size": "medium",
168+
"color": (if $severity == "critical" then "attention"
169+
elif $severity == "high" then "warning"
170+
else "default" end)
171+
}
172+
]
173+
},
174+
{
175+
"type": "Column",
176+
"width": "auto",
177+
"items": [
178+
{
179+
"type": "TextBlock",
180+
"text": ("Confidence: " + $confidence + "%"),
181+
"size": "medium"
182+
}
183+
]
184+
}
185+
]
186+
},
187+
{
188+
"type": "FactSet",
189+
"separator": true,
190+
"facts": [
191+
{ "title": "Issue", "value": ("#" + $issue_num + " — " + $issue_title) },
192+
{ "title": "Author", "value": ("@" + $issue_author) },
193+
{ "title": "Keywords", "value": $keywords },
194+
{ "title": "Relevant Files", "value": $relevant_files }
195+
]
196+
},
197+
{
198+
"type": "TextBlock",
199+
"text": "**📝 Analysis**",
200+
"weight": "bolder",
201+
"spacing": "medium",
202+
"wrap": true
203+
},
204+
{
205+
"type": "TextBlock",
206+
"text": $summary,
207+
"wrap": true
208+
},
209+
{
210+
"type": "TextBlock",
211+
"text": "**🔍 Code Analysis**",
212+
"weight": "bolder",
213+
"spacing": "medium",
214+
"wrap": true
215+
},
216+
{
217+
"type": "TextBlock",
218+
"text": $code_analysis,
219+
"wrap": true,
220+
"fontType": "monospace",
221+
"size": "small"
222+
},
223+
{
224+
"type": "TextBlock",
225+
"text": ("⚡ **Action Required:** " + $action),
226+
"weight": "bolder",
227+
"color": "attention",
228+
"spacing": "medium",
229+
"wrap": true,
230+
"separator": true
231+
}
232+
],
233+
"actions": [
234+
{
235+
"type": "Action.OpenUrl",
236+
"title": "📋 View Issue",
237+
"url": $issue_url
238+
},
239+
{
240+
"type": "Action.OpenUrl",
241+
"title": "📂 View Repository",
242+
"url": "https://github.com/microsoft/mssql-python"
243+
}
244+
]
245+
}
246+
}
247+
]
248+
}' > /tmp/teams_payload.json
249+
250+
echo "Sending notification to Teams Channel..."
251+
252+
HTTP_STATUS=$(curl -s -o /tmp/teams_response.txt -w "%{http_code}" \
253+
-H "Content-Type: application/json" \
254+
-d @/tmp/teams_payload.json \
255+
"$TEAMS_WEBHOOK_URL")
256+
257+
echo "Teams API response: $HTTP_STATUS"
258+
cat /tmp/teams_response.txt
259+
260+
if [ "$HTTP_STATUS" -lt 200 ] || [ "$HTTP_STATUS" -ge 300 ]; then
261+
echo "::error::Failed to send Teams notification. HTTP status: $HTTP_STATUS"
262+
exit 1
263+
fi
264+
265+
echo "✅ Teams Channel notification sent successfully"

0 commit comments

Comments
 (0)