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