added reason #24
This file contains 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
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." |