Diario
Secciones
Ajustes de lectura
Voz natural grabada para este curso, la misma en todos los navegadores.
Ninguna voz para este idioma en este navegador.
Más voces
Código y términos técnicos en inglés
Desactivado: la voz de la página lo lee todo, sin pausa entre dos voces.
Ninguna voz para este idioma en este navegador.
Más voces
Más voces: Microsoft Edge ofrece voces naturales en línea, y Windows (Configuración › Hora e idioma › Voz), macOS y Android instalan otras.
Progreso
Sección titulada «Progreso»- Código de ejemplo: la misma función de slug en .NET (xUnit v3) y Java (JUnit 6)
- Lección 1: primer workflow, leer ejecuciones con
gh - Lección 2: build con matrix en tres sistemas operativos, setup-dotnet, setup-java, caché de Maven
- Lección 3: disparadores, filtros, inputs, concurrencia
- Lección 4: expresiones, contextos, salidas, condiciones
- Lección 5: cachés y artefactos (caché de NuGet con
packages.lock.json,actions/cache, artefactos entre jobs) - Lección 6: workflows reutilizables y acciones compuestas
- Lección 7: seguridad — permisos, secretos, fijación de versiones, OIDC
- Lección 8: desplegar en GitHub Pages
- Lección 9: depurar ejecuciones
- Lección 10: escribir tu propia acción
2026-09-14 — Primero en local: dos trampas de xUnit v3
Sección titulada «2026-09-14 — Primero en local: dos trampas de xUnit v3»Antes de escribir ningún workflow, dotnet test en el proyecto de ejemplo (SDK 10.0.112 en local, xunit.v3 4.0.1) falló dos veces:
Testing with VSTest target is no longer supported by Microsoft.Testing.Platform on .NET 10 SDK and later.Corrección:"test": { "runner": "Microsoft.Testing.Platform" }englobal.json.CS0246: The type or namespace name 'Theory' could not be found. ConImplicitUsingsactivado, esta versión del paquete no añadíausing Xunit. Corrección: elusingen el archivo de pruebas.
El lado Java (mvn -B verify, JUnit 6.1.3, Maven 3.9.16) pasó a la primera.
2026-09-14 — Primer push: cuatro workflows, uno inválido
Sección titulada «2026-09-14 — Primer push: cuatro workflows, uno inválido»El push de los cuatro workflows de las lecciones (commit 61e7e42) los inició todos. GHA 01, GHA 02 (6 jobs) y GHA 04 pasaron. GHA 03 apareció con el nombre de su archivo, falló en 0 s, sin ningún job: You have an error in your yaml syntax on line 41, una línea run: echo "cron: …" (un valor sin comillas que contiene : ). El push siguiente, sin relación con ese archivo, lo hizo fallar de nuevo, a pesar de su filtro paths.
Un segundo commit la misma tarde repitió el error en gha-04-exercises.yml (run: echo "next: $BUILD_LABEL"); esta vez python -c "import yaml; yaml.safe_load(...)" lo detectó antes del push. Lección: validar el YAML en local, siempre.
2026-09-14 — Colisión de dos despliegues de este sitio
Sección titulada «2026-09-14 — Colisión de dos despliegues de este sitio»Los pushes 61e7e42 y cb69dca, con 14 s de diferencia, iniciaron cada uno Deploy to GitHub Pages. El segundo job de despliegue falló:
##[error]HttpError: Deployment request failed for cb69dca950b667b876d8d32cfe778a24b6320c59 due to in progress deployment. Please cancel 61e7e4235b7bc138f2f35cd7f61195bdaed4b019 first or wait for it to complete.El sitio se quedó en la versión anterior hasta el push siguiente. Corrección en deploy.yml (commit 5c9896f): concurrency: { group: pages, cancel-in-progress: false }. Varias sesiones hacen push a este repositorio, así que las colisiones iban a volver a ocurrir.
2026-09-14 — Mediciones
Sección titulada «2026-09-14 — Mediciones»- Caché de Maven, primera ejecución → segunda ejecución de
gha-02: Ubuntu 16 s → 10 s, Windows 43 s → 28 s, macOS 20 s → 9 s. Jobs de .NET sin cambios (21/60/20 s → 22/57/22 s): todavía no hay caché de NuGet. global.json10.0.100+latestFeature→setup-dotnetinstaló el SDK 10.0.401.- Temurin 25.0.4 venía preinstalado en
ubuntu-latest(Resolved Java 25.0.4+1 from tool-cache). macos-latestes arm64 (clave de cachésetup-java-macOS-arm64-maven-…).- Shell por defecto de
run::/usr/bin/bash -e {0}(Ubuntu),/bin/bash -e {0}(macOS),pwsh -command ". '{0}'"(Windows).shell: bashexplícito en Windows:bash.EXE --noprofile --norc -e -o pipefail {0}, bash 5.3.15. - Permisos por defecto de
GITHUB_TOKENen este repositorio:Contents: read,Metadata: read,Packages: read. El token tenía 377 caracteres. - Concurrencia con
cancel-in-progress: true: la ejecución del push fue cancelada por una ejecución manual 41 s después, cancelada a su vez 10 s más tarde por otra antes de que arrancara su job.
2026-09-14 — Lección 5: una caché que no ahorra nada, un conflicto de artefactos que no ocurre
Sección titulada «2026-09-14 — Lección 5: una caché que no ahorra nada, un conflicto de artefactos que no ocurre»setup-dotnetcache: truesin ningúnpackages.lock.json:Dependencies lock file is not found in /home/runner/work/learn/learn. Se añadióRestorePackagesWithLockFileenDirectory.Build.props, se hizo commit de los dos archivos de bloqueo,dotnet restore --locked-modeen la CI.- Caché de NuGet, sin caché → acierto: step de restauración 3 s → 1 s (Ubuntu, macOS), 5 s → 4 s (Windows), para una caché de 54 MB por sistema operativo. La descarga de la caché cuesta más o menos lo que ahorra en un proyecto con tres paquetes de prueba. Se mantiene por la lección y por los archivos de bloqueo.
- Salida
cache-hitdeactions/cache: vacía sin acierto,falsecon una coincidencia derestore-keys,truecon un acierto exacto. - Dos jobs de matrix que suben un artefacto llamado
os: el README anuncia errores de conflicto; en tres ejecuciones de tres, las dos subidas tuvieron éxito y la ejecución tenía dos artefactos llamadosos.download-artifactygh run download --name osdevolvieron ambos el de Ubuntu, sin aviso. - Caducidad de los artefactos: 7 días con
retention-days: 7, si no, 90 días (gh api repos/spareilleux/learn/actions/permissions/artifact-and-log-retention→{"days":90,"maximum_allowed_days":90}).
2026-09-14 — Lección 6: la reutilización, y una rama para un workflow no válido
Sección titulada «2026-09-14 — Lección 6: la reutilización, y una rama para un workflow no válido»- La acción compuesta
dotnet-restorerestauró la caché de NuGet guardada porgha-05: misma clave y misma ruta, otro workflow. Las cachés pertenecen al repositorio y a la rama. - En el workflow llamado:
github.workflowes el nombre del llamador,job.workflow_refapunta agha-06-dotnet-test.yml, elenva nivel de workflow del llamador está vacío. - Matrix de dos llamadas a un workflow reutilizable: la salida
tested-onfueWindows, el job que terminó el último. run:de acción compuesta sinshell::Required property is missing: shell, solo cuando un job ejecuta la acción.- Input no declarado:
startup_failure, ningún job, ygh run viewno muestra el motivo (la página de la ejecución, sí). Probado desde una rama temporalgha-06-invalidpara quemainnunca contuviera un workflow no válido. El borrado de la rama remota lo bloqueó un hook de seguridad local: sigue ahí, hay que borrarla a mano.
2026-09-14 — Lección 7: permisos que no restringen y una inyección que se ejecuta
Sección titulada «2026-09-14 — Lección 7: permisos que no restringen y una inyección que se ejecuta»gh run listdesde un job con solocontents: read(sinactions: read) funcionó: datos públicos de un repositorio público. Se sustituyó por la creación de una etiqueta con nombre vacío: 403Resource not accessible by integrationsinissues: write, 422Validation Failedcon él — no se creó nada en ningún caso.permissions: actions: reada nivel de job → el token perdióContents, yactions/checkoutfuncionó igualmente en este repositorio público.- El input de
workflow_dispatch$(whoami), pegado con${{ }}enrun:, imprimiórunner; a través deenv:, imprimió$(whoami). ::add-mask::oculta el valor solo en las líneas impresas después.- Token OIDC para la audiencia
learn-course: duración 300 s,sub=repo:spareilleux@6644695/learn@1368550922:ref:refs/heads/main, el formato inmutable de los repositorios creados después del 2026-07-15.
2026-09-14 — Lección 8: el despliegue de este sitio, desmontado
Sección titulada «2026-09-14 — Lección 8: el despliegue de este sitio, desmontado»- Una ejecución de despliegue:
build30 s (310 páginas construidas en 7,47 s, artefactogithub-pagesde 9 108 634 bytes conservado 1 día),deploy8 s. Estados del despliegue:waiting→queued→in_progress→successen 13 s. - La cola de concurrencia funcionó: un push 41 s después de otro esperó 14 s, y su job
buildse creó a las 13:32:18, el segundo en que terminó el jobdeployanterior. gh workflow run deploy.yml --ref gha-06-invalid: el build se ejecutó, el job de despliegue fue rechazado (Branch "gha-06-invalid" is not allowed to deploy to github-pages due to environment protection rules), el sitio publicado no cambió. Comprobado antes que no había ningún despliegue demainpendiente, ya que la ejecución de la rama comparte el grupo de concurrenciapages.https://spareilleux.github.io/method/→ 404: un enlace absoluto desde la raíz sale del sitio del proyecto.
2026-09-14 — Lección 9: timeouts que tardan más, y un fallo que cuenta como éxito
Sección titulada «2026-09-14 — Lección 9: timeouts que tardan más, y un fallo que cuenta como éxito»gh run view --log-failed: 15 líneas de 169; el job cancelado por su timeout no aparece.gh run rerun --debug: evaluaciones de condiciones##[debug],RUNNER_DEBUG=1, el jobnoisyde 70 a 190 líneas, y una carpetarunner-diagnostic-logs(logs de Runner y Worker) en el archivo.gh run rerun --failedvolvió a ejecutar los jobs fallidos y el cancelado, y conservó el que tuvo éxito en el intento 1.timeout-minutes: 1en un job: cancelado a los 87 s, tres veces, consleep 90osleep 300. En un step: fallido a los 72 s,The action 'Run date -u +%T' has timed out after 1 minutes.- Una ejecución cuyos jobs tuvieron éxito, fallaron con
continue-on-erroro fueron cancelados por un timeout termina encancelled. Con solo el fallo concontinue-on-error, termina ensuccess, yneeds.<job>.resultessuccess.
2026-09-14 — Lección 10: tres fallos antes de una acción que funciona
Sección titulada «2026-09-14 — Lección 10: tres fallos antes de una acción que funciona»require()en la acción JavaScript:require is not defined in ES module scope, en local, porque elpackage.jsondel repositorio (el del sitio Astro) dice"type": "module". Cambiado aimport; una copia CommonJS falló igual en el runner.- Acción de contenedor, primer push, incluida en el commit sin el bit de ejecución a propósito:
exec: "/entrypoint.sh": permission denied. Los archivos creados en Windows se incluyen en el commit como100644(core.filemodeesfalse); corregido congit update-index --chmod=+x. - Acción de contenedor en
windows-latest:Container action is only supported on Linux. - El runner no impone
required: true; un input desconocido es solo una advertencia (Unexpected input(s) 'txt', valid inputs are ['text', 'max-length']). - Duración de los steps: acción JavaScript en menos de 1 s en los tres sistemas operativos, acción de contenedor en 5 s (construcción de la imagen incluida).
Preguntas abiertas
Sección titulada «Preguntas abiertas»- ¿El disparador
scheduledegha-03(lunes 06:17 UTC) se ejecuta a su hora? Por verificar el 2026-09-21. - ¿Qué artefacto elige
download-artifactcuando dos comparten nombre, y es estable? Por verificar. - ¿Falla
actions/checkouten un repositorio privado cuando el token del job no tiene el permisocontents? Por verificar. - ¿Por qué un timeout de job de 1 minuto se aplica a los 87 s? Por verificar con límites más largos.
- ¿Qué muestra exactamente la página de un pull request para un check obligatorio omitido por
paths? Por verificar.