283 lines
11 KiB
Markdown
283 lines
11 KiB
Markdown
# Guide de Développement, Build Local & Publication des Releases Gitea — ObsiGate
|
|
|
|
Ce guide décrit la procédure pas-à-pas pour **tester**, **compiler localement** l'application Desktop (Windows et Linux), **effectuer les commits & pushs**, puis **publier les binaires** sur la section **Releases / Publications** de Gitea (`https://git.dracodev.net/Projets/ObsiGate/releases`).
|
|
|
|
---
|
|
|
|
## 1. Tests et Prévisualisation Locale
|
|
|
|
### A. Backend & Frontend (Tests unitaires & Linting)
|
|
```powershell
|
|
# Tests backend Python (FastAPI)
|
|
.\.venv\Scripts\python.exe -m pytest tests/
|
|
|
|
# Linting backend (ruff & mypy)
|
|
.\.venv\Scripts\python.exe -m ruff check backend/
|
|
.\.venv\Scripts\python.exe -m mypy backend/ --ignore-missing-imports
|
|
|
|
# Validation & tests unitaires frontend
|
|
node tests/frontend/validate-imports.mjs
|
|
node tests/frontend/unit.test.mjs
|
|
```
|
|
|
|
### B. Mode Développement Desktop (Tauri 2 Live Preview)
|
|
Pour développer l'application desktop avec rechargement à chaud (Hot Reload) :
|
|
```powershell
|
|
cd desktop
|
|
cargo tauri dev
|
|
```
|
|
*Le backend Python et l'interface WebView Tauri démarreront automatiquement sur `http://127.0.0.1:17890`.*
|
|
|
|
---
|
|
|
|
## 2. Compilation Locale de l'Application Desktop
|
|
|
|
### A. Windows (Installeur `.exe` NSIS et Paquet `.msi`)
|
|
1. Ouvrez un terminal PowerShell ou CMD sur votre machine Windows.
|
|
2. Déplacez-vous dans le dossier `desktop/` et exécutez le script :
|
|
```powershell
|
|
cd desktop
|
|
.\build-windows.bat
|
|
```
|
|
3. **Binaires générés dans** `desktop/target/x86_64-pc-windows-msvc/release/bundle/` :
|
|
- `ObsiGate_x.y.z_x64-setup.exe` (Installeur utilisateur NSIS)
|
|
- `ObsiGate_x.y.z_x64_en-US.msi` (Paquet d'installation MSI)
|
|
|
|
### B. Linux (Exécutable `.AppImage` et Paquet `.deb`)
|
|
1. Ouvrez un terminal Bash (Machine Linux ou WSL2 / Conteneur Docker).
|
|
2. Déplacez-vous dans le dossier `desktop/` et exécutez le script :
|
|
```bash
|
|
cd desktop
|
|
chmod +x build-linux.sh
|
|
./build-linux.sh
|
|
```
|
|
3. **Binaires générés dans** `desktop/target/x86_64-unknown-linux-gnu/release/bundle/` :
|
|
- `ObsiGate_x.y.z_amd64.AppImage` (Exécutable portable Linux)
|
|
- `obsigate_x.y.z_amd64.deb` (Paquet Debian/Ubuntu)
|
|
|
|
---
|
|
|
|
## 2bis. Signature des mises à jour (updater Tauri)
|
|
|
|
La signature de l'auto-update Tauri est **indépendante** de la signature de code
|
|
Windows et **gratuite**. Elle garantit qu'une mise à jour téléchargée provient bien
|
|
de vous. Elle repose sur une paire de clés `minisign` :
|
|
|
|
- La **clé publique** est embarquée dans `desktop/tauri.conf.json`
|
|
(`plugins.updater.pubkey`).
|
|
- La **clé privée** signe les artefacts au build. Elle ne doit **jamais** être
|
|
commitée (ignorée par `.gitignore`).
|
|
|
|
### A. Générer la paire de clés (une seule fois)
|
|
|
|
```bash
|
|
cd desktop
|
|
cargo tauri signer generate -w obsigate-updater.key
|
|
# La clé publique s'affiche et est écrite dans obsigate-updater.key.pub
|
|
```
|
|
|
|
> ⚠️ Conservez la clé privée en lieu sûr (gestionnaire de secrets). Si vous la
|
|
> perdez, les mises à jour ne pourront plus être signées. Pour la protéger par mot
|
|
> de passe : ajoutez `-p "<mot de passe>"`.
|
|
|
|
Copiez le contenu de `obsigate-updater.key.pub` dans
|
|
`desktop/tauri.conf.json` → `plugins.updater.pubkey`.
|
|
|
|
### B. Build local signé
|
|
|
|
```powershell
|
|
# Windows PowerShell
|
|
$env:TAURI_SIGNING_PRIVATE_KEY = Get-Content -Raw .\obsigate-updater.key
|
|
# $env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD = "<mot de passe>" # si la clé en a un
|
|
cargo tauri build --bundles nsis,msi
|
|
```
|
|
|
|
```bash
|
|
# Linux / Bash
|
|
export TAURI_SIGNING_PRIVATE_KEY="$(cat obsigate-updater.key)"
|
|
# export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="<mot de passe>"
|
|
cargo tauri build --bundles appimage,deb
|
|
```
|
|
|
|
Le CLI produit des fichiers `.sig` à côté de chaque artefact
|
|
(`*.exe.sig`, `*.msi.sig`, `*.AppImage.sig`, `*.deb.sig`).
|
|
|
|
> Sans clé définie, `createUpdaterArtifacts` est actif et le build échoue : dans
|
|
> le CI, l'étape désactive automatiquement les artefacts de mise à jour si le
|
|
> secret est absent.
|
|
|
|
### C. Secrets CI (Gitea)
|
|
|
|
Dans **Dépôt → Paramètres → Actions → Secrets**, créez :
|
|
|
|
| Secret | Valeur |
|
|
|---|---|
|
|
| `TAURI_SIGNING_PRIVATE_KEY` | contenu **intégral** du fichier `.key` |
|
|
| `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` | mot de passe de la clé (vide si aucun) |
|
|
|
|
Le workflow `.gitea/workflows/desktop-build.yml` les expose aux étapes de build ;
|
|
les fichiers `.sig` sont uploadés comme artefacts.
|
|
|
|
### D. Manifeste de mise à jour (`latest.json`)
|
|
|
|
Le CLI Tauri génère les `.sig` mais **pas** le manifeste JSON consommé par
|
|
l'updater. Celui-ci est produit par `scripts/updater_manifest.py` :
|
|
|
|
```powershell
|
|
# Windows — après build-windows.bat
|
|
.\.venv\Scripts\python.exe scripts\updater_manifest.py --tag v2.3.0
|
|
```
|
|
|
|
`publish_release.py` l'appelle automatiquement : il écrit `desktop/latest.json`,
|
|
l'ajoute aux assets de la release, et rappelle la dernière étape manuelle.
|
|
|
|
**Flux complet de release :**
|
|
|
|
1. `desktop\build-windows.bat` (build + signature `.sig`) ;
|
|
2. `python scripts\publish_release.py --tag vX.Y.Z` (checksums + `latest.json` + upload) ;
|
|
3. **commit** de `desktop/latest.json` sur `main` puis `git push`.
|
|
|
|
L'endpoint de l'updater (`desktop/tauri.conf.json`) pointe vers ce fichier
|
|
versionné :
|
|
|
|
```
|
|
https://git.dracodev.net/Projets/ObsiGate/raw/branch/main/desktop/latest.json
|
|
```
|
|
|
|
Document produit (URLs construites vers les assets de la release) :
|
|
|
|
```json
|
|
{
|
|
"version": "2.3.0",
|
|
"notes": "…",
|
|
"pub_date": "2026-09-12T00:00:00Z",
|
|
"platforms": {
|
|
"windows-x86_64": { "signature": "<contenu .exe.sig>", "url": "<URL du .exe>" },
|
|
"linux-x86_64": { "signature": "<contenu .AppImage.sig>", "url": "<URL .AppImage>" }
|
|
}
|
|
}
|
|
```
|
|
|
|
> Seules les plateformes dont l'artefact **signé** est présent sont incluses.
|
|
> Sans `desktop/latest.json` à jour sur `main`, l'updater ne détecte aucune
|
|
> mise à jour (la signature, elle, reste opérationnelle).
|
|
|
|
---
|
|
|
|
## 3. Version, Commit & Push
|
|
|
|
### Source unique de vérité : `VERSION`
|
|
|
|
Le fichier **`VERSION`** à la racine du dépôt contient la version livrée au format
|
|
`MAJEUR.MINEUR.CORRECTIF`. C'est la **seule** source : elle est incrémentée à chaque
|
|
commit et tout le reste en découle.
|
|
|
|
| Dérivé | Contenu |
|
|
|---|---|
|
|
| `backend/version.py` | lit `VERSION` (priorité : `OBSIGATE_VERSION` > `./VERSION` > `backend/VERSION` > tag git) et l'expose via `/api/health` |
|
|
| `Dockerfile` | `COPY VERSION ./VERSION` — plus aucun numéro codé en dur dans l'image |
|
|
| `build.sh` / CI | affichent la version lue dans `VERSION` |
|
|
| `desktop/build.rs` | injecte `VERSION` dans `GIT_VERSION` (repli `git describe`) |
|
|
| `package.json`, `desktop/tauri.conf.json`, `desktop/Cargo.{toml,lock}`, `README.md`, `README.fr.md`, `docs/ROADMAP.md`, `CHANGELOG.md` | resynchronisés automatiquement à chaque incrément |
|
|
|
|
### Incrément automatique (hooks git versionnés)
|
|
|
|
`scripts/install-hooks.sh` (une seule fois par clone) pose `core.hooksPath=.githooks`
|
|
et `push.followTags=true`. Ensuite, chaque commit incrémente la version selon son
|
|
message (Conventional Commits) :
|
|
|
|
| Message de commit | Incrément |
|
|
|---|---|
|
|
| `!:` ou `BREAKING CHANGE:` | MAJEUR — `x.0.0` |
|
|
| `feat:` / `feat(scope):` | MINEUR — `x.y.0` |
|
|
| `fix:`, `perf:`, `docs:`, … | CORRECTIF — `x.y.z` |
|
|
|
|
`.githooks/prepare-commit-msg` incrémente `VERSION`, resynchronise les fichiers dérivés
|
|
et publie la section `[Unreleased]` du CHANGELOG en `[X.Y.Z] — date`. `.githooks/post-commit`
|
|
rattache ces fichiers au commit qui vient d'être créé (git fige l'arbre avant
|
|
`prepare-commit-msg` : un `git add` à cet instant ne serait repris qu'au commit suivant —
|
|
d'où un `--amend` immédiat, le commit n'étant pas encore poussé) puis crée le tag `vX.Y.Z`,
|
|
publié automatiquement au push (`push.followTags`). Aucun incrément pour un merge, un
|
|
revert, un `chore(release)` ou un `--amend`.
|
|
|
|
Livraison type :
|
|
|
|
```bash
|
|
git add <chemins explicites> # pas de `git add -A` (test_vault = brouillon utilisateur)
|
|
git commit -m "fix(ai): BUG-047 …" # → VERSION incrémentée + tag vX.Y.Z créé
|
|
git push origin main # → branche + tag publiés
|
|
```
|
|
|
|
Contournement ponctuel (commit sans incrément) : `SKIP_VERSION_BUMP=1 git commit …`.
|
|
|
|
> **SHA affiché vs SHA réel** : l'incrément et les fichiers dérivés sont rattachés au
|
|
> commit par un `--amend` immédiat (le commit n'est pas encore poussé), donc le SHA
|
|
> affiché par `git commit` est remplacé par celui de l'amend — `git log`, `HEAD` et le
|
|
> tag `vX.Y.Z` sont, eux, alignés sur ce dernier. `git push` envoie bien la version finale.
|
|
|
|
### Bump manuel / outillage
|
|
|
|
```bash
|
|
scripts/bump_version.py --print-version # version courante
|
|
scripts/bump_version.py --dry-run # prochaine version, sans rien écrire
|
|
scripts/bump_version.py --minor # incrément forcé + resynchronisation
|
|
scripts/bump_version.py --set 3.0.0 # version imposée
|
|
scripts/bump_version.py --major --commit --tag --push
|
|
scripts/bump_version.sh … # même outil (wrapper historique)
|
|
```
|
|
|
|
> La version desktop doit être synchronisée avec le tag pour que l'updater Tauri
|
|
> détecte les mises à jour (`latest.json` reprend la version de `tauri.conf.json`) :
|
|
> l'incrément automatique s'en charge.
|
|
|
|
|
|
---
|
|
|
|
## 4. Publication des Binaires sur Gitea Releases
|
|
|
|
Un script automatisé (`scripts/publish_release.py`) se charge de téléverser vos binaires compilés localement et de générer l'empreinte cryptographique `checksums.txt` (SHA256).
|
|
|
|
### A. Obtenir un Jeton d'Accès Gitea (Une seule fois)
|
|
1. Connectez-vous sur votre instance Gitea : `https://git.dracodev.net`.
|
|
2. Cliquez sur votre **Profil** $\rightarrow$ **Paramètres** $\rightarrow$ **Applications**.
|
|
3. Dans **Gérer les jetons d'accès personnels**, entrez le nom `ObsiGate-Release` et cochez le jeton avec accès en écriture sur les dépôts (`repo`).
|
|
4. Copiez le jeton généré.
|
|
|
|
### B. Exécution de la Publication
|
|
|
|
**Option 1 — Définir la variable d'environnement (Recommandé) :**
|
|
- **Windows PowerShell** :
|
|
```powershell
|
|
$env:GITEA_TOKEN="votre_jeton_gitea_ici"
|
|
.\.venv\Scripts\python.exe scripts/publish_release.py --tag v2.0.0
|
|
```
|
|
- **Linux / Bash** :
|
|
```bash
|
|
export GITEA_TOKEN="votre_jeton_gitea_ici"
|
|
python3 scripts/publish_release.py --tag v2.0.0
|
|
```
|
|
|
|
**Option 2 — Utiliser l'option `--token` :**
|
|
```powershell
|
|
.\.venv\Scripts\python.exe scripts/publish_release.py --tag v2.0.0 --token "votre_jeton_gitea_ici"
|
|
```
|
|
|
|
**Option 3 — Tester à blanc avec `--dry-run` (Sans modifier Gitea) :**
|
|
```powershell
|
|
.\.venv\Scripts\python.exe scripts/publish_release.py --tag v2.0.0 --dry-run
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Résultat Attendu dans Gitea
|
|
|
|
Une fois le script exécuté, visitez la page [ObsiGate Releases](https://git.dracodev.net/Projets/ObsiGate/releases).
|
|
|
|
Vous y trouverez la section de publication officielle contenant :
|
|
- 📦 `ObsiGate_2.0.0_x64-setup.exe` (Installeur Windows)
|
|
- 📦 `ObsiGate_2.0.0_x64_en-US.msi` (Package MSI Windows)
|
|
- 📦 `ObsiGate_2.0.0_amd64.AppImage` (Executable autonome Linux)
|
|
- 📦 `obsigate_2.0.0_amd64.deb` (Paquet Debian/Ubuntu)
|
|
- 🔐 `checksums.txt` (Empreintes de sécurité SHA-256)
|
|
- 📄 Code source `.zip` / `.tar.gz` (générés automatiquement)
|