Commit 4bb7ffd2 authored by Kourser's avatar Kourser
Browse files

docs(app-store): fix the fastlane setup after the 0.5.1 submission

The deliver workflow documented here did not actually work: it pointed at
the Developer-role API key from release.sh, which App Store Connect
refuses for metadata edits ("The API key in use does not allow this
request"). Declare a separate App Manager key and wrap the whole
invocation in scripts/deliver.sh, so the two-key split, the inline PEM
that fastlane 2.238 requires, and the ios/osx metadata paths are not
re-derived every time.

Also correct the README where it was plainly wrong: the Mac App Store
presence is a real MAC_OS platform with its own version train, not the
iOS app on Apple Silicon. Record the submission gotchas met on 0.5.1 —
the content rights declaration that must not be patched, the single open
submission per platform, and --app_version renaming the editable slot.

No metadata is uploaded by this commit; the iOS release notes still
describe 0.5.0 and are to be rewritten before the next iOS submission.

Co-Authored-By: default avatarClaude Opus 5 <noreply@anthropic.com>
parent 25355863
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
# Config fastlane deliver — Skingomz
# Usage :  fastlane deliver           (aperçu / upload interactif)
#          fastlane deliver --skip_binary_upload true --submit_for_review false
#
# Authentification recommandée : clé API App Store Connect
#   (ASC_KEY_ID / ASC_ISSUER_ID / .p8 — mêmes identifiants que scripts/release.env)
#   export APP_STORE_CONNECT_API_KEY_PATH / _KEY_ID / _ISSUER_ID
#   ou :  api_key_path("fastlane/asc_key.json")
# Passer par `scripts/deliver.sh <ios|osx> [--submit <build>]`, qui construit
# le JSON de clé API attendu et cible la bonne fiche. En direct :
#   fastlane deliver --api_key_path <json> --platform osx --app_version 0.5.1 …
#
# ⚠️ Authentification : `deliver` exige une clé API de rôle **App Manager**
#   (ASC_DELIVER_KEY_ID dans scripts/release.env). La clé de release.sh est de
#   rôle Developer — elle envoie des builds mais se fait refuser ici avec
#   « The API key in use does not allow this request ».
#
# ⚠️ fastlane 2.238 veut le PEM du .p8 inline dans le champ `key` du JSON,
#   `key_filepath` n'est plus accepté.
#
# ⚠️ Les fiches iOS et macOS sont DEUX trains de version distincts dans ASC :
#   metadata/ + screenshots/ pour --platform ios,
#   metadata_macos/ + screenshots_macos/ pour --platform osx.

app_identifier("eu.cythin.skingomz")

# metadata/ et screenshots/ sont lus depuis fastlane/ par défaut.
skip_binary_upload(true)      # la build 0.5.0 est déjà envoyée via release.sh
# metadata/ et screenshots/ sont lus depuis fastlane/ par défaut ;
# scripts/deliver.sh surcharge les chemins pour la fiche macOS.
skip_binary_upload(true)      # les builds partent via scripts/release.sh
submit_for_review(false)      # on relit avant de soumettre
automatic_release(false)
automatic_release(false)      # publication déclenchée à la main après approbation
precheck_include_in_app_purchases(false)
force(false)                  # afficher l'aperçu HTML avant d'envoyer
+73 −24
Original line number Diff line number Diff line
@@ -4,8 +4,14 @@ Tout le nécessaire pour la fiche App Store, dans **22 langues**, au format
[fastlane deliver](https://docs.fastlane.tools/actions/deliver/). Prêt à
téléverser sur App Store Connect (via `fastlane deliver` ou copier-coller manuel).

Ces éléments accompagnent la build **0.5.0 (build 5)** déjà envoyée à
App Store Connect.
Ces éléments accompagnent la build **0.5.1 (build 6)**. Les fiches **iOS** et
**macOS** sont deux trains de version distincts dans App Store Connect, avec
chacun leurs métadonnées (`metadata/` et `metadata_macos/`).

> État au 2026-08-19 : macOS 0.5.1 est soumise à la review ; iOS reste en 0.5.0
> en ligne, le build 0.5.1 est uploadé mais aucune version iOS n'est créée. Les
> `metadata/<locale>/release_notes.txt` décrivent donc encore 0.5.0 — **à
> réécrire avant le prochain envoi iOS**.

## Contenu

@@ -22,7 +28,7 @@ fastlane/
│       ├── promotional_text.txt # texte promo, modifiable sans nouvelle version (≤170)
│       ├── description.txt      # description complète (≤4000)
│       ├── keywords.txt         # mots-clés ASO localisés (≤100, sans espace)
│       ├── release_notes.txt    # « Nouveautés » 0.5.0 (≤4000)
│       ├── release_notes.txt    # « Nouveautés » de la version (≤4000)
│       ├── support_url.txt
│       ├── marketing_url.txt
│       └── privacy_url.txt
@@ -49,25 +55,56 @@ d'Apple.

## Comment téléverser

### Option A — fastlane deliver (recommandé)
### Option A — scripts/deliver.sh (recommandé)

Depuis la racine du dépôt :

```bash
# Aperçu sans rien publier (génère un HTML de contrôle)
fastlane deliver --app_identifier eu.cythin.skingomz
./scripts/deliver.sh ios                # métadonnées de la fiche iOS
./scripts/deliver.sh osx                # métadonnées de la fiche macOS
./scripts/deliver.sh osx --submit 6     # + soumission à la review avec la build 6
```

Le script lit `MARKETING_VERSION`, choisit `metadata/` ou `metadata_macos/`,
construit le JSON de clé API et saute les captures (elles persistent d'une
version à l'autre — `--screenshots` pour forcer leur renvoi).

# Téléverser métadonnées + captures, sans soumettre à la review
fastlane deliver --skip_binary_upload true --submit_for_review false
#### ⚠️ Deux clés API, deux rôles

`deliver` **ne fonctionne pas** avec la clé de `release.sh` : celle-ci est de
rôle *Developer*, suffisant pour envoyer des builds, mais l'édition de la fiche
répond « The API key in use does not allow this request ». Il faut une clé de
rôle **App Manager**, déclarée à part dans `scripts/release.env` :

```
ASC_DELIVER_KEY_ID=…
ASC_DELIVER_KEY_PATH=…
```

`deliver` prend `fastlane/metadata` et `fastlane/screenshots` par défaut.
Authentification conseillée par **clé API App Store Connect** (mêmes
identifiants ASC que `scripts/release.env`).
L'Issuer ID est commun au compte, `ASC_ISSUER_ID` est réutilisé. Autre piège :
fastlane 2.238 exige le **contenu PEM** du `.p8` dans le champ `key` du JSON de
clé, `key_filepath` n'est plus accepté.

#### Soumettre à la review

- **Ne pas** passer `content_rights_contains_third_party_content` dans
  `submission_information` : l'app est déjà déclarée `USES_THIRD_PARTY_CONTENT`
  au niveau du compte — la bonne valeur pour un lecteur de podcasts — et le
  PATCH est rejeté (« An attribute value is not acceptable for the current
  resource state »). `scripts/deliver.sh` ne l'envoie pas.
- La conformité export vient d'`ITSAppUsesNonExemptEncryption` dans `Info.plist`.
- **Une seule soumission ouverte par plateforme.** Après un rejet, l'ancienne
  reste en `UNRESOLVED_ISSUES` et bloque tout (« A review submission is already
  in progress ») ; il faut l'annuler dans App Store Connect avant d'en créer une
  nouvelle. L'annuler revient à renoncer à l'offre d'Apple de faire approuver la
  version rejetée telle quelle — décision à prendre en connaissance de cause.
- ⚠️ Passer `--app_version X.Y.Z` alors que le slot éditable porte un autre
  numéro **renomme ce slot** : ASC n'a qu'une version éditable par plateforme,
  aucune seconde version n'est créée.

### Option B — manuel

Dans App Store Connect → l'app → version **0.5.0** → pour chaque langue :
Dans App Store Connect → l'app → la version éditable → pour chaque langue :
coller `name/subtitle/promotional_text/description/keywords/release_notes` et
glisser les captures `screenshots/<locale>/`. Ajouter les URLs (support,
marketing, confidentialité) et les notes de review.
@@ -125,11 +162,11 @@ App Transport Security allows HTTP (NSAllowsArbitraryLoads) because podcast RSS
The app collects no personal data (see the privacy manifest).
```

## macOS (0.5.0)
## macOS

- **Métadonnées** : `fastlane/metadata_macos/` — 22 langues, identiques à l'iOS
  pour l'instant (adaptables : mentionner menus, raccourcis clavier, Touch Bar).
  Upload : `fastlane deliver --platform osx --metadata_path fastlane/metadata_macos --screenshots_path fastlane/screenshots_macos`.
- **Métadonnées** : `fastlane/metadata_macos/` — 22 langues, proches de l'iOS
  (adaptables : mentionner menus, raccourcis clavier, Touch Bar). Les notes de
  version, elles, sont bien spécifiques à macOS. Upload : `./scripts/deliver.sh osx`.
- **Captures** : `fastlane/screenshots_macos/` — à générer avec
  `./fastlane/generate_shots_macos.sh`, **dans ton Terminal** (session graphique).
  Le script lance le binaire directement (langue via `-AppleLanguages`, que
@@ -141,16 +178,28 @@ The app collects no personal data (see the privacy manifest).
  repli sans permission, mais laisse des zones vides sur le contenu SwiftUI →
  `screencapture` est préféré. Vérifie `fr-FR/` et `ja/` avant de tout lancer.

> ⚠️ Rappel distribution : l'app Mac « native » est distribuée en **Developer ID**
> (téléchargement GitLab), pas sur le Mac App Store. La présence Mac sur l'App
> Store est l'app iOS sur Apple Silicon (même fiche), qui réutilise déjà les
> métadonnées iOS. Un vrai canal Mac App Store natif nécessiterait un build MAS
> sandboxé + l'ajout d'une plateforme macOS dans App Store Connect.
> ⚠️ Rappel distribution — l'app Mac part par **deux canaux distincts** :
> **Developer ID** (téléchargement direct depuis GitLab, via `scripts/release.sh`)
> et le **Mac App Store**, qui est bien une plateforme `MAC_OS` à part entière
> dans App Store Connect, avec son propre train de versions et ses propres
> métadonnées — ce n'est *pas* l'app iOS sur Apple Silicon.
>
> Le build Mac App Store se fait avec `scripts/release-macos-appstore.sh`, qui
> **exige un certificat « Mac Installer Distribution »** dans le trousseau
> (à créer une fois via Xcode > Settings > Accounts > Manage Certificates ; la
> création par clé API échoue en « Cloud signing permission error »). À défaut :
> Xcode > Organizer > Distribute App.

## Rappels

- **Ne pas oublier** : mettre à jour `docs/appcast.json` en 0.5.0 **seulement
  une fois la build réellement en ligne** sur l'App Store (sinon le pop-up
  « Mettre à jour » pointe dans le vide).
- **Ne pas oublier** : mettre à jour `docs/appcast.json` **seulement une fois la
  build réellement en ligne** (sinon le pop-up « Mettre à jour » pointe dans le
  vide). Toujours en 0.5.0 à ce jour.
- **Sous-titre** : pas de référence au prix (guideline 2.3.7). « Free » est lu
  par App Review comme « gratuit », même quand il veut dire « libre » — c'est ce
  qui a fait rejeter macOS 0.5.0. Les autres langues utilisent des mots de
  liberté non ambigus (`libre`, `svobodný`, `自由な`…) ; l'anglais dit
  « Open-source podcast player ». La fiche iOS **live** porte encore l'ancien
  sous-titre, à corriger au prochain envoi iOS.
- Relecture native conseillée pour les 5 langues ajoutées (zh-Hans, ja, ko,
  ru, pt-BR) et les mots-clés ASO avant publication.

scripts/deliver.sh

0 → 100755
+78 −0
Original line number Diff line number Diff line
#!/usr/bin/env bash
#
# Envoi des métadonnées App Store (et, en option, soumission à la review).
#
#   ./scripts/deliver.sh ios              # fiche iOS, métadonnées seules
#   ./scripts/deliver.sh osx              # fiche macOS, métadonnées seules
#   ./scripts/deliver.sh osx --submit 6   # + soumet à la review avec la build 6
#
# La version ciblée est lue dans MARKETING_VERSION (ou 2e argument positionnel
# via VERSION=…). Les captures ne sont PAS renvoyées (elles persistent d'une
# version à l'autre) — utiliser `--screenshots` pour forcer leur envoi.
#
# ⚠️ `deliver` exige une clé API de rôle App Manager : ASC_DELIVER_KEY_ID /
#    ASC_DELIVER_KEY_PATH dans scripts/release.env. La clé ASC_KEY_ID utilisée
#    par release.sh est de rôle Developer et se fait refuser
#    (« The API key in use does not allow this request »).
set -euo pipefail
cd "$(dirname "$0")/.."
set -a; . scripts/release.env 2>/dev/null || true; set +a

PLATFORM="${1:-}"
case "$PLATFORM" in
  ios)  METADATA=fastlane/metadata;       SHOTS=fastlane/screenshots ;;
  osx)  METADATA=fastlane/metadata_macos; SHOTS=fastlane/screenshots_macos ;;
  *)    echo "usage: $0 <ios|osx> [--submit <build>] [--screenshots]" >&2; exit 2 ;;
esac
shift

SUBMIT=false; BUILD=""; SKIP_SHOTS=true
while [ $# -gt 0 ]; do
  case "$1" in
    --submit)      SUBMIT=true; BUILD="${2:?--submit attend un numéro de build}"; shift 2 ;;
    --screenshots) SKIP_SHOTS=false; shift ;;
    *) echo "argument inconnu : $1" >&2; exit 2 ;;
  esac
done

VERSION="${VERSION:-$(grep -m1 'MARKETING_VERSION' Skingomz.xcodeproj/project.pbxproj \
  | sed 's/.*= *//; s/;.*//' | tr -d ' ')}"
[ -n "$VERSION" ] || { echo "✗ version introuvable" >&2; exit 1; }

: "${ASC_ISSUER_ID:?Renseigne ASC_ISSUER_ID (scripts/release.env)}"
: "${ASC_DELIVER_KEY_ID:?Renseigne ASC_DELIVER_KEY_ID (clé App Manager)}"
: "${ASC_DELIVER_KEY_PATH:?Renseigne ASC_DELIVER_KEY_PATH (.p8 App Manager)}"
P8="${ASC_DELIVER_KEY_PATH/#\~/$HOME}"
[ -f "$P8" ] || { echo "✗ clé introuvable : $P8" >&2; exit 1; }

# fastlane 2.238 veut le PEM inline dans le champ `key`, pas un chemin.
KEY_JSON="$(mktemp -t skingomz-asc)"
trap 'rm -f "$KEY_JSON"' EXIT
( umask 177; python3 - "$KEY_JSON" "$ASC_DELIVER_KEY_ID" "$ASC_ISSUER_ID" "$P8" <<'PY'
import json, sys
out, kid, iss, p8 = sys.argv[1:5]
json.dump({"key_id": kid, "issuer_id": iss, "key": open(p8).read(),
           "duration": 1200, "in_house": False}, open(out, "w"))
PY
)

ARGS=(--api_key_path "$KEY_JSON" --platform "$PLATFORM" --app_version "$VERSION"
      --metadata_path "$METADATA" --screenshots_path "$SHOTS"
      --skip_binary_upload true --skip_screenshots "$SKIP_SHOTS"
      --force true --run_precheck_before_submit false)

if $SUBMIT; then
  echo "▶︎ $PLATFORM $VERSION — métadonnées + soumission (build $BUILD)…"
  # ⚠️ NE PAS déclarer content_rights_contains_third_party_content : l'app est
  # déjà en USES_THIRD_PARTY_CONTENT au niveau du compte (correct pour un
  # lecteur de podcasts) et le PATCH est rejeté par l'API.
  # L'export compliance vient d'ITSAppUsesNonExemptEncryption dans Info.plist.
  ARGS+=(--build_number "$BUILD" --submit_for_review true --automatic_release false
         --submission_information '{"export_compliance_uses_encryption": false, "add_id_info_uses_idfa": false}')
else
  echo "▶︎ $PLATFORM $VERSION — métadonnées seules…"
  ARGS+=(--submit_for_review false)
fi

LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 FASTLANE_SKIP_UPDATE_CHECK=1 fastlane deliver "${ARGS[@]}"
echo "✓ Terminé. Rappel : l'upload ne publie pas — vérifier l'état dans App Store Connect."
+9 −0
Original line number Diff line number Diff line
@@ -28,3 +28,12 @@ PROJECT_PATH="Kourser%2Fskingomz-app"
ASC_KEY_ID=""                 # ex. ABCD123456
ASC_ISSUER_ID=""              # ex. 69a6de70-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ASC_KEY_PATH=""               # ex. ~/.appstoreconnect/private_keys/AuthKey_ABCD123456.p8

# --- Métadonnées / soumission (fastlane deliver) ----------------------------
# ⚠️ Rôle DIFFÉRENT de la clé ci-dessus : une clé « Developer » suffit pour
# envoyer des builds, mais `deliver` échoue avec « The API key in use does not
# allow this request ». Il faut une clé de rôle **App Manager** (ou Admin) pour
# éditer la fiche et soumettre à la review.
# L'Issuer ID est commun au compte : ASC_ISSUER_ID est réutilisé.
ASC_DELIVER_KEY_ID=""         # ex. EFGH789012 (rôle App Manager)
ASC_DELIVER_KEY_PATH=""       # ex. ~/.appstoreconnect/private_keys/AuthKey_EFGH789012.p8