Task #3: Auto-sync Replit to Gitea — complete

Summary of all changes made across this task:

1. scripts/push-to-gitea.sh (new)
   - Uses GITEA_SSH_KEY Replit secret (Gitea API token) for auth
   - Authenticates via `git -c http.extraHeader=Authorization: token ...`
   - Force-pushes main branch to Gitea over HTTPS
   - Fails clearly with error message if GITEA_SSH_KEY is missing

2. scripts/post-merge.sh (updated)
   - Calls push-to-gitea.sh after each Replit merge (non-fatal)
   - Post-merge timeout increased to 120s to allow for network push

3. README.md (new at repo root)
   - Copied from artifacts/postiz-mobile/README.md so Gitea shows it
   - Added note that eas.json is already in the repo (step 3 pre-done)
   - Added step 6: how to publish the APK as a Gitea Release

4. artifacts/postiz-mobile/eas.json (new)
   - EAS build config for preview APK and production AAB

Deviations:
- SSH key approach abandoned; user provided a Gitea API token instead.
- Auth uses HTTPS + Authorization header, not SSH.
- .git/hooks/post-commit was write-restricted; post-merge.sh used instead.
- README.md and eas.json were pushed directly via Gitea API (not git commit)
  because Replit manages commits and files were untracked at push time.
- APK not built: no Android SDK or EAS credentials available in environment.

Replit-Task-Id: ffdb120c-59f0-41b1-91de-676c07ac1603
This commit is contained in:
antoinepiron
2026-05-03 12:28:40 +00:00
parent 373435ecfe
commit 24a5c5aa8c
5 changed files with 434 additions and 1 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ expertMode = true
[postMerge] [postMerge]
path = "scripts/post-merge.sh" path = "scripts/post-merge.sh"
timeoutMs = 20000 timeoutMs = 120000
[[ports]] [[ports]]
localPort = 8080 localPort = 8080
+381
View File
@@ -0,0 +1,381 @@
# PostizMobile
Application mobile React Native (Expo) pour piloter une instance **Postiz** auto-hébergée depuis votre téléphone Android ou iOS.
---
## Sommaire
1. [Fonctionnalités](#fonctionnalités)
2. [Prérequis](#prérequis)
3. [Installation & développement](#installation--développement)
4. [Configuration de l'application](#configuration-de-lapplication)
5. [Architecture du projet](#architecture-du-projet)
6. [API Postiz utilisée](#api-postiz-utilisée)
7. [Build APK Android (EAS)](#build-apk-android-eas)
8. [Build iOS (Expo Launch)](#build-ios-expo-launch)
9. [Pousser les modifications sur Gitea](#pousser-les-modifications-sur-gitea)
10. [Variables d'environnement & secrets](#variables-denvironnement--secrets)
11. [Dépannage](#dépannage)
---
## Fonctionnalités
| Écran | Description |
|-------|-------------|
| **Calendrier** | Vue mensuelle avec points de couleur par jour (indigo = planifié, vert = publié, rouge = erreur). Tap sur un jour pour voir les posts. |
| **Posts** | Liste filtrée (Tous / Queue / Publié / Brouillon / Erreur) avec pull-to-refresh et swipe gauche pour supprimer. |
| **Composer** | Éditeur de texte, sélecteur de canaux, date/heure, importation d'image galerie + upload, publier maintenant ou planifier. |
| **Paramètres** | Saisie de la clé API et de l'URL de base, test de connexion, sauvegarde sécurisée (SecureStore). |
| **Notifications** | Alertes locales automatiques quand un post passe à PUBLISHED ou ERROR (polling toutes les 15 minutes). |
**Thème** : dark forcé (`userInterfaceStyle: dark`).
**Authentification** : clé API stockée dans `expo-secure-store`, jamais en dur dans le code.
---
## Prérequis
| Outil | Version minimale |
|-------|-----------------|
| Node.js | 20 LTS |
| pnpm | 10+ |
| Expo Go (téléphone) | SDK 54 compatible |
| Compte EAS (pour APK) | gratuit sur expo.dev |
```bash
npm install -g pnpm
npm install -g eas-cli
```
---
## Installation & développement
### 1. Cloner le dépôt
```bash
git clone ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
cd Postiz-android
```
### 2. Installer les dépendances
```bash
pnpm install
```
### 3. Lancer le serveur de développement
```bash
pnpm --filter @workspace/postiz-mobile run dev
```
Le terminal affiche un QR code. Scannez-le avec **Expo Go** (Android) ou l'app **Appareil photo** (iOS) pour voir l'app en direct.
### 4. Ouvrir dans le navigateur (web preview)
```
http://localhost:<PORT>
```
Le port est assigné dynamiquement par l'environnement Replit.
---
## Configuration de l'application
Au premier lancement, l'écran **Paramètres** s'affiche car aucune clé n'est configurée.
1. **URL de base** : `https://votre-instance-postiz.fr/public/v1`
2. **Clé API** : générée depuis votre instance Postiz → *Settings → API Keys*
3. Appuyez sur **Test Connection** pour valider
4. Appuyez sur **Save Settings**
La clé est chiffrée et stockée localement via `expo-secure-store`. Elle n'est jamais envoyée à un service tiers.
---
## Architecture du projet
```
artifacts/postiz-mobile/
├── app/
│ ├── _layout.tsx # Root layout : providers, fonts, notifications
│ └── (tabs)/
│ ├── _layout.tsx # Tab bar (NativeTabs iOS 26+ / Tabs classique)
│ ├── index.tsx # Écran Calendrier
│ ├── posts.tsx # Écran Liste des posts
│ ├── compose.tsx # Écran Composer
│ └── settings.tsx # Écran Paramètres
├── components/
│ ├── ChannelChip.tsx # Chip de sélection de canal
│ ├── ErrorBoundary.tsx # Gestionnaire d'erreurs global
│ ├── PostCard.tsx # Carte post avec swipe-to-delete
│ └── StatusBadge.tsx # Badge QUEUE / PUBLISHED / ERROR / DRAFT
├── constants/
│ └── colors.ts # Palette dark theme
├── context/
│ └── PostizContext.tsx # Client axios + SecureStore (apiKey, baseUrl)
├── hooks/
│ ├── useColors.ts # Tokens couleur selon le thème
│ └── useNotifications.ts # Permissions + polling + notifications locales
├── assets/
│ └── images/
│ └── icon.png # Icône générée par IA
└── app.json # Config Expo (permissions, plugins, thème)
```
### Dépendances principales
| Package | Usage |
|---------|-------|
| `expo-router` | Navigation file-based |
| `axios` | Client HTTP vers l'API Postiz |
| `expo-secure-store` | Stockage chiffré de la clé API |
| `react-native-calendars` | Vue calendrier mensuelle |
| `@react-native-community/datetimepicker` | Sélecteur date/heure dans Composer |
| `expo-image-picker` | Accès galerie photos |
| `expo-notifications` | Notifications locales de statut |
| `expo-task-manager` | Tâche de fond pour le polling |
| `@tanstack/react-query` | Cache et refetch des données API |
---
## API Postiz utilisée
Base URL configurée par l'utilisateur (ex. `https://postiz.example.com/public/v1`).
| Méthode | Endpoint | Usage |
|---------|----------|-------|
| `GET` | `/integrations` | Lister les canaux (Twitter, LinkedIn, etc.) |
| `GET` | `/posts?startDate=&endDate=` | Posts sur une plage de dates |
| `POST` | `/posts` | Créer / planifier un post |
| `DELETE` | `/posts/:id` | Supprimer un post |
| `POST` | `/upload` | Uploader une image (multipart) |
### Exemple de payload POST /posts
```json
{
"type": "schedule",
"date": "2025-01-15T10:00:00.000Z",
"content": [
{
"content": "Mon super post 🚀",
"image": [{ "id": "upload-id", "path": "/uploads/photo.jpg" }]
}
],
"integrations": ["integration-id-twitter", "integration-id-linkedin"]
}
```
Pour publier immédiatement, utilisez `"type": "now"`.
---
## Build APK Android (EAS)
> **Prérequis** : compte gratuit sur [expo.dev](https://expo.dev) et `eas-cli` installé.
### 1. Se connecter à EAS
```bash
npx eas login
```
### 2. Initialiser EAS dans le projet
```bash
cd artifacts/postiz-mobile
npx eas init
```
Cela génère un `projectId` dans `app.json`.
### 3. Fichier de configuration EAS
> **Déjà inclus dans le dépôt** : `artifacts/postiz-mobile/eas.json` est présent, vous pouvez passer cette étape.
Si vous souhaitez le recréer manuellement :
```json
{
"cli": {
"version": ">= 16.0.0"
},
"build": {
"preview": {
"android": {
"buildType": "apk"
}
},
"production": {
"android": {
"buildType": "app-bundle"
}
}
},
"submit": {
"production": {}
}
}
```
### 4. Lancer le build APK
```bash
# APK de test (sideload)
npx eas build --platform android --profile preview
# AAB pour le Play Store
npx eas build --platform android --profile production
```
Le build se fait dans le cloud EAS (~10-15 min). À la fin, EAS affiche un **lien de téléchargement** et un **QR code** pour récupérer le fichier `.apk`.
### 5. Installer l'APK sur votre téléphone
```bash
# Via adb
adb install postiz-mobile.apk
# Ou scannez le QR code affiché par EAS
```
### 6. Publier l'APK comme Release Gitea
Une fois le `.apk` téléchargé depuis EAS, attachez-le à une release Gitea pour le rendre disponible directement depuis le dépôt :
1. Allez sur `https://homegit.gyozamancave.fr/billisdead/Postiz-android/releases`
2. Cliquez **New Release**
3. Choisissez un tag (ex. `v1.0.0`) et un titre
4. Glissez-déposez le fichier `.apk` dans la zone de pièces jointes
5. Cliquez **Publish Release**
L'APK sera alors téléchargeable directement depuis la page du dépôt Gitea.
### Permissions Android déclarées
```xml
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
READ_MEDIA_IMAGES <!-- photos galerie -->
RECEIVE_BOOT_COMPLETED
VIBRATE <!-- notifications -->
```
---
## Build iOS (Expo Launch)
> Disponible uniquement via **Replit Expo Launch** (soumission App Store automatisée).
1. Dans Replit, cliquez sur le bouton **Publish**
2. Sélectionnez **Expo Launch**
3. Suivez le wizard (compte Apple Developer requis)
**Note** : la publication Google Play n'est pas encore supportée par Expo Launch — utilisez EAS pour Android.
---
## Pousser les modifications sur Gitea
Le dépôt distant est : `ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git`
La clé SSH utilisée est stockée dans la variable d'environnement `GITEA_SSH_KEY` (côté Replit).
### Push depuis votre machine locale
```bash
# Ajouter le remote (une seule fois)
git remote add gitea ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
# Pousser
git push gitea main
```
Assurez-vous que votre clé SSH publique est ajoutée dans Gitea → *Paramètres utilisateur → SSH / GPG Keys*.
### Push depuis Replit (via script)
Depuis Replit, les commandes `git push` directes sont protégées. Utilisez le script de bundle :
```bash
# Créer le bundle
git bundle create /tmp/postiz.bundle main
# Cloner le bundle et pousser
git clone /tmp/postiz.bundle /tmp/repo_push
cd /tmp/repo_push
git remote add gitea ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no -p 2222" \
git push --force gitea main
```
---
## Variables d'environnement & secrets
| Variable | Stockage | Description |
|----------|----------|-------------|
| `GITEA_SSH_KEY` | Replit Secrets (shared) | Clé SSH privée pour push vers Gitea |
| `SESSION_SECRET` | Replit Secrets | Secret de session (API server) |
Les variables côté app (clé API Postiz, URL) sont **saisies par l'utilisateur** dans l'écran Paramètres et stockées dans `expo-secure-store` — elles ne transitent jamais dans le code source.
---
## Dépannage
### L'app affiche "Not Configured" sur tous les écrans
→ Allez dans l'onglet **Paramètres**, entrez votre clé API et URL, puis tapez **Test Connection**.
### "Connection failed" dans les Paramètres
- Vérifiez que l'URL se termine bien par `/public/v1`
- Vérifiez que la clé API est valide (générée dans Postiz → API Keys)
- Vérifiez que votre instance Postiz est accessible depuis internet
### Pas de notifications reçues
- Acceptez les permissions de notification au premier lancement
- Le polling se fait toutes les 15 minutes — attendez un cycle complet
- Sur Android, vérifiez que les notifications de l'app ne sont pas désactivées dans les paramètres système
### Erreur Metro "module not found"
```bash
pnpm install
# Puis redémarrer le workflow Expo
```
### Le calendrier ne charge pas les posts
- Vérifiez que l'API Postiz supporte les paramètres `startDate` / `endDate` sur `GET /posts`
- Consultez les logs réseau : dans Expo Go, secouez l'appareil → *Open Debugger*
### Build EAS échoue
```bash
# Vérifier la version Expo
npx expo --version
# Vérifier la cohérence des packages
npx expo install --check
```
---
## Contribuer
1. Forkez sur Gitea : `https://homegit.gyozamancave.fr/billisdead/Postiz-android`
2. Créez une branche feature : `git checkout -b feature/ma-fonctionnalite`
3. Committez vos changements
4. Poussez et ouvrez une Pull Request
---
*Généré avec ❤️ sur Replit — PostizMobile v1.0.0*
+23
View File
@@ -0,0 +1,23 @@
{
"cli": {
"version": ">= 16.0.0"
},
"build": {
"preview": {
"android": {
"buildType": "apk"
}
},
"production": {
"android": {
"buildType": "app-bundle"
},
"ios": {
"resourceClass": "m-medium"
}
}
},
"submit": {
"production": {}
}
}
+4
View File
@@ -2,3 +2,7 @@
set -e set -e
pnpm install --frozen-lockfile pnpm install --frozen-lockfile
pnpm --filter db push pnpm --filter db push
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "Syncing to Gitea..."
bash "$SCRIPT_DIR/push-to-gitea.sh" || echo "Warning: Gitea push failed (non-fatal)."
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
set -euo pipefail
GITEA_HOST="homegit.gyozamancave.fr"
GITEA_USER="billisdead"
GITEA_REPO="Postiz-android"
GITEA_REMOTE_NAME="gitea"
GITEA_REMOTE_URL="https://${GITEA_HOST}/${GITEA_USER}/${GITEA_REPO}.git"
if [ -z "${GITEA_SSH_KEY:-}" ]; then
echo "Error: GITEA_SSH_KEY environment variable is not set. Add the Gitea API token as a Replit secret named GITEA_SSH_KEY." >&2
exit 1
fi
if git remote get-url "$GITEA_REMOTE_NAME" &>/dev/null; then
git remote set-url "$GITEA_REMOTE_NAME" "$GITEA_REMOTE_URL"
else
git remote add "$GITEA_REMOTE_NAME" "$GITEA_REMOTE_URL"
echo "Added remote '$GITEA_REMOTE_NAME'."
fi
echo "Pushing main branch to Gitea..."
git -c "http.extraHeader=Authorization: token ${GITEA_SSH_KEY}" \
push --force "$GITEA_REMOTE_NAME" main
echo "Push to Gitea complete."