Skip to Content
Atlassian Jiraajatv1.0.xImportar y promover

Importar y restaurar

ajat import es la operación inversa de ajat export. Lee un árbol de reglas local en disco y las vuelve a escribir en un tenant de Jira Cloud a través de la Automation REST API. Juntas, exportación e importación cierran el ciclo completo y ofrecen tres capacidades que Jira no tiene:

  • Recuperación ante desastres — una regla dañada, un borrado accidental o una edición manual defectuosa se pueden restaurar desde la última exportación sin reconstruirla a mano.
  • Promoción de sandbox a producción — desarrolla y prueba reglas en un tenant de sandbox y luego impórtalas a producción.
  • Migraciones entre tenants — copia un patrimonio de automatización de un sitio de Jira Cloud a otro con UUID nuevos.

ajat import es el único comando de ajat que escribe en un tenant de Jira en vivo. Es deliberadamente conservador: siempre calcula e imprime primero un plan, y ninguna llamada a la API muta nada hasta que confirmas de forma interactiva o pasas --yes. Ejecuta siempre --dry-run primero e importa contra una exportación en la que confíes.

ajat opera únicamente sobre Atlassian Jira Cloud Automation. La importación escribe a través de la Jira Cloud Automation REST API y no es compatible con Jira Server ni Jira Data Center.

El modelo de seguridad

Como la importación muta un tenant en vivo, el contrato es intencionadamente estricto:

  1. Primero el plan, luego la mutación. Cada ejecución empieza listando los resúmenes de reglas del tenant destino, escaneando el árbol local e imprimiendo un plan (create / update / skip / prune / errors). Ninguna llamada a la API muta el estado hasta que confirmas.
  2. Por defecto: confirmación interactiva. Cuando stdin es un TTY, la importación espera y / yes antes de aplicar el plan.
  3. --dry-run imprime el plan y sale sin preguntar — seguro para trabajos programados que solo necesitan detectar drift.
  4. --yes omite la confirmación para uso en CI, y es obligatorio cuando stdin no es un TTY.
  5. Salto basado en estado. Un fichero hermano .ajat_import_state.json registra el sha256 de cada payload enviado. Las ejecuciones posteriores omiten las reglas cuyo fichero local es idéntico byte a byte al último envío y cuyo UUID sigue presente en el tenant destino.

Las dos operaciones que la importación realiza contra el tenant en vivo son:

OperaciónPeticiónCuándo
CREATEPOST /rest/v1/ruleEl UUID de la regla no está presente en el tenant destino.
UPDATEPUT /rest/v1/rule/{uuid}El UUID de la regla ya existe en el tenant destino.

Inicio rápido

# 1. Previsualiza qué cambiaría — sin escrituras. ajat import --input-dir ./jira-automations-backup --dry-run # 2. Aplica el plan completo con confirmación interactiva. ajat import --input-dir ./jira-automations-backup # 3. Igual, pero no interactivo para CI. ajat import --input-dir ./jira-automations-backup --yes

El plan de importación

Cada ejecución imprime un plan antes de escribir nada. Es el artefacto más importante de una importación segura: léelo, confirma que los recuentos coinciden con tu intención y solo entonces aplica.

Import plan input dir : ./jira-automations-backup create : 3 update : 12 skip : 0 prune : 5 errors : 0
RecuentoSignificado
createReglas cuyo UUID falta en el destino — se enviarán con POST.
updateReglas cuyo UUID ya existe — se enviarán con PUT (se sobrescriben).
skipReglas sin cambios desde el último envío correcto y todavía presentes en el destino.
pruneReglas DISABLED del destino ausentes en el origen que --prune borrará.
errorsFicheros que no se pudieron parsear o que no tenían un prefijo UUID reconocible.

Los ficheros cuyo nombre no empieza por un prefijo UUID reconocible, los que no parsean como JSON y los directorios ocultos se listan en la sección errors del plan y se omiten, en lugar de abortar la ejecución.

Qué se importa

ajat import consume la estructura en disco producida por ajat export:

<input-dir>/ ├── .ajat_import_state.json # escrito por import (skip si no hay cambios) ├── global/<uuid>__<name>.json ├── projects/<KEY>__<Project>/<uuid>__<name>.json ├── multi-project/<scope-dir>/<uuid>__<name>.json └── other-scope/<uuid>__<name>.json

El UUID extraído de cada nombre de fichero es la unidad de identidad. El contenido de cada fichero — el JSON completo devuelto por la exportación — se reenvía tal cual, salvo por el paso opcional de eliminación del UUID que se describe más abajo.

Estrategia de UUID

La Automation REST API permite indicar un UUID al crear una regla. Esto da dos modos a la importación, controlados por --uuid-strategy:

EstrategiaComportamiento en CREATECaso de uso
preserve (por defecto)El payload se envía tal cual; el servidor respeta el UUID indicado cuando es posible.Restauración en el mismo tenant. Los sistemas externos (registros de auditoría, enlaces, dashboards) que referencian UUID de reglas siguen funcionando.
newEl campo "uuid" de nivel superior se elimina antes del POST; el servidor asigna un UUID nuevo.Promoción entre tenants — de sandbox a producción, o copiando reglas a otro sitio de Atlassian.

Las actualizaciones (PUT /rule/{uuid}) usan siempre el UUID extraído del nombre de fichero; --uuid-strategy solo afecta a las creaciones.

Reescritura del ámbito de proyecto con --scope-map

Cuando mueves reglas entre tenants, hay dos campos específicos del tenant que hay que reescribir a la entrada:

CampoPor qué hay que reescribirloFlag
UUID de la reglaNo se desean colisiones de UUID entre tenants.--uuid-strategy=new
ruleScopeARIsCada ARI incrusta el cloudId de origen y el ID de proyecto, ambos distintos en el tenant destino.--scope-map OLD=NEW

--scope-map es repetible. Cada entrada reescribe el ARI correspondiente en el array ruleScopeARIs de cada regla antes de enviarla; los ARI que no figuran en el mapeo se dejan intactos. La previsualización del plan indica el número de entradas activas para que confirmes que se ha cargado el número correcto de mapeos antes de aplicar:

Import plan input dir : ./sandbox-export create : 42 update : 0 skip : 0 errors : 0 scope-map : 2 entries

Notas:

  • --scope-map se aplica tanto a create como a update — la intención del flag es “los ARI de origen están obsoletos, reescríbelos en todas partes”.
  • Una entrada cuyo ARI de origen no coincide con ningún ruleScopeARIs es un no-op silencioso.
  • --scope-map es independiente de --uuid-strategy. Puedes usarlo con preserve cuando los ARI de proyecto del mismo tenant han cambiado, por ejemplo tras renombrar la clave de un proyecto.

Importaciones selectivas

Dos flags acotan la ejecución sin tocar los ficheros locales:

  • --create=false — nunca hace POST de reglas nuevas. Útil cuando quieres actualizar reglas que ya existen en el destino, pero sin reintroducir las que se eliminaron a propósito.
  • --update=false — nunca sobrescribe reglas que ya existen. Útil para una “siembra inicial” de un tenant vacío.

Pasar ambos --create=false --update=false es un error: no habría trabajo que hacer.

Poda de reglas huérfanas con --prune

--prune activa el modo “hacer que el destino coincida con el origen”. Tras la fase de create y update, se borra toda regla DISABLED del tenant destino cuyo UUID no esté presente en la exportación de origen.

# Previsualiza primero. ajat import --input-dir ./jira-automations-backup --prune --dry-run # Aplica. ajat import --input-dir ./jira-automations-backup --prune --yes

--prune borra únicamente las reglas DISABLED del destino ausentes en el origen. Las huérfanas ENABLED se dejan intencionadamente intactas — deshabilitar reglas de producción en vivo como efecto secundario de una importación tendría un radio de impacto sorprendente. Las huérfanas habilitadas deben limpiarse de forma explícita.

Para eliminar una huérfana habilitada, deshabilítala primero y luego poda en la siguiente ejecución:

# 1. Encuentra huérfanas habilitadas en el destino. ajat export --output-dir ./target-snapshot ajat diff ./jira-automations-backup ./target-snapshot # 2. Deshabilita la huérfana. ajat rule disable --input-dir ./target-snapshot --uuid <UUID> --yes # 3. Ahora la siguiente poda la eliminará. ajat import --input-dir ./jira-automations-backup --prune --yes

--prune emite una llamada paginada adicional de resúmenes (filtrada a reglas DISABLED) para identificar candidatas, así que el coste está acotado sea cual sea el tamaño del patrimonio.

Receta: recuperación ante desastres en el mismo tenant

Restaura la última exportación fiable en el mismo tenant conservando los UUID originales para que las referencias externas sigan siendo válidas, y luego verifica con una exportación y un diff.

# 1. Previsualiza la restauración. ajat import --input-dir ./last-known-good --dry-run # 2. Aplícala (por defecto --uuid-strategy=preserve). ajat import --input-dir ./last-known-good --yes # 3. Verifica: exporta el estado actual y confirma que coincide con la exportación. ajat export --output-dir ./post-restore ajat diff ./last-known-good ./post-restore

Un diff limpio tras la restauración es tu evidencia de que el tenant coincide con la exportación que importaste.

Receta: promoción de sandbox a producción

Promociona una exportación de sandbox validada a producción. Usa --uuid-strategy=new para que el servidor asigne UUID nuevos, y --scope-map para reescribir cada ARI de proyecto de sandbox a su equivalente de producción.

# 1. Dry-run para confirmar el plan y el número de entradas de scope-map. ajat import --input-dir ./sandbox-export --uuid-strategy=new \ --scope-map ari:cloud:jira:sandbox-cloud-id:project/PROJ-A=ari:cloud:jira:prod-cloud-id:project/PROJ-A \ --scope-map ari:cloud:jira:sandbox-cloud-id:project/PROJ-B=ari:cloud:jira:prod-cloud-id:project/PROJ-B \ --dry-run # 2. Aplica la promoción. ajat import --input-dir ./sandbox-export --uuid-strategy=new \ --scope-map ari:cloud:jira:sandbox-cloud-id:project/PROJ-A=ari:cloud:jira:prod-cloud-id:project/PROJ-A \ --scope-map ari:cloud:jira:sandbox-cloud-id:project/PROJ-B=ari:cloud:jira:prod-cloud-id:project/PROJ-B \ --yes # 3. Guarda evidencia: exporta producción tras la promoción. ajat export --output-dir ./post-promotion

Fichero de estado

ajat import escribe <input-dir>/.ajat_import_state.json (o la ruta indicada en --state-file) tras cada create, update o fallo registrado. Cada entrada contiene:

  • el UUID local extraído del nombre de fichero,
  • el UUID devuelto por el servidor — relevante con --uuid-strategy=new,
  • el sha256 del payload enviado,
  • el estado (created, updated, failed),
  • el último mensaje de error, cuando aplica.

Borra este fichero para forzar un reenvío completo en la siguiente ejecución.

Flags

FlagTipoPor defectoDescripción
--input-dirstringDirectorio con los ficheros JSON de reglas exportados (obligatorio).
--dry-runboolfalseImprime el plan y sale sin mutar el tenant destino.
--yesboolfalseOmite la confirmación interactiva (obligatorio cuando stdin no es un TTY).
--createbooltrueCrea reglas cuyo UUID falta en el tenant destino.
--updatebooltrueActualiza reglas cuyo UUID está presente en el tenant destino.
--uuid-strategystringpreserveCómo tratar el UUID del payload en CREATE: preserve o new.
--scope-mapstringArray[]Reescribe un ARI de ámbito antes del envío: --scope-map OLD=NEW (repetible).
--pruneboolfalseBorra reglas DISABLED del destino ausentes en la exportación de origen (las huérfanas ENABLED no se tocan).
--state-filestringRuta del fichero de estado (por defecto <input-dir>/.ajat_import_state.json).
--workersint4Escrituras de reglas concurrentes (1..32).

Códigos de salida

CódigoSignificado
0Todas las operaciones planificadas tuvieron éxito o se omitieron.
1Fallo de arranque o configuración (credenciales incorrectas, tenant inalcanzable, flags ausentes).
2Al menos una regla falló al importar; el fichero de estado registra el detalle por regla.
130Interrumpido por SIGINT o SIGTERM.

Antes de una importación de alto impacto

  • Ejecuta ajat doctor para confirmar credenciales y acceso a la Automation API de extremo a extremo.
  • Toma una ajat export fresca del destino para tener un punto de retorno y poder hacer ajat diff antes y después.
  • Ejecuta siempre --dry-run y lee el plan antes de aplicar.

Qué leer a continuación

Last updated on