mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 15:51:00 +00:00
6d3c400e4a
An app linked against an SDK older than iOS 27.1 runs letterboxed on the inner display of an iPhone Duo. The iOS build and the release now run on GitHub's xcode-27 image and select Xcode 27.1; the previews stay on Xcode 26.
197 lines
7.3 KiB
YAML
197 lines
7.3 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:
|
|
# Gated on a repository variable so the release can ship iOS alone while the
|
|
# Google Play account and its signing secrets are not yet in place. Set the
|
|
# repository variable NATIVE_RELEASE_ANDROID to 1 to turn the Android half on.
|
|
if: github.repository == 'liketrek/TREK' && vars.NATIVE_RELEASE_ANDROID == '1'
|
|
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@v6
|
|
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: xcode-27
|
|
timeout-minutes: 60
|
|
environment: store
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
# The iOS 27.1 SDK, on the xcode-27 image: an app built against an older SDK
|
|
# runs letterboxed on the inner display of an iPhone Duo.
|
|
- name: Select Xcode 27.1
|
|
run: |
|
|
XCODE=/Applications/Xcode_27.1.app
|
|
test -d "$XCODE"
|
|
sudo xcode-select -s "$XCODE"
|
|
xcodebuild -version
|
|
xcodebuild -showsdks | grep iphoneos27.1
|
|
|
|
- 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: Distribution certificate
|
|
env:
|
|
APPLE_DIST_CERT_P12_B64: ${{ secrets.APPLE_DIST_CERT_P12_B64 }}
|
|
run: printf '%s' "$APPLE_DIST_CERT_P12_B64" | base64 -d > "$RUNNER_TEMP/dist.p12"
|
|
|
|
# Signs for distribution and uploads to TestFlight. Automatic signing cannot
|
|
# run on a device-less CI runner (it signs for development and then needs a
|
|
# development profile, which needs a registered device), so client/fastlane/Fastfile
|
|
# imports the stored distribution certificate and creates the App Store profile
|
|
# through the API key.
|
|
# The tag's message, past its subject line, is what testers read under
|
|
# "What to Test": one short line per change worth trying.
|
|
- name: TestFlight notes from the tag
|
|
if: startsWith(github.ref, 'refs/tags/')
|
|
run: |
|
|
git fetch --force --depth=1 origin "+${GITHUB_REF}:${GITHUB_REF}"
|
|
{
|
|
echo 'TESTFLIGHT_NOTES<<TREK_NOTES_END'
|
|
# A signed tag carries its signature at the end of the message.
|
|
git for-each-ref "$GITHUB_REF" --format='%(contents:body)' | sed '/-----BEGIN .*SIGNATURE-----/,$d'
|
|
echo 'TREK_NOTES_END'
|
|
} >> "$GITHUB_ENV"
|
|
|
|
- name: Build and upload to TestFlight
|
|
working-directory: client
|
|
env:
|
|
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
|
|
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
|
|
ASC_KEY_PATH: ${{ runner.temp }}/AuthKey.p8
|
|
CERT_P12_PATH: ${{ runner.temp }}/dist.p12
|
|
CERT_P12_PASSWORD: ${{ secrets.APPLE_DIST_CERT_PASSWORD }}
|
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
MARKETING_VERSION: ${{ steps.version.outputs.version }}
|
|
CURRENT_PROJECT_VERSION: ${{ steps.version.outputs.build }}
|
|
FASTLANE_SKIP_UPDATE_CHECK: '1'
|
|
FASTLANE_HIDE_CHANGELOG: '1'
|
|
run: fastlane ios beta
|
|
|
|
- name: Remove secrets
|
|
if: always()
|
|
run: rm -f "$RUNNER_TEMP/AuthKey.p8" "$RUNNER_TEMP/dist.p12"
|