Skip to content

Commit

Permalink
Add convenience scripts for building and running application and deve…
Browse files Browse the repository at this point in the history
…lopment containers
  • Loading branch information
Rayne committed Feb 20, 2021
1 parent d631244 commit 63a490d
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.php_cs.cache
build
builds
composer.lock
vendor
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This project adheres to [Semantic Versioning](http://semver.org).
* Added support for PHP 7.3, PHP 7.4 and 8.0
* Added Dockerfiles for PHP 7.2, 7.3, 7.4 and 8.0
* The application's Docker image is now utilizing PHP 8.0
* Added convenience scripts to build all container variants
* Added convenience scripts to run unit tests in development containers

## [1.1.0]

Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,17 @@ docker run -it --rm -v /my/message:/file rayne/ecoji /file
cat /my/message | docker run -i --rm rayne/ecoji
```

### Build Image
### Docker Images

The [`docker/README.md`](docker/README.md) explains how to build the application and all optional development images for all supported PHP versions.
Additional convenience scripts run the unit tests with all supported PHP versions.

## Tests

The library registers the test runner as composer script.

```bash
docker build -t rayne/ecoji:"$(cat assets/version.txt)" -t rayne/ecoji:latest .
composer test
```

All units tests can also be run in the development containers specified in the `docker` directory.
61 changes: 61 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Docker Images

## Files

- `app`:
Contains the `Dockerfile` for the CLI application

- `bin`:
This directory contains convenience scripts

- `bin/build-all`:
Builds the application image and all development images

- `bin/run`:
Forwards the given arguments to a container running the specified development container,
e.g. `run 8.0 composer test` runs the unit tests inside a development container with PHP 8.0

- `bin/test-all`:
Runs unit tests in all supported development containers.
Reports and reusable files for later runs are written to `/builds/$version-dev-php-$php_version`.
As a consequence, bandwidth and time is saved.
Since every application and PHP version has a dedicated directory,
reports are not overwritten by runs with different versions

- `dev-php-*`:
These directories contain `Dockerfile` files that build development environments for all supported PHP version.

## Docker Example

If one does not want to use the previously mentioned convenience scripts,
this is (almost) the second simplest solution to build and execute a development image.

```bash
cd ..

docker build \
-f docker/dev-php-8.0/Dockerfile \
-t rayne/ecoji:dev-php-8.0 \
.

docker run --rm -ti \
--user "$UID:$UID" \
--workdir /app \
-v "$(pwd):/app:rw" \
rayne/ecoji:dev-php-8.0 composer update

docker run --rm -ti \
--user "$UID:$UID" \
--workdir /app \
-v "$(pwd):/app:rw" \
rayne/ecoji:dev-php-8.0 composer test
```

The same can be accomplished by building all development images first
and then executing the same `composer` commands.

```bash
./bin/build-all
./bin/run 8.0 composer update
./bin/run 8.0 composer test
```
63 changes: 63 additions & 0 deletions docker/bin/build-all
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env bash

set -eux

cd "$(dirname "$0")/../.."
version="$(cat assets/version.txt)"

build_app() {
echo "Build app version $version with PHP-8"

docker build \
-f docker/app/Dockerfile \
-t rayne/ecoji:"$version-app" \
-t rayne/ecoji:"$version" \
-t rayne/ecoji:latest \
.
}

build_dev_8_0() {
echo "Build development version $version with PHP-8.0"

docker build \
-f docker/dev-php-8.0/Dockerfile \
-t rayne/ecoji:"$version-dev-php-8.0" \
-t rayne/ecoji:"$version-dev-php-8" \
.
}

build_dev_7_4() {
echo "Build development version $version with PHP-7.4"

docker build \
-f docker/dev-php-7.4/Dockerfile \
-t rayne/ecoji:"$version-dev-php-7.4" \
-t rayne/ecoji:"$version-dev-php-7" \
.
}

build_dev_7_3() {
echo "Build development version $version with PHP-7.3"

docker build \
-f docker/dev-php-7.3/Dockerfile \
-t rayne/ecoji:"$version-dev-php-7.3" \
.
}

build_dev_7_2() {
echo "Build development version $version with PHP-7.2"

docker build \
-f docker/dev-php-7.3/Dockerfile \
-t rayne/ecoji:"$version-dev-php-7.2" \
.
}

build_app
build_dev_8_0
build_dev_7_4
build_dev_7_3
build_dev_7_2

docker images | grep rayne/ecoji
35 changes: 35 additions & 0 deletions docker/bin/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash

set -eu

TEST_USER=${TEST_USER:-1000}
TEST_GROUP=${TEST_GROUP:-"$TEST_USER"}

cd "$(dirname "$0")/../.."

PROJECT_DIR="$(pwd)"

version=$(cat assets/version.txt)

if [[ "${1-}" == "" ]]; then
echo "Usage: $0 PHP_VERSION [ARGUMENTS]"
echo
echo "Available PHP versions:"
docker images | grep rayne/ecoji | grep dev
echo
echo "> $0 8.0 composer test"
echo
echo 'runs the unit tests in a PHP 8.0 environment.'
exit 1
fi

tag="$version-dev-php-$1"
shift

image="rayne/ecoji:$tag"

docker run --rm -ti \
--user "$TEST_USER:$TEST_GROUP" \
--workdir /app \
-v "$PROJECT_DIR:/app:rw" \
"$image" "$@"
75 changes: 75 additions & 0 deletions docker/bin/test-all
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
#
# This script updates the dependencies and runs the unit tests with multiple PHP versions.
# Dependencies are installed and results are written to `/builds/$version-dev-php-$php_version`.
# The script utilizes the Docker images built with `build-all`.
# Run the build script first.
# Otherwise updates and tests will fail.
#

set -eux

TEST_USER=${TEST_USER:-1000}
TEST_GROUP=${TEST_GROUP:-"$TEST_USER"}

version=$(cat assets/version.txt)

tags=(
"$version"-dev-php-8.0
"$version"-dev-php-7.4
"$version"-dev-php-7.3
"$version"-dev-php-7.2
)

cd "$(dirname "$0")/../.."
[ -d build ] || mkdir build

PROJECT_DIR="$(pwd)"

execute_in_docker(){
local tag="$1"
local image="rayne/ecoji:$tag"
shift

local output_dir="$PROJECT_DIR/builds/$tag"

install -o "$TEST_USER" -g "$TEST_GROUP" -m 755 -d "$PROJECT_DIR/builds"
install -o "$TEST_USER" -g "$TEST_GROUP" -m 755 -d "$output_dir"

# Create output directories.
local build_dir="$output_dir"
local composer_dir="$output_dir/composer"
local report_dir="$output_dir/report"
local vendor_dir="$output_dir/vendor"

install -o "$TEST_USER" -g "$TEST_GROUP" -m 755 -d "$composer_dir"
install -o "$TEST_USER" -g "$TEST_GROUP" -m 755 -d "$report_dir"
install -o "$TEST_USER" -g "$TEST_GROUP" -m 755 -d "$vendor_dir"

# Create empty composer file if the file does not exist yet.
local composer_lock_file="$output_dir/composer.lock"

touch "$composer_lock_file"
chmod 775 "$composer_lock_file"
chown "$TEST_USER:$TEST_GROUP" "$composer_lock_file"

if ! docker run --rm -ti \
--user "$TEST_USER:$TEST_GROUP" \
--workdir /app \
-v "$PROJECT_DIR:/app:rw" \
-v "$build_dir:/app/build:rw" \
-v "$composer_dir:/home/user/.composer:rw" \
-v "$composer_lock_file:/app/composer.lock:rw" \
-v "$vendor_dir:/app/vendor:rw" \
"$image" "$@"; then
echo
echo "The test failed with image: $image"

exit $?
fi
}

for tag in "${tags[@]}"; do
execute_in_docker "$tag" composer update
execute_in_docker "$tag" composer test
done

0 comments on commit 63a490d

Please sign in to comment.