# Automatización de publicaciones en GitHub con agentes de IA y aprobación

La automatización de publicaciones debería eliminar el trabajo administrativo, no dar a un agente de programación autoridad para distribuir software cuando considere que está listo. Un agente puede recopilar cambios, calcular una versión, compilar una candidata, redactar notas y reunir artefactos. Para publicar o revertir una versión, una persona debe revisar una solicitud concreta y aprobar esa acción específica.

Este límite parece conservador hasta que tienes que arreglar una publicación que incluía el binario equivocado, una etiqueta movida o unas notas que prometían una solución que nunca llegó al producto. La llamada a la API es sencilla. Revertir sus consecuencias normalmente no lo es.

## Dale al agente un banco de trabajo para publicaciones, no el control del repositorio

Un agente de publicación debería tener un conjunto pequeño y explícito de operaciones que corresponda al trabajo que quieres que realice. El acceso amplio de escritura al repositorio parece práctico porque evita diseñar una interfaz. También permite que una instrucción equivocada convierta una tarea de publicación en la eliminación de una etiqueta, la modificación de una rama, cambios en los flujos de trabajo o un anuncio público.

Para automatizar publicaciones en GitHub, separo la preparación de la distribución. El agente puede leer los metadatos del repositorio, inspeccionar commits en un intervalo aprobado, ejecutar la compilación, calcular hashes de los artefactos, crear o actualizar una versión en borrador y subir artefactos a ese borrador. No puede publicar una versión, eliminarla, cambiar una etiqueta, modificar la configuración del repositorio, crear tokens ni invocar un endpoint arbitrario de GitHub.

Escribe las acciones permitidas como verbos con entradas fijas. Esto resulta más útil que decirle a un agente que «tenga cuidado».

- `inspect_release_range(base_tag, head_sha)` devuelve commits y pull requests
- `build_candidate(head_sha)` devuelve artefactos y resúmenes SHA-256
- `create_draft(version, target_sha, notes)` devuelve un identificador de borrador
- `upload_asset(draft_id, filename, digest)` sube un archivo verificado
- `request_publish(draft_id)` crea una solicitud de aprobación

El verbo final importa. `request_publish` no debe publicar en silencio si nadie responde. Debe devolver un estado pendiente que quien realiza la llamada pueda mostrar y consultar. Un flujo de publicación que interpreta un tiempo de espera como consentimiento ya ha anulado su propio control.

Evita una salida de emergencia como `github_api(method, path, body)`. Los equipos la añaden para esa operación excepcional que no encajaba en su primer diseño. Con el tiempo, el agente la utilizará porque los modelos de lenguaje prefieren el camino más corto dentro de una interfaz. Cada método de solicitud sin restricciones convierte de nuevo tu autoridad limitada en un token general del repositorio.

La misma regla se aplica al acceso al shell. No expongas `gh` con argumentos arbitrarios y lo llames interfaz de publicación. Envuelve las operaciones concretas que aceptas, valida sus argumentos y rechaza todo lo demás. Si el mes que viene necesitas una acción nueva, añádela de forma deliberada, pruébala y decide dónde debe estar la confirmación.

## Una versión en borrador es un objeto de revisión, no una versión publicada

Una versión en borrador de GitHub te permite preparar el registro público sin hacerlo público. Esa diferencia da a la persona revisora algo concreto que examinar: la versión, el commit de destino, las notas generadas, los archivos adjuntos, las sumas de comprobación y el estado de prepublicación. Un mensaje que diga «lista para publicar la versión v2.4.0» no aporta pruebas suficientes.

La documentación REST de GitHub distingue entre crear una versión con `draft: true` y publicarla cambiando el estado del borrador. GitHub también documenta que `make_latest` determina qué versión presenta como la más reciente. Estos campos pueden parecer simples metadatos, pero afectan a los usuarios y a las herramientas. Trátalos como decisiones de publicación, no como valores predeterminados que el agente deba deducir.

Una solicitud sólida incluye identificadores inmutables. La cadena de versión resulta útil para las personas, pero el SHA del commit identifica el código fuente que realmente revisaste. El resumen del artefacto identifica el archivo que realmente compilaste. Si la solicitud solo dice «publicar v2.4.0», la persona revisora tiene que reconstruir la versión mientras un agente impaciente espera.

Usa un registro de aprobación estructurado como este:

```json
{
  "operation": "publish_release",
  "repository": "acme/widgets",
  "draft_id": "123456",
  "version": "v2.4.0",
  "target_sha": "8b0c5f7c2d6c4e1a9f1a3b0e5e92d7a4c6f80c11",
  "prerelease": false,
  "make_latest": "true",
  "assets": [
    {"name": "widgets-v2.4.0.tar.gz", "sha256": "b3e1..."},
    {"name": "widgets-v2.4.0.tar.gz.sha256", "sha256": "f18a..."}
  ],
  "notes_digest": "c921..."
}
```

La persona que aprueba debería abrir el borrador y comparar este registro con el estado del repositorio. El resumen de las notas puede parecer excesivo hasta que alguien edita un borrador después de la revisión. No hace falta tratar cada coma como inmutable, pero sí hay que saber si cambiaron la lista de artefactos, el destino o la clasificación de la versión.

Un borrador no es inofensivo por defecto. Puede ser visible para usuarios con acceso al repositorio y activar herramientas internas. Incluye la creación de borradores en el conjunto de menor riesgo solo si tu propio entorno los trata como material de revisión. Si los artefactos del borrador llegan a un registro de paquetes o a un espejo de artefactos, exige también aprobación antes de subirlos.

## Vincula la versión a un commit y los artefactos a la versión

El fallo de publicación más habitual no lo provoca un agente malicioso. Es una versión cuyo número, etiqueta, commit de origen y binario proceden de momentos distintos en un repositorio que sigue cambiando.

Un proceso limpio selecciona primero un SHA de commit inmutable. La compilación se ejecuta desde ese SHA, no desde el nombre de una rama. El agente registra los resúmenes cuando termina la compilación. Solo después crea una etiqueta y un borrador que apuntan al mismo SHA. Si tu proceso requiere una etiqueta firmada, la identidad de firma debería operar fuera del proceso del agente, igual que la credencial de publicación.

No permitas que el agente use una referencia mutable como `main` como destino de una publicación pública. Una compilación puede comenzar en una revisión mientras otra combinación de cambios avanza la rama antes de que el agente cree la versión. GitHub resolverá sin problemas `main` en el destino posterior si tu código se lo pide en ese momento. El resultado puede incluir notas sobre una revisión y un artefacto de otra.

Comprueba la relación antes de mostrar la solicitud de aprobación. Una verificación local sencilla puede detectar el problema pronto:

```sh
git fetch --tags origin
git rev-parse "v2.4.0^{}"
git rev-parse HEAD
shasum -a 256 dist/widgets-v2.4.0.tar.gz
```

Los dos primeros identificadores de objetos deben coincidir cuando exista la etiqueta, y `HEAD` debe ser el SHA revisado si compilaste en esa copia de trabajo. El comando de suma de comprobación produce una línea con este formato:

```text
b3e1f2...  dist/widgets-v2.4.0.tar.gz
```

Introduce ese resumen exacto en el registro de aprobación. No pidas a la persona revisora que confíe en el nombre del archivo. Un archivo llamado `widgets-v2.4.0.tar.gz` puede contener una compilación de depuración, una compilación antigua o un binario de otra arquitectura.

La documentación de GitHub Actions advierte que `pull_request_target` se ejecuta en el contexto del repositorio base y puede exponer permisos de escritura o secretos al código no confiable de un pull request si se usa sin cuidado. La misma lección se aplica a un agente de publicación: no compiles un artefacto distribuible a partir de código no confiable en un trabajo que pueda publicar. Separa la validación no confiable de la compilación controlada que recibe autoridad de publicación.

El cálculo de versiones también necesita una regla fija. Un agente puede proponer una versión a partir de commits convencionales o etiquetas combinadas, pero una propuesta no es una prueba. La persona responsable del mantenimiento debe decidir cómo afectan al versionado los cambios incompatibles, los cambios revertidos y las ramas de publicación. El versionado semántico automatizado falla silenciosamente cuando el repositorio no mantiene una disciplina coherente en los commits.

## Las notas de publicación generadas necesitan edición humana

Un agente puede convertir pull requests combinados en un primer borrador convincente. No puede saber si una migración merece una advertencia, si una persona colaboradora quiere aparecer en los reconocimientos o si un cambio de comportamiento rompe un caso de uso que nunca apareció en el título del commit.

Pídele que produzca las notas en secciones que hagan visible la incertidumbre. Coloca primero los cambios que afectan a los usuarios, después las correcciones y luego el trabajo interno. Incluye referencias a los pull requests y el intervalo de commits utilizado. Marca las afirmaciones que procedan de una inspección del código y no de la descripción de una persona responsable. Así evitas que un párrafo fluido oculte una suposición.

Rechazo la instrucción popular «escribe notas de publicación pulidas a partir del registro de Git». Es popular porque produce un documento de inmediato. Es incorrecta porque los mensajes de commit describen la intención de implementación, no necesariamente el comportamiento que llegó al producto. Un commit llamado «fix auth» puede corregir un accesorio de prueba, cambiar un mensaje de error o cerrar un defecto grave. La nota de publicación necesita explicar el impacto real para los usuarios.

Haz que la persona revisora responda unas preguntas sencillas antes de publicar:

- ¿El commit de destino contiene todos los cambios que se afirman aquí?
- ¿Quedó algún pull request eliminado o revertido dentro del intervalo?
- ¿Deben los usuarios cambiar la configuración, los datos, los permisos o los clientes?
- ¿Algún texto de seguridad debe ser revisado por las personas que investigaron el problema?
- ¿Es una prepublicación y debería GitHub mostrarla como la más reciente?

No entregues al agente un aviso de seguridad para que lo parafrasee en una publicación pública. La persona revisora debe decidir el momento de divulgación, las versiones afectadas, las soluciones provisionales y los reconocimientos. Un agente puede dar formato a un texto aprobado, pero no debería decidir qué se hace público.

Mantén vinculados las notas de publicación y los artefactos durante la revisión. Cuando una persona revisora lea «añade compatibilidad con ARM», debería ver el artefacto ARM en el borrador y su suma de comprobación en la solicitud de aprobación. Así se detecta un tipo de error embarazoso que las revisiones separadas de documentación y compilación pueden pasar por alto.

## La confirmación debe producirse en el límite irreversible

Un cuadro de confirmación que aparece después de publicar solo documenta el arrepentimiento. Coloca la solicitud justo antes de la operación que cambia el estado de distribución y muestra la solicitud exacta que se va a autorizar.

La persona que aprueba necesita suficiente contexto para detectar una discrepancia en segundos: repositorio, título del borrador, SHA de destino, nombres y resúmenes de los artefactos, estado de prepublicación, decisión sobre la versión más reciente y proceso que solicita la aprobación. No ocultes el repositorio en un panel de detalles contraído. Publicar en el repositorio equivocado puede causar más daño que una nota mal redactada.

Usa una confirmación distinta para estas operaciones:

- publicar una versión en borrador
- eliminar o retirar una versión
- eliminar la etiqueta de una versión
- reemplazar un artefacto existente de la versión
- cambiar una versión de prepublicación a estable o marcarla como la más reciente

La lista es breve a propósito. Pedir permiso para cada lectura y cada hash de artefacto acostumbra a las personas a aprobar sin mirar. Exigir una decisión en un límite público o destructivo conserva la atención para el punto en el que realmente puede importar.

La confirmación debe estar vinculada al resumen de la solicitud. Si el agente cambia el borrador, añade un artefacto o modifica `make_latest` después de la aprobación, invalida la aprobación y vuelve a solicitarla. No reutilices un clic anterior solo porque la cadena de versión siga coincidiendo.

La autorización por sesión de Sallyport puede identificar un proceso nuevo del agente antes de que realice una acción, y sus controles por llamada pueden exigir una aprobación independiente para el uso de una credencial determinada. Esto encaja bien con el trabajo de publicación: permite que una ejecución revisada del agente prepare un borrador y exige después una decisión por llamada cuando utiliza la credencial de publicación.

No confundas aprobación con autenticación. Una identidad de firma de código o una identidad de carga de trabajo de CI te dice qué proceso hizo la solicitud. La confirmación indica que una persona aceptó esta acción externa concreta. Cuando una publicación sale mal, necesitas ambos registros.

## Mantén las credenciales fuera de las instrucciones y el entorno del agente

Un agente que tiene directamente un token de GitHub puede saltarse tu interfaz de aprobación cuidadosamente diseñada con un comando curl, un archivo de flujo de trabajo modificado o una llamada a una herramienta que olvidaste restringir. Las instrucciones no pueden cerrar esa brecha.

Guarda la credencial en un componente que ejecute únicamente la operación permitida. El agente envía una solicitud estructurada. El componente valida el repositorio, el verbo, la referencia de destino y las restricciones de los artefactos, obtiene la aprobación necesaria, inyecta la credencial en la solicitud saliente y devuelve el resultado. El agente nunca recibe el secreto, ni siquiera como marcador oculto.

Sallyport mantiene los secretos de API y SSH en su bóveda cifrada y ejecuta directamente la acción HTTP o SSH, de modo que un agente compatible con MCP no necesita tener la credencial. El bloqueo de la bóveda deniega las acciones mientras está cerrada. Eso es lo que quieres en una máquina sin supervisión, en lugar de dejar un token en el entorno del shell.

Usa una credencial independiente para las publicaciones. Limítala a los repositorios donde tiene una función concreta y elimina los permisos para administrar organizaciones, gestionar webhooks, editar la configuración de Actions o escribir en repositorios no relacionados. GitHub Apps suele encajar mejor que el token personal de una persona porque la instalación y los permisos tienen un propósito más limitado. La elección exacta depende de la configuración de tu repositorio, pero un token compartido de mantenimiento es una identidad de publicación deficiente.

No pegues un token en una instrucción para el agente, un archivo `.env` ni un artefacto de CI. La redacción no resuelve el problema. Una vez que un proceso puede leer un secreto, a menudo puede codificarlo en un campo de salida, un cuerpo de publicación, un nombre de archivo o una solicitud a otro servicio. La prevención empieza por no entregar nunca el secreto a ese proceso.

## La reversión es una decisión correctiva de publicación, no un botón de eliminación

Eliminar una versión de GitHub puede retirar una página, pero no recupera los archivos descargados, los metadatos almacenados en caché, las etiquetas clonadas, el código fuente replicado ni un despliegue automatizado que ya se haya activado. Un agente que trate la eliminación como una reversión limpia hará que un incidente grave sea más difícil de investigar.

Empieza una solicitud de reversión clasificando el fallo. Si el artefacto está roto pero no supone un peligro, publica una versión corregida con una nota clara y decide si la versión anterior debe pasar a ser una prepublicación o dejar de ocupar la posición de más reciente. Si el artefacto contiene un secreto, código malicioso o una vulnerabilidad grave, detén primero la distribución, revoca las credenciales afectadas, contacta con los usuarios a través de tus canales y conserva las pruebas necesarias para investigar.

Una persona debería aprobar las acciones de reversión por separado de la publicación porque sus consecuencias son distintas. La solicitud debe indicar qué cambiará y qué seguirá visible. «Eliminar la versión v2.4.0» es una descripción débil. «Eliminar el registro público y los artefactos de la versión v2.4.0; la etiqueta v2.4.0 permanece en el SHA X; las descargas existentes no se pueden recuperar» explica qué se está autorizando realmente.

No permitas que un agente elimine una etiqueta para que sus notas de publicación parezcan ordenadas. Otras compilaciones y usuarios pueden depender de las etiquetas. Si tienes que reemplazar una etiqueta, conserva el SHA anterior en el registro del incidente y comunica el cambio. Mover una etiqueta de versión publicada dificulta mucho las verificaciones posteriores.

La opción predeterminada más segura es una versión correctiva. Crea un recorrido de auditoría claro, permite que las herramientas posteriores distingan el artefacto corregido y evita fingir que la primera versión nunca existió. La eliminación tiene sentido cuando se publicó algo por accidente y nadie pudo consumirlo razonablemente, pero eso es una decisión operativa, no una tarea de limpieza automática.

## Un registro de auditoría debe reconstruir la acción, no la historia que la rodea

Cuando alguien pregunta quién publicó una versión, «lo hizo el agente» no es una respuesta. Debes identificar el proceso del agente, la persona que aprobó la acción, la autoridad de la credencial que la ejecutó, los valores de la solicitud y la respuesta de GitHub.

Registra un evento para la sesión del agente y otro para cada operación de publicación. El registro de sesión responde quién inició la ejecución y cuándo dejó de tener autoridad. El registro de acción responde qué operación equivalente a un endpoint ocurrió y con qué valores resueltos. Mantén los secretos fuera de ambos registros.

Para un evento de publicación, registra como mínimo el repositorio, el identificador del borrador, el identificador de la versión, la versión, el SHA de destino, la referencia de origen proporcionada por el agente, los nombres y resúmenes de los artefactos, las opciones de la versión, el resumen de las notas, la hora de la decisión, la identidad de quien aprobó, la identidad del proceso, el código de resultado y el identificador de respuesta. Incluye los fallos. Una solicitud denegada demuestra que un límite funcionó.

Sallyport proyecta los diarios de sesión y actividad desde un registro de auditoría cifrado, encadenado mediante hashes y ciego para escritura. Su comando `sp audit verify` comprueba la cadena sin conexión sobre el texto cifrado y no necesita un secreto de la bóveda. Esta propiedad resulta útil como prueba de publicación porque una persona auditora puede comprobar si se alteraron los registros sin recibir el material de las credenciales.

Los registros no sustituyen a los controles. Un registro perfecto que documente cómo un agente publicó el paquete equivocado te proporciona un análisis posterior ordenado y una mala versión. El registro demuestra su valor cuando lo combinas con acciones limitadas, identificadores fijos y una aprobación que no puede sobrevivir a un cambio en la solicitud.

## Una barrera de publicación debe fallar de forma segura cuando cambien los hechos

La barrera de publicación debería rechazar la ambigüedad en lugar de pedir a la persona que aprueba que la compense. Si el destino del borrador difiere del SHA revisado, si el resumen de un artefacto difiere del manifiesto de compilación, si el borrador ya no existe o si la solicitud de publicación cambió desde la aprobación, detén el proceso y crea una solicitud nueva.

Este comportamiento puede parecer quisquilloso durante una publicación urgente. Es más barato que averiguar si una etiqueta se movió entre la compilación y la publicación o si un agente subió un archivo recompilado después de que la persona revisora comprobara el anterior. El trabajo de publicación se beneficia de una pequeña fricción justo en este punto.

Prueba la barrera con fallos intencionados antes de confiarle una versión estable. Pide al agente que publique un borrador con un SHA distinto. Sube un artefacto cuyos bytes cambien después de calcular la suma de comprobación. Cambia el título de un borrador después de aprobarlo. Intenta eliminar una versión a través de la interfaz de preparación. Cada intento debería fallar con un registro específico que explique el motivo a quien opera el sistema.

Después establece una regla operativa fácil de recordar: el agente prepara una candidata de publicación con nombre y una persona aprueba el cambio público exacto. Si tu automatización actual no puede indicar en ese momento el repositorio, el commit, los artefactos y el efecto de una reversión, todavía no está lista para publicar software sin supervisión.
