Skip to content

Commit ac435f8

Browse files
authored
Update docker-image.yml
Replace hadolint and dockle with manual install due to IBM repo limitation
1 parent ecf0ae5 commit ac435f8

File tree

1 file changed

+52
-30
lines changed

1 file changed

+52
-30
lines changed

.github/workflows/docker-image.yml

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,17 @@
55
# This workflow:
66
# • Builds and tags the container image (`latest` + timestamp)
77
# • Re-uses a BuildKit layer cache for faster rebuilds
8-
# • Lints the Dockerfile with Hadolint
9-
# • Lints the finished image with Dockle (CIS best-practices)
8+
# • Lints the Dockerfile with Hadolint (CLI) → SARIF
9+
# • Lints the finished image with Dockle (CLI) → SARIF
1010
# • Generates an SPDX SBOM with Syft
1111
# • Scans the image for CRITICAL/HIGH CVEs with Trivy
12-
# • Uploads both Dockle and Trivy results as SARIF files
12+
# • Uploads Hadolint, Dockle and Trivy results as SARIF files
1313
# • Pushes the image to GitHub Container Registry (GHCR)
14-
# • Signs and attests the image with Cosign **key-less (OIDC)** –
15-
# no private keys or secrets required
14+
# • Signs + attests the image with Cosign **key-less (OIDC)**
1615
#
1716
# Triggers:
1817
# • Every push / PR to `main`
19-
# • Weekly scheduled run (Tue 18:17 UTC) to catch newly-disclosed CVEs
18+
# • Weekly scheduled run (Tue 18:17 UTC) to catch new CVEs
2019
# ---------------------------------------------------------------
2120

2221
name: Secure Docker Build
@@ -31,10 +30,6 @@ on:
3130

3231
# -----------------------------------------------------------------
3332
# GitHub permission scopes for this job
34-
# - contents: read → checkout source
35-
# - packages: write → push to GHCR with the builtin GITHUB_TOKEN
36-
# - security-events: write → upload SARIF to “Code-scanning alerts”
37-
# - actions: read → required by upload-sarif in private repos
3833
# -----------------------------------------------------------------
3934
permissions:
4035
contents: read
@@ -48,7 +43,7 @@ jobs:
4843

4944
env:
5045
IMAGE_NAME: ghcr.io/${{ github.repository }}
51-
CACHE_DIR: /tmp/.buildx-cache # local BuildKit layer cache
46+
CACHE_DIR: /tmp/.buildx-cache # BuildKit layer cache dir
5247

5348
steps:
5449
# -------------------------------------------------------------
@@ -58,20 +53,32 @@ jobs:
5853
uses: actions/checkout@v4
5954

6055
# -------------------------------------------------------------
61-
# 1️⃣ Lint Dockerfile (Hadolint)
56+
# 1️⃣ Dockerfile lint (Hadolint CLI → SARIF)
6257
# -------------------------------------------------------------
6358
- name: 🔍 Dockerfile lint (Hadolint)
64-
uses: hadolint/[email protected]
59+
id: hadolint
60+
continue-on-error: true # capture result; fail later
61+
run: |
62+
set -e
63+
curl -sSL https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64 -o /usr/local/bin/hadolint
64+
chmod +x /usr/local/bin/hadolint
65+
# Run lint; exit code >0 on rule violations
66+
hadolint -f sarif Containerfile.lite > hadolint-results.sarif
67+
echo "HADOLINT_EXIT=$?" >> "$GITHUB_ENV"
68+
69+
- name: ☁️ Upload Hadolint SARIF
70+
if: always()
71+
uses: github/codeql-action/upload-sarif@v3
6572
with:
66-
dockerfile: Containerfile.lite
73+
sarif_file: hadolint-results.sarif
6774

6875
# -------------------------------------------------------------
6976
# 2️⃣ Set up Buildx & restore cache
7077
# -------------------------------------------------------------
7178
- name: 🛠️ Set up Docker Buildx
7279
uses: docker/setup-buildx-action@v3
7380

74-
- name: 🔄 Restore BuildKit layer cache
81+
- name: 🔄 Restore BuildKit layer cache
7582
uses: actions/cache@v4
7683
with:
7784
path: ${{ env.CACHE_DIR }}
@@ -94,17 +101,24 @@ jobs:
94101
--load
95102
96103
# -------------------------------------------------------------
97-
# 4️⃣ Lint image with Dockle
104+
# 4️⃣ Image lint (Dockle CLI → SARIF)
98105
# -------------------------------------------------------------
99106
- name: 🔍 Image lint (Dockle)
100-
uses: erzz/dockle-action@v2
101-
with:
102-
image: ${{ env.IMAGE_NAME }}:latest
103-
format: sarif
104-
output: dockle-results.sarif
105-
exit-code: 1 # fail on WARN+ (remove to make non-blocking)
106-
107-
- name: ☁️ Upload Dockle SARIF
107+
id: dockle
108+
continue-on-error: true
109+
env:
110+
DOCKLE_VERSION: 0.4.15
111+
run: |
112+
set -e
113+
curl -sSL "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.tar.gz" \
114+
| tar -xz -C /usr/local/bin dockle
115+
dockle --exit-code 1 \
116+
--format sarif \
117+
--output dockle-results.sarif \
118+
$IMAGE_NAME:latest || true
119+
echo "DOCKLE_EXIT=$?" >> "$GITHUB_ENV"
120+
121+
- name: ☁️ Upload Dockle SARIF
108122
if: always()
109123
uses: github/codeql-action/upload-sarif@v3
110124
with:
@@ -120,7 +134,7 @@ jobs:
120134
output-file: sbom.spdx.json
121135

122136
# -------------------------------------------------------------
123-
# 6️⃣ Trivy CVE scan → SARIF (fails on CRITICAL/HIGH)
137+
# 6️⃣ Trivy CVE scan → SARIF (fails on CRITICAL/HIGH)
124138
# -------------------------------------------------------------
125139
- name: 🛡️ Trivy vulnerability scan
126140
uses: aquasecurity/trivy-action@7b7aa264d83dc58691451798b4d117d53d21edfe
@@ -130,16 +144,16 @@ jobs:
130144
template: '@/contrib/sarif.tpl'
131145
output: trivy-results.sarif
132146
severity: CRITICAL,HIGH
133-
exit-code: 1 # break build on CRITICAL/HIGH vulns
147+
exit-code: 1
134148

135-
- name: ☁️ Upload Trivy SARIF
149+
- name: ☁️ Upload Trivy SARIF
136150
if: always()
137151
uses: github/codeql-action/upload-sarif@v3
138152
with:
139153
sarif_file: trivy-results.sarif
140154

141155
# -------------------------------------------------------------
142-
# 7️⃣ Push both tags to GHCR (uses built-in GITHUB_TOKEN)
156+
# 7️⃣ Push both tags to GHCR (using built-in GITHUB_TOKEN)
143157
# -------------------------------------------------------------
144158
- name: 🔑 Log in to GHCR
145159
uses: docker/login-action@v3
@@ -150,7 +164,6 @@ jobs:
150164

151165
- name: 🚀 Push image to GHCR
152166
run: |
153-
# Grab the timestamp tag we built earlier
154167
TIMESTAMP_TAG=$(docker images --format '{{.Tag}}' $IMAGE_NAME | grep -v latest)
155168
docker push $IMAGE_NAME:$TIMESTAMP_TAG
156169
docker push $IMAGE_NAME:latest
@@ -165,6 +178,15 @@ jobs:
165178
env:
166179
COSIGN_EXPERIMENTAL: "1" # enable key-less OIDC flow
167180
run: |
168-
# Cosign will interactively fetch an OIDC token from GitHub Actions
169181
cosign sign --yes $IMAGE_NAME:latest
170182
cosign attest --yes --predicate sbom.spdx.json $IMAGE_NAME:latest
183+
184+
# -------------------------------------------------------------
185+
# 9️⃣ Fail job if any linter exit codes captured non-zero
186+
# -------------------------------------------------------------
187+
- name: ⛔ Enforce lint gates
188+
if: ${{ env.HADOLINT_EXIT != '0' || env.DOCKLE_EXIT != '0' }}
189+
run: |
190+
echo "Hadolint exit: $HADOLINT_EXIT"
191+
echo "Dockle exit: $DOCKLE_EXIT"
192+
exit 1

0 commit comments

Comments
 (0)