Skip to content

Commit 80b3835

Browse files
committed
CI/CD Improvements
- Automated security scanning (Trivy, Snyk) - Automated testing of container startup - Multi-stage builds to reduce image size - Cache layer optimization
1 parent ddd7bc5 commit 80b3835

3 files changed

Lines changed: 344 additions & 27 deletions

File tree

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
name: Build and Publish Docker Image
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- "v*"
9+
pull_request:
10+
branches:
11+
- main
12+
13+
env:
14+
REGISTRY: codeberg.org
15+
IMAGE_NAME: ${{ github.repository }}
16+
17+
jobs:
18+
# ===========================================================================
19+
# Security Scanning Job
20+
# ===========================================================================
21+
security-scan:
22+
name: Security Scan
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v4
28+
29+
- name: Install Trivy
30+
run: |
31+
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
32+
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
33+
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
34+
sudo apt-get update
35+
sudo apt-get install trivy -y
36+
37+
- name: Run Trivy vulnerability scanner (filesystem)
38+
run: trivy fs --severity CRITICAL,HIGH,MEDIUM --exit-code 0 .
39+
40+
# ===========================================================================
41+
# Build and Test Job
42+
# ===========================================================================
43+
build-and-test:
44+
name: Build and Test
45+
runs-on: ubuntu-latest
46+
needs: security-scan
47+
48+
steps:
49+
- name: Checkout repository
50+
uses: actions/checkout@v4
51+
52+
- name: Set up Docker Buildx
53+
uses: docker/setup-buildx-action@v3
54+
55+
# Build image for testing
56+
- name: Build Docker image for testing
57+
run: |
58+
docker build -t hytale-server:test .
59+
60+
# Container startup test
61+
- name: Test container startup
62+
run: |
63+
echo "Starting container startup test..."
64+
65+
# Run container with dummy tokens (will fail auth but tests container mechanics)
66+
docker run -d --name test-container \
67+
-e HYTALE_SERVER_SESSION_TOKEN=test-session \
68+
-e HYTALE_SERVER_IDENTITY_TOKEN=test-identity \
69+
-e HYTALE_SERVER_OWNER_UUID=test-uuid \
70+
hytale-server:test
71+
72+
# Wait for container to initialize
73+
sleep 10
74+
75+
# Check if container is running
76+
if docker ps | grep -q test-container; then
77+
echo "✓ Container started successfully"
78+
else
79+
echo "✗ Container failed to start"
80+
docker logs test-container
81+
exit 1
82+
fi
83+
84+
# Verify Java is available in container
85+
docker exec test-container java -version
86+
echo "✓ Java runtime verified"
87+
88+
# Verify entrypoint script exists and is executable
89+
docker exec test-container test -x /app/entrypoint.sh
90+
echo "✓ Entrypoint script is executable"
91+
92+
# Verify downloader binary exists
93+
docker exec test-container test -x /app/hytale-downloader-linux-amd64
94+
echo "✓ Hytale downloader binary present"
95+
96+
# Cleanup
97+
docker stop test-container
98+
docker rm test-container
99+
echo "✓ All startup tests passed"
100+
101+
# Install Trivy for image scanning
102+
- name: Install Trivy
103+
run: |
104+
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
105+
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
106+
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
107+
sudo apt-get update
108+
sudo apt-get install trivy -y
109+
110+
# Scan built image for vulnerabilities
111+
- name: Run Trivy vulnerability scanner (image)
112+
run: trivy image --severity CRITICAL,HIGH,MEDIUM --exit-code 0 hytale-server:test
113+
114+
# ===========================================================================
115+
# Push Job (only on main branch or tags)
116+
# ===========================================================================
117+
push:
118+
name: Push Image
119+
runs-on: ubuntu-latest
120+
needs: build-and-test
121+
if: github.event_name != 'pull_request'
122+
123+
steps:
124+
- name: Checkout repository
125+
uses: actions/checkout@v4
126+
127+
- name: Set up Docker Buildx
128+
uses: docker/setup-buildx-action@v3
129+
130+
- name: Log in to Container Registry
131+
uses: docker/login-action@v3
132+
with:
133+
registry: ${{ env.REGISTRY }}
134+
username: ${{ secrets.REGISTRY_USERNAME }}
135+
password: ${{ secrets.REGISTRY_TOKEN }}
136+
137+
- name: Extract metadata (tags, labels)
138+
id: meta
139+
uses: docker/metadata-action@v5
140+
with:
141+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
142+
tags: |
143+
type=ref,event=branch
144+
type=semver,pattern={{version}}
145+
type=semver,pattern={{major}}.{{minor}}
146+
type=semver,pattern={{major}}
147+
type=sha
148+
149+
- name: Build and push Docker image
150+
uses: docker/build-push-action@v6
151+
with:
152+
context: .
153+
push: true
154+
tags: ${{ steps.meta.outputs.tags }}
155+
labels: ${{ steps.meta.outputs.labels }}
156+
platforms: linux/amd64

.github/workflows/docker-publish.yml

Lines changed: 147 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,46 @@ env:
1515
IMAGE_NAME: ${{ github.repository }}
1616

1717
jobs:
18-
build-and-push:
18+
# ===========================================================================
19+
# Security Scanning Job
20+
# ===========================================================================
21+
security-scan:
22+
name: Security Scan
23+
runs-on: ubuntu-latest
24+
permissions:
25+
contents: read
26+
security-events: write
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
32+
- name: Run Trivy vulnerability scanner (filesystem)
33+
uses: aquasecurity/trivy-action@master
34+
with:
35+
scan-type: "fs"
36+
scan-ref: "."
37+
format: "sarif"
38+
output: "trivy-fs-results.sarif"
39+
severity: "CRITICAL,HIGH,MEDIUM"
40+
41+
- name: Upload Trivy filesystem scan results
42+
uses: github/codeql-action/upload-sarif@v3
43+
if: always()
44+
with:
45+
sarif_file: "trivy-fs-results.sarif"
46+
category: "trivy-filesystem"
47+
48+
# ===========================================================================
49+
# Build and Test Job
50+
# ===========================================================================
51+
build-and-test:
52+
name: Build and Test
1953
runs-on: ubuntu-latest
2054
permissions:
2155
contents: read
2256
packages: write
57+
security-events: write
2358

2459
steps:
2560
- name: Checkout repository
@@ -28,14 +63,6 @@ jobs:
2863
- name: Set up Docker Buildx
2964
uses: docker/setup-buildx-action@v3
3065

31-
- name: Log in to Container Registry
32-
if: github.event_name != 'pull_request'
33-
uses: docker/login-action@v3
34-
with:
35-
registry: ${{ env.REGISTRY }}
36-
username: ${{ github.actor }}
37-
password: ${{ secrets.GITHUB_TOKEN }}
38-
3966
- name: Extract metadata (tags, labels)
4067
id: meta
4168
uses: docker/metadata-action@v5
@@ -48,12 +75,122 @@ jobs:
4875
type=semver,pattern={{major}}
4976
type=sha
5077
78+
# Build image for testing (not pushed yet)
79+
- name: Build Docker image for testing
80+
uses: docker/build-push-action@v6
81+
with:
82+
context: .
83+
load: true
84+
tags: ${{ env.IMAGE_NAME }}:test
85+
cache-from: type=gha
86+
cache-to: type=gha,mode=max
87+
88+
# Container startup test
89+
- name: Test container startup
90+
run: |
91+
echo "Starting container startup test..."
92+
93+
# Run container with dummy tokens (will fail auth but tests container mechanics)
94+
docker run -d --name test-container \
95+
-e HYTALE_SERVER_SESSION_TOKEN=test-session \
96+
-e HYTALE_SERVER_IDENTITY_TOKEN=test-identity \
97+
-e HYTALE_SERVER_OWNER_UUID=test-uuid \
98+
${{ env.IMAGE_NAME }}:test
99+
100+
# Wait for container to initialize
101+
sleep 10
102+
103+
# Check if container is running
104+
if docker ps | grep -q test-container; then
105+
echo "✓ Container started successfully"
106+
else
107+
echo "✗ Container failed to start"
108+
docker logs test-container
109+
exit 1
110+
fi
111+
112+
# Verify Java is available in container
113+
docker exec test-container java -version
114+
echo "✓ Java runtime verified"
115+
116+
# Verify entrypoint script exists and is executable
117+
docker exec test-container test -x /app/entrypoint.sh
118+
echo "✓ Entrypoint script is executable"
119+
120+
# Verify downloader binary exists
121+
docker exec test-container test -x /app/hytale-downloader-linux-amd64
122+
echo "✓ Hytale downloader binary present"
123+
124+
# Cleanup
125+
docker stop test-container
126+
docker rm test-container
127+
echo "✓ All startup tests passed"
128+
129+
# Scan built image for vulnerabilities
130+
- name: Run Trivy vulnerability scanner (image)
131+
uses: aquasecurity/trivy-action@master
132+
with:
133+
image-ref: ${{ env.IMAGE_NAME }}:test
134+
format: "sarif"
135+
output: "trivy-image-results.sarif"
136+
severity: "CRITICAL,HIGH,MEDIUM"
137+
138+
- name: Upload Trivy image scan results
139+
uses: github/codeql-action/upload-sarif@v3
140+
if: always()
141+
with:
142+
sarif_file: "trivy-image-results.sarif"
143+
category: "trivy-image"
144+
145+
# Log in and push only on main branch or tags
146+
- name: Log in to Container Registry
147+
if: github.event_name != 'pull_request'
148+
uses: docker/login-action@v3
149+
with:
150+
registry: ${{ env.REGISTRY }}
151+
username: ${{ github.actor }}
152+
password: ${{ secrets.GITHUB_TOKEN }}
153+
51154
- name: Build and push Docker image
155+
if: github.event_name != 'pull_request'
52156
uses: docker/build-push-action@v6
53157
with:
54158
context: .
55-
push: ${{ github.event_name != 'pull_request' }}
159+
push: true
56160
tags: ${{ steps.meta.outputs.tags }}
57161
labels: ${{ steps.meta.outputs.labels }}
58162
cache-from: type=gha
59163
cache-to: type=gha,mode=max
164+
platforms: linux/amd64
165+
166+
# ===========================================================================
167+
# Snyk Security Scan (Optional - requires SNYK_TOKEN secret)
168+
# ===========================================================================
169+
snyk-scan:
170+
name: Snyk Security Scan
171+
runs-on: ubuntu-latest
172+
if: github.event_name != 'pull_request'
173+
permissions:
174+
contents: read
175+
security-events: write
176+
continue-on-error: true
177+
178+
steps:
179+
- name: Checkout repository
180+
uses: actions/checkout@v4
181+
182+
- name: Run Snyk to check Docker image for vulnerabilities
183+
uses: snyk/actions/docker@master
184+
continue-on-error: true
185+
env:
186+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
187+
with:
188+
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main
189+
args: --file=Dockerfile --severity-threshold=high
190+
191+
- name: Upload Snyk results to GitHub Security
192+
uses: github/codeql-action/upload-sarif@v3
193+
if: always()
194+
with:
195+
sarif_file: snyk.sarif
196+
category: "snyk"

0 commit comments

Comments
 (0)