Aller au contenu
English

Communiquer une mise en production

  • Leçon 15
  • 50 min
  • Module 5 : Rétablir et maintenir le processus de mise en production
Leçon 15 sur 15 · CI/CD, tests et mises en production sûresCommuniquer une mise en production

Ce que vous saurez faire

Une mise en production est terminée quand les personnes qui prennent la relève savent ce qui a changé. Elles savent aussi qui surveille, pendant combien de temps et comment revenir en arrière. Un court texte qui répond à ces questions transforme une surprise à 2 h en décision qu’une autre personne peut prendre.

Avant de commencerCe qu’il faut savoir et avoir sous la mainEnviron 50 minutes

Ce que vous devez savoir

Ce qu’il vous faut sur votre ordinateur

Exécuté avec GitHub Actions (exécuteurs ubuntu-24.04) dans le dépôt public Nextia-Intelligence/ticket-api-ci, Docker Desktop 4.81.0 sur macOS (Apple silicon) et Azure CLI 2.88.0 dans canadacentral. Les étapes pour Windows et Linux ne sont pas testées.

Trois personnes lisent les notes d’une mise en production, chacune avec une question :

  • Un développeur client : « Dois-je modifier mon code? » Pour 1.2.0 : non, mais confidence est obsolète. Passez à score avant 2.0.
  • Le responsable du soutien : « Que voit mon équipe? » Pour 1.2.0 : aucun changement pour le moment; keywords-1.1 viendra plus tard, par étapes.
  • La personne de garde ce soir, qui n’est peut-être pas Amira : « Si ça ne fonctionne plus, que dois-je faire? » Pour 1.2.0 : déployer l’empreinte de 1.1.0.

Les notes de mise en production sont le court texte qui répond à ces questions pour une version. Elles s’adressent aux personnes qui n’ont pas vu le travail. « Correction de quelques bogues » ne répond à aucune des trois questions.

Voici les vraies notes du correctif urgent. Le flux Release a publié le fichier sur la page de la version, puis ajouté la ligne d’empreinte en dessous :

docs/releases/1.2.1.md
## ticket-api 1.2.1 (hotfix)
- **Fixed:** `GET /v1/history` answered `500` when the history had rows from version 1.1.0. Those rows have no `score`; the API now uses their `confidence`. This happened while 1.1.0 and 1.2.0 ran at the same time on one database, during the rollout of 1.2.0.
- **Why the checks missed it:** the database tests made all their rows with 1.2.0, and the smoke check did not call `/v1/history`. Both are added in this release: a test with a row from 1.1.0, and a smoke check that fails on a `5xx` from `/v1/history`.
- **Made from:** the tag `v1.2.0`, on the branch `hotfix/1.2.1`. The same fix is merged into `main`.
- **Owner:** Amira. **Watch after release:** `GET /v1/history` and the error rate, for one day.
- **Rollback:** deploy the 1.2.0 digest (the bug comes back), or 1.1.0.

Chaque ligne a un rôle :

Ligne Question à laquelle elle répond Pourquoi elle est là
Fixed (corrigé) Que voient les clients maintenant? Le symptôme dans les mots du client (GET /v1/history → 500) et quand il se produit. Pas le changement de code : celui-ci est dans le commit (enregistrement des changements).
Why the checks missed it (pourquoi les vérifications l’ont manqué) Cela peut-il se reproduire? Seulement pour une correction. Elle nomme la lacune et la vérification qui la comble.
Made from (créé à partir de) De quel code s’agit-il? Un correctif urgent n’est pas main. Cette ligne le précise et indique que main contient aussi la correction.
Owner (responsable) Qui dois-je appeler? Une personne, nommée. « L’équipe » ne désigne personne à 2 h.
Watch after release (surveillance après la mise en production) Que peut-il arriver, et jusqu’à quand faut-il surveiller? Le signal à observer et la période de surveillance.
Rollback (retour en arrière) Si ça ne fonctionne plus, que dois-je faire? La cible et le coût du retour. « Le bogue revient » est honnête.
Image (ajoutée par le flux) Qu’est-ce qui s’exécute exactement? L’empreinte. Le retour en arrière de la prochaine mise en production part de celle-ci.

Les notes sont un fichier du dépôt, pas un texte saisi dans un formulaire Web. Elles sont donc révisées dans la demande de tirage (pull request), comme le code. Le flux de mise en production publie exactement ce qui a été révisé.

Un responsable est la personne qui prend les décisions après le déploiement : surveiller, revenir en arrière ou appeler d’autres personnes. Une période de surveillance est la durée après une mise en production pendant laquelle le responsable observe activement des signaux précis. La plupart des problèmes d’une mise en production apparaissent rapidement. Comparez les trois mises en production :

Version À surveiller Pendant Pourquoi cette durée
1.1.0 la vérification sommaire en production et les journaux (logs) une heure Le code était le même qu’avant. Seul le chemin de livraison était nouveau.
1.2.0 les vérifications sommaires, le taux d’erreur dans les journaux, GET /v1/history une journée Un changement de schéma et un nouveau champ. Les problèmes de données apparaissent quand le trafic réel écrit des lignes.
1.2.1 GET /v1/history et le taux d’erreur une journée Une correction pour un bogue qui dépend des données. Les anciennes lignes doivent être lues correctement pendant une journée complète de trafic.

La période augmente avec le risque. Un changement aux données ou à un modèle demande plus de trafic avant de pouvoir lui faire confiance. « À surveiller » doit nommer un signal vérifiable : une requête, un point de terminaison, une recherche dans les journaux. Dans le projet de référence, le taux d’erreur venait de la requête des journaux de Mise en production progressive : requêtes par révision et statut.

Remarquez ce que disaient les notes de 1.2.0 : surveiller GET /v1/history pendant une journée. Le bogue était précisément dans ce point de terminaison. La note était juste. Amira a trouvé le bogue 9 minutes après la mise en production, sur une copie locale. Le nuage n’avait pas de base de données, donc le signal ne pouvait pas y révéler le bogue. Un signal de surveillance doit exister dans l’environnement que vous surveillez.

Un incident est un événement qui dégrade le service pour ses utilisateurs et exige une action immédiate. Souvent, la personne qui commence le travail n’est pas celle qui le termine : son quart finit, ou un spécialiste prend la relève. La transmission d’un incident est un court état écrit qui permet à la prochaine personne de continuer sans poser de questions. Elle comprend six parties :

  1. Ce qui s’est passé, en une ou deux phrases, avec le symptôme.
  2. Impact : qui est touché, depuis quand et dans quelle mesure.
  3. Chronologie : heures et faits, avec des liens vers les preuves. Aucune opinion.
  4. État actuel : ce qui s’exécute maintenant et ce qui ne fonctionne toujours pas.
  5. Prochaines étapes : ce qui reste à faire, avec une condition pour chaque étape (« quand il ne reste aucune version 1.1.0 »).
  6. Responsable : qui s’en occupe maintenant et qui la prochaine personne doit appeler.

La chronologie est la partie que les gens écrivent en dernier, mais dont ils ont besoin en premier. Voici la vraie chronologie du 7 octobre 2026 :

Chronologie de mise en production et de rétablissement du 7 octobre 2026, heures en UTC, trois pistes : main, hotfix/1.2.1, production (en service). 18 h 18 main v1.1.0, production 1.1.0 en préproduction et en production. 18 h 32 main v1.2.0 avec score et migrations, production 1.2.0, puis un déploiement canari : keywords-1.1 pour 10 % des requêtes, puis promotion pour toutes les requêtes. 18 h 41 bogue trouvé sur une copie locale : 1.1.0 et 1.2.0 sur une même base de données, GET /v1/history 500. 18 h 44 PR #6 fusionnée, main avance; la production reçoit la construction 6ae49dc, le code reste 1.2.0. 18 h 49 hotfix/1.2.1 à partir de v1.2.0, fc9005a test et correction, toutes les vérifications réussissent. 18 h 51 étiquette v1.2.1, Release étiquette la même image; son empreinte est déployée manuellement en préproduction, puis approuvée pour la production, 1.2.1 à 18 h 53. 18 h 55 PR #7 est BEHIND (en retard), Update branch (mettre à jour la branche) y fusionne main (543b003); PR #7 fusionnée à 18 h 58 (3464f2c); la construction de main est déployée à 19 h 03, vérification history 503. 19 h 03 exercice de retour en arrière : 1.1.0 en 120 s, retour à 1.2.1 en 116 s, indicateur 1.0 en 43 s, puis retour à 1.1. 19 h 12 PR #8 fusionnée (30e0c7e), réparation en avant 003; construction de main déployée à 19 h 16. 19 h 17 ressources Azure supprimées.
La vraie chronologie de mise en production et de rétablissement du dépôt de référence, le 7 octobre 2026, de la version 1.1.0 à la réparation en avant. La production est la route en service.
Description textuelle du diagramme

La chronologie comporte trois pistes. Sur main : v1.1.0 à 18 h 18, v1.2.0 à 18 h 32, PR #6 à 18 h 44, PR #7 fusionnée à 18 h 58, PR #8 avec la réparation en avant à 19 h 12. Sur hotfix/1.2.1, qui part de l’étiquette v1.2.0 : le commit de correction à 18 h 49, avec toutes les vérifications réussies. Puis l’étiquette v1.2.1 à 18 h 51 et, à 18 h 55, la mise à jour de la branche, car PR #7 était en retard sur main. En production : 1.1.0 à 18 h 18; 1.2.0 à 18 h 32, puis le déploiement canari; le bogue trouvé sur une copie locale à 18 h 41; 1.2.1 déployée manuellement de 18 h 51 à 18 h 53; la construction de main à 19 h 03; l’exercice de retour en arrière à partir de 19 h 03; la construction avec la réparation en avant à 19 h 16; et la suppression des ressources Azure à 19 h 17.

Exemple détaillé : Amira transmet l’incident à 19 h 17

Section intitulée « Exemple détaillé : Amira transmet l’incident à 19 h 17 »

La journée d’Amira se termine. Sam est de garde ce soir. Elle rédige la transmission à partir de la chronologie, avec des liens plutôt que des descriptions :

Incident handoff: GET /v1/history 500 (ticket-api 1.2.0)
**What happened:** In 1.2.0, GET /v1/history answered 500 when the history had a row
written by 1.1.0 (no score). Found at 18:41 UTC on a local copy with both versions on
one database. Classification was never affected.
**Impact:** Only GET /v1/history, and only where 1.1.0 and 1.2.0 wrote to one database
(the local environments; the cloud apps have no database, so /v1/history answers 503
there by design). No client reported it.
**Timeline (UTC, 2026-10-07):**
- 18:32 v1.2.0 released and deployed (release v1.2.0).
- 18:41 Bug found: 500, log "items.0.score Input should be a valid number".
- 18:49 Hotfix fc9005a on hotfix/1.2.1 (from v1.2.0): failing test, fix, all checks green (CI run 37669759163).
- 18:51 v1.2.1 released (Release run 37669994015), deployed by hand (Deploy run 37670050850), production at 18:53.
- 18:58 PR #7 merged the fix into main (after Update branch: it was BEHIND).
- 19:03-19:09 Rollback drill: 1.1.0 (run 37671631615, 120 s), forward to 1.2.1 (run 37671961512, 116 s), flag-only rollback 43 s.
- 19:12 PR #8 merged: migration 003 fills the empty score values.
**Current state:** main = 30e0c7e (1.2.1 code + 003), deployed to staging and production at 19:16.
CLASSIFIER_VERSION=1.1 in production. The history smoke check passes. Locally, 003 left 0 empty rows.
**Next steps:**
1. Watch GET /v1/history and the error rate until 18:53 UTC tomorrow (the 1.2.1 window).
2. If history fails again: deploy the 1.2.1 digest sha256:84937455... (Run workflow); do not go to 1.2.0.
3. Before 2.0 removes confidence: ask clients to move to score (see the 1.2.0 notes).
**Owner:** Sam from now (on duty). Amira is the owner of 1.2.1: call her for code questions.

Lisez-la comme si vous étiez Sam. Chaque ligne est un fait avec une heure ou un lien. Le retour en arrière dans « Prochaines étapes » nomme l’empreinte et indique où ne pas aller : 1.2.0 ramènerait le bogue. « État actuel » indique ce qui s’exécute maintenant, pas ce qui était prévu. Et le texte est court : Sam le lit en deux minutes.

À 19 h 17, l’exercice s’est terminé et Amira a supprimé les ressources Azure. az resource list -g rg-ticket-api-ci a listé 6 ressources : l’espace de travail, l’environnement, les deux applications et les deux identités. Il y avait aussi 2 attributions de rôle. Elle a ensuite exécuté az group delete --name rg-ticket-api-ci --yes --no-wait. Le dépôt GitHub, ses versions et ses exécutions restent : ce sont les preuves vers lesquelles ce cours renvoie.

  1. Ouvrez docs/releases/1.2.0.md dans votre dépôt. Pour chaque ligne, indiquez quel lecteur de Qui lit les notes de mise en production? en a besoin.
  2. Trouvez la ligne qui aurait le plus aidé à 18 h 41. Expliquez pourquoi.
  3. Rédigez la transmission du bogue de 1.2.0 comme si Sam prenait la relève à 18 h 45, avant le correctif urgent. Utilisez les six parties.
  4. Dans « Prochaines étapes », écrivez les deux options de Sam à 18 h 45, avec ce que chacune retire.
  5. Comparez avec la transmission de 19 h 17 ci-dessus. Qu’est-ce qui a changé entre 18 h 45 et 19 h 17 dans « État actuel »?
Afficher une réponse modèle
  1. « New for clients » (nouveautés pour les clients) et l’obsolescence de confidence : le développeur client. « New, off by default » (nouveau, désactivé par défaut), pour keywords-1.1 : le responsable du soutien. « Database » (base de données), pour exécuter les migrations d’abord : la personne qui déploie. « Owner », « Watch » (surveillance) et « Rollback » : la personne de garde.
  2. « Watch after release : … GET /v1/history, pendant une journée ». Cette ligne nommait le signal du bogue avant que quiconque connaisse le bogue.
  3. et 4. À 18 h 45 :
Incident handoff at 18:45 (shortened)
**What happened:** 1.2.0 GET /v1/history answers 500 when a row from 1.1.0 (no score) is
in the history. Found 18:41 UTC on a local copy. Classification works.
**Impact:** GET /v1/history only, where 1.1.0 and 1.2.0 share a database.
**Timeline:** 18:32 v1.2.0 released; 18:41 bug found (500, items.0.score is None).
**Current state:** production runs the 6ae49dc build (1.2.0 code), flag 1.1. Not fixed.
**Next steps (choose one):**
a) Hotfix 1.2.1 from v1.2.0 (Amira started at 18:44). Keeps score and keywords-1.1.
b) Roll back to 1.1.0 (digest sha256:4eb3db8d...): stops the 500, but removes score
and keywords-1.1. Tell clients and the help desk first.
**Owner:** Amira (hotfix). Sam: call Amira before option b.
  1. À 18 h 45, le bogue n’est pas corrigé et la prochaine étape est un choix. À 19 h 17, la correction est en production et sur main, les données sont réparées. La prochaine étape consiste seulement à surveiller. Une transmission est un instantané de l’état : rédigez-en une nouvelle quand l’état change, sans modifier l’ancienne.

À vous de jouer : notes pour la réparation en avant

Section intitulée « À vous de jouer : notes pour la réparation en avant »

PR #8 (migration 003) a été fusionnée et déployée, mais n’a reçu aucune étiquette ni notes de mise en production. Est-ce correct? Rédigez docs/releases/1.2.2.md comme si 003 était publiée comme version 1.2.2. Que doivent dire les lignes « Database » et « Rollback »?

Afficher une réponse

Sans étiquette, le changement n’a pas de page de version. La prochaine personne doit lire la demande de tirage pour savoir que les données ont changé. Pour un changement aux données, une mise en production est préférable. Voici une version :

docs/releases/1.2.2.md
## ticket-api 1.2.2
- **Changes for clients:** none. History items that came from version 1.1.0 already showed
`score` (since 1.2.1); now the database has the value too.
- **Database:** migration `003_backfill_score` sets `score = confidence` where `score` is
empty. It changes no structure. Run it after no 1.1.0 instance is left. Take a backup first:
it changes rows.
- **Owner:** Amira. **Watch after release:** the count of rows with an empty `score` (must
stay 0) and `GET /v1/history`, for one day.
- **Rollback:** deploy the 1.2.1 digest. The filled values stay, and 1.2.1 reads them
correctly. A rollback does not undo `003`; only the backup has the old values.

La ligne « Rollback » est importante : elle précise que le changement aux données reste après un retour en arrière. Elle indique aussi où sont les anciennes valeurs.

Erreur courante

Les notes promettaient une vérification que le déploiement n'a pas exécutée

Symptôme (en service) : les notes de 1.2.1 disent qu’une « vérification sommaire qui échoue sur un 5xx de /v1/history » est ajoutée. Mais la vérification sommaire du déploiement du correctif urgent (exécution 37670050850) n’a affiché que quatre lignes dans chaque environnement :

ok health (200)
ok ready (200)
ok classify with the key (200)
ok classify without a key (401)

Aucune ligne history (historique). La nouvelle vérification ne s’est pas exécutée lors du déploiement pour lequel elle avait été écrite. Le déploiement suivant, après PR #7 (exécution 37671226621), a affiché cinq lignes, dont ok history (503) (historique réussi, code 503). Son commentaire d’approbation le précisait : « Staging passed, including the new history check. » (La préproduction a réussi, y compris la nouvelle vérification de l’historique.)

Cause : le flux Deploy s’exécute depuis main, avec les fichiers de main, y compris scripts/smoke.sh. À 18 h 51, main ne contenait pas encore le correctif urgent et utilisait donc l’ancienne vérification sommaire. Seule l’image venait du correctif urgent. C’est la bonne conception : le processus de déploiement a une seule version, sur main. Mais les notes ne précisaient pas quelle vérification s’exécute à quel moment.

Correction :

  1. Écrivez dans les notes ce qui a été vérifié, pas seulement ce qui a été ajouté : « La nouvelle vérification sommaire de l’historique s’exécute au prochain déploiement de main, après la fusion du correctif. »
  2. Fusionnez le correctif urgent dans la branche d’origine avant de vous fier à ses nouvelles vérifications. Cherchez la nouvelle ligne dans le journal de l’exécution.
  3. Pour le déploiement du correctif urgent lui-même, vérifiez le point de terminaison manuellement et notez le résultat dans la transmission : curl -s -o /dev/null -w "%{http_code}" <URL>/v1/history -H "X-API-Key: …".

Pour un vrai service d’IA : une note dit « nous avons ajouté une évaluation pour ce cas ». Mais le pipeline de mise en production utilise encore l’ancien jeu d’évaluation. Cela donne à tout le monde une fausse confiance. Les notes doivent préciser ce qui s’est exécuté, avec un lien vers l’exécution.

Vérifiez votre compréhension

Pourquoi les notes de 1.2.0 et 1.2.1 demandent-elles une journée de surveillance, et celles de 1.1.0 une heure?

Afficher la réponse

La période de surveillance augmente avec le risque. 1.1.0 avait le même code qu’avant. Seul le chemin de livraison était nouveau. Une heure de vérifications sommaires et de journaux suffisait donc. 1.2.0 a changé le schéma et l’API (un nouveau champ). 1.2.1 a corrigé un bogue qui dépend des données de la table. Les problèmes de données apparaissent seulement quand le trafic réel écrit et lit des lignes, souvent plusieurs heures plus tard. Le responsable surveille donc des signaux précis (GET /v1/history, le taux d’erreur) pendant une journée complète.

Exercice guidé → tâche autonome. Simulez une mise en production échouée en préproduction et un correctif urgent en production avec des environnements jetables. Le parcours local ne coûte rien : deux projets Compose, staging (port 8081) et production (port 8082). Chacun a sa propre base de données, avec une base de test pour les vérifications. Vous les créez, les brisez, les réparez et les supprimez.

Vous avez vu un petit exemple détaillé dans chaque leçon. Maintenant, faites tout le module vous-même, à partir d’un état vierge :

  1. La mise en production échouée en préproduction. Déployez la version 1.2.0 en préproduction avec les outils de main (ils comprennent le test de fumée de l’historique). Démarrez la version 1.1.0 à côté sur le réseau de préproduction, comme pendant un déploiement progressif. Classez un billet de soutien avec cette version. Relancez le test de fumée de la préproduction. Il doit échouer. Arrêtez la promotion : la production reste telle quelle.
  2. La décision. Écrivez en deux phrases quelle option de retour en arrière vous utiliseriez et pourquoi.
  3. Le correctif urgent. Dans un dépôt d’exercice, créez hotfix/1.2.1 à partir de v1.2.0 : test qui échoue, correctif, toutes les vérifications, étiquette. Déployez l’image 1.2.1 en préproduction, puis en production. Fusionnez dans main après une mise à jour de la branche.
  4. Rétablir et vérifier. Montrez le bon fonctionnement connu (tous les tests de fumée réussissent, /v1/history → 200). Réparez les données avec 003 et montrez qu’aucun correctif n’est perdu dans main.
  5. Communiquer. Rédigez les notes de mise en production de la version 1.2.1 et un transfert de responsabilité en six parties.
  6. Nettoyer. Supprimez les deux environnements et leurs bases de données.

Indiquez simulé pour chaque résultat (ou réel, si vous avez fait l’étape 3 avec vos applications Azure). Utilisez vos propres sorties.

Afficher une réponse modèle (simulée, abrégée)

1. La mise en production échouée en préproduction. Les commandes, depuis une copie de travail de main :

Terminal (simulated)
scripts/promote-local.sh staging ghcr.io/usmanahmed99/ticket-api-ci@sha256:bd2316b56067c738199d6203a23845c97fb7b85b550379411eddd7cc6a2ddab8
docker run -d --name ticket-api-staging-old --platform linux/amd64 --network ticket-api-staging_default \
-e API_KEY=old-key -e DATABASE_URL=postgresql://tickets:<password from .env>@db:5432/tickets \
ghcr.io/usmanahmed99/ticket-api-ci@sha256:4eb3db8d4ea249fb9b44b27d96deb68aba6da3e3fbc9cf32311a9cbadf4d857a
docker exec ticket-api-staging-old python -c "import urllib.request,json; r=urllib.request.Request('http://127.0.0.1:8000/v1/classify', data=json.dumps({'subject':'Parcel lost'}).encode(), headers={'Content-Type':'application/json','X-API-Key':'old-key'}); print(urllib.request.urlopen(r).read().decode())"
scripts/smoke.sh http://127.0.0.1:8081 "$(cat secrets/staging_api_key.txt)"; echo "smoke exit $?"

L’ancien conteneur n’a aucun port publié. La requête de classification s’exécute donc à l’intérieur, avec Python. La sortie (simulée) :

ok health (200)
ok ready (200)
ok classify with the key (200)
ok classify without a key (401)
ok history (200)
staging now runs ghcr.io/usmanahmed99/ticket-api-ci@sha256:bd2316b56067c738199d6203a23845c97fb7b85b550379411eddd7cc6a2ddab8
{"category":"shipping","priority":1,"confidence":0.7,"model_version":"keywords-1.0"}
ok health (200)
ok ready (200)
ok classify with the key (200)
ok classify without a key (401)
FAIL history: expected 200|503, got 500
smoke exit 1

Le premier test de fumée a réussi : la base de préproduction était vide, donc aucune ligne ne manquait de score. Le test a échoué seulement après l’ajout d’une ligne par la version 1.1.0. La qualité d’une vérification en préproduction dépend des données et du trafic en préproduction. La production n’a pas été touchée : la mise en production s’est arrêtée en préproduction.

2. La décision. Le code est incorrect, pas le modèle. Un retour en arrière par indicateur n’aide donc pas. Revenir à la version 1.1.0 retirerait score et keywords-1.1 pour tous les clients, afin de réparer un seul point de terminaison. Un correctif urgent est le plus petit changement.

3. Le correctif urgent. Le test échoue d’abord (assert None == 0.7 ± 7.0e-07), puis affiche 3 passed (3 tests réussis). Toutes les vérifications : 31 passed (31 tests réussis), « No known vulnerabilities found » (aucune vulnérabilité connue trouvée), « Gate passed. » (barrière franchie). Le graphe après la fusion dans la branche d’origine est celui de Procédure de correctif urgent : exercice guidé. Déployez d’abord en préproduction :

$ scripts/promote-local.sh staging ghcr.io/usmanahmed99/ticket-api-ci@sha256:84937455beb63744755622d539748c9adb1772f379c9eb7e4f961c5b7f1bc924
ok health (200)
ok ready (200)
ok classify with the key (200)
ok classify without a key (401)
ok history (200)
staging now runs ghcr.io/usmanahmed99/ticket-api-ci@sha256:84937455beb63744755622d539748c9adb1772f379c9eb7e4f961c5b7f1bc924

Puis déployez la même empreinte en production, avec les cinq mêmes lignes ok (réussi). Parcours réel : la même empreinte avec Run workflow (exécuter le flux de travail), comme dans l’exécution 37670050850.

4. Rétablir et vérifier. /v1/history → 200, et l’ancienne ligne affiche score à partir de confidence. Supprimez ticket-api-staging-old, puis déployez la construction avec 003 dans chaque environnement : applied 003_backfill_score (migration appliquée). Le nombre de lignes dont score est vide passe à 0. Dans l’exécution de test de Stratégie de retour en arrière, il passe de 3 à 0 en production. Dans le dépôt d’exercice : git branch --contains v1.2.1 liste main; git log main --oneline | grep Hotfix trouve le commit (changement enregistré); grep -n test_history_reads_rows_from_version_1_1 tests/test_database.py trouve le test dans main.

5. Communiquer. Les notes contiennent les sept lignes de Les parties des notes de 1.2.1. Le transfert de responsabilité contient les six parties, avec vos heures.

6. Nettoyer. Consultez la remise à zéro dans le récapitulatif.

Une personne qui révise l’exercice le marque démontré quand quatre conditions sont remplies. La vérification échouée en préproduction est montrée avec sa ligne FAIL (échec) et son code de sortie 1. La production n’a pas été modifiée. Le nouveau test est montré en échec avant le correctif, puis réussi après, et aucune vérification n’a été omise. Le bon fonctionnement connu est montré avec les cinq tests de fumée après le correctif urgent. 003 ramène les lignes vides à 0. Des preuves montrent que main contient le correctif.

Vérifiez votre compréhension

Rappel : nommez les trois options de retour en arrière de ce module. Pour chacune, indiquez la procédure pour l'API de billets et sa durée pendant l'exercice.

Afficher la réponse

Retour en arrière de l’application : déployer l’empreinte précédente avec le flux de travail Deploy (déployer), avec Run workflow. Passer par la préproduction et l’approbation : 120 secondes jusqu’en production pour la version 1.1.0, 116 secondes pour avancer à 1.2.1. Retour en arrière du modèle : changer seulement l’indicateur, CLASSIFIER_VERSION=1.0, sur la même image : 43 secondes. Données : aucun retour en arrière; réparer en avançant avec une nouvelle migration (003_backfill_score). Une seule migration a fait passer les lignes vides de 1 à 0. Restaurer une sauvegarde seulement en cas de perte de données.

Vérifiez votre compréhension

Prédiction : une équipe omet la fusion d'un correctif urgent dans la branche d'origine et n'a aucun test pour le bogue. Quelles vérifications du module détecteraient encore le bogue à son retour dans la prochaine mise en production? Lesquelles ne le détecteraient pas?

Afficher la réponse

Presque aucune. Le nouveau test de base de données est seulement dans la branche du correctif urgent. La CI sur main ne l’exécute donc pas. Le test de fumée de l’historique est aussi seulement dans la branche du correctif urgent. Le flux de travail Deploy utilise scripts/smoke.sh de main, donc les vérifications de déploiement réussiraient. La barrière d’évaluation et l’analyse statique vérifient autre chose. Seule la période de surveillance de la prochaine mise en production pourrait montrer le 500, après que les utilisateurs le reçoivent. Et git branch --contains v1.2.1 montrerait immédiatement que main ne contient pas le correctif urgent. La fusion dans la branche d’origine et le test permettent au correctif de rester en place.

Vérifiez votre compréhension

Vérification finale : rétablissez le bon fonctionnement connu et vérifiez qu'aucun correctif n'est perdu dans la branche de développement. Montrez vos preuves.

Afficher la réponse

Bon fonctionnement connu : l’environnement qui avait le bogue exécute l’empreinte du correctif urgent. Le test de fumée affiche cinq lignes ok, dont ok history (200) (en local) ou (503) (dans le nuage, sans base de données). GET /v1/history avec une ligne de la version 1.1.0 répond 200. Après 003, le nombre de lignes dont score est vide est de 0. Aucun correctif perdu : git branch --contains v1.2.1 liste main; git log main --oneline | grep Hotfix montre le commit du correctif urgent. Le test test_history_reads_rows_from_version_1_1 se trouve dans tests/test_database.py sur main, et la CI sur main a réussi avec ce test. Chaque résultat porte la mention simulé ou réel. Si un de ces éléments manque, le rétablissement est supposé, pas vérifié.

Récapitulatif

  • Les notes de mise en production répondent à trois lecteurs : ce qui change pour les clients, ce que voit le soutien technique et ce que fait la personne de garde en cas de panne. Chaque mise en production précise un responsable, les signaux à surveiller et pendant combien de temps, ainsi que le retour en arrière et son coût.
  • La période de surveillance augmente avec le risque : une heure pour la version 1.1.0, une journée pour les changements de données des versions 1.2.0 et 1.2.1.
  • Un transfert de responsabilité d’incident comprend six parties : événements, impact, chronologie avec liens, état actuel, prochaines étapes avec conditions, responsable. Rédigez-en un nouveau quand l’état change.
  • Les notes indiquent ce qui a été vérifié, avec un lien vers l’exécution. Le déploiement du correctif urgent a exécuté le test de fumée de main, sans la nouvelle vérification de l’historique.
  • Dans ce module, vous avez choisi entre un retour en arrière de l’application, du modèle et des données. Vous avez livré un correctif urgent à partir de l’étiquette avec toutes les vérifications. Vous l’avez fusionné dans la branche d’origine et avez réparé les données en avançant.

Remise à zéro. Supprimez les environnements locaux et leurs bases de données depuis le dossier du projet : scripts/stop-local.sh staging --volumes et scripts/stop-local.sh production --volumes. Supprimez les conteneurs supplémentaires : docker rm -f -v ticket-api-old ticket-api-staging-old ticket-api-testdb (« No such container », aucun conteneur de ce nom, est acceptable). Vérifiez avec docker ps -a --filter name=ticket-api et docker volume ls --filter name=ticket-api : aucune ligne de ce module. Supprimez le dossier du dépôt d’exercice. Pour recommencer le module, copiez l’instantané end-of-m04; pour le travail final, partez de end-of-m05. Parcours réel : si vous avez créé des ressources Azure, supprimez le groupe de ressources comme dans Vérifier et supprimer. Cette leçon fait partie de L’essentiel de Docker et du nuage pour les développeurs en IA. Vérifiez avec az group exists jusqu’à ce que la commande affiche false (faux).

Le cours. Vous avez commencé avec un changement et la question « comment arrive-t-il en production de façon sûre? ». Maintenant, chaque changement dans votre dépôt lance une analyse statique, des tests, une vérification de sécurité et une barrière d’évaluation de l’IA. Le tout s’exécute sur un exécuteur vierge. Le pipeline construit une image et la relie à son commit. Il promeut cette empreinte en préproduction, puis en production après une approbation. Chaque environnement a sa propre identité et aucun mot de passe stocké. Vous avez mis en production un changement de modèle et un changement de schéma sans briser l’ancienne version. Vous avez fait trois types de retour en arrière et livré un correctif urgent sans le perdre. Le travail final vous demande de concevoir et d’exécuter le pipeline à nouveau, vous-même, avec les preuves de chacune de ces affirmations.

Leçon suivante : Travail final