Comparar snapshots
ajat diff compara dos árboles de reglas en disco producidos por ajat export. Es puramente local — sin credenciales de Jira, sin llamada a la API, sin red — lo que lo hace barato de ejecutar en CI, en una máquina de revisión aislada, o contra un snapshot archivado del que ya no tienes credenciales.
El emparejamiento es la clave: una exportación tomada ayer, más una exportación tomada hoy, más ajat diff, es un historial de cambios auditable de tu estado de automatización — sin almacenar ningún estado adicional.
diff lee dos directorios que ya existen en disco. Prodúcelos primero con
ajat export; conserva directorios de salida con marca
de tiempo para tener siempre un “antes” y un “después” que comparar.
Uso
ajat diff <left-dir> <right-dir> [--format table|json] [--check]<left-dir>es el snapshot “antes”.<right-dir>es el snapshot “después”.--format table(predeterminado) renderiza una tabla legible en stdout.--format jsonemite un único objeto JSON — apto para scripting.--checkdevuelve un código de salida distinto de cero cuando se detecta alguna diferencia — la compuerta de deriva de CI.
diff es un comando de solo lectura y sin credenciales. Nunca contacta con
Jira y nunca modifica nada — solo lee los archivos JSON de los dos directorios.
Categorías de cambio
Se muestran tres categorías:
| Categoría | Significado |
|---|---|
| added | UUID presentes solo en <right-dir>. |
| removed | UUID presentes solo en <left-dir>. |
| changed | UUID presentes en ambos con al menos un delta en un campo vigilado. |
Campos vigilados
Una regla cae en la categoría changed cuando cualquiera de estos campos difiere entre los dos snapshots:
namestate(ENABLED ↔ DISABLED)descriptionactor(actor.accountId)trigger(el tipo de componente disparador de la regla)labels(diff de conjuntos insensible al orden)scope(el conjuntoruleScopeARIs; una lista vacía se renderiza comoglobal)conditions,actions,branches— por conteo de componentes
Los cambios estructurales más profundos — el esquema de un componente específico, por ejemplo — no producen un delta por campo. Si necesitas ese nivel de detalle, los archivos JSON de las reglas en disco son la fuente de verdad; compáralos con la herramienta que prefieras.
Salida en tabla y en JSON
--format table (el predeterminado) imprime un resumen legible en stdout, agrupado por categoría:
ajat diff ./snapshots/2026-05-18 ./snapshots/2026-05-19--format json emite un único objeto JSON con arrays added, removed y changed — ideal para scripting y dashboards:
# Lista los nombres de cada regla que cambió entre dos snapshots
ajat diff ./baseline ./current --format json | jq '.changed[] | .name'Como el diff es totalmente local, puedes ejecutarlo tan a menudo como quieras sin tocar el presupuesto de límite de tasa de la API de Automation.
Ejemplos
# ¿Qué cambió en las últimas 24 horas?
ajat export --output-dir ./snapshots/2026-05-19
ajat diff ./snapshots/2026-05-18 ./snapshots/2026-05-19
# Trata el diff como una compuerta de CI.
ajat diff ./baseline ./current --check
# Salida legible por máquina.
ajat diff ./baseline ./current --format json | jq '.changed[] | .name'
# ¿Qué aplicó realmente el trabajo de importación?
ajat export --output-dir ./pre-import-snapshot
ajat import --input-dir ./source-snapshot --yes
ajat export --output-dir ./post-import-snapshot
ajat diff ./pre-import-snapshot ./post-import-snapshotCódigos de salida
| Código | Significado |
|---|---|
| 0 | La ejecución se completó; --check estaba desactivado, o --check no encontró diferencias. |
| 1 | Fallo de bootstrap (directorio ilegible, --format incorrecto), o --check detectó al menos un diff. |
| 130 | Interrumpido (SIGINT / SIGTERM). |
Compuerta de deriva en CI
--check convierte diff en una barrera de gobernanza: mantén un snapshot base confirmado, exporta el estado actual en cada ejecución y haz fallar el pipeline cuando ambos diverjan. Esto detecta automatización añadida, eliminada o editada fuera de tu proceso de cambios.
# .github/workflows/automation-drift-gate.yaml
on:
schedule: [{ cron: "0 6 * * 1" }] # Lunes 06:00 UTC
workflow_dispatch:
jobs:
drift-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6 # el repo contiene ./baseline de la última revisión aprobada
- run: |
# La URL de descarga viene de tu correo de pedido de Climakers; guárdala como secreto de CI.
curl -sL "${{ secrets.AJAT_DOWNLOAD_URL }}" -o ajat.zip
unzip ajat.zip && chmod +x ajat && sudo mv ajat /usr/local/bin/
- run: ajat export --output-dir ./current --no-progress
env:
AJAT_JIRA_DOMAIN: ${{ secrets.AJAT_JIRA_DOMAIN }}
AJAT_JIRA_USERNAME: ${{ secrets.AJAT_JIRA_USERNAME }}
AJAT_JIRA_API_TOKEN: ${{ secrets.AJAT_JIRA_API_TOKEN }}
# Hace fallar el trabajo (exit 1) en cuanto el estado en vivo se desvía del baseline.
- run: ajat diff ./baseline ./current --checkCuando la compuerta se dispara, reejecuta el mismo comando sin --check (o con
--format json) para ver exactamente qué se desvió, y luego investiga el cambio
o promueve ./current como el nuevo baseline aprobado. Usa la edición de
licencia CI/CD Automation para ejecuciones programadas — consulta
Licenciamiento.
Emparejar con el archivo de estado
ajat export escribe .ajat_state.json junto a cada directorio de exportación. El estado incremental ya responde “qué reglas cambiaron desde la última exportación correcta” — y ajat diff responde “qué cambió sobre ellas” comparando el JSON en disco. Conservar ambos hace que las preguntas de deriva sean respondibles sin reejecutar export.
Relacionado
- Exportar el estado — produce el árbol en disco que
diffconsume. - Informes HTML —
report consistencyanaliza un único snapshot para higiene de etiquetas y deriva de nomenclatura; complementario al diff de dos snapshots. - Buscar en el estado — consulta el estado de reglas en vivo a nivel de resumen cuando no necesitas cuerpos completos ni un segundo snapshot.
- Importar y restaurar — exporta, importa y luego compara para confirmar exactamente qué aplicó una importación.