-
Notifications
You must be signed in to change notification settings - Fork 139
213 lines (197 loc) · 7.15 KB
/
Copy pathdocker-build.yml
File metadata and controls
213 lines (197 loc) · 7.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
name: Build Container with Buildx
on:
workflow_call:
inputs:
dockerfile_path:
description: 'Path to Dockerfile'
required: true
type: string
context_path:
description: 'Build context path'
required: false
default: '.'
type: string
build_args:
description: 'Build arguments in JSON format'
required: false
type: string
default: '{}'
additional_tags:
description: 'Additional image tags (newline-separated)'
required: false
type: string
default: ''
tag_latest:
description: 'Also tag/push image_name:latest'
required: false
type: boolean
default: true
image_name:
description: 'Image name without registry prefix'
required: true
type: string
image_tag:
description: 'Image tag'
required: true
type: string
platforms:
description: 'Target platforms (comma-separated)'
required: false
default: 'linux/amd64'
type: string
runner:
description: 'Runner label to use'
required: false
default: 'linux-amd64-cpu4'
type: string
push:
description: 'Push image to registry'
required: false
default: false
type: boolean
load:
description: 'Load image to local Docker daemon'
required: false
default: true
type: boolean
download_artifacts:
description: 'Download build artifacts before Docker build (needed for release artifact images)'
required: false
default: false
type: boolean
scan:
description: 'Run a Grype vulnerability scan on the built image. Only effective when the image is loaded to the daemon (load=true and not pushing, i.e. PR builds); a no-op otherwise.'
required: false
default: false
type: boolean
timeout_minutes:
description: 'Job timeout in minutes'
required: false
default: 360
type: number
secrets:
NVCR_USERNAME:
description: "NVIDIA Container Registry username (typically '$oauthtoken')"
required: false
NVCR_TOKEN:
description: "NVIDIA Container Registry API token"
required: false
outputs:
image_digest:
description: 'Image digest'
value: ${{ jobs.build.outputs.digest }}
image_tag:
description: 'Image tag used'
value: ${{ jobs.build.outputs.image_tag }}
image_ref:
description: 'Primary image reference'
value: ${{ jobs.build.outputs.image_ref }}
all_tags:
description: 'All tags applied during the build'
value: ${{ jobs.build.outputs.tags }}
jobs:
build:
runs-on: ${{ inputs.runner }}
timeout-minutes: ${{ inputs.timeout_minutes }}
outputs:
digest: ${{ steps.build.outputs.digest }}
image_tag: ${{ inputs.image_tag }}
image_ref: ${{ steps.tag_list.outputs.primary }}
tags: ${{ steps.tag_list.outputs.tags }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download all artifacts
if: inputs.download_artifacts == true
uses: actions/download-artifact@v4
with:
pattern: '*-${{ github.run_id }}'
merge-multiple: true
- name: Set up Docker Buildx
if: inputs.push
uses: docker/setup-buildx-action@v3
with:
buildkitd-config: /etc/buildkit/buildkitd.toml
- name: Login to NVCR
uses: ./.github/actions/docker-auth
with:
username: ${{ secrets.NVCR_USERNAME }}
token: ${{ secrets.NVCR_TOKEN }}
- name: Prepare tag list
id: tag_list
env:
IMAGE_NAME: ${{ inputs.image_name }}
IMAGE_TAG: ${{ inputs.image_tag }}
TAG_LATEST: ${{ inputs.tag_latest }}
ADDITIONAL_TAGS: ${{ inputs.additional_tags }}
run: |
set -euo pipefail
PRIMARY="${IMAGE_NAME}:${IMAGE_TAG}"
echo "primary=${PRIMARY}" >> "$GITHUB_OUTPUT"
TAGS="${PRIMARY}"
if [[ "${TAG_LATEST}" == "true" ]]; then
TAGS="${TAGS}"$'\n'"${IMAGE_NAME}:latest"
fi
if [[ -n "${ADDITIONAL_TAGS// }" ]]; then
TAGS="${TAGS}"$'\n'"${ADDITIONAL_TAGS}"
fi
{
echo "tags<<EOF"
printf "%s\n" "${TAGS}"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Parse build arguments
id: parse-args
run: |
BUILD_ARGS='${{ inputs.build_args }}'
# Convert JSON to docker build-arg format
if [ "${BUILD_ARGS}" != "{}" ] && [ -n "${BUILD_ARGS}" ]; then
echo "build_args<<EOF" >> $GITHUB_OUTPUT
echo "${BUILD_ARGS}" | jq -r 'to_entries | .[] | "\(.key)=\(.value)"' >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
else
echo "build_args=" >> $GITHUB_OUTPUT
fi
- name: Build and optionally push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: ${{ inputs.context_path }}
file: ${{ inputs.dockerfile_path }}
platforms: ${{ inputs.platforms }}
push: ${{ inputs.push }}
load: ${{ inputs.load && !inputs.push }}
tags: ${{ steps.tag_list.outputs.tags }}
build-args: ${{ steps.parse-args.outputs.build_args }}
cache-from: type=gha
cache-to: ${{ inputs.push && 'type=gha,mode=max' || '' }}
# Scan the image the build step just loaded into the daemon — no rebuild.
# Only runs when the image is actually loaded (load=true and not pushing,
# i.e. PR builds); on push refs the image isn't loaded so this is skipped.
- name: Compute Grype scan key
id: scankey
if: ${{ inputs.scan && inputs.load && !inputs.push && steps.build.outcome == 'success' }}
env:
IMAGE_NAME: ${{ inputs.image_name }}
run: |
key="$(basename -- "$IMAGE_NAME")"
printf 'key=%s\n' "$key" >> "$GITHUB_OUTPUT"
- name: Grype vulnerability scan
if: ${{ inputs.scan && inputs.load && !inputs.push && steps.build.outcome == 'success' }}
continue-on-error: true
uses: NVIDIA/dsx-github-actions/.github/actions/security-container-scan@739847ddf00fda38916504ef84e1f504eac3158f
with:
image: ${{ inputs.image_name }}:${{ inputs.image_tag }}
fail-on: critical
fail-build: 'false'
write-summary: 'false'
artifact-name: grype-${{ steps.scankey.outputs.key }}-${{ github.run_id }}-${{ github.run_attempt }}
sbom-artifact-name: sbom-${{ steps.scankey.outputs.key }}-${{ github.run_id }}-${{ github.run_attempt }}
- name: Display build summary
run: |
echo "✅ Build completed successfully"
echo " Image: ${{ inputs.image_name }}:${{ inputs.image_tag }}"
echo " Digest: ${{ steps.build.outputs.digest }}"
echo " Platforms: ${{ inputs.platforms }}"
echo " Pushed: ${{ inputs.push }}"
echo " Loaded locally: ${{ inputs.load && !inputs.push }}"