[FEATURE] WinML Dashboard #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright (c) Microsoft Corporation. All rights reserved. | |
| # Licensed under the MIT License. | |
| name: Issue Triage | |
| on: | |
| issues: | |
| types: [opened] | |
| # Limit concurrent runs to prevent race conditions on Gist updates | |
| concurrency: | |
| group: issue-triage | |
| cancel-in-progress: false | |
| jobs: | |
| triage: | |
| name: AI Issue Triage | |
| runs-on: ubuntu-latest | |
| # Don't run on issues created by bots | |
| if: github.actor != 'github-actions[bot]' && github.actor != 'dependabot[bot]' | |
| permissions: | |
| issues: write | |
| contents: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| sparse-checkout: | | |
| .github/scripts | |
| sparse-checkout-cone-mode: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Run AI Triage | |
| id: triage | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GIST_PAT: ${{ secrets.GIST_PAT }} | |
| GIST_ID: ${{ secrets.GIST_ID }} | |
| ISSUE_NUMBER: ${{ github.event.issue.number }} | |
| ISSUE_TITLE: ${{ github.event.issue.title }} | |
| ISSUE_BODY: ${{ github.event.issue.body }} | |
| ISSUE_URL: ${{ github.event.issue.html_url }} | |
| REPO_OWNER: ${{ github.repository_owner }} | |
| REPO_NAME: ${{ github.event.repository.name }} | |
| run: node .github/scripts/triage-issue.js | |
| - name: Summary | |
| if: always() | |
| env: | |
| ISSUE_NUMBER: ${{ github.event.issue.number }} | |
| ISSUE_TITLE: ${{ github.event.issue.title }} | |
| TRIAGE_LABELS: ${{ steps.triage.outputs.labels }} | |
| TRIAGE_SUMMARY: ${{ steps.triage.outputs.summary }} | |
| TRIAGE_CONFIDENCE: ${{ steps.triage.outputs.confidence }} | |
| run: | | |
| echo "## Issue Triage Results" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "**Issue:** #$ISSUE_NUMBER" >> "$GITHUB_STEP_SUMMARY" | |
| echo "**Title:** $ISSUE_TITLE" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| if [ -n "$TRIAGE_LABELS" ]; then | |
| echo "**Labels Applied:** $TRIAGE_LABELS" >> "$GITHUB_STEP_SUMMARY" | |
| SAFE_TRIAGE_SUMMARY=$(printf '%s' "$TRIAGE_SUMMARY" | sed 's/\\/\\\\/g; s/`/\\`/g; s/\$/\\$/g') | |
| echo "**AI Summary:** $SAFE_TRIAGE_SUMMARY" >> "$GITHUB_STEP_SUMMARY" | |
| echo "**Confidence:** $TRIAGE_CONFIDENCE" >> "$GITHUB_STEP_SUMMARY" | |
| else | |
| echo "[WARN] No labels were applied" >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Send Teams Notification | |
| if: success() && steps.triage.outputs.labels != '' | |
| continue-on-error: true | |
| env: | |
| TEAMS_CHANNEL_WEBHOOK_URL: ${{ secrets.TEAMS_CHANNEL_WEBHOOK_URL }} | |
| ISSUE_NUMBER: ${{ github.event.issue.number }} | |
| ISSUE_TITLE: ${{ github.event.issue.title }} | |
| ISSUE_URL: ${{ github.event.issue.html_url }} | |
| TRIAGE_LABELS: ${{ steps.triage.outputs.labels }} | |
| TRIAGE_SUMMARY: ${{ steps.triage.outputs.summary }} | |
| TRIAGE_CONFIDENCE: ${{ steps.triage.outputs.confidence }} | |
| run: | | |
| if [ -z "$TEAMS_CHANNEL_WEBHOOK_URL" ]; then | |
| echo "Teams webhook not configured, skipping notification" | |
| exit 0 | |
| fi | |
| # Escape special characters for JSON | |
| MAX_TITLE_LENGTH=120 | |
| TITLE_FOR_TEAMS="$ISSUE_TITLE" | |
| if [ "${#ISSUE_TITLE}" -gt "$MAX_TITLE_LENGTH" ]; then | |
| TRUNCATED_TITLE=$(printf '%s' "$ISSUE_TITLE" | cut -c1-$((MAX_TITLE_LENGTH - 1))) | |
| TITLE_FOR_TEAMS="${TRUNCATED_TITLE}..." | |
| fi | |
| SAFE_TITLE=$(printf '%s' "$TITLE_FOR_TEAMS" | jq -Rs '.') | |
| SAFE_LABELS=$(printf '%s' "${TRIAGE_LABELS:-none}" | jq -Rs '.') | |
| SAFE_SUMMARY_TEXT=$(printf '**Summary:** %s' "$TRIAGE_SUMMARY" | jq -Rs '.') | |
| CONFIDENCE_PCT=$(echo "$TRIAGE_CONFIDENCE" | awk '{printf "%.0f", $1 * 100}') | |
| # Build Adaptive Card JSON | |
| cat > /tmp/teams-card.json << CARD_EOF | |
| { | |
| "type": "message", | |
| "attachments": [{ | |
| "contentType": "application/vnd.microsoft.card.adaptive", | |
| "content": { | |
| "\$schema": "http://adaptivecards.io/schemas/adaptive-card.json", | |
| "type": "AdaptiveCard", | |
| "version": "1.4", | |
| "body": [ | |
| { | |
| "type": "TextBlock", | |
| "text": "New Issue Triaged", | |
| "weight": "Bolder", | |
| "size": "Large", | |
| "color": "Accent" | |
| }, | |
| { | |
| "type": "FactSet", | |
| "facts": [ | |
| { "title": "Issue", "value": "#$ISSUE_NUMBER" }, | |
| { "title": "Title", "value": ${SAFE_TITLE} }, | |
| { "title": "Labels", "value": ${SAFE_LABELS} }, | |
| { "title": "Confidence", "value": "${CONFIDENCE_PCT}%" } | |
| ] | |
| }, | |
| { | |
| "type": "TextBlock", | |
| "text": ${SAFE_SUMMARY_TEXT}, | |
| "wrap": true, | |
| "spacing": "Medium" | |
| } | |
| ], | |
| "actions": [ | |
| { | |
| "type": "Action.OpenUrl", | |
| "title": "View Issue", | |
| "url": "$ISSUE_URL" | |
| } | |
| ] | |
| } | |
| }] | |
| } | |
| CARD_EOF | |
| # Send to Teams | |
| HTTP_CODE=$(curl -s -o /tmp/teams-response.txt -w "%{http_code}" \ | |
| -X POST "$TEAMS_CHANNEL_WEBHOOK_URL" \ | |
| -H "Content-Type: application/json" \ | |
| -d @/tmp/teams-card.json) | |
| if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then | |
| echo "Teams notification sent successfully" | |
| else | |
| echo "Failed to send Teams notification (HTTP $HTTP_CODE)" | |
| cat /tmp/teams-response.txt | |
| exit 1 | |
| fi |