From 60a542b94fb03e72b391312de418e58980f89fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 15 Oct 2019 10:28:33 -0500 Subject: [PATCH 1/3] :recycle: Refactor tests to use env vars, Travis matrix, and push dated tags --- .travis.yml | 23 +++++++-- docker-compose.build.yml | 20 -------- scripts/build-push-all.sh | 7 +++ scripts/build-push.sh | 10 ++-- scripts/process_all.py | 78 +++++++++++++++++++++++++++++ scripts/test-all.sh | 4 ++ scripts/test.sh | 4 +- tests/test_01_main/test_defaults.py | 38 +++----------- 8 files changed, 124 insertions(+), 60 deletions(-) delete mode 100644 docker-compose.build.yml create mode 100644 scripts/build-push-all.sh create mode 100644 scripts/process_all.py create mode 100644 scripts/test-all.sh diff --git a/.travis.yml b/.travis.yml index e7b57af..f48b8a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,11 +11,24 @@ install: services: - docker +env: + - NAME='latest' BUILD_PATH='python3.7' TEST_STR1='Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn (default)' + - NAME='python3.7' BUILD_PATH='python3.7' TEST_STR1='Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn (default)' + - NAME='python3.6' BUILD_PATH='python3.6' TEST_STR1='Hello World from Flask in a Docker container running Python 3.6 with Meinheld and Gunicorn (default)' + - NAME='python2.7' BUILD_PATH='python3.6' TEST_STR1='Hello World from Flask in a Docker container running Python 2.7 with Meinheld and Gunicorn (default)' + - NAME='python3.7-alpine3.8' BUILD_PATH='python3.7-alpine3.8' TEST_STR1='Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn on Alpine (default)' + - NAME='python3.6-alpine3.8' BUILD_PATH='python3.6-alpine3.8' TEST_STR1='Hello World from Flask in a Docker container running Python 3.6 with Meinheld and Gunicorn on Alpine (default)' + script: - bash scripts/test.sh -deploy: - provider: script - script: bash scripts/build-push.sh - on: - branch: master +jobs: + include: + - script: bash scripts/test.sh + - stage: deploy + script: skip + deploy: + provider: script + script: bash scripts/build-push-all.sh + on: + branch: master diff --git a/docker-compose.build.yml b/docker-compose.build.yml deleted file mode 100644 index 6c62ffd..0000000 --- a/docker-compose.build.yml +++ /dev/null @@ -1,20 +0,0 @@ -version: '3' -services: - latest: - build: ./python3.7 - image: tiangolo/meinheld-gunicorn-flask:latest - python2.7: - build: ./python2.7 - image: tiangolo/meinheld-gunicorn-flask:python2.7 - python3.6: - build: ./python3.6 - image: tiangolo/meinheld-gunicorn-flask:python3.6 - python3.6-alpine3.8: - build: ./python3.6-alpine3.8 - image: tiangolo/meinheld-gunicorn-flask:python3.6-alpine3.8 - python3.7: - build: ./python3.7 - image: tiangolo/meinheld-gunicorn-flask:python3.7 - python3.7-alpine3.8: - build: ./python3.7-alpine3.8 - image: tiangolo/meinheld-gunicorn-flask:python3.7-alpine3.8 diff --git a/scripts/build-push-all.sh b/scripts/build-push-all.sh new file mode 100644 index 0000000..e54d3f1 --- /dev/null +++ b/scripts/build-push-all.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -e + +echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + +BUILD_PUSH=1 python scripts/process_all.py diff --git a/scripts/build-push.sh b/scripts/build-push.sh index 7a00143..e1a1017 100644 --- a/scripts/build-push.sh +++ b/scripts/build-push.sh @@ -2,8 +2,12 @@ set -e -echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin +use_tag="tiangolo/meinheld-gunicorn-flask:$NAME" +use_dated_tag="${use_tag}-$(date -I)" -docker-compose -f docker-compose.build.yml build +docker build -t "$use_tag" "$BUILD_PATH" -docker-compose -f docker-compose.build.yml push +docker tag "$use_tag" "$use_dated_tag" + +docker push "$use_tag" +docker push "$use_dated_tag" diff --git a/scripts/process_all.py b/scripts/process_all.py new file mode 100644 index 0000000..f5ee799 --- /dev/null +++ b/scripts/process_all.py @@ -0,0 +1,78 @@ +import os +import subprocess +import sys + +environments = [ + { + "NAME": "latest", + "BUILD_PATH": "python3.7", + "TEST_STR1": "Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn (default)", + }, + { + "NAME": "python3.7", + "BUILD_PATH": "python3.7", + "TEST_STR1": "Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn (default)", + }, + { + "NAME": "python3.6", + "BUILD_PATH": "python3.6", + "TEST_STR1": "Hello World from Flask in a Docker container running Python 3.6 with Meinheld and Gunicorn (default)", + }, + { + "NAME": "python2.7", + "BUILD_PATH": "python2.7", + "TEST_STR1": "Hello World from Flask in a Docker container running Python 2.7 with Meinheld and Gunicorn (default)", + }, + { + "NAME": "python3.7-alpine3.8", + "BUILD_PATH": "python3.7-alpine3.8", + "TEST_STR1": "Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn on Alpine (default)", + }, + { + "NAME": "python3.6-alpine3.8", + "BUILD_PATH": "python3.6-alpine3.8", + "TEST_STR1": "Hello World from Flask in a Docker container running Python 3.6 with Meinheld and Gunicorn on Alpine (default)", + }, +] + +start_with = os.environ.get("START_WITH") +build_push = os.environ.get("BUILD_PUSH") + + +def process_tag(*, env: dict): + use_env = {**os.environ, **env} + script = "scripts/test.sh" + if build_push: + script = "scripts/build-push.sh" + return_code = subprocess.call(["bash", script], env=use_env) + if return_code != 0: + sys.exit(return_code) + + +def print_version_envs(): + env_lines = [] + for env in environments: + env_vars = [] + for key, value in env.items(): + env_vars.append(f"{key}='{value}'") + env_lines.append(" ".join(env_vars)) + for line in env_lines: + print(line) + + +def main(): + start_at = 0 + if start_with: + start_at = [ + i for i, env in enumerate((environments)) if env["NAME"] == start_with + ][0] + for i, env in enumerate(environments[start_at:]): + print(f"Processing tag: {env['NAME']}") + process_tag(env=env) + + +if __name__ == "__main__": + if len(sys.argv) > 1: + print_version_envs() + else: + main() diff --git a/scripts/test-all.sh b/scripts/test-all.sh new file mode 100644 index 0000000..89b34d3 --- /dev/null +++ b/scripts/test-all.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e + +python scripts/process_all.py diff --git a/scripts/test.sh b/scripts/test.sh index dfcc3a9..6efdb7f 100644 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash set -e -docker-compose -f docker-compose.build.yml build +use_tag="tiangolo/meinheld-gunicorn-flask:$NAME" + +docker build -t "$use_tag" "$BUILD_PATH" pytest tests diff --git a/tests/test_01_main/test_defaults.py b/tests/test_01_main/test_defaults.py index 4b66397..c7ffa8f 100644 --- a/tests/test_01_main/test_defaults.py +++ b/tests/test_01_main/test_defaults.py @@ -1,3 +1,4 @@ +import os import time import pytest @@ -28,46 +29,21 @@ def verify_container(container, response_text): assert response.text == response_text -@pytest.mark.parametrize( - "image,response_text", - [ - ( - "tiangolo/meinheld-gunicorn-flask:python2.7", - "Hello World from Flask in a Docker container running Python 2.7 with Meinheld and Gunicorn (default)", - ), - ( - "tiangolo/meinheld-gunicorn-flask:python3.6", - "Hello World from Flask in a Docker container running Python 3.6 with Meinheld and Gunicorn (default)", - ), - ( - "tiangolo/meinheld-gunicorn-flask:python3.7", - "Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn (default)", - ), - ( - "tiangolo/meinheld-gunicorn-flask:latest", - "Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn (default)", - ), - ( - "tiangolo/meinheld-gunicorn-flask:python3.6-alpine3.8", - "Hello World from Flask in a Docker container running Python 3.6 with Meinheld and Gunicorn on Alpine (default)", - ), - ( - "tiangolo/meinheld-gunicorn-flask:python3.7-alpine3.8", - "Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn on Alpine (default)", - ), - ], -) def test_defaults(image, response_text): + name = os.getenv("NAME") + image = f"tiangolo/meinheld-gunicorn-flask:{name}" + response_text = os.getenv("TEST_STR1") + sleep_time = int(os.getenv("SLEEP_TIME", 1)) remove_previous_container(client) container = client.containers.run( image, name=CONTAINER_NAME, ports={"80": "8000"}, detach=True ) - time.sleep(1) + time.sleep(sleep_time) verify_container(container, response_text) container.stop() # Test that everything works after restarting too container.start() - time.sleep(1) + time.sleep(sleep_time) verify_container(container, response_text) container.stop() container.remove() From a2cc8846c88d6208a76ce4e53da1efdbc21c5a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 15 Oct 2019 10:33:56 -0500 Subject: [PATCH 2/3] :bug: Remove unused pytest parameter --- tests/test_01_main/test_defaults.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_01_main/test_defaults.py b/tests/test_01_main/test_defaults.py index c7ffa8f..8529254 100644 --- a/tests/test_01_main/test_defaults.py +++ b/tests/test_01_main/test_defaults.py @@ -29,7 +29,7 @@ def verify_container(container, response_text): assert response.text == response_text -def test_defaults(image, response_text): +def test_defaults(): name = os.getenv("NAME") image = f"tiangolo/meinheld-gunicorn-flask:{name}" response_text = os.getenv("TEST_STR1") From c95165c9140a2cfe97d871255bcafa06eb390072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 15 Oct 2019 10:43:19 -0500 Subject: [PATCH 3/3] :bug: Fix build context in Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f48b8a8..95def74 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ env: - NAME='latest' BUILD_PATH='python3.7' TEST_STR1='Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn (default)' - NAME='python3.7' BUILD_PATH='python3.7' TEST_STR1='Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn (default)' - NAME='python3.6' BUILD_PATH='python3.6' TEST_STR1='Hello World from Flask in a Docker container running Python 3.6 with Meinheld and Gunicorn (default)' - - NAME='python2.7' BUILD_PATH='python3.6' TEST_STR1='Hello World from Flask in a Docker container running Python 2.7 with Meinheld and Gunicorn (default)' + - NAME='python2.7' BUILD_PATH='python2.7' TEST_STR1='Hello World from Flask in a Docker container running Python 2.7 with Meinheld and Gunicorn (default)' - NAME='python3.7-alpine3.8' BUILD_PATH='python3.7-alpine3.8' TEST_STR1='Hello World from Flask in a Docker container running Python 3.7 with Meinheld and Gunicorn on Alpine (default)' - NAME='python3.6-alpine3.8' BUILD_PATH='python3.6-alpine3.8' TEST_STR1='Hello World from Flask in a Docker container running Python 3.6 with Meinheld and Gunicorn on Alpine (default)'