REST API · Cloud

Jira Cloud REST API: добавляем метку без замены остальных

Одна учебная задача, операция update.labels.add, проверка исходных меток, обработка неопределённого результата и откат через remove без восстановления устаревшего списка.

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

Задача и отличие добавления от замены

Интеграции нужно отметить обработанную задачу, сохранив метки, которые уже поставила команда. Для пилота возьмём нейтральную метку pilot-rest-check и одну учебную задачу PILOT-1. Если отправить в fields.labels только новую метку, это будет задание значения списка, а не команда добавить один элемент. Поэтому для точечного изменения используем явную операцию add в update.labels.

Сценарий относится к Jira Cloud REST API v3. Cloud обновляется непрерывно; номер API не является версией установленной Jira. Для Data Center нужны отдельная документация REST, поддерживаемая версия и свой способ аутентификации. Учебные JSON ниже не отправлялись в реальную Jira при подготовке материала: ожидаемые результаты ещё нужно подтвердить в своей тестовой среде.

Цель пилота — проверить ограниченное изменение, а не запустить обработку всего проекта. Не добавляйте одновременно комментарии, переходы статуса и изменения исполнителя: при неожиданном результате будет сложнее понять причину. Само добавление метки также может запускать существующие правила автоматизации, поэтому заранее согласуйте нейтральную задачу с владельцем тестового процесса.

Подготовьте доступ и базовый адрес API

Понадобятся доступ к учебной задаче, право её редактировать и разрешённый организацией способ вызова API. Для ручного пилота настройте аутентификацию в доверенном HTTP-клиенте: Basic auth использует email Atlassian и API token, а не пароль аккаунта. Для полноценной интеграции выбирайте подходящий механизм, например OAuth или Forge, отдельно от этого упражнения. Не сохраняйте токен в коллекции для общего доступа, истории команд, Git или журнале запросов.

Базовый URL зависит от типа доступа. Для API token со scopes используйте шлюз https://api.atlassian.com/ex/jira/{cloudId}, подставив Cloud ID своего сайта. Для поддерживаемого обычного токена без scopes применяется адрес сайта https://your-site.atlassian.net. Не смешивайте Cloud ID с Organization ID. Далее пути /rest/api/3/... добавляются к выбранному базовому адресу; заголовок Authorization в примерах намеренно не приведён.

Проверьте сроки и scopes токена, а также права самой учётной записи. Важны и просмотр проекта, и Edit issues, и доступ к конкретной задаче при включённой безопасности задач. Наличие токена не добавляет прав Jira. Для проверки отказа подготовьте отдельную запись, которая видит эту учебную задачу, но не может её редактировать; не меняйте для этого рабочие роли команды.

Прочитайте исходные метки и проверьте возможность изменения

Выполните GET /rest/api/3/issue/PILOT-1?fields=labels с Accept: application/json. Сверьте возвращённый ключ с учебной задачей и сохраните только исходные метки в закрытом журнале пилота. Для понятной проверки заранее добавьте вручную keep-a и keep-b. Убедитесь, что pilot-rest-check пока отсутствует: это позволит однозначно отличить своё изменение от исходного состояния.

Запрос GET /rest/api/3/issue/PILOT-1/editmeta помогает изучить доступные поля и операции. Если Labels есть в ответе, проверьте поддержку add и remove. При отсутствии поля остановите пилот и разберите конфигурацию с администратором. Не считайте editmeta полной копией поведения Edit issue: в текущем Cloud метод изменения больше не требует наличия поля на экране, а метаданные могут учитывать экранные ограничения. Не включайте административные override-параметры ради обхода отказа.

GET /rest/api/3/issue/PILOT-1?fields=labels
Accept: application/json

GET /rest/api/3/issue/PILOT-1/editmeta
Accept: application/json

Добавьте только одну учебную метку

Создайте запрос PUT /rest/api/3/issue/PILOT-1. Установите Accept: application/json и Content-Type: application/json, затем вставьте приведённое тело. Не добавляйте рядом fields.labels и не пересылайте полный ответ предыдущего GET как тело изменения. Запрос должен выражать только согласованную операцию над конкретной меткой.

Ожидаемый ответ при обычном успешном вызове — HTTP 204 No Content. У такого ответа нет обязательного JSON-тела, поэтому попытка всегда разбирать его как JSON может создать ложное впечатление сбоя. Запишите статус HTTP и факт отправки, но не заголовок авторизации. Успешный статус ещё нужно сопоставить с последующим чтением задачи.

{
  "update": {
    "labels": [
      {"add": "pilot-rest-check"}
    ]
  }
}

Сверьте результат, исходные значения и побочные действия

Повторите GET с fields=labels и проверьте три отдельных условия: pilot-rest-check появился, keep-a сохранился, keep-b сохранился. Сравнивайте наличие значений, а не порядок массива. В интерфейсе Jira проверьте ту же задачу и историю изменения; если метку уже обработало другое правило, сохраните время и причину расхождения для разбора.

Дополнительно просмотрите журнал согласованных автоматизаций, реагирующих на метки. Не обещайте отсутствие уведомлений или других действий только потому, что запрос содержал одно поле. Проверка относится к настройкам вашей среды, а не к универсальному поведению любого сайта Jira. Если обнаружен неожиданный переход или назначение, остановите пилот до выяснения причины.

Отдельно согласуйте сценарий параллельного изменения: другой участник добавляет нейтральную метку, затем вы повторно читаете задачу. Её значение также должно сохраниться. Операция add позволяет не отправлять обратно весь прочитанный список, но не является блокировкой задачи и не гарантирует транзакцию между вашим GET и последующим PUT.

  • Новая метка есть, исходные метки не потеряны.
  • Ключ задачи соответствует пилоту; соседняя задача не изменялась этим запросом.
  • Правила и уведомления проверены в границах согласованной среды.
  • Результат записан без токенов и полного содержимого рабочих задач.

Проверьте отказ и обработайте неопределённый результат

Под записью без Edit issues отправьте PUT для той же видимой учебной задачи, заменив значение в add на отдельную метку pilot-rest-denied. Заранее проверьте, что её нет. Запрос должен завершиться отказом, а последующий GET под разрешённой записью — подтвердить отсутствие этой метки. Не меняйте для проверки права рабочих пользователей и не считайте один только неизменившийся список доказательством корректного отказа.

HTTP 400 требует проверки JSON, имени поля и значения. При 401 проверьте способ входа, срок и действительность токена. При 403 или 404 проверьте пользователя, проект и видимость задачи: 404 не всегда означает, что ключ ошибочен. Permission helper помогает разбирать права конкретного пользователя на конкретную задачу. Не выдавайте глобального администратора как стандартное исправление интеграции.

При HTTP 429 учитывайте Retry-After и ограничивайте повторные попытки. При таймауте после PUT результат неопределён: сначала прочитайте labels, а уже затем решайте, нужен ли повтор. Не запускайте бесконечный цикл и не обещайте универсальную идемпотентность всех операций Jira. Журнал должен позволять отличить неотправленный запрос от отправленного запроса без полученного ответа.

Верните исходное состояние точечным удалением

Если пилот сам добавил ранее отсутствовавшую pilot-rest-check, выполните PUT на тот же адрес с операцией remove ниже. После ответа снова прочитайте labels: учебная метка должна исчезнуть, а keep-a, keep-b и согласованные параллельные изменения должны остаться. Не восстанавливайте весь старый массив из журнала: за время проверки в задаче могли появиться нужные новые метки.

Если метка существовала до пилота или её уже использует другой процесс, автоматическое удаление не считается безопасным откатом. Сначала согласуйте принадлежность изменения с владельцем задачи. Откат метки не отменяет письма, внешние вызовы или переходы, которые успело выполнить правило: такие последствия разбираются отдельно по истории и журналу автоматизации.

{
  "update": {
    "labels": [
      {"remove": "pilot-rest-check"}
    ]
  }
}

Условия переноса в рабочую интеграцию

Перед расширением зафиксируйте назначение метки, владельца её словаря, перечень разрешённых проектов и правила реакции. Избегайте множества почти одинаковых написаний: иначе поиск и отчёты будут расходиться даже при корректном REST-запросе. Массовое переименование меток — отдельная операция с собственной выборкой и приёмкой, а не продолжение этого одиночного PUT.

Для автоматического исполнения нужны согласованный способ аутентификации, ограниченный доступ, контроль числа запросов, сверка после сбоев и понятный порядок остановки. Не переносите пилот сразу на все найденные задачи. Сначала подтвердите положительный результат, отказ в лишнем доступе и точечный откат, затем определите небольшой следующий объём вместе с владельцем процесса.

В этом материале проверены документация и структура JSON-примеров; запросы в реальной Jira не выполнялись. Собственные результаты пилота записывайте отдельно с указанием среды и ограничений. Успешная отправка одного запроса не подтверждает готовность всей интеграции и не заменяет проверку её ошибок и побочных действий.

Официальная документация

Применить это к вашей системе

Обсудим контекст, ограничения и безопасный порядок изменений.

Обсудить задачу