From 9e13da018903d769228ba9a1f5585db05ec3c1e4 Mon Sep 17 00:00:00 2001 From: Lacky1234union Date: Tue, 13 Oct 2026 23:39:05 +0300 Subject: [PATCH 1/3] =?UTF-8?q?ci:=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B1=D0=BE=D1=82=D0=B0=20=D0=B2=20SourceCraft?= =?UTF-8?q?=20CI=20=E2=80=94=20ruff,=20mypy,=20pytest=20=D1=81=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D0=B3=D0=BE=D0=BC=20=D0=BF=D0=BE=D0=BA=D1=80?= =?UTF-8?q?=D1=8B=D1=82=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit push в любую ветку (зеркало из Gitea, ADR-010) → кубы lint и test параллельно. Порог покрытия — храповик в pyproject (fail_under), одинаков локально и в CI. Refs #6 Co-Authored-By: Claude Opus 5.5 --- .sourcecraft/ci.yaml | 33 +++++++++++++++++++++++++++++++++ pyproject.toml | 3 +++ 2 files changed, 36 insertions(+) create mode 100644 .sourcecraft/ci.yaml diff --git a/.sourcecraft/ci.yaml b/.sourcecraft/ci.yaml new file mode 100644 index 0000000..bc3b21c --- /dev/null +++ b/.sourcecraft/ci.yaml @@ -0,0 +1,33 @@ +# CI бота. Код приходит push-зеркалом из Gitea (ADR-010): PR живут в Gitea, поэтому +# триггер pull_request здесь не сработает — проверяем каждый push в любую ветку. +# Деплой на хост (workflow deploy на push в main) — #12. +on: + push: + - workflows: [check] + filter: + branches: ["**"] + +workflows: + check: + settings: + max_cube_duration: 10m + tasks: + - name: quality + cubes: + - name: lint + image: ghcr.io/astral-sh/uv:0.8-python3.12-bookworm-slim + env: + UV_LINK_MODE: copy + script: + - uv sync --frozen + - uv run ruff check . + - uv run ruff format --check . + - uv run mypy + - name: test + needs: ["-"] + image: ghcr.io/astral-sh/uv:0.8-python3.12-bookworm-slim + env: + UV_LINK_MODE: copy + script: + - uv sync --frozen + - uv run pytest -q --cov --cov-report=term diff --git a/pyproject.toml b/pyproject.toml index 6f542b0..c271ab6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,10 @@ testpaths = ["tests"] [tool.coverage.run] source = ["app"] branch = true +omit = ["app/__main__.py"] [tool.coverage.report] show_missing = true skip_covered = true +# Ratchet: raise as code lands, never lower. Target by M4 — 70 (SPEC §5.2). +fail_under = 45 From d81f230407e3d8650a13961cdd759eea2eb28b96 Mon Sep 17 00:00:00 2001 From: Lacky1234union Date: Tue, 13 Oct 2026 23:43:13 +0300 Subject: [PATCH 2/3] =?UTF-8?q?ci:=20=D1=82=D1=80=D0=B8=D0=B3=D0=B3=D0=B5?= =?UTF-8?q?=D1=80=20push=20=D0=B1=D0=B5=D0=B7=20=D1=84=D0=B8=D0=BB=D1=8C?= =?UTF-8?q?=D1=82=D1=80=D0=B0=20=D0=B2=D0=B5=D1=82=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #6 Co-Authored-By: Claude Opus 5.5 --- .sourcecraft/ci.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.sourcecraft/ci.yaml b/.sourcecraft/ci.yaml index bc3b21c..6b7771c 100644 --- a/.sourcecraft/ci.yaml +++ b/.sourcecraft/ci.yaml @@ -2,10 +2,7 @@ # триггер pull_request здесь не сработает — проверяем каждый push в любую ветку. # Деплой на хост (workflow deploy на push в main) — #12. on: - push: - - workflows: [check] - filter: - branches: ["**"] + push: check workflows: check: From cccab8ba78a52ffb92b6a8b51fbd40f16753b4b5 Mon Sep 17 00:00:00 2001 From: Lacky1234union Date: Tue, 13 Oct 2026 23:49:10 +0300 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20CI=20SourceCraft=20=E2=80=94=20?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=20=D0=BF=D1=80=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=D0=BD=D0=BE=D0=B2=20=D0=B8=20=D0=BB=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=D0=B2,=20=D1=80=D1=83=D1=87=D0=BD=D0=BE=D0=B9=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BF=D1=83=D1=81=D0=BA,=20=D1=82=D1=80=D0=B8=D0=B3=D0=B3?= =?UTF-8?q?=D0=B5=D1=80=D1=8B=20=D0=B8=D0=B7=20=D0=BE=D1=81=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BD=D0=BE=D0=B9=20=D0=B2=D0=B5=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #6 Co-Authored-By: Claude Opus 5.5 --- docs/DECISIONS.md | 1 + docs/dev/SOURCECRAFT_API.md | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md index bf317bc..7242a2b 100644 --- a/docs/DECISIONS.md +++ b/docs/DECISIONS.md @@ -94,6 +94,7 @@ **Последствия:** - В SourceCraft ничего не пушим и не мержим — зеркало перезаписывает его целиком. - Триггер `pull_request` в SourceCraft не срабатывает (PR живут в Gitea) → CI бота запускается на `push` во все ветки. +- SourceCraft берёт триггеры CI из основной ветки → основная ветка `tgit` в SourceCraft — `dev` (в Gitea остаётся `main`); иначе CI включался бы только после продвижения в `main`. - Токен SourceCraft хранится в настройках зеркала Gitea → нужен отдельный токен с доступом только к `tgit`. - Issues #1–#21 перенесены из SourceCraft с теми же номерами; в SourceCraft закрыты со ссылкой. diff --git a/docs/dev/SOURCECRAFT_API.md b/docs/dev/SOURCECRAFT_API.md index d84cece..a78de55 100644 --- a/docs/dev/SOURCECRAFT_API.md +++ b/docs/dev/SOURCECRAFT_API.md @@ -61,14 +61,27 @@ curl -s -X POST -H "$H" -H "$J" "$R/milestones" -d '{"name":"M5 · …","descrip ## CI/CD ```bash -curl -s -H "$H" "$R/cicd/runs" # прогоны -curl -s -H "$H" "$R/cicd/runs/" # статус прогона -curl -s -H "$H" "$R/cicd/logs////" # лог куба +curl -s -H "$H" "$R/cicd/runs" # прогоны: {"runs": [...], "next_page_token"} +curl -s -H "$H" "$R/cicd/runs/" # прогон: status + workflows[].tasks[].cubes[] +curl -s -H "$H" "$R/cicd/logs////" # лог куба: {"logs": "...", "page_complete", "done"} + +# ручной запуск (head и config_revision — {"branch"|"tag"|"commit": ...}; по умолчанию — основная ветка) +curl -s -X POST -H "$H" -H "$J" "$R/cicd/runs" \ + -d '{"head":{"branch":"feat/x"},"config_revision":{"branch":"feat/x"},"workflows":[{"name":"check"}]}' + # секрет: value — base64 от значения curl -s -X PUT -H "$H" -H "$J" "$R/secrets/DEPLOY_HOST" -d "{\"value\":\"$(printf %s 'user@host' | base64 -w0)\"}" ``` -Исходящих webhooks нет — статус CI получаем опросом (ADR-003). +- **Триггеры `on:` читаются из `.sourcecraft/ci.yaml` основной ветки репозитория.** Пока файла там нет — push ничего + не запускает. Основная ветка `tgit` в SourceCraft — `dev` (`PATCH $R -d '{"default_branch":"dev"}'`), чтобы CI + включался мержем в `dev`, а не продвижением в `main`. +- Прогон: `slug` — числовой (`1000000`…), `status`: `created` → `processing` → `success`/`failed`; `event_type`: + `push`/`manual`/…. У кубов служебные шаги со `slug`, начинающимся на `#` (`#git-clone`, `#prepare-image-for-`). +- Если куб упал, остальные кубы задачи остаются в `created` и не запускаются. +- Код в кубе склонирован в `/sourcecraft/workspace` (`$SOURCECRAFT_WORKSPACE`) — это рабочий каталог. Переменные: + `SOURCECRAFT_COMMIT_SHA`, `SOURCECRAFT_COMMIT_REF_NAME` и др. +- Исходящих webhooks нет — статус CI получаем опросом (ADR-003). ## Метки репозитория