Compare commits
No commits in common. "c0a07e8adcd776c9148174f15550632c19432f69" and "e9c0a61aaff12805ecf23474a58ec65ebd78c3c8" have entirely different histories.
c0a07e8adc
...
e9c0a61aaf
4 changed files with 4 additions and 134 deletions
78
.github/workflows/ci.yml
vendored
78
.github/workflows/ci.yml
vendored
|
|
@ -203,81 +203,3 @@ jobs:
|
||||||
# `component.devServer`), unlike `e2e` above which needs the real app
|
# `component.devServer`), unlike `e2e` above which needs the real app
|
||||||
# running first.
|
# running first.
|
||||||
- run: pnpm --filter web cy:run:component
|
- run: pnpm --filter web cy:run:component
|
||||||
|
|
||||||
# Builds and packages a signed, downloadable Android APK on every push to
|
|
||||||
# `main` — issue #64. `needs:` on every other job is what actually makes
|
|
||||||
# this "build, TEST, and package" rather than just "build and package in
|
|
||||||
# parallel with tests that might still be failing": Forgejo/GitHub Actions
|
|
||||||
# has no native way for a job in a *different* workflow file to block on
|
|
||||||
# one here, so this has to live in this same file to get a real dependency
|
|
||||||
# rather than a same-push coincidence. `if:` (not a separate trigger) keeps
|
|
||||||
# every other job running on every branch as today — only this one is
|
|
||||||
# main-only.
|
|
||||||
#
|
|
||||||
# No dedicated Android test suite exists (zero native code beyond the
|
|
||||||
# Capacitor-generated shell) — "testée" is satisfied by gating on the 5
|
|
||||||
# existing jobs, not by inventing an instrumented test suite for this.
|
|
||||||
#
|
|
||||||
# Unverified on this runner as of writing: no Android build has ever run
|
|
||||||
# on this self-hosted Forgejo `act` runner (unlike lint/test/build/e2e,
|
|
||||||
# exercised for months). If SDK installation turns out too slow/heavy here,
|
|
||||||
# cache `~/.android/sdk`/`~/.gradle` (same idea as the Cypress binary cache
|
|
||||||
# in `e2e` above) rather than accepting a slow job on every push.
|
|
||||||
build-android:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [lint, test, intent-service-test, build, e2e]
|
|
||||||
if: github.ref == 'refs/heads/main'
|
|
||||||
steps:
|
|
||||||
- uses: https://github.com/actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v4
|
|
||||||
|
|
||||||
- uses: https://github.com/actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 22
|
|
||||||
cache: pnpm
|
|
||||||
|
|
||||||
- uses: https://github.com/actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
distribution: temurin
|
|
||||||
# Matches what Android Gradle Plugin 8.x (bundled with the
|
|
||||||
# Capacitor-generated project, see apps/web/android/build.gradle)
|
|
||||||
# expects — bump alongside AGP if that version ever moves.
|
|
||||||
java-version: "21"
|
|
||||||
|
|
||||||
- uses: https://github.com/android-actions/setup-android@v3
|
|
||||||
|
|
||||||
- run: pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
# Unlike the normal web build (served same-origin as the API), a
|
|
||||||
# packaged Capacitor build runs from the WebView's own local origin and
|
|
||||||
# needs an absolute, public HTTPS URL baked in at build time — see
|
|
||||||
# apps/web/.env.capacitor.example's own comment on this.
|
|
||||||
- name: Build le bundle web pour Capacitor
|
|
||||||
env:
|
|
||||||
VITE_API_URL: ${{ secrets.MOBILE_API_URL }}
|
|
||||||
run: pnpm --filter web build:capacitor
|
|
||||||
- run: pnpm --filter web exec cap sync android
|
|
||||||
|
|
||||||
# Le keystore de release est un secret généré une fois à la main (voir
|
|
||||||
# le README, section "Application mobile") — jamais régénéré ici, un
|
|
||||||
# nouveau keystore casserait la mise à jour de l'appli déjà installée
|
|
||||||
# (Android refuse une signature différente de celle déjà installée).
|
|
||||||
- name: Décode le keystore de release
|
|
||||||
env:
|
|
||||||
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
|
||||||
run: echo "$ANDROID_KEYSTORE_BASE64" | base64 -d > apps/web/android/app/release.keystore
|
|
||||||
|
|
||||||
- name: Build l'APK signé
|
|
||||||
working-directory: apps/web/android
|
|
||||||
env:
|
|
||||||
ANDROID_KEYSTORE_PATH: release.keystore
|
|
||||||
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
|
||||||
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
|
||||||
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
|
||||||
run: ./gradlew assembleRelease
|
|
||||||
|
|
||||||
- uses: https://github.com/actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: batchcooking-release.apk
|
|
||||||
path: apps/web/android/app/build/outputs/apk/release/app-release.apk
|
|
||||||
|
|
|
||||||
28
README.md
28
README.md
|
|
@ -266,34 +266,6 @@ Les icônes et le splash sont générés depuis `apps/web/assets/logo.svg` (voir
|
||||||
`apps/web/assets/README.md`). iOS est hors périmètre pour l'instant (nécessite
|
`apps/web/assets/README.md`). iOS est hors périmètre pour l'instant (nécessite
|
||||||
Xcode/macOS).
|
Xcode/macOS).
|
||||||
|
|
||||||
**CI — build automatique d'un APK signé** (`.github/workflows/ci.yml`, job
|
|
||||||
`build-android`, issue #64) : à chaque push sur `main`, une fois les 5 autres
|
|
||||||
jobs verts, un APK release signé est construit et déposé comme artefact de
|
|
||||||
run téléchargeable. Secrets du dépôt Forgejo requis (Réglages du dépôt →
|
|
||||||
Secrets) :
|
|
||||||
|
|
||||||
| Secret | Contenu |
|
|
||||||
|---|---|
|
|
||||||
| `MOBILE_API_URL` | URL HTTPS publique de l'API — même valeur que `VITE_API_URL` dans `.env.capacitor` |
|
|
||||||
| `ANDROID_KEYSTORE_BASE64` | Le keystore de release (`.jks`) encodé en base64 |
|
|
||||||
| `ANDROID_KEYSTORE_PASSWORD` | Mot de passe du keystore |
|
|
||||||
| `ANDROID_KEY_ALIAS` | Alias de la clé dans le keystore |
|
|
||||||
| `ANDROID_KEY_PASSWORD` | Mot de passe de la clé |
|
|
||||||
|
|
||||||
Le keystore doit être généré **une seule fois**, à la main, et rester stable
|
|
||||||
pour toujours : Android refuse d'installer la mise à jour d'une appli signée
|
|
||||||
par une clé différente de celle déjà installée.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
keytool -genkeypair -v -keystore batchcooking-release.jks \
|
|
||||||
-alias batchcooking -keyalg RSA -keysize 2048 -validity 10000
|
|
||||||
base64 -w0 batchcooking-release.jks # → coller comme secret ANDROID_KEYSTORE_BASE64
|
|
||||||
```
|
|
||||||
|
|
||||||
Conserver le fichier `.jks` et ses mots de passe en lieu sûr en dehors du
|
|
||||||
dépôt (jamais commité — voir `apps/web/android/.gitignore`) : le perdre
|
|
||||||
empêche de publier toute future mise à jour de l'appli.
|
|
||||||
|
|
||||||
## Auth (apps/api)
|
## Auth (apps/api)
|
||||||
|
|
||||||
Inscription (création de profil + foyer) et connexion, JWT dans un cookie httpOnly.
|
Inscription (création de profil + foyer) et connexion, JWT dans un cookie httpOnly.
|
||||||
|
|
|
||||||
10
apps/web/android/.gitignore
vendored
10
apps/web/android/.gitignore
vendored
|
|
@ -52,12 +52,10 @@ captures/
|
||||||
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
||||||
.idea/navEditor.xml
|
.idea/navEditor.xml
|
||||||
|
|
||||||
# Keystore files — jamais commités : le keystore de release est un secret
|
# Keystore files
|
||||||
# généré une fois à la main (voir la doc du README, section "Application
|
# Uncomment the following lines if you do not want to check your keystore files in.
|
||||||
# mobile"), décodé depuis le secret CI ANDROID_KEYSTORE_BASE64 à chaque build
|
#*.jks
|
||||||
# de release, jamais versionné ici (issue #64).
|
#*.keystore
|
||||||
*.jks
|
|
||||||
*.keystore
|
|
||||||
|
|
||||||
# External native build folder generated in Android Studio 2.2 and later
|
# External native build folder generated in Android Studio 2.2 and later
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
|
|
|
||||||
|
|
@ -16,30 +16,8 @@ android {
|
||||||
ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
|
ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Lu depuis l'environnement, jamais codé en dur — même règle que les
|
|
||||||
// secrets de apps/api (JWT_SECRET, etc.) : aucune valeur par défaut
|
|
||||||
// devinable. Le keystore lui-même (ANDROID_KEYSTORE_PATH) est un fichier
|
|
||||||
// décodé à la volée depuis le secret CI ANDROID_KEYSTORE_BASE64, jamais
|
|
||||||
// commité (voir apps/web/android/.gitignore) — généré une fois à la main,
|
|
||||||
// voir la doc du README "Application mobile". N'affecte que
|
|
||||||
// `assembleRelease` : `assembleDebug` continue d'utiliser le keystore de
|
|
||||||
// debug généré automatiquement par Android, sans configuration.
|
|
||||||
signingConfigs {
|
|
||||||
release {
|
|
||||||
storeFile System.getenv("ANDROID_KEYSTORE_PATH") ? file(System.getenv("ANDROID_KEYSTORE_PATH")) : null
|
|
||||||
storePassword System.getenv("ANDROID_KEYSTORE_PASSWORD")
|
|
||||||
keyAlias System.getenv("ANDROID_KEY_ALIAS")
|
|
||||||
keyPassword System.getenv("ANDROID_KEY_PASSWORD")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// `signingConfig` reste posé même quand les variables d'environnement
|
|
||||||
// ci-dessus sont absentes (dev local) : Gradle accepte une
|
|
||||||
// signingConfig aux champs `null`, la build échoue seulement au
|
|
||||||
// moment de la signature effective (assembleRelease), jamais à la
|
|
||||||
// configuration — un `assembleDebug` local n'en a jamais besoin.
|
|
||||||
signingConfig signingConfigs.release
|
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue