La herramienta de código abierto github-issue-mover, desarrollada en Dart, facilita la transferencia de incidencias entre repositorios de GitHub. Este proceso, que a simple vista parece una acción sencilla, en realidad orquesta una secuencia de seis interacciones clave con la API de GitHub. Este artículo detalla cada una de estas llamadas esenciales, explicando su propósito, método HTTP y el momento preciso en que se invocan.
Funcionalidad de github-issue-mover
El objetivo principal de esta utilidad es "simplificar la migración de incidencias entre repositorios". Para lograrlo, ejecuta tres tareas fundamentales:
- Duplicación de Incidencias: Crea una nueva incidencia en el repositorio de destino, conservando el título, la descripción, las etiquetas y los asignados de la original.
- Establecimiento de Referencias: Genera comentarios recíprocos en ambas incidencias para indicar el movimiento ("movida a...").
- Cierre Automático: Una vez completada la migración, la incidencia de origen se cierra automáticamente.
Todo el flujo operativo se gestiona mediante un token OAuth 2.0 de GitHub. El código cliente, específicamente el frontend de la apilcación, utiliza el paquete de Dart github para interactuar directamente con la API de GitHub.
Interacciones Esenciales con la API de GitHub
A continuación, se presenta un desglose de las seis llamadas API principales involucradas en el proceso de migración de incidencias:
| # | Punto Final de la API de GitHub | Método HTTP | Momento de Activación |
|---|---|---|---|
| 1 | /user |
GET | Después de iniciar sesión, para validar el token y mostrar datos del usuario. |
| 2 | /repos/{propietario}/{repo}/issues/{número} |
GET | Al introducir la URL de la incidencia de origen. |
| 3 | /repos/{propietario}/{repo} |
GET | Tras ingresar la URL del repositorio de destino. |
| 4 | /repos/{propietario}/{repo}/issues |
POST | Al hacer clic en el botón 'Mover'. |
| 5 | /repos/{propietario}/{repo}/issues/{número}/comments |
GET + POST | Para leer y luego escribir comentarios de la incidencia original en la nueva. |
| 6 | /repos/{propietario}/{repo}/issues/{número} |
PATCH | Después de referenciar y cerrar la incidencia original. |
1. Obtener Información del Usuario Autenticado (GET /user)
Una vez que el usuario otorga la autorización, la primera acción es invocar GET /user. Esta llamada cumple una doble función:
- Confirmar Identidad: Recupera y exhibe el nombre de usuario y la imagen de perfil, validando la identidad en la interfaz.
- Verificar Token: Sirve como un control de validez del token OAuth. Si la solicitud falla (por ejemplo, con un error de autenticación), el sistema asume que el token ha expirado y redirige al usuario para una nueva autenticación.
2. Consultar Detalles de la Incidencia de Origen (GET /repos/.../issues/...)
Al introducir la URL completa de una incidencia, la aplicación primero la simplifica a un formato como propietario/repo#123. Acto seguido, se realiza una llamada a GET /repos/{propietario}/{repo}/issues/{número} para obtener todos los detalles de la incidencia. La información recuperada, que incluye el título, autor y una vista previa de la descripción en Markdown, se presenta en una "tarjeta" en la interfaz. Si la API responde con un 404, se indica que la incidencia o el repositorio no existen.
3. Validar el Repositorio de Destino (GET /repos/...)
Después de procesar la incidencia de origen, el sistema valida el repositorio de destino invocando GET /repos/{propietario}/{repo}. Esta llamada confirma la existencia del repositorio y verifica los permisos del usuario para interactuar con él, mostrando información relevante como su descripción. Una medida de seguridad adicional es deshabilitar el botón 'Mover' y mostrar una advertencia si el repositorio de destino es idéntico al de origen.
4. Crear la Réplica de la Incidencia (POST /repos/.../issues)
Al activar la migración, la aplicación construye un objeto JSON que replica los atributos esenciales de la incidencia original: título, cuerpo, etiquetas y asignados. Adicionalmente, el cuerpo de la nueva incidencia se enriquece con metadatos que indican su origen, como el autor original y la fecha de publicación, y una referencia clara a la incidencia fuente. Posteriormente, se invoca POST /repos/{propietario}/{repo}/issues para crear la nueva incidencia en el repositorio de destino. Al completarse exitosamente, la interfaz actualiza el estado, confirmando la creación y proporcionando el enlace a la nueva incidencia.
Ejemplo conceptual de solicitud POST para crear una incidencia:
{
"title": "Título duplicado de la incidencia original",
"body": "_De @autor_ el _2023-10-27_.\n\nContenido completo de la descripción original.\n\n_Copiado de la incidencia original: usuario/repositorio-origen#123_",
"labels": ["bug", "característica"],
"assignees": ["usuario_asignado_1", "usuario_asignado_2"]
}
curl -X POST \
-H "Authorization: token GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/propietario-destino/repositorio-destino/issues \
-d '{
"title": "Título duplicado de la incidencia original",
"body": "_De @autor_ el _2023-10-27_.\\n\\nContenido completo de la descripción original.\\n\\n_Copiado de la incidencia original: usuario/repositorio-origen#123_",
"labels": ["bug", "característica"],
"assignees": ["usuario_asignado_1", "usuario_asignado_2"]
}'
5. Traslado de Comentarios (GET + POST .../comments)
Esta etapa es una de las más intensivas e implica dos acciones principales:
- Lectura de Comentarios: Se realiza una llamada a
GET /repos/{propietario}/{repo}/issues/{número}/commentspara recuperra todos los comentarios asociados a la incidencia original. - Escritura de Comentarios: Cada comentario recuperado (excluyendo aquellos hechos por el propio usuario que realiza la migración) se procesa. Se le añade un prefijo que indica el autor y la fecha del comentario original (_De @comentarista el _fecha y hora_), y luego se invoca
POST /repos/{propietario}/{repo}/issues/{número}/commentspara publicarlo en la nueva incidencia. Este proceso de escritura se realiza de forma recursiva, y la interfaz proporciona una retroalimentación en tiempo real sobre el número de comentarios trasladados.
6. Referencia y Cierre de la Incidencia Original (POST + PATCH)
La fase final asegura la coherencia entre ambas incidencias:
- Crear Comentario de Referencia: Se vuelve a utilizar
POST /repos/{propietario}/{repo}/issues/{número}/commentspara añadir un comentario en la incidencia original, informando que ha sido movida y proporcionando el enlace a la nueva ubicación (por ejemplo: "Esta incidencia fue movida a nuevo_repositorio/nueva_incidencia#ABC"). - Cerrar Incidencia Original: Finalmente, se envía una solicitud
PATCH /repos/{propietario}/{repo}/issues/{número}para modificar el estado de la incidencia original, estableciendo su atributostateaclosed.
Ejemplo conceptual de solicitud PATCH para cerrar una incidencia:
{
"state": "closed"
}
Con estos pasos, el proceso se completa, y ambas incidencias quedan interconectadas y con su estado actualizado.
APIs Secundarias para la Autocompletado
Adicionalmente a las seis llamadas principales, la función de autocompletado en los campos de entrada utiliza discretamente otras cuatro APIs de GitHub:
| API de GitHub | Propósito |
|---|---|
GET /user/repos |
Recupera una lista de todos los repositorios a los que el usuario tiene acceso, para construir un caché local. |
GET /user/orgs |
Enumera las organizaciones a las que pertenece el usuario. |
GET /users/{username}/repos |
Obtiene los repositorios asociados a un usuario o una organización específica. |
GET /repos/{owner}/{repo}/issues |
Utilizado para sugerir números de incidencia una vez que se ha introducido el formato repo#. |
Estas llamadas se ejecutan y sus resultados se almacenan en caché en el frontend al iniciar sesión, permitiendo que las sugerencias de autocompletado aparezcan instantáneamente sin necesidad de realizar solicitudes repetidas a la API de GitHub.
En resumen, github-issue-mover es un ejemplo eficiente de cómo, con una combinación mínima de APIs (una para autenticación, dos para lectura de detalles, una para creación, dos para lectura/escritura de comentarios y una para actualización de estado), se puede ofrecer una experiencia de migración de incidencias completa y robusta en GitHub.