11#! /bin/bash
2+ # shellcheck disable=SC2155
23
34# WARNING: Please, DO NOT edit this file! It is maintained in the Repository Template (https://github.com/nhs-england-tools/repository-template). Raise a PR instead.
45
@@ -22,6 +23,7 @@ set -euo pipefail
2223function docker-build() {
2324
2425 local dir=${dir:- $PWD }
26+
2527 _create-effective-dockerfile
2628 version-create-effective-file
2729 docker build \
@@ -35,14 +37,14 @@ function docker-build() {
3537 --build-arg GIT_BRANCH=" $( _get-git-branch-name) " \
3638 --build-arg GIT_COMMIT_HASH=" $( git rev-parse --short HEAD) " \
3739 --build-arg BUILD_DATE=" $( date -u +" %Y-%m-%dT%H:%M:%S%z" ) " \
38- --build-arg BUILD_VERSION=" $( _get-version) " \
39- --tag " ${DOCKER_IMAGE} :$( _get-version) " \
40+ --build-arg BUILD_VERSION=" $( _get-effective- version) " \
41+ --tag " ${DOCKER_IMAGE} :$( _get-effective- version) " \
4042 --rm \
4143 --file " ${dir} /Dockerfile.effective" \
4244 .
4345 # Tag the image with all the stated versions, see the documentation for more details
44- for version in $( _get-all-versions) latest; do
45- docker tag " ${DOCKER_IMAGE} :$( _get-version) " " ${DOCKER_IMAGE} :${version} "
46+ for version in $( _get-all-effective- versions) latest; do
47+ docker tag " ${DOCKER_IMAGE} :$( _get-effective- version) " " ${DOCKER_IMAGE} :${version} "
4648 done
4749 docker rmi --force " $( docker images | grep " <none>" | awk ' {print $3}' ) " 2> /dev/null || :
4850}
@@ -56,10 +58,11 @@ function docker-build() {
5658function docker-check-test() {
5759
5860 local dir=${dir:- $PWD }
61+
5962 # shellcheck disable=SC2086,SC2154
6063 docker run --rm --platform linux/amd64 \
6164 ${args:- } \
62- " ${DOCKER_IMAGE} :$( _get-version) " 2> /dev/null \
65+ " ${DOCKER_IMAGE} :$( _get-effective- version) " 2> /dev/null \
6366 ${cmd:- } \
6467 | grep -q " ${check} " && echo PASS || echo FAIL
6568}
@@ -72,10 +75,11 @@ function docker-check-test() {
7275function docker-run() {
7376
7477 local dir=${dir:- $PWD }
78+
7579 # shellcheck disable=SC2086
7680 docker run --rm --platform linux/amd64 \
7781 ${args:- } \
78- " ${DOCKER_IMAGE} :$( dir=" $dir " _get-version) " \
82+ " ${DOCKER_IMAGE} :$( dir=" $dir " _get-effective- version) " \
7983 ${cmd:- }
8084}
8185
@@ -85,8 +89,9 @@ function docker-run() {
8589function docker-push() {
8690
8791 local dir=${dir:- $PWD }
92+
8893 # Push all the image tags based on the stated versions, see the documentation for more details
89- for version in $( dir=" $dir " _get-all-versions) latest; do
94+ for version in $( dir=" $dir " _get-all-effective- versions) latest; do
9095 docker push " ${DOCKER_IMAGE} :${version} "
9196 done
9297}
@@ -97,7 +102,8 @@ function docker-push() {
97102function docker-clean() {
98103
99104 local dir=${dir:- $PWD }
100- for version in $( dir=" $dir " _get-all-versions) latest; do
105+
106+ for version in $( dir=" $dir " _get-all-effective-versions) latest; do
101107 docker rmi " ${DOCKER_IMAGE} :${version} " > /dev/null 2>&1 || :
102108 done
103109 rm -f \
@@ -112,10 +118,12 @@ function docker-clean() {
112118function version-create-effective-file() {
113119
114120 local dir=${dir:- $PWD }
115- build_datetime=${BUILD_DATETIME:- $(date -u +' %Y-%m-%dT%H:%M:%S%z' )}
116- if [ -f " $dir /VERSION" ]; then
121+ local version_file=" $dir /VERSION"
122+ local build_datetime=${BUILD_DATETIME:- $(date -u +' %Y-%m-%dT%H:%M:%S%z' )}
123+
124+ if [ -f " $version_file " ]; then
117125 # shellcheck disable=SC2002
118- cat " $dir /VERSION " | \
126+ cat " $version_file " | \
119127 sed " s/\(\$ {yyyy}\|\$ yyyy\)/$( date --date=" ${build_datetime} " -u +" %Y" ) /g" | \
120128 sed " s/\(\$ {mm}\|\$ mm\)/$( date --date=" ${build_datetime} " -u +" %m" ) /g" | \
121129 sed " s/\(\$ {dd}\|\$ dd\)/$( date --date=" ${build_datetime} " -u +" %d" ) /g" | \
@@ -132,18 +140,18 @@ function version-create-effective-file() {
132140
133141# Retrieve the Docker image version from the '.tool-versions' file and pull the
134142# image if required. This function is to be used in conjunction with the
135- # external images and it prevents Docker from downloading an image each time it
136- # is used, since the digest is not stored locally for compressed images. To
137- # optimise, the solution is to pull the image using its digest and then tag it,
138- # checking this tag for existence for any subsequent use.
143+ # external images and it prevents Docker from downloading an image each time it
144+ # is used, since the digest is not stored locally for compressed images. To
145+ # optimise, the solution is to pull the image using its digest and then tag it,
146+ # checking this tag for existence for any subsequent use.
139147# Arguments (provided as environment variables):
140148# name=[full name of the Docker image]
141149# shellcheck disable=SC2001
142150function docker-get-image-version-and-pull() {
143151
144152 # Get the image full version from the '.tool-versions' file
145- versions_file=" $( git rev-parse --show-toplevel) /.tool-versions"
146- version=" latest"
153+ local versions_file=" $( git rev-parse --show-toplevel) /.tool-versions"
154+ local version=" latest"
147155 if [ -f " $versions_file " ]; then
148156 line=$( grep " docker/${name} " " $versions_file " | sed " s/^#\s*//; s/\s*#.*$//" )
149157 [ -n " $line " ] && version=$( echo " $line " | awk ' {print $2}' )
@@ -155,8 +163,8 @@ function docker-get-image-version-and-pull() {
155163 # version="1.2.3@sha256:hash"
156164 # tag="1.2.3"
157165 # digest="sha256:hash"
158- tag=" $( echo " $version " | sed ' s/@.*$//' ) "
159- digest=" $( echo " $version " | sed ' s/^.*@//' ) "
166+ local tag=" $( echo " $version " | sed ' s/@.*$//' ) "
167+ local digest=" $( echo " $version " | sed ' s/^.*@//' ) "
160168
161169 # Check if the image exists locally already
162170 if ! docker images | awk ' { print $1 ":" $2 }' | grep " ^${name} :${tag} $" ; then
@@ -188,6 +196,7 @@ function docker-get-image-version-and-pull() {
188196function _create-effective-dockerfile() {
189197
190198 local dir=${dir:- $PWD }
199+
191200 cp " ${dir} /Dockerfile" " ${dir} /Dockerfile.effective"
192201 _replace-image-latest-by-specific-version
193202 _append-metadata
@@ -199,7 +208,10 @@ function _create-effective-dockerfile() {
199208function _replace-image-latest-by-specific-version() {
200209
201210 local dir=${dir:- $PWD }
202- versions_file=$( git rev-parse --show-toplevel) /.tool-versions
211+ local versions_file=$( git rev-parse --show-toplevel) /.tool-versions
212+ local dockerfile=" ${dir} /Dockerfile.effective"
213+ local build_datetime=${BUILD_DATETIME:- $(date -u +' %Y-%m-%dT%H:%M:%S%z' )}
214+
203215 if [ -f " $versions_file " ]; then
204216 # First, list the entries specific for Docker to take precedence, then the rest
205217 content=$( grep " docker/" " $versions_file " ; grep -v " docker/" " $versions_file " )
@@ -208,9 +220,24 @@ function _replace-image-latest-by-specific-version() {
208220 line=$( echo " $line " | sed " s/^#\s*//; s/\s*#.*$//" | sed " s;docker/;;" )
209221 name=$( echo " $line " | awk ' {print $1}' )
210222 version=$( echo " $line " | awk ' {print $2}' )
211- sed -i " s;FROM ${name} :latest;FROM ${name} :${version} ;g" " ${dir} /Dockerfile.effective "
223+ sed -i " s;\( FROM .*\) ${name} :latest;\1 ${name} :${version} ;g" " $dockerfile "
212224 done
213225 fi
226+
227+ if [ -f " $dockerfile " ]; then
228+ # shellcheck disable=SC2002
229+ cat " $dockerfile " | \
230+ sed " s/\(\$ {yyyy}\|\$ yyyy\)/$( date --date=" ${build_datetime} " -u +" %Y" ) /g" | \
231+ sed " s/\(\$ {mm}\|\$ mm\)/$( date --date=" ${build_datetime} " -u +" %m" ) /g" | \
232+ sed " s/\(\$ {dd}\|\$ dd\)/$( date --date=" ${build_datetime} " -u +" %d" ) /g" | \
233+ sed " s/\(\$ {HH}\|\$ HH\)/$( date --date=" ${build_datetime} " -u +" %H" ) /g" | \
234+ sed " s/\(\$ {MM}\|\$ MM\)/$( date --date=" ${build_datetime} " -u +" %M" ) /g" | \
235+ sed " s/\(\$ {SS}\|\$ SS\)/$( date --date=" ${build_datetime} " -u +" %S" ) /g" | \
236+ sed " s/\(\$ {hash}\|\$ hash\)/$( git rev-parse --short HEAD) /g" \
237+ > " $dockerfile .tmp"
238+ mv " $dockerfile .tmp" " $dockerfile "
239+ fi
240+
214241 # Do not ignore the issue if 'latest' is used in the effective image
215242 sed -Ei " /# hadolint ignore=DL3007$/d" " ${dir} /Dockerfile.effective"
216243}
@@ -221,6 +248,7 @@ function _replace-image-latest-by-specific-version() {
221248function _append-metadata() {
222249
223250 local dir=${dir:- $PWD }
251+
224252 cat \
225253 " $dir /Dockerfile.effective" \
226254 " $( git rev-parse --show-toplevel) /scripts/docker/Dockerfile.metadata" \
@@ -231,26 +259,29 @@ function _append-metadata() {
231259# Print top Docker image version.
232260# Arguments (provided as environment variables):
233261# dir=[path to the image directory where the Dockerfile is located, default is '.']
234- function _get-version() {
262+ function _get-effective- version() {
235263
236264 local dir=${dir:- $PWD }
265+
237266 head -n 1 " ${dir} /.version" 2> /dev/null || :
238267}
239268
240269# Print all Docker image versions.
241270# Arguments (provided as environment variables):
242271# dir=[path to the image directory where the Dockerfile is located, default is '.']
243- function _get-all-versions() {
272+ function _get-all-effective- versions() {
244273
245274 local dir=${dir:- $PWD }
275+
246276 cat " ${dir} /.version" 2> /dev/null || :
247277}
248278
249279# Print Git branch name. Check the GitHub variables first and then the local Git
250- # repo.
280+ # repo.
251281function _get-git-branch-name() {
252282
253- branch_name=$( git rev-parse --abbrev-ref HEAD)
283+ local branch_name=$( git rev-parse --abbrev-ref HEAD)
284+
254285 if [ -n " ${GITHUB_HEAD_REF:- } " ]; then
255286 branch_name=$GITHUB_HEAD_REF
256287 elif [ -n " ${GITHUB_REF:- } " ]; then
0 commit comments