From 4832ae9b711adbf1a2763fb89f2a4f6bee658896 Mon Sep 17 00:00:00 2001 From: Kirill Mokevnin Date: Wed, 12 Aug 2026 19:55:05 -0400 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20=D0=BF=D1=80=D0=B8=D0=B2=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=B8=20=D0=B8=D0=BD=D1=84=D1=80=D0=B0=D1=81=D1=82?= =?UTF-8?q?=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D1=83=20=D0=BA=20=D0=BA?= =?UTF-8?q?=D0=B0=D0=BD=D0=BE=D0=BD=D1=83=20=D0=BA=D0=B0=D0=BC=D0=BF=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Версия рантайма переезжает в .python-version и берётся оттуда uv-ом, поэтому setup-python из CI убран, requires-python поднят до 3.14. В dependabot добавлены prefix chore и labels, добавлен линт заголовка PR. Линтер в Makefile идёт по всему репозиторию, а не только по пакету проекта, и появилась цель check. Co-Authored-By: Claude Opus 5 (1M context) --- .github/dependabot.yml | 18 ++++++++++++------ .github/workflows/pr-title.yml | 24 ++++++++++++++++++++++++ .github/workflows/pyci.yml | 33 ++++++++++++++++----------------- .python-version | 1 + Makefile | 7 +++++-- pyproject.toml | 2 +- uv.lock | 8 +------- 7 files changed, 60 insertions(+), 33 deletions(-) create mode 100644 .github/workflows/pr-title.yml create mode 100644 .python-version diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 896e26f..3160f90 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,21 +1,27 @@ version: 2 updates: + # Экосистема uv покрывает и pyproject.toml, и uv.lock. Отдельный блок pip на + # том же каталоге давал бы вторую пачку PR на те же зависимости. - package-ecosystem: "uv" directory: "/" schedule: interval: "monthly" open-pull-requests-limit: 1 + labels: ["dependencies", "automated"] + commit-message: + prefix: "chore" groups: - all-uv-dependencies: - patterns: - - "*" + uv-all: + patterns: ["*"] - package-ecosystem: "github-actions" directory: "/" schedule: interval: "monthly" open-pull-requests-limit: 1 + labels: ["dependencies", "automated"] + commit-message: + prefix: "chore" groups: - all-github-actions-dependencies: - patterns: - - "*" + github-actions-all: + patterns: ["*"] diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml new file mode 100644 index 0000000..22c4d6b --- /dev/null +++ b/.github/workflows/pr-title.yml @@ -0,0 +1,24 @@ +name: PR Title + +# Заголовок PR обязан быть conventional commit: при squash-мерже он становится +# сообщением коммита, а по нему release-please определяет, какой разряд версии +# поднять. Проверка отдельных коммитов ветки намеренно не делается, чтобы не +# мешать работе внутри PR. +on: + pull_request_target: + types: + - opened + - edited + - synchronize + - reopened + +permissions: + pull-requests: read + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pyci.yml b/.github/workflows/pyci.yml index f69e4ba..7956d81 100644 --- a/.github/workflows/pyci.yml +++ b/.github/workflows/pyci.yml @@ -1,28 +1,27 @@ name: Python CI on: - - push - - pull_request + push: + branches: + - main + pull_request: + branches: + - main jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - - name: Set up Python - uses: actions/setup-python@v7 - with: - python-version: '3.12' - - name: Install dependencies - run: | - pip install uv - make setup + # setup-python не нужен: версию питона держит .python-version, и uv сам + # ставит её при первом `uv sync`. Единый источник версии, поэтому раннер + # и образ кита не могут разойтись. + - uses: astral-sh/setup-uv@v10.0.0 - - name: Run the linter - run: | - make lint - - - name: Run the tests - run: | - make test + - name: Install + run: make install + - name: Run linter + run: make lint + - name: Run tests + run: make test diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..6324d40 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.14 diff --git a/Makefile b/Makefile index f135c07..b6ef0ad 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ MANAGE := uv run python manage.py .PHONY: test test: - uv run pytest + @uv run pytest .PHONY: setup setup: db-clean install migrate @@ -25,4 +25,7 @@ shell: .PHONY: lint lint: - uv run ruff check python_django_orm_blog + @uv run ruff check . + +.PHONY: check +check: install lint test diff --git a/pyproject.toml b/pyproject.toml index cd15e94..b498d08 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ version = "0.1.0" description = "A simple Django project that implements a simple blog." authors = [{name = "Hexlet Team", email = ""}] readme = "README.md" -requires-python = ">=3.12" +requires-python = ">=3.14" dependencies = [ "django>=6.1", ] diff --git a/uv.lock b/uv.lock index 437f24c..88a6055 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.12" +requires-python = ">=3.14" [[package]] name = "asgiref" @@ -197,12 +197,6 @@ version = "7.2.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" }, - { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" }, - { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, - { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, - { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" }, - { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" }, { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" }, { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" }, { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" }, From 22922f65336f7bcc4487023f7b5023c614e4c194 Mon Sep 17 00:00:00 2001 From: Kirill Mokevnin Date: Wed, 12 Aug 2026 19:55:06 -0400 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B8=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20blog=20=D0=BD=D0=B0=D1=80=D1=83?= =?UTF-8?q?=D0=B6=D1=83=20=D0=BF=D0=B0=D0=BA=D0=B5=D1=82=D0=B0=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit django-admin startapp кладёт приложение рядом с пакетом проекта, а не внутрь него, поэтому python_django_orm_blog/blog переехал в blog. Метка приложения не изменилась: django берёт её из последнего компонента name, поэтому миграции остаются валидными, makemigrations --check это подтверждает. Раскладку показывают уроки python_django_orm_course, они правятся отдельными коммитами в репозиториях курсов ru и es. Co-Authored-By: Claude Opus 5 (1M context) --- {python_django_orm_blog/blog => blog}/__init__.py | 0 .../blog => blog}/migrations/0001_initial.py | 0 {python_django_orm_blog/blog => blog}/migrations/__init__.py | 0 {python_django_orm_blog/blog => blog}/models.py | 0 {python_django_orm_blog/blog => blog}/tests.py | 2 +- python_django_orm_blog/settings.py | 2 +- 6 files changed, 2 insertions(+), 2 deletions(-) rename {python_django_orm_blog/blog => blog}/__init__.py (100%) rename {python_django_orm_blog/blog => blog}/migrations/0001_initial.py (100%) rename {python_django_orm_blog/blog => blog}/migrations/__init__.py (100%) rename {python_django_orm_blog/blog => blog}/models.py (100%) rename {python_django_orm_blog/blog => blog}/tests.py (96%) diff --git a/python_django_orm_blog/blog/__init__.py b/blog/__init__.py similarity index 100% rename from python_django_orm_blog/blog/__init__.py rename to blog/__init__.py diff --git a/python_django_orm_blog/blog/migrations/0001_initial.py b/blog/migrations/0001_initial.py similarity index 100% rename from python_django_orm_blog/blog/migrations/0001_initial.py rename to blog/migrations/0001_initial.py diff --git a/python_django_orm_blog/blog/migrations/__init__.py b/blog/migrations/__init__.py similarity index 100% rename from python_django_orm_blog/blog/migrations/__init__.py rename to blog/migrations/__init__.py diff --git a/python_django_orm_blog/blog/models.py b/blog/models.py similarity index 100% rename from python_django_orm_blog/blog/models.py rename to blog/models.py diff --git a/python_django_orm_blog/blog/tests.py b/blog/tests.py similarity index 96% rename from python_django_orm_blog/blog/tests.py rename to blog/tests.py index 8abdea6..4bb207c 100644 --- a/python_django_orm_blog/blog/tests.py +++ b/blog/tests.py @@ -1,7 +1,7 @@ import django.db import pytest -from python_django_orm_blog.blog import models +from blog import models @pytest.mark.django_db diff --git a/python_django_orm_blog/settings.py b/python_django_orm_blog/settings.py index a4945f2..dd4d477 100644 --- a/python_django_orm_blog/settings.py +++ b/python_django_orm_blog/settings.py @@ -35,7 +35,7 @@ INSTALLED_APPS = [ 'django_extensions', - 'python_django_orm_blog.blog', + 'blog', ] MIDDLEWARE = [