SetValue.NETSetValue.NET

Custom GitHub Actions

August 08, 2020

Generic badge

En el anterior post, realizábamos una pequeña introducción a las GitHub Actions, qué son y cómo pueden contribuir a mejorar la construcción de un software. En este nuevo artículo, vamos a construir una GitHub Action sencilla en JavaScript, que nos permita automatizar una tarea.

Let's go

En primer lugar, necesitamos tener instalado Node.js 12.x en nuestra máquina. Una vez instalado, nos descargamos el toolkit necesario para poder empezar a construir nuestra GitHub Action, para ello, en un terminal, realizamos las siguientes operaciones:

md CustomGitHubAction
cd CustomGitHubAction
npm init -y
npm install @actions/core
npm install @actions/github
code .

Una vez completados, en Visual Studio Code, creamos tres ficheros:

  • action.yml. Metadatos de la Action
  • index.js. Código que va a ejecutar la Action
  • README.md. Una documentación de cómo funciona la Action

En el fichero JavaScript, vamos a definir una pequeña rutina para mostrar la hora por consola de una zona horaria especificada en los parámetros de la Action, y si no es especificada, por defecto mostraremos el valor de distintas zonas horarias. Evidentemente esto es un ejemplo muy sencillo, con el objetivo de mostrar la capacidad y las posibilidades que tiene construir tus propias GitHub Actions.

const core = require('@actions/core');
const github = require('@actions/github');

const culture = 'es-ES';

try {
    var utcDate = new Date(new Date().toUTCString());
    const timeZone = core.getInput('time-zone');
    if (timeZone) {
        var customTime = utcDate.toLocaleString(culture, { timeZone: timeZone });
        console.log(`Time in your zone (${timeZone}): ${getTimeString(customTime)}`);
        core.setOutput("time", new Date(customTime));
    }
    else {
        var newYork = utcDate.toLocaleString(culture, { timeZone: 'America/New_York' });
        var madrid = utcDate.toLocaleString(culture, { timeZone: 'Europe/Madrid' });
        var minsk = utcDate.toLocaleString(culture, { timeZone: 'Europe/Minsk' });
        var shangai = utcDate.toLocaleString(culture, { timeZone: 'Asia/Shanghai' });
        var brisbane = utcDate.toLocaleString(culture, { timeZone: 'Australia/Brisbane' });

        console.log(`New York: ${getTimeString(newYork)}`);
        console.log(`Madrid: ${getTimeString(madrid)}`);
        console.log(`Minsk: ${getTimeString(minsk)}`);
        console.log(`Shangai: ${getTimeString(shangai)}`);
        console.log(`Brisbane: ${getTimeString(brisbane)}`);
        core.setOutput("time", utcDate);
    }

    const payload = JSON.stringify(github.context.payload, undefined, 2)
    console.log(`Payload: ${payload}`);
} catch (error) {
    core.setFailed(error.message);
}

function getTimeString(dateTime) {
    return new Date(dateTime).toTimeString().split(' ')[0];
}

Después, en los metadatos de la action, establecemos la configuración de la Action, indicando, entre otras cosas los inputs y outputs.

name: 'What time is it'
description: 'Shows the current time in a specific time zone'
inputs:
    time-zone:
        description: 'Time Zone'
        required: false
        default: ''
outputs:
    time:
        description: 'Current time in your time zone'
runs:
    using: 'node12'
    main: 'index.js'

Seguimos con el readme, en él debemos especificar cómo se utiliza la Action, detallando su configuración y uso.

# What time is it? action
Esta Action muestra por consola la hora en la zona horaria que se especifique en los inputs, en caso de no especificarse ninguna, muestra la hora en distintas zonas horarias.
## Inputs
### `time-zone`
Nombre de la zona horaria de la que quieras conocer la hora que es. [Lista completa](https://gist.github.com/rxaviers/8481876).
## Outputs
### `time`
Hora actual en la zona especificada o en UTC si no se ha especificado ninguna.
## Ejemplo
uses: actions/what-time-is-it-action@v1
with:
  time-zone: 'Europe/Madrid'

Una vez creados estos ficheros, necesitamos hacer commit en un repositorio, es importante no utilizar ningún .gitignore, en caso de utilizarlo, hay que eliminar de éste, cualquier línea que impida que se incluya la carpeta node_modules. A modo de best practice, es recomendable etiquetar para versionar cada release que liberemos.

git add .
git commit -m "New GitHub Action. First Release"
git tag -a -m "First Release" v1
git push --follow-tags

Let's try

Para validar la Action que hemos creado, en el mismo repositorio, necesitamos crear un workflow que consuma esta GitHub Action. Este proceso lo podemos realizar directamente desde el propio repositorio en el portal de GitHub.

GitHub Action yaml

name: Test What time is it
on:
  [push]

jobs:
  what_time_is_it_job:
    runs-on: ubuntu-latest
    name: What time is it?

    steps:
    - name: Checkout step
      uses: actions/checkout@v2
    - name: What time is it step
      uses: ./
      id: get-time
      with:
        time-zone: 'Europe/Madrid'
    - name: Output
      run: echo "Your time is ${{ steps.get-time.outputs.time}}"

Finalmente, tras definir el workflow, hacemos commit, y comprobamos el resultado de la ejecución.

GitHub Action yaml

Test What time is it

Buy Me A Coffee