@@ -2,7 +2,9 @@ name: Security Vulnerability Slack Notification
22
33on :
44 schedule :
5+ # Runs every hour at minute 0
56 - cron : ' 0 * * * *'
7+ # Allows you to test manually
68 workflow_dispatch :
79
810jobs :
@@ -12,42 +14,49 @@ jobs:
1214 - name : Checkout code
1315 uses : actions/checkout@v3
1416
15- - name : Check for Recent Alerts
17+ - name : Check for New Alerts
1618 env :
1719 GH_TOKEN : ${{ secrets.DEPENDABOT_PAT }}
1820 SLACK_WEBHOOK_URL : ${{ secrets.SLACK_WEBHOOK_URL }}
1921 run : |
20- echo "--- CHECKING FOR ALERTS ---"
22+ # 1. Calculate time 65 minutes ago
23+ # This ensures we only notify about alerts created since the last run
24+ TIME_THRESHOLD=$(date -u -d '65 minutes ago' +'%Y-%m-%dT%H:%M:%SZ')
25+ echo "Checking for alerts created after: $TIME_THRESHOLD"
2126
22- # 1 . Fetch ALL open alerts
27+ # 2 . Fetch Open Alerts
2328 RAW_DATA=$(gh api "/repos/${{ github.repository }}/dependabot/alerts?state=open")
2429
25- # 2. Filter: (Currently set to ALL open alerts for testing)
26- # To go live, uncomment the time filter later: | select(.created_at > $TIME_THRESHOLD)
27- ALERTS=$(echo "$RAW_DATA" | jq '[ .[] | select(.state == "open") ]')
30+ # 3. Filter for NEW items only
31+ # We look for Open alerts created > 65 mins ago
32+ ALERTS=$(echo "$RAW_DATA" | jq --arg TIME "$TIME_THRESHOLD" \
33+ '[ .[] | select(.state == "open") | select(.created_at > $TIME) ]')
2834
29- # 3. Check count
35+ # --- FOR TESTING ONLY: UNCOMMENT BELOW TO IGNORE TIME FILTER ---
36+ # ALERTS=$(echo "$RAW_DATA" | jq '[ .[] | select(.state == "open") ]')
37+ # ---------------------------------------------------------------
38+
39+ # 4. Check count
3040 LENGTH=$(echo "$ALERTS" | jq 'length')
3141 if [ "$LENGTH" -eq 0 ]; then
32- echo "::notice:: No alerts found."
42+ echo "::notice:: No new alerts found in the last hour ."
3343 exit 0
3444 fi
3545
36- echo "Found $LENGTH alerts . Sending notifications..."
46+ echo "Found $LENGTH new alert(s) . Sending notifications..."
3747 REPO_NAME="${{ github.repository }}"
3848 ISSUE_USER="Dependabot"
3949
40- # 4. LOOP through each alert found
41- # 'jq -c .[]' prints each alert object on a new line so we can loop over them
50+ # 5. LOOP through each alert
4251 echo "$ALERTS" | jq -c '.[]' | while read -r alert; do
4352
44- # Extract details for THIS specific alert
53+ # Extract details
4554 SUMMARY=$(echo "$alert" | jq -r '.security_advisory.summary // "Security Vulnerability"')
4655 PACKAGE=$(echo "$alert" | jq -r '.dependency.package.name // "Unknown Package"')
4756 SEVERITY=$(echo "$alert" | jq -r '.security_advisory.severity // "Unknown"')
4857 ISSUE_URL=$(echo "$alert" | jq -r '.html_url // .url // "https://github.com"')
4958
50- # Format Title
59+ # Format Title (e.g., "Cross-site Scripting - next (high)")
5160 ISSUE_TITLE="${SUMMARY} - ${PACKAGE} (${SEVERITY})"
5261
5362 echo "Sending alert for: $PACKAGE"
5867 --arg title "$ISSUE_TITLE" \
5968 --arg user "$ISSUE_USER" \
6069 --arg url "$ISSUE_URL" \
61- --arg template "*📢 New Dependabot Alert ($REPO_NAME) 📢 *\n\n*Issue Title:* $ISSUE_TITLE\n*Opened By:* $ISSUE_USER\n\n*View Issue:* $ISSUE_URL" \
70+ --arg template "*🚨 New Dependabot Alert ($REPO_NAME) 🚨 *\n\n*Issue Title:* $ISSUE_TITLE\n*Opened By:* $ISSUE_USER\n\n*View Issue:* $ISSUE_URL" \
6271 '$template')
6372
6473 # Build Payload
7786 --data "$SLACK_PAYLOAD" \
7887 "$SLACK_WEBHOOK_URL"
7988
80- # Small sleep to prevent rate limiting if there are many alerts
8189 sleep 1
8290 done
0 commit comments