From 35b4b456a2584cf0d6f33d630a478a73bd255a4b Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 26 Jul 2025 22:59:25 +0300 Subject: [PATCH 01/13] ci: Implement comprehensive CI/CD pipeline This commit introduces a robust CI/CD pipeline using GitHub Actions, consolidating linting and testing into a single workflow. It also adds configuration for code coverage reporting. Key changes: - **New `ci.yml` Workflow:** A new `ci.yml` workflow replaces the old `linting.yml`. This new workflow includes jobs for: - **Linting:** Running `ruff` to check code style and formatting. - **Testing:** Building Docker containers, running the test suite with `coverage`, and uploading the results to Codecov. - **Coverage Configuration:** A `.coveragerc` file has been added to configure the source files for coverage analysis and to exclude irrelevant files like tests and migrations. - **README Update:** The `README.md` has been updated to include a Codecov badge and reflect the new `CI/CD` workflow name. - **Test Refinement:** Removed redundant assertions from `TestUserPromoFeed` that checked for the absence of `promo_common` and `promo_unique` fields, as this is handled by the serializer. --- .github/workflows/ci.yml | 74 +++++++++++++++++++ .github/workflows/linting.yml | 28 ------- README.md | 3 +- promo_code/.coveragerc | 12 +++ .../user/tests/user/operations/test_feed.py | 7 +- 5 files changed, 89 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/linting.yml create mode 100644 promo_code/.coveragerc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..dc82806 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,74 @@ +name: CI/CD + +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] + workflow_dispatch: + +jobs: + lint: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.13"] + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: pip install ruff + + - name: Run Ruff Linter + uses: astral-sh/ruff-action@v3.2.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Run Ruff Formatter Check + run: ruff format --check + + test: + runs-on: ubuntu-latest + needs: lint + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Create .env file for Docker + run: | + echo "DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0" >> .env + echo "DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }}" >> .env + + echo "POSTGRES_DATABASE=${{ secrets.POSTGRES_DATABASE }}" >> .env + echo "POSTGRES_USERNAME=${{ secrets.POSTGRES_USERNAME }}" >> .env + echo "POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}" >> .env + + echo "ANTIFRAUD_INTERNAL_PORT=8081" >> .env + echo "ANTIFRAUD_EXTERNAL_PORT=8081" >> .env + echo "ANTIFRAUD_CACHE_MS=1000" >> .env + + + - name: Build and run Docker containers + run: docker-compose up -d --build + + - name: Wait for services to be healthy + run: | + echo "Waiting for PostgreSQL..." + sleep 20 + + - name: Run tests and generate coverage report 🛡️ + run: > + docker-compose exec -T web sh -c + "coverage run manage.py test && coverage xml" + + - name: Upload coverage to Codecov 🚀 + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml deleted file mode 100644 index 6ade1f9..0000000 --- a/.github/workflows/linting.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Linting -on: - push: - branches: [main, develop] - pull_request: - branches: [main, develop] - workflow_dispatch: - -jobs: - lint: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.13"] - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - - name: Run Ruff via Action - uses: astral-sh/ruff-action@v3.2.2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - - run: ruff format --check diff --git a/README.md b/README.md index efa130b..5faed58 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Promo Code API -[![Linting](https://github.com/RandomProgramm3r/Promo-Code-API/actions/workflows/linting.yml/badge.svg)](https://github.com/RandomProgramm3r/Promo-Code-API/actions) +[![CI/CD](https://github.com/RandomProgramm3r/Promo-Code-API/actions/workflows/linting.yml/badge.svg)](https://github.com/RandomProgramm3r/Promo-Code-API/actions) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) +[![codecov](https://codecov.io/gh/YourUsername/YourRepo/graph/badge.svg?token=YOUR_TOKEN)](https://codecov.io/gh/YourUsername/YourRepo) The application provides an HTTP API for companies and end-users, is integrated with an external anti-fraud service, and uses PostgreSQL and Redis for data storage and caching. diff --git a/promo_code/.coveragerc b/promo_code/.coveragerc new file mode 100644 index 0000000..b306ead --- /dev/null +++ b/promo_code/.coveragerc @@ -0,0 +1,12 @@ +[run] +source = business, promo_code, user, core +omit = + settings.py + */tests/* + */migrations/* + */__init__.py + manage.py + */apps.py + */urls.py + */wsgi.py + */asgi.py diff --git a/promo_code/user/tests/user/operations/test_feed.py b/promo_code/user/tests/user/operations/test_feed.py index 898704a..fe9df74 100644 --- a/promo_code/user/tests/user/operations/test_feed.py +++ b/promo_code/user/tests/user/operations/test_feed.py @@ -442,9 +442,6 @@ def test_user3_lu_40_get_all_promos_pagination_offset10_limit2(self): response.status_code, rest_framework.status.HTTP_200_OK, ) - for item in response.data: - self.assertNotIn('promo_common', item) - self.assertNotIn('promo_unique', item) self.assertEqual(response['X-Total-Count'], '6') self.assertEqual(response.data, []) @@ -619,9 +616,7 @@ def test_user3_lu_40_get_promos_by_non_existent_category(self): response.status_code, rest_framework.status.HTTP_200_OK, ) - for item in response.data: - self.assertNotIn('promo_common', item) - self.assertNotIn('promo_unique', item) + self.assertEqual(response['X-Total-Count'], '0') self.assertEqual(response.data, []) From 6ff88eb5b4387b9900dc47a832b9b8ee3c53c4c5 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 26 Jul 2025 23:01:38 +0300 Subject: [PATCH 02/13] docs: Add Codecov badge URL in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5faed58..5824957 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![CI/CD](https://github.com/RandomProgramm3r/Promo-Code-API/actions/workflows/linting.yml/badge.svg)](https://github.com/RandomProgramm3r/Promo-Code-API/actions) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) -[![codecov](https://codecov.io/gh/YourUsername/YourRepo/graph/badge.svg?token=YOUR_TOKEN)](https://codecov.io/gh/YourUsername/YourRepo) +[![codecov](https://codecov.io/github/RandomProgramm3r/Promo-Code-API/graph/badge.svg?token=VNBK0FAU3Z)](https://codecov.io/github/RandomProgramm3r/Promo-Code-API) The application provides an HTTP API for companies and end-users, is integrated with an external anti-fraud service, and uses PostgreSQL and Redis for data storage and caching. From f7fbd1567d7d1ee660618d0115fa04bb9807aeb0 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 26 Jul 2025 23:07:31 +0300 Subject: [PATCH 03/13] ci: Add Docker Compose setup action to workflow This commit updates the `ci.yml` workflow to include the `docker/compose-action@v2`. This action ensures that Docker Compose and Buildx are properly set up and available for subsequent steps in the CI pipeline, improving the reliability of the build process. --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc82806..bb8ca7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,8 @@ jobs: echo "ANTIFRAUD_EXTERNAL_PORT=8081" >> .env echo "ANTIFRAUD_CACHE_MS=1000" >> .env + - name: Set up Docker Buildx & Compose + uses: docker/compose-action@v2 - name: Build and run Docker containers run: docker-compose up -d --build From 16d9670aae509af4e76a7128da42fc5085ee9ce6 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 26 Jul 2025 23:17:38 +0300 Subject: [PATCH 04/13] ci: Replace Docker Compose action with manual installation This commit modifies the `ci.yml` workflow to manually install the Docker Compose plugin using `apt-get`. This replaces the `docker/compose-action` and provides more direct control over the installed version. The new step updates the package list and installs `docker-compose-plugin`, ensuring that the `docker-compose` command is available for subsequent build and test steps. --- .github/workflows/ci.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb8ca7a..6fb437c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,8 +53,11 @@ jobs: echo "ANTIFRAUD_EXTERNAL_PORT=8081" >> .env echo "ANTIFRAUD_CACHE_MS=1000" >> .env - - name: Set up Docker Buildx & Compose - uses: docker/compose-action@v2 + - name: Install Docker Compose v1 + run: | + sudo apt-get update + sudo apt-get install -y docker-compose-plugin + docker-compose version - name: Build and run Docker containers run: docker-compose up -d --build From b148328b830b9095c6ea127f40439a66d5804c29 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 26 Jul 2025 23:23:14 +0300 Subject: [PATCH 05/13] ci: Update to Docker Compose V2 syntax This commit refactors the `ci.yml` workflow to use the modern Docker Compose V2 syntax (`docker compose` instead of `docker-compose`). The manual installation step for the Docker Compose plugin has been removed, as the GitHub Actions runner environment includes a compatible version of Docker Compose V2 by default. This simplifies the workflow and relies on the standard tooling provided by the runner. --- .github/workflows/ci.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6fb437c..0b18329 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,14 +53,8 @@ jobs: echo "ANTIFRAUD_EXTERNAL_PORT=8081" >> .env echo "ANTIFRAUD_CACHE_MS=1000" >> .env - - name: Install Docker Compose v1 - run: | - sudo apt-get update - sudo apt-get install -y docker-compose-plugin - docker-compose version - - name: Build and run Docker containers - run: docker-compose up -d --build + run: docker compose up -d --build - name: Wait for services to be healthy run: | @@ -69,7 +63,7 @@ jobs: - name: Run tests and generate coverage report 🛡️ run: > - docker-compose exec -T web sh -c + docker compose exec -T web sh -c "coverage run manage.py test && coverage xml" - name: Upload coverage to Codecov 🚀 From 9a57a964965b75987089d1698f4e64dfaa0d74a0 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 26 Jul 2025 23:39:07 +0300 Subject: [PATCH 06/13] ci: Align PostgreSQL environment variables with Docker image This commit updates the `ci.yml` workflow to use `POSTGRES_DB` and `POSTGRES_USER` instead of `POSTGRES_DATABASE` and `POSTGRES_USERNAME`. This change aligns the environment variable names with the official PostgreSQL Docker image, ensuring correct database initialization in the CI environment. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b18329..ae2e243 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,8 +45,8 @@ jobs: echo "DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0" >> .env echo "DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }}" >> .env - echo "POSTGRES_DATABASE=${{ secrets.POSTGRES_DATABASE }}" >> .env - echo "POSTGRES_USERNAME=${{ secrets.POSTGRES_USERNAME }}" >> .env + echo "POSTGRES_DB=${{ secrets.POSTGRES_DB }}" >> .env + echo "POSTGRES_USER=${{ secrets.POSTGRES_USER }}" >> .env echo "POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}" >> .env echo "ANTIFRAUD_INTERNAL_PORT=8081" >> .env From ac30d5b1b832de6f465ded84753358a8f2e09734 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 26 Jul 2025 23:50:52 +0300 Subject: [PATCH 07/13] ci: Revert PostgreSQL environment variable names This commit reverts the environment variable names for the PostgreSQL connection in the `ci.yml` workflow back to `POSTGRES_DATABASE` and `POSTGRES_USERNAME`. --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae2e243..8054dbe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,14 +45,15 @@ jobs: echo "DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0" >> .env echo "DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }}" >> .env - echo "POSTGRES_DB=${{ secrets.POSTGRES_DB }}" >> .env - echo "POSTGRES_USER=${{ secrets.POSTGRES_USER }}" >> .env + echo "POSTGRES_DATABASE=${{ secrets.POSTGRES_DB }}" >> .env # + echo "POSTGRES_USERNAME=${{ secrets.POSTGRES_USER }}" >> .env # echo "POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}" >> .env echo "ANTIFRAUD_INTERNAL_PORT=8081" >> .env echo "ANTIFRAUD_EXTERNAL_PORT=8081" >> .env echo "ANTIFRAUD_CACHE_MS=1000" >> .env + - name: Build and run Docker containers run: docker compose up -d --build From 96c12d16a06224f10676ccfb28d302c1a3c5df24 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 27 Jul 2025 00:01:34 +0300 Subject: [PATCH 08/13] ci: Add POSTGRES_HOST variable and debug step This commit updates the `ci.yml` workflow to explicitly set the `POSTGRES_HOST` environment variable to `db`. This ensures the web service can reliably connect to the PostgreSQL container. Additionally, a new step has been added to `cat` the `.env` file, providing better visibility into the environment configuration for debugging purposes. --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8054dbe..3d3aebb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,11 +48,13 @@ jobs: echo "POSTGRES_DATABASE=${{ secrets.POSTGRES_DB }}" >> .env # echo "POSTGRES_USERNAME=${{ secrets.POSTGRES_USER }}" >> .env # echo "POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}" >> .env - + echo "POSTGRES_HOST=db" >> .env + echo "ANTIFRAUD_INTERNAL_PORT=8081" >> .env echo "ANTIFRAUD_EXTERNAL_PORT=8081" >> .env echo "ANTIFRAUD_CACHE_MS=1000" >> .env - + - name: Debug .env file + run: cat .env - name: Build and run Docker containers run: docker compose up -d --build From 60afa4f9a5af7cf4e9c843d383e28f7824e2f4ea Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 27 Jul 2025 00:14:10 +0300 Subject: [PATCH 09/13] refactor: Add coverage to dependencies and clean up CI This commit moves the `coverage` package into the main production dependencies to ensure it is always available in the application environment. Key changes: **`requirements/prod.txt`:** Added `coverage` to the list of production requirements. - **`ci.yml`:** Removed the temporary debugging step that printed the `.env` file contents, as it is no longer needed. --- .github/workflows/ci.yml | 2 -- requirements/prod.txt | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d3aebb..4c6bc67 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,8 +53,6 @@ jobs: echo "ANTIFRAUD_INTERNAL_PORT=8081" >> .env echo "ANTIFRAUD_EXTERNAL_PORT=8081" >> .env echo "ANTIFRAUD_CACHE_MS=1000" >> .env - - name: Debug .env file - run: cat .env - name: Build and run Docker containers run: docker compose up -d --build diff --git a/requirements/prod.txt b/requirements/prod.txt index 18ecb42..4c0cc1c 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -9,3 +9,4 @@ pycountry==24.6.1 python-dotenv==1.0.1 requests==2.32.4 parameterized==0.9.0 +coverage==7.9.2 From 37ae2843227aecbff519e5073865bce7873b0664 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 27 Jul 2025 00:31:44 +0300 Subject: [PATCH 10/13] ci: Refactor .env file creation using heredoc This commit updates the `ci.yml` workflow to use a `heredoc` (`<> .env - echo "DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }}" >> .env - - echo "POSTGRES_DATABASE=${{ secrets.POSTGRES_DB }}" >> .env # - echo "POSTGRES_USERNAME=${{ secrets.POSTGRES_USER }}" >> .env # - echo "POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}" >> .env - echo "POSTGRES_HOST=db" >> .env - - echo "ANTIFRAUD_INTERNAL_PORT=8081" >> .env - echo "ANTIFRAUD_EXTERNAL_PORT=8081" >> .env - echo "ANTIFRAUD_CACHE_MS=1000" >> .env + cat <> .env + DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0 + DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }} + POSTGRES_DATABASE=${{ secrets.POSTGRES_DB }} + POSTGRES_USERNAME=${{ secrets.POSTGRES_USER }} + POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} + POSTGRES_HOST=db + ANTIFRAUD_INTERNAL_PORT=8081 + ANTIFRAUD_EXTERNAL_PORT=8081 + ANTIFRAUD_CACHE_MS=1000 + EOF - name: Build and run Docker containers run: docker compose up -d --build From 61198c2a03003e83db5b1ab8c7209dbd18daa392 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 27 Jul 2025 00:37:42 +0300 Subject: [PATCH 11/13] ci: Prevent shell expansion in heredoc This commit updates the `ci.yml` workflow by quoting the `heredoc` delimiter (`<<'EOF'`). This prevents the shell from interpreting `${{...}}` as a shell variable, ensuring that the GitHub Actions context is correctly used to populate the secrets. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb2f91c..9db90f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: - name: Create .env file for Docker run: | - cat <> .env + cat <<'EOF' >> .env DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0 DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }} POSTGRES_DATABASE=${{ secrets.POSTGRES_DB }} From 7d2967f0679a6b085a0df03798f7c2d11a6338b5 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 27 Jul 2025 00:41:25 +0300 Subject: [PATCH 12/13] fix(ci): Change directory before running coverage This commit updates the `ci.yml` workflow to change into the `promo_code` directory before executing the `coverage run` command. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9db90f6..6d4c1a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,7 @@ jobs: - name: Run tests and generate coverage report 🛡️ run: > docker compose exec -T web sh -c - "coverage run manage.py test && coverage xml" + "cd promo_code && coverage run manage.py test && coverage xml" - name: Upload coverage to Codecov 🚀 uses: codecov/codecov-action@v5 From d0735925a62c585ed17efc20ca01fdec50892e45 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 27 Jul 2025 00:47:06 +0300 Subject: [PATCH 13/13] ci: Update anti-fraud service configuration This commit updates the `ci.yml` workflow with new environment variables for the anti-fraud service. Key changes: - The `ANTIFRAUD_INTERNAL_PORT` and `ANTIFRAUD_EXTERNAL_PORT` have been changed to `9090`. - The `ANTIFRAUD_CACHE_MS` has been increased to `5000`. - A new `ANTIFRAUD_ADDRESS` variable has been added to provide the full service URL. --- .github/workflows/ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d4c1a1..e2d67a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,9 +49,10 @@ jobs: POSTGRES_USERNAME=${{ secrets.POSTGRES_USER }} POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} POSTGRES_HOST=db - ANTIFRAUD_INTERNAL_PORT=8081 - ANTIFRAUD_EXTERNAL_PORT=8081 - ANTIFRAUD_CACHE_MS=1000 + ANTIFRAUD_INTERNAL_PORT=9090 + ANTIFRAUD_EXTERNAL_PORT=9090 + ANTIFRAUD_CACHE_MS=5000 + ANTIFRAUD_ADDRESS=http://antifraud:9090 EOF - name: Build and run Docker containers