Architecture du pipeline
Universal Installer V2 expose une API REST FastAPI qui permet d'intégrer toutes ses fonctions dans n'importe quel pipeline CI/CD. Le serveur tourne sur un runner GitLab dédié et reçoit les commandes de compression, packaging et déploiement depuis le pipeline.
# Architecture du pipeline
Code commit
└── GitLab CI trigger
├── Stage 1 : build (PyInstaller)
├── Stage 2 : compress + package (Universal Installer API)
├── Stage 3 : sign (SignTool / GPG)
├── Stage 4 : deploy cloud (Universal Installer API)
└── Stage 5 : notify (Slack / email)
L'API REST d'Universal Installer
Le serveur API démarre en une commande et expose un Swagger UI pour tester les endpoints :
# Démarrer le serveur API
universal-installer api --port 8420 --host 0.0.0.0 --auth-token $UI_API_TOKEN --work-dir /tmp/ui-workspace
# Swagger UI disponible à http://runner:8420/docs
Les stages GitLab CI
# .gitlab-ci.yml
stages:
- build
- package
- sign
- deploy
- notify
variables:
UI_API: "http://ui-runner:8420"
UI_TOKEN: $UI_API_TOKEN # Variable CI/CD secrète GitLab
Stage : compression et packaging
package:
stage: package
tags: [ui-runner]
script:
- |
# Compresser le dossier de build
RESPONSE=$(curl -s -X POST "$UI_API/api/v1/compress" -H "Authorization: Bearer $UI_TOKEN" -H "Content-Type: application/json" -d '{
"source": "dist/",
"output": "artifacts/app_'"$CI_COMMIT_TAG"'.uxc",
"algo": "auto",
"encrypt": true,
"encrypt_password": "'"$ARCHIVE_PASSWORD"'"
}')
echo "Compression: $RESPONSE"
RATIO=$(echo $RESPONSE | python3 -c "import sys,json; print(json.load(sys.stdin)['ratio'])")
echo "Ratio: $RATIO"
- |
# Générer le patch delta depuis la version précédente
curl -s -X POST "$UI_API/api/v1/delta" -H "Authorization: Bearer $UI_TOKEN" -H "Content-Type: application/json" -d '{
"source": "releases/app_latest.uxc",
"target": "artifacts/app_'"$CI_COMMIT_TAG"'.uxc",
"output": "artifacts/patch_'"$CI_COMMIT_TAG"'.uxcd"
}'
artifacts:
paths: [artifacts/]
expire_in: 30 days
Stage : signature et vérification
sign:
stage: sign
tags: [windows-runner] # SignTool requiert Windows
script:
- # Générer MSI depuis l'archive UXC
- |
curl -s -X POST "$UI_API/api/v1/make-installer" -H "Authorization: Bearer $UI_TOKEN" -d '{"source": "artifacts/app_'"$CI_COMMIT_TAG"'.uxc",
"type": "msi", "version": "'"$CI_COMMIT_TAG"'"}'
- # Signer avec Authenticode
- signtool sign /tr http://timestamp.digicert.com /td sha256 /fd sha256
/f %CERT_PATH% /p %CERT_PASSWORD%
artifacts/*.msi
- # Vérifier l'intégrité
- |
curl -s -X POST "$UI_API/api/v1/verify" -H "Authorization: Bearer $UI_TOKEN" -d '{"path": "artifacts/app_'"$CI_COMMIT_TAG"'.uxc"}'
Stage : déploiement cloud
deploy:
stage: deploy
tags: [ui-runner]
only: [tags]
script:
- |
RESULT=$(curl -s -X POST "$UI_API/api/v1/upload" -H "Authorization: Bearer $UI_TOKEN" -H "Content-Type: application/json" -d '{
"local_path": "artifacts/app_'"$CI_COMMIT_TAG"'.uxc",
"profile": "prod-s3",
"remote_path": "releases/app_'"$CI_COMMIT_TAG"'.uxc",
"also_upload_delta": true,
"delta_path": "artifacts/patch_'"$CI_COMMIT_TAG"'.uxcd",
"update_latest": true
}')
URL=$(echo $RESULT | python3 -c "import sys,json; print(json.load(sys.stdin)['url'])")
echo "Déployé : $URL"
echo "RELEASE_URL=$URL" >> deploy.env
artifacts:
reports:
dotenv: deploy.env
Rollback sur échec
rollback:
stage: deploy
tags: [ui-runner]
when: on_failure
script:
- |
# Restaurer la version précédente
curl -s -X POST "$UI_API/api/v1/rollback" -H "Authorization: Bearer $UI_TOKEN" -d '{
"profile": "prod-s3",
"remote_path": "releases/app_latest.uxc",
"rollback_to": "releases/app_'"$CI_COMMIT_BEFORE_SHA"'.uxc"
}'
Notifications
notify:
stage: notify
when: always
script:
- |
STATUS="succès"
if [ "$CI_JOB_STATUS" = "failed" ]; then STATUS="échec"; fi
curl -X POST "$SLACK_WEBHOOK" -d '{"text": "'"$CI_PROJECT_NAME"' v'"$CI_COMMIT_TAG"' : '"$STATUS"'
URL: '"$RELEASE_URL"'"}'
Conclusion
L'API REST de Universal Installer V2 transforme chaque fonctionnalité (compression, packaging, signature, déploiement cloud, delta) en un endpoint REST appelable depuis n'importe quel pipeline CI/CD. Le pipeline GitLab CI décrit ici est reproductible et couvre tout le cycle : build → package → sign → deploy → rollback → notify.