Ir al contenido

Poblar un proyecto desde un repositorio de GitHub

Apunta un agente a un repositorio de GitHub y recibes un tablero operativo: cada issue como una historia, en el estado que dicta su historial, con las listas de tareas, las etiquetas y los milestones trasladados. Después ese mismo agente toma una historia, la reclama, la mueve por la máquina de estados y enlaza el pull request que abrió.

Esta página recorre ese ciclo de principio a fin. El paso de poblado tiene dos rutas: GitHub-to-EAT, el importador de código abierto de East Agile, lo hace en un solo comando (paso 3); la API de importación hace el mismo trabajo llamada a llamada (pasos 4 y 5), que es lo que conduce un agente cuando quiere el identificador del trabajo. Todo lo demás va por la API, porque el objetivo es que un agente pueda hacer el resto sin supervisión.

Esto no es una «importación con IA» aparte. El paso de poblado usa el mismo importador de GitHub que puedes ejecutar a mano desde Ajustes del proyecto → Importar / Exportar, descrito en Instrucciones de uso → Importar desde otras herramientas. El agente llama al mismo endpoint que llamarías tú. Lo que añade esta página es todo lo que lo rodea: quién guarda la clave, cómo comprobar la importación antes de que escriba, y qué hace el agente con el tablero una vez existe.

El origen GitHub en la pestaña Import / Export: propietario y repositorio rellenos, token vacío, pull requests e hitos marcados

  • Un proyecto — y una sesión o una clave ea_user_… para crearlo.
  • Una clave de agente — una clave ea_agent_… limitada a ese proyecto. El rol que necesita depende de cuánto del ciclo quieras que ejecute el agente; consulta el paso 2. Consulta también Guía de la API → Dos tipos de claves.
  • Un token de acceso personal de GitHub — con acceso de lectura a las issues del repositorio. Toda importación se autentica, porque la descarga va por la API GraphQL de GitHub y GraphQL rechaza una petición que no lleva token. Solo puedes omitirlo cuando el Tracker descarga en tu nombre: un repositorio público, en un despliegue que tiene un token compartido de reserva (el alojado eastagiletracker.com tiene uno; una instalación autoalojada no tiene ninguno hasta que su operador defina GITHUB_IMPORT_PAT), y nunca con --engine direct de GitHub-to-EAT. Consulta Tokens y límites de uso.
  • Node.js 22+ — solo para la ruta de GitHub-to-EAT del paso 3. La ruta por API no necesita más que curl.

El proyecto tiene que existir antes que la clave de agente, y tiene que crearlo una persona: las claves de agente quedan ligadas a un proyecto al emitirse y no pueden crear proyectos. Créalo en la interfaz, o con tu propia clave ea_user_…:

Ventana de terminal
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}'

La respuesta lleva el project_id que necesitan todas las llamadas de abajo.

Un propietario del proyecto crea las claves de agente en Ajustes del proyecto → Agentes. El rol que elijas decide cuánto de esta página puede hacer el agente por su cuenta, y hay dos respuestas sensatas:

  • owner — una sola clave ejecuta todo el ciclo, importación incluida. Importar es exclusivo del propietario, porque una importación reescribe la forma del proyecto entera. Emitir un agente con rol owner exige que tú mismo seas propietario del proyecto: el rol de un agente nunca puede superar al de quien lo creó.
  • member — mínimo privilegio. El agente reclama historias, las mueve, comenta y enlaza pull requests, pero no puede importar. La importación la ejecutas tú (paso 5) con tu propia clave y luego le entregas el tablero al agente.

En cualquier caso, no lo dejes en el valor por defecto. Una clave de agente nueva es viewer mientras no digas otra cosa, y un viewer puede leer el tablero pero no reclamar ni mover una historia — que es casi todo este ciclo.

Las claves de agente importan aquí por una razón que va más allá del acceso. Una clave de agente actúa como participante con nombre en un solo proyecto, así que cada historia que crea, cada cambio de estado que hace y cada comentario que escribe se le atribuye a ese agente en el historial — distinguible de tu propio trabajo en lugar de mezclado con él.

Ventana de terminal
export TRACKER_TOKEN="ea_agent_xxxxx"

Haz que el agente lea /meta antes que nada:

Ventana de terminal
curl https://eastagiletracker.com/api/v1/meta \
-H "X-TrackerToken: $TRACKER_TOKEN"

Eso responde las dos preguntas que el agente tendría que adivinar: a qué proyecto está ligada la clave (auth.project_id) y qué cambios de estado son legales para cada tipo de historia (transitions). Una feature recorre unstarted → started → finished → delivered → accepted; una chore es solo unstarted → started → accepted. Leer el mapa gana a codificarlo a mano.

GitHub-to-EAT es el importador de código abierto de East Agile: una herramienta de línea de comandos con licencia MIT que hace todo el paso de poblado — los pasos 4 y 5 de abajo — en un solo comando. Recurre a ella cuando hay una persona ante un terminal. Recurre a la API que hay debajo cuando conduce un agente sin supervisión y quiere el identificador del trabajo para consultarlo.

Necesita Node.js 22+ y no tiene dependencias de ejecución propias. Todavía no está publicada en npm, así que instálala desde el repositorio:

Ventana de terminal
git clone git@github.com:EastAgile/GitHub-to-EAT.git
cd GitHub-to-EAT
npm install --global .

Después apúntala a la clave que emitiste en el paso 2 y al proyecto que hiciste en el paso 1:

Ventana de terminal
export EAT_AGENT_KEY="ea_agent_xxxxx"
github-to-eat --project $PROJECT_ID --repo octocat/hello-world

Primero imprime una leyenda de correspondencias — exactamente cómo va a aterrizar cada tipo seleccionado — y te pide confirmación antes de escribir nada. Fuera de un terminal, en una tubería, en CI o dentro de un agente, no hay dónde mostrar esa pregunta, así que una ejecución que fuera a escribir tiene que pasar --yes; sin él la herramienta sale con 2 y no escribe nada en lugar de adivinar tu respuesta. Volver a ejecutarla es seguro: lo ya importado se salta, nunca se duplica.

BanderaQué hace
--dry-runComprobación previa y luego imprime el plan que llevaría a cabo — cuántas historias importaría, cuántas saltaría por estar ya ahí — sin escribir nada. No necesita --yes.
--includeQué tipos importar, separados por comas: issues,prs,milestones,releases,deps. Por defecto issues, y toda selección tiene que contenerlo. Son las mismas opciones que la tabla del paso 6.
--tokenTu token de acceso personal de GitHub (GITHUB_TOKEN en el entorno o en un .env también cuenta). Necesita repo, o el permiso granular Issues: Read, sobre ese repositorio. Obligatorio para un repositorio privado, para un servidor sin token compartido de reserva y siempre para --engine direct. Omítelo en el motor por defecto del servicio alojado y el Tracker gasta su propio presupuesto compartido — consulta Tokens y límites de uso.
--engineserver, el valor por defecto, envía una sola llamada /import/json y deja que el Tracker descargue, mapee y escriba. direct ejecuta esa misma tubería en tu máquina y escribe a través de la API pública — así que lee GitHub él mismo y siempre necesita un token, saliendo con 2 sin él.
--states, --milestones, --story-type, --no-comments, --no-tasksAcotan o sobrescriben la correspondencia para una ejecución; nada se persiste. Cada una implica --engine direct.

Define EAT_API_BASE y EAT_APP_BASE para apuntarla a un Tracker autoalojado o local; ambas apuntan por defecto al servicio alojado. El README lleva la referencia completa de banderas, los códigos de salida y la resolución de problemas.

Todo lo de abajo es esa misma importación conducida llamada a llamada, que es lo que quieres cuando la ejecuta un agente.

Importar es exclusivo del propietario — usa una clave de agente con rol owner, o tu propia clave si dejaste al agente como member. Ejecútala primero con dry_run, antes de dejar que escriba nada:

Ventana de terminal
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
}'

Una prueba en seco descarga de GitHub, resuelve y de-duplica exactamente igual que la real, informa de los mismos recuentos — imported, skipped, errors, unmatched — y luego revierte toda la transacción. Nada persiste y ningún evento de importación completada llega a tu registro de auditoría. Es la forma más barata de descubrir que querías incluir los milestones, o que un repo es mayor de lo que creías, mientras todavía no te cuesta nada.

Toda llamada a /import/json es asíncrona, la prueba en seco incluida: el endpoint devuelve 202 con un identificador de trabajo, no un resultado, y los recuentos llegan en el trabajo cuando lo consultas (paso 5). El trabajo de una prueba en seco alcanza done igual que el de una real; la diferencia es que no se escribió nada.

Quita dry_run y vuelve a enviarla. Como antes, el endpoint devuelve 202 con un identificador de trabajo:

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

Consulta el trabajo hasta que alcance un estado terminal:

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

El estado recorre pending → fetching → writing → done | failed. Solo los dos últimos son terminales: done lleva los recuentos del resultado, failed lleva un mensaje de error y un código de máquina estable sobre el que ramificar. Mientras la descarga pagina, progress_current y progress_total dicen por qué página va — merece la pena mostrarlo si hay una persona mirando.

Tokens. Pasa "token": "github_pat_…". Omítelo y el servidor pone el token de plataforma compartido, que solo lee repositorios públicos y cuya cuota se descuenta entre todos los llamantes del despliegue — Tokens y límites de uso cubre lo que eso te cuesta. Sea cual sea el token que se use, sirve para las llamadas ascendentes a GitHub y para nada más: nunca se registra, nunca se audita, nunca se almacena y nunca se devuelve en una respuesta ni en un error.

Volver a ejecutarla es seguro. Una fila ya importada se reconoce por su id de origen y se salta, no se duplica. Una segunda importación completa el tablero con lo que ha aparecido desde la primera.

Las issues se importan por defecto. Todo lo demás es opcional, una bandera por tipo:

Desde GitHubSe convierte enBandera
IssueUna historia. Abierta → unstarted en el Backlog. Cerrada → accepted, o rejected cuando GitHub dice que la issue se cerró como not_planned o duplicate (la historia lleva entonces una etiqueta acorde).por defecto
Lista de tareas del cuerpo de la issueTareas — cada línea - [ ] / - [x] se convierte en una tarea en el orden del cuerpo, y [x] llega completada. La lista también permanece en la descripción.por defecto
EtiquetasEtiquetas, trasladadas tal cual.por defecto
Pull requestUna historia con la etiqueta pull-request. Abierto → started, fusionado → accepted, cerrado sin fusionar → rejected.include_pull_requests
MilestoneUna épica, titulada como el milestone y de-duplicada por título — dos issues que comparten milestone caen en una misma épica. Con la bandera desactivada viaja como etiqueta milestone:<título>.include_milestones
ReleaseUna historia de release. Publicada → accepted, borrador → unstarted.include_releases
Dependencia de issueUn bloqueo sobre la historia. Solo issues, nunca pull requests.include_dependencies

El tipo de historia se infiere cuando la issue no lo dice. Una etiqueta que contenga bug, fix o defect — o un título que empiece por fix o bug — la convierte en un bug; chore, maintenance, devops o infra la convierten en una chore; cualquier otra cosa es una feature. Conviene saberlo antes de importar, porque en East Agile Tracker solo las features llevan puntos y solo las features alimentan la velocidad. Consulta Introducción → Historias.

Un tablero de proyecto justo después de importar el repositorio de ejemplo: issues como historias con sus etiquetas, hitos como épicas y personas de GitHub como propietarias

Ahora el tablero tiene historial y el agente tiene una clave. A partir de aquí el ciclo son cuatro llamadas.

Encontrar una historia, o escribir una. Filtra el tablero buscando algo que tomar:

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

import_source=github lo acota a lo que trajo la importación. Si el agente ha encontrado trabajo que el repo nunca capturó, crea la historia en su lugar — consulta Guía de la API → Crear una historia.

Reclamarla. Un agente se añade como propietario enviando un cuerpo vacío:

Ventana de terminal
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 '{}'

Un cuerpo vacío significa quien llama, así que el agente no necesita conocer su propio id. El tablero muestra ya al agente como propietario, que es como una persona que mira sabe que el trabajo está tomado.

Empezarla.

Ventana de terminal
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"}'

Después el agente va y hace el trabajo — lee el repo, escribe el código, abre el pull request. Esa parte ocurre en tu herramienta de programación, no aquí.

Adjuntar el pull request.

Ventana de terminal
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"}'

Una URL de pull request de GitHub se reconoce como tal — no hace falta decirlo. La historia y el código que la cierra quedan a un clic una del otro, en ambas direcciones.

Terminarla. Pásala a finished y párate ahí. A una feature aún le quedan delivered y accepted por delante, y esas son las puertas de revisión: alguien distinto del agente decide que el trabajo está bien. Una chore no tiene esa puerta — started → accepted es todo su camino restante.

Una issue cerrada importada cuya sección CODE enlaza el pull request que la corrigió, con los comentarios de GitHub al lado

Toda importación se autentica. La descarga de issues, comentarios y pull requests va por la API GraphQL de GitHub, y GraphQL rechaza una petición que no lleva token — no hay nivel anónimo, ni en un repositorio público ni en uno privado. La pregunta nunca es si llega un token a GitHub, solo de quién.

Pasa token en la llamada de importación, o --token a GitHub-to-EAT. Basta con un token de acceso personal granular con acceso de lectura a las issues del repositorio. Sirve para las llamadas ascendentes a GitHub y para nada más: nunca se registra, nunca se audita, nunca se almacena y nunca se devuelve en una respuesta ni en un error.

Trae el tuyo para cualquier cosa que pase de una demo. Así gastas un presupuesto que nadie más toca, y ninguna comprobación previa puede rechazarte por la importación de otro.

--engine direct no te deja elección. Ese motor lee GitHub desde tu máquina en vez de a través del Tracker, así que el token del servidor queda fuera de alcance; una ejecución sin token sale con 2 y un error de uso antes de descargar o escribir nada. GITHUB_TOKEN en tu entorno o en tu .env cuenta igual que --token.

Lo que obliga al token es el recorrido de las issues, no el motor entero. direct lee issues, comentarios y pull requests por GraphQL, que no tiene modo anónimo; solo toca REST para el listado de releases y la sonda gratuita /rate_limit. La herramienta todavía incluye un lector REST anónimo antiguo que ejecutaba una importación de repositorio público dentro del presupuesto de 60 por hora, pero ninguna ruta de la CLI llega ya hasta él y está previsto borrarlo, así que trata --token como obligatorio para direct.

No envíes ningún token y el servidor pondrá el token de plataforma que configuró su operador (GITHUB_IMPORT_PAT). Vienen con él tres límites:

  • Es configuración opcional. El alojado eastagiletracker.com provisiona uno, así que allí funciona una importación de repositorio público sin token. Una instalación autoalojada — el binario descargado — no tiene ninguno hasta que su operador defina GITHUB_IMPORT_PAT en el entorno, y hasta entonces rechaza toda importación sin token con 400 import_github_no_token.
  • Solo lee repositorios públicos. El servicio alojado lo emite de solo lectura sobre repos públicos, así que un repositorio privado siempre necesita tu propio token.
  • Todos los llamantes del despliegue comparten un presupuesto. Antes de que corra una importación sin token, el servidor lee los puntos GraphQL que le quedan al token compartido y la rechaza con 400 import_github_shared_quota_low por debajo de 500. Un presupuesto que se agota a mitad de importación hace fallar el trabajo con import_github_rate_limited_platform. Ambos mensajes nombran el mismo remedio: aportar tu propio token.

GitHub mide sus dos API por separado, y el techo sin autenticar es dos órdenes de magnitud más bajo.

API de GitHubSe usa paraCon tokenSin token
GraphQLIssues, comentarios, pull requests, sub-issues, dependencias5.000 puntos por hora, puntuados sobre los nodos que devuelve la consultaRechazado — GraphQL no tiene nivel anónimo
RESTReleases (include_releases) y la comprobación previa /rate_limit5.000 peticiones por hora60 peticiones por hora, contadas por dirección IP y compartidas con todos los que están detrás

Una importación nunca cae a ese nivel de 60 por hora: sin token que enviar, la petición se rechaza de entrada en vez de reintentarse de forma anónima. El número importa por lo que haces alrededor de la importación — un script que lee GitHub directamente, o una shell en la misma red que otros clientes, agota 60 peticiones en segundos.

Lee tu presupuesto restante cuando quieras; GET /rate_limit está exento de ambos límites, así que la comprobación no cuesta nada:

Ventana de terminal
curl -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/rate_limit

Los puntos GraphQL no son peticiones. GitHub puntúa una consulta por los nodos que devuelve, así que una página de 100 issues con sus comentarios y asignados cuesta muchos puntos, y un repositorio grande gasta el presupuesto horario en muchas menos llamadas de lo que sugieren las cifras de la era REST. --dry-run (paso 3) y dry_run (paso 4) cuestan cada uno los mismos puntos que la descarga real — eso es lo que hace fiables sus recuentos — así que presupuesta dos pasadas cuando prepares una importación grande.

  • Guía de la API — la gramática de búsqueda, el flujo de eventos, las transiciones en lote, las escrituras idempotentes y el resto de la superficie.
  • Instrucciones de uso — las mismas operaciones desde la interfaz, y los otros diez importadores.
  • Introducción — por qué la máquina de estados y los cuatro tipos de historia tienen esta forma.
  • GitHub-to-EAT — el repositorio del importador: cada bandera, ambos motores, y cómo contribuir.