From 1be02478cec94acbcf1ca881d774a8eb3eae29ea Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 12 Jan 2025 11:21:44 +0100 Subject: [PATCH 01/12] tests: improve github integration test coverage --- intbot/core/integrations/github.py | 21 +- intbot/tests/test_integrations/test_github.py | 203 ++++++++++++++++++ intbot/tests/test_tasks.py | 1 - pyproject.toml | 6 + uv.lock | 28 +++ 5 files changed, 249 insertions(+), 10 deletions(-) create mode 100644 intbot/tests/test_integrations/test_github.py diff --git a/intbot/core/integrations/github.py b/intbot/core/integrations/github.py index 1a2a6ae..7cb217b 100644 --- a/intbot/core/integrations/github.py +++ b/intbot/core/integrations/github.py @@ -84,6 +84,8 @@ def fetch_github_item_details(item_id): class GithubProjectV2Item: + # NOTE: This might be something for pydantic schemas in the future + def __init__(self, content: dict): self.content = content @@ -107,30 +109,30 @@ def content_type(self): return self.content["projects_v2_item"]["content_type"] def node_id(self): - # NOTE(artcz): This is more relevant, because of how the graphql query - # above is constructed. + # NOTE(artcz): This is relevant, because of how the graphql query above + # is constructed. # Using node_id, which is an id of a ProjectV2Item we can get both # DraftIssue and Issue from one query. - # If we use the content_node_id we need to adjust the query as that ID - # points us directly either an Issue or DraftIssue + # If we use the content_node_id we would probably need two separate + # ways of getting that data. return self.content["projects_v2_item"]["node_id"] - def content_node_id(self): - return self.content["projects_v2_item"]["content_node_id"] - def changes(self) -> dict: if "changes" in self.content: fv = self.content["changes"]["field_value"] field_name = fv["field_name"] field_type = fv["field_type"] + if field_type == "date": changed_from = ( fv["from"].split("T")[0] if fv["from"] is not None else "None" ) changed_to = fv["to"].split("T")[0] if fv["to"] is not None else "None" + elif field_type == "single_select": changed_from = fv["from"]["name"] if fv["from"] is not None else "None" changed_to = fv["to"]["name"] if fv["to"] is not None else "None" + else: changed_from = "None" changed_to = "None" @@ -152,8 +154,9 @@ def as_discord_message(self, github_object: GithubDraftIssue | GithubIssue) -> s changes = self.changes() if changes: - details = "**{field}** of **{obj}** from **{from}** to **{to}**".format - details = details(**{"obj": github_object.as_discord_message(), **changes}) + details = "**{field}** of **{obj}** from **{from}** to **{to}**".format( + **{"obj": github_object.as_discord_message(), **changes} + ) else: details = github_object.as_discord_message() diff --git a/intbot/tests/test_integrations/test_github.py b/intbot/tests/test_integrations/test_github.py new file mode 100644 index 0000000..818160d --- /dev/null +++ b/intbot/tests/test_integrations/test_github.py @@ -0,0 +1,203 @@ +import pytest +import respx +from core.integrations.github import ( + GITHUB_API_URL, + GithubProjectV2Item, + fetch_github_item_details, + parse_github_webhook, +) +from httpx import Response + + +def test_parse_github_webhook_raises_value_error_for_unsupported(): + headers = {"X-Github-Event": "random_event"} + content = {} + + with pytest.raises(ValueError): + parse_github_webhook(headers, content) + + +@pytest.fixture +def mocked_github_response(): + def _mock_response(item_type, content_data): + return {"data": {"node": {"content": content_data}}} + + return _mock_response + + +@pytest.fixture +def sample_content(): + return { + "sender": {"login": "testuser", "html_url": "https://github.com/testuser"}, + "projects_v2_item": { + "content_type": "Issue", + "node_id": "test_node_id", + }, + } + + +@respx.mock +def test_fetch_github_item_details(mocked_github_response): + mocked_response = mocked_github_response( + "Issue", + { + "id": "test_issue_id", + "title": "Test Issue", + "url": "https://github.com/test/repo/issues/1", + }, + ) + respx.post(GITHUB_API_URL).mock(return_value=Response(200, json=mocked_response)) + + result = fetch_github_item_details("test_node_id") + + assert result["id"] == "test_issue_id" + assert result["title"] == "Test Issue" + assert result["url"] == "https://github.com/test/repo/issues/1" + + +@respx.mock +def test_github_project_created_event(mocked_github_response, sample_content): + sample_content["action"] = "created" + mocked_response = mocked_github_response( + "Issue", + { + "id": "test_issue_id", + "title": "Test Issue", + "url": "https://github.com/test/repo/issues/1", + }, + ) + respx.post(GITHUB_API_URL).mock(return_value=Response(200, json=mocked_response)) + + parser = GithubProjectV2Item(sample_content) + message = parser.as_str() + + assert message == ( + "[@testuser](https://github.com/testuser) created " + "[Test Issue](https://github.com/test/repo/issues/1)" + ) + + +@respx.mock +def test_github_project_edited_event_for_status_change( + mocked_github_response, sample_content +): + sample_content["action"] = "edited" + sample_content["changes"] = { + "field_value": { + "field_name": "Status", + "field_type": "single_select", + "from": {"name": "To Do"}, + "to": {"name": "In Progress"}, + } + } + mocked_response = mocked_github_response( + "Issue", + { + "id": "test_issue_id", + "title": "Test Issue", + "url": "https://github.com/test/repo/issues/1", + }, + ) + respx.post(GITHUB_API_URL).mock(return_value=Response(200, json=mocked_response)) + + parser = GithubProjectV2Item(sample_content) + message = parser.as_str() + + assert message == ( + "[@testuser](https://github.com/testuser) changed **Status** of " + "**[Test Issue](https://github.com/test/repo/issues/1)** " + "from **To Do** to **In Progress**" + ) + + +@respx.mock +def test_github_project_edited_event_for_date_change( + mocked_github_response, sample_content +): + sample_content["action"] = "edited" + sample_content["changes"] = { + "field_value": { + "field_name": "Deadline", + "field_type": "date", + "from": "2024-01-01T10:20:30", + "to": "2025-01-05T20:30:10", + } + } + mocked_response = mocked_github_response( + "Issue", + { + "id": "test_issue_id", + "title": "Test Issue", + "url": "https://github.com/test/repo/issues/1", + }, + ) + respx.post(GITHUB_API_URL).mock(return_value=Response(200, json=mocked_response)) + + parser = GithubProjectV2Item(sample_content) + message = parser.as_str() + + assert message == ( + "[@testuser](https://github.com/testuser) changed **Deadline** of " + "**[Test Issue](https://github.com/test/repo/issues/1)** " + "from **2024-01-01** to **2025-01-05**" + ) + + +@respx.mock +def test_github_project_draft_issue_event(mocked_github_response, sample_content): + sample_content["action"] = "created" + sample_content["projects_v2_item"]["content_type"] = "DraftIssue" + mocked_response = mocked_github_response( + "DraftIssue", + { + "id": "draft_issue_id", + "title": "Draft Title", + }, + ) + respx.post(GITHUB_API_URL).mock(return_value=Response(200, json=mocked_response)) + + parser = GithubProjectV2Item(sample_content) + message = parser.as_str() + + assert message == "[@testuser](https://github.com/testuser) created Draft Title" + + +def test_github_project_unsupported_action(sample_content): + sample_content["action"] = "unsupported_action" + + parser = GithubProjectV2Item(sample_content) + + with pytest.raises(ValueError, match="Action unsupported unsupported_action"): + parser.action() + + +@respx.mock +def test_github_project_edited_event_no_changes(mocked_github_response, sample_content): + sample_content["action"] = "edited" + mocked_response = mocked_github_response( + "Issue", + { + "id": "test_issue_id", + "title": "Test Issue", + "url": "https://github.com/test/repo/issues/1", + }, + ) + respx.post(GITHUB_API_URL).mock(return_value=Response(200, json=mocked_response)) + + parser = GithubProjectV2Item(sample_content) + message = parser.as_str() + + assert message == ( + "[@testuser](https://github.com/testuser) changed " + "[Test Issue](https://github.com/test/repo/issues/1)" + ) + + +@respx.mock +def test_fetch_github_item_details_api_error(): + respx.post(GITHUB_API_URL).mock( + return_value=Response(500, json={"message": "Internal Server Error"}) + ) + + with pytest.raises(Exception, match="GitHub API error: 500 - .*"): + fetch_github_item_details("test_node_id") diff --git a/intbot/tests/test_tasks.py b/intbot/tests/test_tasks.py index 47d76c9..674bcab 100644 --- a/intbot/tests/test_tasks.py +++ b/intbot/tests/test_tasks.py @@ -41,7 +41,6 @@ def test_process_webhook_fails_if_unsupported_source(): result = process_webhook.enqueue(str(wh.uuid)) assert result.status == ResultStatus.FAILED - assert result._exception_class == ValueError assert result.traceback.endswith("ValueError: Unsupported source asdf\n") diff --git a/pyproject.toml b/pyproject.toml index 7132a11..3f18adb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,8 @@ dependencies = [ "django-stubs>=5.1.1", "pdbpp>=0.10.3", "pytest-cov>=6.0.0", + "pytest-socket>=0.7.0", + "respx>=0.22.0", ] [tool.pytest.ini_options] @@ -28,6 +30,10 @@ pythonpath = [ "intbot" ] +# Disable attempts of using the internet in tests, but allow connection to the +# database +addopts = "--disable-socket --allow-unix-socket" + [tool.coverage.run] branch = true omit = [ diff --git a/uv.lock b/uv.lock index f5b768e..dccf480 100644 --- a/uv.lock +++ b/uv.lock @@ -326,6 +326,8 @@ dependencies = [ { name = "pytest-asyncio" }, { name = "pytest-cov" }, { name = "pytest-django" }, + { name = "pytest-socket" }, + { name = "respx" }, { name = "ruff" }, { name = "whitenoise" }, ] @@ -346,6 +348,8 @@ requires-dist = [ { name = "pytest-asyncio", specifier = ">=0.25.2" }, { name = "pytest-cov", specifier = ">=6.0.0" }, { name = "pytest-django", specifier = ">=4.9.0" }, + { name = "pytest-socket", specifier = ">=0.7.0" }, + { name = "respx", specifier = ">=0.22.0" }, { name = "ruff", specifier = ">=0.8.6" }, { name = "whitenoise", specifier = ">=6.8.2" }, ] @@ -545,6 +549,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/47/fe/54f387ee1b41c9ad59e48fb8368a361fad0600fe404315e31a12bacaea7d/pytest_django-4.9.0-py3-none-any.whl", hash = "sha256:1d83692cb39188682dbb419ff0393867e9904094a549a7d38a3154d5731b2b99", size = 23723 }, ] +[[package]] +name = "pytest-socket" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/ff/90c7e1e746baf3d62ce864c479fd53410b534818b9437413903596f81580/pytest_socket-0.7.0.tar.gz", hash = "sha256:71ab048cbbcb085c15a4423b73b619a8b35d6a307f46f78ea46be51b1b7e11b3", size = 12389 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/58/5d14cb5cb59409e491ebe816c47bf81423cd03098ea92281336320ae5681/pytest_socket-0.7.0-py3-none-any.whl", hash = "sha256:7e0f4642177d55d317bbd58fc68c6bd9048d6eadb2d46a89307fa9221336ce45", size = 6754 }, +] + +[[package]] +name = "respx" +version = "0.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/7c/96bd0bc759cf009675ad1ee1f96535edcb11e9666b985717eb8c87192a95/respx-0.22.0.tar.gz", hash = "sha256:3c8924caa2a50bd71aefc07aa812f2466ff489f1848c96e954a5362d17095d91", size = 28439 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/67/afbb0978d5399bc9ea200f1d4489a23c9a1dad4eee6376242b8182389c79/respx-0.22.0-py2.py3-none-any.whl", hash = "sha256:631128d4c9aba15e56903fb5f66fb1eff412ce28dd387ca3a81339e52dbd3ad0", size = 25127 }, +] + [[package]] name = "ruff" version = "0.8.6" From d0a48c56d7950ca5b032180379cb7b6cdc1e5fc1 Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 12 Jan 2025 12:43:04 +0100 Subject: [PATCH 02/12] add github action --- .github/workflows/build_test_and_lint.yml | 55 +++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 .github/workflows/build_test_and_lint.yml diff --git a/.github/workflows/build_test_and_lint.yml b/.github/workflows/build_test_and_lint.yml new file mode 100644 index 0000000..d4eb050 --- /dev/null +++ b/.github/workflows/build_test_and_lint.yml @@ -0,0 +1,55 @@ +name: Build Test and Lint + +on: + push: + branches: + - main + pull_request: + +jobs: + build-test-and-lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - name: Build Docker image + run: | + make docker/build + + - name: Run Docker container for tests + run: | + docker run --rm \ + -e DJANGO_SETTINGS_MODULE=intbot.settings \ + -e DATABASE_URL=postgres://testuser:testpassword@localhost:5432/testdb \ + --network host \ + intbot \ + make test + + services: + postgres: + image: postgres:16.4 + env: + POSTGRES_USER: testuser + POSTGRES_PASSWORD: testpassword + POSTGRES_DB: testdb + ports: + - 5432:5432 + options: >- + --health-cmd="pg_isready -U testuser -d testdb" + --health-interval=10s + --health-timeout=5s + --health-retries=5 + From a519c5401b2e4e30d32b745c15dfb34edf1fbb66 Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 12 Jan 2025 12:52:37 +0100 Subject: [PATCH 03/12] add intbot:latest flag --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c8a1af6..efdaddc 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,7 @@ in-container/manage: # ========================= docker/build: - docker build . -t intbot:$(current_git_hash) + docker build . -t intbot:$(current_git_hash) intbot:latest docker/run/gunicorn: $(DOCKER_RUN_WITH_PORT) make in-container/gunicorn From 240b25789924cea26e67e3bed10d503a557513e5 Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Mon, 13 Jan 2025 13:16:41 +0100 Subject: [PATCH 04/12] fix missing arg --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index efdaddc..91fe770 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,7 @@ in-container/manage: # ========================= docker/build: - docker build . -t intbot:$(current_git_hash) intbot:latest + docker build . -t intbot:$(current_git_hash) -t intbot:latest docker/run/gunicorn: $(DOCKER_RUN_WITH_PORT) make in-container/gunicorn From 68b0dd120c610d49fd0fd3ce9795414ae3946b7c Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Fri, 17 Jan 2025 10:12:24 +0100 Subject: [PATCH 05/12] update ci build/test setup --- .github/workflows/build_test_and_lint.yml | 12 ++++++------ Makefile | 9 +++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_test_and_lint.yml b/.github/workflows/build_test_and_lint.yml index d4eb050..7b8569a 100644 --- a/.github/workflows/build_test_and_lint.yml +++ b/.github/workflows/build_test_and_lint.yml @@ -36,19 +36,19 @@ jobs: -e DATABASE_URL=postgres://testuser:testpassword@localhost:5432/testdb \ --network host \ intbot \ - make test + make in-container/tests services: postgres: image: postgres:16.4 env: - POSTGRES_USER: testuser - POSTGRES_PASSWORD: testpassword - POSTGRES_DB: testdb + POSTGRES_USER: intbot_user + POSTGRES_PASSWORD: intbot_password + POSTGRES_DB: intbot_database_test ports: - - 5432:5432 + - 14672:5432 options: >- - --health-cmd="pg_isready -U testuser -d testdb" + --health-cmd="pg_isready -U intbot_user -d intbot_database_test" --health-interval=10s --health-timeout=5s --health-retries=5 diff --git a/Makefile b/Makefile index 91fe770..cbafebe 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,10 @@ UV_RUN_DEV=cd intbot && DJANGO_ENV="dev" uv run # Docker DOCKER_RUN_WITH_PORT=docker run -p 4672:4672 --add-host=host.internal:host-gateway -e DJANGO_ENV="local_container" -it intbot:$(V) +DOCKER_RUN=docker run --add-host=host.internal:host-gateway -e DJANGO_ENV="test" -it intbot:$(V) MANAGE=cd intbot && ./manage.py +# In container we run with migrations +CONTAINER_TEST_CMD=DJANGO_SETTINGS_MODULE="intbot.settings" DJANGO_ENV="test" pytest --migrations # Deployment DEPLOY_CMD=cd deploy && uvx --from "ansible-core" ansible-playbook -i hosts.yml @@ -108,6 +111,9 @@ in-container/migrate: in-container/manage: $(MANAGE) $(ARG) +in-container/tests: + $(CONTAINER_TEST_CMD) -vvv + # Docker management targets # ========================= @@ -118,6 +124,9 @@ docker/build: docker/run/gunicorn: $(DOCKER_RUN_WITH_PORT) make in-container/gunicorn +docker/run/tests: + $(DOCKER_RUN) make in-container/tests + # Deploymenet targets # ==================== From 1d4cc6458819b12b5b95833c7ca4b1f3cb65146d Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 19 Jan 2025 17:25:58 +0100 Subject: [PATCH 06/12] add in-container/lint and type check --- Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Makefile b/Makefile index cbafebe..a0c3813 100644 --- a/Makefile +++ b/Makefile @@ -114,6 +114,12 @@ in-container/manage: in-container/tests: $(CONTAINER_TEST_CMD) -vvv +in-container/lint: + cd intbot && ruff check . + +in-container/type-check: + cd intbot && mypy intbot + # Docker management targets # ========================= @@ -127,6 +133,10 @@ docker/run/gunicorn: docker/run/tests: $(DOCKER_RUN) make in-container/tests +docker/run/lint: + $(DOCKER_RUN) make in-container/lint + $(DOCKER_RUN) make in-container/type-check + # Deploymenet targets # ==================== From 06bd133e8c7b9421b62c542ad2c7951b1ffde346 Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 19 Jan 2025 17:26:45 +0100 Subject: [PATCH 07/12] add linting to CI --- .github/workflows/build_test_and_lint.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build_test_and_lint.yml b/.github/workflows/build_test_and_lint.yml index 7b8569a..a61c087 100644 --- a/.github/workflows/build_test_and_lint.yml +++ b/.github/workflows/build_test_and_lint.yml @@ -38,6 +38,10 @@ jobs: intbot \ make in-container/tests + - name: Run Docker container for lint + run: | + docker run --rm intbot make in-container/lint + services: postgres: image: postgres:16.4 From 51ed4a825f1c00ceb4e25ab14a5fc6eab78b53a0 Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 19 Jan 2025 17:33:52 +0100 Subject: [PATCH 08/12] add type check to CI build --- .github/workflows/build_test_and_lint.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_test_and_lint.yml b/.github/workflows/build_test_and_lint.yml index a61c087..0766b2d 100644 --- a/.github/workflows/build_test_and_lint.yml +++ b/.github/workflows/build_test_and_lint.yml @@ -41,6 +41,7 @@ jobs: - name: Run Docker container for lint run: | docker run --rm intbot make in-container/lint + docker run --rm intbot make in-container/type-check services: postgres: From 5be6e9bddd07b540dae57f2e8d5924accb88fad1 Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 19 Jan 2025 17:37:33 +0100 Subject: [PATCH 09/12] add CI_RUN --- .github/workflows/build_test_and_lint.yml | 4 ++-- Makefile | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_test_and_lint.yml b/.github/workflows/build_test_and_lint.yml index 0766b2d..0ebfb69 100644 --- a/.github/workflows/build_test_and_lint.yml +++ b/.github/workflows/build_test_and_lint.yml @@ -40,8 +40,8 @@ jobs: - name: Run Docker container for lint run: | - docker run --rm intbot make in-container/lint - docker run --rm intbot make in-container/type-check + docker run --rm intbot make ci/lint + docker run --rm intbot make ci/type-check services: postgres: diff --git a/Makefile b/Makefile index a0c3813..dabbabb 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ DOCKER_RUN=docker run --add-host=host.internal:host-gateway -e DJANGO_ENV="test" MANAGE=cd intbot && ./manage.py # In container we run with migrations CONTAINER_TEST_CMD=DJANGO_SETTINGS_MODULE="intbot.settings" DJANGO_ENV="test" pytest --migrations +CI_RUN=cd intbot && DJANGO_SETTINGS_MODULE="intbot.settings" DJANGO_ENV="ci" # Deployment DEPLOY_CMD=cd deploy && uvx --from "ansible-core" ansible-playbook -i hosts.yml @@ -114,11 +115,11 @@ in-container/manage: in-container/tests: $(CONTAINER_TEST_CMD) -vvv -in-container/lint: - cd intbot && ruff check . +ci/lint: + $(CI_RUN) ruff check . -in-container/type-check: - cd intbot && mypy intbot +ci/type-check: + $(CI_RUN) mypy intbot # Docker management targets @@ -134,8 +135,8 @@ docker/run/tests: $(DOCKER_RUN) make in-container/tests docker/run/lint: - $(DOCKER_RUN) make in-container/lint - $(DOCKER_RUN) make in-container/type-check + $(DOCKER_RUN) make ci/lint + $(DOCKER_RUN) make ci/type-check # Deploymenet targets From 9185f94c84306ede0c63c2c3d3a36ef17610579e Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 19 Jan 2025 17:38:14 +0100 Subject: [PATCH 10/12] add empty django_env for ci --- intbot/intbot/settings.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/intbot/intbot/settings.py b/intbot/intbot/settings.py index 84832db..77dbccc 100644 --- a/intbot/intbot/settings.py +++ b/intbot/intbot/settings.py @@ -306,5 +306,8 @@ def warn_if_missing(name, default=""): # Currently used only for collecting staticfiles in docker DEBUG = False +elif DJANGO_ENV == "ci": + DEBUG = False + else: raise ValueError(f"Unsupported DJANGO_ENV `{DJANGO_ENV}`") From 06fb12f2abae59c8ec9e7f4e4b8b872f916667b9 Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 19 Jan 2025 17:41:23 +0100 Subject: [PATCH 11/12] fix type check error --- intbot/intbot/settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/intbot/intbot/settings.py b/intbot/intbot/settings.py index 77dbccc..1e9463b 100644 --- a/intbot/intbot/settings.py +++ b/intbot/intbot/settings.py @@ -12,6 +12,7 @@ import os import warnings +from typing import Any from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. @@ -112,6 +113,9 @@ DJANGO_ENV = os.environ["DJANGO_ENV"] APP_VERSION = os.environ.get("APP_VERSION", "latest")[:8] +# Just to make mypy happy +TASKS: dict[str, Any] + if DJANGO_ENV == "dev": DEBUG = True ALLOWED_HOSTS = ["127.0.0.1", "localhost"] From 4ccbdf018258ba5d5d5838ff2c4864c52ae2382a Mon Sep 17 00:00:00 2001 From: Artur Czepiel Date: Sun, 19 Jan 2025 17:45:11 +0100 Subject: [PATCH 12/12] add deployment workflow --- .github/workflows/deploy.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..c5aab98 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,20 @@ +name: Deploy latest version of the app + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Run deployment + run: make deploy/app