diff --git a/.wiki/concepts/gitea-project-create-runbook.md b/.wiki/concepts/gitea-project-create-runbook.md new file mode 100644 index 0000000..bc988b6 --- /dev/null +++ b/.wiki/concepts/gitea-project-create-runbook.md @@ -0,0 +1,81 @@ +--- +title: "Создание Gitea-репо (проект в Gitea)" +type: concept +tags: [runbook, gitea, repo, project, ops, admin] +related: [concepts/runbooks-index.md, concepts/project-create-canon.md] +updated: 2026-08-27 +--- + +# Создание Gitea-репо (private) + +> **⚙️ СЛУЖЕБНЫЙ РАНБУК — только для администратора проекта `.admin`.** +> Применять/выполнять шаги может только **`.admin`** (оператор проекта admin). Другим проектам/агентам — читать по запросу, не выполнять. +> Из проекта не выносить: не копировать в другие вики, не пересказывать, не публиковать. +> Нужен деплой или прод-операция по этому ранбуку — **поставить задачу админу (`.admin`) и написать письмо**. Админ выполняет, остальные верифицируют. + +## Scope + +Создание **private** Gitea-репо для нового проекта. Вход: ops-задача на борде `.admin` +(`task_create`, **priority P0**) + покрывающее письмо от заказчика (таска не пингует +живую сессию). Парная review **НЕ нужна** (ops-задача). + +Механика: репо создаёт admin (`OpeItcLoc03`) через `POST /user/repos` → **transfer** +к целевому владельцу. Это канон (скил `project-create`): admin-endpoint отказывает без +`write:admin`. + +## Артефакты + +- **Gitea:** `https://git.kzntsv.site`, API base `/api/v1`. +- **Admin-токен:** `<из pass gitea/admin-token>` (login `OpeItcLoc03`, id 1, is_admin). +- **Push-токен:** user-токен целевого владельца с `repo:write` (для `victor` — `<из pass gitea/victor-books-ci-bookva-overlay>`). +- **SSH-порт** git.kzntsv.site — **2222** (не 22). + +## Шаги + +1. **Получить имя и владельца от оператора.** Никогда не выводить сам (hard rule + скила `project-create`; прецедент tg-digest — решили по аналогии, оператор поправил). +2. **Pre-flight (с admin-токеном):** + - `GET /users/` → 200 = владелец существует; + - `GET /repos//` → **404 = имя свободно**. + > Без auth приватные/скрытые сущности могут давать 404 даже если существуют — проверять с токеном. +3. **Создать** (от admin, owner = `OpeItcLoc03`): + ```bash + TOK=$(pass show gitea/admin-token) + curl -s -X POST "$BASE/user/repos" \ + -H "Authorization: token $TOK" -H "Content-Type: application/json" \ + -d '{"name":"","private":true,"description":"","auto_init":false}' + ``` + `auto_init:false` — без seed-коммита (репо пустое, готово к bootstrap). +4. **Transfer к владельцу:** + ```bash + curl -s -X POST "$BASE/repos/OpeItcLoc03//transfer" \ + -H "Authorization: token $TOK" -H "Content-Type: application/json" \ + -d '{"new_owner":"","team_ids":[]}' + ``` +5. **Verify:** в ответе transfer — `full_name` = `/`, `private:true`, + `empty:true`, `default_branch` (ожид. `main`). +6. **Проверить push-токен:** `GET /repos//` с user-токеном → + `permissions.push == true`. +7. **Ответить письмом** (`inbox_send`, from `.admin`, type action) заказчику: + clone URLs (HTTPS + SSH), push-токен как **pass-реф** (только имя записи, не значение), + подтверждение что репо пустое. Закрыть ops-таску (`task_close`, reason + verify). + +## Verify / smoke + +- Репо указано как private и пустое (в списке репо владельца). +- User-токен владельца видит репо и имеет push-права. +- Ответ-письмо ушло (clone URLs + токен-реф + подтверждение). + +## Rollback + +- Сразу после создания (до transfer): `DELETE /repos/OpeItcLoc03/`. +- После transfer: `DELETE /repos//` (с admin-токеном). + +## Gotchas + +1. **Gitea-эндпоинты без auth** могут 404 на существующие (скрытые/приватные) сущности — все проверки с токеном. (2026-08-27) +2. **Имя/владелец — решение оператора**, не по аналогии из соседних проектов (hard rule, tg-digest кейс). (2026-08-27) +3. **SSH-порт Gitea — 2222**, не 22. (2026-08-27) +4. **`POST /user/repos`** создаёт на владельца токена (`OpeItcLoc03`), потом transfer — нужно admin-право (иначе 403). (2026-08-27) +5. **Секреты:** в ранбуке/письме только pass-рефы; значения токенов не сыпать (write-time secret-scan блокирует 422). (2026-08-27) +6. **`/users/?` без auth → 404 даже для существующего** (victor) — проверять с admin-токеном. (2026-08-27) diff --git a/.wiki/concepts/runbooks-index.md b/.wiki/concepts/runbooks-index.md index 0ba4c3d..46cc7dc 100644 --- a/.wiki/concepts/runbooks-index.md +++ b/.wiki/concepts/runbooks-index.md @@ -46,6 +46,7 @@ updated: 2026-08-26 | Операция | Ранбук | Что покрывает | |---|---|---| +| Создание Gitea-репо (проект в Gitea) | [`gitea-project-create-runbook.md`](gitea-project-create-runbook.md) | private-репо: admin POST /user/repos → transfer к владельцу; pre-flight; verify; rollback; gotchas (SSH-порт 2222, pass-рефы) | | MinIO split (books-vds + CMS-media) | [`minio-split-cutover-runbook.md`](minio-split-cutover-runbook.md) | cutover Track A/B, rollback | | Общий Portainer-канон VDS kzntsv | [`portainer-stack-management-vds.md`](portainer-stack-management-vds.md) | JWT auth, gotchas 1-10, redeploy-рецепт, инвентарь стеков | | Политика деплоя mappa | [`deploy-policy-mappa.md`](deploy-policy-mappa.md) | кто деплоит, канон таска+письмо |