xcorecli 1.0.2__tar.gz → 1.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xcorecli-1.1.1/.vscode/dryrun.log +8 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/PKG-INFO +2 -2
- xcorecli-1.1.1/docs/deploy/index.md +406 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/index.md +2 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/reference.md +29 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/mkdocs.yml +2 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/pyproject.toml +1 -1
- {xcorecli-1.0.2 → xcorecli-1.1.1}/uv.lock +1 -1
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/_xcore.py +14 -0
- xcorecli-1.1.1/xcli/deploy/cli.py +538 -0
- xcorecli-1.1.1/xcli/deploy/config.py +289 -0
- xcorecli-1.1.1/xcli/deploy/generate.py +122 -0
- xcorecli-1.1.1/xcli/deploy/runner.py +692 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/init/manager.py +0 -6
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/main.py +8 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/manager/cli.py +83 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/marketplace/cli.py +13 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/plugin/install_commands.py +7 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/plugin/local_commands.py +12 -1
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/plugin/marketplace_commands.py +2 -0
- xcorecli-1.1.1/xcli/plugin/security_commands.py +532 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/plugin/update_commands.py +21 -1
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/sandbox/cli.py +3 -0
- xcorecli-1.1.1/xcli/worker/__init__.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/worker/worker.py +8 -8
- xcorecli-1.0.2/.vscode/dryrun.log +0 -4
- xcorecli-1.0.2/GEMINI.md +0 -68
- xcorecli-1.0.2/integration.yaml +0 -280
- xcorecli-1.0.2/xcli/init/cli.py +0 -11
- xcorecli-1.0.2/xcli/plugin/security_commands.py +0 -69
- {xcorecli-1.0.2 → xcorecli-1.1.1}/.github/workflows/publish.yml +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/.gitignore +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/.python-version +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/.vscode/configurationCache.log +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/.vscode/settings.json +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/.vscode/targets.log +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/README.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/commands/health.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/commands/init.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/config/index.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/getting-started/auth.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/getting-started/configuration.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/getting-started/install.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/manager/index.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/manager/monitoring.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/manager/services.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/migration/index.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/plugin/index.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/plugin/install.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/plugin/local.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/plugin/marketplace.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/plugin/runtime.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/plugin/security.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/plugin/update.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/sandbox/index.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/worker/index.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/docs/worker/process.md +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/makefile +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/__init__.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/_credentials.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/_run.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/config/__init__.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/config/cli.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/config/runtime.py +0 -0
- {xcorecli-1.0.2/xcli/init → xcorecli-1.1.1/xcli/deploy}/__init__.py +0 -0
- {xcorecli-1.0.2/xcli/manager → xcorecli-1.1.1/xcli/init}/__init__.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/init/upgrade.py +0 -0
- {xcorecli-1.0.2/xcli/marketplace → xcorecli-1.1.1/xcli/manager}/__init__.py +0 -0
- {xcorecli-1.0.2/xcli/plugin → xcorecli-1.1.1/xcli/marketplace}/__init__.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/migrations/__init__.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/migrations/cli.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/migrations/runtime.py +0 -0
- {xcorecli-1.0.2/xcli/sandbox → xcorecli-1.1.1/xcli/plugin}/__init__.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/plugin/cli.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/plugin/runtime_commands.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/plugin/scaffold.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/plugin/shared.py +0 -0
- {xcorecli-1.0.2/xcli/worker → xcorecli-1.1.1/xcli/sandbox}/__init__.py +0 -0
- {xcorecli-1.0.2 → xcorecli-1.1.1}/xcli/worker/cli.py +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
make --dry-run --always-make --keep-going --print-directory
|
|
2
|
+
make: Entering directory '/home/eliezer/devs/xcoreCli'
|
|
3
|
+
echo "📚 Liste des commandes disponibles :"
|
|
4
|
+
grep -E '^[a-zA-Z0-9_-]+:.*?## .*$' makefile \
|
|
5
|
+
| sort \
|
|
6
|
+
| awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $1, $2}'
|
|
7
|
+
make: Leaving directory '/home/eliezer/devs/xcoreCli'
|
|
8
|
+
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# Deploy — Déploiement en production
|
|
2
|
+
|
|
3
|
+
Le module `deploy` permet de déployer des plugins, extensions (services), fichiers de configuration (.env, certificats…) et le fichier `integration.yaml` vers des serveurs distants via SSH/SFTP. Il supporte les sources **locales** et les **repos GitHub** (publics et privés), avec un système de hooks pre/post.
|
|
4
|
+
|
|
5
|
+
## Quickstart
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 1. Scan automatique du projet (détecte plugins, extensions, integration.yaml)
|
|
9
|
+
xcli deploy generate
|
|
10
|
+
|
|
11
|
+
# 2. Éditer xcore-deploy.yaml (targets, tweaks)
|
|
12
|
+
|
|
13
|
+
# 3. Simuler sans rien envoyer
|
|
14
|
+
xcli deploy run production --dry-run
|
|
15
|
+
|
|
16
|
+
# 4. Déployer
|
|
17
|
+
xcli deploy run production
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Structure complète de `xcore-deploy.yaml`
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
version: "1"
|
|
26
|
+
|
|
27
|
+
# ── Serveurs ─────────────────────────────────────────────────────────────────
|
|
28
|
+
targets:
|
|
29
|
+
production:
|
|
30
|
+
host: prod.monapp.com
|
|
31
|
+
port: 22
|
|
32
|
+
user: deploy
|
|
33
|
+
ssh_key: ~/.ssh/id_ed25519
|
|
34
|
+
xcore_url: https://api.monapp.com
|
|
35
|
+
xcore_token: "${XCORE_ADMIN_TOKEN}"
|
|
36
|
+
plugins_root: /opt/xcore/app/plugins
|
|
37
|
+
extensions_root: /opt/xcore/app/extensions
|
|
38
|
+
|
|
39
|
+
staging:
|
|
40
|
+
host: staging.monapp.com
|
|
41
|
+
user: deploy
|
|
42
|
+
ssh_key: ~/.ssh/id_ed25519
|
|
43
|
+
xcore_url: https://staging.monapp.com
|
|
44
|
+
xcore_token: "${XCORE_STAGING_TOKEN}"
|
|
45
|
+
plugins_root: /opt/xcore/app/plugins
|
|
46
|
+
|
|
47
|
+
# ── Hooks globaux ─────────────────────────────────────────────────────────────
|
|
48
|
+
hooks:
|
|
49
|
+
pre_deploy:
|
|
50
|
+
- cmd: "uv run xcli plugin security validate --save"
|
|
51
|
+
- cmd: "uv run pytest tests/ -x -q"
|
|
52
|
+
ignore_errors: false
|
|
53
|
+
|
|
54
|
+
post_deploy:
|
|
55
|
+
- cmd: "uv run xcli deploy status production"
|
|
56
|
+
ignore_errors: true
|
|
57
|
+
|
|
58
|
+
# ── Config XCore (integration.yaml) ──────────────────────────────────────────
|
|
59
|
+
integration:
|
|
60
|
+
source: ./integration.yaml
|
|
61
|
+
remote_path: /opt/xcore/integration.yaml
|
|
62
|
+
restart_xcore: true
|
|
63
|
+
|
|
64
|
+
# ── Fichiers (config, .env, certificats) ──────────────────────────────────────
|
|
65
|
+
# Copiés vers le serveur avant les extensions et plugins.
|
|
66
|
+
files:
|
|
67
|
+
- source: ./.env
|
|
68
|
+
dest: /opt/xcore/.env
|
|
69
|
+
# only: [production]
|
|
70
|
+
|
|
71
|
+
- source: ./conf/private.pem
|
|
72
|
+
dest: /opt/xcore/conf/private.pem
|
|
73
|
+
only: [production]
|
|
74
|
+
|
|
75
|
+
- source: ./conf/public.pem
|
|
76
|
+
dest: /opt/xcore/conf/public.pem
|
|
77
|
+
|
|
78
|
+
# ── Extensions (services) ─────────────────────────────────────────────────────
|
|
79
|
+
extensions:
|
|
80
|
+
- name: mail
|
|
81
|
+
source: ./extensions/mail
|
|
82
|
+
restart: true
|
|
83
|
+
only: [production]
|
|
84
|
+
|
|
85
|
+
- name: pubsub
|
|
86
|
+
repo: https://github.com/org/xcore-pubsub
|
|
87
|
+
ref: v1.0.0
|
|
88
|
+
restart: true
|
|
89
|
+
|
|
90
|
+
# ── Plugins ───────────────────────────────────────────────────────────────────
|
|
91
|
+
plugins:
|
|
92
|
+
- name: auth
|
|
93
|
+
source: ./app/auth
|
|
94
|
+
sign: true
|
|
95
|
+
reload: true
|
|
96
|
+
|
|
97
|
+
- name: billing
|
|
98
|
+
repo: https://github.com/org/billing-plugin
|
|
99
|
+
ref: main
|
|
100
|
+
sign: true
|
|
101
|
+
reload: true
|
|
102
|
+
|
|
103
|
+
- name: pdf-generator
|
|
104
|
+
source: ./app/pdf-generator
|
|
105
|
+
reload: true
|
|
106
|
+
only: [production]
|
|
107
|
+
hooks:
|
|
108
|
+
pre_deploy:
|
|
109
|
+
- cmd: "uv run xcli plugin security validate ./app/pdf-generator"
|
|
110
|
+
post_deploy:
|
|
111
|
+
- cmd: "echo 'pdf-generator déployé'"
|
|
112
|
+
ignore_errors: true
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Section `files:` — Copie de fichiers
|
|
118
|
+
|
|
119
|
+
Les fichiers déclarés dans `files:` sont copiés vers le serveur **avant** les extensions et plugins. Utile pour `.env`, certificats, fichiers de config, etc.
|
|
120
|
+
|
|
121
|
+
```yaml
|
|
122
|
+
files:
|
|
123
|
+
- source: ./.env
|
|
124
|
+
dest: /opt/xcore/.env
|
|
125
|
+
- source: ./conf/private.pem
|
|
126
|
+
dest: /opt/xcore/conf/private.pem
|
|
127
|
+
only: [production]
|
|
128
|
+
- source: ./config/prod.yaml
|
|
129
|
+
dest: /opt/xcore/config/prod.yaml
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
| Champ | Description |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `source` | Chemin local du fichier (relatif à la racine du projet) |
|
|
135
|
+
| `dest` | Chemin distant de destination |
|
|
136
|
+
| `only` | (optionnel) Restreindre à certains targets |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Sources : local vs GitHub
|
|
141
|
+
|
|
142
|
+
Chaque plugin et extension accepte soit `source:` (chemin local), soit `repo:` (dépôt Git).
|
|
143
|
+
|
|
144
|
+
### Source locale
|
|
145
|
+
|
|
146
|
+
```yaml
|
|
147
|
+
plugins:
|
|
148
|
+
- name: mon-plugin
|
|
149
|
+
source: ./app/mon-plugin
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### GitHub — repo public
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
plugins:
|
|
156
|
+
- name: mon-plugin
|
|
157
|
+
repo: https://github.com/org/mon-plugin
|
|
158
|
+
ref: v2.1.0
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### GitHub — repo privé via token
|
|
162
|
+
|
|
163
|
+
```yaml
|
|
164
|
+
plugins:
|
|
165
|
+
- name: mon-plugin
|
|
166
|
+
repo: https://github.com/org/mon-plugin-prive
|
|
167
|
+
ref: main
|
|
168
|
+
token: "${GITHUB_TOKEN}"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### GitHub — repo privé via SSH
|
|
172
|
+
|
|
173
|
+
```yaml
|
|
174
|
+
plugins:
|
|
175
|
+
- name: mon-plugin
|
|
176
|
+
repo: git@github.com:org/mon-plugin-prive.git
|
|
177
|
+
ref: main
|
|
178
|
+
# utilise ssh_key du target
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Plugin dans un sous-dossier du repo
|
|
182
|
+
|
|
183
|
+
```yaml
|
|
184
|
+
plugins:
|
|
185
|
+
- name: mon-plugin
|
|
186
|
+
repo: https://github.com/org/monorepo
|
|
187
|
+
ref: main
|
|
188
|
+
subdirectory: packages/mon-plugin
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
!!! note "Clone automatique"
|
|
192
|
+
xcli fait un `git clone --depth 1 --branch <ref>` dans un dossier temporaire, puis emballe et transfère le code. Le clone est supprimé après le déploiement.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Variables d'environnement
|
|
197
|
+
|
|
198
|
+
Les valeurs `${VAR}` ou `{VAR}` dans le YAML sont interpolées depuis l'environnement système.
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
export XCORE_ADMIN_TOKEN="mon-token-secret"
|
|
202
|
+
export XCORE_STAGING_TOKEN="staging-token"
|
|
203
|
+
export GITHUB_TOKEN="ghp_..."
|
|
204
|
+
export PROD_HOST="prod.monapp.com"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Ordre d'exécution complet
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
hooks.pre_deploy (global)
|
|
213
|
+
│
|
|
214
|
+
├─ integration.yaml (si défini)
|
|
215
|
+
│ → sftp integration.yaml
|
|
216
|
+
│ → POST /config/reload (ou restart service)
|
|
217
|
+
│
|
|
218
|
+
├─ Fichiers (section files:)
|
|
219
|
+
│ → sftp chaque fichier
|
|
220
|
+
│
|
|
221
|
+
├─ Pour chaque extension :
|
|
222
|
+
│ extension.hooks.pre_deploy
|
|
223
|
+
│ → archive tar.gz
|
|
224
|
+
│ → sftp + extraction
|
|
225
|
+
│ → POST /services/{name}/restart
|
|
226
|
+
│ extension.hooks.post_deploy
|
|
227
|
+
│
|
|
228
|
+
├─ Pour chaque plugin :
|
|
229
|
+
│ plugin.hooks.pre_deploy
|
|
230
|
+
│ → signature HMAC (si sign: true)
|
|
231
|
+
│ → archive tar.gz
|
|
232
|
+
│ → sftp + extraction
|
|
233
|
+
│ → POST /plugins/{name}/reload
|
|
234
|
+
│ plugin.hooks.post_deploy
|
|
235
|
+
│
|
|
236
|
+
hooks.post_deploy (global)
|
|
237
|
+
└─ Rapport tableau final
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Hooks
|
|
243
|
+
|
|
244
|
+
### Niveau global
|
|
245
|
+
|
|
246
|
+
Définis sous `hooks:` à la racine.
|
|
247
|
+
|
|
248
|
+
| Moment | Quand |
|
|
249
|
+
|---|---|
|
|
250
|
+
| `hooks.pre_deploy` | Avant integration.yaml, fichiers, extensions et plugins |
|
|
251
|
+
| `hooks.post_deploy` | Après tous les plugins |
|
|
252
|
+
|
|
253
|
+
### Niveau plugin / extension
|
|
254
|
+
|
|
255
|
+
Définis sous `plugins[].hooks` ou `extensions[].hooks`.
|
|
256
|
+
|
|
257
|
+
| Moment | Quand |
|
|
258
|
+
|---|---|
|
|
259
|
+
| `pre_deploy` | Avant l'archivage |
|
|
260
|
+
| `post_deploy` | Après le hot-reload / restart |
|
|
261
|
+
|
|
262
|
+
### Options d'un hook
|
|
263
|
+
|
|
264
|
+
```yaml
|
|
265
|
+
hooks:
|
|
266
|
+
pre_deploy:
|
|
267
|
+
- cmd: "ma-commande --option valeur"
|
|
268
|
+
cwd: "./sous-dossier" # répertoire d'exécution (défaut : racine projet)
|
|
269
|
+
ignore_errors: true # continue même si exit code != 0 (défaut : false)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
!!! warning "Hooks bloquants"
|
|
273
|
+
Par défaut (`ignore_errors: false`), un hook qui échoue **annule le déploiement**. Utilise `ignore_errors: true` pour les commandes non-critiques (notifications, rapports...).
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Commandes
|
|
278
|
+
|
|
279
|
+
### `xcli deploy generate`
|
|
280
|
+
|
|
281
|
+
Scanne le projet et génère `xcore-deploy.yaml` automatiquement.
|
|
282
|
+
|
|
283
|
+
Détecte les plugins (dossiers avec `plugin.yaml`), les extensions (`__init__.py`) et `integration.yaml`. Si le fichier existe déjà, les **targets et hooks sont conservés**.
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
xcli deploy generate
|
|
287
|
+
xcli deploy generate --output deploy/prod.yaml
|
|
288
|
+
xcli deploy generate --plugins-dir ./custom-plugins --dry-run
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
| Option | Description |
|
|
292
|
+
|---|---|
|
|
293
|
+
| `--output`, `-o` | Fichier de sortie (défaut: `xcore-deploy.yaml`) |
|
|
294
|
+
| `--plugins-dir`, `-p` | Répertoire des plugins (défaut: `./app`) |
|
|
295
|
+
| `--extensions-dir`, `-e` | Répertoire des extensions (défaut: `./extensions`) |
|
|
296
|
+
| `--dry-run` | Affiche le résultat sans écrire le fichier |
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
### `xcli deploy init`
|
|
301
|
+
|
|
302
|
+
Génère un fichier `xcore-deploy.yaml` d'exemple complet.
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
xcli deploy init
|
|
306
|
+
xcli deploy init --output deploy/prod.yaml
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### `xcli deploy list`
|
|
312
|
+
|
|
313
|
+
Liste les targets, plugins, extensions, fichiers et hooks déclarés.
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
xcli deploy list
|
|
317
|
+
xcli deploy list --file deploy/prod.yaml
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### `xcli deploy run <target>`
|
|
323
|
+
|
|
324
|
+
Déploie l'intégralité (integration.yaml + fichiers + extensions + plugins) vers un target.
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
xcli deploy run production
|
|
328
|
+
xcli deploy run staging
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Options :**
|
|
332
|
+
|
|
333
|
+
| Option | Description |
|
|
334
|
+
|---|---|
|
|
335
|
+
| `--plugin <nom>` | Déploie **uniquement** ce plugin (skip extensions, fichiers et integration) |
|
|
336
|
+
| `--dry-run` | Simule sans envoyer ni exécuter de commandes réelles |
|
|
337
|
+
| `--no-reload` | Transfère les fichiers sans déclencher reload/restart |
|
|
338
|
+
| `--file <chemin>` | Fichier de configuration alternatif |
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
# Déployer un seul plugin (skip extensions + fichiers + integration)
|
|
342
|
+
xcli deploy run production --plugin auth
|
|
343
|
+
|
|
344
|
+
# Simuler le déploiement complet
|
|
345
|
+
xcli deploy run production --dry-run
|
|
346
|
+
|
|
347
|
+
# Transférer sans redémarrer
|
|
348
|
+
xcli deploy run production --no-reload
|
|
349
|
+
|
|
350
|
+
# Fichier alternatif
|
|
351
|
+
xcli deploy run production --file deploy/prod.yaml
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
### `xcli deploy copy <target> <source> <dest>`
|
|
357
|
+
|
|
358
|
+
Copie un fichier vers un serveur distant via SFTP (sans passer par le déploiement complet).
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
xcli deploy copy production .env /opt/xcore/.env
|
|
362
|
+
xcli deploy copy staging config.yaml /opt/xcore/config.yaml --dry-run
|
|
363
|
+
xcli deploy copy production docker-compose.yml /opt/xcore/ --file deploy/prod.yaml
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
### `xcli deploy status <target>`
|
|
369
|
+
|
|
370
|
+
Affiche l'état des plugins sur le serveur via l'API XCore.
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
xcli deploy status production
|
|
374
|
+
xcli deploy status staging --file deploy/prod.yaml
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Dépendances requises
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
pip install paramiko # SSH/SFTP
|
|
383
|
+
pip install httpx # Appels API XCore (reload/restart)
|
|
384
|
+
# git doit être disponible dans le PATH pour les sources repo
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## Exemples de hooks courants
|
|
390
|
+
|
|
391
|
+
```yaml
|
|
392
|
+
hooks:
|
|
393
|
+
pre_deploy:
|
|
394
|
+
- cmd: "uv run xcli plugin security validate --save"
|
|
395
|
+
- cmd: "uv run xcli plugin security validate --check-breaking"
|
|
396
|
+
- cmd: "uv run pytest tests/ -x -q"
|
|
397
|
+
ignore_errors: false
|
|
398
|
+
|
|
399
|
+
post_deploy:
|
|
400
|
+
- cmd: "uv run xcli deploy status production"
|
|
401
|
+
- cmd: >
|
|
402
|
+
curl -s -X POST https://hooks.slack.com/services/XXX
|
|
403
|
+
-H 'Content-type: application/json'
|
|
404
|
+
-d '{"text": "✅ Déploiement production terminé"}'
|
|
405
|
+
ignore_errors: true
|
|
406
|
+
```
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
- **Project Initialization**: Seamlessly scaffold new projects and manage `integration.yaml`.
|
|
11
11
|
- **Plugin Lifecycle**: Full control over installing, signing, and updating plugins.
|
|
12
|
+
- **Production Deploy**: Deploy plugins to remote servers via SSH with pre/post hooks.
|
|
12
13
|
- **Real-time Monitoring**: Integrated dashboard for service health and resource usage.
|
|
13
14
|
- **Worker Orchestration**: Manage Celery/XWorker processes with ease.
|
|
14
15
|
- **Security & Sandboxing**: Resource isolation and AST-based whitelisting for plugins.
|
|
@@ -29,4 +30,5 @@ make install
|
|
|
29
30
|
|
|
30
31
|
- [Installation Guide](getting-started/install.md)
|
|
31
32
|
- [Authentication Setup](getting-started/auth.md)
|
|
33
|
+
- [Deploy to Production](deploy/index.md)
|
|
32
34
|
- [Core Commands Reference](reference.md)
|
|
@@ -21,6 +21,35 @@ A comprehensive list of all commands available in `xcorecli`.
|
|
|
21
21
|
- `manager services reload`: Reconnect a service.
|
|
22
22
|
- `manager services unload`: Shutdown a service.
|
|
23
23
|
|
|
24
|
+
## `deploy` Production Deployment
|
|
25
|
+
|
|
26
|
+
- `deploy init`: Generate a `xcore-deploy.yaml` template file.
|
|
27
|
+
- `deploy list`: Show targets, plugins, extensions, and hooks declared in the config.
|
|
28
|
+
- `deploy <target>`: Deploy integration.yaml + extensions + plugins to a remote server.
|
|
29
|
+
- `deploy status <target>`: Show plugin state on a remote server via the XCore API.
|
|
30
|
+
|
|
31
|
+
**Key options for `deploy <target>`:**
|
|
32
|
+
|
|
33
|
+
| Option | Description |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `--plugin <name>` | Deploy only one plugin (skips extensions + integration) |
|
|
36
|
+
| `--dry-run` | Simulate without sending anything |
|
|
37
|
+
| `--no-reload` | Transfer files without triggering reload/restart |
|
|
38
|
+
| `--file <path>` | Use an alternate config file |
|
|
39
|
+
|
|
40
|
+
**Deploy order:** `integration.yaml` → extensions (services) → plugins
|
|
41
|
+
|
|
42
|
+
**Sources:** each plugin/extension accepts `source: ./local/path` OR `repo: https://github.com/org/repo` (public), with optional `token: "${GITHUB_TOKEN}"` for private repos or `git@github.com:...` SSH URLs.
|
|
43
|
+
|
|
44
|
+
**Hook levels:**
|
|
45
|
+
|
|
46
|
+
| Level | Keys | When |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| Global | `hooks.pre_deploy` / `hooks.post_deploy` | Once per full deploy run |
|
|
49
|
+
| Per-plugin/extension | `hooks.pre_deploy` / `post_deploy` | Before/after each item |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
24
53
|
## `plugin` Lifecycle
|
|
25
54
|
|
|
26
55
|
- `plugin info`: Detailed local plugin report.
|
|
@@ -17,6 +17,19 @@ if TYPE_CHECKING:
|
|
|
17
17
|
console = Console()
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
def _require_xcore() -> None:
|
|
21
|
+
"""Raise a clean error if xcore is not installed in the current environment."""
|
|
22
|
+
try:
|
|
23
|
+
import xcore # noqa: F401
|
|
24
|
+
except ImportError as exc:
|
|
25
|
+
console.print(
|
|
26
|
+
"[red]xcore is not installed.[/red]\n"
|
|
27
|
+
"Run: [cyan]pip install xcore[/cyan]\n"
|
|
28
|
+
"[dim]Or install in your project: pip install -r requirements.txt[/dim]"
|
|
29
|
+
)
|
|
30
|
+
raise SystemExit(1) from exc
|
|
31
|
+
|
|
32
|
+
|
|
20
33
|
def _require_config() -> 'Path':
|
|
21
34
|
path = find_config_path(required=True)
|
|
22
35
|
assert path is not None
|
|
@@ -29,6 +42,7 @@ def load_raw_config() -> dict:
|
|
|
29
42
|
|
|
30
43
|
async def boot() -> 'Xcore':
|
|
31
44
|
"""Boot xcore in standalone mode (no FastAPI). Reads integration.yaml automatically."""
|
|
45
|
+
_require_xcore()
|
|
32
46
|
from xcore import Xcore
|
|
33
47
|
|
|
34
48
|
_require_config()
|