Aller au contenu
CI/CD & Automatisation medium

Cache Python/pip dans GitHub Actions

9 min de lecture

Les projets Python peuvent avoir des temps d'installation de dépendances significatifs, surtout avec des packages comme numpy, pandas ou tensorflow qui nécessitent une compilation. Le cache permet de réduire ce temps de plusieurs minutes à quelques secondes.

  • Activer le cache pip intégré à setup-python
  • Cacher Poetry et Pipenv selon votre gestionnaire de dépendances
  • Configurer actions/cache pour un contrôle fin des chemins
  • Cacher un environnement virtuel complet pour sauter l'installation
  • Éviter les pièges : cache invalide après mise à jour Python, double cache

La méthode la plus simple utilise le cache intégré de actions/setup-python :

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.11'
cache: 'pip' # Active le cache pip
- run: pip install -r requirements.txt

Si vous gérez vos dépendances avec Poetry, indiquez-le à setup-python : le cache portera alors sur le poetry.lock.

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.11'
cache: 'poetry'
- run: |
pip install poetry
poetry install

Même principe pour Pipenv : le cache suit alors le Pipfile.lock.

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.11'
cache: 'pipenv'
- run: |
pip install pipenv
pipenv install --dev

Pour plus de contrôle, utilisez actions/cache directement :

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.11'
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ~/.cache/pip
key: pip-${{ runner.os }}-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
pip-${{ runner.os }}-
- run: pip install -r requirements.txt

Si vous configurez actions/cache à la main, le path: dépend du gestionnaire et du système. Ce tableau donne les emplacements à cacher.

GestionnaireChemin LinuxChemin macOSChemin Windows
pip~/.cache/pip~/Library/Caches/pip~\AppData\Local\pip\Cache
Poetry~/.cache/pypoetry~/Library/Caches/pypoetry%APPDATA%\pypoetry\Cache
Pipenv~/.cache/pipenv~/Library/Caches/pipenv%USERPROFILE%\.pipenv

Pour des gains maximum, cachez l'environnement virtuel complet :

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.11'
- name: Cache virtualenv
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: cache-venv
with:
path: .venv
key: venv-${{ runner.os }}-${{ hashFiles('**/requirements*.txt') }}
- name: Create venv and install deps
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
- name: Run tests
run: |
source .venv/bin/activate
pytest

Gain : l'installation est complètement sautée si le cache existe.

name: Python CI
on: [push, pull_request]
# Aucun droit par défaut : le job demande le minimum
permissions: {}
jobs:
test:
runs-on: ubuntu-24.04
permissions:
contents: read
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: |
requirements.txt
requirements-dev.txt
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run linters
run: |
ruff check .
mypy .
- name: Run tests
run: pytest --cov=src --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
files: ./coverage.xml
name: Python CI with Poetry
on: [push, pull_request]
permissions: {}
jobs:
test:
runs-on: ubuntu-24.04
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Setup Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.11'
- name: Install Poetry
uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1
with:
version: '1.8.2'
virtualenvs-create: true
virtualenvs-in-project: true
- name: Cache Poetry virtualenv
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: .venv
key: poetry-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
restore-keys: |
poetry-${{ runner.os }}-
- name: Install dependencies
run: poetry install --no-interaction
- name: Run tests
run: poetry run pytest

Pour numpy, scipy, pandas qui ont des dépendances compilées :

- name: Cache pip wheels
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
~/.cache/pip
~/.local/lib/python*/site-packages
key: pip-wheels-${{ runner.os }}-${{ hashFiles('**/requirements*.txt') }}

Les environnements pre-commit sont longs à reconstruire. Les cacher rend le hook quasi instantané dès la deuxième exécution.

- name: Cache pre-commit
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}
- run: pre-commit run --all-files

Un cache pip dépend de la version de Python. Si la clé ne l'inclut pas, une montée de version restaure des paquets compilés pour l'ancienne — et tout casse.

# ❌ La clé ne change pas si Python change
key: pip-${{ hashFiles('requirements.txt') }}
# ✅ Inclure la version Python
key: pip-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }}

Empiler le cache: de setup-python et un actions/cache sur le même chemin produit deux gestionnaires qui se marchent dessus. Gardez-en un seul.

# ❌ Double cache, comportement imprévisible
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
cache: 'pip'
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ~/.cache/pip
# ✅ Utiliser l'un ou l'autre
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
cache: 'pip'
  • Le cache intégré de setup-python (cache: 'pip') suffit pour la plupart des projets — une ligne.
  • Pour Poetry ou Pipenv, indiquez le bon gestionnaire : cache: 'poetry', cache: 'pipenv'.
  • actions/cache donne le contrôle des chemins : utile pour les wheels compilées ou les hooks pre-commit.
  • Cacher le virtualenv complet saute carrément l'installation — le gain maximal.
  • Incluez la version Python dans la clé de cache, sinon une mise à jour de Python restaure un cache incompatible.
  • N'empilez jamais cache: de setup-python et un actions/cache sur le même chemin : choisissez l'un.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn