Configurar Jenkins con agentes Windows y Git-Bash permite automatizar compilaciones y despliegues en entornos Windows aprovechando la flexibilidad de los scripts Bash. En este artículo, aprenderéis paso a paso cómo configurar un agente de Jenkins en Windows, integrarlo con Git-Bash y ejecutar tareas de automatización de manera eficiente.
Seguid leyendo y os mostraré todos los pasos de forma rápida y sencilla...
¿QUÉ ES GIT-BASH?
git-bash es una aplicación que nos permite usar Git a través de una consola de comandos en sistemas Windows. Básicamente, es una terminal que simula un entorno Unix/Linux, lo que facilita trabajar con comandos de Git como si estuvieras en una terminal de Linux o MacOS, pero en Windows.
¿Qué incluye git-bash?
- Git (obviamente) para gestionar repositorios.
- Bash (Bourne Again Shell), que es una shell de Unix.
- Un montón de comandos típicos de Linux/Unix (como ls, pwd, cp, rm, etc.), que no vienen por defecto en el símbolo del sistema de Windows (cmd).
Web Oficial: https://git-scm.com/
Git-Bash: ejecuta Git y Bash en Windows fácilmente.
1.- ELEMENTOS NECESARIOS PARA ESTE TUTORIAL
- Un equipo con el servidor de Jenkins instalado
- Un equipo con Windows (en principio cualquier versión)
- Internet es recomendado
2.- ESCENARIO INICIAL
En nuestro escenario inicial, tenemos un servidor Jenkins corriendo en un equipo con GNU/Linux Debian, al cual le hemos conectado un agente Windows 7 donde se ejecutarán los jobs. El problema aparece cuando añadimos un paso de tipo "shell" en un agente con Windows y ejecutamos el job, obteniendo un error como se muestra a continuación:
Lanzada por el usuario admin
Running as SYSTEM
Ejecutando remotamente en Windows7_Agent1 en el espacio de trabajo c:\slaveJenkins\workspace\Git_Bash_Windows_Agent
[Git_Bash_Windows_Agent] $ sh -xe C:\Users\raul\AppData\Local\Temp\jenkins2442745402998455299.sh
El sistema no puede encontrar el fichero especificado
FATAL: la ejecución del comando ha fallado
java.io.IOException: CreateProcess error=2, El sistema no puede encontrar el archivo especificado
at java.base/java.lang.ProcessImpl.create(Native Method)
at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:506)
at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:159)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1126)
Also: hudson.remoting.Channel$CallSiteStackTrace: Remote call to Windows7_Agent1
at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1923)
at hudson.remoting.UserRequest$ExceptionResponse.retrieve(UserRequest.java:384)
at hudson.remoting.Channel.call(Channel.java:1112)
at hudson.Launcher$RemoteLauncher.launch(Launcher.java:1121)
at hudson.Launcher$ProcStarter.start(Launcher.java:507)
at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:144)
at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:92)
at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:818)
at hudson.model.Build$BuildExecution.build(Build.java:199)
at hudson.model.Build$BuildExecution.doRun(Build.java:164)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:527)
at hudson.model.Run.execute(Run.java:1833)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:44)
at hudson.model.ResourceController.execute(ResourceController.java:101)
at hudson.model.Executor.run(Executor.java:446)
Caused: java.io.IOException: Cannot run program "sh" (in directory "c:\slaveJenkins\workspace\Git_Bash_Windows_Agent"): CreateProcess error=2, El sistema no puede encontrar el archivo especificado
at java.base/java.lang.ProcessBui lder.start(ProcessBuilder.java:1170)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1089)
at Jenkins v2.492.2//hudson.Proc$LocalProc.<init>(Proc.java:252)
at Jenkins v2.492.2//hudson.Proc$LocalProc.<init>(Proc.java:221)
at Jenkins v2.492.2//hudson.Launcher$LocalLauncher.launch(Launcher.java:995)
at Jenkins v2.492.2//hudson.Launcher$ProcStarter.start(Launcher.java:507)
at Jenkins v2.492.2//hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:1362)
at Jenkins v2.492.2//hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:1337)
at hudson.remoting.UserRequest.perform(UserRequest.java:225)
at hudson.remoting.UserRequest.perform(UserRequest.java:50)
at hudson.remoting.Request$2.run(Request.java:391)
at hudson.remoting.InterceptingExecutorService.lambda$wrap$0(InterceptingExecutorService.java:81)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at hudson.remoting.Engine$1.lambda$newThread$0(Engine.java:140)
at java.base/java.lang.Thread.run(Thread.java:1575)
Build step 'Ejecutar linea de comandos (shell)' marked build as failure
Finished: FAILURE
El error que nos da la pista de lo que puede suceder, es la siguiente línea en el log de ejecución del job:
Caused: java.io.IOException: Cannot run program "sh" (in directory "c:\slaveJenkins\workspace\Git_Bash_Windows_Agent"): CreateProcess error=2, El sistema no puede encontrar el archivo especificado
Este error es provocado simplemente por ejecutar un paso de tipo shell en una máquina agente de tipo Windows, intentando hacer un simple "ls":
Script de shell
En la siguiente imagen se puede ver el error en formato gráfico:

3.- INSTALAR GIT BASH
Ahora, lo que debemos hacer es instalar Git-Bash en el equipo agente Windows. Para ello, accederemos a la web oficial https://git-scm.com/downloads y descargaremos la versión para nuestro sistema operativo. En este ejemplo, se ha instalado la versión 2.26.1 para 64 bits.
El proceso es sumamente sencillo, como cualquier instalador de Windows, siguiente, siguiente, siguiente... y por eso omitiré dicha explicación.
4.- CONFIGURAR CORRECTAMENTE EL PATH EN WINDOWS
En este ejemplo y para demostrar que también funciona con sistemas operativos relativamente viejos, vamos a modificar el $PATH de un Windows 7 Professional. Las nuevas versiones de Windows, a partir de Windows 10, han hecho la edición de variables de entorno y del $PATH un proceso mucho más sencillo, pero el procedimiento es exactamente el mismo.
Por ejemplo, el $PATH del Windows 7 donde estoy haciendo las pruebas es el siguiente:
%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;\;C:\Program Files (x86)\Sony\VAIO Startup Setting Tool;c:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\Crucial\Crucial Storage Executive;C:\Program Files (x86)\NetSarang\Xshell 7\;C:\Program Files\AutoFirma\AutoFirma;C:\Program Files\Java\jdk-23.0.2\bin\;C:\Program Files\PuTTY\;C:\Program Files (x86)\AMD\ATI.ACE\Core-Static;C:\Program Files\Git\cmd;C:\Program Files\Git\bin
Falta añadir al $PATH, la ruta "C:\Program Files\Git\bin". En la siguiente lista he puesto totos los directorios, en filas, para que veáis que dicho directorio está añadido justo al final. En función del sistema operativo, deberéis hacerlo de una u otra forma, pero el proceso es casi idéntico en todos ellos.
%SystemRoot%\system32
%SystemRoot%
%SystemRoot%\System32\Wbem
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\
C:\Program Files\WIDCOMM\Bluetooth Software\
C:\Program Files\WIDCOMM\Bluetooth Software\syswow64
C:\Program Files (x86)\Sony\VAIO Startup Setting Tool
c:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static
C:\Program Files\Crucial\Crucial Storage Executive
C:\Program Files (x86)\NetSarang\Xshell 7\
C:\Program Files\AutoFirma\AutoFirma
C:\Program Files\Java\jdk-23.0.2\bin\
C:\Program Files\PuTTY\
C:\Program Files (x86)\AMD\ATI.ACE\Core-Static
C:\Program Files\Git\cmd
C:\Program Files\Git\bin
Por ejemplo, en Windows 7 se hace desde el siguiente menú desde "Editar las variables de entorno del sistema":
Editar variables de entorno en Windows 7
Una vez hechos los cambios, es obligatorio reiniciar el servicio de Jenkins en el agente para que vuelva a leer el nuevo $PATH.
5.- EJECUTAR EL JOB DE JENKINS CON GIT-BASH CONFIGURADO
Para comprobar que todo funciona correctamente, en este ejemplo he creado un pequeño y sencillo script de shell que va a correr en un agente con Windows 7 y utilizando Git-Bash. Este script realizará varios pasos:
- Crear un directorio
- Descargar un fichero de internet y guardarlo en el directorio creado
- Comprobar el MD5Sum del fichero y mostrar un mensaje de OK/KO
- Descargar un repositorio de GitHub
El script en cuestión es el siguiente:
# Creamos un directorio
mkdir demo_dir
# Descargamos un fichero
curl https://cdn.kernel.org/pub/linux/kernel/v6.x/patch-6.13.6.xz -o ./demo_dir/patch-6.13.6.xz
# Comprobamos el MD5sum del fichero
if [[ "$(md5sum ./demo_dir/patch-6.13.6.xz | awk '{print $1}')" == "1898782d3a08083da6d9db3c62461338" ]]
then
echo "Enhorabuena! el fichero es correcto!"
else
echo "Ups! el fichero está corrupto!"
fi
# Descargamos un repositorio de GitHub
git clone https://github.com/Automattic/themes ./wordpress_themes/
Una vez ejecutado el script, vemos que efectivamente, se ha ejecutado correctamente realizando todos y cada uno de los pasos que hemos incluido:
Lanzada por el usuario admin
Running as SYSTEM
Ejecutando remotamente en Windows7_Agent1 en el espacio de trabajo c:\slaveJenkins\workspace\Git_Bash_Windows_Agent
[WS-CLEANUP] Deleting project workspace...
[WS-CLEANUP] Deferred wipeout is used...
[WS-CLEANUP] Done
[Git_Bash_Windows_Agent] $ sh -xe C:\Users\raul\AppData\Local\Temp\jenkins6557732845385861380.sh
+ mkdir demo_dir
+ curl https://cdn.kernel.org/pub/linux/kernel/v6.x/patch-6.13.6.xz -o ./demo_dir/patch-6.13.6.xz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
35 500k 35 175k 0 0 840k 0 --:--:-- --:--:-- --:--:-- 840k
100 500k 100 500k 0 0 1744k 0 --:--:-- --:--:-- --:--:-- 1744k
++ md5sum ./demo_dir/patch-6.13.6.xz
++ awk '{print $1}'
+ [[ 1898782d3a08083da6d9db3c62461338 == \1\8\9\8\7\8\2\d\3\a\0\8\0\8\3\d\a\6\d\9\d\b\3\c\6\2\4\6\1\3\3\8 ]]
+ echo 'Enhorabuena! el fichero es correcto!'
Enhorabuena! el fichero es correcto!
+ git clone https://github.com/Automattic/themes ./wordpress_themes/
Cloning into './wordpress_themes'...
Updating files: 10% (1477/13427)
Updating files: 20% (2686/13427)
Updating files: 30% (3894/13427)
Updating files: 40% (5371/13427)
Updating files: 50% (6848/13427)
Updating files: 60% (8191/13427)
Updating files: 70% (9485/13427)
Updating files: 80% (10742/13427)
Updating files: 90% (12085/13427)
Updating files: 100% (13427/13427), done.
Finished: SUCCESS
Ahora ya podréis ejecutar comandos de GNU/Linux en jobs de Jenkins utilizando agentes Windows. ¡Espero que os sirva!
ENJOY!