HTTP API¶
Base URL:
https://qa.videograce.ru/api/v1
Все JSON mutation-запросы должны иметь Content-Type: application/json.
Аутентификация человека¶
Browser session¶
POST /api/v1/auth/login
Content-Type: application/json
{"username":"qa1","password":"..."}
Ответ устанавливает HttpOnly session cookie и возвращает csrf_token.
Для POST и DELETE из browser session передавайте:
X-QA-CSRF: <csrf_token>
CLI session token¶
QA_TOKEN="$(
curl -fsS https://qa.videograce.ru/api/v1/auth/token \
-H 'Content-Type: application/json' \
-d '{"username":"qa1","password":"..."}' |
python3 -c 'import json,sys; print(json.load(sys.stdin)["token"])'
)"
Дальше:
Authorization: Bearer <QA_TOKEN>
Для Bearer session token CSRF header не требуется.
Аутентификация агента¶
Agent API принимает только token, выданный при регистрации:
Authorization: Bearer qaa_...
User token нельзя использовать вместо agent token и наоборот.
Пользователи¶
| Метод | Endpoint | Назначение |
|---|---|---|
GET |
/users |
Активные аккаунты |
POST |
/users |
Создать аккаунт |
POST |
/users/<id>/update |
Имя, роль, active или пароль |
DELETE |
/users/<id> |
Обезличить и удалить доступ |
Создание:
{
"username": "qa1",
"display_name": "QA Engineer",
"password": "long-random-password",
"role": "tester"
}
Увольнение без удаления истории:
{"active": false}
Окружения¶
Получить список¶
GET /environments
Создать¶
POST /environments
Content-Type: application/json
{
"name": "stage1",
"base_url": "https://stage1.videograce.ru",
"secret_ref": "env://VG_QA_STAGE1_SECRET"
}
Каталог¶
| Метод | Endpoint | Назначение |
|---|---|---|
GET |
/suites |
Список suite |
GET |
/suites/<id> |
Suite с кейсами |
POST |
/catalog/import |
Идемпотентный импорт JSON |
Прогоны¶
Создать¶
POST /runs
Content-Type: application/json
{
"suite_id": 1,
"environment_id": 2,
"mode": "combined",
"build_info": "3.0.260708 / web 609"
}
mode: manual, agent, combined.
Получить¶
GET /runs
GET /runs/<run_id>
Детальный ответ содержит cases, steps, jobs и artifacts.
Ручной результат¶
POST /case-runs/<case_run_id>/manual-result
Content-Type: application/json
{
"status": "failed",
"actual_result": "После повторного включения исходящий RTP отсутствует",
"steps": [
{"step_index": 0, "status": "passed", "comment": ""},
{"step_index": 1, "status": "passed", "comment": ""},
{"step_index": 2, "status": "failed", "comment": "trackMuted=true"}
]
}
Итог: passed, failed, skipped.
Отменить¶
POST /runs/<run_id>/cancel
Content-Type: application/json
{}
Финализировать¶
POST /runs/<run_id>/finalize
Content-Type: application/json
{"summary":"Release candidate rejected"}
Для combined-прогона с завершенной ручной частью:
{
"summary": "Manual verification only",
"skip_pending_agents": true
}
Ожидающие jobs отменяются, agent results становятся skipped.
Ручная загрузка артефакта¶
curl -fsS \
"https://qa.videograce.ru/api/v1/runs/$RUN_ID/artifacts" \
-H "Authorization: Bearer $QA_TOKEN" \
-H "X-QA-Case-Run: $CASE_RUN_ID" \
-H "X-QA-Filename-Encoded: $(python3 -c \
'import urllib.parse; print(urllib.parse.quote("Снимок экрана.png"))')" \
-H 'Content-Type: image/png' \
--data-binary @screenshot.png
Скачать:
GET /artifacts/<artifact_id>/download
Отчеты¶
GET /runs/<run_id>/report?format=json
GET /runs/<run_id>/report?format=markdown
GET /runs/<run_id>/report?format=junit
Agent API¶
| Метод | Endpoint | Ответственность |
|---|---|---|
POST |
/agent/jobs/claim |
Получить совместимый job |
POST |
/agent/jobs/<id>/heartbeat |
Продлить lease |
POST |
/agent/jobs/<id>/events |
Записать событие |
POST |
/agent/jobs/<id>/complete |
Передать итог |
POST |
/agent/runs/<run_id>/artifacts |
Загрузить artifact |
Подробный flow и примеры находятся в разделе Агенты и runner-ы.
Ошибки¶
Ошибка возвращается в едином формате:
{
"error": {
"code": "run_incomplete",
"message": "complete all cases before finalizing (2 cases remaining)"
}
}
Ориентируйтесь на error.code, а не на текст message.
| HTTP | Значение |
|---|---|
400 |
Неверный payload |
401 |
Нет или истекла аутентификация |
403 |
Нет permission или CSRF |
404 |
Объект не найден |
409 |
Конфликт состояния |
413 |
Artifact или JSON слишком большой |
415 |
Неверный Content-Type |