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). Proporciona buenas prácticas y ejemplos que puedes usar para crear tus propios flujos de trabajo de CI, rápidos, confiables y robustos. Los flujos de trabajo de GHA que están en esta carpeta se pueden adaptar para que funcionen con cualquier CI, porque la estructura base seguirá siendo la misma.
Este documento:
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 cambiar de Travis o Circle a GHA sin optimizar los scripts de PR, revisa nuestra guía de ~10 minutos sobre Migrar desde Travis.
Las acciones recomendadas para verificar que el contenido de tu repositorio tenga integridad son las siguientes:
configlet para verificar 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ás quieras más verificaciones 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 se rompe el config.json) que probablemente debería ejecutarse siempre, pero solo necesita ejecutarse una vez por commit.Puede ser muy útil hacer que las acciones que deben ejecutarse también estén disponibles localmente. Esto significa que los scripts que hacen el trabajo real también se puedan ejecutar manualmente. Para lograrlo, no pongas la acción en línea dentro de los archivos de flujo de trabajo, sino que debes crear un script independiente. Por ejemplo, la verificación de stubs se puede escribir por completo en bash dentro del archivo de flujo de trabajo, pero la recomendación aquí es crear en su lugar un nuevo script ejecutable, scripts/ci-check.
«Pero el comando es muy corto, por ejemplo
eslint . --ext ts --ext tsx».Cuando este comando necesita actualizarse, ahora hay que actualizarlo en todos los lugares: la documentación, los archivos de flujo de trabajo y la mente de los mantenedores. 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 ha cambiado o agregado en este PR. Por ejemplo, si se actualizó two-fer, una llamada podría verse así:
scripts/pr exercises/two-fer/README.md exercises/two-fer/.meta/example.ext
Se recomienda ejecutar cualquier acción contra el ejercicio modificado y no contra el archivo modificado. Esto se debe a que cambiar un archivo probablemente genere cambios en todo el ejercicio (piensa en: la configuración, los paquetes).
¿Aún no estás listo? / ¿Es muy complejo?
Antes de implementar esta optimización, ¡puedes ignorarla sin problema! La guía de migración sugiere agregarla en una etapa posterior. Si se ignoran los argumentos de entrada, todas las verificaciones se ejecutarán sobre todos los ejercicios. No hay ningún problema con eso. Solo tardará más.
Si el track tiene un único archivo de dependencias «de nivel superior» u otros archivos de configuración, agrega un paso de integridad (que exista junto a un scripts/sync o bin/sync, el cual copiaría todos los archivos de configuración a todos los ejercicios) que garantice que los archivos de nivel superior o base sean iguales al que se copió en los directorios de los ejercicios. Así, las dependencias se pueden actualizar, sincronizar en todo el repositorio y podemos garantizar que todos los ejercicios tengan la misma configuración.
Una forma común de lograr esto es usar una suma de verificación. Ubuntu (y varias otras distribuciones de Linux) incluye una herramienta llamada sha1sum, pero serviría usar cualquier método para aplicar un hash o reducir el archivo de configuración (md5, sha1, crc32) a un valor de suma de verificación:
$ sha1sum README.md
cd58091c5043bf21f00d39ff1740d8b2976deeff *README.md
Si el track usa flujos de trabajo adicionales que requieren acceso al token de GitHub u otros secretos, la buena práctica es fijar todas las acciones usadas en el flujo de trabajo a un commit específico. Consulta la guía de endurecimiento de 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 la gestión de dependencias, considera agregarlos al 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. Esto garantiza que el lockfile esté actualizado al cambiar dependencias y evita 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 le hace linting a este repositorio. Se ejecuta en cada commit. Para los PR, se ejecuta sobre el commit actual y sobre un árbol «después del merge».ci.yml: Este flujo de trabajo solo se ejecuta en la rama principal, una vez por cada commit.
pr.ci.yml: Este flujo de trabajo solo se ejecuta en los 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 tiene indicado en la parte superior qué «scripts» deberían estar disponibles. Si quieres que sean binarios, reemplaza scripts/xxx por bin/xxx. Algunas herramientas requerirán que los binarios estén dentro de una carpeta bin.
scripts/ci: un script que debe compilar y probar todos los ejercicios, usando las soluciones de ejemplo contra las pruebasscripts/ci-check: un script que debe hacer linting de todos los ejercicios y, opcionalmente, verificar los stubs, la integridad de la configuración y másscripts/pr: igual que scripts/ci, pero solo debe ejecutarse para los ejercicios resueltos a partir de las rutas dadas como entradascripts/pr-check: igual que scripts/ci-check, pero solo debe 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.
Cambiaste un archivo de nivel superior que debería activar una ejecución de CI en todos los ejercicios
Al momento de escribir esto, pr.ci.yml solo permite pruebas por «extensión». Lo ideal sería actualizarlo para que se active siempre que se cambien ciertos archivos (por ejemplo, el binario para ejecutar las pruebas). Sin embargo, estos cambios suelen ser poco frecuentes y los hacen los mantenedores, así que probablemente sea suficientemente seguro que ci.yml se ejecute en main, siempre, para todo.
Creaste un archivo scripts/xxx en Windows y ahora no funciona en {other OS}
De forma predeterminada, los archivos creados en Windows no tienen metadatos incrustados en el índice de git sobre si son ejecutables, porque el modelo de permisos en Windows es diferente. De forma predeterminada, Git usa los metadatos del índice de git para determinar si el archivo debería ser ejecutable en sistemas basados en POSIX y, por lo tanto, hace que el archivo scripts/xxx NO sea ejecutable.
git update-index --chmod=+x scripts/xxx
git commit -m "Make scripts/xxx executable"