Перейти до вмісту

Наповнення проєкту з репозиторію GitHub

Спрямуйте агента на репозиторій GitHub — і отримаєте готову дошку: кожен issue як історія, у стані, якого вимагає її журнал змін, разом із чек-листами, мітками та віхами. Далі той самий агент бере історію, стає її власником, проводить її крізь машину станів і прикріплює відкритий ним pull request.

Ця сторінка описує весь цикл. У кроку наповнення два шляхи: GitHub-to-EAT, відкритий імпортер East Agile, робить усе однією командою (крок 3); API імпорту виконує ту саму роботу виклик за викликом (кроки 4 і 5), і саме ним керує агент, коли йому потрібен дескриптор завдання. Усе подальше йде через API, бо суть у тому, щоб решту агент робив без нагляду.

Це не окремий «ШІ-імпорт». Крок наповнення — той самий імпортер GitHub, який ви запускаєте вручну з Налаштування проєкту → Імпорт / Експорт, описаний у Посібник користувача → Імпорт з інших трекерів. Агент викликає той самий ендпоїнт, що й ви. Ця сторінка додає все довкола: хто тримає ключ, як перевірити імпорт до запису і що агент робить із дошкою, коли вона вже є.

Джерело GitHub на вкладці Import / Export: власник і репозиторій заповнені, токен порожній, pull request’и та віхи позначено

  • Проєкт — і сесія або ключ ea_user_…, яким ви його створите.
  • Ключ агента — ключ ea_agent_…, прив’язаний до цього проєкту. Яка роль йому потрібна, залежить від того, яку частину циклу має вести агент; див. крок 2. Див. також Посібник з API → Два види ключів.
  • Персональний токен доступу GitHub — з правом читати issues репозиторію. Будь-який імпорт проходить автентифікацію, бо вибірка йде через GraphQL API GitHub, а GraphQL відхиляє запит без токена. Пропустити його можна лише тоді, коли вибірку робить Tracker від вашого імені: публічний репозиторій, на розгортанні, яке має спільний запасний токен (розміщений eastagiletracker.com має такий; власна інсталяція не має жодного, доки її оператор не задасть GITHUB_IMPORT_PAT), і ніколи з --engine direct у GitHub-to-EAT. Див. Токени та ліміти запитів.
  • Node.js 22+ — лише для шляху через GitHub-to-EAT у кроці 3. Шляху через API вистачає curl.

Проєкт має існувати раніше за ключ агента, і створити його має людина: ключі агентів прив’язуються до одного проєкту під час видачі й самі проєкт не створюють. Зробіть це в інтерфейсі або власним ключем ea_user_…:

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects \
-H "X-TrackerToken: $TRACKER_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "hello-world", "iteration_length_weeks": 1}'

Відповідь несе project_id, потрібний кожному виклику нижче.

Власник проєкту створює ключі агентів у Налаштування проєкту → Агенти. Обрана роль вирішує, яку частину цієї сторінки агент зробить сам, і розумних відповідей дві:

  • owner — один ключ проходить увесь цикл, включно з імпортом. Імпортувати може лише власник, бо імпорт переписує форму проєкту цілком. Щоб видати агента з роллю owner, ви самі маєте бути власником проєкту: роль агента ніколи не перевищує роль його творця.
  • member — найменші права. Агент бере історії, рухає їх, коментує та прикріплює pull request’и, але імпортувати не може. Імпорт ви запускаєте самі (крок 5) власним ключем, а потім передаєте дошку агентові.

У будь-якому разі не залишайте типове значення. Новий ключ агента — viewer, доки ви не скажете інакше, а viewer читає дошку, але не бере й не рухає історію — тобто не робить більшої частини цього циклу.

Ключі агентів важливі тут не лише через доступ. Ключ агента виступає як іменований учасник одного проєкту, тож кожна створена ним історія, кожна зміна стану й кожен коментар приписані в журналі саме цьому агентові — відрізнювані від вашої власної роботи, а не злиті з нею.

Terminal window
export TRACKER_TOKEN="ea_agent_xxxxx"

Нехай агент прочитає /meta перш за все:

Terminal window
curl https://eastagiletracker.com/api/v1/meta \
-H "X-TrackerToken: $TRACKER_TOKEN"

Це відповідає на два питання, які агент інакше вгадував би: до якого проєкту прив’язано ключ (auth.project_id) і які переходи станів дозволені для кожного типу історії (transitions). Feature іде unstarted → started → finished → delivered → accepted; chore — лише unstarted → started → accepted. Прочитати карту краще, ніж зашити її в код.

GitHub-to-EAT — власний відкритий імпортер East Agile: інструмент командного рядка під ліцензією MIT, який виконує весь крок наповнення — кроки 4 і 5 нижче — однією командою. Беріть його, коли за терміналом сидить людина. Беріть API під ним, коли керує агент без нагляду і йому потрібен дескриптор завдання для опитування.

Йому потрібен Node.js 22+ і немає власних залежностей часу виконання. У npm він поки не опублікований, тож встановіть його з репозиторію:

Terminal window
git clone git@github.com:EastAgile/GitHub-to-EAT.git
cd GitHub-to-EAT
npm install --global .

Потім спрямуйте його на ключ із кроку 2 і проєкт із кроку 1:

Terminal window
export EAT_AGENT_KEY="ea_agent_xxxxx"
github-to-eat --project $PROJECT_ID --repo octocat/hello-world

Спершу він друкує легенду відповідностей — як саме ляже кожен обраний тип — і просить підтвердження, перш ніж щось записати. Поза терміналом, у конвеєрі, у CI чи в агенті показати цей запит нікуди, тож запуск, який писав би, зобов’язаний передати --yes; без нього інструмент завершується з кодом 2 і не пише нічого, замість того щоб вгадувати вашу відповідь. Повторний запуск безпечний: уже імпортоване пропускається, а не дублюється.

ПрапорецьЩо робить
--dry-runПопередня перевірка, потім друк плану, який було б виконано — скільки історій він імпортував би, скільки пропустив би як уже наявні — і нічого не пише. --yes не потрібен.
--includeЯкі типи імпортувати, через кому: issues,prs,milestones,releases,deps. Типово issues, і будь-який вибір мусить його містити. Це ті самі опції, що й у таблиці кроку 6.
--tokenВаш персональний токен доступу GitHub (GITHUB_TOKEN у середовищі чи в .env теж рахується). Йому потрібен repo або деталізоване право Issues: Read на цей репозиторій. Обов’язковий для приватного репозиторію, для сервера без спільного запасного токена і завжди для --engine direct. Пропустіть його на типовому рушії розміщеної служби — і Tracker витратить власний спільний бюджет; див. Токени та ліміти запитів.
--engineserver, типове значення, шле один виклик /import/json і залишає вибірку, зіставлення та запис Tracker’у. direct запускає той самий конвеєр на вашій машині й пише через публічний API — тобто читає GitHub сам і завжди потребує токен, інакше завершується з кодом 2.
--states, --milestones, --story-type, --no-comments, --no-tasksЗвужують або перекривають зіставлення для одного запуску; нічого не зберігається. Кожен із них передбачає --engine direct.

Задайте EAT_API_BASE і EAT_APP_BASE, щоб спрямувати його на самостійно розміщений або локальний Tracker; обидва типово вказують на розміщену службу. README несе повний довідник прапорців, коди виходу та розбір проблем.

Усе нижче — той самий імпорт, керований виклик за викликом, і саме це вам потрібно, коли його запускає агент.

Імпорт доступний лише власнику — використайте ключ агента з роллю owner або власний ключ, якщо залишили агента як member. Запустіть спершу з dry_run, перш ніж дозволяти запис:

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/import/json \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": "github",
"owner": "octocat",
"repo": "hello-world",
"include_pull_requests": true,
"include_milestones": true,
"dry_run": true
}'

Сухий прогін вибирає дані з GitHub, зіставляє та усуває дублікати точно як справжній, повідомляє ті самі підрахунки — imported, skipped, errors, unmatched — і потім відкочує всю транзакцію. Нічого не зберігається, і жодна подія про завершений імпорт не потрапляє до вашого журналу аудиту. Це найдешевший спосіб з’ясувати, що ви хотіли включити віхи або що репозиторій більший, ніж ви думали, — поки це ще нічого не коштує.

Кожен виклик /import/json є асинхронним, включно із сухим прогоном: ендпоїнт повертає 202 з дескриптором завдання, а не результат, а підрахунки з’являються на завданні, коли ви його опитуєте (крок 5). Завдання сухого прогону досягає стану done так само, як і справжнє; різниця в тому, що нічого не було записано.

Приберіть dry_run і надішліть знову. Як і раніше, ендпоїнт повертає 202 з дескриптором завдання:

{ "import_id": "…", "status": "pending" }

Опитуйте завдання, доки воно не досягне кінцевого стану:

Terminal window
curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/imports/$IMPORT_ID \
-H "X-TrackerToken: $TRACKER_TOKEN"

Статус іде pending → fetching → writing → done | failed. Кінцевими є лише два останні: done несе підрахунки результату, failed несе повідомлення про помилку і стабільний машинний код, за яким можна розгалужуватися. Поки вибірка йде посторінково, progress_current і progress_total кажуть, на якій вона сторінці — варто показати, якщо дивиться людина.

Токени. Передайте "token": "github_pat_…". Пропустіть його — і сервер підставить спільний платформний токен, який читає лише публічні репозиторії й витрачається на всіх викликів у розгортанні; Токени та ліміти запитів пояснює, чого це коштує. Хоч би який токен використали, він веде виклики до GitHub і нічого більше: він ніколи не потрапляє в логи, ніколи в журнал аудиту, ніколи не зберігається і ніколи не повертається у відповіді чи помилці.

Повторний запуск безпечний. Рядок, уже імпортований раніше, розпізнається за id у джерелі й пропускається, а не дублюється. Другий імпорт доповнює дошку тим, що з’явилося після першого.

6. Що потрапляє на дошку

Section titled “6. Що потрапляє на дошку”

Issues імпортуються типово. Усе інше вмикається за вибором, по одному прапорцю на тип:

З GitHubСтаєПрапорець
IssueІсторія. Відкритий → unstarted у Backlog. Закритий → accepted, або rejected, коли GitHub каже, що issue закрито як not_planned чи duplicate (історія тоді несе відповідну мітку).типово
Чек-лист у тілі issueЗавдання — кожен рядок - [ ] / - [x] стає одним завданням у порядку тексту, [x] приходить уже виконаним. Чек-лист лишається й в описі.типово
МіткиМітки, перенесені як є.типово
Pull requestІсторія з міткою pull-request. Відкритий → started, влитий → accepted, закритий без злиття → rejected.include_pull_requests
ВіхаЕпік, названий за віхою й позбавлений дублів за заголовком — два issue зі спільною віхою потрапляють в один епік. З вимкненим прапорцем вона їде як мітка milestone:<заголовок>.include_milestones
РелізІсторія релізу. Опублікований → accepted, чернетка → unstarted.include_releases
Залежність issueБлокер на історії. Лише issues, ніколи pull request’и.include_dependencies

Тип історії виводиться, коли issue його не називає. Мітка, що містить bug, fix або defect, — чи заголовок, що починається з fix або bug, — робить її багом; chore, maintenance, devops чи infra роблять її chore; усе інше — feature. Про це варто знати до імпорту, бо в East Agile Tracker points несуть лише features і лише features живлять velocity. Див. Вступ → Історії.

Дошка проєкту одразу після імпорту демонстраційного репозиторію: issues стали історіями з мітками, віхи — епіками, люди з GitHub — власниками

7. Агент працює над історією

Section titled “7. Агент працює над історією”

Тепер дошка має журнал змін, а агент — ключ. Далі цикл укладається в чотири виклики.

Знайдіть історію або напишіть її. Відфільтруйте дошку, щоб знайти, що взяти:

Terminal window
curl "https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories?state=unstarted" \
-H "X-TrackerToken: $TRACKER_TOKEN"

import_source=github звужує вибірку до того, що приніс імпорт. Якщо агент знайшов роботу, якої репозиторій ніколи не фіксував, він створює історію сам — див. Посібник з API → Створення історії.

Візьміть її собі. Агент додає себе власником, надіславши порожнє тіло:

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/owners \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

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

Розпочніть її.

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/transitions \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"to": "started"}'

Далі агент іде й робить роботу — читає репозиторій, пише код, відкриває pull request. Ця частина відбувається у вашому інструменті розробки, не тут.

Прикріпіть pull request.

Terminal window
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/links \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/octocat/hello-world/pull/42"}'

URL pull request’а на GitHub розпізнається сам — казати про це не треба. Історія і код, що її закриває, тепер за один клік один від одного, в обидва боки.

Завершіть її. Переведіть у finished і зупиніться. У feature попереду ще delivered і accepted, і це ворота перевірки: що роботу зроблено правильно, вирішує хтось, окрім агента. У chore таких воріт немає — started → accepted і є весь її залишковий шлях.

Імпортований закритий issue: у розділі CODE посилання на pull request, що його виправив, поруч коментарі з GitHub

Токени та ліміти запитів

Section titled “Токени та ліміти запитів”

Будь-який імпорт проходить автентифікацію. Вибірка issues, коментарів і pull request’ів іде через GraphQL API GitHub, а GraphQL відхиляє запит без токена — анонімного рівня немає ні для публічного репозиторію, ні для приватного. Питання не в тому, чи дійде токен до GitHub, а лише чий.

Передайте token у виклику імпорту або --token у GitHub-to-EAT. Досить деталізованого персонального токена доступу з правом читати issues репозиторію. Він веде виклики до GitHub і нічого більше: ніколи не потрапляє в логи, ніколи в журнал аудиту, ніколи не зберігається і ніколи не повертається у відповіді чи помилці.

Для всього серйознішого за демонстрацію приносьте свій. Тоді ви витрачаєте бюджет, якого ніхто більше не торкається, і жодна попередня перевірка не відмовить вам через чужий імпорт.

--engine direct не лишає вибору. Цей рушій читає GitHub із вашої машини, а не через Tracker, тож токен сервера недосяжний; запуск без токена завершується з кодом 2 і помилкою використання ще до того, як щось вибере чи запише. GITHUB_TOKEN у вашому середовищі чи в .env рахується так само, як --token.

Токен вимагає обхід issues, а не весь рушій. direct читає issues, коментарі та pull request’и через GraphQL, у якого немає анонімного режиму; REST він торкається лише заради списку releases і безкоштовної проби /rate_limit. Інструмент досі містить старіший анонімний REST-завантажувач, який проводив імпорт публічного репозиторію в межах ліміту 60 на годину, але жоден шлях CLI до нього вже не доходить і його мають видалити — тож вважайте --token обов’язковим для direct.

Спільний токен розгортання

Section titled “Спільний токен розгортання”

Не надсилайте token — і сервер підставить платформний токен, налаштований його оператором (GITHUB_IMPORT_PAT). З ним ідуть три обмеження:

  • Це необов’язкове налаштування. Розміщений eastagiletracker.com надає такий токен, тож імпорт публічного репозиторію без токена там працює. Власна інсталяція — завантажений бінарник — не має жодного, доки її оператор не задасть GITHUB_IMPORT_PAT в оточенні, і до того часу вона відхиляє кожен імпорт без токена помилкою 400 import_github_no_token.
  • Він читає лише публічні репозиторії. Розміщена служба видає його тільки на читання публічних репозиторіїв, тож приватному репозиторію завжди потрібен ваш власний токен.
  • Усі виклики в розгортанні ділять один бюджет. Перш ніж запустити імпорт без токена, сервер читає залишок очок GraphQL спільного токена і відхиляє запит із 400 import_github_shared_quota_low нижче 500. Бюджет, що скінчився посеред імпорту, валить завдання з import_github_rate_limited_platform. Обидва повідомлення називають те саме розв’язання: дати свій токен.

GitHub рахує свої два API окремо, і стеля без автентифікації на два порядки нижча.

API GitHubВикористовується дляЗ токеномБез токена
GraphQLIssues, коментарі, pull request’и, вкладені issues, залежності5 000 очок на годину, нарахованих за вузлами, які повертає запитВідмова — у GraphQL немає анонімного рівня
RESTРелізи (include_releases) і попередня перевірка /rate_limit5 000 запитів на годину60 запитів на годину, рахованих на IP-адресу і поділених з усіма за нею

Імпорт ніколи не скочується на цей рівень у 60 на годину: коли надсилати нічого, запит відхиляється заздалегідь, а не повторюється анонімно. Число важливе для того, що ви робите довкола імпорту — скрипт, який читає GitHub напряму, або оболонка в одній мережі з іншими клієнтами вичерпує 60 запитів за секунди.

Читайте залишок бюджету будь-коли; GET /rate_limit звільнений від обох лімітів, тож перевірка нічого не коштує:

Terminal window
curl -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/rate_limit

Очки GraphQL — не запити. GitHub оцінює запит за вузлами, які він повертає, тож одна сторінка зі 100 issues разом з їхніми коментарями та призначеними коштує багато очок, а великий репозиторій витрачає годинний бюджет за значно меншу кількість викликів, ніж підказують цифри епохи REST. --dry-run (крок 3) і dry_run (крок 4) коштують кожен стільки ж очок, скільки справжня вибірка — саме це робить їхні підрахунки надійними — тож закладайте два проходи, коли готуєте великий імпорт.

  • Посібник з API — граматика пошуку, потік подій, масові переходи, ідемпотентні записи та решта поверхні.
  • Посібник користувача — ті самі операції з інтерфейсу і решта десять імпортерів.
  • Вступ — чому машина станів і чотири типи історій влаштовані саме так.
  • GitHub-to-EAT — власний репозиторій імпортера: кожен прапорець, обидва рушії та як зробити внесок.