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