uvx en GitHub Actions amigable con cache
Simon Willison publicó una receta para usar uvx (el tool runner de uv) en GitHub Actions sin que cada workflow descargue todo de PyPI cada vez. El truco está en dos piezas: estableces una variable de entorno UV_EXCLUDE_NEWER con una fecha fija al inicio del workflow, y usas esa fecha como parte de la clave de caché. Cada uvx tool-name se resolverá a la versión más reciente hasta esa fecha, y la caché sobrevivirá entre ejecuciones. Para actualizar las herramientas, adelantas la fecha.
Esto importa si automatizas workflows Python con GitHub Actions: en lugar de esperar cada vez a que el runner descargue las dependencias, reutilizas lo que ya tiene en caché. El resultado son builds más rápidos y menos tráfico hacia PyPI. El patrón es pequeño pero inmediatamente aplicable: dos líneas de config y sabes que tus workflows no reinician desde cero cada vez.
Si quieres probarlo. Añade UV_EXCLUDE_NEWER: "2026-07-12" (o la fecha que prefieras) al inicio de tu workflow y usa esa variable en la clave de la acción de caché. La receta completa está documentada con ejemplo.
En detalle
El problema
Cuando usas uvx tool-name en un workflow de GitHub Actions, por defecto cada ejecución contacta con PyPI para descargar la herramienta y sus dependencias. Esto añade latencia a cada build y desperdicia ancho de banda: si la herramienta no cambió, estás rehaciendo trabajo innecesario.
La caché de GitHub Actions existe precisamente para esto, pero hacía falta una forma de hacer que uvx respetara esa caché en lugar de descargar siempre todo de nuevo. El problema es que uvx por defecto intenta resolverse a la versión más reciente disponible, y eso significa que la clave de caché cambia cada vez que hay un nuevo release de la herramienta, aunque para ti ese release no importe.
La solución de Willison
La receta se basa en UV_EXCLUDE_NEWER, una variable de entorno de uv que dice: «ignora todo lo que se publicó después de esta fecha». Si estableces UV_EXCLUDE_NEWER: "2026-07-12" al inicio del workflow, cada llamada a uvx se resolverá a la versión más reciente publicada hasta el 12 de julio de 2026, y esa versión permanecerá estable mientras no cambies la fecha.
Usas esa fecha también en la clave de la acción de caché (actions/cache@v4), así GitHub sabe que la caché es válida mientras la fecha no cambie. Cuando quieres actualizar las herramientas, adelantas la fecha y la caché se invalida automáticamente.
La ventaja es que tienes control explícito sobre cuándo actualizar, en lugar de sufrir cada nuevo release de la herramienta sin previo aviso. Es una forma de fijación suave: no bloqueas una versión específica, pero bloqueas una ventana temporal, y eso es suficiente para mantener la caché coherente.
Por qué importa
Si tienes workflows que se ejecutan frecuentemente (CI en cada commit, deploys automáticos, jobs programados), el tiempo ahorrado en cada ejecución se acumula. Más importante aún: eliminas una fuente de inestabilidad. Un workflow que hoy pasa y mañana falla porque una nueva versión de una herramienta rompió algo es un problema que esta receta previene, porque la fecha te da un punto de control explícito.
Hay también un issue abierto contra astral-sh/setup-uv pidiendo cambiar el default a favor de la caché en lugar del purge de wheels. Si esa propuesta se aprueba, parte de este trabajo podría volverse automático. Mientras tanto, la receta de Willison funciona hoy.