@mostajs/deployment
v0.1.0
Published
Orchestrateur de séquences de déploiement réutilisables — plan d’étapes idempotentes (definePlan) exécuté en dry-run/apply/rollback/resume avec snapshot, auto-rollback et validation post-déploiement. Zéro dépendance runtime.
Maintainers
Readme
@mostajs/deployment
Orchestrateur de séquences de déploiement réutilisables — dry-run, apply, rollback. Cron-ready, CI-ready, on-prem-ready.
Auteur : Dr Hamid MADANI [email protected] License : AGPL-3.0-or-later Statut : 🚧 v0.0.1 — design + plan livrés. Pas encore publié sur npm.
Voir
docs/PLAN-V0.1.0.mdpour le plan de développement etdocs/ARCHITECTURE.mdpour les concepts.
Pourquoi ce module ?
Les déploiements applicatifs (migration de schéma DB, bascule de service, hot-reload de config, séparation système / métier comme le chantier system dialect dans @mostajs/net 2.7.5) suivent toujours le même squelette :
- Inventaire (qu'est-ce qu'on a en place ?)
- Backup (rollback possible ?)
- Préparer (créer ressources, écrire configs, sans toucher au runtime)
- Migrer (déplacer les données — souvent via
@mostajs/orm-copy-data) - Activer (restart pm2, reload Apache — point de bascule)
- Vérifier (smoke E2E — souvent via
@mostajs/validation) - Rollback automatique en cas d'échec à 5 ou 6
@mostajs/deployment formalise ce squelette en DSL TypeScript : tu exprimes ton plan, le runtime exécute (en mode dry-run, apply, ou rollback).
Pas encore publié — pourquoi ?
Le module sort d'un cas concret (migration system dialect en prod amia.fr) documenté dans Entreprise/octonet-mcp/docs/MIGRATION-SYSTEM-DIALECT-PROD.md. Pour éviter le piège YAGNI (« inventer une mauvaise abstraction avant 2-3 cas concrets »), on attend d'avoir traversé au moins 2 migrations différentes avant de figer l'API publique.
Cible v0.1.0 : après le 2ᵉ cas d'usage (probablement la séparation octonet_meta → 3 bases : octonet_meta_system + octonet_meta_business + octonet_meta_audit, ou un déploiement multi-tenant), l'API se stabilise → publish npm.
Aperçu API (cible v0.1.0)
import { definePlan, run } from '@mostajs/deployment'
const migrationSystemDialect = definePlan({
name: 'system-dialect-prod',
steps: [
{
name: 'inventaire',
idempotent: true,
run: async (ctx) => {
ctx.log('count tables…')
ctx.set('tables.before', await ctx.psql.tables('octonet_meta'))
},
},
{
name: 'backup',
idempotent: false, // skip si déjà fait
run: async (ctx) => {
await ctx.exec(`pg_dump octonet_meta > ${ctx.workdir}/backup.sql`)
},
rollback: async (ctx) => { /* no-op : backup ne s'annule pas */ },
},
{
name: 'migrate-data',
run: async (ctx) => {
const { copyData } = await import('@mostajs/orm-copy-data')
await copyData({
source: { type: 'db', dialect: 'postgres', uri: ctx.env.OCTONET_META },
dests: [{ type: 'db', dialect: 'postgres', uri: ctx.env.OCTONET_META_SYSTEM }],
tables: ctx.env.SYSTEM_TABLES,
})
},
rollback: async (ctx) => {
await ctx.exec(`dropdb octonet_meta_system && createdb octonet_meta_system`)
},
},
// … etc.
],
validate: async (ctx) => {
const { defineSuite, run } = await import('@mostajs/validation')
return run(defineSuite('post-deploy', /* phases… */))
},
})
await run(migrationSystemDialect, { mode: 'dry-run' }) // simule, log, pas d'effet
await run(migrationSystemDialect, { mode: 'apply' }) // exécute, snapshot pour rollback
await run(migrationSystemDialect, { mode: 'rollback' }) // re-applique steps en sens inverseRoadmap
Voir docs/PLAN-V0.1.0.md. Synthèse :
- v0.0.1 (actuelle) : design + plan + script template
- v0.1.0 : API minimale
definePlan/run/ hooks pre/post / dry-run / apply / rollback. Adapter SSH+sudo - v0.2.0 : adapter pm2 + Apache + Postgres builtin. Plan persistant (reprise après crash)
- v0.3.0 : Docker + K8s adapters. CI runner GitHub Actions
- v1.0.0 : API stable. Publish npm.
License
AGPL-3.0-or-later — usage libre tant que le code dérivé reste open-source.
Licence commerciale disponible : [email protected].
— (c) 2026 Dr Hamid MADANI <[email protected]>
