GitHub Actions: Guía para utilizar con Net Core

El 8 de agosto, GitHub lanzó la versión beta de GitHub Actions, un servicio que nos permite realizar integración y entrega continua (CI/CD) de nuestros repositorios. Así que, en este articulo, verán una guía para utilizar GitHub Actions con Net Core.

GitHub Actions

Con este nuevo servicio de GitHub vamos a poder construir aplicaciones en contenedores, desplegar un servicio web, publicar librerías o automatizar la bienvenida a nuevos programadores en nuestros repositorios de código abierto. De esta manera, podremos automatizar el ciclo de desarrollo de un software , pero primero mientras este en beta hay que Registrarse .

Código abierto

GitHub Actions es de código abierto, donde cualquier desarrollador puede crear acciones reutilizables. Aparte, ya existen repositorios que podemos utilizar para realizar CI/CD con cualquier tecnología y desplegar nuestro software en cualquier nube.

Yaml

Para utilizar esta funcionalidad en nuestro repositorio debemos tener una carpeta ‘.github/workflows‘, que es donde GitHub Actions lee los workflows que se van creando. Dentro de esa carpeta crearemos un archivo de extensión yml, donde programaremos múltiples jobs y a cada uno se le especificará los pasos que debe realizar.

Creamos el repositorio

Vamos a empezar creando un simple repositorio público en nuestra cuenta de GitHub.

Creando Repositorio
Creando Repositorio
Nuevo Repositorio
Nuevo Repositorio

Y desde la misma plataforma de GitHub vamos a crear un archivo vació con el nombre ‘main.yml’ dentro del directorio ‘.github/workflows

Creando nuevo archivo  '.github/workflows/main.yml'
Creando nuevo archivo ‘.github/workflows/main.yml’

Si esperamos unos segundos y entramos al menú ‘Actions’ nos aparecerá una pantalla que es donde se administra toda la funcionalidad de GitHub Actions. En este caso nos va a dar error porque el archivo que creamos esta vació, sin especificar ningún ‘Job’ que se ejecute en un evento.

Menu GitHub Actions
Menu GitHub Actions

Ahora, vamos a crear un proyecto de ASP.Net Core, en mi caso voy a crear un proyecto MVC. Para esto, primero voy a clonar el repositorio, segundo voy a abrirlo desde el Visual Studio Code y por último voy a abrir una terminal y ejecutar el comando ‘dotnet new mvc’. Recomiendo también agregar un archivo ‘.gitignore’ al repositorio.

Repositorio abierto con VsCode
Repositorio abierto con VsCode
Creando proyecto MVC en el repositorio
Creando proyecto MVC en el repositorio

Creando el Workflow de GitHub Actions

Los flujos de trabajo son procesos automatizados que se personalizan para poder construir, probar, empaquetar, lanzar o implementar nuestros proyectos. Cada flujo debe tener mínimo un trabajo, y este tendrá una serie de pasos.

A partir de ahora vamos a editar nuestro archivo main.yml mientras explico las sintaxis que debe tener el workflow.

Name

Todos los flujos de trabajo comienzan con un nombre, que será utilizado para identificarlo en el menu de GitHub Actions.


name: MiNuevoWorkflow

On

Luego de especificar el nombre, hay que especificar cuando se va a ejecutar el workflow, o sea, durante que evento se va a ejecutar; además podemos especificar más de un evento. Se utilizan los mismos eventos que los WebHooks de GitHub.

En el siguiente ejemplo le indico al workflow que se ejecute cuando se realice un push en el repositorio.


name: MiNuevoWorkflow
on: push

Y para poder especificar más de un evento lo hacemos de la siguiente manera. Por Ejemplo: hacer que se ejecute el flujo cuando se realice un push, un pull request o cuando se realiza un despliegue del proyecto.


name: MiNuevoWorkflow
on: [push, pull_request, deployment]

Cuando se utilizan los eventos push o pull_request podemos además especificar el branch o el tag en donde se realiza el evento. De esta manera podemos evitar que se ejecute el workflow en cada commit.


name: MiNuevoWorkflow
on: 
    push:
      branches:    
        - master         # Eventos de Push sobre el branch 'master'
        - 'releases/*'   # Eventos de Push sobre branchs que coincidan con 'refs/heads/releases/*'
        - '!refs/pull/*' # Eventos de Push sobre branchs que no coincidan con 'refs/pull/*'
      tags:        
        - v1             # Eventos de Push sobre v1 tag
        - v1.0           # Eventos de Push sobre v1.0 tag

Todos los eventos que se pueden utilizar los podes encontrar en este link.

Jobs

Como mencioné anteriormente, cada workflow tiene mínimo un job. Cada trabajo ejecuta una serie de pasos y cada trabajo se ejecuta de manera paralela, pero si queremos que uno dependa de otro podemos especificarlo con la palabra clave ‘needs’.

Cada job debe tener una identificación que se utiliza, por ejemplo, para indicar que un job se ejecute al terminar otro, pero para indicarle un nombre distinto al identificar lo podemos hacer con la palabra clave ‘name’. En el siguiente ejemplo muestro un workflow con un job identificado como ‘build’ pero con el nombre ‘Mi primer job’.


name: MiNuevoWorkflow
on: 
  push:
    branches:
    - master      # Eventos de Push sobre el branch 'master'
  pull_request:
    branches:
    - master      # Eventos de Pull Request sobre el branch 'master'
jobs:
  build:
    name: Mi primer job

Runs On

Para poder, por ejemplo, compilar nuestro código de la aplicación MVC, vamos a necesitar tener instalado el SDK de Net Core en un ambiente virtual. GitHub Actions nos provee instancias virtuales tanto de Windows, Linux y Mac. Cada trabajo se ejecuta en una instancia nueva. En el siguiente fragmento voy a agregar como indicar que instancia voy a utilizar.


name: MiNuevoWorkflow
on: 
  push:
    branches:
    - master      # Eventos de Push sobre el branch 'master'
  pull_request:
    branches:
    - master      # Eventos de Pull Request sobre el branch 'master'
jobs:
  build:
    name: Mi primer job
    runs-on: ubuntu-18.04

Steps

!Ahora sí! La parte más importante de los Jobs, los pasos que debe ejecutar. Los pasos se ejecutan uno por uno. Acá podremos utilizar acciones reutilizables por otros desarrolladores y ejecutar comandos del sistema operativo.

Lo primero que deberíamos hacer es usar el Action Checkout que nos sirve para clonar el repositorio en la instancia y hacer checkout en la rama ‘master’.

Lo segundo sería instalar el SDK de Net Core. Para esto vamos a usar el Action Setup-dotnet. Y nuestro archivo Yaml quedaría de la siguiente manera.


name: MiNuevoWorkflow
on: 
  push:
    branches:
    - master      # Eventos de Push sobre el branch 'master'
  pull_request:
    branches:
    - master      # Eventos de Pull Request sobre el branch 'master'
jobs:
  build:
    name: Mi primer job
    runs-on: ubuntu-18.04
    steps:
    - uses: actions/checkout@master
    - uses: actions/setup-dotnet@v1
      with:
        dotnet-version: '2.2.103' # Versión del SDK.

La sintaxis Use se usa para indicar que acciones vas a reutilizar en tu Job. Se indica el repositorio donde esta subida la acción de la siguiente manera: ” [usuario]/[nombre del repositorio] “.

Run

Ahora que ya vamos a tener el repositorio clonado y el SDK instalado, lo que quedaría es ejecutar un comando de dotnet para poder probar de que compile perfectamente. Entonces simplemente voy a agregar un solo comando para publicar el proyecto en una carpeta dentro de la instancia. Voy a utilizar la palabra Run para poder ejecutar un comando en la shell del sistema operativo. Cada Run representa un nuevo proceso, o sea, una instancia de la shell.


name: MiNuevoWorkflow
on: 
  push:
    branches:
    - master      # Eventos de Push sobre el branch 'master'
  pull_request:
    branches:
    - master      # Eventos de Pull Request sobre el branch 'master'
jobs:
  build:
    name: Mi primer job
    runs-on: ubuntu-18.04
    steps:
    - uses: actions/checkout@master
    - uses: actions/setup-dotnet@v1
      with:
        dotnet-version: '2.2.103' # Versión del SDK.
    - run: dotnet publish -o app

Resultado

Ahora que tenemos hecho nuestro workflow, vamos a hacer commit a todos los archivos y luego push. De esta manera vamos a tener el proyecto y el workflow ya en GitHub.

Luego de hacer push, volvemos al menú de GitHub Actions y vamos a ver que aparece una tabla ‘Workflows Run’, que es donde aparecen todas las veces que se ejecutó el workflow. En este caso es la primera vez que se ejecuta y vemos que tiene un punto marrón, esto aparece porque indica que se esta ejecutando.

paso 4 2.PNG
Menú GitHub Actions mostrando que se esta ejecutando un workflow

Si hacemos click sobre ese item nos aparecerá el log del job que se ejecuta y lo que falta por ejecutar.

Y cuando finalicen todos los pasos de manera correcta, se mostrarán con tildes verdes.

paso 6.PNG
Log del workflow finalizado correctamente
Workflow finalizado correctamente

En caso de que algún paso de algún job tenga un error, nos aparecerá una cruz roja como al principio por subir el archivo ‘main.yml’.

Probar con los 3 sistemas operativos

Aprovechando que GitHub Actions nos permite levantar una instancia virtual de Windows, Linux o Mac, entonces podríamos probar que nuestro proyecto funcione en cualquier ambiente.

Strategy

Strategy nos permitirá crear una matriz del Job definiendo diferentes variaciones, como en este caso que vamos a crear una matriz del Job creado donde cada Job en la matriz tendrá un sistema operativo diferente.

Matrix

Para poder crear la matriz vamos a usar la palabra clave Matrix para poder definir las variaciones de cada uno.

En Run-on ya no vamos a especificar un sistema operativo, sino que vamos a indicar la propiedad de la matriz. Se puede declarar cualquier propiedad en la matriz definiendo los valores de la matriz entre corchetes ( ‘[ ]’ )


name: MiNuevoWorkflow
on: 
  push:
    branches:
    - master      # Eventos de Push sobre el branch 'master'
  pull_request:
    branches:
    - master      # Eventos de Pull Request sobre el branch 'master'
jobs:
  build:
    name: Mi primer job
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macOS-latest]
    steps:
    - uses: actions/checkout@master
    - uses: actions/setup-dotnet@v1
      with:
        dotnet-version: '2.2.103' # Versión del SDK.
    - run: dotnet publish -o app

Entonces en GitHub Actions nos aparecerá que de un workflow se ejecutan 3 Jobs en paralelo.

Paso 10.PNG
Matriz de 3 Jobs en un workflow

Cada Jobs se va a estar ejecutando independientemente de los otros con su propio resultado.

Paso 11.PNG
Ejecución de los Jobs de la Matriz

Y cuando finalicen los 3 Jobs, ahí sera cuando finalice la ejecución del workflow.

Paso 12.PNG
Jobs completados con éxito en todos los sistemas operativos

En esta guía vimos como compilar el proyecto pero podríamos dar muchos más usos como por ejemplo: ejecutar los test, publicar librerías en un servidor de Nuget o levantar la aplicación en algún proveedor de nube como Azure, AWS o Google Cloud. Para todo esto hay muchas acciones para usar en el perfil de GitHub Actions o en el siguiente link podrán ver un proyecto hecho por la comunidad donde varios desarrolladores subieron sus acciones reutilizables.