# SourceCraft API — шпаргалка > Issues и PR ведём в Gitea ([`GITEA_API.md`](GITEA_API.md), ADR-010). Здесь нужны в основном CI-прогоны, логи и секреты; > разделы про issues/метки/PR — справочно (бот и скрипты могут работать с `tgit-uploads`). Справочник: [методы](https://sourcecraft.dev/portal/docs/en/api-ref/index.md) · [интерактивный](https://api.sourcecraft.tech/docs/index.html) · [swagger.json](https://api.sourcecraft.tech/sourcecraft.swagger.json) ```bash set -a; . ./.env; set +a # SOURCECRAFT_TOKEN R=https://api.sourcecraft.tech/repos/rogachevegorushka/tgit H="Authorization: Bearer $SOURCECRAFT_TOKEN" alias curl='curl --retry 4 --retry-all-errors --retry-delay 2' J="Content-Type: application/json" ``` > В CI вместо личного токена — предопределённая переменная `SOURCECRAFT_TOKEN`. ## Подводные камни - Соединение с `api.sourcecraft.tech` иногда рвётся (`curl: (35)`, пустой ответ) — отсюда `--retry`. Перед повторным POST проверить, не создалась ли сущность. - `color` у метки — hex **без** `#` (`"ff7f0e"`), иначе `400 ValidationError`. - Ответы-списки кладут элементы в разные ключи: `/issues` → `issues`, `/labels` и `/milestones` → `items`, `/pulls` → `pull_requests`, метки issue → `labels`, связи → `links`. - Веха в issue задаётся `milestone_id` (UUID); `milestone_slug` отвергается с `400 must be a valid ID`. - Issue адресуется номером (`issues/1`), метка — slug'ом (`size/0.5` → `size-0-5`). - Тело issue — поле `description` (не `body`); тело комментария — `body`. - Длинный markdown удобнее собрать в JSON-файл и передать `--data @file.json`. ## Issues ```bash # список / одна curl -s -H "$H" "$R/issues" curl -s -H "$H" "$R/issues/1" # создать (status_slug: open | inProgress | paused | closed | declined | duplicate) curl -s -X POST -H "$H" -H "$J" "$R/issues" --data @issue.json # issue.json: {"title": "...", "description": "...", "label_slugs": ["bot","feature","size-1"], "status_slug": "open"} # обновить (описание, статус, исполнитель) curl -s -X PATCH -H "$H" -H "$J" "$R/issues/1" -d '{"status_slug":"closed"}' # комментарий curl -s -X POST -H "$H" -H "$J" "$R/issues/1/comments" -d '{"body":"текст"}' # метки issue: POST — добавить, PUT — заменить, DELETE — убрать curl -s -X POST -H "$H" -H "$J" "$R/issues/1/labels" -d '{"slugs":["ci"]}' # связь между issue (related_to | parent_of | subissue_of | blocks | blocked_by | duplicates | duplicated_by) curl -s -X POST -H "$H" -H "$J" "$R/issues/9/issue_links" -d '{"target_issue_slug":"8","link_type":"blocked_by"}' ``` ## Вехи ```bash curl -s -H "$H" "$R/milestones" curl -s -X POST -H "$H" -H "$J" "$R/milestones" -d '{"name":"M5 · …","description":"…"}' # → id для milestone_id ``` ## CI/CD ```bash curl -s -H "$H" "$R/cicd/runs" # прогоны curl -s -H "$H" "$R/cicd/runs/" # статус прогона curl -s -H "$H" "$R/cicd/logs////" # лог куба # секрет: 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). ## Метки репозитория ```bash curl -s -H "$H" "$R/labels" curl -s -X POST -H "$H" -H "$J" "$R/labels" -d '{"name":"size/1","slug":"size-1","color":"a0a0a0"}' ``` Заведены: зоны `bot` `ci` `infra` `llm` `docs` · типы `feature` `fix` `refactor` · размеры `size/0.5` `size/1` `size/2`. ## Pull requests ```bash # создать PR в dev curl -s -X POST -H "$H" -H "$J" "$R/pulls" --data @pr.json # pr.json: {"title": "...", "description": "...", "source_branch": "feat/2-x", "target_branch": "dev", "publish": true} curl -s -H "$H" "$R/pulls/1" curl -s -H "$H" "$R/pulls/1/merge-checks" # мерж (rebase | squash, delete_branch) curl -s -X POST -H "$H" -H "$J" "$R/pulls/1/merge" -d '{"delete_branch": true}' ```