## What changed - adds production iOS identity, localized storefront metadata, native privacy declarations, App Store-safe artwork, and account-deletion UX - mirrors the live Danish Google Play title, short description, and long description in the App Store metadata source - generates Android launcher/store icons from the opaque iOS marketing master so both platforms use the same white background - adds guarded GitHub Actions workflows for storefront readiness, credential health, signed TestFlight uploads, and App Store candidate preparation - adds pinned Fastlane configuration with a committed dependency lock, release manifest tooling, and an operational App Store runbook - preserves the upstream iOS safe-area implementation while retaining opaque App Store icon assets ## Why The repository previously supported development-signed device bundles but had no production App Store identity, reproducible storefront source of truth, or protected signed-release pipeline. Apple also requires in-app account deletion for apps that support account creation. The Android icon master was transparent, which rendered as black on dark store/device surfaces. ## Impact Automation remains fail-closed behind `APP_STORE_AUTOMATION_ENABLED=false`. No build can upload to TestFlight or change App Store metadata until the switch is deliberately enabled after merge and the remaining release gates are satisfied. ## Validation - focused App Store, iOS icon, and cross-platform icon-background tests pass - every generated Android store/launcher icon is opaque with pure-white corners; iOS marketing artwork is checked the same way - Android icon drift check passes for all 19 generated files - production Vite build and the broader focused release checks completed successfully - storefront metadata is valid; only the two expected screenshot-set warnings remain - App Store Readiness is green at head `4445fecc` - Apple Distribution certificate and App Store profile were independently verified for `HP3FJ4GVL7.io.truckwash.app` - live App Store Connect API authentication succeeded for app `6792777794` - App Store record, free Denmark-only availability, and automatic `Internal QA` TestFlight group are configured - EU trader status, Content Rights, 4+ age rating, and the published App Privacy label are completed in App Store Connect - iPhone and iPad accessibility declarations are configured honestly as pre-release drafts ## Remaining external gates - reviewed iPhone and iPad screenshot sets are still required - an App Review login must be supplied without creating or exposing customer credentials - the first signed TestFlight candidate must run after merge and deliberate automation enablement
73 lines
2.1 KiB
YAML
73 lines
2.1 KiB
YAML
name: App Store Readiness
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches: [master]
|
|
paths:
|
|
- "fastlane/**"
|
|
- "ios/**"
|
|
- "scripts/mobile/**"
|
|
- "Gemfile*"
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: app-store-readiness-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
validate:
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
|
|
with:
|
|
node-version: 22
|
|
|
|
- name: Setup Ruby
|
|
uses: ruby/setup-ruby@003a5c4d8d6321bd302e38f6f0ec593f77f06600 # v1
|
|
with:
|
|
ruby-version: "3.3"
|
|
|
|
- name: Resolve the pinned Fastlane dependency graph
|
|
run: bundle lock
|
|
|
|
- name: Check the committed Fastlane dependency lock
|
|
id: fastlane-lock
|
|
continue-on-error: true
|
|
run: test -z "$(git status --porcelain -- Gemfile.lock)"
|
|
|
|
- name: Preserve a generated lock for review
|
|
if: steps.fastlane-lock.outcome == 'failure'
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
with:
|
|
name: generated-fastlane-lock
|
|
path: Gemfile.lock
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
- name: Require a current committed Fastlane dependency lock
|
|
if: steps.fastlane-lock.outcome == 'failure'
|
|
run: |
|
|
echo 'Gemfile.lock is missing or stale. Download generated-fastlane-lock and commit it.' >&2
|
|
exit 1
|
|
|
|
- name: Validate App Store metadata and available assets
|
|
run: node scripts/mobile/validate-app-store.mjs
|
|
|
|
- name: Validate JavaScript syntax
|
|
run: |
|
|
node --check scripts/mobile/validate-app-store.mjs
|
|
node --check scripts/mobile/app-store-connect.mjs
|
|
node --check scripts/mobile/create-ios-release-manifest.mjs
|
|
node scripts/mobile/app-store-connect.mjs self-test-jwt
|