mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 07:40:59 +00:00
8963180006
- iOS: microphone usage text for "Take Video", no-export-compliance flag, ExportOptions.plist for App Store Connect uploads, the unused push forwarders gone; CI builds with Xcode 26 and lints the property lists. - Android: version and signing from Gradle properties (unsigned without them), R8 with keep rules for TREK's and Capacitor's reflective classes, no Auto Backup of the session cookie, no external file provider path, template and Firebase leftovers removed, keystores and service accounts ignored, full-size adaptive icon layers with a monochrome layer; CI also builds the release APK. - native-release.yml: signed bundle to a Play testing track and archive to TestFlight, by hand or on a v* tag, behind the store environment. - Version handshake: the server reports nativeApi 1, the app refuses a server below its minimum and tolerates an app older than the offline copy. - Address screen: privacy policy link, "Try the demo" and "What is a TREK server?"; the privacy link also in the app's server settings. Three new native strings in all 27 locales. - Donation links and the notices asking for one are hidden in the app. - Store listings for "TREK Travel Planner" in client/fastlane: texts, review notes with placeholders, privacy and account deletion page drafts, the feature graphic and icon, a length and image check in CI, and a Playwright store project with the scripts that turn its captures into screenshots. - Docs: wiki/Native-Apps.md, README no longer says there is no store app.
192 lines
6.7 KiB
YAML
192 lines
6.7 KiB
YAML
name: Native apps release
|
|
|
|
# Builds the signed store builds of the iOS and Android apps and uploads them:
|
|
# the Android App Bundle to a Google Play testing track, the iOS archive to
|
|
# App Store Connect (TestFlight). Promotion to production stays a manual step
|
|
# in both consoles.
|
|
#
|
|
# Runs only in liketrek/TREK, only by hand or on a version tag, and only after a
|
|
# required reviewer approves the `store` environment, which holds every secret
|
|
# (see wiki/Native-Apps.md for the list). Pull requests never reach it.
|
|
#
|
|
# Both stores get the same numbers: the version from client/package.json
|
|
# without a prerelease suffix, and a build number that only grows. A prerelease
|
|
# reuses its X.Y.Z with a higher build number and belongs on the internal track
|
|
# and in TestFlight only.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
track:
|
|
description: Google Play track
|
|
type: choice
|
|
options: [internal, alpha, beta]
|
|
default: internal
|
|
push:
|
|
tags: ['v*']
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: native-release
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
android:
|
|
if: github.repository == 'liketrek/TREK'
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 40
|
|
environment: store
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version-file: .nvmrc
|
|
cache: npm
|
|
|
|
- uses: actions/setup-java@v5
|
|
with:
|
|
distribution: temurin
|
|
java-version: 21
|
|
cache: gradle
|
|
|
|
- name: Version and build number
|
|
id: version
|
|
run: |
|
|
echo "version=$(node -p "require('./client/package.json').version.split('-')[0]")" >> "$GITHUB_OUTPUT"
|
|
echo "build=$((GITHUB_RUN_NUMBER + 1000))" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Install
|
|
run: npm ci --workspace=shared --workspace=client
|
|
|
|
- name: Build shared
|
|
run: npm run build --workspace=shared
|
|
|
|
- name: Build the address screen and sync it into the shell
|
|
working-directory: client
|
|
run: npm run cap:sync -- android
|
|
|
|
- name: Upload key
|
|
env:
|
|
KEYSTORE_B64: ${{ secrets.ANDROID_UPLOAD_KEYSTORE_B64 }}
|
|
run: printf '%s' "$KEYSTORE_B64" | base64 -d > "$RUNNER_TEMP/upload.jks"
|
|
|
|
- name: Build the signed App Bundle
|
|
working-directory: client/android
|
|
env:
|
|
ORG_GRADLE_PROJECT_trekKeystorePassword: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
|
ORG_GRADLE_PROJECT_trekKeyAlias: ${{ secrets.ANDROID_KEY_ALIAS }}
|
|
ORG_GRADLE_PROJECT_trekKeyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
|
run: >-
|
|
./gradlew bundleRelease --no-daemon
|
|
-PtrekVersionName=${{ steps.version.outputs.version }}
|
|
-PtrekVersionCode=${{ steps.version.outputs.build }}
|
|
-PtrekKeystore="$RUNNER_TEMP/upload.jks"
|
|
|
|
- uses: actions/upload-artifact@v6
|
|
with:
|
|
name: trek-android-${{ steps.version.outputs.version }}-${{ steps.version.outputs.build }}
|
|
path: client/android/app/build/outputs/bundle/release/app-release.aab
|
|
retention-days: 30
|
|
|
|
# Play only accepts API uploads once one bundle was uploaded by hand
|
|
# (wiki/Native-Apps.md). `draft` until the app has left draft in the console.
|
|
- name: Upload to Google Play
|
|
uses: r0adkll/upload-google-play@e738b9dd8f2476ea806d921b64aacd24f34515a5 # v1.1.5
|
|
with:
|
|
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
|
|
packageName: com.liketrek.trek
|
|
releaseFiles: client/android/app/build/outputs/bundle/release/app-release.aab
|
|
track: ${{ inputs.track || 'internal' }}
|
|
status: draft
|
|
|
|
- name: Remove the upload key
|
|
if: always()
|
|
run: rm -f "$RUNNER_TEMP/upload.jks"
|
|
|
|
ios:
|
|
if: github.repository == 'liketrek/TREK'
|
|
runs-on: macos-15
|
|
timeout-minutes: 60
|
|
environment: store
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
# App Store uploads must be built with Xcode 26; the image's default is older.
|
|
- name: Select Xcode 26
|
|
run: |
|
|
XCODE=$(ls -d /Applications/Xcode_26*.app | sort -V | tail -1)
|
|
test -n "$XCODE"
|
|
sudo xcode-select -s "$XCODE"
|
|
xcodebuild -version
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version-file: .nvmrc
|
|
cache: npm
|
|
|
|
- name: Version and build number
|
|
id: version
|
|
run: |
|
|
echo "version=$(node -p "require('./client/package.json').version.split('-')[0]")" >> "$GITHUB_OUTPUT"
|
|
echo "build=$((GITHUB_RUN_NUMBER + 1000))" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Install
|
|
run: npm ci --workspace=shared --workspace=client
|
|
|
|
- name: Build shared
|
|
run: npm run build --workspace=shared
|
|
|
|
- name: Build the address screen and sync it into the shell
|
|
working-directory: client
|
|
run: npm run cap:sync -- ios
|
|
|
|
- name: App Store Connect API key
|
|
env:
|
|
ASC_KEY_P8_B64: ${{ secrets.ASC_KEY_P8_B64 }}
|
|
run: printf '%s' "$ASC_KEY_P8_B64" | base64 -d > "$RUNNER_TEMP/AuthKey.p8"
|
|
|
|
- name: Archive
|
|
working-directory: client/ios/App
|
|
env:
|
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
|
|
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
|
|
run: >-
|
|
xcodebuild archive
|
|
-project App.xcodeproj
|
|
-scheme App
|
|
-configuration Release
|
|
-destination 'generic/platform=iOS'
|
|
-archivePath "$RUNNER_TEMP/TREK.xcarchive"
|
|
MARKETING_VERSION=${{ steps.version.outputs.version }}
|
|
CURRENT_PROJECT_VERSION=${{ steps.version.outputs.build }}
|
|
DEVELOPMENT_TEAM="$APPLE_TEAM_ID"
|
|
-allowProvisioningUpdates
|
|
-authenticationKeyPath "$RUNNER_TEMP/AuthKey.p8"
|
|
-authenticationKeyID "$ASC_KEY_ID"
|
|
-authenticationKeyIssuerID "$ASC_ISSUER_ID"
|
|
|
|
# ExportOptions.plist says destination=upload, so this step sends the build
|
|
# to App Store Connect, where it shows up in TestFlight after processing.
|
|
- name: Export and upload to App Store Connect
|
|
working-directory: client/ios/App
|
|
env:
|
|
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
|
|
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
|
|
run: >-
|
|
xcodebuild -exportArchive
|
|
-archivePath "$RUNNER_TEMP/TREK.xcarchive"
|
|
-exportOptionsPlist ../ExportOptions.plist
|
|
-exportPath "$RUNNER_TEMP/export"
|
|
-allowProvisioningUpdates
|
|
-authenticationKeyPath "$RUNNER_TEMP/AuthKey.p8"
|
|
-authenticationKeyID "$ASC_KEY_ID"
|
|
-authenticationKeyIssuerID "$ASC_ISSUER_ID"
|
|
|
|
- name: Remove the API key
|
|
if: always()
|
|
run: rm -f "$RUNNER_TEMP/AuthKey.p8"
|