Когда руководство решило перевести проектный трекинг с Яндекс.Трекера на JIRA, мы быстро поняли: простого "экспорта-импорта" не будет. Ни одно из готовых решений не справлялось с задачей полноценно — а именно с сохранением всей истории, авторства, чек-листов, вложений, связей, ссылок на другие задачи и пользователей, и даже оригинальной нумерации задач из Яндекс.Трекера.
Что ж, вызов принят. Ниже расскажу, как я за 3 месяца написал систему, которая перенесла всё — до последней запятой в комментарии.
🔍 Цель миграции
Хотелось получить не просто "скопированные тикеты", а максимально идентичную JIRA-копию всей истории проекта. Без потери структуры, смысла и ссылок между элементами.
Цель:
✅ Перенос задач из Яндекс.Трекера в JIRA
✅ Сохранение:
-
авторства и ответственных
-
статусов, приоритетов, компонентов
-
чек-листов
-
всех комментариев и ссылок внутри них
-
вложений и inline-файлов
-
связей между задачами
-
нумерации тикетов
✅ Возможность восстановления после сбоя
✅ Поддержка большого количества задач и вложений
🔧 Архитектура проекта
Чтобы не утонуть в сотнях нюансов и не потерять контроль, я собрал систему по модульному принципу. Компоненты:
-
app.js— координатор: управляет процессом "переезда", логирует этапы -
yandex-tracker.service.js— подключение к API Yandex Tracker -
jira-service.js— подключение к JIRA, создание задач, вложений, комментариев -
service-adapter.js— преобразование данных: markdown → wiki, чек-листы, связи -
command-manager.js— выполнение миграции по шагам, возможность восстановления -
logger.js— обычный логгер singleton
🧠 Ключевые фичи
📌 1. Постраничная загрузка
Задачи из Яндекс загружаются порциями по 100, чтобы не упасть по лимитам API.
🧱 2. Восстановление после падения
Каждое действие по переносу данных сперва записыватся в "команду" с общей структурой "было-стало(должно стать)". По мере выполнения команд результаты (id задач, комментариев, вложений и т.д.) записываются. В случае сбоя процесс можно продолжить с места остановки. В случае необходимости использовать результаты в переносе другой очереди для сохранения ссылок между тикетами разных очередей можно использовать базу данных результатов.
🔄 3. Markdown → JIRA wiki
Я использовал парсер, переводящий markdown в формат JIRA, включая:
-
списки
-
таблицы
-
заголовки
-
код-блоки
-
ссылки на пользователей и задачи
🔗 4. Сохранение связей
Все связи между задачами, а также упоминания пользователей и задачи в комментариях — переведены в соответствующий синтаксис JIRA.
📎 5. Вложения
Все прикреплённые файлы перенесены. Даже те, что были вставлены "внутрь" описания задачи или комментариев.
🧪 Пример задачи
До:
-
KEY-123, автор — Иванов, компонент — Frontend -
markdown-описание
-
чек-лист
-
комментарии с ссылками на
KEY-456и@petrov -
3 вложения
После:
-
KEY-123в JIRA, тот же автор, тот же компонент -
описание в wiki-разметке
-
чек-лист в виде таблицы
-
комментарии с
jira:issueиjira:user -
все файлы прикреплены
⚙️ Использованные технологии
-
Node.js
-
REST API Яндекс.Трекера и JIRA (Data Center 9.13)
-
dotenv,fs -
markdown → wiki парсер
-
IAM-токены и base64-авторизация
💡 Результат
-
✅ Перенесено более 4500 задач
-
✅ Все связи, комментарии, файлы и история сохранены
-
✅ Вся архитектура логирована и масштабируема
-
✅ Код пригоден для адаптации к другим системам
❗ Что было сложным
-
JIRA не позволяет менять
issueKey— пришлось использовать ссылку из оригинальной задачи в качестве CustomField -
Markdown и wiki несовместимы — без парсера терялись важные элементы
-
Ограничения API на количество вложений, тайм-ауты и rate limits
-
Ограниченные возможности по тестированию - в масштабе 4к задач попадались уникальные, структрура, принцип ссылки на пользователей, другие задачи иногда бьыли специфичными. Такие задачи трудно выявить, понадобился механизм, своевременно и оперативно предупреждающий о таких кейсах, а также алгоритм, быстро и гибко адаптируемый к подобным изменениям и отвесчающий требованиям гибкости, масштабируемости, наблюдаемости
🔚 Вывод
Можно было пойти простым путём — CSV и ручной импорт. Но тогда мы бы потеряли:
-
чек-листы
-
связи
-
форматирование
-
авторство
Вместо этого — я сделал инструмент, которым можно реально переехать без боли.
💬 Если вы тоже стоите перед задачей миграции — пишите. Поделюсь опытом или исходниками.
Личное послесловие
Этот проект родился в непростое для меня время — в период тревоги, бессонных ночей и внутренней неуверенности. Казалось бы, не лучший момент для сложной инженерной работы. Но именно она и стала для меня точкой опоры.
Вместо того чтобы «выпасть» из процесса, я решил превратить это в задачу: не просто перенести тикеты из одной системы в другую, а доказать самому себе, что могу, несмотря ни на что. И это сработало.
Код стал не только инструментом, но и способом сохранить фокус, порядок, смысл — даже тогда, когда на уровне ощущений всё казалось зыбким.
Если вы проходите через что-то подобное — знайте: иногда один законченный проект может значить больше, чем просто набор pull request’ов. Это может быть шаг назад к себе.
Автор: mrdrey
