Introducción a las acciones de GitHub - Automatización de software

¡Comienza a usar las acciones de GitHub! En esta guía, aprenderá qué son y cómo funcionan, además de un flujo de trabajo de ejemplo práctico de un benchmarker creado con Python.

Introducción

En esta guía, veremos qué son las acciones de GitHub, cómo funcionan y crearemos un flujo de trabajo usando Python para mostrar cómo puede usar las acciones de GitHub para automatizar tareas.

Desde su creación en 2008, GitHub ha crecido hasta convertirse en el líder de facto en hospedaje de proyectos de desarrollo. Una idea orientada a la comunidad para permitir que todos nuestros programas favoritos de código abierto se hospeden gratis en un lugar central explotó. GitHub se hizo tan popular que se convirtió en sinónimo de git; encontrará docenas de artículos en línea que explican cómo git no es lo mismo que GitHub, y viceversa.

En su aniversario de 10 años, una gran empresa adquirió GitHub por 7500 millones de dólares. El nombre de esa empresa es Microsoft. Dejando a un lado la adquisición de GitHub, construyendo WSL y teniendo muchos proyectos de código abierto como VS Code, .NET y TypeScript, solo por nombrar algunos, Microsoft cambió el juego de desarrollo y la opinión del público en general sobre la invasión de la privacidad de la empresa. eso era Windows 10.

Por más orientado a la comunidad que aún pueda estar, el siguiente objetivo de GitHub era comenzar a obtener algunos ingresos, ingresando a la escena empresarial. Cue - Acciones de GitHub.

Echando un vistazo a las soluciones empresariales existentes {#echando un vistazo a las soluciones empresariales existentes}

En el momento en que Microsoft puso sus manos en GitHub, algunos grandes jugadores ya habían establecido la escena empresarial para el desarrollo de software:

  • BitBucket de Atlassian permitió una integración perfecta con Jira y Trello, los líderes en gestión y organización de problemas.
    • CodeCommit de Amazon * permitió a las organizaciones que utilizan AWS nunca abandonar la comodidad de una interfaz de usuario y una herramienta CLI.
  • GitLab, con su enfoque orientado a DevOps destinado a centralizar todo el proceso de desarrollo bajo un mismo techo.

En los últimos años, GitHub ha logrado agregar muchas de las funciones de la competencia empresarial, incluido CI/CD

CI/CD y automatización

El desarrollo de software moderno se basa en gran medida en la automatización, y por una sencilla razón: acelera todo. Las nuevas versiones se crean, prueban e implementan automáticamente en los entornos apropiados.

Todo lo que se necesita es un solo esfuerzo para escribir un par de scripts y configurar algunas máquinas para ejecutarlos. La oferta de GitHub de tales características viene en forma de Acciones de GitHub

Una descripción general de las acciones de GitHub

Al momento de escribir esta guía, las acciones de GitHub tienen menos de dos años. A pesar de su corta edad, la característica ha madurado bastante bien debido a que es una característica de GitHub.

La comunidad

Innumerables usuarios se sumaron y comenzaron a conocer los entresijos de GitHub Actions y comenzaron a escribir sus propios módulos reutilizables (o acciones) y los compartieron con el resto del mundo. GitHub depende en gran medida de tales contribuciones en su modelo de marketing. Actualmente hay más de 9500 acciones diferentes que le permiten, en unas pocas líneas de código, configurar sus entornos, ejecutar linters y probadores, interactuar con numerosas API de plataformas importantes, etc. Todo sin tener que instalar ningún software además de git y su favorito. editor.

Flujos de trabajo

Definimos nuestro proceso automatizado a través de workflows. Son archivos YAML que contienen, entre otras cosas, el nombre de nuestro flujo de trabajo, eventos desencadenantes, trabajos y pasos de nuestra canalización y ejecutores para realizarlos.

YAML

YAML no es un lenguaje de marcado o YAML (un acrónimo recursivo) es un lenguaje que se usa principalmente para escribir archivos de configuración. A menudo se prefiere a JSON para facilitar la escritura y la legibilidad. Aunque JSON es más rápido en términos de serialización y mucho más estricto, YAML se usa en lugares donde la velocidad no es de gran importancia.

Si nunca has tenido experiencia con YAML, te recomiendo que visites Aprende X en Y minutos, donde X=YAML.

Si tienes algo de experiencia, te recomiendo leer sobre algunas de las idiosincrasias y trampas de YAML. ://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html#gotchas).

Eventos desencadenantes

La palabra clave on especifica uno o más eventos GitHub (nota: no solo git) que activarán el flujo de trabajo. El evento puede ser muy amplio, p. en cada envío al repositorio, o muy específico, p. cada vez que una solicitud de extracción recibe un nuevo comentario.

Los eventos también se pueden programar de forma similar a un cron:

1
2
3
4
name: my workflow
on:
  push:
    branches: [main, test]

Aquí, tenemos un evento desencadenante establecido para cada impulso a la rama main o test. Otra forma de registrar disparadores es en un cronograma, como:

1
2
3
4
name: my nightly build workflow
on:
  schedule:
    cron: '0 22 * * *'

Esta es una compilación nocturna programada para las 10 p.m. todos los días.

Trabajos

Hasta ahora, le hemos dado un nombre a nuestro flujo de trabajo y hemos configurado diferentes eventos que lo activan. La palabra clave trabajos enumera las acciones que se ejecutarán. Un flujo de trabajo puede contener múltiples trabajos con múltiples “pasos” cada uno:

1
2
3
4
5
6
7
8
9
jobs:
  job1:
    steps:
      .
      .
  job2:
    steps:
      .
      .

Por defecto, todos los trabajos se ejecutan en paralelo, pero podemos hacer que un trabajo espere la ejecución de otro usando la palabra clave necesita:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
jobs:
  job1:
    steps:
      .
      .
  job2:
    needs: job1
    steps:
      .
      .
  job3:
    needs: [job1, job2]
    steps:
      .
      .

Asegurar que los trabajos se ejecuten con éxito uno por uno.

También podemos configurar de forma independiente el entorno de cada trabajo o ejecutar un trabajo en múltiples configuraciones usando la estrategia de matriz. La documentación señala:

Una matriz le permite crear múltiples trabajos mediante la sustitución de variables en una sola definición de trabajo.

Aquí hay un ejemplo de una construcción de matriz configurada para trabajar en múltiples plataformas:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
jobs:
  ubuntu_job:
    runs-on: ubuntu-latest
    steps:
      .
      .
  multi_os_job:
    runs-on: {{matrix.os}}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-2016, macos-latest ]
    steps:
      .
      .

Acciones

Las acciones son módulos reutilizables que se pueden colocar en flujos de trabajo como cualquier otro trabajo o paso. Ambos pueden tomar entradas y producir salidas. El mercado de la comunidad es rico en muchas acciones de arranque para preparar entornos; usaremos algunos hoy.

Puede escribir sus propias acciones como contenedores docker o mediante el uso de JavaScript estándar y contribuir al mercado, o guardárselas para usted.

Se puede hacer referencia fácilmente a una acción en un flujo de trabajo como cualquier otro paso en la lista:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
jobs:
  compile_code:
    runs-on: ubuntu-latest
    steps:
      - name: check out repo
        uses: actions/[correo electrónico protegido]
      - name: compile code
        run: gcc main.c
      .
      .

Aquí podemos ver un ejemplo del uso de acciones como cualquier otro paso. Tenga en cuenta que los pasos, a diferencia de los trabajos, siempre se ejecutan consecutivamente.

Corredores

Los corredores, también conocidos como agentes o trabajadores, son máquinas que tienen la tarea de ejecutar sus flujos de trabajo. Cada corredor se puede configurar de manera diferente. Por ejemplo, GitHub ofrece corredores en los tres tipos de SO más populares: Ubuntu, Windows y MacOS.

GitHub ofrece sus propios ejecutores, pero también puede optar por hospedar su propio ejecutor con la aplicación de ejecutor GitHub Actions configurada.

Precios

Los corredores de GitHub pueden ejecutar flujos de trabajo de forma gratuita si el repositorio es público y el umbral mensual no supera los 2000 minutos.

Teams y Enterprises tienen sus propias categorías de precios (típicas) con diferentes ventajas y precios, a $4/usuario por mes y $21/usuario por mes respectivamente, al momento de escribir esta guía.

Para obtener una descripción general completa de los planes de GitHub, consulte la [página de precios] actualizada de GitHub (https://github.com/pricing).

Artefactos: datos persistentes del flujo de trabajo

Dado que los corredores de GitHub están disponibles temporalmente, también lo están los datos que procesan y generan. Artefactos son datos que pueden permanecer disponibles en la página del repositorio después de la ejecución de ejecutores y deben cargarse con la acción especial upload-artifact.

El período de tiempo de retención predeterminado es de 90 días, pero eso se puede cambiar:

Workflow overview screen

La pantalla de descripción general nos recibe con una gran cantidad de datos, incluido el número de ejecución del flujo de trabajo, una lista de todos los trabajos que están en cola de ejecución o que ya se han ejecutado, la representación visual de diferentes trabajos y sus conexiones, así como cualquier artefacto producido. por el flujo de trabajo.

Acciones de GitHub en la práctica - Un Benchmarker de Python

{.icon aria-hidden=“true”}

Nota: este ejemplo usa un repositorio creado para este artículo, que se puede encontrar, como era de esperar, en GitHub.

Combinemos lo que hemos cubierto en un flujo de trabajo completo. Crearemos un flujo de trabajo de evaluación comparativa de Python que colocaremos en .github/workflows/benchmark.yml.

El flujo de trabajo se activará cada vez que se envíe a la rama principal.

1
2
3
4
5
6
name: python version benchmarker

on:

push:
  branches: [main]

El flujo de trabajo consta de tres etapas.

La etapa de pelusa

El primer trabajo tiene la tarea de eliminar el contenido de benchmarker.py, asegurándose de que tenga una puntuación de al menos 8,0:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
jobs:
  pylint:
    runs-on: ubuntu-latest
      steps:
        - uses: actions/[correo electrónico protegido]                 # checkout repo
        - uses: actions/[correo electrónico protegido]             # set up environment for python
            with:
              python-version: 3.7
        - uses: py-actions/[correo electrónico protegido] # install dependencies from requirements.txt
            with:
              path: requirements.txt
        - name: run pylint, fail under 8.5
          run: pip install pylint; pylint benchmarker.py --fail-under=8

Punto de referencia

Ejecutaremos el punto de referencia en 6 versiones e implementaciones diferentes de python, fallando si el código no es compatible con todas ellas (configurado con el parámetro “fail-fast” de la estrategia de matriz, que es “verdadero” de forma predeterminada) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  benchmark:
    runs-on: ubuntu-latest
    needs: pylint
    outputs:
      pypy2: ${{ steps.result.outputs.pypy2 }}
      pypy3: ${{ steps.result.outputs.pypy3 }}
      py2-7: ${{ steps.result.outputs.py2-7 }}
      py3-6: ${{ steps.result.outputs.py3-6 }}
      py3-7: ${{ steps.result.outputs.py3-7 }}
      py3-8: ${{ steps.result.outputs.py3-8 }}
    strategy:
      matrix:
        include:
        - python-version: pypy2
          out: pypy2
        - python-version: pypy3
          out: pypy3
        - python-version: 2.7
          out: py2-7
        - python-version: 3.6
          out: py3-6
        - python-version: 3.7
          out: py3-7
        - python-version: 3.8
          out: py3-8
    steps:
    - uses: actions/[correo electrónico protegido]
    - name: setup py
    uses: actions/[correo electrónico protegido]
     with:
        python-version: ${{matrix.python-version}}
    - name: save benchmark stats
      id: result
      run: |
        echo "::set-output name=${{matrix.out}}::$(python benchmarker.py)"

Echemos un vistazo más detallado a esto, para ver algunos problemas más finos que puede encontrar al usar GitHub Actions. La palabra clave outputs especifica pares clave:valor que un trabajo puede producir y permitir que otros trabajos hagan referencia. El valor clave es el nombre de la salida y el valor es una referencia a una salida particular de un paso con un id dado.

En nuestro caso, el paso con un id: resultado producirá una salida basada en el valor de la matriz de la versión de python que tuvo que modificarse y proporcionarse con el parámetro out desde el acceso al objeto de GitHub la sintaxis no permite puntos en los nombres de los objetos, además de tener números en la primera posición.

No había una forma inherente de colocar las salidas en un solo json y hacer referencia a steps.result.outputs como un objeto JSON, lo que se puede hacer con fines de solo lectura, como veremos en la siguiente etapa. Cada salida debe definirse explícitamente.

Subir a Pastebin y crear un artefacto nuevo {#subir a Pastebin y crear un artefacto}

La tercera y última etapa leerá los resultados de la etapa anterior y los compilará en un solo archivo. Ese archivo se cargará como un artefacto y también se cargará en Pastebin.

Para realizar una solicitud post a pastebin, necesitaremos configurar una cuenta y luego usar su clave API:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
  pastebin:
    runs-on: ubuntu-latest
    needs: benchmark
    steps:
      - uses: actions/[correo electrónico protegido]
      - uses: actions/[correo electrónico protegido]
        with:
          python-version: 3.9          
      - uses: py-actions/[correo electrónico protegido]
        with: 
          path: requirements.txt
      - name: use benchmark data
        run: echo '${{ toJSON(needs.benchmark.outputs) }}' > matrix-outputs.json
      - name: pastebin API request
        env:
          PASTEBIN_API_KEY: ${{ secrets.PASTEBIN_API_KEY }}
        run: python pastebin.py
      - name: upload newly created artifact
        uses: actions/[correo electrónico protegido]
        with:
          name: benchmark-stats
          path: newpaste.txt

El secreto se coloca como una variable de entorno de trabajo para acceder fácilmente con os.environ[PASTEBIN_API_KEY] en Python.

Gestión de secretos en GitHub

GitHub ofrece un lugar seguro para los secretos a nivel de repositorio o de todo el proyecto. Para guardar un secreto, vaya al repositorio Configuración y agregue un nuevo valor en la pestaña Secretos:

Secrets Management in GitHub

¿Cuándo no elegir GitHub Actions como herramienta de CI/CD?

Aunque hemos visto el potencial de esta nueva característica de GitHub, hay algunas cosas a considerar; cosas que pueden ser un factor decisivo y hacer que busque una herramienta de automatización en otro lugar:

  • La oferta de corredores de GitHub es bastante escasa. Con 2 núcleos y 8 GB de RAM, son buenos para ejecutar linters y pruebas; pero ni siquiera pienses en una compilación seria.
  • La depuración de REWRITE Workflow puede ser una experiencia desagradable. No hay forma de volver a ejecutar un solo trabajo sino de volver a ejecutar todo el flujo de trabajo. Si el paso final es encontrar problemas, tendrá que volver a escribir el flujo de trabajo para que la solución de problemas sea un poco más soportable o esperar a que se ejecute todo el flujo de trabajo antes de llegar al punto de solución de problemas.
  • No hay soporte para compilaciones distribuidas.

Conclusión

Las GitHub Actions han madurado mucho en los últimos años, pero no lo suficiente. Aún así, el potencial está ahí. Con la mejor API de todas las plataformas git y con el enfoque innovador de escribir acciones en JavaScript, todo respaldado por la comunidad git más grande del mundo, no hay duda de que GitHub Actions tiene el potencial para hacerse cargo. todo el juego CI/CD. Pero no todavía.

Por ahora, use esta herramienta para compilar/empaquetar de manera simple o para agregar etiquetas a sus confirmaciones mientras la empresa aún depende de Jenkins, Travis CI y GitLab CI. I.