From d63d2a4241df75533019fd79bafad6e103132808 Mon Sep 17 00:00:00 2001
From: Pavel Kirilin <win10@list.ru>
Date: Mon, 30 Aug 2021 01:32:36 +0400
Subject: [PATCH] Fixed CI\CD for projects.

Signed-off-by: Pavel Kirilin <win10@list.ru>
---
 .../.github/workflows/pre-commit.yml          | 19 ----
 .../.github/workflows/tests.yml               | 95 +++++++++++++++++++
 .../.gitlab-ci.yml                            | 34 +++++--
 .../deploy/docker-compose.yml                 |  3 +-
 .../db/migrations/env.py                      | 10 +-
 pyproject.toml                                |  2 +-
 6 files changed, 128 insertions(+), 35 deletions(-)
 delete mode 100644 fastapi_template/template/{{cookiecutter.project_name}}/.github/workflows/pre-commit.yml
 create mode 100644 fastapi_template/template/{{cookiecutter.project_name}}/.github/workflows/tests.yml

diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/.github/workflows/pre-commit.yml b/fastapi_template/template/{{cookiecutter.project_name}}/.github/workflows/pre-commit.yml
deleted file mode 100644
index 9bdc910..0000000
--- a/fastapi_template/template/{{cookiecutter.project_name}}/.github/workflows/pre-commit.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Testing {{cookiecutter.project_name}}
-
-on: push
-
-jobs:
-  test:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-      - name: Set up Python
-        uses: actions/setup-python@v2
-        with:
-          python-version: '3.9'
-      - name: Install deps
-        uses: knowsuchagency/poetry-install@v1
-        env:
-          POETRY_VIRTUALENVS_CREATE: false
-      - name: Run pre-commit check
-        run: poetry run pre-commit run -a
diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/.github/workflows/tests.yml b/fastapi_template/template/{{cookiecutter.project_name}}/.github/workflows/tests.yml
new file mode 100644
index 0000000..f4a9a18
--- /dev/null
+++ b/fastapi_template/template/{{cookiecutter.project_name}}/.github/workflows/tests.yml
@@ -0,0 +1,95 @@
+name: Testing {{cookiecutter.project_name}}
+
+on: push
+
+jobs:
+  black:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: '3.9'
+      - name: Install deps
+        uses: knowsuchagency/poetry-install@v1
+        env:
+          POETRY_VIRTUALENVS_CREATE: false
+      - name: Run black check
+        run: poetry run black --check .
+  flake8:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: '3.9'
+      - name: Install deps
+        uses: knowsuchagency/poetry-install@v1
+        env:
+          POETRY_VIRTUALENVS_CREATE: false
+      - name: Run flake8 check
+        run: poetry run flake8 --count .
+  mypy:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: '3.9'
+      - name: Install deps
+        uses: knowsuchagency/poetry-install@v1
+        env:
+          POETRY_VIRTUALENVS_CREATE: false
+      - name: Run mypy check
+        run: poetry run mypy .
+  pytest:
+    runs-on: ubuntu-latest
+    {%- if cookiecutter.db_info.name != "none" %}
+    {%- if cookiecutter.db_info.name != "sqlite" %}
+    services:
+      {{cookiecutter.project_name}}-db:
+        image: {{ cookiecutter.db_info.image }}
+        env:
+          {%- if cookiecutter.db_info.name == "postgresql" %}
+          POSTGRES_PASSWORD: {{ cookiecutter.project_name }}
+          POSTGRES_USER: {{ cookiecutter.project_name }}
+          POSTGRES_DB: {{ cookiecutter.project_name }}
+          {%- endif %}
+          {%- if cookiecutter.db_info.name == "mysql" %}
+          MYSQL_PASSWORD: {{ cookiecutter.project_name }}
+          MYSQL_USER: {{ cookiecutter.project_name }}
+          MYSQL_DATABASE: {{ cookiecutter.project_name }}
+          ALLOW_EMPTY_PASSWORD: yes
+          {%- endif %}
+        {%- if cookiecutter.db_info.name == "mysql" %}
+        options: --health-cmd="mysqladmin ping -u root" --health-interval=15s --health-timeout=5s --health-retries=5
+        {%- endif %}
+        {%- if cookiecutter.db_info.name == "postgresql" %}
+        options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=5
+        {%- endif %}
+        ports:
+          - {{ cookiecutter.db_info.port }}
+    {%- endif %}
+    {%- endif %}
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: '3.9'
+      - name: Install deps
+        uses: knowsuchagency/poetry-install@v1
+        env:
+          POETRY_VIRTUALENVS_CREATE: false
+      - name: Run pytest check
+        run: poetry run pytest -vv --cov="{{cookiecutter.project_name}}" . {% if cookiecutter.enable_alembic %}--test-alembic{%- endif %}
+        {%- if cookiecutter.db_info.name != "none" %}
+        {%- if cookiecutter.db_info.name != "sqlite" %}
+        env:
+          {{ cookiecutter.project_name | upper }}_DB_HOST: localhost
+          {{ cookiecutter.project_name | upper }}_DB_PORT: {{'${{'}}job.services.{{cookiecutter.project_name}}-db.ports['{{cookiecutter.db_info.port}}']{{'}}'}}
+        {%- endif %}
+        {%- endif %}
diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml b/fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml
index aa218e2..5d18f16 100644
--- a/fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml
+++ b/fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml
@@ -14,19 +14,32 @@ stages:
     - poetry config virtualenvs.create false
     - poetry install
 
+black:
+  extends:
+    - .test-template
+  script:
+    - black --check .
+
 flake8:
   extends:
     - .test-template
   script:
     - flake8 --count .
 
+mypy:
+  extends:
+    - .test-template
+  script:
+    - mypy .
+
 pytest:
   extends:
     - .test-template
   {%- if cookiecutter.db_info.name != "none" %}
-  {%- if cookiecutter.db_info.name != "mysql" %}
+  {%- if cookiecutter.db_info.name != "sqlite" %}
   services:
     - name: {{ cookiecutter.db_info.image }}
+      alias: {{ cookiecutter.project_name }}-db
   {%- endif %}
   variables:
     {%- if cookiecutter.db_info.name == "postgresql" %}
@@ -39,15 +52,16 @@ pytest:
     {{ cookiecutter.project_name | upper }}_DB_HOST: localhost
     MYSQL_PASSWORD: {{ cookiecutter.project_name }}
     MYSQL_USER: {{ cookiecutter.project_name }}
-    MYSQL_DB: {{ cookiecutter.project_name }}
+    MYSQL_DATABASE: {{ cookiecutter.project_name }}
+    ALLOW_EMPTY_PASSWORD: yes
     {%- endif %}
   {%- endif %}
   script:
-    - pytest -vv --cov="{{cookiecutter.project_name}}" . --test-alembic
-
-black:
-  extends:
-    - .test-template
-  script:
-    - black --check .
-
+    {%- if cookiecutter.db_info.name != "none" %}
+    {%- if cookiecutter.db_info.name != "sqlite" %}
+    - apt update
+    - apt install -y wait-for-it
+    - wait-for-it -t 180 {{ cookiecutter.project_name }}-db:{{cookiecutter.db_info.port}}
+    {%- endif %}
+    {%- endif %}
+    - pytest -vv --cov="{{cookiecutter.project_name}}" . {% if cookiecutter.enable_alembic %}--test-alembic{%- endif %}
diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/docker-compose.yml b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/docker-compose.yml
index 248b1e3..5f465cb 100644
--- a/fastapi_template/template/{{cookiecutter.project_name}}/deploy/docker-compose.yml
+++ b/fastapi_template/template/{{cookiecutter.project_name}}/deploy/docker-compose.yml
@@ -38,6 +38,7 @@ services:
       - MYSQL_PASSWORD={{cookiecutter.project_name}}
       - MYSQL_USER={{cookiecutter.project_name}}
       - MYSQL_DATABASE={{cookiecutter.project_name}}
+      - ALLOW_EMPTY_PASSWORD=yes
     volumes:
       - {{cookiecutter.project_name}}-db-data:/bitnami/mysql/data
   {%- endif %}
@@ -55,7 +56,7 @@ services:
     volumes:
       - {{cookiecutter.project_name}}-db-data:/db_data/
     {%- else %}
-    command: wait-for-it {{cookiecutter.project_name}}-db:{{cookiecutter.db_info.port}} -- alembic upgrade head
+    command: wait-for-it -t 180 {{cookiecutter.project_name}}-db:{{cookiecutter.db_info.port}} -- alembic upgrade head
     {%- endif %}
   {%- endif %}
 
diff --git a/fastapi_template/template/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/db/migrations/env.py b/fastapi_template/template/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/db/migrations/env.py
index 6507aa0..7ab3146 100644
--- a/fastapi_template/template/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/db/migrations/env.py
+++ b/fastapi_template/template/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/db/migrations/env.py
@@ -31,7 +31,7 @@ target_metadata = meta
 # ... etc.
 
 
-def run_migrations_offline() -> None:
+async def run_migrations_offline() -> None:
     """Run migrations in 'offline' mode.
 
     This configures the context with just a URL
@@ -78,8 +78,10 @@ async def run_migrations_online() -> None:
     async with connectable.connect() as connection:
         await connection.run_sync(do_run_migrations)
 
-
+loop = asyncio.get_event_loop()
 if context.is_offline_mode():
-    run_migrations_offline()
+    task = run_migrations_offline()
 else:
-    asyncio.run(run_migrations_online())
+    task = run_migrations_online()
+
+loop.run_until_complete(task)
diff --git a/pyproject.toml b/pyproject.toml
index 2976e9e..d0c7b3b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "fastapi_template"
-version = "2.1.3"
+version = "2.1.4"
 description = "Feature-rich robust FastAPI template"
 authors = ["Pavel Kirilin <win10@list.ru>"]
 packages = [
-- 
GitLab