Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7.4 KiB
CLAUDE.md — Postiz Android
Projet
Application Android (React Native / Expo SDK 52) pour piloter une instance Postiz 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) :
{ 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
# 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 :
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 pouraction-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 :
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.
Workflow de release
# 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).