v3 : troisième relecture — une coquille n'inverse plus un sens ; retour à la version précédente
- Mot mal tapé = un seul glissement (une lettre ajoutée, retirée, ou deux voisines inversées), jamais au début du mot (préfixes : valide/invalide, limitée/illimitée), jamais une lettre remplacée (deux/dix, majorité/minorité), jamais sur un mot de négation ou de quantité, mots de 4 lettres au moins. - Parenthèses, crochets, « / » et tout ce qui est entre accents graves comptent comme le sens (ceil(N^(1/5)) → ceil(N^1/5) n'est plus une coquille). - Caractères invisibles (inversion du sens d'écriture, largeur nulle, BOM) refusés dans les textes, titres, traductions et motifs de signalement. - Déploiement : la version en service est gardée (image « previous ») ; un témoin marque le déploiement en cours ; « retablir » relance la maquette au premier déploiement, la version précédente ensuite ; la liste des conteneurs retirés n'est plus vidée par un pipeline annulé. - Tests : 59 Rust (dont 14 scénarios d'API, avec deux → dix sur E2 en vigueur et l'inversion bidi), e2e 12 / 12. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+32
-17
@@ -34,6 +34,8 @@ steps:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
commands:
|
||||
- BUILD=$(echo "$CI_COMMIT_SHA" | cut -c1-8)
|
||||
# La version en service est gardée : « retablir » la relance si ce déploiement échoue.
|
||||
- docker image inspect libredecision-app:latest >/dev/null 2>&1 && docker tag libredecision-app:latest libredecision-app:previous || true
|
||||
- docker build -t libredecision-app:latest -f docker/app.Dockerfile --target production --build-arg LD_BUILD=$BUILD .
|
||||
- echo "Image app construite ($BUILD)"
|
||||
|
||||
@@ -99,6 +101,8 @@ steps:
|
||||
- /opt/libredecision-app:/opt/libredecision-app
|
||||
commands:
|
||||
- DOMAIN=decision.librodrome.org
|
||||
# Témoin : à partir d'ici, un échec appelle « retablir ». Le healthcheck réussi l'efface.
|
||||
- touch /opt/libredecision-app/deploying
|
||||
- echo "APP_DOMAIN=$DOMAIN" > /opt/libredecision-app/.env
|
||||
- cp docker/app-compose.yml /opt/libredecision-app/docker-compose.yml
|
||||
# Tout conteneur, même arrêté, qui revendique encore la racine (la maquette avant son
|
||||
@@ -106,11 +110,11 @@ steps:
|
||||
# « restart: always » : sinon un redémarrage de Docker le ramènerait, et fabio lui
|
||||
# donnerait /api/* (route la plus longue). Rien n'est supprimé ; la maquette est
|
||||
# recréée par son propre workflow, sous son nouveau domaine.
|
||||
# Ceux qui tournaient sont notés dans /opt/libredecision-app/retires : si la suite
|
||||
# échoue, l'étape « retablir » les relance (et seulement eux).
|
||||
# Ceux qui tournaient sont ajoutés à /opt/libredecision-app/retires (jamais vidé ici :
|
||||
# un pipeline annulé ne perd pas sa liste) ; si la suite échoue, « retablir » les relance.
|
||||
- |
|
||||
RETIRES=/opt/libredecision-app/retires
|
||||
: > "$RETIRES"
|
||||
touch "$RETIRES"
|
||||
for TAG in "urlprefix-$DOMAIN/*" "urlprefix-$DOMAIN/api/*"; do
|
||||
for C in $(docker ps -aq --filter "label=SERVICE_3000_TAGS=$TAG") $(docker ps -aq --filter "label=SERVICE_8002_TAGS=$TAG"); do
|
||||
NAME=$(docker inspect --format '{{.Name}}' "$C")
|
||||
@@ -182,6 +186,7 @@ steps:
|
||||
*'"ok":true'*"\"build\":\"$BUILD\""*|*"\"build\":\"$BUILD\""*'"ok":true'*)
|
||||
echo "PASS: $BUILD repond sur $TARGET"
|
||||
: > /opt/libredecision-app/retires
|
||||
rm -f /opt/libredecision-app/deploying
|
||||
exit 0 ;;
|
||||
esac
|
||||
i=$((i+1))
|
||||
@@ -190,9 +195,10 @@ steps:
|
||||
echo "FAIL: $BUILD ne repond pas apres 10 minutes"
|
||||
exit 1
|
||||
|
||||
# Échec après le retrait de la racine : le produit s'arrête, ce qu'il avait retiré
|
||||
# repart (restart: always rendu). Échec avant (construction, tests) : rien à faire,
|
||||
# la liste est vide depuis le dernier déploiement réussi.
|
||||
# Échec avant le déploiement (construction, tests, SBOM) : rien n'a bougé, rien à faire.
|
||||
# Échec après, au premier déploiement : le produit s'arrête et ce qu'il avait retiré de la
|
||||
# racine repart (restart: always rendu). Échec après, plus tard : la version précédente du
|
||||
# produit (image « previous ») est relancée.
|
||||
# NOTE: volumes + pas de from_secret : compatible
|
||||
- name: retablir
|
||||
image: docker:27-cli
|
||||
@@ -205,17 +211,26 @@ steps:
|
||||
- /opt/libredecision-app:/opt/libredecision-app
|
||||
commands:
|
||||
- |
|
||||
RETIRES=/opt/libredecision-app/retires
|
||||
if [ ! -s "$RETIRES" ]; then echo "Rien a retablir"; exit 0; fi
|
||||
# Hors de « restart: always » aussi, sinon un redémarrage de Docker le ramènerait
|
||||
# à côté de ce qui revient ; le prochain déploiement le recrée (--force-recreate).
|
||||
docker update --restart=no lpk-libredecision-app >/dev/null 2>&1 || true
|
||||
docker stop lpk-libredecision-app >/dev/null 2>&1 || true
|
||||
for C in $(cat "$RETIRES"); do
|
||||
echo "Retour de $(docker inspect --format '{{.Name}}' "$C" 2>/dev/null || echo "$C")"
|
||||
docker update --restart=always "$C" >/dev/null && docker start "$C" >/dev/null || echo " echec pour $C"
|
||||
done
|
||||
: > "$RETIRES"
|
||||
D=/opt/libredecision-app
|
||||
if [ ! -e "$D/deploying" ]; then echo "Echec avant le deploiement : rien a retablir"; exit 0; fi
|
||||
if [ -s "$D/retires" ]; then
|
||||
# Hors de « restart: always » aussi, sinon un redémarrage de Docker le ramènerait
|
||||
# à côté de ce qui revient ; le prochain déploiement le recrée (--force-recreate).
|
||||
docker update --restart=no lpk-libredecision-app >/dev/null 2>&1 || true
|
||||
docker stop lpk-libredecision-app >/dev/null 2>&1 || true
|
||||
for C in $(cat "$D/retires"); do
|
||||
echo "Retour de $(docker inspect --format '{{.Name}}' "$C" 2>/dev/null || echo "$C")"
|
||||
docker update --restart=always "$C" >/dev/null && docker start "$C" >/dev/null || echo " echec pour $C"
|
||||
done
|
||||
: > "$D/retires"
|
||||
elif docker image inspect libredecision-app:previous >/dev/null 2>&1; then
|
||||
echo "Retour a la version precedente du produit"
|
||||
docker tag libredecision-app:previous libredecision-app:latest
|
||||
cd "$D" && docker compose up -d --force-recreate
|
||||
else
|
||||
echo "Aucune version precedente a relancer"
|
||||
fi
|
||||
rm -f "$D/deploying"
|
||||
when:
|
||||
- status: failure
|
||||
|
||||
|
||||
Reference in New Issue
Block a user