@@ -92,13 +92,211 @@ mirror:
9292mirror-dry :
9393 DRY_RUN=1 ./ scripts/ mirror.sh
9494
95- # Resolve and update all pinned build inputs and binary checksums.
96- update :
97- ./ scripts/ update-versions.sh
95+ # Resolve and update pinned build inputs and binary checksums.
96+ # Components: alpine, trivy, busybox, or all (default).
97+ update * components :
98+ #!/usr/bin/env bash
99+ set -euo pipefail
100+
101+ config_file=" build.yaml"
102+ dockerfile=" Dockerfile"
103+ dry_run=" ${DRY_RUN:- 0} "
104+ update_alpine=0
105+ update_trivy=0
106+ update_busybox=0
107+
108+ set -- {{ components }}
109+ if [ " $# " -eq 0 ]; then
110+ set -- all
111+ fi
112+
113+ for component in " $@ " ; do
114+ case " $component " in
115+ all)
116+ update_alpine=1
117+ update_trivy=1
118+ update_busybox=1
119+ ;;
120+ alpine)
121+ update_alpine=1
122+ ;;
123+ trivy)
124+ update_trivy=1
125+ ;;
126+ busybox)
127+ update_busybox=1
128+ ;;
129+ * )
130+ printf ' update: unknown component: %s\n' " $component " >&2
131+ printf ' valid components: all, alpine, trivy, busybox\n' >&2
132+ exit 2
133+ ;;
134+ esac
135+ done
136+
137+ for command_name in curl yq awk grep sort sed just; do
138+ if ! command -v " $command_name " > /dev/null 2>&1 ; then
139+ printf ' update: %s is required\n' " $command_name " >&2
140+ exit 2
141+ fi
142+ done
143+
144+ temp_dir=" $( mktemp -d " ${TMPDIR:-/ tmp} /arcane-tools-update.XXXXXX" ) "
145+ trap ' rm -rf "$temp_dir"' EXIT HUP INT TERM
146+
147+ validate_version () {
148+ local component=" $1 "
149+ local version=" $2 "
150+ local pattern=" $3 "
151+
152+ if ! printf ' %s\n' " $version " | grep -Eq " $pattern " ; then
153+ printf ' update: invalid %s version from upstream: %s\n' \
154+ " $component " " $version " >&2
155+ exit 1
156+ fi
157+ }
158+
159+ if [ " $update_alpine " -eq 1 ]; then
160+ curl -fsSL https://alpinelinux.org/releases.json \
161+ -o " ${temp_dir} /alpine-releases.json"
162+ alpine_version=" $(
163+ yq -r ' .latest_stable' " ${temp_dir} /alpine-releases.json" | \
164+ sed ' s/^v//'
165+ ) "
166+ validate_version alpine " $alpine_version " ' ^[0-9]+\.[0-9]+$'
167+ fi
168+
169+ if [ " $update_trivy " -eq 1 ]; then
170+ trivy_release_url=" $(
171+ curl -fsSL -o /dev/null -w ' %{url_effective}' \
172+ https://github.com/aquasecurity/trivy/releases/latest
173+ ) "
174+ trivy_tag=" ${trivy_release_url##*/ } "
175+ trivy_version=" ${trivy_tag# v} "
176+ validate_version trivy " $trivy_version " \
177+ ' ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$'
178+
179+ curl -fsSL \
180+ " https://github.com/aquasecurity/trivy/releases/download/v${trivy_version} /trivy_${trivy_version} _checksums.txt" \
181+ -o " ${temp_dir} /trivy-upstream.txt"
182+
183+ : > " ${temp_dir} /trivy.txt"
184+ for trivy_arch in 32bit 64bit ARM ARM64 PPC64LE s390x; do
185+ trivy_file=" trivy_${trivy_version} _Linux-${trivy_arch} .tar.gz"
186+ matches=" $(
187+ grep -E " ^[0-9a-f]{64} ${trivy_file} $" \
188+ " ${temp_dir} /trivy-upstream.txt" || true
189+ ) "
190+ match_count=" $(
191+ printf ' %s\n' " $matches " | \
192+ awk ' NF { count++ } END { print count + 0 }'
193+ ) "
194+ if [ " $match_count " -ne 1 ]; then
195+ printf ' update: expected one checksum for %s, found %s\n' \
196+ " $trivy_file " " $match_count " >&2
197+ exit 1
198+ fi
199+ printf ' %s\n' " $matches " >> " ${temp_dir} /trivy.txt"
200+ done
201+ fi
202+
203+ if [ " $update_busybox " -eq 1 ]; then
204+ curl -fsSL https://busybox.net/downloads/ \
205+ -o " ${temp_dir} /busybox-index.html"
206+ busybox_version=" $(
207+ grep -Eo ' busybox-[0-9]+\.[0-9]+\.[0-9]+\.tar\.bz2' \
208+ " ${temp_dir} /busybox-index.html" | \
209+ sed -e ' s/^busybox-//' -e ' s/\.tar\.bz2$//' | \
210+ sort -u -t. -k1,1n -k2,2n -k3,3n | \
211+ awk ' END { print }'
212+ ) "
213+ validate_version busybox " $busybox_version " \
214+ ' ^[0-9]+\.[0-9]+\.[0-9]+$'
215+
216+ busybox_file=" busybox-${busybox_version} .tar.bz2"
217+ curl -fsSL \
218+ " https://busybox.net/downloads/${busybox_file} .sha256" \
219+ -o " ${temp_dir} /busybox.sha256"
220+ if ! grep -Eq " ^[0-9a-f]{64} ${busybox_file} $" \
221+ " ${temp_dir} /busybox.sha256" ; then
222+ printf ' update: invalid checksum file for %s\n' \
223+ " $busybox_file " >&2
224+ exit 1
225+ fi
226+ fi
227+
228+ printf ' Resolved versions:\n'
229+ if [ " $update_alpine " -eq 1 ]; then
230+ printf ' alpine: %s -> %s\n' \
231+ " $( yq -r ' .versions.alpine' " $config_file " ) " " $alpine_version "
232+ fi
233+ if [ " $update_trivy " -eq 1 ]; then
234+ printf ' trivy: %s -> %s\n' \
235+ " $( yq -r ' .versions.trivy' " $config_file " ) " " $trivy_version "
236+ fi
237+ if [ " $update_busybox " -eq 1 ]; then
238+ printf ' busybox: %s -> %s\n' \
239+ " $( yq -r ' .versions.busybox' " $config_file " ) " " $busybox_version "
240+ fi
241+
242+ if [ " $dry_run " = " 1" ]; then
243+ printf ' Dry run; no files changed.\n'
244+ exit 0
245+ fi
246+
247+ update_version () {
248+ local yaml_key=" $1 "
249+ local docker_arg=" $2 "
250+ local version=" $3 "
251+
252+ awk -v key=" $yaml_key " -v value=" $version " '
253+ $0 ~ "^ " key ": " {
254+ print " " key ": \"" value "\""
255+ found = 1
256+ next
257+ }
258+ { print }
259+ END {
260+ if (!found) {
261+ exit 1
262+ }
263+ }
264+ ' " $config_file " > " ${temp_dir} /build.yaml"
265+ mv " ${temp_dir} /build.yaml" " $config_file "
266+ awk -v key=" $docker_arg " -v value=" $version " '
267+ $0 ~ "^ARG " key "=" {
268+ print "ARG " key "=" value
269+ found = 1
270+ next
271+ }
272+ { print }
273+ END {
274+ if (!found) {
275+ exit 1
276+ }
277+ }
278+ ' " $dockerfile " > " ${temp_dir} /Dockerfile"
279+ mv " ${temp_dir} /Dockerfile" " $dockerfile "
280+ }
281+
282+ if [ " $update_alpine " -eq 1 ]; then
283+ update_version alpine ALPINE_VERSION " $alpine_version "
284+ fi
285+ if [ " $update_trivy " -eq 1 ]; then
286+ update_version trivy TRIVY_VERSION " $trivy_version "
287+ cp " ${temp_dir} /trivy.txt" checksums/trivy.txt
288+ fi
289+ if [ " $update_busybox " -eq 1 ]; then
290+ update_version busybox BUSYBOX_VERSION " $busybox_version "
291+ cp " ${temp_dir} /busybox.sha256" checksums/busybox.sha256
292+ fi
293+
294+ just manifest
295+ printf ' Updated selected versions, checksums, and checksums/manifest.md.\n'
98296
99297# Show the latest upstream versions without changing files.
100- update-dry :
101- . / scripts / update-versions.sh --dry-run
298+ update-dry * components :
299+ DRY_RUN= 1 just update {{ components }}
102300
103301clean :
104302 rm -rf dist
0 commit comments