Skip to content

Commit

Permalink
Initial pass at a unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
flounderpinto committed Dec 13, 2023
1 parent ea430e6 commit 2694a90
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 123 deletions.
158 changes: 35 additions & 123 deletions src/dockerBuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,29 @@ CODE_DIR="${CODE_DIR:-/opt/code}"
function dockerBuildUsage
{
echo $'Usage:'
echo $'\tdockerBuild.sh dockerBuild [-t tag1,tag2,tagN] [-a] [-h] <-e dockerRegistryName> <-r dockerRepoName> <-d buildContextDir> <-f dockerFile> <-g gitRepoDir>'
echo $'\t\t-t - A comma-separated list of additional tags to apply to the image'
echo $'\tdockerBuild.sh dockerBuild -e dockerRegistryName -r dockerRepoName -d buildContextDir -f dockerFile [-g gitRepoDir] [-t tag1,tag2,tagN] [-b buildArg] [-p platform1] [-a args] [-h]'
echo $'\t\t-e - Docker registry name. e.g. "index.docker.io/my-registry"'
echo $'\t\t-r - Docker repo name. e.g. "builder-docker"'
echo $'\t\t-d - Docker build context'
echo $'\t\t-f - Dockerfile'
echo $'\t\t-g - Git repo directory'
echo $'\t\t-p - Build platform'
echo $'\t\t-t - A comma-separated list of additional tags to apply to the image'
echo $'\t\t-b - Build-arg values. Can be defined multiple times.'
echo $'\t\t-p - Set target platform for build'
echo $'\t\t-a - Additional docker build args passed directly to docker build'
echo $'\t\t-h - Show this help.'
}

function getGitVersion
{
git --git-dir "$GIT_DIR" log -1 --pretty=%H
}

function getGitBranch
{
git --git-dir "$GIT_DIR" branch --show-current
}

function createBuilder
{
local createBuilderCmd="docker buildx create --use"
Expand All @@ -42,6 +52,22 @@ function removeBuilder
fi
}

function build
{
local buildCmd="$1"
echo "Building: $buildCmd"
#TODO - NEEDED?
eval "$buildCmd" | tee "$THIS_DIR"/tmp
#The exit code of 'docker build' is lost with $? because of the pipe. Use PIPESTATUS instead.
local buildSuccess=${PIPESTATUS[0]}
if [ "$buildSuccess" -ne 0 ]; then
echo "Docker build error. Exiting."
#Remove builder before exiting instance
removeBuilder
exit "$buildSuccess"
fi
}

# Builds and tags a docker image.
function dockerBuild
{
Expand Down Expand Up @@ -115,7 +141,7 @@ function dockerBuild

if [ -z "$DOCKER_REPO" ]; then
echo "Error, the docker repo name (-r) is required."
dockerBuildUsage
dockerBuildUsage#TODO
exit 1
fi

Expand All @@ -139,7 +165,8 @@ function dockerBuild
#Default is to just tag with the git version.
if [ ${#TAGS[@]} -eq 0 ]; then
local gitVersion=""
gitVersion=$(git --git-dir "$GIT_DIR" log -1 --pretty=%H)
#gitVersion=$(git --git-dir "$GIT_DIR" log -1 --pretty=%H) #TODO
gitVersion=$(getGitVersion)
if [ -z "$gitVersion" ]; then
echo "Error, Could not determine git repo version."
exit 1
Expand All @@ -149,7 +176,8 @@ function dockerBuild

#Find the current git branch.
local gitBranch=""
gitBranch=$(git --git-dir "$GIT_DIR" branch --show-current)
#gitBranch=$(git --git-dir "$GIT_DIR" branch --show-current) #TODO
gitBranch=$(getGitBranch)
if [ -z "$gitBranch" ]; then
echo "Could not determine git branch name, caching to main."
gitBranch="$MAIN_BRANCH"
Expand All @@ -168,7 +196,6 @@ function dockerBuild
echo "TAGS:${TAGS[*]}"

#Put together the build command.
# Freezes often sometimes occur in Jenkins without the --network host option.
local buildCmd="docker buildx build -o type=registry"
for buildArg in "${BUILD_ARGS[@]}"; do
buildCmd="${buildCmd} --build-arg $buildArg"
Expand All @@ -194,16 +221,7 @@ function dockerBuild
createBuilder

#Build
echo "Building: $buildCmd"
eval "$buildCmd" | tee "$THIS_DIR"/tmp
#The exit code of 'docker build' is lost with $? because of the pipe. Use PIPESTATUS instead.
local buildSuccess=${PIPESTATUS[0]}
if [ "$buildSuccess" -ne 0 ]; then
echo "Docker build error. Exiting."
#Remove builder before exiting instance
removeBuilder
exit "$buildSuccess"
fi
build "$buildCmd"

#Remove builder instance
removeBuilder
Expand All @@ -218,111 +236,5 @@ function dockerBuildStandard
dockerBuild -d "$CODE_DIR" -f "$CODE_DIR/docker/Dockerfile" -g "$CODE_DIR" "$@"
}

function dockerPushUsage
{
echo $'Usage:'
echo $'\tdockerBuild.sh dockerPush [-t tag1,tag2,tagN] [-h] <-r dockerRepoName> <-g gitRepoDir>'
echo $'\t\t-t - A comma-separated list of tags to push'
echo $'\t\t-e - Docker registry name. e.g. "index.docker.io/my-registry"'
echo $'\t\t-r - Docker repo name. e.g. "builder-docker"'
echo $'\t\t-g - Git repo directory'
echo $'\t\t-h - Show this help.'
}

function dockerPush
{
local TAGS=()
local DOCKER_REGISTRY=""
local DOCKER_REPO=""
local GIT_DIR=""

while getopts ":t:e:r:g:h" opt; do
case $opt in
t)
IFS=',' read -ra TAG_LIST <<< "$OPTARG"
for i in "${TAG_LIST[@]}"; do
TAGS+=("$i")
done
;;
e)
DOCKER_REGISTRY=$OPTARG
;;
r)
DOCKER_REPO=$OPTARG
;;
g)
GIT_DIR=$OPTARG
#The location of the .git directory is required.
GIT_DIR="$GIT_DIR/.git"
;;
h)
dockerPushUsage
exit 1
;;
\?)
echo "Invalid option: -$OPTARG" >&2
dockerPushUsage
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
dockerPushUsage
exit 1
;;
esac
done

if [ -z "$DOCKER_REGISTRY" ]; then
echo "Error, the docker registry name (-e) is required."
dockerBuildUsage
exit 1
fi

if [ -z "$DOCKER_REPO" ]; then
echo "Error, the docker repo name (-r) is required."
dockerBuildUsage
exit 1
fi

#If not git repo provided, default to current directory
if [ -z "$GIT_DIR" ]; then
GIT_DIR="./.git"
fi

#Default is to just push the git version tag.
if [ ${#TAGS[@]} -eq 0 ]; then
local gitVersion=""
gitVersion=$(git --git-dir "$GIT_DIR" log -1 --pretty=%H)
if [ -z "$gitVersion" ]; then
echo "Error, Could not determine git repo version"
exit 1
fi
TAGS+=("$gitVersion")
fi

docker login

local retVal=0

for i in "${TAGS[@]}"; do
echo "Pushing: $DOCKER_REGISTRY/$DOCKER_REPO:$i"
docker push "$DOCKER_REGISTRY"/"$DOCKER_REPO":"$i"
local pushStatus=$?
if [ "$pushStatus" -ne 0 ]; then
echo "Error pushing $DOCKER_REGISTRY/$DOCKER_REPO:$i"
retVal=1
fi
done

exit $retVal
}

#When calling this script through docker, many arguments are
# always the same. This is a shortcut for calling dockerPush()
function dockerPushStandard
{
dockerPush -g "$CODE_DIR" "$@"
}

#Allows function calls based on arguments passed to the script
"$@"
3 changes: 3 additions & 0 deletions test/unit/expected/allArgs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
createBuilder
docker buildx build -o type=registry --build-arg build-arg --platform=target1,target2 args -t docker-registry/docker-repo:tag1 -t docker-registry/docker-repo:tag2 -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
3 changes: 3 additions & 0 deletions test/unit/output
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
createBuilder
docker buildx build -o type=registry --build-arg build-arg --platform=target1,target2 args -t docker-registry/docker-repo:tag1 -t docker-registry/docker-repo:tag2 -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
71 changes: 71 additions & 0 deletions test/unit/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/bin/bash

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
OUTPUT_FILE="$SCRIPT_DIR/output"

source ../../src/dockerBuild.sh

# Set up mocks
function getGitVersion
{
echo "mocked-git-version"
}
export -f getGitVersion

function getGitBranch
{
echo "mocked-git-branch"
}
export -f getGitBranch

function createBuilder
{
echo "createBuilder" >> "$OUTPUT_FILE"
}
export -f createBuilder

function removeBuilder
{
echo "removeBuilder" >> "$OUTPUT_FILE"
}
export -f removeBuilder

function build
{
echo "$1" >> "$OUTPUT_FILE"
}
export -f build


function oneTimeSetUp()
{
echo "oneTimeSetUp"
}

function oneTimeTearDown()
{
echo "oneTimeTearDown"
rm "$OUTPUT_FILE"
}

testAllArgs()
{
local REGISTRY=docker-registry
local REPO=docker-repo
local BUILD_CONTEXT=build-context-dir
local DOCKERFILE=dockerfile
local GIT_DIR=git-dir
local TAGS=tag1,tag2
local BUILD_ARG=build-arg
local PLATFORM=target1,target2
local ARGS=args

result=$(dockerBuild -e $REGISTRY -r $REPO -d $BUILD_CONTEXT -f $DOCKERFILE -g $GIT_DIR -t $TAGS -b $BUILD_ARG -p $PLATFORM -a $ARGS)
echo "$result"
output=$(<"$OUTPUT_FILE")
expected=$(<"$SCRIPT_DIR/expected/allArgs")
assertEquals "$expected" "$output"
}

# Load and run shUnit2.
. shunit2

0 comments on commit 2694a90

Please sign in to comment.