From 535f69aa497e1466898b61cd5c4d7ef88b6c0c47 Mon Sep 17 00:00:00 2001 From: Antoine Piron Date: Thu, 11 Jun 2026 19:04:30 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20add=20CLAUDE.md=20with=20project=20over?= =?UTF-8?q?view=20+=20Gitea=E2=86=92GitHub=20CI=20methodology?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9deee01 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,216 @@ +# CLAUDE.md — Postiz Android + +## Projet + +Application Android (React Native / Expo SDK 52) pour piloter une instance [Postiz](https://postiz.com) auto-hébergée. +Pas de compte expo.dev ni EAS cloud — le build APK est 100 % local ou via GitHub Actions. + +--- + +## Structure du dépôt + +``` +Postiz-android/ +├── artifacts/postiz-mobile/ ← app React Native (source de vérité) +│ ├── app/(tabs)/ ← écrans : compose, calendar, posts, settings, notifications +│ ├── components/ ← ChannelChip, MediaLibraryModal, … +│ ├── context/PostizContext.tsx ← état global : workspaces, clients, API +│ ├── hooks/ ← useColors, usePostizQuery, … +│ ├── build-apk.sh ← build signé local (sans EAS) +│ └── install-android-sdk.sh ← setup Android SDK first-time +├── lib/ ← packages partagés (api-spec, api-zod, db, …) +├── .github/workflows/release.yml ← CI GitHub Actions (build APK + GitHub Release) +└── CLAUDE.md ← ce fichier +``` + +--- + +## Screens & fonctionnalités + +| Écran | Description | +|-------|-------------| +| **Compose** | Éditeur de post, sélection de channels par workspace (tap header = tout sélectionner), images, scheduling | +| **Calendar** | Vue mensuelle avec dots colorés par état (indigo=schedulé, vert=publié, rouge=erreur) | +| **Posts** | Liste filtrée (All/Queue/Published/Draft/Error), swipe gauche=supprimer, swipe droite=reprogrammer | +| **Settings** | Gestion multi-workspace : nom, Base URL, API key, test de connexion | +| **Notifications** | Polling toutes les 15 min, alerte locale sur PUBLISHED/ERROR | + +--- + +## Modèle de données clé + +`PostizWorkspace` (dans `PostizContext.tsx`) : +```ts +{ id, name, baseUrl, apiKey } +``` +Stockage : `AsyncStorage` clé `postiz_workspaces_v2`. Migration auto depuis l'ancien format mono-workspace. + +Channels groupés par workspace dans la vue Compose. Tap sur le header workspace = sélection/désélection collective. Sélection individuelle par chip toujours possible. + +--- + +## Commandes utiles + +```bash +# Dev (Expo Go sur l'appareil) +pnpm --filter @workspace/postiz-mobile run dev + +# Build APK signé local +cd artifacts/postiz-mobile +./install-android-sdk.sh # première fois seulement +cp ~/.config/postiz-mobile/signing.env.example ~/.config/postiz-mobile/signing.env +# remplir les credentials keystore dans signing.env +./build-apk.sh # → dist/postiz-mobile-YYYYMMDD-HHMM.apk + +# Déclencher un build + release GitHub +git tag v1.x.y +git push origin v1.x.y # le push mirror Gitea→GitHub déclenche Actions +``` + +--- + +## Secrets GitHub Actions requis + +| Secret | Contenu | +|--------|---------| +| `KEYSTORE_B64` | Keystore `.jks` encodé en base64 | +| `KEYSTORE_ALIAS` | Alias de la clé dans le keystore | +| `KEYSTORE_STORE_PASSWORD` | Mot de passe du keystore | +| `KEYSTORE_KEY_PASSWORD` | Mot de passe de la clé | + +--- + +## Postiz API (endpoints utilisés) + +| Méthode | Endpoint | Usage | +|---------|----------|-------| +| `GET` | `/integrations` | Liste des channels connectés | +| `GET` | `/posts?startDate=&endDate=` | Posts sur une plage de dates | +| `POST` | `/posts` | Créer / programmer un post | +| `DELETE` | `/posts/:id` | Supprimer un post | +| `POST` | `/upload` | Upload image (multipart) | + +--- + +--- + +## Méthodologie CI : Gitea sans runner → push mirror → GitHub Actions + +> Template réutilisable pour tout projet hébergé sur une instance Gitea privée +> sans runner CI, avec build automatisé via GitHub Actions. + +### Principe + +``` +Développement local + ↓ git push + Gitea (privé) ← dépôt principal, pas de runner + ↓ push mirror automatique (configuré dans Gitea) + GitHub (public ou privé) ← miroir en lecture + ↓ tag v*.*.* + GitHub Actions ← CI/CD, build, release +``` + +Gitea joue le rôle de source de vérité et de dépôt privé. +GitHub est un miroir passif qui fournit les runners CI gratuitement. +Aucun runner n'est installé côté Gitea. + +### Configuration du push mirror dans Gitea + +Dans Gitea → Settings → Repository → **Push Mirrors** : +- Mirror URL : `https://github.com/USER/REPO.git` +- Credentials : token GitHub avec scope `repo` +- Synchronisation : à chaque push (immédiat) + +Tous les commits, branches et tags poussés sur Gitea sont automatiquement +répliqués sur GitHub dans les secondes qui suivent. + +### Workflow GitHub Actions type + +`.github/workflows/release.yml` : + +```yaml +name: Release + +on: + push: + tags: + - 'v*.*.*' + +jobs: + build: + # Guard clause : n'exécuter que sur GitHub, pas sur Gitea + # (au cas où Gitea serait un jour équipé d'un runner) + if: github.server_url == 'https://github.com' + runs-on: ubuntu-latest + permissions: + contents: write # nécessaire pour créer une GitHub Release + + steps: + - uses: actions/checkout@v4 + # … étapes de build … + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: dist/*.apk +``` + +**Points clés du workflow :** +- Déclencheur : `push.tags: ['v*.*.*']` — seul un tag au format semver déclenche le build. +- Guard `if: github.server_url == 'https://github.com'` — protection si Gitea obtient un runner à l'avenir. +- `permissions: contents: write` — obligatoire pour `action-gh-release`. +- Les secrets sensibles (keystores, tokens) sont stockés dans GitHub → Settings → Secrets, jamais dans le dépôt. + +### Génération du changelog automatique + +Le workflow extrait les commits `feat:` et `fix:` entre le tag précédent et HEAD : + +```bash +PREV_TAG=$(git tag --sort=-version:refname | grep -v "^${{ github.ref_name }}$" | head -1) + +FEATS=$(git log "${PREV_TAG}..HEAD" --pretty=format:"%s" --no-merges \ + | grep -E "^feat(\([^)]+\))?: " \ + | sed -E 's/^feat(\([^)]+\))?: //' \ + | sed 's/^/- /') + +FIXES=$(git log "${PREV_TAG}..HEAD" --pretty=format:"%s" --no-merges \ + | grep -E "^fix(\([^)]+\))?: " \ + | sed -E 's/^fix(\([^)]+\))?: //' \ + | sed 's/^/- /') +``` + +Nécessite des messages de commit au format [Conventional Commits](https://www.conventionalcommits.org/). + +### Workflow de release + +```bash +# 1. Développer et commiter normalement +git add -p +git commit -m "feat(scope): description" +git push # → répliqué sur GitHub automatiquement + +# 2. Quand prêt pour une release +git tag v1.x.y +git push origin v1.x.y # → tag répliqué sur GitHub → Actions déclenché + +# 3. Suivre le build +# GitHub → Actions → workflow en cours +# L'APK (ou autre artefact) est attaché à la GitHub Release créée automatiquement +``` + +### Avantages de cette approche + +| Aspect | Bénéfice | +|--------|---------| +| Pas de runner Gitea | Aucune infrastructure à maintenir côté self-hosted | +| GitHub gratuit | Runners Ubuntu illimités sur repos publics | +| Gitea comme source de vérité | Dépôt principal privé, contrôle total | +| Tag comme déclencheur | Build intentionnel, pas à chaque commit | +| Guard clause | Workflow safe si l'architecture évolue | + +### Limites et points de vigilance + +- Le push mirror est unidirectionnel : Gitea → GitHub. Ne jamais pousser directement sur GitHub. +- Les secrets GitHub ne sont pas répliqués — à configurer manuellement sur GitHub. +- Si le mirror est en retard (rare), attendre quelques secondes avant de vérifier que le tag est bien arrivé sur GitHub. +- Les GitHub Actions sur repos privés consomment des minutes (quota mensuel).