GitHub Actions: buenas prácticas


Este documento de trabajo sirve como una colección de buenas prácticas para usar GitHub Actions. Si tienes alguna sugerencia o algo que agregar, ¡abre un pull request en GitHub!

Colección de buenas prácticas

Establece tiempos de espera para los flujos de trabajo

Por defecto, GitHub Actions cancela los flujos de trabajo después de 6 horas si para entonces no han terminado. Muchos flujos de trabajo no necesitan ni de lejos tanto tiempo para terminar, pero a veces ocurren errores inesperados o un job se queda colgado hasta que la ejecución del flujo de trabajo se cancela 6 horas después de haber empezado. Por eso se recomienda especificar un tiempo de espera más corto.

El tiempo de espera ideal depende de cada flujo de trabajo, pero 30 minutos suelen ser más que suficientes para los flujos de trabajo que se usan en los repos de Exercism.

Esto tiene las siguientes ventajas:

  • Los PR no se quedan esperando CI medio día, los problemas se pueden detectar antes o las ejecuciones del flujo de trabajo se pueden reiniciar.
  • La cantidad total de compilaciones paralelas es limitada, así que los jobs que se quedan colgados no causarán problemas a otros PR si se cancelan a tiempo.

Ejemplo

jobs:
  configlet:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    steps:
      - [...]

Considera si realmente se necesitan las acciones (de terceros)

Las acciones deberían tratarse como dependencias en tu lenguaje de programación favorito1: son código escrito por autores externos, fuera del control de Exercism. Incluso si confías en quienes escribieron la acción, puede haber una toma de control hostil del repositorio que indirectamente les dé acceso a los repos de Exercism, incluido acceso de escritura.

Por eso, considera con cuidado si de verdad vale la pena incorporar una acción nueva o si es mejor mover el código a una acción (nueva) bajo el control de Exercism.

Fíjate también en si la acción recibe mantenimiento activo, por ejemplo revisando la actividad reciente del repo o verificando que la acción pertenezca a una organización y no a una cuenta individual.

Por lo general, las acciones publicadas por GitHub o por la organización de Exercism se pueden considerar más o menos seguras para incluir sin mayores miramientos.

Limita el alcance del token del flujo de trabajo

Por defecto, el token de acceso que se le da al flujo de trabajo tiene permisos amplios, tanto de lectura como de escritura.

El principio de mínimo privilegio también debería aplicarse a los flujos de trabajo.

Puedes especificar qué permisos necesita un flujo de trabajo de forma individual para cada uno.

Ejemplo

Si un flujo de trabajo solo necesita leer el contenido de un repo pero no escribir en él, por ejemplo porque es una comprobación normal de CI, puedes restringir el token así:

permissions:
  contents: read

Consulta la documentación de GitHub para ver la lista completa de permisos.

Fija las acciones a sus SHA

Cuando uses otras acciones, fíjalas a un commit (mediante su SHA), no a una rama o una etiqueta. Así te aseguras de que se ejecute el mismo código cada vez, algo que no está garantizado cuando fijas a una rama o una etiqueta.

Esto tiene dos beneficios:

  1. Hace que tu compilación sea estable
  2. Evita que un atacante cambie una rama o etiqueta para que apunte a código malicioso

La única excepción a esta regla podrían ser las acciones que hemos creado nosotros mismos (Exercism).

Cómo encontrar el SHA del commit

Normalmente querrás fijar el SHA del commit de una versión específica. Para encontrar el SHA del commit de una versión, ve a la página de versiones del repositorio de la acción (por ejemplo, https://github.com/actions/checkout/releases). Busca la versión que quieres usar y haz clic en el SHA abreviado (por ejemplo, a12a394) que aparece en la sección de resumen a la izquierda de la versión. Se te redirigirá a la página de detalles de la versión, donde se indica el SHA completo del commit que puedes usar.

Ejemplo

- name: Checkout code
  uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846

Fija la versión de los runners de tests

La mayoría de los flujos de trabajo se ejecutan en los runners compatibles de GitHub. Cuando uses uno de estos runners, usa una versión específica en lugar de la última versión.

Esto garantiza que el flujo de trabajo se ejecute siempre en el mismo runner, lo que hace que tu compilación sea estable.

Ejemplo

Usa:

runs-on: ubuntu-22.04

en lugar de:

runs-on: ubuntu-latest

Considera configurar una estrategia de concurrencia

A menudo no es necesario ni útil ejecutar CI en commits intermedios si mientras tanto se ha subido un commit más reciente.

Puedes configurar una estrategia de concurrencia para cancelar automáticamente los flujos de trabajo en ejecución dentro del mismo contexto.

Ejemplo

Para cancelar las compilaciones intermedias de un PR, puedes usar la siguiente configuración de concurrencia:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
Aviso de terceros

El ejemplo anterior se basa en el flujo de trabajo de CI de PkgTemplates.jl, publicado bajo la licencia MIT:

MIT License

Copyright (c) 2017-2020 Chris de Graaf, Invenia Technical Computing Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Considera qué disparadores se necesitan realmente

Lee la guía «Fortalecimiento de la seguridad para GitHub Actions»

Las prácticas mencionadas arriba no son en absoluto exhaustivas. Para una guía completa sobre buenas prácticas de seguridad para usar GitHub Actions de forma segura, consulta la guía de seguridad de GitHub.

Lista de verificación de los flujos de trabajo

Puedes usar la siguiente lista de verificación para comprobar si un flujo de trabajo sigue las buenas prácticas. La lista no pretende ser completa, sino que se centra en los puntos más importantes.

Versión para copiar y pegar, por ejemplo para PR

  1. a menos que el lenguaje use el ecosistema npm. ↩