Skip to content

Commit 625c91b

Browse files
authored
Merge pull request ToolJet#15561 from ToolJet/gyrpe-automated-slack-notify-develop
2 parents 3821ae5 + 53498e9 commit 625c91b

1 file changed

Lines changed: 194 additions & 0 deletions

File tree

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
name: Grype - Docker Image Vulnerability Scan
2+
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: "30 6 * * 1"
7+
8+
jobs:
9+
PeriodicVulnerability-CheckOn-docker-image-lts:
10+
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
17+
- name: Free up disk space
18+
run: |
19+
echo "=== Disk space before cleanup ==="
20+
df -h
21+
sudo rm -rf /usr/share/dotnet
22+
sudo rm -rf /opt/ghc
23+
sudo rm -rf /usr/local/share/boost
24+
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
25+
sudo docker system prune -af
26+
sudo apt-get clean
27+
echo "=== Disk space after cleanup ==="
28+
df -h
29+
30+
- name: Pull ToolJet LTS Docker image
31+
run: docker pull tooljet/tooljet:ee-lts-latest
32+
33+
- name: Grype Scan - Table Output (visible in logs)
34+
uses: anchore/scan-action@v7
35+
with:
36+
image: 'tooljet/tooljet:ee-lts-latest'
37+
fail-build: false
38+
severity-cutoff: high
39+
output-format: table
40+
only-fixed: true
41+
42+
- name: Grype Scan - JSON Output (for report)
43+
uses: anchore/scan-action@v7
44+
with:
45+
image: 'tooljet/tooljet:ee-lts-latest'
46+
fail-build: false
47+
severity-cutoff: high
48+
output-format: json
49+
output-file: grype-lts-results.json
50+
only-fixed: true
51+
52+
- name: Parse Results
53+
id: parse-grype
54+
run: |
55+
if [ -f grype-lts-results.json ]; then
56+
critical=$(jq '[.matches[]? | select(.vulnerability.severity=="Critical")] | length' grype-lts-results.json)
57+
high=$(jq '[.matches[]? | select(.vulnerability.severity=="High")] | length' grype-lts-results.json)
58+
else
59+
critical=0
60+
high=0
61+
fi
62+
total=$((critical + high))
63+
echo "critical=$critical" >> $GITHUB_OUTPUT
64+
echo "high=$high" >> $GITHUB_OUTPUT
65+
echo "total=$total" >> $GITHUB_OUTPUT
66+
echo "=== Vulnerability Summary ==="
67+
echo "Critical: $critical"
68+
echo "High: $high"
69+
echo "Total: $total"
70+
71+
- name: Upload JSON Report as Artifact
72+
if: always()
73+
uses: actions/upload-artifact@v4
74+
with:
75+
name: grype-lts-scan-report
76+
path: grype-lts-results.json
77+
retention-days: 7
78+
if-no-files-found: warn
79+
80+
- name: Determine notification color
81+
id: determine-color
82+
run: |
83+
critical=${{ steps.parse-grype.outputs.critical }}
84+
high=${{ steps.parse-grype.outputs.high }}
85+
86+
if [ "$critical" -gt 0 ]; then
87+
echo "color=#FF0000" >> $GITHUB_OUTPUT
88+
elif [ "$high" -gt 0 ]; then
89+
echo "color=#FFA500" >> $GITHUB_OUTPUT
90+
else
91+
echo "color=#36A64F" >> $GITHUB_OUTPUT
92+
fi
93+
94+
- name: Send Slack Notification
95+
run: |
96+
payload=$(cat <<EOF
97+
{
98+
"attachments": [
99+
{
100+
"color": "${{ steps.determine-color.outputs.color }}",
101+
"blocks": [
102+
{
103+
"type": "header",
104+
"text": {
105+
"type": "plain_text",
106+
"text": "🐳 Docker Image Vulnerability Scan Report",
107+
"emoji": true
108+
}
109+
},
110+
{
111+
"type": "section",
112+
"fields": [
113+
{
114+
"type": "mrkdwn",
115+
"text": "*Repository:*\n${{ github.repository }}"
116+
},
117+
{
118+
"type": "mrkdwn",
119+
"text": "*Image:*\ntooljet/tooljet:ee-lts-latest"
120+
},
121+
{
122+
"type": "mrkdwn",
123+
"text": "*Scanner:*\nGrype"
124+
},
125+
{
126+
"type": "mrkdwn",
127+
"text": "*Scan Time:*\n$(date -u +"%Y-%m-%d %H:%M UTC")"
128+
}
129+
]
130+
},
131+
{
132+
"type": "divider"
133+
},
134+
{
135+
"type": "section",
136+
"text": {
137+
"type": "mrkdwn",
138+
"text": "*Docker Image Vulnerabilities (fixable only):*"
139+
}
140+
},
141+
{
142+
"type": "section",
143+
"fields": [
144+
{
145+
"type": "mrkdwn",
146+
"text": "🔴 *Critical:*\n${{ steps.parse-grype.outputs.critical }}"
147+
},
148+
{
149+
"type": "mrkdwn",
150+
"text": "🟠 *High:*\n${{ steps.parse-grype.outputs.high }}"
151+
},
152+
{
153+
"type": "mrkdwn",
154+
"text": "📊 *Total:*\n${{ steps.parse-grype.outputs.total }}"
155+
}
156+
]
157+
},
158+
{
159+
"type": "divider"
160+
},
161+
{
162+
"type": "actions",
163+
"elements": [
164+
{
165+
"type": "button",
166+
"text": {
167+
"type": "plain_text",
168+
"text": "📥 Download Full Report",
169+
"emoji": true
170+
},
171+
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
172+
"style": "primary"
173+
}
174+
]
175+
}
176+
]
177+
}
178+
]
179+
}
180+
EOF
181+
)
182+
183+
response=$(curl -s -w "%{http_code}" -X POST \
184+
-H 'Content-type: application/json' \
185+
--data "$payload" \
186+
"${{ secrets.SLACK_WEBHOOK_URL_VUR }}")
187+
188+
http_code="${response: -3}"
189+
if [ "$http_code" != "200" ]; then
190+
echo "Slack notification failed with HTTP $http_code"
191+
exit 1
192+
fi
193+
194+
echo "Slack notification sent successfully"

0 commit comments

Comments
 (0)