From dd73ece638a3acd1526d451b6a7b07d1b319026d Mon Sep 17 00:00:00 2001 From: Thibault Derousseaux Date: Tue, 17 Sep 2024 15:43:08 -0400 Subject: [PATCH] Finishing touch --- .github/workflows/deploy.yml | 13 ++++++------ .vscode/settings.json | 5 ++++- README.md | 2 +- pyproject.toml | 3 +-- .../station_information.json | 0 .../station_location.csv | 0 .../station_status.json | 0 tests/conftest.py | 6 +++--- tests/docker/_run_command.py | 9 ++++++++ tests/docker/conftest.py | 21 ++++++------------- 10 files changed, 30 insertions(+), 29 deletions(-) rename tests/{data => __resources__}/station_information.json (100%) rename tests/{data => __resources__}/station_location.csv (100%) rename tests/{data => __resources__}/station_status.json (100%) create mode 100644 tests/docker/_run_command.py diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index cbcfba9..73825ad 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,7 +4,6 @@ on: push: branches: - main - - update-to-0.9.0 permissions: id-token: write @@ -19,8 +18,8 @@ jobs: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ vars.AWS_DEPLOYMENT_ROLE }} aws-region: ${{ vars.AWS_REGION }} + role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ vars.AWS_DEPLOYMENT_ROLE }} - uses: aws-actions/amazon-ecr-login@v2 id: log-into-ecr - name: Build, tag, and push Docker image to Amazon ECR @@ -30,18 +29,18 @@ jobs: run: | docker build --tag $TAG . docker push $TAG - echo "image=$TAG" >> $GITHUB_OUTPUT + echo "tag=$TAG" >> $GITHUB_OUTPUT - name: Inline variables in the task definition run: sed -i -e 's/AWS_ACCOUNT_ID/${{ secrets.AWS_ACCOUNT_ID }}/g' -e 's/AWS_DATABASE_URL_SECRET_NAME/${{ vars.AWS_DATABASE_URL_SECRET_NAME }}/g' -e 's/AWS_EXECUTION_ROLE/${{ vars.AWS_EXECUTION_ROLE }}/g' -e 's/AWS_REGION/${{ vars.AWS_REGION }}/g' task-definition.json - uses: aws-actions/amazon-ecs-render-task-definition@v1 id: render-task-definition with: - task-definition: task-definition.json container-name: atoti-session - image: ${{ steps.build-tag-and-push-docker-image.outputs.image }} + image: ${{ steps.build-tag-and-push-docker-image.outputs.tag }} + task-definition: task-definition.json - uses: aws-actions/amazon-ecs-deploy-task-definition@v2 with: - task-definition: ${{ steps.render-task-definition.outputs.task-definition }} - service: atoti-project-template cluster: atoti-project-template + service: atoti-project-template + task-definition: ${{ steps.render-task-definition.outputs.task-definition }} wait-for-service-stability: true diff --git a/.vscode/settings.json b/.vscode/settings.json index 3313033..c8e54eb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,5 +16,8 @@ "python.analysis.autoImportCompletions": true, "python.languageServer": "Pylance", "python.testing.pytestEnabled": true, - "python.testing.unittestEnabled": false + "python.testing.unittestEnabled": false, + "yaml.schemas": { + "https://json.schemastore.org/github-workflow.json": "file:///Users/tibdex/repositories/project-template/.github/workflows/deploy.yml" + } } diff --git a/README.md b/README.md index f0fd20b..565b35a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This template can be used to start Atoti projects where the goal is to [go into On top of the `atoti` package, it comes with: - Dependency management with [uv](https://docs.astral.sh/uv) -- Config management with [Pydantic Settings](https://docs.pydantic.dev/2.6/concepts/pydantic_settings) +- Config management with [Pydantic](https://docs.pydantic.dev/2.6/concepts/pydantic_settings) - Testing with [pytest](https://docs.pytest.org) - Type checking with [mypy](http://mypy-lang.org) - Formatting and linting with [Ruff](https://docs.astral.sh/ruff) diff --git a/pyproject.toml b/pyproject.toml index 48b26dd..73bb0b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,8 +11,7 @@ dependencies = [ ] [tool.mypy] -# Remove once https://github.com/python/mypy/issues/10428 is fixed. -files = "app,tests" +files = "app,tests" # Remove once https://github.com/python/mypy/issues/10428 is fixed. strict = true warn_redundant_casts = true warn_unused_configs = true diff --git a/tests/data/station_information.json b/tests/__resources__/station_information.json similarity index 100% rename from tests/data/station_information.json rename to tests/__resources__/station_information.json diff --git a/tests/data/station_location.csv b/tests/__resources__/station_location.csv similarity index 100% rename from tests/data/station_location.csv rename to tests/__resources__/station_location.csv diff --git a/tests/data/station_status.json b/tests/__resources__/station_status.json similarity index 100% rename from tests/data/station_status.json rename to tests/__resources__/station_status.json diff --git a/tests/conftest.py b/tests/conftest.py index dbaeb72..2aeaabc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,7 +7,7 @@ from app import Config, start_app _TESTS_DIRECTORY = Path(__file__).parent -_TESTS_DATA_PATH = _TESTS_DIRECTORY / "data" +_TESTS_RESOURCES_DIRECTORY = _TESTS_DIRECTORY / "__resources__" _PROJECT_DIRECTORY = _TESTS_DIRECTORY.parent @@ -20,10 +20,10 @@ def project_name_fixture() -> str: def config_fixture() -> Config: return Config( data_refresh_period=None, - reverse_geocoding_path=_TESTS_DATA_PATH / "station_location.csv", + reverse_geocoding_path=_TESTS_RESOURCES_DIRECTORY / "station_location.csv", port=0, user_content_storage=None, - velib_data_base_path=_TESTS_DATA_PATH, + velib_data_base_path=_TESTS_RESOURCES_DIRECTORY, ) diff --git a/tests/docker/_run_command.py b/tests/docker/_run_command.py new file mode 100644 index 0000000..5297ad4 --- /dev/null +++ b/tests/docker/_run_command.py @@ -0,0 +1,9 @@ +from collections.abc import Mapping, Sequence +from subprocess import STDOUT, CalledProcessError, check_output + + +def run_command(args: Sequence[str], /, *, env: Mapping[str, str] | None = None) -> str: + try: + return check_output(args, env=env, stderr=STDOUT, text=True) # noqa: S603 + except CalledProcessError as error: + raise RuntimeError(f"Command `{error.cmd}` failed:\n{error.output}") from error diff --git a/tests/docker/conftest.py b/tests/docker/conftest.py index 83cd81a..9b0374e 100644 --- a/tests/docker/conftest.py +++ b/tests/docker/conftest.py @@ -1,27 +1,18 @@ -from collections.abc import Generator, Mapping, Sequence +from collections.abc import Generator from datetime import timedelta from pathlib import Path from shutil import which -from subprocess import STDOUT, CalledProcessError, check_output from uuid import uuid4 import atoti as tt import docker import pytest -from ._docker_container import docker_container as _docker_container +from ._docker_container import docker_container +from ._run_command import run_command from ._timeout import Timeout -def _run_command( - args: Sequence[str], /, *, env: Mapping[str, str] | None = None -) -> str: - try: - return check_output(args, env=env, stderr=STDOUT, text=True) # noqa: S603 - except CalledProcessError as error: - raise RuntimeError(f"Command `{error.cmd}` failed:\n{error.output}") from error - - @pytest.fixture(name="docker_bin", scope="session") def docker_bin_fixture() -> Path: docker_bin = which("docker") @@ -43,12 +34,12 @@ def docker_image_name_fixture( # BuildKit is enabled by default for all users on Docker Desktop. # See https://docs.docker.com/build/buildkit/#getting-started. is_buildkit_already_enabled = ( - "docker desktop" in _run_command([str(docker_bin), "version"]).lower() + "docker desktop" in run_command([str(docker_bin), "version"]).lower() ) # BuildKit is not supported by Docker's Python SDK so `docker_client.images.build` cannot be used. # See https://github.com/docker/docker-py/issues/2230. - output = _run_command( + output = run_command( [str(docker_bin), "build", "--tag", tag, "."], env=None if is_buildkit_already_enabled else {"DOCKER_BUILDKIT": "1"}, ) @@ -63,7 +54,7 @@ def session_inside_docker_container_fixture( ) -> Generator[tt.Session, None, None]: timeout = Timeout(timedelta(minutes=1)) - with _docker_container(docker_image_name, client=docker_client) as container: + with docker_container(docker_image_name, client=docker_client) as container: logs = container.logs(stream=True) while "Session listening on port" not in next(logs).decode():