Category: Programación

Integración Continua en GitHub con AppVeyor (parte 2)

En esta segunda parte, Jorge nos amplía y completa un poco más la anterior entrada sobre la Integración Continua con AppVeyor, para mostrarnos cómo generar y publicar una release automáticamente.


 

Generación del artefacto

Lo primero que será necesario es configurar un "artifact", que sera lo que se haga "push" hacia GitHub, para ello, en la pestaña "SETTINGS" en el menú "Build", haremos que los resultados que nos interesen se añadan a un .zip, creando un "After build script", en el cual meteremos los binarios que nos interese. Previamente a eso, vamos a indicarle en la parte superior, que queremos que la compilación utilice "debug" y "release".

El script:

7z a PostAppVeyor_%configuration%.zip %APPVEYOR_BUILD_FOLDER%\%APPVEYOR_PROJECT_NAME%\bin\%configuration%\*.exe

Añadirá todos los .exe que haya en la carpeta al fichero que indicamos, en caso de necesitar añadir otros ficheros o librerías, se podría indicar cambiando el patrón de búsqueda o poniendo rutas absolutas.

Con esto, AppVeyor va a generar el .zip, ahora sólo queda hacer que sea público como resultado de la compilación. Para eso, en la pestaña "SETTINGS", en el menú "Artifacts", lo creamos mediante el botón "Add artifact".

Seleccionando el .zip que se ha generado mediante el script, se le pone un nombre con el cual publicarlo en AppVeyor (hay que tener en cuenta que AppVeyor borra todos estos archivos a los 6 meses).

 

Publicación del artefacto

Después de todo lo anterior, sólo nos queda publicar los binarios en el apartado de "Release" de GitHub cuando nos interese. Para ello, lo primero de todo, necesitamos generar un token en GitHub para AppVeyor. Esto se hace desde el perfil , en el apartado "Settings/Developer Settings/Personal Access Tokens" pulsando en "Generate new token".

Tras darle un nombre, los permisos que necesitamos asignarles son simplemente "public_repo" y pulsar en "Generate token".

Esto nos genera un código alfanumérico, que debemos copiar, ya que lo necesitaremos en AppVeyor para configurarlo.

Una vez tenemos el token, nos vamos a AppVeyor y en la pestaña "SETTINGS" en el menú "Deployment", seleccionamos "Add deployment".

En el desplegable, hay que seleccionar "GitHub Releases". Cabe destacar que vamos a configurarlo para que sólo se publiquen como release los "Tags" del repositorio en la rama master. Para eso, vamos a configurar los parámetros de publicación que se ofrecen, teniendo especial cuidado en añadir una condición que sera "APPVEYOR_REPO_TAG" = true, para que sólo las etiquetas se suban a GitHub Release. Un ejemplo de como configurarlo seria el siguiente:

Una vez todo listo, solo nos queda crear un tag en nuestro proyecto, y pushear el tag a Github, esto iniciará el proceso, y cuando acabe, se podrá ver el resultado en el apartado "releases" del repositorio de GitHub.

 

Con esto queda cerrado el ciclo de despligue que junto a la entrada anterior sobre integración y testeo continuo, nos permite llevar nuestro código a cotas de calidad de desarrollo muy altas, preparando a su vez el proyecto sofware para poder gestionarlo cómodamente y de manera segura ante eventuales contribuyentes.

 

Integración Continua en GitHub con AppVeyor (parte 1)

En esta ocasión tengo el gusto de presentar a Jorge, un excelente compañero de trabajo y un grandísimo profesional. En su día a día siempre anda buscando la mejor forma de hacer las cosas y en esta ocasión nos trae un detallado tutorial de Integración Continua, ámbito en el que recientemente se ha sumergido, y del que hoy nos presenta unas pildoritas de sabiduría y buen hacer.


GitHub, con todo el revuelo que ha provocado la compra por parte de Microsoft, es uno de los mayores repositorios de código que existen, y el mayor de código libre. Dispone de múltiples herramientas que ayudan al desarrollo de aplicaciones y testeo de aplicaciones que en muchos casos no son explotadas, lo cual es una lástima ya que son gratuitas (siempre que tu repositorio sea público) y aportan una gran ayuda.

En esta entrada vamos a hablar sobre una de esas herramientas llamada AppVeyor, ¿y que es AppVeyor? Es una herramienta de integración continua que permite realizar compilaciones, ejecutar teses, y publicar binarios, todo ello con unos pocos clicks gracias a su alta integración en GitHub (y encima gratuito si tu repositorio es público).

Llegados a este punto, se puede pensar, ¿qué me puede aportar a mi todo eso? La respuesta es sencilla, si tienes algún repositorio en el que colaboras con más gente, siempre sabréis que los cambios van a compilar, y en el caso de que tengáis test unitarios, que los ha pasado, y además de todo eso, publicar las "release" si así lo queréis. Vale, ahora pensarás, yo soy un desarrollador independiente, que no comparte repositorios, y tampoco me preocupo en sacar ninguna "release", ¿en qué puede ayudarme a mi? Fácil, puedes configurar diferentes "build" para diferentes entornos, y probar que tu código es perfectamente funcional en varias plataformas y versiones sin necesitar disponer de esas máquinas para compilar en ellas.

 

Compilación

¿Te he convencido? Pues vamos a ver como podemos configurar esta herramienta para nuestro repositorio. Lo primero es registrarnos en su web (algo muy fácil usando nuestra cuenta de GitHub).

Con sólo eso, ya estamos registrados, y llegamos a nuestro "dashboard", que por el momento estará vacío, pero vamos a solucionarlo pulsando en "NEW PROJECT" .

Para este ejemplo, he creado un repositorio en mi perfil llamado PostAppVeyor, el cual aparece automáticamente, y simplemente hay que pulsar en "ADD".

Ya tenemos nuestra integración lista, aunque de momento no haya hecho nada, veamos qué pasa si pulsamos en "NEW BUILD".

Pulsando esto, se lanzará una compilación que se puede seguir desde "LATEST BUILD".

Un detalle importante, es que al haber añadido AppVeyor al repositorio, se establecen automáticamente los WebHooks para notificar a GitHub los resultados, y si miramos el historial de commits del repositorio, se puede ver el resultado.

Esto también se aplica automáticamente para los "Pull Request", de modo que siempre se comprobarán las modificaciones que haya sobre el repositorio.

 

Test unitarios

Vale, el repositorio compila, ¿cómo añado los teses? Otra respuesta fácil, AppVeyor es capaz de detectarlos automáticamente. Añadamos un test al proyecto y veamos que pasa al "pushearlo" a GitHub. Automáticamente se inicia una compilación pero... ha fallado, ¿por qué?, si en Visual Studio pasaba el test sin problemas...

Vale, esto es debido a que los teses unitarios de Visual Studio, necesitan descargar paquetes NuGet. Vamos a solucionar esto yendo a la pestaña "SETTINGS" y al menu "Build". Hay que buscar "Before build script" para añadir un evento previo a la compilación, que haga un "nuget restore", tras esto, basta con pulsar en "Save" y ya estaría listo.

Ahora que tenemos todo lo necesario, vamos a volver a probar (Mediante el botón "RE-BUILD" del resultado que ha fallado) y ¡sopresa!, ya funciona correctamente.

Pero espera... a mi no me dice eso. Mis teses no se ejecutan, ¿qué pasa? Bueno, es posible que tu proyecto este hecho en un Visual Studio superior al que usa por defecto (2015), y el descubrimiento de teses unitarios no haya funcionado del todo bien, esto podemos solucionarlo rápidamente seleccionando la versión de Visual Studio que vamos a utilizar (en mi caso 2017). Volviendo a la pestaña "SETTINGS", pero esta vez en el menú "Environment", seleccionando Visual Studio 2017 y damos a "Save".

Veamos el resultado ahora pulsando en "RE-BUILD".... ¡¡¡Premio, nuestros teses ya se ejecutan!!!

Con todo lo que hemos hecho hasta ahora, tenemos un repositorio que comprueba automáticamente si el código compila correctamente, y ademas ejecuta los teses unitarios para comprobar que sigue cumpliendo con el funcionamiento esperado.

En la próxima entrada veremos cómo generar y publicar las "releases" a partir de nuestro código compilado y testeado.

 

Hidden Console Start (HCS) – Esconde la consola y lanza procesos/aplicaciones en segundo plano

Dicen que no te das cuenta de algo hasta que lo pierdes... Esto es lo que me ha pasado cuando recientemente mi orientación profesional ha cambiado y he tenido  que trabajar con sistemas Windows en vez de GNU-Linux.

Acostumbrado a tener corriendo servicios en distintas máquinas con GNU-Linux acabas echando de menos su shell y la bestialidad de herramientas que hay. Vale sí lo reconozco, al final trabajaba en una máquina Windows, pero porque sigo pensando que las herramientas de desarrollo siguen siendo mejor que las que hay disponibles en GNU-Linux. Hay que reconocer que un Windows lo uso sólo para desarrollar (eso sí multiplataforma) y para jugar, para lo demás GNU-Linux sin duda!!!

Una de las cosas que he echado en falta recientemente es la posibilidad de usar el operador & de background tan potente en GNU-Linux. Este operador permite lanzar un proceso que se sigue ejecutando sin bloquear la shell y si la cerramos, éste sigue en segundo plano. Pues esto tan chulo, no puedes hacerlo en un Windows, porque su comando start no lo permite y la opción /B del comando no impide que al cerrarse la consola de comandos el proceso que has lanzado muera. A no ser que el proceso que has lazando cree su propio hilo no dependiente del proceso de la consola. Y tampoco es posible lanzar un proceso de consola de comandos sin consola, a no ser que esté programado explícitamente que la consola se oculte o no aparezca. Windows en este aspecto se cubre mucho, porque la única forma de crear procesos en background es construyendo servicios de Windows que tienen sus propias reglas a cumplir y por consiguiente hace falta desarrollo específico para que algo corra en segundo plano.

Visto el panorama y teniendo cierto conocimiento e idea, me decidí a generar una herramienta similar que funcionase en Windows como el operador &, o por lo menos a intentarlo. Para ello lo primero pensé en que quizás lo más adecuado fuese hacerlo en multiplataforma y generar una solución que funcionase tanto en Windows como en GNU-Linux. Atendiendo a este requisito, enseguida a mi mente llegó Python, porque además su instalación de paquetes es sencilla y potente a partes iguales, por no decir que es posible generar binarios (por ejemplo un .exe en Windows) si hiciera falta gracias a herramientas como py2exe y PyInstaller.

Con el punto de partida claro y unas horas de desarrollo, consigo lo que bautizo como Hidden Console Start o HCS. El proyecto puedes encontrarlo en Github:

Y su instalación es sencilla si tienes ya Python en tu equipo. En caso de no tener Python, pásate por la web de Python y descárgate la última versión disponible. Una vez instalado Python, solo tienes que ejecutar el siguiente comando en el CMD o PowerShell para instalar HCS:

pip install hcs --upgrade

Una vez instalado puedes ejecutar el proceso o aplicación que se quiera ejecutando HCS de la siguiente forma:

hcs -e "P1" "P2" ... "Pn-1" "Pn"

Pongamos un ejemplo:

hcs -e "ping 127.0.0.1 > log1.txt" "ping 192.168.1.17 > log2.txt"

En el ejemplo se lanzan dos comandos ping a distintas direcciones que son guardados en log1.txt y log2.txt respectivamente. Como se puede ver la consola de comandos no queda bloqueada y la información de los comandos ejecutados se va guardando el los ficheros.

Si por alguna razón tus procesos o aplicaciones no mueren o acaban, puedes finalizarlos en el caso de Windows abriendo el administrador de tareas:

Y en el caso de GNU-Linux con htop:

De esta forma podemos lanzar procesos y aplicaciones en segundo plano en sistemas Windows de una forma más o menos equivalente a como lo haríamos en GNU-Linux. Y obviamente podríamos usar HCS en GNU-Linux porque también funciona, pudiendo usarlo de la misma manera que en Windows.

Aumentar espacio de tu Raspberry Pi usando un dispositivo de almacenamiento USB

Una de las bondades de los sistemas GNU/Linux es la posibilidad de montar una unidad USB y  formatearla convenientemente. La cual puede ser montada a voluntad o meterla en la fstab (File Systems TABle) para que se monte con el arranque del sistema si lo deseamos. Para estas cosas GNU/Linux es la caña y es super flexible!! 😉

Un opción que podría ejemplificar fácilmente el uso de este procedimiento, puede ser una Raspberry Pi a la que queráis darle más espacio que el que tenéis disponible en la microSD donde tenéis montado el sistema operativo. Actualmente las memorias USB han bajado mucho su precio y han aumentado los tamaños máximos de las mismas, encontrándonos a precios razonables memorias de 128GB o256GB.

Empecemos con lo básico que es conectar la memoria USB a la Rapsberry Pi (obvio pero por si acaso lo digo 😉 ). Con la memoria USB conectada ejecutamos el siguiente comando:

ls -l /dev/disk/by-uuid/

El comando nos responde identificado las unidades disponibles. Las unidades "mmcblk0p1" y "mmcblk0p2" corresponden a la partición de boot del la Rapsberry Pi y a la de ficheros de Raspbian (Sistema Operativo) respectivamente. La que nos insteresa es la "sda1". Anota el identificador (UUID) que tiene, en mi ejemplo el mio es "51a4dc12-f769-4286-bdb6-58f40f6a7ce2".

Ahora vamos a preparar el punto de montaje de la unidad. Para ello ejecuta el siguiente comando para crear la ruta "media/usb" donde montaremos la unidad:

sudo mkdir /media/usb

Puedes usar otra ruta si lo deseas, pero intenta que sea corta, ya que tendrás que escribirla tantas veces como quieras acceder a la unidad.

Ahora hay que asegurarnos que el usuario "pi" es propietario de la nueva carpeta donde montaremos la unidad. Para ello ejecuta:

sudo chown -R pi:pi /media/usb

Para montar la unidad lo haremos con el siguiente comando:

sudo mount /dev/sda1 /media/usb

Si ejecutamos el comando:

df -h -T

Veremos que aparece la unidad en el punto de montaje "media/usb" indicado, así como el tipo de sistema de ficheros. Si has usado otro punto de montaje, aparecerá que el que hayas puesto.

Como usar la memoria USB con el formato FAT32 (aparece como vfat) no es lo más óptimo, formatearemos la unidad a EXT4 mucho más óptimo para nuestro sistema Raspbian. Puedes formatear fácilmente la unidad con el siguiente comando tras desmontar la unidad con:

sudo umount /media/usb
sudo mkfs.ext4 /dev/sda

⚠️ Ten en cuenta que si ejecutas los comandos para formatear la memoria USB, perderás los datos que hubiese dentro. ⚠️ Si estamos conformes con el formateo decimos que sí.

Si quisiéramos que la unidad se montase automáticamente, tendremos que incluir la nueva unidad en fstab. Para ello abriremos primero el fichero de configuración de fstab:

sudo nano /etc/fstab

Y añadiremos tras la última línea esta otra:

UUID=51a4dc12-f769-4286-bdb6-58f40f6a7ce2 /media/usb ext4 auto,nofail,noatime,users,exec,rw 0 0

El parámetro más importante es el "UUID" que anotamos al principio del artículo. Si finalmente optaste por formatear la memoria USB a EXT4, te recomiendo que vuelvas a ejecutar el comando porque el valor habrá cambiado.

Para concer específicamente el significado de cada parámetro te dejo la siguiente referencia:

Si finalmente decidiste NO formatear la memoria USB, la línea cambia un poco y se sustituye "ext4" por "vfat":

UUID=51a4dc12-f769-4286-bdb6-58f40f6a7ce2 /media/usb ext4 auto,nofail,noatime,users,exec,rw 0 0

Ahora solo nos resta comprobar si efectivamente la unidad se monta sola y para ello ejecutaremos un reinicio:

reboot

Si lo hemos hecho bien deberíamos poder ver la memoria USB en "/media/usb". Ya tenemos más espacio en nuestra Raspberry Pi!! 😉