Plantillas de flujo de trabajo


Este documento explica cómo configurar flujos de trabajo de Integración Continua (CI) para un track de lenguaje de Exercism usando GitHub Actions (GHA). Incluye buenas prácticas y ejemplos que puedes usar para crear tus propios flujos de trabajo de CI rápidos, fiables y robustos. Los flujos de trabajo de GHA de esta carpeta se pueden adaptar para funcionar con cualquier CI, porque la estructura base seguirá siendo la misma.

En él:

  • Se esboza el flujo de trabajo de CI ideal
  • Se comentan consideraciones y recomendaciones
  • Se te ofrecen algunas plantillas para usar
  • Se cierra con una guía para migrar desde Travis

Puedes encontrar un ejemplo de implementación de estos archivos de flujo de trabajo en exercism/javascript.

AYUDA: esto parece muchísimo trabajo 😓

El resto del documento está pensado para explicar cómo funcionan los flujos de trabajo. Si tienes prisa y solo quieres pasar de Travis o Circle a GHA sin optimizar los scripts de PR, echa un vistazo a nuestra guía de unos 10 minutos para migrar desde Travis.

Acciones de CI del track

Estas son las acciones recomendadas para comprobar que el contenido de tu repositorio es íntegro:

  1. lint de configlet para comprobar config.json
  2. comprobar que hay stubs
  3. comprobar la documentación (v3 requiere archivos nuevos; esto podría pasar a configlet)
  4. hacer lint de los ejercicios con una configuración de «maintainers»
  5. probar los ejercicios con los archivos de ejemplo (puede incluir un paso de compilación)

También puede haber acciones específicas del track. Por ejemplo:

  1. comprobar la integridad de las configuraciones de los ejercicios
  2. comprobar el formato de los archivos de los ejercicios

Y quizá quieras más comprobaciones de calidad de vida, como:

  1. asegurarte de que existe CONTRIBUTING
  2. asegurarte de que hay un lockfile razonable para las dependencias
  3. asegurarte de que los enlaces dentro de los archivos markdown son válidos
  4. ...

Recomendaciones

Frecuencia de las comprobaciones

Para cada acción, piensa con qué frecuencia debería ejecutarse.

  • El lint con configlet es tan importante (porque un track puede romperse si el config.json se rompe) que probablemente debería ejecutarse siempre, pero solo hace falta que se ejecute una vez por commit.
  • La existencia o la integridad de los archivos solo necesita ejecutarse una vez por commit.
  • Si se supone que un track debe funcionar con varias versiones del runtime o del compilador, compilar y probar los ejercicios debería ejecutarse contra cada versión compatible.
  • Las PR probablemente solo necesiten ejecutar acciones sobre los archivos añadidos o modificados, pero como un archivo puede influir en un ejercicio, es más seguro ejecutar las acciones para el ejercicio si cambia uno de sus archivos.

Puede resultar muy útil que las acciones que deben ejecutarse estén disponibles también en local. Esto significa que los scripts que hacen el trabajo real también se puedan ejecutar a mano. Para conseguirlo, no incluyas la acción dentro de los archivos de flujo de trabajo, sino que debes crear un script independiente. Por ejemplo, la comprobación de stubs se puede hacer enteramente con bash dentro del archivo de flujo de trabajo, pero lo que se recomienda aquí es crear un nuevo script ejecutable scripts/ci-check.

«Pero si el comando es muy corto, por ejemplo eslint . --ext ts --ext tsx».

Cuando hay que actualizar este comando, hay que actualizarlo en todos los sitios: la documentación, los archivos de flujo de trabajo y la mente de los maintainers. Extraerlo a un script resuelve todo eso. Además, leer un archivo de flujo de trabajo puede ser muy abrumador.

Comprobaciones en las PR en las que cambian los ejercicios

Los scripts scripts/pr y scripts/pr-check (consulta las plantillas) se ejecutan con varios argumentos, uno por cada archivo que se haya modificado o añadido en esta PR. Por ejemplo, si se ha actualizado two-fer, la llamada podría ser así:

scripts/pr exercises/two-fer/README.md exercises/two-fer/.meta/example.ext

Se recomienda ejecutar las acciones sobre el ejercicio modificado y no sobre el archivo modificado. Esto se debe a que cambiar un archivo probablemente provoque cambios en todo el ejercicio (piensa en la configuración, los paquetes).

¿Aún no estás listo? / ¿Es complicado?

Antes de implementar esta optimización, ¡puedes ignorarla sin problema! La guía de migración sugiere añadirla en una fase posterior. Si se ignoran los argumentos de entrada, todas las comprobaciones se ejecutarán sobre todos los ejercicios. No pasa nada. Simplemente tardará más.

Comprobaciones de integridad

Si el track tiene un único archivo de dependencias «de nivel superior» u otros archivos de configuración, añade un paso de integridad (que conviva con un scripts/sync o un bin/sync, que copiaría todos los archivos de configuración a todos los ejercicios) que garantice que los archivos de nivel superior o base son los mismos que los copiados a los directorios de los ejercicios. Así se pueden actualizar las dependencias, sincronizarlas por todo el repositorio y garantizar que todos los ejercicios tengan la misma configuración.

Una forma habitual de conseguirlo es usar una suma de comprobación. Ubuntu (y varias otras distribuciones de Linux) incluye una herramienta llamada sha1sum, pero serviría cualquier método que aplique un hash o reduzca el archivo de configuración (md5, sha1, crc32) a un valor de suma de comprobación:

$ sha1sum README.md
cd58091c5043bf21f00d39ff1740d8b2976deeff *README.md

Comprobaciones de seguridad

Si el track usa flujos de trabajo adicionales que necesitan acceso al token de GitHub u otros secretos, la buena práctica es fijar todas las acciones que se usan en el flujo de trabajo a un commit concreto. Consulta la guía de endurecimiento de la seguridad de GitHub para más detalles.

Por ejemplo:

- uses: julia-actions/setup-julia@v1
+ uses: julia-actions/setup-julia@d26d1111976eae5f00db04f0515ab744ec9cd79e # 1.3.1

Si las herramientas tienen lockfiles para gestionar las dependencias, plantéate incluirlos en el repositorio y usar un «lockfile congelado» dentro de los archivos de flujo de trabajo. Por ejemplo: npm ci, yarn install --frozen-lockfile y bundle install --frozen. Así te aseguras de que el lockfile esté actualizado cuando cambies las dependencias y evitas que entren paquetes maliciosos.

Plantillas

En este directorio hay, como mínimo, las siguientes plantillas:

  • configlet.yml: este flujo de trabajo descarga el binario más reciente de configlet y hace lint de este repositorio. Se ejecuta en cada commit. En las PR, se ejecuta sobre el commit real y sobre un árbol «después del merge».
  • ci.yml: este flujo de trabajo solo se ejecuta en la rama main, una vez por cada commit.
    1. Ejecuta un comando de «pre-check» (comprobar stubs, hacer lint, documentación, etc.) para todos los ejercicios
    2. Ejecuta un comando de «ci» (compilar y probar) para varias versiones, para todos los ejercicios
  • pr.ci.yml: este flujo de trabajo solo se ejecuta en las PR, una vez por cada commit.
    1. Ejecuta un comando de «pre-check» (comprobar stubs, hacer lint, documentación, etc.) para los archivos modificados
    2. Ejecuta un comando de «ci» (compilar y probar) para varias versiones, para los ejercicios modificados

Los flujos de trabajo que no son de PR también se pueden activar mediante workflow_dispatch.

Cada archivo indica al principio qué «scripts» deberían estar disponibles. Si quieres que sean binarios, sustituye scripts/xxx por bin/xxx. Algunas herramientas exigen que los binarios estén dentro de una carpeta bin.

  • scripts/ci: un script que debería compilar y probar todos los ejercicios usando las soluciones de ejemplo contra las pruebas
  • scripts/ci-check: un script que debería hacer lint de todos los ejercicios y, opcionalmente, comprobar stubs, la integridad de la configuración y más cosas
  • scripts/pr: igual que scripts/ci, pero solo debería ejecutarse para los ejercicios resueltos a partir de las rutas dadas como entrada
  • scripts/pr-check: igual que scripts/ci-check, pero solo debería ejecutarse para los archivos o ejercicios resueltos a partir de las rutas dadas como entrada

Solución de problemas

Si tienes algún problema o quieres que alguien revise tus flujos de trabajo, avisa al equipo @exercism/github-actions.

Has cambiado un archivo de nivel superior que debería lanzar una ejecución de CI sobre todos los ejercicios.

En el momento de escribir esto, pr.ci.yml solo permite pruebas de «extensión». Lo ideal sería actualizarlo para que se lance siempre que cambien ciertos archivos (por ejemplo, el binario con el que se ejecutan las pruebas). Sin embargo, estos cambios suelen ser poco frecuentes y los hacen los maintainers, así que el hecho de que ci.yml se ejecute en main, siempre, para todo, probablemente sea lo bastante seguro.

Has creado un archivo scripts/xxx en Windows y ahora no funciona en {otro SO}

De forma predeterminada, los archivos creados en Windows no llevan incrustados en el índice de git metadatos sobre si son ejecutables, porque el modelo de permisos de Windows es distinto. Git, por defecto, usa los metadatos del índice de git para determinar si el archivo debería ser ejecutable en sistemas basados en POSIX y, por tanto, hace que el archivo scripts/xxx NO sea ejecutable.

git update-index --chmod=+x scripts/xxx
git commit -m "Make scripts/xxx executable"