Перейти к содержимому
GitRiverGitRiver
EN
Навигация

Совместимость с интерфейсом ГитЛаба

Слой совместимости с ГитЛабом: какие вызовы его API приняты, чем отличаются ответы и что не поддерживается

GitRiver отвечает на часть вызовов ГитЛаба по адресу /api/v4 — по тому же пути, что и сам ГитЛаб. Инструменту, написанному под ГитЛаб, достаточно сменить адрес сервера и токен.

Документ описывает, что поддержано, а что нет. Не попавшее в таблицу «Поддержанные вызовы» не работает, даже если у ГитЛаба такой вызов есть.

Договор этого слоя — совпадение с ответом ГитЛаба: обещание совместимости /api/v1 на /api/v4 не распространяется, и номер v4 здесь — версия интерфейса ГитЛаба, а не GitRiver.

GitRiver также отвечает на интерфейс ГитХаба, на /api/v3 (описание). Числовые идентификаторы у диалектов ОБЩИЕ: номер репозитория в ответе /api/v3 и /api/v4 — одно и то же число.

Подключение

# python-gitlab
python3 -c "
import gitlab
gl = gitlab.Gitlab('https://git.example.org', private_token='ТОКЕН')
gl.auth(); print(gl.user.username)
"

# glab
glab auth login --hostname git.example.org --token ТОКЕН
# сервер без TLS (закрытый контур) — протокол задаётся отдельно:
glab config set --host git.example.org:8099 api_protocol http

# Terraform
provider "gitlab" {
  base_url = "https://git.example.org/api/v4/"
  token    = "ТОКЕН"
}

# curl
curl -H "PRIVATE-TOKEN: ТОКЕН" https://git.example.org/api/v4/user

Токен — обычный персональный токен доступа GitRiver. Принимаются три формы: PRIVATE-TOKEN: <…> (так ходят python-gitlab, glab, поставщик Terraform и плагин Jenkins), Authorization: Bearer <…> и Authorization: token <…>. Заголовок PRIVATE-TOKEN принимается и в /api/v1.

Адресация проекта

Проект адресуется двумя способами, как и у ГитЛаба:

  • числом — /api/v4/projects/12;
  • полным путём с закодированной чертой — /api/v4/projects/группа%2Fпроект (у подгруппы путь многосегментный: группа%2Fподгруппа%2Fпроект).

Группа — так же: /api/v4/groups/7 либо /api/v4/groups/группа. Пользователь — номером либо именем учётной записи.

Поддержанные вызовы

Вызов Состояние
GET /api/v4/version версия сервера; ею клиенты проверяют доступность
GET /api/v4/metadata то же в новой форме
GET /api/v4/user владелец токена
GET /api/v4/users поиск учётных записей; параметры username, search
GET /api/v4/users/{id} профиль; видимость — по настройке public_profiles
GET /api/v4/users/{id}/projects проекты пользователя, видимые клиенту
GET /api/v4/groups группы, видимые клиенту; параметр search
GET /api/v4/groups/{id} одна группа
GET /api/v4/groups/{id}/projects проекты группы, видимые клиенту
GET /api/v4/projects все проекты сервера, видимые клиенту; параметры owned, membership, search, order_by
GET /api/v4/projects/{id} один проект, с правами клиента
GET /api/v4/projects/{id}/repository/branches ветки, постранично; параметр search
GET /api/v4/projects/{id}/repository/branches/{branch} одна ветка
GET /api/v4/projects/{id}/repository/commits коммиты; параметры ref_name, path
GET /api/v4/projects/{id}/repository/commits/{sha} один коммит
GET /api/v4/projects/{id}/repository/tree дерево; параметры path, ref, recursive
GET /api/v4/projects/{id}/repository/files/{path} файл с содержимым в base64; параметр ref
GET /api/v4/projects/{id}/repository/files/{path}/raw сырой файл
GET /api/v4/projects/{id}/issues задачи; параметр state
POST /api/v4/projects/{id}/issues создать задачу
GET /api/v4/projects/{id}/issues/{iid} одна задача
PUT /api/v4/projects/{id}/issues/{iid} правка; state_event=close|reopen
GET /api/v4/projects/{id}/issues/{iid}/notes заметки
POST /api/v4/projects/{id}/issues/{iid}/notes добавить заметку
GET /api/v4/projects/{id}/merge_requests запросы на слияние; параметр state
POST /api/v4/projects/{id}/merge_requests создать запрос
GET /api/v4/projects/{id}/merge_requests/{iid} один запрос
PUT /api/v4/projects/{id}/merge_requests/{iid} правка; state_event=close|reopen
PUT /api/v4/projects/{id}/merge_requests/{iid}/merge слить; параметр squash
GET /api/v4/projects/{id}/merge_requests/{iid}/notes заметки
POST /api/v4/projects/{id}/merge_requests/{iid}/notes добавить заметку
GET /api/v4/projects/{id}/releases релизы; черновики — только тем, кто может писать
POST /api/v4/projects/{id}/releases создать релиз (тег должен существовать)
GET /api/v4/projects/{id}/releases/{tag_name} релиз по тегу
GET /api/v4/projects/{id}/pipelines конвейеры; параметры status, ref
GET /api/v4/projects/{id}/pipelines/{id} один конвейер
GET /api/v4/projects/{id}/pipelines/{id}/jobs задания конвейера

Изменяющие вызовы действуют так же, как те же действия через /api/v1: с проверкой прав, вебхуками, оповещениями каналов, уведомлениями и записью в ленту активности. Слияние подчиняется правилам защиты ветки и списку допущенных к слиянию.

Пока не поддержаны: участники проектов и групп, метки и вехи отдельными вызовами, обсуждения-ветки (discussions), запуск и отмена конвейеров, задания CI отдельными вызовами, вложения к релизам, вебхуки, переменные CI, repository/compare, сниппеты, эпики и GraphQL.

Постраничная выдача

Как у ГитЛаба: параметры page (с 1) и per_page (по умолчанию 20, предел 100). Соседние страницы приходят и заголовком Link (RFC 8288), и счётчиками ГитЛаба:

Заголовок Значение
X-Page номер текущей страницы
X-Per-Page размер страницы
X-Next-Page номер следующей; на последней странице пустой, как у ГитЛаба
X-Prev-Page номер предыдущей; на первой пустой
X-Total всего записей — там, где общее число известно (см. ниже)
X-Total-Pages всего страниц — там же

Браузерным клиентам эти заголовки видны: политика CORS открывает их явно.

Цена страницы не зависит от её номера: глубокие страницы обходятся так же дёшево, как первые. Исключение одно — история коммитов, о ней ниже.

X-Total и X-Total-Pages не выставляются у истории коммитов и рекурсивного дерева. Сам ГитЛаб при отключённом счёте эти заголовки тоже опускает. Обходите выдачу по X-Next-Page — он есть везде.

Что всё-таки зависит от объёма

Цена страницы истории коммитов (repository/commits) растёт с её номером: на репозитории с пятьюдесятью тысячами коммитов пятисотая страница обходится примерно в тридцать раз дороже первой. Номер страницы ограничен десятью тысячами. Клиенту, который читает историю целиком, дешевле склонировать репозиторий.

У рекурсивного дерева (repository/tree?recursive=true) выдача ограничена десятью тысячами записей: страница за этой границей отклоняется с 400 и внятной причиной. Так же поступает и сам ГитЛаб. Выборку сужают параметром path.

Ошибки

Тело отказа — {"message": "…"}, как у ГитЛаба. В эту форму приводятся все отказы слоя, в том числе несуществующий адрес, неподходящий метод, истёкший срок ответа и превышение предела частоты.

Тексты 401, 404 и 405 — канонические (401 Unauthorized, 404 Not Found, 405 Method Not Allowed), с номером кода в начале, как у ГитЛаба. Подробность о том, чего именно не нашлось, пишется в журнал сервера, а не в тело. У прочих отказов текст содержательный.

Недоступный объект отвечает 404 с тем же телом, что и несуществующий адрес: закрытое неотличимо от несуществующего. Так отвечает и сам ГитЛаб, и так же ведёт себя /api/v1. 403 остаётся там, где клиент объект видит, но прав не хватает на само действие: архивный проект, токен без нужной области доступа, предел редакции.

Отличие от диалекта ГитХаба: непрошедшая проверку сущность отдаётся с кодом 400, а не 422 — так же, как у ГитЛаба и как в /api/v1.

Расхождения

Правило слоя: поле либо несёт достоверное значение, либо не отдаётся вовсе. Подставленных «правдоподобных» значений слой не отдаёт.

Совместимость понимается так: каждый поддержанный вызов отвечает так же, как у ГитЛаба, за вычетом отличий, перечисленных ниже. Вызовы, которых нет в таблице «Поддержанные вызовы», не поддерживаются.

Осознанные отличия

Здесь — отличия ПОВЕДЕНИЯ. Отличия по составу полей перечислены ниже, в разделе «Отличия в составе полей»; тот перечень полон на день выпуска.

Что Как у нас Что учесть
GET /users/{id} видимость решает настройка сервера public_profiles; по умолчанию профили закрыты чтобы инструмент читал профили без входа, администратор включает public_profiles; настройка действует одинаково на /api/v1, /api/v3 и /api/v4. Карточка автора (author/user) у задачи, комментария, запроса на слияние, рецензии и релиза отдаётся в ответе всегда, независимо от настройки
access_level 20 Reporter, 30 Developer, 40 Maintainer уровня 50 (Owner) нет: роли владельца, отличной от администратора репозитория, в GitRiver нет
visibility проекта только public и private промежуточной видимости «внутренний» (internal) у репозитория в GitRiver нет. У групп есть все три
last_activity_at равен времени последней правки отдельного учёта активности в GitRiver нет
avatar_url проекта null загрузки изображений в GitRiver нет, а значок-идентикон есть только у пользователей и групп. null означает «картинки нет»
метки массив имён так же, как у ГитЛаба: метка там — имя, а не объект. Отдельных вызовов управления метками пока нет
state вехи active / closed значения ГитЛаба; в /api/v1 те же состояния называются open / closed
состояние конвейера canceled с одной «l» написание ГитЛаба; сравнивайте строку canceled, а не cancelled
конвейер в очереди своей группы waiting_for_resource у ГитЛаба это ожидание resource_group, у нас — группы одновременности (concurrency); смысл тот же: сборка ждёт, пока завершится другая из той же группы
id задания конвейера собственная нумерация заданий номер задания уникален среди заданий и не связан с номером конвейера — так же, как у ГитЛаба
создание запроса из форка не поддержано у ГитЛаба это target_project_id в теле; в /api/v3 путь есть (head в форме владелец:ветка)
POST /projects/{id}/releases черновик и предрелиз не выставляются у ГитЛаба этих признаков в теле нет; они есть в /api/v1 и в диалекте ГитХаба
files/{path} больше 1 МБ отказ, с указанием на /raw такой файл читается через /raw: сырая выдача пределом не ограничена
токен задания CI работает как анонимный клиент приватный проект по нему недоступен; инструменту нужен персональный токен
pipelines/{id}/jobs отдаёт все задания конвейера сразу постраничного обхода у этого вызова нет

Как заполняются поля

Поле Как у нас
id целое число, присвоенное объекту при первом обращении и не меняющееся впредь. Общее с диалектом ГитХаба: один объект — одно число в обоих ответах
адресация %2F путь проекта принимается одним параметром целиком, включая подгруппы
avatar_url пользователя и группы значок-идентикон, выводимый из имени (/avatars/{имя}.svg)
время ISO 8601 с миллисекундами и Z — форма ГитЛаба (в диалекте ГитХаба время с точностью до секунды)
content_sha256 у файла настоящая сумма содержимого; клиенты сверяют по ней скачанное
commit_id и last_commit_id у файла коммит, на который разрешился ref, и последний коммит, менявший файл, — два разных значения, как у ГитЛаба
recursive=true у дерева в выдаче и файлы, и каталоги всех уровней вложенности, как у ГитЛаба
can_push у ветки учитывает и права клиента, и защиту ветки: true только тогда, когда отправка клиента в эту ветку будет принята
признаки возможностей проекта issues_enabled, merge_requests_enabled, wiki_enabled, jobs_enabled, container_registry_enabled и те же сведения уровнями доступа. Клиент читает их ДО действия: glab issue create без issues_enabled отказывает, не пробуя создать задачу. Значения достоверны — в GitRiver возможность либо есть у всех проектов, либо её нет вовсе (snippets_enabled — false)
булевы параметры запроса принимаются в свободной форме (True, 1, yes, on), как их понимает сам ГитЛаб: python-gitlab шлёт питоновское recursive=False, и обычный обход дерева работает
state запроса на слияние у слитого запроса собственное состояние merged (в диалекте ГитХаба он closed с признаком слияния)
номера страниц у списка проектов группы и пользователя цена страницы и здесь не зависит от её номера — как и у остальных постраничных вызовов выше

Проверенные клиенты

Слой работает с python-gitlab и glab на всех поддержанных вызовах, включая постраничный обход: python-gitlab сам разбирает X-Next-Page.

Что гарантировано отдельно от формы ответа

Адресация проекта числом и путём даёт один и тот же результат. Числовые идентификаторы устойчивы между вызовами и между диалектами /api/v3 и /api/v4 — id одного репозитория совпадает в обоих. Чужой приватный репозиторий недоступен, постраничная выдача заголовками работает так, как описано выше, а настройка видимости профилей действует на /api/v1, /api/v3 и /api/v4 одинаково.

Отличия в составе полей

Перечень касается состава и типов полей ответа, в том числе вложенных, в сравнении с GitLab Community Edition 19.3.1; значений полей он не описывает.

Перечень ниже полон на день выпуска: каждое отличие в составе полей либо устранено, либо названо здесь — как у нас и почему. Необъявленных отличий выпуск не содержит.

Принятые расхождения

Перечни полей раскрываются: их сотни, и таблицей они нечитаемы. Искать поле в этом разделе следует поиском по странице — оно названо здесь целиком, вместе с путём внутри ответа.

Нет у нас — все вызовы диалекта, полей: 218.

Настройки проекта ГитЛаба, которых в GitRiver нет: автоматическое развёртывание, политики и стратегии CI, импорт, служба поддержки, правила хранения образов, выбор хранилища, уровни доступа к отдельным разделам, шаблоны сообщений и способ слияния. Достоверного значения у них нет, и по правилу слоя поле не отдаётся. Кроме того, не отдаются owner, topics, open_issues_count, updated_at, readme_url, empty_repo, у namespace нет parent_id; в списках проектов нет permissions — права клиента приходят только в ответе по одному проекту. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$._links.cluster_agents, $._links.events, $._links.labels, $._links.members, $.allow_merge_on_skipped_pipeline, $.analytics_access_level, $.auto_cancel_pending_pipelines, $.auto_devops_deploy_strategy, $.auto_devops_enabled, $.autoclose_referenced_issues, $.build_git_strategy, $.build_timeout, $.can_create_merge_request_in, $.ci_allow_fork_pipelines_to_run_in_parent_project, $.ci_config_path, $.ci_default_git_depth, $.ci_delete_pipelines_in_seconds, $.ci_display_pipeline_variables, $.ci_forward_deployment_enabled, $.ci_forward_deployment_rollback_allowed, $.ci_id_token_sub_claim_components, $.ci_id_token_sub_claim_components[], $.ci_job_token_scope_enabled, $.ci_pipeline_variables_minimum_override_role, $.ci_push_repository_for_job_token_allowed, $.ci_separated_caches, $.cicd_catalog_enabled, $.container_expiration_policy, $.container_expiration_policy.cadence, $.container_expiration_policy.enabled, $.container_expiration_policy.keep_n, $.container_expiration_policy.name_regex, $.container_expiration_policy.name_regex_keep, $.container_expiration_policy.next_run_at, $.container_expiration_policy.older_than, $.container_registry_access_level, $.creator_id, $.description_html, $.emails_disabled, $.emails_enabled, $.empty_repo, $.enforce_auth_checks_on_uploads, $.environments_access_level, $.feature_flags_access_level, $.forking_access_level, $.group_runners_enabled, $.import_error, $.import_status, $.import_type, $.import_url, $.infrastructure_access_level, $.issue_branch_template, $.keep_latest_artifact, $.lfs_enabled, $.marked_for_deletion_at, $.marked_for_deletion_on, $.max_artifacts_size, $.merge_commit_template, $.merge_method, $.model_experiments_access_level, $.model_registry_access_level, $.monitor_access_level, $.mr_default_title_template, $.namespace.parent_id, $.only_allow_merge_if_all_discussions_are_resolved, $.only_allow_merge_if_pipeline_succeeds, $.open_issues_count, $.owner, $.owner.avatar_url, $.owner.id, $.owner.locked, $.owner.name, $.owner.public_email, $.owner.state, $.owner.username, $.owner.web_url, $.package_registry_access_level, $.packages_enabled, $.pages_access_level, $.permissions.project_access.notification_level, $.printing_merge_request_link_enabled, $.protect_merge_request_pipelines, $.public_jobs, $.readme_url, $.releases_access_level, $.remove_source_branch_after_merge, $.repository_object_format, $.repository_storage, $.request_access_enabled, $.resolve_outdated_diff_discussions, $.resource_group_default_process_mode, $.restrict_user_defined_variables, $.runner_token_expiration_interval, $.runners_token, $.security_and_compliance_access_level, $.service_desk_address, $.service_desk_enabled, $.shared_runners_enabled, $.shared_with_groups, $.show_diff_preview_in_email, $.squash_commit_template, $.squash_option, $.suggestion_commit_message, $.tag_list, $.topics, $.updated_at, $.warn_about_potentially_unwanted_characters, $[]._links.cluster_agents, $[]._links.events, $[]._links.labels, $[]._links.members, $[].allow_merge_on_skipped_pipeline, $[].analytics_access_level, $[].auto_cancel_pending_pipelines, $[].auto_devops_deploy_strategy, $[].auto_devops_enabled, $[].autoclose_referenced_issues, $[].build_git_strategy, $[].build_timeout, $[].can_create_merge_request_in, $[].ci_allow_fork_pipelines_to_run_in_parent_project, $[].ci_config_path, $[].ci_default_git_depth, $[].ci_delete_pipelines_in_seconds, $[].ci_display_pipeline_variables, $[].ci_forward_deployment_enabled, $[].ci_forward_deployment_rollback_allowed, $[].ci_id_token_sub_claim_components, $[].ci_id_token_sub_claim_components[], $[].ci_job_token_scope_enabled, $[].ci_pipeline_variables_minimum_override_role, $[].ci_push_repository_for_job_token_allowed, $[].ci_separated_caches, $[].container_expiration_policy, $[].container_expiration_policy.cadence, $[].container_expiration_policy.enabled, $[].container_expiration_policy.keep_n, $[].container_expiration_policy.name_regex, $[].container_expiration_policy.name_regex_keep, $[].container_expiration_policy.next_run_at, $[].container_expiration_policy.older_than, $[].container_registry_access_level, $[].creator_id, $[].description_html, $[].emails_disabled, $[].emails_enabled, $[].empty_repo, $[].enforce_auth_checks_on_uploads, $[].environments_access_level, $[].feature_flags_access_level, $[].forking_access_level, $[].group_runners_enabled, $[].import_status, $[].import_type, $[].import_url, $[].infrastructure_access_level, $[].issue_branch_template, $[].keep_latest_artifact, $[].lfs_enabled, $[].marked_for_deletion_at, $[].marked_for_deletion_on, $[].max_artifacts_size, $[].merge_commit_template, $[].merge_method, $[].model_experiments_access_level, $[].model_registry_access_level, $[].monitor_access_level, $[].mr_default_title_template, $[].namespace.parent_id, $[].only_allow_merge_if_all_discussions_are_resolved, $[].only_allow_merge_if_pipeline_succeeds, $[].open_issues_count, $[].owner, $[].owner.avatar_url, $[].owner.id, $[].owner.locked, $[].owner.name, $[].owner.public_email, $[].owner.state, $[].owner.username, $[].owner.web_url, $[].package_registry_access_level, $[].packages_enabled, $[].pages_access_level, $[].permissions, $[].permissions.group_access, $[].permissions.group_access.access_level, $[].permissions.group_access.notification_level, $[].permissions.project_access, $[].permissions.project_access.access_level, $[].permissions.project_access.notification_level, $[].printing_merge_request_link_enabled, $[].protect_merge_request_pipelines, $[].public_jobs, $[].readme_url, $[].releases_access_level, $[].remove_source_branch_after_merge, $[].repository_object_format, $[].repository_storage, $[].request_access_enabled, $[].resolve_outdated_diff_discussions, $[].resource_group_default_process_mode, $[].restrict_user_defined_variables, $[].runner_token_expiration_interval, $[].runners_token, $[].security_and_compliance_access_level, $[].service_desk_address, $[].service_desk_enabled, $[].shared_runners_enabled, $[].shared_with_groups, $[].show_diff_preview_in_email, $[].squash_commit_template, $[].squash_option, $[].suggestion_commit_message, $[].tag_list, $[].topics, $[].updated_at, $[].warn_about_potentially_unwanted_characters

Нет у нас — все вызовы диалекта, полей: 168.

Настройки группы ГитЛаба, которых в GitRiver нет: обязательная двухфакторная проверка, ограничения на создание подгрупп и проектов, размер артефактов, общий доступ с другими группами, защита ветки по умолчанию, пометки удаления по расписанию. Кроме того, не отдаются full_name, default_branch, archived, а в ответе по одной группе — перечень shared_projects. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$.archived, $.auto_devops_enabled, $.crm_enabled, $.default_branch, $.default_branch_protection, $.default_branch_protection_defaults, $.default_branch_protection_defaults.allow_force_push, $.default_branch_protection_defaults.allowed_to_merge, $.default_branch_protection_defaults.allowed_to_merge[], $.default_branch_protection_defaults.allowed_to_merge[].access_level, $.default_branch_protection_defaults.allowed_to_push, $.default_branch_protection_defaults.allowed_to_push[], $.default_branch_protection_defaults.allowed_to_push[].access_level, $.default_branch_protection_defaults.developer_can_initial_push, $.emails_disabled, $.emails_enabled, $.enabled_git_access_protocol, $.full_name, $.lfs_enabled, $.lock_math_rendering_limits_enabled, $.lock_resource_access_token_notify_inherited, $.marked_for_deletion_on, $.math_rendering_limits_enabled, $.max_artifacts_size, $.mentions_disabled, $.organization_id, $.prevent_sharing_groups_outside_hierarchy, $.project_creation_level, $.projects[]._links.cluster_agents, $.projects[]._links.events, $.projects[]._links.labels, $.projects[]._links.members, $.projects[].allow_merge_on_skipped_pipeline, $.projects[].analytics_access_level, $.projects[].auto_cancel_pending_pipelines, $.projects[].auto_devops_deploy_strategy, $.projects[].auto_devops_enabled, $.projects[].autoclose_referenced_issues, $.projects[].build_git_strategy, $.projects[].build_timeout, $.projects[].can_create_merge_request_in, $.projects[].ci_allow_fork_pipelines_to_run_in_parent_project, $.projects[].ci_config_path, $.projects[].ci_default_git_depth, $.projects[].ci_delete_pipelines_in_seconds, $.projects[].ci_display_pipeline_variables, $.projects[].ci_forward_deployment_enabled, $.projects[].ci_forward_deployment_rollback_allowed, $.projects[].ci_id_token_sub_claim_components, $.projects[].ci_id_token_sub_claim_components[], $.projects[].ci_job_token_scope_enabled, $.projects[].ci_pipeline_variables_minimum_override_role, $.projects[].ci_push_repository_for_job_token_allowed, $.projects[].ci_separated_caches, $.projects[].container_expiration_policy, $.projects[].container_expiration_policy.cadence, $.projects[].container_expiration_policy.enabled, $.projects[].container_expiration_policy.keep_n, $.projects[].container_expiration_policy.name_regex, $.projects[].container_expiration_policy.name_regex_keep, $.projects[].container_expiration_policy.next_run_at, $.projects[].container_expiration_policy.older_than, $.projects[].container_registry_access_level, $.projects[].creator_id, $.projects[].description_html, $.projects[].emails_disabled, $.projects[].emails_enabled, $.projects[].empty_repo, $.projects[].enforce_auth_checks_on_uploads, $.projects[].environments_access_level, $.projects[].feature_flags_access_level, $.projects[].forking_access_level, $.projects[].group_runners_enabled, $.projects[].import_status, $.projects[].import_type, $.projects[].import_url, $.projects[].infrastructure_access_level, $.projects[].issue_branch_template, $.projects[].keep_latest_artifact, $.projects[].lfs_enabled, $.projects[].marked_for_deletion_at, $.projects[].marked_for_deletion_on, $.projects[].max_artifacts_size, $.projects[].merge_commit_template, $.projects[].merge_method, $.projects[].model_experiments_access_level, $.projects[].model_registry_access_level, $.projects[].monitor_access_level, $.projects[].mr_default_title_template, $.projects[].namespace.parent_id, $.projects[].only_allow_merge_if_all_discussions_are_resolved, $.projects[].only_allow_merge_if_pipeline_succeeds, $.projects[].open_issues_count, $.projects[].package_registry_access_level, $.projects[].packages_enabled, $.projects[].pages_access_level, $.projects[].printing_merge_request_link_enabled, $.projects[].protect_merge_request_pipelines, $.projects[].public_jobs, $.projects[].readme_url, $.projects[].releases_access_level, $.projects[].remove_source_branch_after_merge, $.projects[].repository_object_format, $.projects[].repository_storage, $.projects[].request_access_enabled, $.projects[].resolve_outdated_diff_discussions, $.projects[].resource_group_default_process_mode, $.projects[].restrict_user_defined_variables, $.projects[].runner_token_expiration_interval, $.projects[].runners_token, $.projects[].security_and_compliance_access_level, $.projects[].service_desk_address, $.projects[].service_desk_enabled, $.projects[].shared_runners_enabled, $.projects[].shared_with_groups, $.projects[].show_diff_preview_in_email, $.projects[].squash_commit_template, $.projects[].squash_option, $.projects[].suggestion_commit_message, $.projects[].tag_list, $.projects[].topics, $.projects[].updated_at, $.projects[].warn_about_potentially_unwanted_characters, $.request_access_enabled, $.require_two_factor_authentication, $.resource_access_token_notify_inherited, $.runners_token, $.share_with_group_lock, $.shared_projects, $.shared_runners_setting, $.shared_with_groups, $.show_diff_preview_in_email, $.subgroup_creation_level, $.two_factor_grace_period, $[].archived, $[].auto_devops_enabled, $[].crm_enabled, $[].default_branch, $[].default_branch_protection, $[].default_branch_protection_defaults, $[].default_branch_protection_defaults.allow_force_push, $[].default_branch_protection_defaults.allowed_to_merge, $[].default_branch_protection_defaults.allowed_to_merge[], $[].default_branch_protection_defaults.allowed_to_merge[].access_level, $[].default_branch_protection_defaults.allowed_to_push, $[].default_branch_protection_defaults.allowed_to_push[], $[].default_branch_protection_defaults.allowed_to_push[].access_level, $[].default_branch_protection_defaults.developer_can_initial_push, $[].emails_disabled, $[].emails_enabled, $[].full_name, $[].lfs_enabled, $[].lock_math_rendering_limits_enabled, $[].lock_resource_access_token_notify_inherited, $[].marked_for_deletion_on, $[].math_rendering_limits_enabled, $[].max_artifacts_size, $[].mentions_disabled, $[].organization_id, $[].project_creation_level, $[].request_access_enabled, $[].require_two_factor_authentication, $[].resource_access_token_notify_inherited, $[].share_with_group_lock, $[].shared_runners_setting, $[].show_diff_preview_in_email, $[].subgroup_creation_level, $[].two_factor_grace_period

Нет у нас — все вызовы диалекта, полей: 77.

Поля профиля ГитЛаба, которых в модели участника GitRiver нет: рассказ о себе, место и должность, ссылки на внешние сети, предпочтения оформления, пределы на число проектов, сведения о входах, о внешних учётных записях и о двухфакторной проверке. Не отдаются также почта (email, public_email, commit_email), время создания учётной записи (created_at) и признак администратора (is_admin). Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$.bio, $.bio_html, $.bot, $.can_create_group, $.can_create_project, $.color_scheme_id, $.commit_email, $.confirmed_at, $.created_at, $.created_by, $.current_sign_in_at, $.current_sign_in_ip, $.discord, $.email, $.external, $.github, $.highest_role, $.identities, $.is_admin, $.job_title, $.last_activity_on, $.last_sign_in_at, $.last_sign_in_ip, $.linkedin, $.local_time, $.location, $.locked, $.namespace_id, $.note, $.organization, $.preferred_language, $.private_profile, $.projects_limit, $.pronouns, $.public_email, $.sign_in_count, $.theme_id, $.twitter, $.two_factor_enabled, $.website_url, $.work_information, $[].bio, $[].bot, $[].can_create_group, $[].can_create_project, $[].color_scheme_id, $[].commit_email, $[].confirmed_at, $[].created_at, $[].created_by, $[].current_sign_in_at, $[].discord, $[].email, $[].external, $[].github, $[].identities, $[].is_admin, $[].job_title, $[].last_activity_on, $[].last_sign_in_at, $[].linkedin, $[].local_time, $[].location, $[].locked, $[].namespace_id, $[].note, $[].organization, $[].preferred_language, $[].private_profile, $[].projects_limit, $[].pronouns, $[].public_email, $[].theme_id, $[].twitter, $[].two_factor_enabled, $[].website_url, $[].work_information

Нет у нас — все вызовы диалекта, полей: 19.

Поля задачи ГитЛаба, которым в GitRiver нет соответствия: кто закрыл задачу (closed_by), число связанных запросов на слияние (merge_requests_count), критичность (severity), подписка (subscribed), ссылки на реакции и на дубликат в _links. У автора нет locked и public_email. О вехе: iid — её номер внутри проекта, а своей нумерации вех в GitRiver нет; web_url вёл бы на страницу вехи, которой в интерфейсе нет. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$._links.award_emoji, $._links.closed_as_duplicate_of, $.author.locked, $.author.public_email, $.closed_by, $.merge_requests_count, $.milestone.iid, $.milestone.web_url, $.severity, $.subscribed, $[]._links.award_emoji, $[]._links.closed_as_duplicate_of, $[].author.locked, $[].author.public_email, $[].closed_by, $[].merge_requests_count, $[].milestone.iid, $[].milestone.web_url, $[].severity

Нет у нас — все вызовы диалекта, полей: 64.

Поля запроса на слияние ГитЛаба, которым в GitRiver нет соответствия: кто слил и кто закрыл запрос (merged_by, merge_user, closed_by), сжатие коммитов (squash, squash_on_merge, squash_commit_sha), автослияние по успеху конвейера, слияние не раньше заданного времени (merge_after), ошибка слияния, признак первого вклада, время сборки и первого развёртывания, подписка, признак разрешённых обсуждений, права клиента (user). pipeline не отдаётся, а у head_pipeline нет подробного состояния, собственного номера, времени начала и конца, длительностей, автора запуска, ошибок разбора и ряда других полей. У автора нет locked и public_email. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$.author.locked, $.author.public_email, $.blocking_discussions_resolved, $.closed_by, $.first_contribution, $.first_deployed_to_production_at, $.head_pipeline.archived, $.head_pipeline.before_sha, $.head_pipeline.committed_at, $.head_pipeline.coverage, $.head_pipeline.detailed_status, $.head_pipeline.detailed_status.details_path, $.head_pipeline.detailed_status.favicon, $.head_pipeline.detailed_status.group, $.head_pipeline.detailed_status.has_details, $.head_pipeline.detailed_status.icon, $.head_pipeline.detailed_status.illustration, $.head_pipeline.detailed_status.label, $.head_pipeline.detailed_status.text, $.head_pipeline.detailed_status.tooltip, $.head_pipeline.duration, $.head_pipeline.finished_at, $.head_pipeline.iid, $.head_pipeline.queued_duration, $.head_pipeline.started_at, $.head_pipeline.tag, $.head_pipeline.updated_at, $.head_pipeline.user, $.head_pipeline.user.avatar_url, $.head_pipeline.user.id, $.head_pipeline.user.locked, $.head_pipeline.user.name, $.head_pipeline.user.public_email, $.head_pipeline.user.state, $.head_pipeline.user.username, $.head_pipeline.user.web_url, $.head_pipeline.yaml_errors, $.latest_build_finished_at, $.latest_build_started_at, $.merge_after, $.merge_error, $.merge_user, $.merge_when_pipeline_succeeds, $.merged_by, $.pipeline, $.prepared_at, $.squash, $.squash_commit_sha, $.squash_on_merge, $.subscribed, $.user, $.user.can_merge, $[].author.locked, $[].author.public_email, $[].blocking_discussions_resolved, $[].closed_by, $[].merge_after, $[].merge_user, $[].merge_when_pipeline_succeeds, $[].merged_by, $[].prepared_at, $[].squash, $[].squash_commit_sha, $[].squash_on_merge

Нет у нас — все вызовы диалекта, полей: 2.

У автора заметки нет locked и public_email. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$[].author.locked, $[].author.public_email

Нет у нас — все вызовы диалекта, полей: 28.

У ветки вложенный commit несёт только id и short_id: полный коммит даёт GET /projects/{id}/repository/commits/{sha}. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$.commit.author_email, $.commit.author_name, $.commit.authored_date, $.commit.committed_date, $.commit.committer_email, $.commit.committer_name, $.commit.created_at, $.commit.extended_trailers, $.commit.message, $.commit.parent_ids, $.commit.parent_ids[], $.commit.title, $.commit.trailers, $.commit.web_url, $[].commit.author_email, $[].commit.author_name, $[].commit.authored_date, $[].commit.committed_date, $[].commit.committer_email, $[].commit.committer_name, $[].commit.created_at, $[].commit.extended_trailers, $[].commit.message, $[].commit.parent_ids, $[].commit.parent_ids[], $[].commit.title, $[].commit.trailers, $[].commit.web_url

Нет у нас — все вызовы диалекта, полей: 2.

У последнего конвейера коммита (last_pipeline) нет собственного номера iid и времени правки updated_at. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$.last_pipeline.iid, $.last_pipeline.updated_at

Нет у нас — все вызовы диалекта, полей: 62.

У релиза нет вложенного коммита (commit), адреса commit_path и заверений (evidences) — заверения релиза подписью в GitRiver нет. В _links нет ссылок на правку и на перечни связанных задач и запросов на слияние. У автора нет locked и public_email. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$._links.closed_issues_url, $._links.closed_merge_requests_url, $._links.edit_url, $._links.merged_merge_requests_url, $._links.opened_issues_url, $._links.opened_merge_requests_url, $.author.locked, $.author.public_email, $.commit, $.commit.author_email, $.commit.author_name, $.commit.authored_date, $.commit.committed_date, $.commit.committer_email, $.commit.committer_name, $.commit.created_at, $.commit.extended_trailers, $.commit.id, $.commit.message, $.commit.parent_ids, $.commit.parent_ids[], $.commit.short_id, $.commit.title, $.commit.trailers, $.commit.web_url, $.commit_path, $.evidences, $.evidences[], $.evidences[].collected_at, $.evidences[].filepath, $.evidences[].sha, $[]._links.closed_issues_url, $[]._links.closed_merge_requests_url, $[]._links.edit_url, $[]._links.merged_merge_requests_url, $[]._links.opened_issues_url, $[]._links.opened_merge_requests_url, $[].author.locked, $[].author.public_email, $[].commit, $[].commit.author_email, $[].commit.author_name, $[].commit.authored_date, $[].commit.committed_date, $[].commit.committer_email, $[].commit.committer_name, $[].commit.created_at, $[].commit.extended_trailers, $[].commit.id, $[].commit.message, $[].commit.parent_ids, $[].commit.parent_ids[], $[].commit.short_id, $[].commit.title, $[].commit.trailers, $[].commit.web_url, $[].commit_path, $[].evidences, $[].evidences[], $[].evidences[].collected_at, $[].evidences[].filepath, $[].evidences[].sha

Нет у нас — все вызовы диалекта, полей: 80.

Поля конвейера ГитЛаба, которым в GitRiver нет соответствия: собственный номер в проекте (iid), время правки, покрытие, ошибки разбора файла (yaml_errors), подробное состояние, длительность ожидания в очереди, before_sha, committed_at, tag, признак архива; карточка автора запуска (user) не отдаётся. У заданий нет сведений об исполнителе (runner), артефактов, тегов, времени правки, вложенных коммита, проекта и автора запуска; у вложенного pipeline нет iid и updated_at. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$.archived, $.before_sha, $.committed_at, $.coverage, $.detailed_status, $.detailed_status.details_path, $.detailed_status.favicon, $.detailed_status.group, $.detailed_status.has_details, $.detailed_status.icon, $.detailed_status.illustration, $.detailed_status.label, $.detailed_status.text, $.detailed_status.tooltip, $.iid, $.queued_duration, $.tag, $.updated_at, $.user, $.user.avatar_url, $.user.id, $.user.locked, $.user.name, $.user.public_email, $.user.state, $.user.username, $.user.web_url, $.yaml_errors, $[].archived, $[].artifacts, $[].commit, $[].commit.author_email, $[].commit.author_name, $[].commit.authored_date, $[].commit.committed_date, $[].commit.committer_email, $[].commit.committer_name, $[].commit.created_at, $[].commit.extended_trailers, $[].commit.id, $[].commit.message, $[].commit.parent_ids, $[].commit.parent_ids[], $[].commit.short_id, $[].commit.title, $[].commit.trailers, $[].commit.web_url, $[].iid, $[].pipeline.iid, $[].pipeline.updated_at, $[].project, $[].project.ci_job_token_scope_enabled, $[].runner, $[].tag_list, $[].updated_at, $[].user, $[].user.avatar_url, $[].user.bio, $[].user.bot, $[].user.created_at, $[].user.discord, $[].user.followers, $[].user.following, $[].user.github, $[].user.id, $[].user.job_title, $[].user.linkedin, $[].user.local_time, $[].user.location, $[].user.locked, $[].user.name, $[].user.organization, $[].user.pronouns, $[].user.public_email, $[].user.state, $[].user.twitter, $[].user.username, $[].user.web_url, $[].user.website_url, $[].user.work_information

Нет у нас — все вызовы диалекта, полей: 5.

Сведений об агенте ГитЛаба для Kubernetes (kas) в ответе /metadata нет: такого агента в GitRiver нет. Поле уходит из перечня в том выпуске, где слой начинает его отдавать.

Поля

$.kas, $.kas.enabled, $.kas.externalK8sProxyUrl, $.kas.externalUrl, $.kas.version