[GIT] Versionando PowerBi trabajando en equipo - previa para CI/CD

Estoy seguro que una de las dudas más grandes de las soluciones de Power Bi actualmente se están preguntando ¿Como persistir/versionar PowerBi?

Naturalmente, cuando los desarrollos son realizados por una única persona no suele haber tantos problemas porque bastaría con una herramienta de estilo Sharepoint para guardar los archivos una vez finalizados. Sin embargo, si trabajamos en equipo sobre un dataset en constante crecimiento la cuestión se complica.

Luego de varios años trabajando en distintos proyectos y métodos voy a compartir mi forma rutinaria de trabajar en equipo persistiendo nuestros archivos. Este artículo aprovechara las tecnologías de versionado de Git con desarrollos de Power Bi Desktop usando Azure DevOps.

Primero me gustaría aclarar que este post asume que ya tenemos conocimientos básicos sobre Repositorio y Versionado Git.

Cuando trabajamos solos sobre un report o dataset no suele haber problemas en el desarrollo. La triste realidad por el momento es que trabajar en simultáneo sobre un mismo archivo Power Bi Desktop es imposible. Por esta razón, necesitamos organizarnos más que nunca al momento de trabajar en equipo sobre un mismo archivo. Junto con ello es indispensable aplicar prácticas de desarrollo de software sobre los archivos para recuperar versiones anteriores históricas con posibilidades de integración y deploy continuo.

La primera solución

Ésta idea nace trabajando en un proyecto con Sharepoint. Un equipo de 10 personas sobre un mismo dataset. La solución que pensamos rápidamente fue crear un chat todos juntos donde avisaríamos si estábamos usando el archivo original para que NADIE más lo modifique. Decíamos algo tipo "Pulling Dataset Nombre". Al terminar de subirlo volver a avisar con un "Pushing Dataset Nombre". De ese modo nuestro sharepoint versionaba el desarrollo y persistíamos nuestras versiones. El problema con esta solución era tener que bajar el archivo, publicarlo y luego subirlo a sharepoint por cada cambio que quisiéramos hacer. Si sincronizaban sharepoint para evitar el problema anterior ocurráa que no se siguía la regla al pie de la letra pensando que hacían un cambio rápido y luego ir a avisar al chat. En ese interín chocaba con otra persona editando y comenzaban los conflictos. Ésta puede ser una gran posibilidad en un único ambiente de desarrollo sin automatizaciones ni metodologías de proyectos puesto que aunque sea tenemos versiones de respaldo de los desarrollos.

Solución Definitiva

Si quisiéramos llevarlo al siguiente nivel necesitaríamos una estructura más robusta. Entonces me pregunté como podíamos mejorar esto y ahí nacieron las ideas. Me di cuenta que si se hacía bien podíamos tener versionado, evitar el chat, cumplir con ambientes y usar CD/CI que alinearía una estructura agile.

Llevando este escenario a las mejores prácticas vamos a utilizar Azure DevOps (que cuenta con limitada cantidad de licencias free). Vamos por esta herramienta porque no solamente cuenta con las últimas versiones de la tecnología GIT sino también con Pipelines que nos ayudarían a construir CI/CD con Power Bi. Tuvimos en cuenta una las problemáticas que sucede en ambas soluciones (sharepoint y git repo) para evitarlas en esta metodología. El mayor temor al momento de trabajar con Sharepoint es pisarse versiones y el mayor miedo de trabajar con GIT es que un archivo de power bi no puede pasar por una acción "Merge".

NOTA: Para aquellos interesados en CI/CD pueden encontrarlo por google o en este post de la comunidad de Power Bi.

En un principio lo que voy a mostrar suena obvio y hasta repetitivo porque consisten en usar un repositorio Git con Azure DevOps, pero hay un punto de quiebre que resultó ser el quiebre de optimización.

Al igual que la solución inicial de Sharepoint tenemos que descargar la última versión del repositorio para comenzar a trabajar (pull) y luego devolverla al repositorio al terminar de modificar (commit and push). Esos dos conceptos son los principales de los cuales no podemos escapar, pero SI podemos hacerlo de todo lo demás que lo rodea. Podemos:

  • Evitar el chat y merge bloqueando el archivo cuando alguien lo toma automáticamente
  • Programar una integración continua al devolver y hasta deployarlo en el ambiente adecuado según el momento del sprint.

Muchos se preguntarán ¿Por qué bloquear el archivo?. Normalmente, cuando trabajamos con repositorios, hacemos pull request modificamos algunas cosas y la devolvemos a main. Veamos la imagen considerando que el violeta y verde son usuarios que toman el archivo celeste pbix en tiempos distintos.

image

Como dos tomaron en el archivo al momento de subirlo se generará un conflicto. Como es un archivo unico y cerrado no podemos mergear su código. Para evitar el conflicto la lógica de sharepoint funcionaba no por el chat, sino porque se esperaba a que termine un cambio para comenzar otro. Algo así:

image

Al termino del violeta comienza el verde tomando la versión modificada de violeta. Entonces nos preguntamos ¿Cómo forzar al usuario verde que el violeta termine su cambio antes de comenzar el suyo? bloqueando el archivo. Cuando el usuario haga pull request nos avise que no puede porque el Usuario X lo esta modificando.

De ese modo reduciríamos nuestra práctica colaborativa de un archivo a cuatro acciones. Bloquear, pull, push y desbloquear. Bloquear, descargar, subir y desbloquear. Aclaro que por supuesto stage y commit se siguen haciendo por prácticas de repositorio. Veamos una imagen para entender mejor como fluiría todo el repo y un spoiler de integración continua.

image

Una vez implementado los números de la imagen serían las acciones rutinarias de los desarrolladores. Para configurar esto necesitaremos un usuario dueño de la arquitectura quien hará el seteo inicial y podrá desbloquear el archivo aún cuando esté bloqueado en casos excepcionales.

Todo inicia etiquetando al archivo requerido como "Lockable", es decir bloqueable. Esto lo convierte en un archivo de solo lectura a menos que seamos nosotros quien lo bloqueemos. Para ello el usuario Owner podrá ejecutar un código semejante al siguiente

git lfs track ".\dataset.pbix" --lockable

A partir de ese momento estará listo el seteo inicial para que la diaria de los desarrolladores sea la mencionada en nuestro diagrama iniciando por el lock.

git lfs lock ".\dataset.pbix"

Al momento de ejecutar el lock sabremos si esta disponible o si otra persona lo tiene. Si alguien hizo lock y todavía no lo desbloqueó veremos un aviso de que no podemos bloquearlo porque persona@compañia.com.ar lo tiene en su poder. En caso que este disponible nos permitiría bloquearlo. Esta es una de las razones por la cual decidí usar la función lock de GIT porque no solo podemos realizar la acción sino ver quien lo tiene así en caso de emergencias. 

Asumo que los pasos intermedios ya son familiares. Hablo hacer pull de un archivo, realizar un cambio, stage y commit changes finalizando con un push.

No todo termina aquí. Ahora que terminamos nuestro trabajo es momento de disponibilizar el archivo para que otro usuario pueda usarlo. Entonces ejecutaremos 

git lfs unlock ".\dataset.pbix"

Este comando liberará el archivo para que otra persona pueda editarlo. El comando solo sirve cuando nosotros fuimos quien dimos "lock" al archivo. Si intentamos hacerlo contra un archivo que no hemos bloqueado fallaría.

Así hemos terminado con los pasos necesario para el desarrollo conjunto en equipo de un archivo versionado. Cada vez que algún miembro necesita el archivo ejecutaría esos paso.

No todo termina aquí. Seguramente pueden ocurrir problemas. Por ejemplo un desarrollador dio push de sus cambios pero nunca hizo el unlock y ahora salió de vacaciones. Por esta razón es indispensable tener un "responsable" al que llamé owner. Para una mejor organización solo esa persona debería conocer que es posible desbloquear lo que nosotros mismos no hemos bloqueado. El comando es similar pero lleva un argumento adicional para estos casos extremos.

git lfs unlock <filename> --force

Con el agregado del final podríamos desbloquear el archivo en caso que la persona que lo tiene se haya olvidado de hacerlo, no podamos contactarnos para que lo desbloquee.

Así concluimos con una metodología de trabajo con Azure DevOps sobre Git versionando Power Bi en equipo. También ahora sabemos que va más allá de la edición puesto que podríamos generar Build y Deploys configurables según las necesidades del equipo para automatizar y evolucionar el modo de trabajo. Un claro ejemplo sería tener automatizaciones que publiquen el archivo pbix del repositorio a un determinado Workspace de PowerBi Service. De momento la mayoría de las personas utilizar PowerBi Desktop y por eso opto por esta metodología, pero no quiero terminar sin antes mencionar que la tecnología no para de crecer y para los desarrolladores más pro código seguro veremos mejores prácticas con el lanzamiento de TMDL.