Skip to content

Commit

Permalink
- Added ability to:
Browse files Browse the repository at this point in the history
   specify git branch manually.
   specify a toml config file.
   specify a buildx image location.
- Don't globally "use" builder.
- Upgraded unit tests to beter test builder.
  • Loading branch information
flounderpinto committed Jan 30, 2024
1 parent 11e95d4 commit 3911731
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 70 deletions.
43 changes: 25 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,31 @@ Using the option flags in the script, and modifications to the build pipeline fi
### Script syntax
```bash
Usage:
dockerBuild.sh dockerBuild -e dockerRegistryName -r dockerRepoName -c buildContextDir -f dockerFile [-g gitRepoDir] [-p platform]... [-t tag]... [-b buildArg]... [-a arg]... [-n] [-o] [-h]
-e - Docker registry name.
e.g. "index.docker.io/my-registry"
-r - Docker repo name.
e.g. "builder-docker".
-c - Docker build context.
-f - Dockerfile location.
-g - Git repo directory.
-p - Target platform for build.
Can be a comma-separated list or defined multiple times.
e.g. "linux/amd64", or "linux/amd64,linux/arm/v7"
-t - Additional tags to apply to the image.
Can be defined multiple times.
-b - Build-arg values.
Can be defined multiple times.
-a - Additional docker build args passed directly to docker build.
Can be a comma-separated list or defined multiple times.
-h - Show this help.
dockerBuild.sh dockerBuild -e dockerRegistryName -r dockerRepoName -c buildContextDir -f dockerFile [-k tomlConfigFile] [-x buildxImage] [-g gitRepoDir] [-m gitBranchName] [-p platform]... [-t tag]... [-b buildArg]... [-a arg]... [-n] [-o] [-h]
-e - Docker registry name.
e.g. "index.docker.io/my-registry"
-r - Docker repo name.
e.g. "builder-docker".
-c - Docker build context.
-f - Dockerfile location.
-k - Toml config file.
-x - BuildX image location.
-g - Git repo directory.
-m - Git branch name.
This script will attempt to determine this automatically.
To override that behavior, use this flag to specify the branch name manually.
-p - Target platform for build.
Can be a comma-separated list or defined multiple times.
e.g. "linux/amd64", or "linux/amd64,linux/arm/v7"
-t - Additional tags to apply to the image.
Can be defined multiple times.
-b - Build-arg values.
Can be defined multiple times.
-a - Additional docker build args passed directly to docker build.
Can be a comma-separated list or defined multiple times.
-n - Do not tag with the git version hash.
-o - Do not tag with the git branch name.
-h - Show this help.
```
There's 3 other functions in the script that simplify the 3 use cases above.
```bash
Expand Down
101 changes: 78 additions & 23 deletions src/dockerBuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,24 @@
DOCKER_REGISTRY="${REGISTRY}"
MAIN_BRANCH="${MAIN_BRANCH:-main}"

BUILDER=""

function dockerBuildUsage
{
echo $'Usage:'
echo $'\tdockerBuild.sh dockerBuild -e dockerRegistryName -r dockerRepoName -c buildContextDir -f dockerFile [-g gitRepoDir] [-p platform]... [-t tag]... [-b buildArg]... [-a arg]... [-n] [-o] [-h]'
echo $'\tdockerBuild.sh dockerBuild -e dockerRegistryName -r dockerRepoName -c buildContextDir -f dockerFile [-k tomlConfigFile] [-x buildxImage] [-g gitRepoDir] [-m gitBranchName] [-p platform]... [-t tag]... [-b buildArg]... [-a arg]... [-n] [-o] [-h]'
echo $'\t\t-e - Docker registry name.'
echo $'\t\t\te.g. "index.docker.io/my-registry"'
echo $'\t\t-r - Docker repo name.'
echo $'\t\t\te.g. "builder-docker".'
echo $'\t\t-c - Docker build context.'
echo $'\t\t-f - Dockerfile location.'
echo $'\t\t-k - Toml config file.'
echo $'\t\t-x - BuildX image location.'
echo $'\t\t-g - Git repo directory.'
echo $'\t\t-m - Git branch name.'
echo $'\t\t\tThis script will attempt to determine this automatically.'
echo $'\t\t\tTo override that behavior, use this flag to specify the branch name manually.'
echo $'\t\t-p - Target platform for build.'
echo $'\t\t\tCan be a comma-separated list or defined multiple times. '
echo $'\t\t\te.g. "linux/amd64", or "linux/amd64,linux/arm/v7"'
Expand All @@ -24,6 +31,8 @@ function dockerBuildUsage
echo $'\t\t\tCan be defined multiple times.'
echo $'\t\t-a - Additional docker build args passed directly to docker build.'
echo $'\t\t\tCan be a comma-separated list or defined multiple times.'
echo $'\t\t-n - Do not tag with the git version hash.'
echo $'\t\t-o - Do not tag with the git branch name.'
echo $'\t\t-h - Show this help.'
}

Expand All @@ -37,57 +46,85 @@ function getGitBranch
git --git-dir "$GIT_DIR" branch --show-current
}

function createBuilder
#This function exits in order to intercept the command in unit tests.
function _create
{
local createBuilderCmd="docker buildx create --use"
eval "$createBuilderCmd"
echo "Creating: $1"
BUILDER=$(eval "$1")
echo "CREATED BUILDER $BUILDER"
local status=$?
if [ "$status" -ne 0 ]; then
echo "Error creating builder instance"
exit 1
fi
}

function removeBuilder
function createBuilder
{
local removeBuilderCmd="docker buildx rm --force"
eval "$removeBuilderCmd"
local buildxImage="$1"
local tomlConfigFile="$2"
local createBuilderCmd="docker buildx create --driver=docker-container --driver-opt=\"image=$buildxImage\""
if [ -n "$tomlConfigFile" ]; then
createBuilderCmd="${createBuilderCmd} --config ${tomlConfigFile}"
fi
_create "$createBuilderCmd"
}

#This function exits in order to intercept the command in unit tests.
function _remove
{
eval "$1"
local status=$?
if [ "$status" -ne 0 ]; then
echo "Error removing builder instance"
exit 1
fi
}

function build
function removeBuilder
{
local removeBuilderCmd="docker buildx rm $BUILDER --force"
_remove "$removeBuilderCmd"
}

#This function exits in order to intercept the command in unit tests.
function _build
{
local buildCmd="$1"
echo "Building: $buildCmd"
eval "$buildCmd"
echo "Building: $1"
eval "$1"
local buildSuccess=$?
if [ "$buildSuccess" -ne 0 ]; then
echo "Docker build error. Exiting."
#Remove builder before exiting instance
removeBuilder
removeBuilder "$BUILDER"
exit "$buildSuccess"
fi
}

function buildImage
{
local buildCmd="BUILDX_BUILDER=$BUILDER $1"
_build "$buildCmd"
}

# Builds and tags a docker image.
function dockerBuild
{
local DOCKER_REPO=""
local BUILD_CONTEXT_DIR=""
local DOCKER_FILE=""
local TOML_CONFIG_FILE=""
local BUILDX_IMAGE=""
local GIT_DIR=""
local GIT_BRANCH=""
local NO_GIT_VERSION=""
local NO_GIT_BRANCH=""
local PLATFORM=()
local TAGS=()
local BUILD_ARGS=()
local ADDITIONAL_BUILD_FLAGS=()

while getopts ":e:r:c:f:g:p:t:b:a:noh" opt; do
while getopts ":e:r:c:f:k:x:g:m:p:t:b:a:noh" opt; do
case $opt in
e)
DOCKER_REGISTRY="$OPTARG"
Expand All @@ -101,9 +138,18 @@ function dockerBuild
f)
DOCKER_FILE="$OPTARG"
;;
k)
TOML_CONFIG_FILE="$OPTARG"
;;
x)
BUILDX_IMAGE="$OPTARG"
;;
g)
GIT_DIR="$OPTARG"
;;
m)
GIT_BRANCH="$OPTARG"
;;
p)
PLATFORM+=("$OPTARG")
;;
Expand Down Expand Up @@ -163,6 +209,11 @@ function dockerBuild
exit 1
fi

#If no buildx image location provided, use default.
if [ -z "$BUILDX_IMAGE" ]; then
BUILDX_IMAGE="moby/buildkit:buildx-stable-1"
fi

#If not git repo provided, default to the code dir
if [ -z "$GIT_DIR" ]; then
GIT_DIR="."
Expand All @@ -186,21 +237,26 @@ function dockerBuild
# Default to the main branch for caching.
local gitBranch="$MAIN_BRANCH"
if [ -z "$NO_GIT_BRANCH" ]; then
gitBranch=$(getGitBranch)
if [ -z "$gitBranch" ]; then
echo "Could not determine git branch name."
exit 1
if [ -n "$GIT_BRANCH" ]; then
gitBranch="$GIT_BRANCH"
else
#Tag with the branch name, so we have a tag that tracks the latest version of a branch,
# and also so that we have a location to push the build cache.
TAGS+=("$gitBranch")
gitBranch=$(getGitBranch)
if [ -z "$gitBranch" ]; then
echo "Could not determine git branch name."
exit 1
fi
fi
#Tag with the branch name, so we have a tag that tracks the latest version of a branch,
# and also so that we have a location to push the build cache.
TAGS+=("$gitBranch")
fi

echo "REGISTRY:$DOCKER_REGISTRY"
echo "REPO:$DOCKER_REPO"
echo "BUILD_CONTEXT_DIR:$BUILD_CONTEXT_DIR"
echo "DOCKER_FILE:$DOCKER_FILE"
echo "TOML_CONFIG_FILE:$TOML_CONFIG_FILE"
echo "BUILDX_IMAGE:$BUILDX_IMAGE"
echo "GIT_DIR:$GIT_DIR"
echo "PLATFORM:${PLATFORM[*]}"
echo "TAGS:${TAGS[*]}"
Expand Down Expand Up @@ -234,14 +290,13 @@ function dockerBuild
# single branch should be fairly minimal.
# https://docs.docker.com/build/cache/backends/#multiple-caches
buildCmd="${buildCmd} --cache-from=type=registry,ref=$DOCKER_REGISTRY/$DOCKER_REPO:$gitBranch"
buildCmd="${buildCmd} --cache-from=type=registry,ref=$DOCKER_REGISTRY/$DOCKER_REPO:$gitBranch"
buildCmd="${buildCmd} -f $DOCKER_FILE $BUILD_CONTEXT_DIR 2>&1"

#Create a new builder instance
createBuilder
createBuilder "$BUILDX_IMAGE" "$TOML_CONFIG_FILE"

#Build
build "$buildCmd"
buildImage "$buildCmd"

#Remove builder instance
removeBuilder
Expand Down
6 changes: 3 additions & 3 deletions test/unit/expected/buildStandardBranch
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
createBuilder
docker buildx build -o type=registry -t docker-registry/docker-repo:mocked-git-version -t docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch -f ./docker/Dockerfile . 2>&1
removeBuilder
docker buildx create --driver=docker-container --driver-opt="image=moby/buildkit:buildx-stable-1"
BUILDX_BUILDER=test_builder docker buildx build -o type=registry -t docker-registry/docker-repo:mocked-git-version -t docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch -f ./docker/Dockerfile . 2>&1
docker buildx rm test_builder --force
6 changes: 3 additions & 3 deletions test/unit/expected/buildStandardMain
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
createBuilder
docker buildx build -o type=registry -t docker-registry/docker-repo:latest -t docker-registry/docker-repo:mocked-git-version -t docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch -f ./docker/Dockerfile . 2>&1
removeBuilder
docker buildx create --driver=docker-container --driver-opt="image=moby/buildkit:buildx-stable-1"
BUILDX_BUILDER=test_builder docker buildx build -o type=registry -t docker-registry/docker-repo:latest -t docker-registry/docker-repo:mocked-git-version -t docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch -f ./docker/Dockerfile . 2>&1
docker buildx rm test_builder --force
6 changes: 3 additions & 3 deletions test/unit/expected/buildStandardTag
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
createBuilder
docker buildx build -o type=registry -t docker-registry/docker-repo:tag1 --cache-from=type=registry,ref=docker-registry/docker-repo:main --cache-from=type=registry,ref=docker-registry/docker-repo:main -f ./docker/Dockerfile . 2>&1
removeBuilder
docker buildx create --driver=docker-container --driver-opt="image=moby/buildkit:buildx-stable-1"
BUILDX_BUILDER=test_builder docker buildx build -o type=registry -t docker-registry/docker-repo:tag1 --cache-from=type=registry,ref=docker-registry/docker-repo:main -f ./docker/Dockerfile . 2>&1
docker buildx rm test_builder --force
6 changes: 3 additions & 3 deletions test/unit/expected/multipleArgs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
createBuilder
docker buildx build -o type=registry --build-arg build-arg1 --build-arg build-arg2 --platform=platform1,platform2 --arg1 on --arg2 off -t docker-registry/docker-repo:tag1 -t docker-registry/docker-repo:tag2 -t docker-registry/docker-repo:mocked-git-version -t docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch -f dockerfile build-context-dir 2>&1
removeBuilder
docker buildx create --driver=docker-container --driver-opt="image=moby/buildkit:buildx-stable-1"
BUILDX_BUILDER=test_builder docker buildx build -o type=registry --build-arg build-arg1 --build-arg build-arg2 --platform=platform1,platform2 --arg1 on --arg2 off -t docker-registry/docker-repo:tag1 -t docker-registry/docker-repo:tag2 -t docker-registry/docker-repo:mocked-git-version -t docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch -f dockerfile build-context-dir 2>&1
docker buildx rm test_builder --force
6 changes: 3 additions & 3 deletions test/unit/expected/singleArgs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
createBuilder
docker buildx build -o type=registry --build-arg build-arg --platform=target --arg on -t docker-registry/docker-repo:tag -t docker-registry/docker-repo:mocked-git-version -t docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch -f dockerfile build-context-dir 2>&1
removeBuilder
docker buildx create --driver=docker-container --driver-opt="image=myrepo/moby/buildkit:buildx-stable-1" --config test.toml
BUILDX_BUILDER=test_builder docker buildx build -o type=registry --build-arg build-arg --platform=target --arg on -t docker-registry/docker-repo:tag -t docker-registry/docker-repo:mocked-git-version -t docker-registry/docker-repo:mocked-git-branch --cache-from=type=registry,ref=docker-registry/docker-repo:mocked-git-branch -f dockerfile build-context-dir 2>&1
docker buildx rm test_builder --force
Loading

0 comments on commit 3911731

Please sign in to comment.