Skip to content

Instantly share code, notes, and snippets.

@jumploops
Last active August 13, 2024 17:42
Show Gist options
  • Save jumploops/f781a72312782546c0f6a5c00111b594 to your computer and use it in GitHub Desktop.
Save jumploops/f781a72312782546c0f6a5c00111b594 to your computer and use it in GitHub Desktop.
Vulnerability Scan Github Action using Magic Loops
name: Vulnerability Scan
on:
pull_request:
types: [opened, synchronize]
jobs:
vulnerability_scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Fetch all history for all tags and branches
run: git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/heads/*
- name: Get the PR Diff for specific file types
run: git diff origin/${{ github.base_ref }} -- '*.js' '*.ts' '*.jsx' '*.tsx' > pr.diff
- name: Send diff to the API
id: send_diff
run: |
diffContent=$(jq -Rs . < pr.diff)
response=$(curl -s -X POST \
-H "Content-Type: application/json" \
-d "{\"gitDiff\": $diffContent}" \
"https://magicloops.dev/api/loop/run/YOUR_LOOP_ID")
echo "response=$(echo "$response" | base64 -w 0)" >> $GITHUB_OUTPUT
- name: Extract severity and description from response
id: extract_severity_description
run: |
response=$(echo "${{ steps.send_diff.outputs.response }}" | base64 --decode)
severity=$(echo "$response" | jq -r '.loopOutput.severity')
description=$(echo "$response" | jq -r '.loopOutput.description')
echo "Severity: $severity"
echo "Description: $description" # This will not log the actual description, to keep it secure
# Escape newlines and special characters for GitHub Actions set-output
description="${description//'%'/'%25'}"
description="${description//$'\n'/'%0A'}"
description="${description//$'\r'/'%0D'}"
description="${description//\`/\\\`}"
echo "severity=$severity" >> $GITHUB_OUTPUT
echo "description<<EOF" >> $GITHUB_OUTPUT
echo "$description" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Delete previous comments and create new PR comment
run: |
description=$(echo "${{ steps.extract_severity_description.outputs.description }}" | sed 's/%0A/\n/g')
severity="${{ steps.extract_severity_description.outputs.severity }}"
# Set emoji based on severity
if [ "$severity" = "low" ]; then
severity_emoji="✅"
elif [ "$severity" = "medium" ]; then
severity_emoji="⚠️"
elif [ "$severity" = "high" ]; then
severity_emoji="🛑"
else
severity_emoji="ℹ️"
fi
comment_body=$(cat << EOF | jq -R -s '{"body": .}'
#### $severity_emoji Vulnerability Scan Results $severity_emoji
**Severity**: $severity
**Description**:
$description
EOF
)
pr_number=$(jq -r '.number' "$GITHUB_EVENT_PATH")
# Get all comments on the PR
comments=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/issues/$pr_number/comments")
# Find and delete all comments containing "Vulnerability Scan Results"
echo "$comments" | jq -r '.[] | select(.body | contains("Vulnerability Scan Results")) | .id' | while read comment_id; do
if [ ! -z "$comment_id" ]; then
curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-X DELETE \
"https://api.github.com/repos/${{ github.repository }}/issues/comments/$comment_id"
fi
done
# Create new comment
curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/json" \
-X POST \
-d "$comment_body" \
"https://api.github.com/repos/${{ github.repository }}/issues/$pr_number/comments"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Fail job if severity is high
if: steps.extract_severity_description.outputs.severity == 'high'
run: |
echo "::error::Vulnerability severity level is high. Scan failed."
exit 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment