Skip to content

Commit 946d2e8

Browse files
committed
fix: added docker security scan and publish for github actions CI
1 parent 15ab532 commit 946d2e8

File tree

2 files changed

+194
-0
lines changed

2 files changed

+194
-0
lines changed

.github/workflows/docker-publish.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Build and Push Docker Image
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
tags: [ 'v*' ]
7+
pull_request:
8+
branches: [ main, master ]
9+
workflow_dispatch: # Allow manual triggering
10+
11+
jobs:
12+
build-and-push:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
packages: write
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Docker Buildx
23+
uses: docker/setup-buildx-action@v3
24+
25+
- name: Login to GitHub Container Registry
26+
uses: docker/login-action@v3
27+
with:
28+
registry: ghcr.io
29+
username: ${{ github.repository_owner }}
30+
password: ${{ secrets.GITHUB_TOKEN }}
31+
32+
- name: Extract metadata for Docker
33+
id: meta
34+
uses: docker/metadata-action@v5
35+
with:
36+
images: ghcr.io/${{ github.repository }}
37+
tags: |
38+
type=ref,event=branch
39+
type=ref,event=pr
40+
type=semver,pattern={{version}}
41+
type=semver,pattern={{major}}.{{minor}}
42+
type=sha,format=short
43+
type=raw,value=latest,enable={{is_default_branch}}
44+
45+
- name: Build and push Docker image
46+
uses: docker/build-push-action@v5
47+
with:
48+
context: .
49+
file: debian.dockerfile
50+
push: ${{ github.event_name != 'pull_request' }}
51+
tags: ${{ steps.meta.outputs.tags }}
52+
labels: ${{ steps.meta.outputs.labels }}
53+
cache-from: type=gha
54+
cache-to: type=gha,mode=max
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
name: Docker Security Scan
2+
3+
on:
4+
pull_request:
5+
branches: [ main, master ]
6+
7+
jobs:
8+
security-scan:
9+
name: Docker Build and Security Scan
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: read
13+
pull-requests: write
14+
security-events: write
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Docker Buildx
21+
uses: docker/setup-buildx-action@v3
22+
23+
- name: Build Docker image
24+
uses: docker/build-push-action@v5
25+
with:
26+
context: .
27+
file: debian.dockerfile
28+
push: false
29+
load: true
30+
tags: test-image:${{ github.sha }}
31+
cache-from: type=gha
32+
cache-to: type=gha,mode=max
33+
34+
- name: Get image size
35+
id: image-size
36+
run: |
37+
SIZE=$(docker image inspect test-image:${{ github.sha }} --format='{{.Size}}')
38+
SIZE_MB=$(echo "scale=2; $SIZE/1024/1024" | bc)
39+
echo "size=$SIZE_MB MB" >> $GITHUB_OUTPUT
40+
41+
- name: Check image health
42+
id: image-health
43+
run: |
44+
if docker run --rm --entrypoint sh test-image:${{ github.sha }} -c "exit 0"; then
45+
echo "status=✅ Image is healthy" >> $GITHUB_OUTPUT
46+
else
47+
echo "status=❌ Image health check failed" >> $GITHUB_OUTPUT
48+
fi
49+
50+
- name: Run Trivy vulnerability scanner
51+
id: trivy-scan
52+
uses: aquasecurity/trivy-action@master
53+
with:
54+
image-ref: test-image:${{ github.sha }}
55+
format: 'table'
56+
output: 'trivy-results.txt'
57+
severity: 'CRITICAL,HIGH'
58+
59+
- name: Generate Trivy SARIF output
60+
uses: aquasecurity/trivy-action@master
61+
with:
62+
image-ref: test-image:${{ github.sha }}
63+
format: 'sarif'
64+
output: 'trivy-results.sarif'
65+
severity: 'CRITICAL,HIGH,MEDIUM'
66+
67+
- name: Upload Trivy scan results to GitHub Security tab
68+
uses: github/codeql-action/upload-sarif@v2
69+
if: always()
70+
with:
71+
sarif_file: 'trivy-results.sarif'
72+
73+
- name: Count vulnerabilities
74+
id: count-vulns
75+
run: |
76+
CRITICAL=$(grep -c "CRITICAL" trivy-results.txt || echo 0)
77+
HIGH=$(grep -c "HIGH" trivy-results.txt || echo 0)
78+
MEDIUM=$(grep -c "MEDIUM" trivy-results.txt || echo 0)
79+
echo "critical=$CRITICAL" >> $GITHUB_OUTPUT
80+
echo "high=$HIGH" >> $GITHUB_OUTPUT
81+
echo "medium=$MEDIUM" >> $GITHUB_OUTPUT
82+
83+
- name: Create PR comment
84+
uses: actions/github-script@v6
85+
with:
86+
github-token: ${{ secrets.GITHUB_TOKEN }}
87+
script: |
88+
const fs = require('fs');
89+
let trivyOutput = '';
90+
try {
91+
const trivyFile = fs.readFileSync('trivy-results.txt', 'utf8');
92+
trivyOutput = '```\n' + trivyFile.substring(0, 10000) + '\n```';
93+
if (trivyFile.length > 10000) {
94+
trivyOutput += '\n... (output truncated)';
95+
}
96+
} catch (error) {
97+
trivyOutput = 'Error reading vulnerability scan results.';
98+
}
99+
100+
const imageSize = process.env.IMAGE_SIZE;
101+
const imageHealth = process.env.IMAGE_HEALTH;
102+
const criticalCount = process.env.CRITICAL_COUNT;
103+
const highCount = process.env.HIGH_COUNT;
104+
const mediumCount = process.env.MEDIUM_COUNT;
105+
106+
const securityStatus = criticalCount > 0 || highCount > 0
107+
? '❌ Security issues found'
108+
: '✅ No critical/high vulnerabilities';
109+
110+
const body = `## Docker Image Analysis
111+
112+
### Image Status
113+
- ${imageHealth}
114+
- Image Size: ${imageSize}
115+
- Security Status: ${securityStatus}
116+
117+
### Vulnerability Summary
118+
- Critical: ${criticalCount}
119+
- High: ${highCount}
120+
- Medium: ${mediumCount}
121+
122+
<details>
123+
<summary>View Full Security Scan Results</summary>
124+
125+
${trivyOutput}
126+
</details>
127+
`;
128+
129+
github.rest.issues.createComment({
130+
issue_number: context.issue.number,
131+
owner: context.repo.owner,
132+
repo: context.repo.repo,
133+
body: body
134+
});
135+
env:
136+
IMAGE_SIZE: ${{ steps.image-size.outputs.size }}
137+
IMAGE_HEALTH: ${{ steps.image-health.outputs.status }}
138+
CRITICAL_COUNT: ${{ steps.count-vulns.outputs.critical }}
139+
HIGH_COUNT: ${{ steps.count-vulns.outputs.high }}
140+
MEDIUM_COUNT: ${{ steps.count-vulns.outputs.medium }}

0 commit comments

Comments
 (0)