Guía9 min

Cache en GitHub Actions: key del lockfile, nunca secretos

Resumen

actions/cache guarda dependencias por key. La key debe incluir hash de pnpm-lock.yaml, no 'v1' eterno. No caches .env ni credenciales. restore-keys son fallbacks. Un agente que cachea todo el home ensucia hits. Docs actions/cache + GitHub caching dependencies.

GitHub
Una key de cache hecha con hash del lockfile, no un string fijo

Qué resuelve

Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.

CI lento no se arregla cacheando ~. actions/cache guarda un path con una key. Hit = key exacta. restore-keys son prefijos de fallback (parcial).

Para pnpm, la key incluye el OS y el hash del lockfile. Si el agente pone key: deps-v1, nunca se invalida y sirves node_modules de hace tres meses.

No sustituye un job bien escrito. El curso instalar un agente no cubre cache. gh pr no acelera install.

Receta pnpm

- uses: actions/cache@v4
  with:
    path: |
      ~/.local/share/pnpm/store
    key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
    restore-keys: |
      ${{ runner.os }}-pnpm-

setup-node con cache: pnpm hace esto por ti. Prefiere eso a un cache casero. No dupliques.

No caches:

  • .env, *.pem, tokens
  • node_modules y el store a la vez sin criterio (pnpm store basta)
  • El repo entero
  • Artefactos de build que ya subes como actions/upload-artifact

Key con hash del lockfile

Límites

GitHub documenta tamaño y eviction (LRU por repo). Un cache de 10 GB de “por si acaso” se evicta y no ayuda. Paths concretos.

save vacío: las versiones nuevas de cache no guardan si no hay files (fix documentado). No asumas hit.

Pin SHA o v4 reciente; el README depreca majors viejos cuando cambia el backend.

Receta AGENTS.md

Prefer setup-node cache: pnpm.
If actions/cache: key must include hashFiles of the lockfile.
Never cache secrets or the whole $HOME.
restore-keys only as prefix fallback.

Hit vs miss

FAQ

¿Matrix OS? runner.os en la key. No mezcles linux/windows.

¿Branches? El cache es por repo; las keys distintas no chocan. Un miss no es un error: el job sigue.

¿pnpm fetch? Compatible con store cache.

¿Secretos en path? Si un script escribe un token junto al store, cambia el path. El cache se comparte entre PRs del mismo repo (con matices de fork).

Un miss no debe fallar el job: restore es best-effort. fail-on-cache-miss solo si el ticket es “el cache es obligatorio” (casi nunca). El agente no pone fail-on-miss para “verse estricto”.

Verificado 2026-09-03 contra actions/cache README y GitHub caching dependencies.