1
1
name : Docker Build & Deploy
2
-
3
2
on :
4
3
push :
5
4
branches :
11
10
- main
12
11
workflow_dispatch :
13
12
schedule :
14
- - cron : ' 0 2 * * 0' # Weekly cleanup on Sundays
15
-
13
+ - cron : 0 2 * * 0 # Weekly cleanup on Sundays
16
14
concurrency :
17
15
group : ${{ github.workflow }}-${{ github.ref }}
18
16
cancel-in-progress : ${{ github.event_name == 'pull_request' }}
19
-
20
17
env :
21
18
REGISTRY : ghcr.io
22
19
IMAGE_NAME : ${{ github.repository }}
23
20
DOCKER_BUILD_SUMMARY : true
24
21
DOCKER_BUILD_CHECKS_ANNOTATIONS : true
25
-
26
22
jobs :
27
23
validate :
28
24
if : github.event_name == 'pull_request'
32
28
steps :
33
29
- name : Set up Docker Buildx
34
30
uses : docker/setup-buildx-action@v3
35
-
36
31
- name : Build for validation (Git context)
37
32
uses : docker/build-push-action@v6.18.0
38
33
timeout-minutes : 15
@@ -49,14 +44,12 @@ jobs:
49
44
annotations : |
50
45
org.opencontainers.image.title=Tux Discord Bot
51
46
org.opencontainers.image.description=All Things Linux Discord Bot
52
-
53
47
- name : Test container starts
54
48
run : |
55
49
docker run --rm --name tux-test \
56
50
--entrypoint python \
57
51
tux:pr-${{ github.event.number }} \
58
52
-c "import tux; import sqlite3; import asyncio; print('🔍 Testing bot imports...'); print('✅ Main bot module imports successfully'); print('✅ SQLite available'); print('✅ Asyncio available'); conn = sqlite3.connect(':memory:'); conn.close(); print('✅ Database connectivity working'); print('🎉 All smoke tests passed!')"
59
-
60
53
build :
61
54
if : github.event_name != 'pull_request'
62
55
runs-on : ubuntu-latest
@@ -74,25 +67,21 @@ jobs:
74
67
uses : actions/checkout@v4
75
68
with :
76
69
fetch-depth : 0
77
-
78
70
- name : Set up QEMU
79
71
uses : docker/setup-qemu-action@v3
80
72
with :
81
73
platforms : linux/amd64,linux/arm64
82
-
83
74
- name : Set up Docker Buildx
84
75
uses : docker/setup-buildx-action@v3
85
76
with :
86
77
driver-opts : |
87
78
image=moby/buildkit:buildx-stable-1
88
-
89
79
- name : Log in to Container Registry
90
80
uses : docker/login-action@v3
91
81
with :
92
82
registry : ${{ env.REGISTRY }}
93
83
username : ${{ github.actor }}
94
84
password : ${{ secrets.GITHUB_TOKEN }}
95
-
96
85
- name : Extract metadata
97
86
id : meta
98
87
uses : docker/metadata-action@v5
@@ -111,7 +100,6 @@ jobs:
111
100
org.opencontainers.image.source=https://github.com/${{ github.repository }}
112
101
org.opencontainers.image.revision=${{ github.sha }}
113
102
org.opencontainers.image.licenses=MIT
114
-
115
103
- name : Build and push
116
104
id : build
117
105
uses : docker/build-push-action@v6.18.0
@@ -135,14 +123,12 @@ jobs:
135
123
annotations : ${{ steps.meta.outputs.annotations }}
136
124
build-args : |
137
125
BUILDKIT_INLINE_CACHE=1
138
-
139
126
- name : Test pushed image
140
127
run : |
141
128
docker run --rm --name tux-prod-test \
142
129
--entrypoint python \
143
130
"$(echo '${{ steps.meta.outputs.tags }}' | head -1)" \
144
131
-c "import tux; import sqlite3; import asyncio; print('🔍 Testing production image...'); print('✅ Bot imports successfully'); print('✅ Dependencies available'); conn = sqlite3.connect(':memory:'); conn.close(); print('✅ Database connectivity working'); print('🎉 Production image verified!')"
145
-
146
132
security :
147
133
if : github.event_name != 'pull_request'
148
134
needs : build
@@ -154,32 +140,28 @@ jobs:
154
140
uses : actions/checkout@v4
155
141
with :
156
142
fetch-depth : 0
157
-
158
143
- name : Get first image tag
159
144
id : first_tag
160
- run : echo "image=$(echo '${{ needs.build.outputs.image }}' | head -1)" >> "$GITHUB_OUTPUT"
161
-
145
+ run : echo "image=$(echo '${{ needs.build.outputs.image }}' | head -1)" >>
146
+ " $GITHUB_OUTPUT "
162
147
- name : Cache Trivy
163
148
uses : actions/cache@v4
164
149
with :
165
150
path : ~/.cache/trivy
166
151
key : cache-trivy-${{ github.run_id }}
167
152
restore-keys : |
168
153
cache-trivy-
169
-
170
154
- name : Run Trivy vulnerability scanner
171
155
uses : aquasecurity/trivy-action@master
172
156
with :
173
157
image-ref : ${{ steps.first_tag.outputs.image }}
174
158
format : sarif
175
159
output : trivy-results.sarif
176
160
severity : CRITICAL,HIGH
177
-
178
161
- name : Upload Trivy scan results
179
162
uses : github/codeql-action/upload-sarif@v3
180
163
with :
181
164
sarif_file : trivy-results.sarif
182
-
183
165
- name : Fail on critical vulnerabilities (excluding known issues)
184
166
uses : aquasecurity/trivy-action@master
185
167
with :
@@ -189,9 +171,9 @@ jobs:
189
171
exit-code : ' 1'
190
172
ignore-unfixed : true
191
173
trivyignores : .trivyignore
192
-
193
174
cleanup :
194
- if : github.event_name != 'pull_request' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
175
+ if : github.event_name != 'pull_request' && (github.event_name == 'schedule' ||
176
+ github.event_name == 'workflow_dispatch')
195
177
runs-on : ubuntu-latest
196
178
permissions :
197
179
packages : write
0 commit comments