forked from lifinance/contracts
-
Notifications
You must be signed in to change notification settings - Fork 0
198 lines (160 loc) Β· 8.91 KB
/
securityAlertsReview.yml
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
name: Security Alerts Review
on:
push:
paths:
- "**/*.sol"
- ".github/workflows/securityAlertsReview.yml"
issue_comment:
types:
- created
- edited
pull_request:
types:
- ready_for_review
workflow_dispatch:
jobs:
check-security-alerts:
runs-on: ubuntu-latest
steps:
- name: Fetch PR Number
id: fetch_pr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${{ github.repository }}/pulls?state=open" | jq -r '.[0].number')
if [[ -z "$PR_NUMBER" || "$PR_NUMBER" == "null" ]]; then
echo "No open PR found, skipping check."
exit 0
fi
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
echo "PR number: $PR_NUMBER"
- name: Fetch Security Alerts for PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Fetching security alerts for PR #${PR_NUMBER}..."
# Fetch security alerts via GitHub API
ALERTS=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${{ github.repository }}/code-scanning/alerts?pr=${PR_NUMBER}")
# Log raw API response for debugging
echo "Raw API Response:"
echo "$ALERTS"
# Ensure valid JSON parsing; default to empty array if parsing fails
UNRESOLVED_ALERTS=$(echo "$ALERTS" | jq -c '[.[] | select(.state == "open")]' || echo "[]")
DISMISSED_WITH_COMMENTS=$(echo "$ALERTS" | jq -c '[.[] | select(.state == "dismissed" and (.dismissed_comment != null and .dismissed_comment != ""))]' || echo "[]")
DISMISSED_WITHOUT_COMMENTS=$(echo "$ALERTS" | jq -c '[.[] | select(.state == "dismissed" and (.dismissed_comment == null or .dismissed_comment == ""))]' || echo "[]")
UNRESOLVED_COUNT=$(echo "$UNRESOLVED_ALERTS" | jq -r 'length')
DISMISSED_WITH_COMMENTS_COUNT=$(echo "$DISMISSED_WITH_COMMENTS" | jq -r 'length')
DISMISSED_WITHOUT_COMMENTS_COUNT=$(echo "$DISMISSED_WITHOUT_COMMENTS" | jq -r 'length')
# Output for debugging
echo "UNRESOLVED_ALERTS: $UNRESOLVED_ALERTS"
echo "DISMISSED_WITH_COMMENTS: $DISMISSED_WITH_COMMENTS"
echo "DISMISSED_WITHOUT_COMMENTS: $DISMISSED_WITHOUT_COMMENTS"
echo "UNRESOLVED_COUNT: $UNRESOLVED_COUNT"
echo "DISMISSED_WITH_COMMENTS_COUNT: $DISMISSED_WITH_COMMENTS_COUNT"
echo "DISMISSED_WITHOUT_COMMENTS_COUNT: $DISMISSED_WITHOUT_COMMENTS_COUNT"
# Save them properly in the environment as single-line JSON
echo "UNRESOLVED_ALERTS=$UNRESOLVED_ALERTS" >> $GITHUB_ENV
echo "DISMISSED_WITH_COMMENTS=$DISMISSED_WITH_COMMENTS" >> $GITHUB_ENV
echo "DISMISSED_WITHOUT_COMMENTS=$DISMISSED_WITHOUT_COMMENTS" >> $GITHUB_ENV
echo "UNRESOLVED_COUNT=$UNRESOLVED_COUNT" >> $GITHUB_ENV
echo "DISMISSED_WITH_COMMENTS_COUNT=$DISMISSED_WITH_COMMENTS_COUNT" >> $GITHUB_ENV
echo "DISMISSED_WITHOUT_COMMENTS_COUNT=$DISMISSED_WITHOUT_COMMENTS_COUNT" >> $GITHUB_ENV
- name: Find Existing PR Comment
id: find_comment
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Searching for existing PR comment..."
COMMENT_ID=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" | jq -r \
'.[] | select(.body | startswith("### π€ GitHub Action: Security Alerts Review")) | .id')
if [[ -n "$COMMENT_ID" && "$COMMENT_ID" != "null" ]]; then
echo "EXISTING_COMMENT_ID=$COMMENT_ID" >> $GITHUB_ENV
fi
echo "Found comment ID: $COMMENT_ID"
- name: Post or Update PR Comment
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
COMMENT_BODY="### π€ GitHub Action: Security Alerts Review π\n\n"
# Add Unresolved Alerts
if [[ "$UNRESOLVED_COUNT" -gt 0 ]]; then
COMMENT_BODY+="π¨ **Unresolved Security Alerts Found!** π¨\n"
COMMENT_BODY+="The following security alerts must be **resolved** before merging:\n\n"
while IFS= read -r row; do
ALERT_URL=$(echo "$row" | jq -r '.html_url')
ALERT_FILE=$(echo "$row" | jq -r '.most_recent_instance.location.path')
ALERT_DESCRIPTION=$(echo "$row" | jq -r '.most_recent_instance.message.text')
COMMENT_BODY+="π΄ [View Alert]($ALERT_URL) - **File:** \`$ALERT_FILE\`\n"
COMMENT_BODY+=" πΉ $ALERT_DESCRIPTION\n\n"
done < <(echo "$UNRESOLVED_ALERTS" | jq -c '.[]')
COMMENT_BODY+="β οΈ **Please resolve these alerts before merging.**\n\n"
fi
# Add Dismissed Alerts With Comments (Including Reason)
if [[ "$DISMISSED_WITH_COMMENTS_COUNT" -gt 0 ]]; then
COMMENT_BODY+="π’ **Some security alerts were dismissed with comments.** β
\n"
COMMENT_BODY+="The following alerts were dismissed with explanations:\n\n"
while IFS= read -r row; do
ALERT_URL=$(echo "$row" | jq -r '.html_url')
ALERT_FILE=$(echo "$row" | jq -r '.most_recent_instance.location.path')
ALERT_DESCRIPTION=$(echo "$row" | jq -r '.most_recent_instance.message.text')
DISMISS_REASON=$(echo "$row" | jq -r '.dismissed_reason')
DISMISS_COMMENT=$(echo "$row" | jq -r '.dismissed_comment')
COMMENT_BODY+="π’ [View Alert]($ALERT_URL) - **File:** \`$ALERT_FILE\`\n"
COMMENT_BODY+=" πΉ $ALERT_DESCRIPTION\n"
COMMENT_BODY+=" βοΈ **Dismissal Reason:** \`$DISMISS_REASON\`\n"
COMMENT_BODY+=" π¬ **Comment:** \"$DISMISS_COMMENT\"\n\n"
done < <(echo "$DISMISSED_WITH_COMMENTS" | jq -c '.[]')
COMMENT_BODY+="β
**These alerts were dismissed with valid explanations.**\n\n"
fi
# Add Dismissed Alerts Without Comments
if [[ "$DISMISSED_WITHOUT_COMMENTS_COUNT" -gt 0 ]]; then
COMMENT_BODY+="β **Some security alerts were dismissed without comments!** β\n"
COMMENT_BODY+="The following alerts were dismissed but require a reason:\n\n"
while IFS= read -r row; do
ALERT_URL=$(echo "$row" | jq -r '.html_url')
ALERT_FILE=$(echo "$row" | jq -r '.most_recent_instance.location.path')
ALERT_DESCRIPTION=$(echo "$row" | jq -r '.most_recent_instance.message.text')
COMMENT_BODY+="β οΈ [View Alert]($ALERT_URL) - **File:** \`$ALERT_FILE\`\n"
COMMENT_BODY+=" πΉ $ALERT_DESCRIPTION\n\n"
done < <(echo "$DISMISSED_WITHOUT_COMMENTS" | jq -c '.[]')
COMMENT_BODY+="β οΈ **Please provide a dismissal reason for these alerts.**\n\n"
fi
# If no issues, success message
if [[ "$UNRESOLVED_COUNT" -eq 0 && "$DISMISSED_WITHOUT_COMMENTS_COUNT" -eq 0 ]]; then
COMMENT_BODY+="β
**No unresolved security alerts!** π\n\n"
fi
# Update existing comment if found
if [[ -n "$EXISTING_COMMENT_ID" ]]; then
echo "Updating existing comment ID: $EXISTING_COMMENT_ID"
curl -s -X PATCH -H "Authorization: token ${GITHUB_TOKEN}" -H "Content-Type: application/json" \
-d "{\"body\": \"$COMMENT_BODY\"}" \
"https://api.github.com/repos/${{ github.repository }}/issues/comments/${EXISTING_COMMENT_ID}"
else
echo "Posting new comment to PR..."
curl -s -X POST -H "Authorization: token ${GITHUB_TOKEN}" -H "Content-Type: application/json" \
-d "{\"body\": \"$COMMENT_BODY\"}" \
"https://api.github.com/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments"
fi
- name: Check if Action Should Fail
run: |
echo "π Checking if the workflow should fail based on security alerts..."
echo "UNRESOLVED_COUNT"
echo $UNRESOLVED_COUNT
echo "DISMISSED_COUNT"
echo $DISMISSED_COUNT
# If there are unresolved alerts
if [[ "$UNRESOLVED_COUNT" -gt 0 ]]; then
echo "β ERROR: $UNRESOLVED_COUNT unresolved security alerts found!"
echo "β οΈ These alerts must be resolved before merging."
exit 1 # Fail the workflow
fi
# If there are dismissed alerts without comments
if [[ "$DISMISSED_COUNT" -gt 0 ]]; then
echo "β ERROR: $DISMISSED_COUNT security alerts were dismissed without comments!"
echo "β οΈ Please provide a dismissal reason for these alerts."
exit 1 # Fail the workflow
fi
echo "β
No security issues found. The workflow will pass successfully."