Release script multi-instances (cloudyfy + farewell), remotes et docs §16

- scripts/gitea-release.py : argument d'instance (URL/owner/trousseau par hôte),
  usage inchangé sinon ; tokens par instance dans le trousseau macOS
- remotes : origin (cloudyfy, HTTPS) + farewell (SSH, alias giteassh:2222)
- docs §16/§16.bis : deux remotes, scopes des tokens, commande d'ajout au
  trousseau pour farewell
This commit is contained in:
Siphonight 2026-09-05 20:21:35 +02:00
parent f57ab5f99f
commit 4210e5b21e
2 changed files with 63 additions and 22 deletions

View File

@ -680,18 +680,22 @@ cd ~/projects/HormoneTrack
adb install -r app/build/outputs/apk/debug/app-debug.apk adb install -r app/build/outputs/apk/debug/app-debug.apk
``` ```
**Git (initialisé le 2026-09-05, branche `main`, remote Gitea)** : **Git (initialisé le 2026-09-05, branche `main`, DEUX remotes Gitea)** :
- Dépôt : `https://gitea.cloudyfy.fr/Siphonight/HormoneTrack` (privé) ; - `origin` → `https://gitea.cloudyfy.fr/Siphonight/HormoneTrack` (privé, HTTPS + trousseau)
- `farewell` → `git@farewell:Siphonight/HormoneTrack.git` (SSH, alias `farewell`
= `giteassh.farewell.dev:2222` avec clé dédiée, cf `~/.ssh/config`)
- Historique = commits logiques par couche (toolchain / moteur / UI / docs) ; - Historique = commits logiques par couche (toolchain / moteur / UI / docs) ;
- **Chaque release = tag annoté** (`v1.1.0`, `v1.2.0`, …) : - **Chaque release = tag annoté** (`v1.1.0`, `v1.2.0`, …) :
`git tag -a vX.Y.Z -m "…" && git tag` pour lister ; `git tag -a vX.Y.Z -m "…" && git tag` pour lister ;
- `local.properties`, `build/`, `.gradle/`, `.idea/`, **`local-test-data/`** sont - `local.properties`, `build/`, `.gradle/`, `.idea/`, **`local-test-data/`** sont
ignorés (`.gitignore`) — ce dernier protège les données de santé de test ; ignorés (`.gitignore`) — ce dernier protège les données de santé de test ;
- Avant chaque commit de release : `./gradlew testDebugUnitTest` doit être vert ; - Avant chaque commit de release : `./gradlew testDebugUnitTest` doit être vert ;
- Push : `git push -u origin main --tags` (auth par trousseau macOS — token Gitea - Push : `git push origin main --tags` + `git push farewell main --tags`
à scope `write:repository` ; ⚠️ un token SANS `write:user` ne permet PAS de (farewell : auth SSH par clé `siphonight@penguin` ; le push-to-create y est
créer un repo via API ni d'utiliser push-to-create, mais suffit pour push, DÉSACTIVÉ → le repo doit exister au préalable sur l'instance).
créer des releases et y attacher des fichiers). ⚠️ Tokens Gitea : scope `write:repository` suffit pour push, releases et
assets ; il NE permet PAS de créer un repo via API (il faut `write:user`)
ni d'utiliser push-to-create.
### 16.bis Releases Gitea avec APK téléchargeable ### 16.bis Releases Gitea avec APK téléchargeable
@ -699,7 +703,8 @@ Les releases Gitea embarquent l'APK de chaque version — les utilisateurs n'ont
besoin de compiler. **Le corps de chaque release = la section CHANGELOG de la besoin de compiler. **Le corps de chaque release = la section CHANGELOG de la
version** (markdown rendu par Gitea), extrait automatiquement. version** (markdown rendu par Gitea), extrait automatiquement.
Le tout est automatisé par `scripts/gitea-release.py` : Le tout est automatisé par `scripts/gitea-release.py` — **multi-instances**
(`cloudyfy` par défaut, `farewell`) :
```bash ```bash
# 1. Construire l'APK au niveau du tag # 1. Construire l'APK au niveau du tag
@ -707,10 +712,17 @@ git checkout vX.Y.Z && ./gradlew assembleDebug
cp app/build/outputs/apk/debug/app-debug.apk /tmp/apks/HormoneTrack-vX.Y.Z.apk cp app/build/outputs/apk/debug/app-debug.apk /tmp/apks/HormoneTrack-vX.Y.Z.apk
git checkout main git checkout main
# 2. Créer (ou mettre à jour) la release : corps = CHANGELOG + APK attaché # 2. Publier sur chaque instance (corps = CHANGELOG + APK attaché)
python3 scripts/gitea-release.py vX.Y.Z /tmp/apks/HormoneTrack-vX.Y.Z.apk python3 scripts/gitea-release.py cloudyfy vX.Y.Z /tmp/apks/HormoneTrack-vX.Y.Z.apk
python3 scripts/gitea-release.py farewell vX.Y.Z /tmp/apks/HormoneTrack-vX.Y.Z.apk
# sans APK : python3 scripts/gitea-release.py farewell vX.Y.Z (corps seul)
``` ```
Le script choisit l'instance (URL, owner) et lit le token Gitea correspondant
dans le trousseau macOS (`security find-internet-password -s <hôte> -w`) :
`gitea.cloudyfy.fr` ✓ présent ; `gitea.farewell.dev` → à ajouter :
`security add-internet-password -s gitea.farewell.dev -a Siphonight -w <TOKEN> -U`.
Le script : Le script :
- extrait la section `## [X.Y.Z]` de `docs/CHANGELOG.md` comme corps ; - extrait la section `## [X.Y.Z]` de `docs/CHANGELOG.md` comme corps ;
⚠️ piège : le tag git porte le « v » (`v1.2.3`) mais la CHANGELOG non ⚠️ piège : le tag git porte le « v » (`v1.2.3`) mais la CHANGELOG non

View File

@ -1,10 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Publie/met à jour une release Gitea : corps = section CHANGELOG de la version, """Publie/met à jour une release Gitea : corps = section CHANGELOG de la version,
APK en pièce jointe (optionnel). Réutilisable à chaque release. APK en pièce jointe (optionnel). Réutilisable à chaque release, multi-instances.
Usage : Usage :
python3 scripts/gitea-release.py v1.2.3 [chemin/vers/app.apk] python3 scripts/gitea-release.py [instance] vX.Y.Z [chemin/vers/app.apk]
- instance : « cloudyfy » (défaut) ou « farewell » — voir INSTANCES ci-dessous ;
- le corps est extrait de docs/CHANGELOG.md (section « ## [X.Y.Z] », SANS « v » - le corps est extrait de docs/CHANGELOG.md (section « ## [X.Y.Z] », SANS « v »
— le tag git porte le « v », la CHANGELOG non : piège corrigé, cf §16.bis) ; — le tag git porte le « v », la CHANGELOG non : piège corrigé, cf §16.bis) ;
- si la release existe déjà, son corps est mis à jour (PATCH) ; - si la release existe déjà, son corps est mis à jour (PATCH) ;
@ -12,8 +13,11 @@ Usage :
est remplacé). est remplacé).
Auth : le token Gitea est lu dans le trousseau macOS Auth : le token Gitea est lu dans le trousseau macOS
(security find-internet-password -s gitea.cloudyfy.fr -w) — scope requis : (security find-internet-password -s <hôte> -w) — scope requis :
write:repository (suffit pour releases + assets, pas pour créer un repo). write:repository (suffit pour releases + assets, pas pour créer un repo).
Pour ajouter un token au trousseau :
security add-internet-password -s gitea.farewell.dev -a Siphonight \
-w <TOKEN> -U
""" """
import json import json
import re import re
@ -22,18 +26,28 @@ import sys
import urllib.error import urllib.error
import urllib.request import urllib.request
GITEA = "https://gitea.cloudyfy.fr" # Instances connues : clé = nom court, hôte = service du trousseau
OWNER, REPO = "Siphonight", "HormoneTrack" INSTANCES = {
"cloudyfy": {"url": "https://gitea.cloudyfy.fr", "owner": "Siphonight",
"host": "gitea.cloudyfy.fr"},
"farewell": {"url": "https://gitea.farewell.dev", "owner": "Siphonight",
"host": "gitea.farewell.dev"},
}
CHANGELOG = "docs/CHANGELOG.md" CHANGELOG = "docs/CHANGELOG.md"
def gitea_token() -> str: def gitea_token(host: str) -> str:
out = subprocess.run( out = subprocess.run(
["security", "find-internet-password", "-s", "gitea.cloudyfy.fr", "-w"], ["security", "find-internet-password", "-s", host, "-w"],
capture_output=True, text=True capture_output=True, text=True
).stdout.strip() ).stdout.strip()
if not out: if not out:
sys.exit("Token Gitea introuvable dans le trousseau macOS") sys.exit(
f"Token Gitea introuvable dans le trousseau pour {host}\n"
f" Ajoute-le avec : security add-internet-password -s {host} "
f"-a Siphonight -w <TOKEN> -U"
)
return out return out
@ -68,10 +82,21 @@ def changelog_section(version: str) -> str:
def main(): def main():
tag = sys.argv[1] if len(sys.argv) > 1 else sys.exit("Usage: gitea-release.py vX.Y.Z [app.apk]") args = sys.argv[1:]
apk_path = sys.argv[2] if len(sys.argv) > 2 else None # Premier argument = instance s'il n'est pas un tag (un tag commence par « v »)
token = gitea_token() instance = "cloudyfy"
base = f"{GITEA}/api/v1/repos/{OWNER}/{REPO}" if args and not args[0].startswith("v"):
instance = args.pop(0)
if instance not in INSTANCES:
sys.exit(f"Instance inconnue : {instance} (attendu : {', '.join(INSTANCES)})")
if not args:
sys.exit(f"Usage: gitea-release.py [{instance}] vX.Y.Z [app.apk]")
tag = args[0]
apk_path = args[1] if len(args) > 1 else None
conf = INSTANCES[instance]
base = f"{conf['url']}/api/v1/repos/{conf['owner']}/{REPO_NAME}"
token = gitea_token(conf["host"])
body = changelog_section(tag) body = changelog_section(tag)
# Récupère la release du tag (crée-la si absente) # Récupère la release du tag (crée-la si absente)
@ -112,8 +137,12 @@ def main():
link = "—" link = "—"
action = "créée" if created else "mise à jour" action = "créée" if created else "mise à jour"
print(f"Release {tag} {action} (id {release_id}) — corps {len(body)} caractères, APK : {link}") print(f"[{instance}] Release {tag} {action} (id {release_id}) — "
f"corps {len(body)} caractères, APK : {link}")
# Nom du dépôt (identique sur les deux instances)
REPO_NAME = "HormoneTrack"
if __name__ == "__main__": if __name__ == "__main__":
main() main()