When we use Jenkins for CI, we will run into errors when running phpunit
.
This is related to Docker assigning a pseudo-tty with docker-compose run
commands. The way Jenkins runs jobs (essentially through shell commands we define), the TTY allocation fails, and thus the Jenkins job also fails, before we even run our test suite.
TTY Allocation
So, in our CI context, we need to stop doing that via the -T
flag.
Let's update our develop
script to do that
- We create a
TTY
variable TTY
is set to-T
when the CI compose file is used- The
$TTY
option is appended to eachrun
command
#!/usr/bin/env bash
# Set environment variables for dev or CI
export APP_PORT=${APP_PORT:-80}
export DB_PORT=${DB_PORT:-3306}
export DB_ROOT_PASS=${DB_ROOT_PASS:-secret}
export DB_NAME=${DB_NAME:-helpspot}
export DB_USER=${DB_USER:-helpspot}
export DB_PASS=${DB_PASS:-secret}
# Decide which docker-compose file to use
COMPOSE_FILE="dev"
# Disable pseudo-TTY allocation for CI (Jenkins)
TTY=""
if [ ! -z "$BUILD_NUMBER" ]; then
COMPOSE_FILE="ci"
TTY="-T"
fi
COMPOSE="docker-compose -f docker-compose.$COMPOSE_FILE.yml"
if [ $# -gt 0 ];then
if [ "$1" == "art" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
app \
php artisan "$@"
# If "composer" is used, pass-thru to "composer"
# inside a new container
elif [ "$1" == "composer" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
app \
composer "$@"
# If "test" is used, run unit tests,
# pass-thru any extra arguments to php-unit
elif [ "$1" == "test" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
app \
./vendor/bin/phpunit "$@"
# If "npm" is used, run npm
# from our node container
elif [ "$1" == "npm" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
node \
npm "$@"
# If "gulp" is used, run gulp
# from our node container
elif [ "$1" == "gulp" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
node \
./node_modules/.bin/gulp "$@"
else
$COMPOSE "$@"
fi
else
$COMPOSE ps
fi
We can see how this appears differently when testing it out:
# We get colored output
./develop test
# We do not get colored output
BUILD_NUMBER=1234 ./develop test
Testing Helper
Along the same vain (testing), we can speed up our tests by not having Docker spin up a new container each time we run phpunit
. Instead, if we have our containers running, we can use the existing app
service.
This makes use of the exec
command instead of the run
command:
The new command:
elif [ "$1" == "t" ]; then
shift 1
$COMPOSE exec \
app \
sh -c "cd /var/www/html && ./vendor/bin/phpunit $@"
Here's the develop
script in its final form with the ./develop t
command, which runs phpunit via docker-compose exec
:
#!/usr/bin/env bash
# Set environment variables for dev or CI
export APP_PORT=${APP_PORT:-80}
export DB_PORT=${DB_PORT:-3306}
export DB_ROOT_PASS=${DB_ROOT_PASS:-secret}
export DB_NAME=${DB_NAME:-helpspot}
export DB_USER=${DB_USER:-helpspot}
export DB_PASS=${DB_PASS:-secret}
# Decide which docker-compose file to use
COMPOSE_FILE="dev"
# Disable pseudo-TTY allocation for CI (Jenkins)
TTY=""
if [ ! -z "$BUILD_NUMBER" ]; then
COMPOSE_FILE="ci"
TTY="-T"
fi
COMPOSE="docker-compose -f docker-compose.$COMPOSE_FILE.yml"
if [ $# -gt 0 ];then
if [ "$1" == "art" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
app \
php artisan "$@"
# If "composer" is used, pass-thru to "composer"
# inside a new container
elif [ "$1" == "composer" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
app \
composer "$@"
# If "test" is used, run unit tests,
# pass-thru any extra arguments to php-unit
elif [ "$1" == "test" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
app \
./vendor/bin/phpunit "$@"
elif [ "$1" == "t" ]; then
shift 1
$COMPOSE exec \
app \
sh -c "cd /var/www/html && ./vendor/bin/phpunit $@"
# If "npm" is used, run npm
# from our node container
elif [ "$1" == "npm" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
node \
npm "$@"
# If "gulp" is used, run gulp
# from our node container
elif [ "$1" == "gulp" ]; then
shift 1
$COMPOSE run --rm $TTY \
-w /var/www/html \
node \
./node_modules/.bin/gulp "$@"
else
$COMPOSE "$@"
fi
else
$COMPOSE ps
fi
And we can test this out:
./develop up -d
# Takes ~5.370 seconds
time ./develop test
# Takes ~3.953
# A few seconds (ish) quicker!
time ./develop t