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:
Puedes encontrar un ejemplo de implementación de estos archivos de flujo de trabajo en exercism/javascript.
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.
Estas son las acciones recomendadas para comprobar que el contenido de tu repositorio es íntegro:
configlet para comprobar config.json
v3 requiere archivos nuevos; esto podría pasar a configlet)También puede haber acciones específicas del track. Por ejemplo:
Y quizá quieras más comprobaciones de calidad de vida, como:
Para cada acción, piensa con qué frecuencia debería ejecutarse.
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.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.
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.
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
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.
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.
pr.ci.yml: este flujo de trabajo solo se ejecuta en las PR, una vez por cada commit.
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 pruebasscripts/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 cosasscripts/pr: igual que scripts/ci, pero solo debería ejecutarse para los ejercicios resueltos a partir de las rutas dadas como entradascripts/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 entradaSi 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.ymlsolo 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 queci.ymlse 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/xxxNO sea ejecutable.
git update-index --chmod=+x scripts/xxx
git commit -m "Make scripts/xxx executable"