Acerca de almacenar en caché las dependencias de flujo de trabajo
Las ejecuciones de flujo de trabajo a menudo reutilizan las mismas salidas o dependencias descargadas de una ejecución a otra. Por ejemplo, las herramientas de administración de paquetes y dependencias como Maven, Gradle, npm y Yarn mantienen una caché local de las dependencias descargadas.
Los trabajos en ejecutores hospedados en GitHub se inician en una imagen de ejecutor limpia y deben descargar dependencias cada vez, lo que provoca una mayor utilización de la red, un tiempo de ejecución más largo y un mayor costo. Para ayudar a acelerar el tiempo que se tarda en volver a crear archivos como dependencias, GitHub puede almacenar en caché los archivos que utilizas con frecuencia en los flujos de trabajo.
Para almacenar en caché las dependencias de un trabajo, puedes usar la acción cache
de GitHub. La acción crea y restaura una memoria caché que identifica una clave única. Como alternativa, si almacenas en caché los administradores de paquetes que se enumeran debajo, el uso de sus respectivas acciones setup-* requiere una configuración mínima, y creará y restaurará las cachés de dependencias automáticamente.
Administradores de paquetes | acción de setup-* para almacenar en caché |
---|---|
npm, Yarn, pnpm | setup-node |
pip, pipenv, Poetry | setup-python |
Gradle, Maven | setup-java |
RubyGems | setup-ruby |
Go go.sum | setup-go |
NuGet de .NET | setup-dotnet |
Warning
Ten en cuenta los siguientes aspectos al utilizar el almacenamiento en caché con GitHub Actions:
- Se recomienda no almacenar ninguna información confidencial en la memoria caché. Por ejemplo, la información confidencial puede incluir tokens de acceso o credenciales de inicio de sesión almacenados en un archivo en la ruta de la caché. Además, los programas de interfaz de línea de comandos (CLI), como
docker login
, pueden guardar las credenciales de acceso en un archivo de configuración. Cualquier usuario con acceso de lectura puede crear una solicitud de incorporación de cambios en un repositorio y acceder a los contenidos de una caché. Las bifurcaciones de un repositorio también pueden crear solicitudes de extracción en la rama base y acceder a las cachés en la rama base. - Al usar ejecutores autohospedados, las cachés de las ejecuciones de flujo de trabajo se almacenan en almacenamiento en la nube propiedad de GitHub. Una solución de almacenamiento propiedad del cliente solo está disponible con GitHub Enterprise Server.
Comparar artefactos y caché de dependencias
Los artefactos y el almacenamiento en caché son similares porque brindan la posibilidad de almacenar archivos en GitHub, pero cada característica ofrece diferentes casos de uso y no se puede usar indistintamente.
- Usa el almacenamiento en caché cuando quieras reutilizar archivos que no cambian a menudo entre trabajos o ejecuciones de flujo de trabajo, como las dependencias de compilación de un sistema de administración de paquetes.
- Usa artefactos cuando quieras guardar los archivos que genera un trabajo para verlos una vez que ha finalizado la ejecución de un flujo de trabajo (por ejemplo, archivos binarios compilados o registros de compilación).
Para más información sobre los artefactos de ejecución de flujos de trabajo, consulta "Almacenamiento y uso compartido de datos desde un flujo de trabajo".
Restricciones para acceder a una caché
Las restricciones de acceso proporcionan aislamiento y seguridad de caché al crear una frontera lógica entre las ramas o etiquetas diferentes.
Las ejecuciones de flujo de trabajo pueden restaurar las memorias caché creadas en la rama actual o en la rama predeterminada (normalmente main
). Si se desencadena una ejecución de flujo de trabajo para una solicitud de incorporación de cambios, también puede restaurar las memorias caché creadas en la rama base, incluidas las ramas base de repositorios bifurcados. Por ejemplo, si la rama feature-b
tiene la rama base feature-a
, una ejecución de flujo de trabajo desencadenada en una solicitud de incorporación de cambios tendría acceso a las memorias caché creadas en la rama predeterminada main
, la rama base feature-a
y la rama actual feature-b
.
Las ejecuciones de flujo de trabajo no pueden restaurar las memorias caché creadas para ramas secundarias o ramas del mismo nivel. Por ejemplo, una memoria caché creada para la rama secundaria feature-b
no sería accesible para una ejecución de flujo de trabajo desencadenada en la rama primaria main
. De forma similar, una memoria caché creada para la rama feature-a
con la rama main
base no sería accesible para su la rama feature-c
del mismo nivel con la rama base main
. Las ejecuciones de flujo de trabajo tampoco pueden restaurar las memorias caché creadas para nombres de etiqueta diferentes. Por ejemplo, una memoria caché creada para la etiqueta release-a
con la rama main
no sería accesible para un flujo de trabajo desencadenado para la etiqueta release-b
con la rama base main
.
Cuando se crea una memoria caché mediante una ejecución de flujo de trabajo desencadenada en una solicitud de incorporación de cambios, dicha memoria caché se crea para la referencia de combinación (refs/pull/.../merge
). Por este motivo, la memoria caché tendrá un ámbito limitado y solo se puede restaurar mediante nuevas ejecuciones de la solicitud de incorporación de cambios. No se puede restaurar mediante la rama base u otras solicitudes de incorporación de cambios destinadas a esa rama base.
Varias ejecuciones de flujo de trabajo en un repositorio pueden compartir memorias caché. Se puede acceder a una memoria caché creada para una rama en una ejecución de flujo de trabajo y restaurarla desde otra ejecución de flujo de trabajo para el mismo repositorio y rama.
Uso de la acción cache
La acción cache
intentará restaurar una caché en función del key
que proporciones. Cuando la acción encuentra una memoria caché que coincide exactamente con la clave, la acción restaura los archivos almacenados en caché al path
que configures.
Opcionalmente, puedes proporcionar una lista de restore-keys
para que se usen cuando key
no coincide con una memoria caché existente. Una lista de restore-keys
resulta útil cuando se restaura una memoria caché desde otra rama porque restore-keys
puede coincidir parcialmente con claves de caché. Para obtener más información sobre la coincidencia con restore-keys
, consulta "Coincidencia con una clave de caché".
Si hay una coincidencia exacta con el elemento key
proporcionado, se considera un acierto de caché. Si ninguna memoria caché coincide exactamente con el elemento key
proporcionado, se considera un error de caché. En un error de caché, la acción crea automáticamente una nueva memoria caché si el trabajo se completa correctamente. La nueva caché usará el elemento key
que proporcionaste y contiene los archivos que especificaste en path
. Para obtener más información sobre cómo se controla esto, consulta "Aciertos y errores de caché".
No se puede cambiar el contenido de una memoria caché existente. En su lugar, puedes crear una nueva memoria caché con una nueva clave.
Parámetros de entrada de la acción cache
-
key
: obligatorio La clave creada al guardar una memoria caché y la clave usada para buscar una caché. Puede ser cualquier combinación de variables, valores de contexto, cadenas estáticas y funciones. Las claves tienen una longitud máxima de 512 caracteres y las claves más largas que la longitud máxima provocarán un error en la acción. -
path
: obligatorio las rutas de acceso en el ejecutor para almacenar en caché o restaurar.-
Puedes especificar una única ruta de acceso o agregar varias rutas de acceso en líneas independientes. Por ejemplo:
- name: Cache Gradle packages uses: actions/cache@v3 with: path: | ~/.gradle/caches ~/.gradle/wrapper
-
Puedes especificar directorios o archivos únicos, y los patrones globales son compatibles.
-
Puedes especificar rutas de acceso absolutas o rutas de acceso relativas al directorio del área de trabajo.
-
-
restore-keys
: opcional una cadena que contiene claves de restauración alternativas, con cada clave de restauración colocada en una nueva línea. Si no se produce ningún acierto de caché parakey
, estas claves de restauración se usan secuencialmente en el orden proporcionado para buscar y restaurar una caché. Por ejemplo:restore-keys: | npm-feature-${{ hashFiles('package-lock.json') }} npm-feature- npm-
-
enableCrossOsArchive
: Opcional Valor booleano que, cuando se habilita, permite que los ejecutores de Windows guarden o restauren memorias caché independientes del sistema operativo en el que se creó la memoria caché. Si no se establece este parámetro, el valor predeterminado esfalse
. Para obtener más información, consulta la sección sobre caché entre sistemas operativos en la documentación de caché de Acciones.
Parámetros de salida de la acción cache
cache-hit
: valor booleano para indicar que se encontró una coincidencia exacta para la clave.
Aciertos y errores de caché
Cuando key
coincide exactamente con una memoria caché existente, se denomina un acierto de caché y la acción restaura los archivos almacenados en caché en el directorio path
.
Cuando key
no coincide con una caché existente, se denomina un error de caché y se crea automáticamente una caché si el trabajo se completa correctamente.
Cuando se produce un error de caché, la acción también busca los elementos restore-keys
especificados en busca de coincidencias:
- Si proporcionas
restore-keys
, la accióncache
busca secuencialmente las memorias caché que coincidan con la lista derestore-keys
.- Cuando hay una coincidencia exacta, la acción restaura los archivos en la memoria caché al directorio
path
. - Si no hay coincidencias exactas, la acción busca coincidencias parciales de las claves de restauración. Cuando la acción encuentra una coincidencia parcial, se restaura la caché más reciente al directorio
path
.
- Cuando hay una coincidencia exacta, la acción restaura los archivos en la memoria caché al directorio
- La acción
cache
se completa y se ejecuta el paso siguiente del flujo de trabajo. - Si el trabajo se completa correctamente, la acción crea automáticamente una caché con los contenidos del directorio
path
.
Para obtener una explicación más detallada del proceso de coincidencia de caché, consulta "Coincidencia de una clave de caché".
Ejemplo de uso de la acción cache
En este ejemplo se crea una nueva memoria caché cuando cambian los paquetes del archivo package-lock.json
o cuando cambia el sistema operativo del ejecutor. La clave de caché usa contextos y expresiones para generar una clave que incluye el sistema operativo del ejecutor y un hash SHA-256 del archivo package-lock.json
.
name: Caching with npm on: push jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Cache node modules id: cache-npm uses: actions/cache@v3 env: cache-name: cache-node-modules with: # npm cache files are stored in `~/.npm` on Linux/macOS path: ~/.npm key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }} name: List the state of node modules continue-on-error: true run: npm list - name: Install dependencies run: npm install - name: Build run: npm run build - name: Test run: npm test
name: Caching with npm
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Cache node modules
id: cache-npm
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
name: List the state of node modules
continue-on-error: true
run: npm list
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Test
run: npm test
Usar contextos para crear claves de caché
Una clave de caché puede incluir cualquiera de los contextos, funciones, literales y operadores admitidos por GitHub Actions. Para obtener más información, vea «Acceso a información contextual sobre ejecuciones de flujo de trabajo» y «Evaluación de expresiones en flujos de trabajo y acciones».
Usar expresiones para crear un elemento key
te permite crear automáticamente una caché cuando las dependencias cambian.
Por ejemplo, puedes crear una key
mediante una expresión que calcule el hash de un archivo package-lock.json
de npm. Por lo tanto, cuando cambian las dependencias que componen el cambio en el archivo package-lock.json
, la clave de caché cambia y se crea automáticamente una caché.
npm-${{ hashFiles('package-lock.json') }}
GitHub evalúa la expresión hash "package-lock.json"
para generar el key
final.
npm-d5ea0750
Uso de la salida de la acción cache
Puedes usar la salida de la acción cache
para hacer algo en función de si se ha producido un acierto o un error en la caché. Si se encuentra una coincidencia exacta para la caché en la key
especificada, la salida cache-hit
se establece en true
.
En el flujo de trabajo de ejemplo anterior, hay un paso que enumera el estado de los módulos de Node si se ha producido un error en la caché:
- if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
name: List the state of node modules
continue-on-error: true
run: npm list
Hacer coincidir una clave de caché
La acción cache
busca primero los aciertos de caché para key
y la versión de la memoria caché en la rama que contiene la ejecución del flujo de trabajo. Si no hay ningún acierto, busca restore-keys
y la versión. Si sigue sin haber aciertos en la rama actual, la acción cache
reintenta los mismos pasos en la rama predeterminada. Ten en cuenta que se aplican las restricciones de ámbito durante la búsqueda. Para obtener más información, consulta "Restricciones para acceder a una memoria caché".
La versión de la memoria caché es una forma de marcar con un sello una memoria caché con metadatos de path
y la herramienta de compresión que se usa al crear la memoria caché. Esto garantiza que la ejecución del flujo de trabajo de consumo coincida únicamente con una memoria caché que realmente puede descomprimir y usar. Para obtener más información, consulta Versión de caché en la documentación de caché de Acciones.
restore-keys
permite especificar una lista de claves de restauración alternativas que se usarán cuando se produce un error de caché en key
. Puedes crear múltiples claves de restauración ordenadas desde las más específicas hasta las menos específicas. La acción cache
busca restore-keys
en orden secuencial. Cuando una clave no coincide directamente, la acción busca las claves prefijadas con la clave de restauración. Si hay múltiples coincidencias parciales para una clave de restauración, la acción devuelve la caché que se creó más recientemente.
Ejemplo usando múltiples claves de restauración
restore-keys: |
npm-feature-${{ hashFiles('package-lock.json') }}
npm-feature-
npm-
El ejecutor evalúa las expresiones, que se resuelven en estos restore-keys
:
restore-keys: |
npm-feature-d5ea0750
npm-feature-
npm-
La clave de restauración npm-feature-
coincide con cualquier clave que comience por la cadena npm-feature-
. Por ejemplo, las claves npm-feature-fd3052de
y npm-feature-a9b253ff
coinciden con la clave de restauración. Se utilizará la caché con la fecha de creación más reciente. Las claves en este ejemplo se buscan en el siguiente orden:
npm-feature-d5ea0750
coincide con un hash específico.npm-feature-
coincide con las claves de caché con el prefijonpm-feature-
.npm-
coincide con cualquier clave con el prefijonpm-
.
Ejemplo de prioridad de búsqueda
key:
npm-feature-d5ea0750
restore-keys: |
npm-feature-
npm-
Por ejemplo, si una solicitud de incorporación de cambios contiene una rama feature
y tiene como destino la rama predeterminada (main
), la acción busca key
y restore-keys
en el orden siguiente:
- Clave
npm-feature-d5ea0750
en la ramafeature
- Clave
npm-feature-
en la ramafeature
- Clave
npm-
en la ramafeature
- Clave
npm-feature-d5ea0750
en la ramamain
- Clave
npm-feature-
en la ramamain
- Clave
npm-
en la ramamain
Límites de uso y política de desalojo
GitHub eliminará todas las entradas de caché a las que no se haya accedido en más de 7 días. No hay límite en la cantidad de cachés que puedes almacenar, pero el tamaño total de todas las cachés de un repositorio es limitado hasta 10 GB. Una vez que un repositorio haya alcanzado su almacenamiento máximo de caché, la directiva de expulsión de caché creará espacio mediante la eliminación de las cachés más antiguas del repositorio.
Si excedes el límite, GitHub guardará la nueva caché, pero comenzará a desalojar las cachés hasta que el tamaño total sea inferior al límite del repositorio. El proceso de expulsión de caché puede provocar la paginación excesiva de caché, donde las memorias caché se crean y eliminan con una alta frecuencia. Para reducir esto, puedes revisar las memorias caché de un repositorio y tomar medidas correctivas, como quitar el almacenamiento en caché de flujos de trabajo específicos. Para obtener más información, consulta "Administración de memorias caché".
Administración de cachés
Para administrar las memorias caché creadas a partir de los flujos de trabajo, puedes:
- Ver una lista de todas las entradas de caché de un repositorio.
- Filtrar y ordenar la lista de memorias cachés mediante metadatos específicos, como el tamaño de la memoria caché, la hora de creación o la hora a la que se accedió por última vez.
- Eliminar las entradas de caché de un repositorio.
- Supervisar el uso de caché agregada para repositorios y organizaciones.
Hay varias maneras de administrar memorias cachés para los repositorios:
-
Mediante la interfaz web de GitHub, como se muestra a continuación.
-
Mediante la API REST. Para obtener más información, vea «Puntos de conexión de API de REST para la caché de Acciones de GitHub».
-
Instalación del subcomando
gh cache
para administrar las memorias caché desde la línea de comandos. Para más información, consulte la documentación de la CLI de GitHub.Note
Si lo haces manualmente, asegúrate de tener instalada la versión 2.32.0 o posterior de la CLI.
Visualización de entradas de caché
Puedes usar la interfaz web para ver una lista de entradas de caché de un repositorio. En la lista de caché, puedes ver cuánto espacio en disco usa cada memoria caché, cuándo se creó la memoria caché y cuándo se usó por última vez la memoria caché.
-
En GitHub, navegue hasta la página principal del repositorio.
-
En el nombre del repositorio, haz clic en Acciones.
-
En la barra lateral izquierda, en la sección "Administración", haz clic en Cachés.
-
Revisa la lista de entradas de caché del repositorio.
- Para buscar entradas de caché usadas para una rama específica, haz clic en el menú desplegable Rama y selecciona una rama. La lista de memorias caché mostrará todas las memorias caché usadas para la rama seleccionada.
- Para buscar entradas de caché con una clave de caché específica, usa la sintaxis
key: key-name
en el campo Filtrar memorias cachés. La lista de memorias caché mostrará las memorias caché de todas las ramas en las que se usó la clave.
Eliminación de entradas de caché
Los usuarios con acceso write
a un repositorio pueden usar la interfaz web de GitHub para eliminar entradas de caché.
-
En GitHub, navegue hasta la página principal del repositorio.
-
En el nombre del repositorio, haz clic en Acciones.
-
En la barra lateral izquierda, en la sección "Administración", haz clic en Cachés.
-
A la derecha de la entrada de caché que quieres eliminar, haz clic en .
Eliminación forzosa de entradas de caché
Las cachés tienen restricciones de ámbito de rama vigentes, lo que significa que algunas cachés tienen opciones de uso limitadas. Para más información sobre las restricciones de ámbito de caché, consulta "Restricciones para acceder a una memoria caché" antes en este artículo. Si las cachés limitadas a una rama específica usan una gran cantidad de cuota de almacenamiento, es posible que las cachés de la rama default
se creen y eliminen con una frecuencia alta.
Por ejemplo, un repositorio podría tener muchas nuevas solicitudes de incorporación de cambios abiertas, cada una con cachés propias restringidas a esa rama. Estas cachés podrían ocupar la mayoría del almacenamiento en caché de ese repositorio. Una vez que un repositorio haya alcanzado su almacenamiento máximo de caché, la directiva de expulsión de caché creará espacio mediante la eliminación de las cachés más antiguas del repositorio. Para evitar la eliminación de cachés cuando esto sucede, puedes configurar flujos de trabajo de eliminación de cachés con una cadencia más rápida que la directiva de expulsión de caché. Puedes utilizar GitHub CLI para borrar cachés de ramas específicas.
En el siguiente flujo de trabajo de ejemplo se usa gh cache
para eliminar hasta 100 cachés creadas por una rama una vez que se cierra una solicitud de incorporación de cambios.
Para ejecutar el ejemplo siguiente en solicitudes de incorporación de cambios entre repositorios o solicitudes de incorporación de cambios de bifurcaciones, puedes desencadenar el flujo de trabajo con el evento pull_request_target
. Si usas pull_request_target
para desencadenar el flujo de trabajo, hay consideraciones de seguridad que debes tener en cuenta. Para obtener más información, vea «Eventos que desencadenan flujos de trabajo».
name: cleanup caches by a branch
on:
pull_request:
types:
- closed
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Cleanup
run: |
echo "Fetching list of cache key"
cacheKeysForPR=$(gh cache list --ref $BRANCH --limit 100 --json id --jq '.[].id')
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "Deleting caches..."
for cacheKey in $cacheKeysForPR
do
gh cache delete $cacheKey
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
Como alternativa, puedes usar la API para listar o eliminar automáticamente todas las cachés en tu propia cadencia. Para obtener más información, vea «Puntos de conexión de API de REST para la caché de Acciones de GitHub».