Configurer l'exécuteur
- Leçon 4
- 45 min
- Module 2 : Créer un pipeline CI reproductible
Leçon 4 sur 15 · CI/CD, tests et mises en production sûresConfigurer l'exécuteur
1. Comprendre le chemin de livraison
2. Créer un pipeline CI reproductible
3. Gérer les environnements et les secrets
4. Mettre en production les changements d'IA et de base de données
5. Rétablir et maintenir le processus de mise en production
Ce que vous saurez faire
Une vérification qui s’exécute seulement sur votre ordinateur dépend de cet ordinateur. Donnez aux vérifications une machine propre au début de chaque tâche. Ainsi, un résultat a le même sens pour toute l’équipe.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Déclencheur, flux de travail, tâche, étape, exécuteur et artefact, dans Du commit à la mise en production : le vocabulaire, sur le vrai pipeline.
- Quelle vérification détecte quelle erreur, et pourquoi l’analyse statique passe en premier, dans Définir les vérifications : quelle vérification détecte quelle erreur et Les vérifications rapides en premier.
- Les commits (enregistrements de modifications), les branches et
git push, dans Les étapes d’une demande de tirage : ce qu’est une demande de tirage du cours L’essentiel de Git et du développement en équipe. - Les versions exactes dans
requirements-lock.txt, dans Environnement et premier point de terminaison : étape 1 : créer le projet du cours Créer et déployer votre première API. - Le cache des couches d’une construction Docker, dans Construire efficacement : le cache des couches du cours L’essentiel de Docker et du nuage pour les développeurs en IA.
Ce qu’il vous faut sur votre ordinateur
- Le dossier de projet
~/projects/ticket-api-ci(Windows :$HOME\projects\ticket-api-ci) contenant l’API de billets 1.1.0 du cours Docker et le commit dedocs/release-process.md, provenant de Définir les vérifications : Exercice du module. C’est un dépôt Git sur la branchemain, sans dépôt distant pour le moment. - Son environnement virtuel
.venv, créé à partir derequirements-lock.txt, comme dans Environnement et premier point de terminaison : étape 1 : créer le projet du cours sur les API. Le clone du module 1 n’a pas de.venv: créez-le dans~/projects/ticket-api-ci. - Un compte GitHub gratuit. Vous créez un dépôt public dans cette leçon. Les dépôts publics exécutent gratuitement GitHub Actions sur les exécuteurs standard de GitHub.
- Git. L’interface en ligne de commande GitHub
ghest facultative : chaque étape GitHub est aussi décrite pour les pages Web. - Si votre projet manque ou ne fonctionne plus, copiez l’instantané
end-of-m01, comme dans Utiliser un instantané.
Exécuté avec GitHub Actions (exécuteurs ubuntu-24.04) dans le dépôt public Nextia-Intelligence/ticket-api-ci, et ruff 0.16.10 avec Python 3.14 sur macOS (Apple silicon). Les étapes Windows et Linux ne sont pas testées.
Où une tâche s’exécute : l’exécuteur
Section intitulée « Où une tâche s’exécute : l’exécuteur »Les vérifications d’Amira fonctionnent sur son Mac. Sam pose une question pertinente : « Est-ce qu’elles fonctionnent aussi sur un ordinateur qui n’est pas le tien? » Son Mac contient des paquets d’anciennes expériences, un cache de la semaine dernière et des réglages que personne n’a notés. Une vérification qui réussit sur ce Mac prouve seulement qu’elle y réussit.
Un exécuteur est la machine qui exécute les tâches d’un flux de travail. GitHub en propose deux types :
| Exécuteur hébergé par GitHub | Exécuteur autohébergé | |
|---|---|---|
| Qui possède la machine | GitHub | Vous : un serveur, une machine virtuelle ou un ordinateur dans votre bureau |
| État au début d’une tâche | Une nouvelle machine virtuelle (VM) | Ce que la dernière tâche y a laissé |
| Coût pour un dépôt public | Gratuit sur les exécuteurs standard | Votre propre matériel et son entretien |
| À utiliser pour | La plupart des pipelines, et tout ce cours | Du matériel spécialisé (un GPU), ou l’accès à un réseau privé |
Le cours utilise seulement des exécuteurs hébergés par GitHub. Une ligne du flux de travail choisit l’exécuteur : runs-on: ubuntu-24.04.
Une machine propre pour chaque tâche
Section intitulée « Une machine propre pour chaque tâche »« À l’exception des exécuteurs à un seul processeur, chaque exécuteur hébergé par GitHub est une nouvelle machine virtuelle (VM) hébergée par GitHub » (Documentation GitHub). Le journal de la tâche indique quelle machine elle a reçue. Voici le début de la première tâche de l’exécution 37663364319 dans le dépôt de référence :
Current runner version: '2.337.0'Azure Region: southcentralusOperating SystemUbuntu24.04.5LTSRunner ImageImage: ubuntu-24.04Version: 20260927.320.1GITHUB_TOKEN PermissionsContents: readMetadata: readLa deuxième tâche de cette exécution a démarré environ 6 secondes après la fin de la première. Elle s’est exécutée sur une autre VM, dans centralus. Rien de la première VM ne s’y trouvait. Elle a récupéré le code à nouveau.
C’est l’intérêt d’un exécuteur propre. Chaque tâche démarre à partir de la même image connue (ici ubuntu-24.04, version 20260927.320.1). Elle reçoit seulement ce que le flux de travail installe. Si une vérification nécessite un paquet absent du fichier de verrouillage, la tâche échoue, à chaque exécution, pour tout le monde. Une étape de configuration manquante ne peut pas passer inaperçue sur un exécuteur.
Description textuelle du diagramme
La tâche 1 exécute les vérifications sur une nouvelle VM. La tâche 2 construit l’image sur une autre nouvelle VM et doit récupérer le code à nouveau. Rien de la tâche 1 ne s’y trouve. La flèche entre elles transmet seulement le résultat : la tâche 2 démarre uniquement si la tâche 1 a réussi. Deux éléments hors des VM restent après une tâche. Un cache conserve des fichiers qui accélèrent la prochaine exécution, comme les paquets téléchargés. Un artefact conserve un résultat pour les personnes et les tâches suivantes, comme le rapport de tests. La leçon 3 de ce module porte sur les artefacts.
Un cache qui ne peut pas changer le résultat
Section intitulée « Un cache qui ne peut pas changer le résultat »Une VM propre a un coût : chaque tâche télécharge tout à nouveau. Un cache est un ensemble de fichiers qu’une tâche sauvegarde et qu’une tâche ultérieure restaure pour éviter de les télécharger à nouveau. Le flux de travail demande à actions/setup-python de mettre en cache les téléchargements de pip :
- uses: actions/setup-python@v7 with: python-version: "3.14.8" cache: pip cache-dependency-path: requirements-lock.txtLe cache possède une clé : un nom formé à partir du système d’exploitation de l’exécuteur, de la version de Python et d’une empreinte de requirements-lock.txt. Une tâche restaure un cache seulement si la clé correspond. Les vrais journaux montrent les trois cas.
La première exécution réussie n’a trouvé aucun cache, a effectué l’installation en 15 secondes et en a sauvegardé un à la fin de la tâche :
pip cache is not found...Sent 44025642 of 44025642 (100.0%), 42.1 MBs/secCache saved with the key: setup-python-Linux-x64-24.04-Ubuntu-python-3.14.8-pip-ec6bc0c05328f7a2f23375d7193327a08c67ec754519aba7be011c58d10a258dL’exécution suivante (37664331105, la première demande de tirage) avait le même fichier de verrouillage. La clé correspondait donc :
Cache restored successfullyCache restored from key: setup-python-Linux-x64-24.04-Ubuntu-python-3.14.8-pip-ec6bc0c05328f7a2f23...L’installation a pris 12,3 secondes au lieu de 15,0 secondes. Le gain est faible, car pip installe quand même chaque paquet. Il évite seulement les téléchargements. Le troisième cas est moins évident : la toute première exécution a échoué et n’a sauvegardé aucun cache. Le cache est sauvegardé dans une étape « post » à la fin de la tâche. Cette étape ne s’est pas exécutée après l’échec.
Voici la règle. Un cache peut accélérer une tâche. Il ne doit jamais changer ce que la tâche vérifie ou construit. Ce cache respecte la règle pour trois raisons :
- La clé provient du fichier de verrouillage. Si une version dans
requirements-lock.txtchange, l’empreinte change. L’ancien cache ne correspond plus, et la tâche télécharge à nouveau. - pip installe exactement les versions du fichier de verrouillage. Le cache lui fournit seulement les mêmes fichiers plus rapidement.
- L’absence de cache ralentit seulement la tâche. Le résultat reste le même.
Un mauvais cache enfreint la règle. Par exemple, un cache du dossier .venv entier avec une clé fixe, comme venv, restaurerait d’anciens paquets après une modification du fichier de verrouillage. Les vérifications testeraient alors des paquets que l’image ne contient pas. La leçon 2 utilise la même idée pour la construction Docker, avec le cache des couches de BuildKit (type=gha). Comme dans le cours Docker, un fichier modifié déclenche à nouveau son étape.
GitHub supprime un cache que personne n’a utilisé pendant 7 jours. Un dépôt peut conserver 10 Go de caches par défaut. Une tâche peut restaurer les caches de sa propre branche et de la branche par défaut, main. (Source : Documentation GitHub : mise en cache des dépendances.)
Fixer aussi les versions des actions
Section intitulée « Fixer aussi les versions des actions »Le flux de travail utilise les actions par version majeure : actions/checkout@v7. Le propriétaire de l’action peut déplacer v7 vers une version v7.x plus récente contenant des correctifs. Le journal montre le commit exact que v7 désignait ce jour-là :
Download action repository 'actions/checkout@v7' (SHA:3d3c42e5aac5ba805825da76410c181273ba90b1)Download action repository 'actions/setup-python@v7' (SHA:5fda3b95a4ea91299a34e894583c3862153e4b97)La référence la plus stricte est ce SHA de commit complet : uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1. GitHub précise que c’est « actuellement la seule façon d’utiliser une action comme une version immuable » (Documentation GitHub : utilisation sécurisée). Le compromis est le même qu’avec l’empreinte d’une image dans le cours Docker : rien ne change sans votre intervention. Cela inclut les correctifs de sécurité. Ce cours fixe la version majeure, car toutes les actions utilisées ici proviennent de GitHub ou de Docker. Pour une action provenant d’une personne ou d’un petit projet, fixez le SHA et lisez le code de cette version.
Exemple détaillé : le premier flux de travail
Section intitulée « Exemple détaillé : le premier flux de travail »Amira crée le dépôt, envoie le projet et ajoute le premier flux de travail. Elle s’attend à une réussite : les cours sur les API et sur Docker avaient 25 tests réussis.
1. Créer le dépôt sur GitHub
Section intitulée « 1. Créer le dépôt sur GitHub »Sur github.com, Amira sélectionne + (en haut à droite) → New repository (nouveau dépôt). Elle entre le nom ticket-api-ci, choisit Public (public) et laisse les options README, .gitignore et licence vides. Le projet possède déjà ses fichiers. Elle sélectionne Create repository (créer le dépôt).
2. Vérifier ce que Git enverra, puis envoyer
Section intitulée « 2. Vérifier ce que Git enverra, puis envoyer »cat .gitignoregit statusgit remote add origin https://github.com/<you>/ticket-api-ci.gitgit push -u origin mainRemplacez <you> par votre nom d’utilisateur GitHub. Si Git affiche remote origin already exists (le dépôt distant origin existe déjà), le dossier pointe encore vers celui du cours Docker. Exécutez git remote remove origin, comme dans Définir les vérifications : Exercice du module, puis ajoutez à nouveau le dépôt distant. git push envoie tous les commits de main, y compris celui contenant docs/release-process.md. Si Git demande un mot de passe, votre mot de passe GitHub ne fonctionne pas. Connectez-vous d’abord avec gh auth login, ou utilisez une autre méthode de la documentation GitHub.
3. Ajouter les outils et les réglages d’analyse statique
Section intitulée « 3. Ajouter les outils et les réglages d’analyse statique »Deux nouveaux outils vont dans requirements.txt, dans la section pour travailler sur l’API : ruff, un analyseur statique rapide pour Python, et pip-audit, utilisé dans Construire et tester.
# Needed to work on the APIpytest==9.1.1httpx2==2.13.1ruff==0.16.10pip-audit==2.10.1Installez-les et réécrivez le fichier de verrouillage, comme dans le cours sur les API. Dans le dépôt de référence, cela a ajouté 18 lignes, comme ruff==0.16.10, pip_audit==2.10.1 et leurs dépendances.
python -m pip install -r requirements.txtpython -m pip freeze > requirements-lock.txtIndiquez ensuite à ruff ce qu’il doit vérifier, dans pyproject.toml :
[tool.ruff]line-length = 100target-version = "py312"
[tool.ruff.lint]select = ["E", "F", "I", "B"]E et F correspondent aux erreurs de base : erreurs de style et véritables erreurs, comme une importation inutilisée. I vérifie l’ordre des importations. B détecte les bogues probables. Le cours n’utilise pas ruff format. Cet outil modifierait le code du cours sur les API uniquement pour le style. L’historique de chaque modification serait alors plus difficile à lire.
4. Le fichier du flux de travail
Section intitulée « 4. Le fichier du flux de travail »GitHub exécute chaque fichier YAML du dossier .github/workflows/. Amira crée .github/workflows/ci.yml. Le dépôt de référence a ajouté le pipeline entier dans un seul commit. Cette leçon commence avec la première tâche et une seule vérification. Les deux leçons suivantes ajoutent le reste :
# Continuous integration: check every change, then build one image per commit.# Pull requests: checks and a test build (nothing is pushed).# main, hotfix/* and version tags: checks, then build, smoke-test and push the# image to GitHub Container Registry, with build evidence.name: CI
on: pull_request: push: branches: [main, "hotfix/**"] tags: ["v*"]
permissions: contents: read
concurrency: group: ci-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs: checks: name: Lint, test, audit runs-on: ubuntu-24.04 timeout-minutes: 15 steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 with: python-version: "3.14.8" cache: pip cache-dependency-path: requirements-lock.txt - name: Install the exact versions run: python -m pip install -r requirements-lock.txt - name: Lint run: ruff check .Chaque partie a sa raison d’être :
on:énumère les déclencheurs. Chaque demande de tirage exécute les vérifications. Un envoi les exécute surmain, sur une branche de correctif urgent et sur une étiquette de version. Le module 3 retire le déclencheur d’étiquette quand le flux de mise en production prend le relais.permissions: contents: readlimiteGITHUB_TOKEN, la clé fournie par GitHub à chaque exécution, à la lecture du code. Une tâche qui a besoin de plus de droits les demande. Les lignesGITHUB_TOKEN Permissions(autorisations de GITHUB_TOKEN) du journal montrent le résultat.concurrencyregroupe les exécutions d’une même branche. Un nouvel envoi à une demande de tirage annule son exécution précédente. Surmain,cancel-in-progressvautfalse. Chaque commit demainobtient donc une exécution complète.name: Lint, test, auditest le nom de la tâche sur GitHub. La leçon 3 fait de ce nom une vérification obligatoire. Choisissez-le donc avec soin.timeout-minutes: 15arrête une tâche qui reste bloquée. Le délai par défaut est beaucoup plus long.- Les étapes : récupérer le code, obtenir Python 3.14.8 avec le cache pip, installer les versions exactes, effectuer l’analyse statique.
Dans les expressions, ${{ github.ref }} est la branche ou l’étiquette de l’exécution. ${{ github.event_name }} est le déclencheur, comme push.
5. Créer un commit, envoyer et prédire
Section intitulée « 5. Créer un commit, envoyer et prédire »git add requirements.txt requirements-lock.txt pyproject.toml .github/workflows/ci.ymlgit commit -m "Add the CI pipeline: the first job, with lint"git pushFaites une prédiction : les cours sur les API et sur Docker ont testé ce code. La tâche réussit-elle?
Sur GitHub, ouvrez l’onglet Actions (actions) du dépôt. L’exécution apparaît en quelques secondes. Dans le dépôt de référence, la première exécution 37663263329 a échoué après 25 secondes :

La page indique que la tâche a échoué, mais pas pourquoi. Pour lire le journal, connectez-vous, ouvrez la tâche, puis ouvrez l’étape rouge Lint (analyse statique). Ou utilisez l’interface en ligne de commande GitHub :
gh run view --log-failedLa sortie (abrégée; exécution de référence) :
B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling --> ticket_api/config.py:28:13 |27 | except OSError as error:28 | raise SettingsError(f"{name}_FILE: cannot read {path}: {error.strerror}") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^29 | return os.environ.get(name) or None |
I001 [*] Import block is un-sorted or un-formatted --> ticket_api/routes.py:1:1...Found 2 errors.[*] 1 fixable with the `--fix` option.##[error]Process completed with exit code 1.Le code fonctionne et ses tests réussissent. Mais l’analyseur statique a trouvé deux problèmes qu’aucun test ne cherchait. Les tests ont vérifié ce que le code fait. L’analyseur statique a vérifié comment il est écrit.
6. Reproduire l’échec sur votre ordinateur
Section intitulée « 6. Reproduire l’échec sur votre ordinateur »Un échec en CI est plus facile à corriger quand vous pouvez le voir sur votre propre ordinateur. Le fichier de verrouillage a fourni ruff 0.16.10 à l’exécuteur. Il vous a fourni la même version :
ruff --versionruff check .La sortie : ruff 0.16.10, puis les deux mêmes erreurs, ligne pour ligne, et Found 2 errors. (2 erreurs trouvées). Le code de sortie est 1, comme sur l’exécuteur. Même outil, même version, mêmes réglages, même résultat. Voilà pourquoi la tâche installe les paquets à partir du fichier de verrouillage.
7. Corriger les deux problèmes détectés
Section intitulée « 7. Corriger les deux problèmes détectés »I001 peut être corrigé automatiquement. ruff check --fix . trie les importations de ticket_api/routes.py :
import asynciofrom typing import Annotated, get_args
import loggingfrom typing import Annotated, get_argsB904 exige une décision, donc ruff ne le corrige pas. Dans un bloc except, une nouvelle erreur entraîne l’ancienne avec elle, et le journal affiche les deux. Ici, SettingsError indique déjà le problème en une ligne claire. L’ancien OSError ajoute donc seulement de l’information inutile. from None indique que ce choix est volontaire :
except OSError as error: raise SettingsError(f"{name}_FILE: cannot read {path}: {error.strerror}") raise SettingsError(f"{name}_FILE: cannot read {path}: {error.strerror}") from NoneVérifiez à nouveau, puis créez un commit et envoyez-le :
ruff check .python -m pytest -qgit commit -am "Fix the two lint findings: raise ... from None, and sort the imports"git pushLa sortie des deux premières commandes :
All checks passed!......................... [100%]25 passed in 0.25sLa nouvelle exécution réussit. L’étape Lint de l’exécution 37663364319 du dépôt de référence a affiché All checks passed! (toutes les vérifications ont réussi; même message). Son commit est c862935 : deux lignes modifiées.
Exercice guidé : votre exécuteur et votre première exécution réussie
Section intitulée « Exercice guidé : votre exécuteur et votre première exécution réussie »- Créez le dépôt public
ticket-api-cisur GitHub, sans README. - Vérifiez
.gitignoreetgit status, puis poussezmain. - Ajoutez
ruff==0.16.10etpip-audit==2.10.1, installez-les, puis régénérez le fichier de verrouillage. - Ajoutez les paramètres
[tool.ruff]àpyproject.toml. - Créez
.github/workflows/ci.ymlavec la première tâche, puis faites un commit (enregistrement des changements) et poussez-le. - Ouvrez l’exécution dans l’onglet Actions (actions). Notez la version de l’image de l’exécuteur et la région Azure dans Set up job (préparer la tâche).
- Lisez le journal de l’étape qui a échoué. Ensuite, exécutez
ruff check .sur votre ordinateur et comparez. - Corrigez les deux problèmes détectés, exécutez
ruff check .et les tests, puis faites un commit et poussez-le. - Ouvrez la nouvelle exécution. Dans l’étape de
actions/setup-python, trouvez la ligne du cache. Dans l’étape finale après la tâche, trouvezCache saved with the key(cache enregistré avec la clé).
Afficher le résultat attendu
La première exécution est rouge. L’étape Lint (analyse statique) affiche B904 dans ticket_api/config.py:28:13 et I001 dans ticket_api/routes.py:1:1, puis Found 2 errors. (2 erreurs trouvées). Votre ordinateur affiche les deux mêmes erreurs. Set up job indique Image: ubuntu-24.04 (image : ubuntu-24.04) et une version (20260927.320.1 le jour du test; la vôtre peut être plus récente). Il indique aussi une région Azure qui peut changer d’une exécution à l’autre. La deuxième exécution est verte, avec All checks passed! (toutes les vérifications ont réussi) dans Lint. Son étape Python indique pip cache is not found (cache pip introuvable), car l’exécution échouée n’a enregistré aucun cache. Ses dernières étapes enregistrent un cache d’environ 44 Mo. Une troisième exécution avec le même fichier de verrouillage indiquerait Cache restored successfully (cache restauré avec succès).
À vous de jouer : prévoir les résultats de l’analyseur statique
Section intitulée « À vous de jouer : prévoir les résultats de l’analyseur statique »Faites ceci uniquement sur votre ordinateur. Ne poussez pas ces changements. Ajoutez une ligne au début de ticket_api/main.py : import os. Le module n’utilise jamais os. Faites une prédiction : combien de problèmes ruff check . signale-t-il, et avec quels codes de règle? Est-ce que --fix peut les corriger? Ensuite, exécutez la commande, puis retirez la ligne avec ruff check --fix ..
Afficher la réponse
Deux problèmes, pas un seul. La sortie (abrégée) :
I001 [*] Import block is un-sorted or un-formatted --> ticket_api/main.py:1:1...F401 [*] `os` imported but unused --> ticket_api/main.py:1:8...Found 2 errors.[*] 2 fixable with the `--fix` option.F401 désigne l’importation inutilisée. I001 désigne l’ordre : os doit venir après logging. Les deux portent [*], donc ruff check --fix . corrige les deux en retirant la ligne. L’ordinateur de test a affiché Found 1 error (1 fixed, 0 remaining). (1 erreur trouvée, 1 corrigée, 0 restante). Le retrait a aussi corrigé l’ordre. Un exécuteur signalerait les deux mêmes problèmes, avec les mêmes versions. Voilà pourquoi il faut exécuter ruff check . avant chaque poussée : la réponse de l’exécuteur n’est jamais une surprise.
Erreur courante
Le fichier de flux de travail ne démarre pas
Symptôme : vous poussez un flux de travail, et aucune tâche ne démarre. L’onglet Actions affiche plutôt une erreur pour le fichier de flux de travail. Cela arrive lorsque GitHub ne peut pas lire le YAML. (Cette erreur a été faite volontairement sur l’ordinateur de test, pas dans le dépôt de référence.)
Cause : une ligne a une mauvaise indentation. En YAML, les espaces au début d’une ligne déterminent à quel élément elle appartient. Ici, with: a été déplacé de deux espaces vers la gauche, hors de son étape :
- uses: actions/setup-python@v7 with: python-version: "3.14.8"Diagnostic : vérifiez le fichier sur votre ordinateur avec actionlint, un outil de vérification des fichiers de flux de travail. Il s’exécute dans un conteneur, donc il n’y a rien à installer :
docker run --rm -v "$PWD":/repo -w /repo rhysd/actionlint:latest .github/workflows/*.ymlLa sortie :
.github/workflows/ci.yml:25:6: could not parse as YAML: did not find expected '-' indicator [syntax-check] |25 | steps: | ^~~~~Le numéro de ligne pointe vers la liste qui ne fonctionne plus (steps:), pas vers la ligne incorrecte. Lisez les lignes en dessous.
Correction : replacez with: sous uses:, deux espaces à droite du -. Exécutez actionlint à nouveau : aucune sortie signifie qu’aucun problème n’a été trouvé. Ensuite, faites un commit et poussez-le.
Pour un vrai service d’IA : un flux de travail est du code qui protège la production. Vérifiez-le comme du code : actionlint avant la poussée, et une demande de tirage (pull request) pour chaque changement. Cela s’applique une fois que Publier les preuves ajoute l’ensemble de règles.
Vérifiez votre compréhension
La tâche 1 installe les paquets du fichier de verrouillage. Pourquoi la tâche 2 doit-elle récupérer le code à nouveau, et pourquoi ne peut-elle pas utiliser les paquets de la tâche 1?
Afficher la réponse
Chaque tâche s’exécute sur une nouvelle machine virtuelle (VM), et GitHub supprime la VM lorsque la tâche se termine. La tâche 2 démarre sur une autre VM propre, sans rien de la tâche 1 : aucun code, paquet ou fichier. Seul ce que la tâche 1 a enregistré hors de sa VM demeure : un cache, un artefact ou son résultat (réussite ou échec). C’est un avantage. Le résultat de la tâche 2 dépend uniquement de ce qu’elle fait. Personne n’a donc besoin de savoir ce qui se trouvait sur une machine auparavant.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Sam veut un pipeline plus rapide. Il propose de mettre tout le dossier .venv en cache avec la clé fixe venv. Quel problème survient lorsque requirements-lock.txt change, et comment le cache du cours l'évite-t-il?
Afficher la réponse
Avec une clé fixe, l’exécution suivante restaure l’ancien .venv, avec les anciennes versions. Les vérifications réussissent ou échouent alors avec des paquets que le fichier de verrouillage et l’image n’ont plus. Le cache a changé le résultat, ce qu’un cache ne doit jamais faire. La clé du cache du cours provient de l’empreinte de requirements-lock.txt. Un fichier de verrouillage modifié ne correspond donc jamais à un ancien cache. Il ne stocke aussi que les téléchargements de pip : pip installe toujours exactement les versions du fichier de verrouillage.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Exercice pratique : montrez vos deux premières exécutions. Quelle étape a échoué lors de la première, quels codes de règle a-t-elle signalés, et qu'a affiché ruff check . sur votre ordinateur?
Afficher la réponse
La première exécution a échoué à l’étape Lint, avec le code de sortie 1 : B904 dans ticket_api/config.py à la ligne 28 et I001 dans ticket_api/routes.py à la ligne 1, puis Found 2 errors. Sur votre ordinateur, ruff check . a affiché les deux mêmes problèmes. Le fichier de verrouillage fournissait ruff 0.16.10 aux deux machines, et pyproject.toml leur fournissait les mêmes règles. La deuxième exécution, après le commit de correction, est verte, et son étape Lint indique All checks passed!
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Un exécuteur est la machine qui exécute une tâche. Les exécuteurs hébergés par GitHub démarrent chaque tâche sur une nouvelle VM. N’utilisez jamais un exécuteur autohébergé pour un dépôt public.
- Une VM propre rend chaque résultat reproductible : une tâche dispose uniquement de ce que le flux de travail installe.
- Un cache peut accélérer une tâche, jamais la modifier. Sa clé provient du fichier de verrouillage, et il stocke uniquement des téléchargements.
- Fixez les actions à une version majeure, ou au SHA complet d’un commit pour le verrouillage le plus strict.
- La première exécution réelle a échoué à l’analyse statique, avec les deux mêmes problèmes sur l’exécuteur et votre ordinateur. Vous les avez corrigés, et l’exécution est devenue verte.
Ensuite, la tâche reçoit les vérifications utiles (tests et vérification de sécurité). Une deuxième tâche construit l’image une seule fois et la teste.
Leçon suivante : Construire et tester