diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 7528c334..a61a76e5 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -22,6 +22,7 @@ steps: plugins: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO}#${BUILDKITE_COMMIT}: run: tests + command: ["bats", "tests", "tests/v2"] # The rest of the steps are integration tests diff --git a/README.md b/README.md index fb830350..35e868f5 100644 --- a/README.md +++ b/README.md @@ -560,12 +560,16 @@ Select when to upload container logs. The default is `on-error`. +### `cli-version` (optional) + +If set to `2`, plugin will use `docker compose` to execute commands; otherwise it will default to version `1` using `docker-compose` instead. + ## Developing To run the tests: ```bash -docker-compose run --rm tests +docker-compose run --rm tests bats tests tests/v2 ``` ## License diff --git a/lib/shared.bash b/lib/shared.bash index 070ffd39..da79239b 100644 --- a/lib/shared.bash +++ b/lib/shared.bash @@ -177,6 +177,9 @@ function build_image_override_file_with_version() { # Runs the docker-compose command, scoped to the project, with the given arguments function run_docker_compose() { local command=(docker-compose) + if [[ "$(plugin_read_config CLI_VERSION "1")" == "2" ]] ; then + command=(docker compose) + fi if [[ "$(plugin_read_config VERBOSE "false")" == "true" ]] ; then command+=(--verbose) diff --git a/plugin.yml b/plugin.yml index 1086916a..2d5e542d 100644 --- a/plugin.yml +++ b/plugin.yml @@ -78,6 +78,11 @@ configuration: type: boolean entrypoint: type: string + cli-version: + type: string + enum: + - 1 + - 2 anyOf: - required: - run diff --git a/tests/build.bats b/tests/build.bats index c95388c4..15628d21 100644 --- a/tests/build.bats +++ b/tests/build.bats @@ -75,6 +75,23 @@ load '../lib/shared' unstub docker-compose } +@test "Build with docker-compose and v1 is set explicitly " { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLI_VERSION=1 + + stub docker-compose \ + "-f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull myservice : echo built myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + unstub docker-compose +} + @test "Build with a repository" { export BUILDKITE_JOB_ID=1111 export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice diff --git a/tests/v2/build.bats b/tests/v2/build.bats new file mode 100644 index 00000000..2322435d --- /dev/null +++ b/tests/v2/build.bats @@ -0,0 +1,487 @@ +#!/usr/bin/env bats + +load '/usr/local/lib/bats/load.bash' +load '../../lib/shared' + +# export DOCKER_COMPOSE_STUB_DEBUG=/dev/stdout +# export BUILDKITE_AGENT_STUB_DEBUG=/dev/stdout +# export BATS_MOCK_TMPDIR=$PWD + +setup_file() { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLI_VERSION=2 +} + +@test "Build without a repository" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull myservice : echo built myservice" + + run $PWD/hooks/command + + unstub docker + assert_success + assert_output --partial "built myservice" +} + +@test "Build with no-cache" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_NO_CACHE=true + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull --no-cache myservice : echo built myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + unstub docker +} + +@test "Build with parallel" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_PARALLEL=true + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull --parallel myservice : echo built myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + unstub docker +} + +@test "Build with build args" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ARGS_0=MYARG=0 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ARGS_1=MYARG=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull --build-arg MYARG=0 --build-arg MYARG=1 myservice : echo built myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + unstub docker +} + +@test "Build with a repository" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_REPOSITORY=my.repository/llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml push myservice : echo pushed myservice" \ + + stub buildkite-agent \ + "meta-data set docker-compose-plugin-built-image-tag-myservice my.repository/llamas:test-myservice-build-1 : echo set image metadata for myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "pushed myservice" + assert_output --partial "set image metadata for myservice" + unstub docker + unstub buildkite-agent +} + +@test "Build with a repository and multiple build aliases" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_REPOSITORY=my.repository/llamas + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_ALIAS_0=myservice-1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_ALIAS_1=myservice-2 + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml push myservice : echo pushed myservice" \ + + stub buildkite-agent \ + "meta-data set docker-compose-plugin-built-image-tag-myservice my.repository/llamas:test-myservice-build-1 : echo set image metadata for myservice" \ + "meta-data set docker-compose-plugin-built-image-tag-myservice-1 my.repository/llamas:test-myservice-build-1 : echo set image metadata for myservice-1" \ + "meta-data set docker-compose-plugin-built-image-tag-myservice-2 my.repository/llamas:test-myservice-build-1 : echo set image metadata for myservice-2" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "pushed myservice" + assert_output --partial "set image metadata for myservice" + assert_output --partial "set image metadata for myservice-1" + assert_output --partial "set image metadata for myservice-2" + unstub docker + unstub buildkite-agent +} + +@test "Build with a repository and push retries" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_REPOSITORY=my.repository/llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PUSH_RETRIES=3 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml push myservice : exit 1" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml push myservice : exit 1" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml push myservice : echo pushed myservice" \ + + stub buildkite-agent \ + "meta-data set docker-compose-plugin-built-image-tag-myservice my.repository/llamas:test-myservice-build-1 : echo set image metadata for myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "pushed myservice" + assert_output --partial "set image metadata for myservice" + unstub docker + unstub buildkite-agent +} + +@test "Build with a repository and custom config file" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG=tests/composefiles/docker-compose.v2.0.yml + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_REPOSITORY=my.repository/llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull myservice : echo built myservice" \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml push myservice : echo pushed myservice" \ + + stub buildkite-agent \ + "meta-data set docker-compose-plugin-built-image-tag-myservice-tests/composefiles/docker-compose.v2.0.yml my.repository/llamas:test-myservice-build-1 : echo set image metadata for myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "pushed myservice" + assert_output --partial "set image metadata for myservice" + unstub docker + unstub buildkite-agent +} + +@test "Build with a repository and multiple custom config files" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG_0=tests/composefiles/docker-compose.v2.0.yml + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG_1=tests/composefiles/docker-compose.v2.1.yml + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_REPOSITORY=my.repository/llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -f tests/composefiles/docker-compose.v2.1.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull myservice : echo built myservice" \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -f tests/composefiles/docker-compose.v2.1.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml push myservice : echo pushed myservice" \ + + stub buildkite-agent \ + "meta-data set docker-compose-plugin-built-image-tag-myservice-tests/composefiles/docker-compose.v2.0.yml-tests/composefiles/docker-compose.v2.1.yml my.repository/llamas:test-myservice-build-1 : echo set image metadata for myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "pushed myservice" + assert_output --partial "set image metadata for myservice" + unstub docker + unstub buildkite-agent +} + +@test "Build with a repository and multiple services" { + export BUILDKITE_JOB_ID=1112 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=myservice1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_1=myservice2 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_REPOSITORY=my.repository/llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1112 -f docker-compose.buildkite-1-override.yml build --pull myservice1 myservice2 : echo built all services" \ + "compose -f docker-compose.yml -p buildkite1112 -f docker-compose.buildkite-1-override.yml push myservice1 myservice2 : echo pushed all services" \ + + stub buildkite-agent \ + "meta-data set docker-compose-plugin-built-image-tag-myservice1 my.repository/llamas:test-myservice1-build-1 : echo set image metadata for myservice1" \ + "meta-data set docker-compose-plugin-built-image-tag-myservice2 my.repository/llamas:test-myservice2-build-1 : echo set image metadata for myservice2" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built all services" + assert_output --partial "pushed all services" + assert_output --partial "set image metadata for myservice1" + assert_output --partial "set image metadata for myservice2" + unstub docker + unstub buildkite-agent +} + +@test "Build with a docker-compose v1.0 configuration file" { + export BUILDKITE_JOB_ID=1112 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG="tests/composefiles/docker-compose.v1.0.yml" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=helloworld + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + run $PWD/hooks/command + + assert_failure + assert_output --partial "Compose file versions 2.0 and above" +} + +@test "Build with a cache-from image" { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG="tests/composefiles/docker-compose.v3.2.yml" + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=helloworld + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CACHE_FROM_0=helloworld:my.repository/myservice_cache:latest + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "pull my.repository/myservice_cache:latest : echo pulled cache image" \ + "compose -f tests/composefiles/docker-compose.v3.2.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull helloworld : echo built helloworld" + + run $PWD/hooks/command + + assert_success + assert_output --partial "pulled cache image" + assert_output --partial "- my.repository/myservice_cache:latest" + assert_output --partial "built helloworld" + unstub docker +} + +@test "Build with a cache-from image with no-cache also set" { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG="tests/composefiles/docker-compose.v3.2.yml" + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=helloworld + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CACHE_FROM_0=helloworld:my.repository/myservice_cache:latest + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_NO_CACHE=true + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f tests/composefiles/docker-compose.v3.2.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull --no-cache helloworld : echo built helloworld" + + run $PWD/hooks/command + + assert_success + refute_output --partial "pulled cache image" + refute_output --partial "- my.repository/myservice_cache:latest" + assert_output --partial "built helloworld" + unstub docker +} + +@test "Build with several cache-from images for one service" { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG="tests/composefiles/docker-compose.v3.2.yml" + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=helloworld + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CACHE_FROM_0=helloworld:my.repository/myservice_cache:branch-name + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CACHE_FROM_1=helloworld:my.repository/myservice_cache:latest + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "pull my.repository/myservice_cache:branch-name : echo pulled cache image" \ + "compose -f tests/composefiles/docker-compose.v3.2.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull helloworld : echo built helloworld" + + run $PWD/hooks/command + + assert_success + assert_output --partial "pulled cache image" + assert_output --partial "- my.repository/myservice_cache:branch-name" + refute_output --partial "- my.repository/myservice_cache:latest" + assert_output --partial "built helloworld" + unstub docker +} + +@test "Build with several cache-from images for one service with first image being not available" { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG="tests/composefiles/docker-compose.v3.2.yml" + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=helloworld + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CACHE_FROM_0=helloworld:my.repository/myservice_cache:branch-name + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CACHE_FROM_1=helloworld:my.repository/myservice_cache:latest + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "pull my.repository/myservice_cache:branch-name : exit 1" \ + "pull my.repository/myservice_cache:latest : echo pulled cache image" \ + "compose -f tests/composefiles/docker-compose.v3.2.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull helloworld : echo built helloworld" + + run $PWD/hooks/command + + assert_success + assert_output --partial "pulled cache image" + refute_output --partial "- my.repository/myservice_cache:branch-name" + assert_output --partial "- my.repository/myservice_cache:latest" + assert_output --partial "built helloworld" + unstub docker +} + +@test "Build with a cache-from image when pulling of the cache-from image failed" { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG="tests/composefiles/docker-compose.v3.2.yml" + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=helloworld + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CACHE_FROM_0=helloworld:my.repository/myservice_cache:latest + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "pull my.repository/myservice_cache:latest : exit 1" \ + "compose -f tests/composefiles/docker-compose.v3.2.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull helloworld : echo built helloworld" + + run $PWD/hooks/command + + assert_success + assert_output --partial "my.repository/myservice_cache:latest will not be used as a cache for helloworld" + refute_output --partial "- my.repository/myservice_cache:latest" + assert_output --partial "built helloworld" + unstub docker +} + +@test "Build with a cache-from image with hyphen" { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG="tests/composefiles/docker-compose.v3.2.yml" + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=hello-world + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CACHE_FROM_0=hello-world:my.repository/my-service_cache:latest + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "pull my.repository/my-service_cache:latest : echo pulled cache image" \ + "compose -f tests/composefiles/docker-compose.v3.2.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull hello-world : echo built hello-world" + + run $PWD/hooks/command + + assert_success + assert_output --partial "pulled cache image" + assert_output --partial "- my.repository/my-service_cache:latest" + assert_output --partial "built hello-world" + unstub docker +} + +@test "Build with a cache-from image retry on failing pull" { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG="tests/composefiles/docker-compose.v3.2.yml" + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=helloworld + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CACHE_FROM_0=helloworld:my.repository/myservice_cache:latest + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PULL_RETRIES=3 + + stub docker \ + "pull my.repository/myservice_cache:latest : exit 1" \ + "pull my.repository/myservice_cache:latest : exit 1" \ + "pull my.repository/myservice_cache:latest : echo pulled cache image" \ + "compose -f tests/composefiles/docker-compose.v3.2.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull helloworld : echo built helloworld" + + run $PWD/hooks/command + + assert_success + assert_output --partial "pulled cache image" + assert_output --partial "- my.repository/myservice_cache:latest" + assert_output --partial "built helloworld" + unstub docker +} + +@test "Build with a custom image-name" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_NAME=my-llamas-image + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_REPOSITORY=my.repository/llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml push myservice : echo pushed myservice" \ + + stub buildkite-agent \ + "meta-data set docker-compose-plugin-built-image-tag-myservice my.repository/llamas:my-llamas-image : echo set image metadata for myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "pushed myservice" + assert_output --partial "set image metadata for myservice" + unstub docker + unstub buildkite-agent +} + +@test "Build with a custom image-name and a config" { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG="tests/composefiles/docker-compose.v3.2.yml" + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_NAME=my-llamas-image + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_REPOSITORY=my.repository/llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f tests/composefiles/docker-compose.v3.2.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml build --pull myservice : echo built myservice" \ + "compose -f tests/composefiles/docker-compose.v3.2.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml push myservice : echo pushed myservice" \ + + stub buildkite-agent \ + "meta-data set docker-compose-plugin-built-image-tag-myservice-tests/composefiles/docker-compose.v3.2.yml my.repository/llamas:my-llamas-image : echo set image metadata for myservice" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "pushed myservice" + assert_output --partial "set image metadata for myservice" + unstub docker + unstub buildkite-agent +} + +@test "Build multiple images with custom image-names" { + export BUILDKITE_JOB_ID=1112 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_0=myservice1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_1=myservice2 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_NAME_0=my-llamas-image-1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_NAME_1=my-llamas-image-2 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_IMAGE_REPOSITORY=my.repository/llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1112 -f docker-compose.buildkite-1-override.yml build --pull myservice1 myservice2 : echo built all services" \ + "compose -f docker-compose.yml -p buildkite1112 -f docker-compose.buildkite-1-override.yml push myservice1 myservice2 : echo pushed all services" \ + + stub buildkite-agent \ + "meta-data set docker-compose-plugin-built-image-tag-myservice1 my.repository/llamas:my-llamas-image-1 : echo set image metadata for myservice1" \ + "meta-data set docker-compose-plugin-built-image-tag-myservice2 my.repository/llamas:my-llamas-image-2 : echo set image metadata for myservice2" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built all services" + assert_output --partial "pushed all services" + assert_output --partial "set image metadata for myservice1" + assert_output --partial "set image metadata for myservice2" + unstub docker + unstub buildkite-agent +} diff --git a/tests/v2/push.bats b/tests/v2/push.bats new file mode 100644 index 00000000..6aaf4099 --- /dev/null +++ b/tests/v2/push.bats @@ -0,0 +1,168 @@ +#!/usr/bin/env bats + +load '/usr/local/lib/bats/load.bash' +load '../../lib/shared' + +# export DOCKER_COMPOSE_STUB_DEBUG=/dev/tty +# export DOCKER_STUB_DEBUG=/dev/tty +# export BUILDKITE_AGENT_STUB_DEBUG=/dev/tty +# export BATS_MOCK_TMPDIR=$PWD + +setup_file() { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLI_VERSION=2 +} + +@test "Push a single service with an image in it's config" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PUSH=app + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-app : exit 1" + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 config : cat $PWD/tests/composefiles/docker-compose.config.v3.2.yml" \ + "image inspect somewhere.dkr.ecr.some-region.amazonaws.com/blah : exit 0" \ + "compose -f docker-compose.yml -p buildkite1111 push app : echo pushed app" + + run $PWD/hooks/command + + assert_success + assert_output --partial ":warning: Skipping build" + assert_output --partial "pushed app" + unstub docker + unstub buildkite-agent +} + +@test "Push two services with target repositories and tags" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PUSH_0=myservice1:my.repository/myservice1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PUSH_1=myservice2:my.repository/myservice2:llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 config : echo blah " \ + "image inspect buildkite1111_myservice1 : exit 1" \ + "compose -f docker-compose.yml -p buildkite1111 build myservice1 : echo blah " \ + "tag buildkite1111_myservice1 my.repository/myservice1 : echo tagging image1" \ + "push my.repository/myservice1 : echo pushing myservice1 image" \ + "compose -f docker-compose.yml -p buildkite1111 config : echo blah " \ + "image inspect buildkite1111_myservice2 : exit 1" \ + "compose -f docker-compose.yml -p buildkite1111 build myservice2 : echo blah " \ + "tag buildkite1111_myservice2 my.repository/myservice2:llamas : echo tagging image2" \ + "push my.repository/myservice2:llamas : echo pushing myservice2 image" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice1 : exit 1" \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice2 : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "tagging image1" + assert_output --partial "pushing myservice1 image" + assert_output --partial "tagging image2" + assert_output --partial "pushing myservice2 image" + unstub docker + unstub buildkite-agent +} + +@test "Push a prebuilt image with a repository and a tag" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PUSH=myservice:my.repository/myservice:llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 config : echo blah" \ + "pull myimage : echo pulled prebuilt image" \ + "tag myimage buildkite1111_myservice : echo " \ + "tag buildkite1111_myservice my.repository/myservice:llamas : echo tagged image" \ + "push my.repository/myservice:llamas : echo pushed myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "pulled prebuilt image" + assert_output --partial "tagged image" + assert_output --partial "pushed myservice" + unstub docker + unstub buildkite-agent +} + +@test "Push a prebuilt image to multiple tags" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PUSH_0=myservice:my.repository/myservice:llamas + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PUSH_1=myservice:my.repository/myservice:latest + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PUSH_2=myservice:my.repository/myservice:alpacas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 config : echo blah" \ + "pull prebuilt : echo pulled prebuilt image" \ + "tag prebuilt buildkite1111_myservice : echo " \ + "tag buildkite1111_myservice my.repository/myservice:llamas : echo tagged image1" \ + "push my.repository/myservice:llamas : echo pushed myservice1" \ + "compose -f docker-compose.yml -p buildkite1111 config : echo blah" \ + "tag prebuilt buildkite1111_myservice : echo " \ + "tag buildkite1111_myservice my.repository/myservice:latest : echo tagged image2" \ + "push my.repository/myservice:latest : echo pushed myservice2" \ + "compose -f docker-compose.yml -p buildkite1111 config : echo blah" \ + "tag prebuilt buildkite1111_myservice : echo " \ + "tag buildkite1111_myservice my.repository/myservice:alpacas : echo tagged image3" \ + "push my.repository/myservice:alpacas : echo pushed myservice3" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo prebuilt" \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo prebuilt" \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo prebuilt" + + run $PWD/hooks/command + + assert_success + assert_output --partial "pulled prebuilt image" + assert_output --partial "tagged image1" + assert_output --partial "pushed myservice1" + assert_output --partial "tagged image2" + assert_output --partial "pushed myservice2" + assert_output --partial "tagged image3" + assert_output --partial "pushed myservice3" + unstub docker + unstub buildkite-agent +} + +@test "Push a single service that needs to be built" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PUSH=helper:my.repository/helper:llamas + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-helper : exit 1" + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 config : cat $PWD/tests/composefiles/docker-compose.config.v3.2.yml" \ + "image inspect buildkite1111_helper : exit 1" \ + "compose -f docker-compose.yml -p buildkite1111 build helper : echo built helper" \ + "tag buildkite1111_helper my.repository/helper:llamas : echo tagged helper" \ + "push my.repository/helper:llamas : echo pushed helper" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built helper" + assert_output --partial "tagged helper" + assert_output --partial "pushed helper" + unstub docker + unstub buildkite-agent +} diff --git a/tests/v2/run.bats b/tests/v2/run.bats new file mode 100644 index 00000000..5d28fae0 --- /dev/null +++ b/tests/v2/run.bats @@ -0,0 +1,973 @@ +#!/usr/bin/env bats + +load '/usr/local/lib/bats/load.bash' +load '../../lib/shared' +load '../../lib/run' + +# export DOCKER_COMPOSE_STUB_DEBUG=/dev/tty +# export BUILDKITE_AGENT_STUB_DEBUG=/dev/tty +# export BATS_MOCK_TMPDIR=$PWD + +setup_file() { + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLI_VERSION=2 +} + +@test "Run without a prebuilt image" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="echo hello world" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'echo hello world' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image and an empty command" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image and a custom workdir" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_WORKDIR=/test_workdir + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --workdir=/test_workdir --rm myservice : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image with a quoted command" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="sh -c 'echo hello world'" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c $'sh -c \'echo hello world\'' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image with a multi-line command" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="cmd1 +cmd2 +cmd3" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c $'cmd1\ncmd2\ncmd3' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image with a command config" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_COMMAND_0=echo + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_COMMAND_1="hello world" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice echo 'hello world' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image with custom env" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ENV_0=MYENV=0 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ENV_1=MYENV + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ENVIRONMENT_0=MYENV=2 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ENVIRONMENT_1=MYENV + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ENVIRONMENT_2=ANOTHER="this is a long string with spaces; and semi-colons" + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 -e MYENV=0 -e MYENV -e MYENV=2 -e MYENV -e ANOTHER=this\ is\ a\ long\ string\ with\ spaces\;\ and\ semi-colons --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image with no-cache" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_NO_CACHE=true + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="echo hello world" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull --no-cache myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'echo hello world' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image with build args" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ARGS_0=MYARG=0 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ARGS_1=MYARG=1 + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="echo hello world" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull --build-arg MYARG=0 --build-arg MYARG=1 myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'echo hello world' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with a prebuilt image" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with a prebuilt image and custom config file" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG=tests/composefiles/docker-compose.v2.0.yml + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice-tests/composefiles/docker-compose.v2.0.yml : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice-tests/composefiles/docker-compose.v2.0.yml : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with a prebuilt image and multiple custom config files" { +export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG_0=tests/composefiles/docker-compose.v2.0.yml + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG_1=tests/composefiles/docker-compose.v2.1.yml + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -f tests/composefiles/docker-compose.v2.1.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -f tests/composefiles/docker-compose.v2.1.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 : echo pulled myservice" \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -f tests/composefiles/docker-compose.v2.1.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice-tests/composefiles/docker-compose.v2.0.yml-tests/composefiles/docker-compose.v2.1.yml : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice-tests/composefiles/docker-compose.v2.0.yml-tests/composefiles/docker-compose.v2.1.yml : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with a prebuilt image and custom config file set from COMPOSE_FILE" { + export COMPOSE_FILE=tests/composefiles/docker-compose.v2.0.yml + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f tests/composefiles/docker-compose.v2.0.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice-tests/composefiles/docker-compose.v2.0.yml : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice-tests/composefiles/docker-compose.v2.0.yml : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with a single prebuilt image, no retry on failed pull" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : exit 2" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_failure + assert_output --partial "Exited with 2" + unstub docker + unstub buildkite-agent +} + +@test "Run with a single prebuilt image, retry on failed pull" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PULL_RETRIES=3 + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : exit 2" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "pulled myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a TTY" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_TTY=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 -T --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice without tty" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice without tty" + unstub docker + unstub buildkite-agent +} + +@test "Run without dependencies" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_DEPENDENCIES=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 --no-deps --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice without dependencies" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice without dependencies" + unstub docker + unstub buildkite-agent +} + +@test "Run without ansi output" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ANSI=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml --no-ansi run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice without ansi output" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice without ansi output" + unstub docker + unstub buildkite-agent +} + +@test "Run with use aliases" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_USE_ALIASES=true + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 --use-aliases --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice with use aliases output" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice with use aliases output" + unstub docker + unstub buildkite-agent +} + +@test "Run with a volumes option" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_VOLUMES_0="./dist:/app/dist" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_VOLUMES_1="./pkg:/app/pkg" + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 -v $PWD/dist:/app/dist -v $PWD/pkg:/app/pkg --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice with volumes" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice with volumes" + unstub docker + unstub buildkite-agent +} + +@test "Run with an external volume" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_VOLUMES="buildkite:/buildkite" + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 -v buildkite:/buildkite --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice with volumes" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice with volumes" + unstub docker + unstub buildkite-agent +} + +@test "Run with default volumes, extra delimiters" { + # Tests introduction of extra delimiters, as would occur if + # EXPORT BUILDKITE_DOCKER_DEFAULT_VOLUMES="new:mount; ${BUILDKITE_DOCKER_DEFAULT_VOLUMES:-}" + # was used with no existing value + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_DOCKER_DEFAULT_VOLUMES="buildkite:/buildkite; ./dist:/app/dist;; ; ;" + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 -v buildkite:/buildkite -v $PWD/dist:/app/dist --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice with volumes" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice with volumes" + unstub docker + unstub buildkite-agent +} + +@test "Run with default volumes" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_DOCKER_DEFAULT_VOLUMES="buildkite:/buildkite;./dist:/app/dist" + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 -v buildkite:/buildkite -v $PWD/dist:/app/dist --rm myservice /bin/sh -e -c 'pwd' : echo ran myservice with volumes" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice with volumes" + unstub docker + unstub buildkite-agent +} + +@test "Run with multiple config files" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="echo hello world" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG_0="llamas1.yml" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG_1="llamas2.yml" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG_2="llamas3.yml" + + stub docker \ + "compose -f llamas1.yml -f llamas2.yml -f llamas3.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f llamas1.yml -f llamas2.yml -f llamas3.yml -p buildkite1111 up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f llamas1.yml -f llamas2.yml -f llamas3.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'echo hello world' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice-llamas1.yml-llamas2.yml-llamas3.yml : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with a failure should expand previous group" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'pwd' : exit 2" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_failure + assert_output --partial "^^^ +++" + assert_output --partial "Failed to run command, exited with 2" + unstub docker + unstub buildkite-agent +} + +@test "Run with multiple prebuilt images and multiple pulls" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PULL_0=myservice1 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PULL_1=myservice2 + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull --parallel myservice1 myservice2 : echo pulled myservice1 and myservice2" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice1=0 myservice1 : echo started dependencies for myservice1" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice1_build_1 --rm myservice1 /bin/sh -e -c 'pwd' : echo ran myservice1" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice1 : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice1 : echo myimage1" \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice2 : exit 0" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice2 : echo myimage2" + + run $PWD/hooks/command + + assert_success + assert_output --partial "pulled myservice1 and myservice2" + assert_output --partial "ran myservice1" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image and a custom user" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="sh -c 'whoami'" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_USER="1000" + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --user=1000 --rm myservice /bin/sh -e -c $'sh -c \'whoami\'' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run without a prebuilt image and a custom user and group" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="sh -c 'whoami'" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_USER="1000:1001" + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --user=1000:1001 --rm myservice /bin/sh -e -c $'sh -c \'whoami\'' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Fail with custom user and propagate UIDs" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="sh -c 'whoami'" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_USER="1000:1001" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_PROPAGATE_UID_GID="true" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_failure + assert_output --partial "Error" + assert_output --partial "Can't set both user and propagate-uid-gid" + unstub buildkite-agent +} + + +@test "Run without --rm" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND=pwd + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RM=false + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml pull myservice : echo pulled myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml up -d --scale myservice=0 myservice : echo started dependencies for myservice" \ + "compose -f docker-compose.yml -p buildkite1111 -f docker-compose.buildkite-1-override.yml run --name buildkite1111_myservice_build_1 myservice /bin/sh -e -c $'pwd' : echo ran myservice without tty" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : echo myimage" \ + "meta-data get docker-compose-plugin-built-image-tag-myservice : echo myimage" + + run $PWD/hooks/command + + assert_success + assert_output --partial "ran myservice without tty" + unstub docker + unstub buildkite-agent +} + +@test "Run with custom entrypoint" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_ENTRYPOINT="my custom entrypoint" + + ENTRYPOINT='--entrypoint\ \"my\ custom\ entrypoint\"' + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm --entrypoint 'my custom entrypoint' myservice : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with mount-buildkite-agent enabled" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_MOUNT_BUILDKITE_AGENT=true + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm -e BUILDKITE_JOB_ID -e BUILDKITE_BUILD_ID -e BUILDKITE_AGENT_ACCESS_TOKEN -v $BATS_MOCK_TMPDIR/bin/buildkite-agent:/usr/bin/buildkite-agent myservice : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with various build arguments" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="echo hello world" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_NO_CACHE=true + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_BUILD_PARALLEL=true + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull --no-cache --parallel myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm myservice /bin/sh -e -c 'echo hello world' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with git-mirrors" { + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="echo hello world" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_REPO_MIRROR=/tmp/sample-mirror + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 -v /tmp/sample-mirror:/tmp/sample-mirror:ro --rm myservice /bin/sh -e -c 'echo hello world' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + run $PWD/hooks/command + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +} + +@test "Run with mount-ssh-agent" { + export SSH_AUTH_SOCK=/tmp/ssh_auth_sock + export BUILDKITE_JOB_ID=1111 + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_RUN=myservice + export BUILDKITE_PIPELINE_SLUG=test + export BUILDKITE_BUILD_NUMBER=1 + export BUILDKITE_COMMAND="echo hello world" + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CHECK_LINKED_CONTAINERS=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_CLEANUP=false + export BUILDKITE_PLUGIN_DOCKER_COMPOSE_MOUNT_SSH_AGENT=true + + stub docker \ + "compose -f docker-compose.yml -p buildkite1111 build --pull myservice : echo built myservice" \ + "compose -f docker-compose.yml -p buildkite1111 up -d --scale myservice=0 : echo ran myservice dependencies" \ + "compose -f docker-compose.yml -p buildkite1111 run --name buildkite1111_myservice_build_1 --rm -e SSH_AUTH_SOCK=/ssh-agent -v /tmp/ssh_auth_sock:/ssh-agent -v /root/.ssh/known_hosts:/root/.ssh/known_hosts myservice /bin/sh -e -c 'echo hello world' : echo ran myservice" + + stub buildkite-agent \ + "meta-data exists docker-compose-plugin-built-image-tag-myservice : exit 1" + + apk add netcat-openbsd + nc -lkvU $SSH_AUTH_SOCK & + + run $PWD/hooks/command + + kill %1 + + assert_success + assert_output --partial "built myservice" + assert_output --partial "ran myservice" + unstub docker + unstub buildkite-agent +}