Introducción
Fieldlight Studio necesita ahora un paquete fotográfico completo: tres fotografías pequeñas, una hoja de contactos, pies de foto y una galería que funcione después de descargarla. Un agente de Jenkins puede preparar las fotografías; otro tiene la herramienta de empaquetado proporcionada. Elegir correctamente ambos agentes no hace que sus espacios de trabajo compartan archivos.
Observarás ese problema de archivos ausentes, añadirás una transferencia temporal real dentro de una ejecución del Pipeline y conservarás el ZIP resultante para utilizarlo de forma independiente. Este laboratorio comienza con sus propios originales, agentes conectados y un trabajo aún sin ejecutar; no utiliza archivos ni ejecuciones del laboratorio anterior.
Los requisitos previos son las etiquetas de agentes, la asignación de etapas, la opción de ancho, los artefactos nativos, el ajuste de huellas digitales y la limpieza del espacio de trabajo enseñados en Elige el agente de fotografías, además de conocimientos básicos de navegación en Jenkins. No se requiere programar en Java ni instalar agentes. Ambos agentes son contenedores separados con sistemas de archivos independientes en la misma máquina virtual de prácticas y comparten su núcleo. Fieldlight y sus fotografías de estudio generadas por IA no representan a ningún cliente ni evento reales. La duración es una estimación del autor, no un tiempo medido con principiantes.
Observa los espacios de trabajo separados
En este paso seguirás el trabajo desde el agente de imágenes hasta el agente de empaquetado y observarás por qué una preparación correcta no produce por sí sola una entrega utilizable. Empieza en Photo Desk.
Inspecciona los tres originales de Garden Stories: lavanda, un sendero de jardín y una regadera. Abre cada imagen y vuelve con la acción Back del navegador. El escritorio indica No completed collection yet. Estos originales deben permanecer sin cambios. La entrega deseada utiliza vistas previas de exactamente 320 pixels wide (320 píxeles de ancho), conservando su relación de aspecto.
Cambia a Jenkins y abre build-photo-pack. Selecciona Configure → Pipeline. Lee el Script preparado. El agent none de nivel superior permite que cada etapa asigne su propio agente capaz de realizarla. Prepare photos solicita photo-imaging y ejecuta /opt/fieldlight/prepare-photos --width 320; Pack collection solicita photo-packing y ejecuta /opt/fieldlight/pack-photos.
Cada etapa comienza con deleteDir() y tiene su propia limpieza post { always { deleteDir() } }. Un espacio de trabajo es un directorio perteneciente al agente asignado a un trabajo. Aunque ambas etapas utilizan el mismo nombre de trabajo, sus directorios están en sistemas de archivos de contenedores separados. No son dos nombres para un directorio compartido. Los originales de solo lectura se encuentran fuera del espacio de trabajo del trabajo, en /opt/fieldlight/originals en el agente de imágenes.
El programa de imágenes escribe seis archivos relativos a su espacio de trabajo actual:
prepared/
images/
garden-01.png
garden-02.png
garden-03.png
contact-sheet.png
captions.csv
preparation.json
Las tres vistas previas miden 320 × 213 píxeles. La hoja de contactos las muestra juntas; el CSV relaciona cada nombre de archivo con su pie de foto y dimensiones; el JSON identifica la colección, el ancho solicitado y los hashes de las imágenes originales. La herramienta de empaquetado proporcionada consume estos archivos reales desde su propio espacio de trabajo. No obtiene los archivos ausentes del otro agente ni de Photo Desk.
Vuelve a la página del trabajo sin editar el script y selecciona Build Now una vez. Abre la nueva ejecución numerada en Build History y después Console Output. Espera al FAILURE previsto. Primero, image-studio indica 3 previews at 320 pixels wide. Después de su limpieza, pack-studio ejecuta el comando de empaquetado e indica Missing prepared/preparation.json in this agent's workspace. También se realiza la limpieza final.
Este es un fallo de ubicación de archivos, no un original dañado ni un programa ausente. La etapa de preparación terminó, pero no hubo transferencia. Copiar archivos manualmente, compartir un montaje, eliminar la limpieza o colocar ambas etapas en el agente de imágenes evitaría la lección sin entregar el flujo de trabajo previsto con dos agentes. Mantén las asignaciones de ambas etapas y ambas secciones de limpieza.
Si la ejecución sigue en curso o en cola, espera a su estado final antes de comprobarla. Si una edición accidental provocó otro error, restaura el script original de la configuración que aparece a continuación, guarda y ejecútalo una vez para observar este fallo esperado por falta de archivos:
pipeline {
agent none
stages {
stage('Prepare photos') {
agent { label 'photo-imaging' }
steps {
deleteDir()
sh '/opt/fieldlight/prepare-photos --width 320'
}
post {
always { deleteDir() }
}
}
stage('Pack collection') {
agent { label 'photo-packing' }
steps {
deleteDir()
sh '/opt/fieldlight/pack-photos'
archiveArtifacts artifacts: 'photo-pack.zip', fingerprint: true
}
post {
always { deleteDir() }
}
}
}
}
Conserva la ejecución fallida y su consola. Cambia a Photo Desk y actualiza la página: debe seguir indicando que no hay ninguna colección completada. Los tres originales completos siguen disponibles. El siguiente paso transferirá únicamente el resultado pequeño preparado y después creará un archivo comprimido conservado.
Transfiere las fotografías y conserva el paquete
En este paso transferirás los seis archivos preparados dentro de la misma ejecución del Pipeline, archivarás el ZIP completo y lo inspeccionarás de forma independiente. Empieza en Jenkins, vuelve a build-photo-pack y selecciona Configure → Pipeline.
stash guarda un pequeño conjunto de archivos seleccionados para utilizarlos más adelante en la misma ejecución del Pipeline. Asígnale un nombre y un patrón includes. Aquí prepared/** incluye los archivos de la carpeta de preparación y los archivos anidados de images/. Se conservan las rutas relativas, por lo que restaurar el stash crea prepared/ en el espacio de trabajo receptor. Guarda en el stash solo estos pequeños derivados, no los originales, el entorno de ejecución Java ni los directorios de herramientas.
unstash restaura ese conjunto con nombre en el espacio de trabajo del agente actual. Su nombre debe coincidir con el del stash anterior. Colócalo después del deleteDir() inicial de la etapa receptora y antes del comando de empaquetado. Coloca el stash después del procesamiento y antes de la limpieza de la etapa de imágenes. De lo contrario, los archivos aún no existen, ya se han eliminado o se eliminan inmediatamente después de restaurarlos.
Un stash es una transferencia temporal, no un archivo comprimido descargable: normalmente Jenkins lo descarta cuando termina esta ejecución. En cambio, archiveArtifacts conserva el ZIP final con su ejecución. Mantener ambas operaciones hace que la transferencia sea temporal y que la entrega se pueda utilizar más adelante.
Haz clic dentro de Script, selecciona todo con Ctrl+A en Windows/Linux o Command+A en macOS y sustitúyelo por esta versión completa:
pipeline {
agent none
stages {
stage('Prepare photos') {
agent { label 'photo-imaging' }
steps {
deleteDir()
sh '/opt/fieldlight/prepare-photos --width 320'
stash name: 'prepared-photos', includes: 'prepared/**'
}
post {
always { deleteDir() }
}
}
stage('Pack collection') {
agent { label 'photo-packing' }
steps {
deleteDir()
unstash 'prepared-photos'
sh '/opt/fieldlight/pack-photos'
archiveArtifacts artifacts: 'photo-pack.zip', fingerprint: true
}
post {
always { deleteDir() }
}
}
}
}
Las dos líneas nuevas son el stash con nombre y el unstash correspondiente. Los comandos proporcionados de imágenes y empaquetado, los agentes correctos, el límite que protege los archivos originales y la limpieza permanecen. El ajuste archiveArtifacts conserva photo-pack.zip y registra su huella digital nativa; la huella digital rastrea la identidad del archivo, no una aprobación del cliente ni una firma digital.
Selecciona Save y después Build Now. Espera a que la nueva ejecución termine en SUCCESS. Abre su Console Output y lee la secuencia: image-studio prepara las fotografías de 320 píxeles, Jenkins indica Stashed 6 file(s) y se vacía el espacio de trabajo de imágenes. Después pack-studio restaura el stash, la herramienta de empaquetado indica Packed 9 collection files into photo-pack.zip y Jenkins archiva el ZIP y registra su huella digital antes de vaciar el espacio de trabajo de empaquetado.
Si la consola indica No such saved stash, compara los dos nombres del stash y su orden, restaura el script completo, guarda y vuelve a ejecutar. Si sigue indicando que falta un archivo preparado, comprueba que el patrón includes sea prepared/** y que unstash aparezca después de la limpieza receptora. Cada nueva ejecución inicia una nueva transferencia; el stash de una ejecución anterior no es un sustituto. Ante un error de sintaxis de Groovy, restaura el script completo y conserva sus llaves, comillas y comas. Mantén todas las ejecuciones fallidas y correctas; los errores habituales no requieren restablecer la máquina virtual.
En la página de la ejecución correcta, selecciona el artefacto photo-pack.zip y guárdalo. Extrae el ZIP completo en una carpeta nueva en tu propio ordenador. No abras únicamente el archivo HTML dentro de un visor de archivos comprimidos: también deben extraerse los archivos vecinos. La carpeta debe contener:
index.html
styles.css
delivery.txt
captions.csv
preparation.json
contact-sheet.png
images/
garden-01.png
garden-02.png
garden-03.png
Abre el index.html extraído en un navegador. La galería Fieldlight Studio debe mostrar las tres fotografías correctas del jardín y sus pies de foto. Abre cada fotografía y vuelve con Back del navegador. Selecciona Open contact sheet para ver el resumen real de las tres fotografías y después usa Back del navegador para volver a la galería. Desde la carpeta extraída, abre captions.csv, preparation.json y delivery.txt en un editor de texto; los enlaces de la galería apuntan a estos mismos archivos, los nombres de archivo del CSV deben apuntar a los archivos reales de images/, cada vista previa debe medir 320 × 213 píxeles y el JSON debe identificar garden con el ancho 320. Las notas deben identificar este trabajo, ejecución y agente de empaquetado reales de Jenkins.

La galería completa incluye las tres fotografías del jardín, un enlace a la hoja de contactos y enlaces a los archivos reales de pies de foto, detalles de imágenes y entrega. Mantén juntos sus archivos vecinos al abrir tu copia extraída.
Mantén junta la carpeta extraída completa. Ábrela en una nueva ventana privada del navegador sin utilizar Photo Desk: todas las imágenes, los estilos y los enlaces a archivos deben seguir funcionando desde archivos locales. La galería no utiliza fuentes remotas ni imágenes alternativas en línea. Una imagen local que no funciona significa que falta un archivo real de la entrega o está mal ubicado; extrae el ZIP original completo en una carpeta nueva en lugar de copiar los archivos ausentes del sitio web de origen.
Cambia a Photo Desk, actualiza la página y selecciona Open prepared collection. Esta vista lee los archivos de tu archivo comprimido nativo real. Inspecciona sus fotografías y adjuntos, vuelve con la acción Back del navegador y selecciona Download complete ZIP. Sus bytes deben coincidir con el artefacto de Jenkins que descargaste. Vuelve al escritorio y confirma que los tres originales completos permanecen sin cambios.
Por último, cambia a Jenkins. Vuelve a abrir la ejecución correcta y confirma que su artefacto sigue siendo descargable después de la limpieza. Conserva la ejecución inicial con archivos ausentes, todo el historial, los originales, las herramientas, las conexiones de los nodos y las etiquetas de capacidad. Si vuelves a editar el script, guarda y completa una nueva ejecución correcta antes de comprobarlo. Ahora tienes una transferencia real entre dos agentes y una entrega completa conservada.
Resumen
Has observado espacios de trabajo independientes de Jenkins y después has transferido únicamente el resultado fotográfico necesario mediante un stash con nombre y un unstash correspondiente dentro de una ejecución. El agente de empaquetado creó una galería local completa y la conservación nativa de artefactos la mantuvo utilizable después de vaciar ambos espacios de trabajo de las etapas. El desafío independiente cambia la colección y el ancho reutilizando los mismos mecanismos enseñados.



