El escenario
Como parte de una aplicación con Azure Functions existente, que contiene unas Functions HTTP que generan archivos Excel y los devuelven como un byte array, quería agregar un proyecto web para tests de integración que al ser ejecutados descargaran el archivo Excel resultante. Estas Azure Functions se despliegan automáticamente desde un repositorio en GitHub.
Kudu y los scripts de despliegue
Al usar GitHub para desplegar cualquier aplicación en Azure App Service (incluyendo Azure Function), Kudu elige el script de despliegue de acuerdo al tipo de proyecto. Tal como dice en el artículo Customizing deployments de la wiki de Kudu, si tenemos un proyecto web en el repositorio, entonces compila y despliega ese proyecto.
Entonces, ¿qué pasa cuando agregamos un proyecto web al repo donde tenemos nuestras Azure Functions? Bueno, Kudu recibe los nuevos bits, encuentra el proyecto web, lo compila y lo despliega, y ¡nuestras Functions desaparecieron! Pero no se preocupen, hay una solución simple a esto: usar un script personalizado de despliegue o custom deployment script.
Generando el script de despliegue
Para generar nuestro script personalizado de despliegue vamos a partir del script estándar que usa Kudu para desplegar las aplicaciones en Azure Functions y vamos a modificarlo para que ignore nuestra carpeta con los proyectos de test.
Pero, ¿cómo conseguimos ese script?
La manera más simple es bajarlo del sitio de Kudu:
- Abrir Kudu. Ej.: https://{site}.scm.azurewebsites.net/
- Desde el menú Tools, elige ‘Download deployment script’
- Deja los archivos en la raíz de tu repo
Pero, si ya hemos subido los cambios que agregan nuestro proyecto web, el script de despliegue que bajaremos será el que corresponde a aplicaciones web. Para este caso podemos usar una herramienta llamada kuduscript
.
Primero instalaremos la herramienta:
- Necesitamos tener node.js instalado
- Luego instalamos
kuduscript
con npm:npm install kuduscript -g
Después de eso, abrimos una ventana de comandos de Windows (si intentamos realizarlo desde Linux/macOS vamos a recibir un error porque el template de bash no está disponible) y corremos el siguiente comando en la raíz de nuestro repo:
kuduscript -y --functionApp
Esto generará dos archivos:
.deployment
: contiene el comando a correr para desplegar tu appdeploy.cmd
: contiene el script de despliegue
Modificando el script de despliegue para el proyecto
Ahora necesitamos decirle a Kudu que ignore la carpeta que contiene nuestro proyecto de prueba (en mi caso agregué el proyecto dentro de una carpeta llamada tests
).
En el archivo deploy.cmd
hay dos líneas que comienzan con call :ExecuteCmd "%KUDU_SYNC_CMD%" ...
(las líneas 85 y 98 en mi caso). Este comando tiene un parámetro «ignore» (-i) al final, que le indica cuáles archivos/carpetas ignorar al copiar los archivos en la carpeta destino. Ahí es donde debemos agregar nuestra carpeta a la lista.
Por ejemplo, cambiamos esto:
call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 50 -f "%DEPLOYMENT_TEMP%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd;node_modules"
Por esto:
call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 50 -f "%DEPLOYMENT_TEMP%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd;node_modules;tests"
Lo único que falta es hacer el commit de estos dos archivos y subir los cambios.