mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-03-21 22:57:17 +01:00
feat(suite-native): expo eas (#10898)
* feat(suite-native): build binaries for develop * fix(suite-native): project ID map * fix(suite-native): version
This commit is contained in:
157
.github/workflows/suite-native_develop_ci.yml
vendored
157
.github/workflows/suite-native_develop_ci.yml
vendored
@@ -14,137 +14,36 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
android_develop:
|
||||
build:
|
||||
name: Install and build
|
||||
runs-on: ubuntu-latest
|
||||
environment: develop
|
||||
timeout-minutes: 45
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Setup react-native kernel and increase watchers
|
||||
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
||||
|
||||
- name: Install dependecies
|
||||
cache: yarn
|
||||
- name: Setup EAS
|
||||
uses: expo/expo-github-action@v8
|
||||
with:
|
||||
eas-version: latest
|
||||
token: ${{ secrets.EXPO_TOKEN }}
|
||||
- name: Install libs
|
||||
run: yarn install
|
||||
|
||||
- name: Build JS libs
|
||||
run: yarn build:libs
|
||||
|
||||
- name: Expo Prebuild
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
run: yarn expo prebuild --platform android
|
||||
|
||||
- name: Decode files
|
||||
env:
|
||||
ENCODED_STRING_KEYSTORE: ${{ secrets.DEVELOP_KEYSTORE_FILE }}
|
||||
ENCODED_STRING_JSON_FILE: ${{secrets.GOOGLE_PLAY_JSON_KEY}}
|
||||
run: |
|
||||
echo $ENCODED_STRING_KEYSTORE | base64 -d > suite-native/app/android/app/release.keystore
|
||||
echo $ENCODED_STRING_JSON_FILE > suite-native/app/android/firebase_key.json
|
||||
|
||||
- name: Ruby Setup for Fastlane
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: "3.2.1"
|
||||
bundler-cache: true
|
||||
- name: Install bundler
|
||||
working-directory: suite-native/app/
|
||||
run: gem install bundler
|
||||
|
||||
- name: Fastlane build and deploy
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
SIGNING_KEY_FILE: release.keystore
|
||||
SIGNING_KEY_STORE_PASSWORD: ${{ secrets.SIGNING_KEY_STORE_PASSWORD }}
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
||||
GOOGLE_PLAY_JSON_KEY_FILE: ./android/firebase_key.json
|
||||
FIREBASE_APP_ID: ${{secrets.ANDROID_FIREBASE_APP_ID}}
|
||||
# builds and publishes the app
|
||||
run: |
|
||||
bundle install
|
||||
bundle exec fastlane android develop
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: app-apk
|
||||
path: |
|
||||
suite-native/app/android/**/*.apk
|
||||
|
||||
ios_develop:
|
||||
runs-on: macos-12
|
||||
environment: develop
|
||||
timeout-minutes: 75
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
|
||||
|
||||
- name: Restore yarn cache
|
||||
uses: actions/cache@v3
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }}
|
||||
restore-keys: |
|
||||
yarn-cache-folder-
|
||||
|
||||
- name: Decode files
|
||||
env:
|
||||
APPSTORE_CERTIFICATE_CONTENT: ${{ secrets.APPSTORE_CERTIFICATE_CONTENT }}
|
||||
run: |
|
||||
echo $APPSTORE_CERTIFICATE_CONTENT | base64 -d > suite-native/app/TrezorDistributionCertificate.p12
|
||||
|
||||
- name: Install missing Python deps (to build bcrypto lib in Node)
|
||||
run: pip install setuptools
|
||||
|
||||
- name: Install dependecies
|
||||
run: |
|
||||
yarn install
|
||||
yarn build:libs
|
||||
|
||||
- name: Expo Prebuild
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
run: yarn expo prebuild --platform ios
|
||||
|
||||
- name: Ruby Setup for Fastlane
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: "3.2.1"
|
||||
bundler-cache: true
|
||||
- name: Install bundler
|
||||
working-directory: suite-native/app/
|
||||
run: gem install bundler
|
||||
|
||||
- name: Fastlane build and deploy
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
APPSTORE_KEY_ID: ${{ secrets.APPSTORE_KEY_ID }}
|
||||
APPSTORE_KEY_ISSUER_ID: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
||||
APPSTORE_KEY_FILE_CONTENT: ${{ secrets.APPSTORE_KEY_FILE_CONTENT }}
|
||||
APPSTORE_CERTIFICATE_PASSWORD: ${{ secrets.APPSTORE_CERTIFICATE_PASSWORD }}
|
||||
TMP_KEYCHAIN_NAME: ${{ secrets.TMP_KEYCHAIN_NAME }}
|
||||
TMP_KEYCHAIN_PASSWORD: ${{ secrets.TMP_KEYCHAIN_PASSWORD }}
|
||||
|
||||
# builds and publishes the app
|
||||
run: |
|
||||
bundle install
|
||||
bundle exec fastlane ios develop
|
||||
- name: Build on EAS Android
|
||||
run: eas build
|
||||
--platform android
|
||||
--profile develop
|
||||
--non-interactive
|
||||
--no-wait
|
||||
working-directory: suite-native/app
|
||||
- name: Build on EAS iOS
|
||||
run: eas build
|
||||
--platform ios
|
||||
--profile develop
|
||||
--non-interactive
|
||||
--auto-submit
|
||||
--no-wait
|
||||
working-directory: suite-native/app
|
||||
|
||||
159
.github/workflows/suite-native_production_ci.yml
vendored
159
.github/workflows/suite-native_production_ci.yml
vendored
@@ -1,136 +1,23 @@
|
||||
name: "[Release] suite-native production"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
android_production:
|
||||
runs-on: ubuntu-latest
|
||||
environment: production
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Setup react-native kernel and increase watchers
|
||||
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
||||
|
||||
- name: Install dependecies
|
||||
run: |
|
||||
yarn install
|
||||
yarn build:libs
|
||||
|
||||
- name: Expo Prebuild
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
run: yarn expo prebuild --platform android
|
||||
|
||||
- name: Decode files
|
||||
env:
|
||||
ENCODED_STRING_KEYSTORE: ${{ secrets.PRODUCTION_KEYSTORE_FILE }}
|
||||
ENCODED_STRING_JSON_FILE: ${{secrets.PRODUCTION_GOOGLE_PLAY_JSON_KEY}}
|
||||
run: |
|
||||
echo $ENCODED_STRING_KEYSTORE | base64 -d > suite-native/app/android/app/prod-upload-key.keystore
|
||||
echo $ENCODED_STRING_JSON_FILE > suite-native/app/android/google_play_key.json
|
||||
|
||||
- name: Ruby Setup for Fastlane
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: "3.2.1"
|
||||
bundler-cache: true
|
||||
- name: Install bundler
|
||||
working-directory: suite-native/app/
|
||||
run: gem install bundler
|
||||
|
||||
- name: Fastlane build and deploy
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
SIGNING_KEY_FILE: prod-upload-key.keystore
|
||||
SIGNING_KEY_STORE_PASSWORD: ${{ secrets.SIGNING_KEY_STORE_PASSWORD_PROD }}
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS_PROD }}
|
||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD_PROD }}
|
||||
GOOGLE_PLAY_JSON_KEY_FILE: ./android/google_play_key.json
|
||||
# builds and publishes the app
|
||||
run: |
|
||||
bundle install
|
||||
bundle exec fastlane android production
|
||||
|
||||
ios_production:
|
||||
runs-on: macos-12
|
||||
environment: production
|
||||
timeout-minutes: 75
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
|
||||
|
||||
- name: Restore yarn cache
|
||||
uses: actions/cache@v3
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }}
|
||||
restore-keys: |
|
||||
yarn-cache-folder-
|
||||
|
||||
- name: Decode files
|
||||
env:
|
||||
APPSTORE_CERTIFICATE_CONTENT: ${{ secrets.APPSTORE_CERTIFICATE_CONTENT_PROD }}
|
||||
run: |
|
||||
echo $APPSTORE_CERTIFICATE_CONTENT | base64 -d > suite-native/app/TrezorDistributionCertificate.p12
|
||||
|
||||
- name: Install missing Python deps (to build bcrypto lib in Node)
|
||||
run: pip install setuptools
|
||||
|
||||
- name: Install dependecies
|
||||
run: |
|
||||
yarn install
|
||||
yarn build:libs
|
||||
|
||||
- name: Expo Prebuild
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
run: yarn expo prebuild --platform ios
|
||||
|
||||
- name: Ruby Setup for Fastlane
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: "3.2.1"
|
||||
bundler-cache: true
|
||||
- name: Install bundler
|
||||
working-directory: suite-native/app/
|
||||
run: gem install bundler
|
||||
|
||||
- name: Fastlane build and deploy
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
APPSTORE_KEY_ID: ${{ secrets.APPSTORE_KEY_ID_PROD }}
|
||||
APPSTORE_KEY_ISSUER_ID: ${{ secrets.APPSTORE_KEY_ISSUER_ID_PROD }}
|
||||
APPSTORE_KEY_FILE_CONTENT: ${{ secrets.APPSTORE_KEY_FILE_CONTENT_PROD }}
|
||||
APPSTORE_CERTIFICATE_PASSWORD: ${{ secrets.APPSTORE_CERTIFICATE_PASSWORD_PROD }}
|
||||
TMP_KEYCHAIN_NAME: ${{ secrets.APPSTORE_TMP_KEYCHAIN_NAME_PROD }}
|
||||
TMP_KEYCHAIN_PASSWORD: ${{ secrets.APPSTORE_TMP_KEYCHAIN_PASSWORD_PROD }}
|
||||
|
||||
# builds and publishes the app
|
||||
run: |
|
||||
bundle install
|
||||
bundle exec fastlane ios production
|
||||
#name: "[Build] release"
|
||||
#
|
||||
#on: [pull_request]
|
||||
#jobs:
|
||||
# build:
|
||||
# name: Install and build
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@v3
|
||||
# - uses: actions/setup-node@v3
|
||||
# with:
|
||||
# node-version-file: ".nvmrc"
|
||||
# cache: yarn
|
||||
# - name: Setup EAS
|
||||
# uses: expo/expo-github-action@v8
|
||||
# with:
|
||||
# eas-version: latest
|
||||
# token: ${{ secrets.EXPO_TOKEN }}
|
||||
# - name: Install libs
|
||||
# run: yarn install
|
||||
# - name: Build on EAS
|
||||
# run: eas build --platform all --profile production --auto-submit --non-interactive
|
||||
# working-directory: suite-native/app
|
||||
|
||||
131
.github/workflows/suite-native_staging_ci.yml
vendored
131
.github/workflows/suite-native_staging_ci.yml
vendored
@@ -1,131 +0,0 @@
|
||||
name: "[Release]: suite-native staging"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
android_staging:
|
||||
runs-on: ubuntu-latest
|
||||
environment: staging
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Setup react-native kernel and increase watchers
|
||||
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
||||
|
||||
- name: Expo Prebuild
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
run: yarn expo prebuild --platform android
|
||||
|
||||
- name: Decode files
|
||||
env:
|
||||
ENCODED_STRING_KEYSTORE: ${{ secrets.STAGING_KEYSTORE_FILE }}
|
||||
ENCODED_STRING_JSON_FILE: ${{secrets.GOOGLE_PLAY_JSON_KEY_STAGING}}
|
||||
run: |
|
||||
echo $ENCODED_STRING_KEYSTORE | base64 -d > suite-native/app/android/app/stag-upload-key.keystore
|
||||
echo $ENCODED_STRING_JSON_FILE > suite-native/app/android/google_play_key.json
|
||||
|
||||
- name: Ruby Setup for Fastlane
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: "3.2.1"
|
||||
bundler-cache: true
|
||||
- name: Install bundler
|
||||
working-directory: suite-native/app/
|
||||
run: gem install bundler
|
||||
|
||||
- name: Fastlane build and deploy
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
SIGNING_KEY_FILE: stag-upload-key.keystore
|
||||
SIGNING_KEY_STORE_PASSWORD: ${{ secrets.SIGNING_KEY_STORE_PASSWORD_STAGING }}
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS_STAGING }}
|
||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD_STAGING }}
|
||||
GOOGLE_PLAY_JSON_KEY_FILE: ./android/google_play_key.json
|
||||
# builds and publishes the app
|
||||
run: |
|
||||
bundle install
|
||||
bundle exec fastlane android staging
|
||||
|
||||
ios_staging:
|
||||
runs-on: macos-12
|
||||
environment: staging
|
||||
timeout-minutes: 75
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
|
||||
|
||||
- name: Restore yarn cache
|
||||
uses: actions/cache@v3
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }}
|
||||
restore-keys: |
|
||||
yarn-cache-folder-
|
||||
|
||||
- name: Decode files
|
||||
env:
|
||||
APPSTORE_CERTIFICATE_CONTENT: ${{ secrets.APPSTORE_CERTIFICATE_CONTENT_STAGING }}
|
||||
run: |
|
||||
echo $APPSTORE_CERTIFICATE_CONTENT | base64 -d > suite-native/app/TrezorDistributionCertificate.p12
|
||||
|
||||
- name: Install missing Python deps (to build bcrypto lib in Node)
|
||||
run: pip install setuptools
|
||||
|
||||
- name: Install dependecies
|
||||
run: |
|
||||
yarn install
|
||||
yarn build:libs
|
||||
|
||||
- name: Expo Prebuild
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
run: yarn expo prebuild --platform ios
|
||||
|
||||
- name: Ruby Setup for Fastlane
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: "3.2.1"
|
||||
bundler-cache: true
|
||||
- name: Install bundler
|
||||
working-directory: suite-native/app/
|
||||
run: gem install bundler
|
||||
|
||||
- name: Fastlane build and deploy
|
||||
working-directory: suite-native/app/
|
||||
env:
|
||||
APPSTORE_KEY_ID: ${{ secrets.APPSTORE_KEY_ID_STAGING }}
|
||||
APPSTORE_KEY_ISSUER_ID: ${{ secrets.APPSTORE_KEY_ISSUER_ID_STAGING }}
|
||||
APPSTORE_KEY_FILE_CONTENT: ${{ secrets.APPSTORE_KEY_FILE_CONTENT_STAGING }}
|
||||
APPSTORE_CERTIFICATE_PASSWORD: ${{ secrets.APPSTORE_CERTIFICATE_PASSWORD_STAGING }}
|
||||
TMP_KEYCHAIN_NAME: ${{ secrets.APPSTORE_TMP_KEYCHAIN_NAME_STAGING }}
|
||||
TMP_KEYCHAIN_PASSWORD: ${{ secrets.APPSTORE_TMP_KEYCHAIN_PASSWORD_STAGING }}
|
||||
|
||||
# builds and publishes the app
|
||||
run: |
|
||||
bundle install
|
||||
bundle exec fastlane ios staging
|
||||
@@ -10,7 +10,10 @@ const MESSAGES_SRC = '../../packages/protobuf/messages.json';
|
||||
|
||||
const DIST = path.resolve(__dirname, '../build');
|
||||
|
||||
const commitHash = execSync('git rev-parse HEAD').toString().trim();
|
||||
// Because of Expo EAS, we need to use the commit hash from expo to avoid failing git command inside EAS
|
||||
// because we need to call `yarn build:libs during native build`
|
||||
const commitHash =
|
||||
process.env.EAS_BUILD_GIT_COMMIT_HASH || execSync('git rev-parse HEAD').toString().trim();
|
||||
|
||||
export const config: webpack.Configuration = {
|
||||
target: 'web',
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"prepublish": "yarn g:tsx ../../scripts/prepublish.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"expo-constants": "15.4.5",
|
||||
"ua-parser-js": "^1.0.37"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Dimensions, Platform } from 'react-native';
|
||||
|
||||
import { getLocales } from 'expo-localization';
|
||||
import Constants from 'expo-constants';
|
||||
|
||||
import { EnvUtils } from './types';
|
||||
|
||||
@@ -24,9 +25,9 @@ const getDeviceType = () => '';
|
||||
|
||||
const getOsVersion = () => `${Platform.Version}`;
|
||||
|
||||
const getSuiteVersion = () => process.env.EXPO_PUBLIC_VERSION || '';
|
||||
const getSuiteVersion = () => Constants.expoConfig?.version || '';
|
||||
|
||||
const getCommitHash = () => process.env.EXPO_PUBLIC_COMMIT_HASH || '';
|
||||
const getCommitHash = () => Constants.expoConfig?.extra?.commitHash;
|
||||
|
||||
const isFirefox = () => false;
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
EXPO_PUBLIC_ENVIRONMENT=debug
|
||||
EXPO_PUBLIC_COMMIT_HASH=
|
||||
EXPO_PUBLIC_CHANGELOG=
|
||||
EXPO_PUBLIC_VERSION=
|
||||
EXPO_PUBLIC_BUILD_NUMBER=
|
||||
EXPO_PUBLIC_CODESIGN_BUILD=false
|
||||
EXPO_PUBLIC_JWS_PUBLIC_KEY='-----BEGIN PUBLIC KEY-----MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbSUHJlr17+NywPS/w+xMkp3dSD8eWXSuAfFKwonZPe5fL63kISipJC+eJP7Mad0WxgyJoiMsZCV6BZPK2jIFdg==-----END PUBLIC KEY-----'
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
EXPO_PUBLIC_ENVIRONMENT=develop
|
||||
EXPO_PUBLIC_COMMIT_HASH=
|
||||
EXPO_PUBLIC_CHANGELOG=
|
||||
EXPO_PUBLIC_VERSION=
|
||||
EXPO_PUBLIC_BUILD_NUMBER=
|
||||
EXPO_PUBLIC_CODESIGN_BUILD=false
|
||||
EXPO_PUBLIC_JWS_PUBLIC_KEY='-----BEGIN PUBLIC KEY-----MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbSUHJlr17+NywPS/w+xMkp3dSD8eWXSuAfFKwonZPe5fL63kISipJC+eJP7Mad0WxgyJoiMsZCV6BZPK2jIFdg==-----END PUBLIC KEY-----'
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
EXPO_PUBLIC_ENVIRONMENT=production
|
||||
EXPO_PUBLIC_COMMIT_HASH=
|
||||
EXPO_PUBLIC_CHANGELOG=
|
||||
EXPO_PUBLIC_VERSION=
|
||||
EXPO_PUBLIC_BUILD_NUMBER=
|
||||
EXPO_PUBLIC_CODESIGN_BUILD=true
|
||||
EXPO_PUBLIC_JWS_PUBLIC_KEY='-----BEGIN PUBLIC KEY-----MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAES7MbBzU/v5BsljkTM8Mz0Jsk+Nn5n2wH\no2/+MUI3TgCVdTbEHhn3HXaY7GJ6TLyWqxn+pIDY9wUUAyUqOStTUQ==-----END PUBLIC KEY-----'
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
EXPO_PUBLIC_ENVIRONMENT=staging
|
||||
EXPO_PUBLIC_COMMIT_HASH=
|
||||
EXPO_PUBLIC_CHANGELOG=
|
||||
EXPO_PUBLIC_VERSION=
|
||||
EXPO_PUBLIC_BUILD_NUMBER=
|
||||
EXPO_PUBLIC_CODESIGN_BUILD=false
|
||||
EXPO_PUBLIC_JWS_PUBLIC_KEY='-----BEGIN PUBLIC KEY-----MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAES7MbBzU/v5BsljkTM8Mz0Jsk+Nn5n2wH\no2/+MUI3TgCVdTbEHhn3HXaY7GJ6TLyWqxn+pIDY9wUUAyUqOStTUQ==-----END PUBLIC KEY-----'
|
||||
@@ -36,14 +36,6 @@ Because of usage of new Fabric architecture, it is not possible to use Chrome de
|
||||
|
||||
Best way how to debug app is download [Flipper](https://fbflipper.com).
|
||||
|
||||
## Distribution
|
||||
|
||||
Fastlane is the easiest way to automate beta deployments and releases for iOS and Android apps.
|
||||
|
||||
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
|
||||
|
||||
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
|
||||
|
||||
### Installation
|
||||
|
||||
Make sure you have the latest version of the Xcode command line tools installed:
|
||||
@@ -51,69 +43,3 @@ Make sure you have the latest version of the Xcode command line tools installed:
|
||||
```sh
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
|
||||
|
||||
### Available Actions
|
||||
|
||||
#### iOS
|
||||
|
||||
##### iOS develop
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios develop
|
||||
```
|
||||
|
||||
Push a new beta build to TestFlight for develop build schema.
|
||||
|
||||
---
|
||||
|
||||
##### iOS staging
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios staging
|
||||
```
|
||||
|
||||
Push a new beta build to TestFlight for staging build schema.
|
||||
|
||||
---
|
||||
|
||||
##### iOS production
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios production
|
||||
```
|
||||
|
||||
TODO
|
||||
|
||||
---
|
||||
|
||||
#### Android
|
||||
|
||||
##### android develop
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android develop
|
||||
```
|
||||
|
||||
Build and upload the app (develop) to Firebase App Distribution for testing in a small group of testers.
|
||||
|
||||
---
|
||||
|
||||
##### android staging
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android staging
|
||||
```
|
||||
|
||||
Build and upload the app (staging) to Google Play Store for internal testing.
|
||||
|
||||
---
|
||||
|
||||
##### android production
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android production
|
||||
```
|
||||
|
||||
Build and upload the app (production) to Google Play Store for internal testing.
|
||||
|
||||
@@ -4,31 +4,19 @@ import { ExpoConfig, ConfigContext } from 'expo/config';
|
||||
|
||||
import { suiteNativeVersion } from './package.json';
|
||||
|
||||
type BuildType = 'debug' | 'develop' | 'staging' | 'production';
|
||||
|
||||
const getBuildType = (): BuildType => {
|
||||
if (process.env.ENVIRONMENT === 'production') return 'production';
|
||||
if (process.env.ENVIRONMENT === 'staging') return 'staging';
|
||||
if (process.env.ENVIRONMENT === 'develop') return 'develop';
|
||||
return 'debug';
|
||||
};
|
||||
const buildType = getBuildType();
|
||||
type BuildType = 'debug' | 'develop' | 'production';
|
||||
|
||||
const bundleIdentifiers = {
|
||||
debug: 'io.trezor.suite.debug',
|
||||
develop: 'io.trezor.suite.develop',
|
||||
staging: 'io.trezor.suite.staging',
|
||||
production: 'io.trezor.suite',
|
||||
} as const satisfies Record<BuildType, string>;
|
||||
const bundleIdentifier = bundleIdentifiers[buildType];
|
||||
|
||||
const appIconsIos = {
|
||||
debug: './assets/debug/appIcon.png',
|
||||
develop: './assets/develop/appIcon.png',
|
||||
staging: './assets/staging/appIcon.png',
|
||||
production: './assets/production/appIcon.png',
|
||||
} as const satisfies Record<BuildType, string>;
|
||||
const appIconIos = appIconsIos[buildType];
|
||||
|
||||
const appIconsAndroid = {
|
||||
debug: {
|
||||
@@ -37,95 +25,133 @@ const appIconsAndroid = {
|
||||
develop: {
|
||||
backgroundColor: '#900B0B',
|
||||
},
|
||||
staging: {
|
||||
backgroundColor: '#E49C18',
|
||||
},
|
||||
production: {
|
||||
backgroundColor: '#0F6148',
|
||||
},
|
||||
} as const;
|
||||
const appIconAndroid = appIconsAndroid[buildType];
|
||||
|
||||
const appNames = {
|
||||
debug: 'Trezor Suite Debug',
|
||||
develop: 'Trezor Suite Develop',
|
||||
staging: 'Trezor Suite Staging',
|
||||
production: 'Trezor Suite',
|
||||
} as const satisfies Record<BuildType, string>;
|
||||
const appName = appNames[buildType];
|
||||
const appSlug = appName.replace(/\s/g, '');
|
||||
|
||||
if (!process.env.SENTRY_AUTH_TOKEN && buildType !== 'debug') {
|
||||
throw new Error('Missing SENTRY_AUTH_TOKEN env variable');
|
||||
}
|
||||
const projectIds = {
|
||||
develop: '3e4ea82b-6c9f-4cd3-8975-54bddda3ec2d',
|
||||
production: 'b9bbf16c-3d44-4d58-8f0c-ba9e6265276a',
|
||||
debug: '',
|
||||
} as const satisfies Record<BuildType, string>;
|
||||
|
||||
export default ({ config }: ConfigContext): ExpoConfig => ({
|
||||
...config,
|
||||
name: appName,
|
||||
slug: appSlug,
|
||||
version: suiteNativeVersion,
|
||||
splash: {
|
||||
image: './assets/splash_icon.png',
|
||||
backgroundColor: '#25292E',
|
||||
resizeMode: 'contain',
|
||||
},
|
||||
android: {
|
||||
package: bundleIdentifier,
|
||||
versionCode: 1,
|
||||
adaptiveIcon: {
|
||||
foregroundImage: './assets/appIcon_android.png',
|
||||
monochromeImage: './assets/appIcon_android.png',
|
||||
...appIconAndroid,
|
||||
export default ({ config }: ConfigContext): ExpoConfig => {
|
||||
const buildType = (process.env.ENVIRONMENT_EXPO as BuildType) ?? 'debug';
|
||||
const name = appNames[buildType];
|
||||
const slug = appNames[buildType].toLowerCase().split(' ').join('-');
|
||||
const bundleIdentifier = bundleIdentifiers[buildType];
|
||||
const projectId = projectIds[buildType];
|
||||
const appIconIos = appIconsIos[buildType];
|
||||
const appIconAndroid = appIconsAndroid[buildType];
|
||||
|
||||
if (!process.env.SENTRY_AUTH_TOKEN && buildType !== 'debug') {
|
||||
throw new Error('Missing SENTRY_AUTH_TOKEN env variable');
|
||||
}
|
||||
|
||||
return {
|
||||
...config,
|
||||
name,
|
||||
slug,
|
||||
version: suiteNativeVersion,
|
||||
splash: {
|
||||
image: './assets/splash_icon.png',
|
||||
backgroundColor: '#25292E',
|
||||
resizeMode: 'contain',
|
||||
},
|
||||
},
|
||||
ios: {
|
||||
bundleIdentifier,
|
||||
icon: appIconIos,
|
||||
},
|
||||
plugins: [
|
||||
[
|
||||
'expo-font',
|
||||
{
|
||||
fonts: [
|
||||
'../../packages/theme/fonts/TTSatoshi-Medium.otf',
|
||||
'../../packages/theme/fonts/TTSatoshi-DemiBold.otf',
|
||||
android: {
|
||||
package: bundleIdentifier,
|
||||
adaptiveIcon: {
|
||||
foregroundImage: './assets/appIcon_android.png',
|
||||
monochromeImage: './assets/appIcon_android.png',
|
||||
...appIconAndroid,
|
||||
},
|
||||
},
|
||||
ios: {
|
||||
bundleIdentifier,
|
||||
icon: appIconIos,
|
||||
infoPlist: {
|
||||
NSCameraUsageDescription:
|
||||
'$(PRODUCT_NAME) needs access to your Camera to scan your XPUB.',
|
||||
NSFaceIDUsageDescription:
|
||||
'$(PRODUCT_NAME) needs Face ID and Touch ID to keep sensitive data about your portfolio private.',
|
||||
NSMicrophoneUsageDescription: 'This app does not require access to the microphone.',
|
||||
ITSAppUsesNonExemptEncryption: false,
|
||||
UISupportedInterfaceOrientations: [
|
||||
'UIInterfaceOrientationPortrait',
|
||||
'UIInterfaceOrientationPortraitUpsideDown',
|
||||
],
|
||||
},
|
||||
],
|
||||
[
|
||||
'@sentry/react-native/expo',
|
||||
{
|
||||
url: 'https://sentry.io/',
|
||||
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||
project: 'suite-native',
|
||||
organization: 'satoshilabs',
|
||||
},
|
||||
],
|
||||
[
|
||||
'expo-barcode-scanner',
|
||||
{
|
||||
cameraPermission: 'Allow $(PRODUCT_NAME) to access camera for QR code scanning.',
|
||||
},
|
||||
],
|
||||
[
|
||||
'expo-build-properties',
|
||||
{
|
||||
android: {
|
||||
minSdkVersion: 28,
|
||||
},
|
||||
ios: {
|
||||
deploymentTarget: '14.0',
|
||||
flipper: 'true',
|
||||
NSAppTransportSecurity: {
|
||||
NSAllowsArbitraryLoads: true,
|
||||
NSExceptionDomains: {
|
||||
localhost: {
|
||||
NSExceptionAllowsInsecureHTTPLoads: true,
|
||||
},
|
||||
'data.trezor.io': {
|
||||
NSExceptionAllowsInsecureHTTPLoads: true,
|
||||
NSIncludesSubdomains: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
[
|
||||
'expo-font',
|
||||
{
|
||||
fonts: [
|
||||
'../../packages/theme/fonts/TTSatoshi-Medium.otf',
|
||||
'../../packages/theme/fonts/TTSatoshi-DemiBold.otf',
|
||||
],
|
||||
},
|
||||
],
|
||||
[
|
||||
'@sentry/react-native/expo',
|
||||
{
|
||||
url: 'https://sentry.io/',
|
||||
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||
project: 'suite-native',
|
||||
organization: 'satoshilabs',
|
||||
},
|
||||
],
|
||||
[
|
||||
'expo-barcode-scanner',
|
||||
{
|
||||
cameraPermission:
|
||||
'Allow $(PRODUCT_NAME) to access camera for QR code scanning.',
|
||||
},
|
||||
],
|
||||
[
|
||||
'expo-build-properties',
|
||||
{
|
||||
android: {
|
||||
minSdkVersion: 28,
|
||||
},
|
||||
ios: {
|
||||
deploymentTarget: '14.0',
|
||||
flipper: 'true',
|
||||
},
|
||||
},
|
||||
],
|
||||
'@trezor/react-native-usb/plugins/withUSBDevice.js',
|
||||
// Define FLIPPER_VERSION
|
||||
'./plugins/withGradleProperties.js',
|
||||
// These should come last
|
||||
'./plugins/withRemoveXcodeLocalEnv.js',
|
||||
['./plugins/withEnvFile.js', { buildType }],
|
||||
],
|
||||
'@trezor/react-native-usb/plugins/withUSBDevice.js',
|
||||
// Define FLIPPER_VERSION
|
||||
'./plugins/withGradleProperties.js',
|
||||
// These should come last
|
||||
'./plugins/withRemoveXcodeLocalEnv.js',
|
||||
['./plugins/withEnvFile.js', { buildType }],
|
||||
// This plugin must be removed once we use EAS
|
||||
'./plugins/withAndroidSigningConfig.js',
|
||||
],
|
||||
});
|
||||
extra: {
|
||||
commitHash: process.env.EAS_BUILD_GIT_COMMIT_HASH?.substring(-6) || '',
|
||||
eas: {
|
||||
projectId,
|
||||
},
|
||||
},
|
||||
owner: 'trezorcompany',
|
||||
};
|
||||
};
|
||||
|
||||
57
suite-native/app/eas.json
Normal file
57
suite-native/app/eas.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"cli": {
|
||||
"version": ">= 7.1.1",
|
||||
"promptToConfigurePushNotifications": false,
|
||||
"appVersionSource": "remote"
|
||||
},
|
||||
"build": {
|
||||
"develop": {
|
||||
"env": {
|
||||
"ENVIRONMENT_EXPO": "develop"
|
||||
},
|
||||
"autoIncrement": true,
|
||||
"ios": {
|
||||
"distribution": "store"
|
||||
},
|
||||
"android": {
|
||||
"distribution": "internal"
|
||||
}
|
||||
},
|
||||
"production": {
|
||||
"env": {
|
||||
"ENVIRONMENT_EXPO": "production"
|
||||
},
|
||||
"autoIncrement": true,
|
||||
"android": {
|
||||
"credentialsSource": "remote"
|
||||
},
|
||||
"ios": {
|
||||
"credentialsSource": "remote"
|
||||
}
|
||||
}
|
||||
},
|
||||
"submit": {
|
||||
"develop": {
|
||||
"android": {
|
||||
"track": "internal",
|
||||
"changesNotSentForReview": true
|
||||
},
|
||||
"ios": {
|
||||
"bundleIdentifier": "io.trezor.suite.develop",
|
||||
"ascAppId": "1631884497",
|
||||
"appleTeamId": "C3P22XVH2C"
|
||||
}
|
||||
},
|
||||
"production": {
|
||||
"android": {
|
||||
"track": "internal",
|
||||
"changesNotSentForReview": true
|
||||
},
|
||||
"ios": {
|
||||
"bundleIdentifier": "io.trezor.suite",
|
||||
"ascAppId": "1631884497",
|
||||
"appleTeamId": "C3P22XVH2C"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
skip_docs
|
||||
|
||||
# Paths
|
||||
APP_GRADLE_PATH = File.join(ANDROID_PATH, 'app/build.gradle').freeze
|
||||
|
||||
platform :android do
|
||||
|
||||
before_all do |lane|
|
||||
if lane == :develop
|
||||
fetch_and_bump_firebase_version
|
||||
elsif lane == :staging
|
||||
TRACK = "internal"
|
||||
fetch_and_bump_play_version
|
||||
elsif lane == :production
|
||||
TRACK = "internal"
|
||||
fetch_and_bump_play_version
|
||||
end
|
||||
|
||||
ENV["ENVFILE"] = ".env"
|
||||
replace_debug_info_environment_variables
|
||||
end
|
||||
|
||||
desc "Android: Increments internal build number and version number"
|
||||
private_lane :fetch_and_bump_play_version do
|
||||
google_play_json_key_file = CredentialsManager::AppfileConfig.try_fetch_value(:json_key_file)
|
||||
package_name = CredentialsManager::AppfileConfig.try_fetch_value(:package_name)
|
||||
|
||||
previous_build_number = google_play_track_version_codes(
|
||||
package_name: package_name,
|
||||
track: TRACK,
|
||||
json_key: google_play_json_key_file,
|
||||
)[0]
|
||||
|
||||
build_number_int = previous_build_number + 1
|
||||
ENV["EXPO_PUBLIC_BUILD_NUMBER"] = "#{build_number_int}"
|
||||
|
||||
android_set_version_code(gradle_file: APP_GRADLE_PATH, version_code: build_number_int)
|
||||
android_set_version_name(gradle_file: APP_GRADLE_PATH, version_name: ENV["EXPO_PUBLIC_VERSION"])
|
||||
end
|
||||
|
||||
private_lane :fetch_and_bump_firebase_version do
|
||||
google_play_json_key_file = CredentialsManager::AppfileConfig.try_fetch_value(:json_key_file)
|
||||
latest_release = firebase_app_distribution_get_latest_release(
|
||||
app: ANDROID_FIREBASE_APP_ID,
|
||||
service_credentials_file: google_play_json_key_file,
|
||||
)
|
||||
|
||||
build_number_int = latest_release[:buildVersion].to_i + 1
|
||||
ENV["EXPO_PUBLIC_BUILD_NUMBER"] = "#{build_number_int}"
|
||||
|
||||
# when there are no Firebase releases yet
|
||||
unless latest_release.nil?
|
||||
android_set_version_code(gradle_file: APP_GRADLE_PATH, version_code: build_number_int)
|
||||
end
|
||||
android_set_version_name(gradle_file: APP_GRADLE_PATH, version_name: ENV["EXPO_PUBLIC_VERSION"])
|
||||
end
|
||||
|
||||
desc "Build and upload the app to Google Play Store."
|
||||
private_lane :deploy_android_play_store do |options|
|
||||
productFlavor = options[:flavor]
|
||||
|
||||
gradle(task: 'clean', project_dir: ANDROID_PATH)
|
||||
|
||||
gradle(
|
||||
task: 'bundle',
|
||||
flavor: productFlavor,
|
||||
print_command: true,
|
||||
build_type: 'Release',
|
||||
project_dir: ANDROID_PATH
|
||||
)
|
||||
|
||||
# Upload Android App Bundle to PlayStore like Internal testing Release
|
||||
upload_to_play_store(
|
||||
track: TRACK,
|
||||
# set as "draft" to complete the release at some other time in PlayStore
|
||||
release_status: 'draft', # <http://docs.fastlane.tools/actions/upload_to_play_store/#parameters>
|
||||
skip_upload_images: true,
|
||||
skip_upload_screenshots: true,
|
||||
skip_upload_apk: true
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
desc "Build Debug build."
|
||||
lane :debugging do |options|
|
||||
gradle(task: 'clean', project_dir: ANDROID_PATH)
|
||||
|
||||
gradle(
|
||||
task: 'assemble',
|
||||
flavor: 'Dev',
|
||||
build_type: 'Debug',
|
||||
project_dir: ANDROID_PATH
|
||||
)
|
||||
end
|
||||
|
||||
desc "Deploy staging build to Google Play Store."
|
||||
lane :staging do |options|
|
||||
deploy_android_play_store(flavor: "Stag")
|
||||
end
|
||||
|
||||
desc "Deploy production build to Google Play Store."
|
||||
lane :production do |options|
|
||||
deploy_android_play_store(flavor: "Prod")
|
||||
end
|
||||
|
||||
desc "Build and deploy the app to Firebase App Distribution for develop build."
|
||||
lane :develop do |options|
|
||||
google_play_json_key_file = CredentialsManager::AppfileConfig.try_fetch_value(:json_key_file)
|
||||
|
||||
gradle(task: 'clean', project_dir: ANDROID_PATH)
|
||||
|
||||
gradle(
|
||||
task: 'assemble',
|
||||
flavor: 'FirebaseDevelop',
|
||||
build_type: 'Release',
|
||||
project_dir: ANDROID_PATH
|
||||
)
|
||||
|
||||
# find apk path
|
||||
output_path = File.join(ANDROID_PATH, 'android/app/build/outputs/apk/').freeze
|
||||
output_json_path = output_path + "output-metadata.json"
|
||||
build_output = load_json(json_path: output_json_path)
|
||||
elements = build_output["elements"][0]
|
||||
apk_path = output_path + elements["outputFile"]
|
||||
|
||||
firebase_app_distribution(
|
||||
app: ANDROID_FIREBASE_APP_ID,
|
||||
apk_path: apk_path,
|
||||
service_credentials_file: google_play_json_key_file,
|
||||
release_notes: "#{ENV["EXPO_PUBLIC_COMMIT_HASH"]} - #{ENV["EXPO_PUBLIC_CHANGELOG"]}",
|
||||
groups: "develop-testers",
|
||||
debug: true
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -1,36 +0,0 @@
|
||||
# iOS
|
||||
for_platform :ios do
|
||||
itc_team_id("119058140") # App Store Connect Team ID
|
||||
team_id("C3P22XVH2C") # Developer Portal Team ID
|
||||
|
||||
for_lane :debugging do
|
||||
app_identifier 'io.trezor.suite.debug'
|
||||
end
|
||||
for_lane :develop do
|
||||
app_identifier 'io.trezor.suite.develop'
|
||||
end
|
||||
for_lane :staging do
|
||||
app_identifier 'io.trezor.suite.staging'
|
||||
end
|
||||
for_lane :production do
|
||||
app_identifier 'io.trezor.suite'
|
||||
end
|
||||
end
|
||||
|
||||
# Android
|
||||
for_platform :android do
|
||||
json_key_file(ENV['GOOGLE_PLAY_JSON_KEY_FILE']) # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
|
||||
|
||||
for_lane :debugging do
|
||||
package_name 'io.trezor.suite.debug'
|
||||
end
|
||||
for_lane :develop do
|
||||
package_name 'io.trezor.suite.develop'
|
||||
end
|
||||
for_lane :staging do
|
||||
package_name 'io.trezor.suite.staging'
|
||||
end
|
||||
for_lane :production do
|
||||
package_name 'io.trezor.suite'
|
||||
end
|
||||
end
|
||||
@@ -1,63 +0,0 @@
|
||||
# Common Functions and Requirements
|
||||
# across Android/iOS Fastfiles
|
||||
|
||||
# necessary for sed when a branch name includes slash
|
||||
def escape_slash(string)
|
||||
string.gsub('/', '\/')
|
||||
end
|
||||
|
||||
# Path Constants
|
||||
SUITE_NATIVE_ROOT_PATH = File.expand_path('../', Dir.pwd).freeze
|
||||
|
||||
# Android project
|
||||
ANDROID_PATH = File.join(SUITE_NATIVE_ROOT_PATH, 'android').freeze
|
||||
ANDROID_FIREBASE_APP_ID = ENV['FIREBASE_APP_ID']
|
||||
|
||||
# iOS project
|
||||
IOS_PATH = File.join(SUITE_NATIVE_ROOT_PATH, 'ios').freeze
|
||||
|
||||
# Retrieve version of Suite Native app in package.json
|
||||
PACKAGE_JSON_PATH = File.join(SUITE_NATIVE_ROOT_PATH, 'package.json').freeze
|
||||
|
||||
commit = last_git_commit
|
||||
commit_message = commit[:message]
|
||||
commit_hash = commit[:abbreviated_commit_hash]
|
||||
|
||||
ENV["EXPO_PUBLIC_COMMIT_HASH"] = "#{commit_hash}"
|
||||
ENV["EXPO_PUBLIC_CHANGELOG"] = escape_slash "[#{git_branch}] - #{commit_message}".strip
|
||||
ENV["EXPO_PUBLIC_VERSION"] = load_json(json_path: "package.json")["suiteNativeVersion"]
|
||||
|
||||
private_lane :replace_debug_info_environment_variables do |options|
|
||||
platform = lane_context[SharedValues::PLATFORM_NAME]
|
||||
environment_file_name = ENV["ENVFILE"]
|
||||
environment_file = File.join(SUITE_NATIVE_ROOT_PATH, environment_file_name)
|
||||
|
||||
commit_hash_substitute = "s/^(EXPO_PUBLIC_COMMIT_HASH)=(.*)$/\\1=#{ENV["EXPO_PUBLIC_COMMIT_HASH"]}/"
|
||||
changelog_substitute = "s/^(EXPO_PUBLIC_CHANGELOG)=(.*)$/\\1=#{ENV["EXPO_PUBLIC_CHANGELOG"]}/"
|
||||
version_substitute = "s/^(EXPO_PUBLIC_VERSION)=(.*)$/\\1=#{ENV["EXPO_PUBLIC_VERSION"]}/"
|
||||
build_number_substitute = "s/^(EXPO_PUBLIC_BUILD_NUMBER)=(.*)$/\\1=#{ENV["EXPO_PUBLIC_BUILD_NUMBER"]}/"
|
||||
|
||||
if is_ci and platform == :ios
|
||||
sh(
|
||||
<<-SHELL
|
||||
sed -r -i '' '#{commit_hash_substitute}' '#{environment_file}'
|
||||
sed -r -i '' '#{changelog_substitute}' '#{environment_file}'
|
||||
sed -r -i '' '#{version_substitute}' '#{environment_file}'
|
||||
sed -r -i '' '#{build_number_substitute}' '#{environment_file}'
|
||||
SHELL
|
||||
)
|
||||
elsif is_ci and platform == :android
|
||||
sh(
|
||||
<<-SHELL
|
||||
sed -r -i '#{commit_hash_substitute}' '#{environment_file}'
|
||||
sed -r -i '#{changelog_substitute}' '#{environment_file}'
|
||||
sed -r -i '#{version_substitute}' '#{environment_file}'
|
||||
sed -r -i '#{build_number_substitute}' '#{environment_file}'
|
||||
SHELL
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
import "./IosFastfile"
|
||||
import "./AndroidFastfile"
|
||||
@@ -1,249 +0,0 @@
|
||||
skip_docs
|
||||
|
||||
# iOS Specific Constants
|
||||
IOS_PROJECT = File.join(IOS_PATH, "TrezorSuite.xcodeproj").freeze
|
||||
IOS_PROJECT_WORKSPACE = File.join(IOS_PATH, "TrezorSuite.xcworkspace").freeze
|
||||
|
||||
# temporary keychain database
|
||||
def delete_temp_keychain(name)
|
||||
delete_keychain(
|
||||
name: name
|
||||
) if File.exist? File.expand_path("~/Library/Keychains/#{name}-db")
|
||||
end
|
||||
|
||||
def create_temp_keychain(name, password)
|
||||
create_keychain(
|
||||
name: name,
|
||||
password: password,
|
||||
unlock: true,
|
||||
default_keychain: true,
|
||||
add_to_search_list: true,
|
||||
lock_when_sleeps: false,
|
||||
timeout: 3600
|
||||
)
|
||||
end
|
||||
|
||||
def ensure_temp_keychain(name, password)
|
||||
delete_temp_keychain(name)
|
||||
create_temp_keychain(name, password)
|
||||
end
|
||||
|
||||
platform :ios do
|
||||
|
||||
before_all do |lane|
|
||||
xcversion(version: "14.1")
|
||||
app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
|
||||
|
||||
puts "Running lane #{lane} with App ID #{app_identifier}."
|
||||
|
||||
if lane != :debugging
|
||||
PROVISIONING_NAME = "AppStore #{app_identifier}"
|
||||
import_certificate_to_keychain
|
||||
load_appstore_connect_api_key
|
||||
fetch_and_bump_versions
|
||||
else
|
||||
PROVISIONING_NAME = "#{app_identifier} Development"
|
||||
end
|
||||
|
||||
ENV["ENVFILE"] = ".env"
|
||||
replace_debug_info_environment_variables
|
||||
end
|
||||
|
||||
desc "Import certificate to keychain"
|
||||
private_lane :import_certificate_to_keychain do
|
||||
# creates temporary keychain
|
||||
keychain_name = ENV['TMP_KEYCHAIN_NAME']
|
||||
keychain_password = ENV['TMP_KEYCHAIN_PASSWORD']
|
||||
ensure_temp_keychain(keychain_name, keychain_password)
|
||||
|
||||
# import certificate to temporary keychain
|
||||
import_certificate(
|
||||
keychain_name: ENV['TMP_KEYCHAIN_NAME'],
|
||||
keychain_password: ENV['TMP_KEYCHAIN_PASSWORD'],
|
||||
certificate_path: "TrezorDistributionCertificate.p12",
|
||||
certificate_password: ENV["APPSTORE_CERTIFICATE_PASSWORD"] || "default"
|
||||
)
|
||||
end
|
||||
|
||||
desc "Load Appstore Connect API Key information to use in subsequent lanes"
|
||||
private_lane :load_appstore_connect_api_key do
|
||||
app_store_connect_api_key(
|
||||
key_id: ENV['APPSTORE_KEY_ID'], # the Key ID used for Appstore Connect authentication
|
||||
issuer_id: ENV['APPSTORE_KEY_ISSUER_ID'], # the issuer ID used for Appstore Connect authentication
|
||||
key_content: ENV['APPSTORE_KEY_FILE_CONTENT'], # the base64-encoded private key (.p8) used for Appstore Connect authentication
|
||||
is_key_content_base64: true,
|
||||
duration: 1200,
|
||||
in_house: false
|
||||
)
|
||||
end
|
||||
|
||||
desc "Check certs and profiles"
|
||||
private_lane :prepare_distribution_signing do
|
||||
app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
|
||||
api_key = lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
|
||||
|
||||
# it makes sure you have a valid certificate and its private key installed on the local machine
|
||||
cert(
|
||||
api_key: api_key,
|
||||
keychain_path: "~/Library/Keychains/#{ENV['TMP_KEYCHAIN_NAME']}-db",
|
||||
keychain_password: ENV["TMP_KEYCHAIN_PASSWORD"]
|
||||
)
|
||||
|
||||
# it makes sure you have a valid provisioning profile installed locally, that matches the installed certificate
|
||||
sigh(
|
||||
api_key: api_key,
|
||||
app_identifier: app_identifier,
|
||||
provisioning_name: PROVISIONING_NAME,
|
||||
force: true # always recreate this exact profile to ensure it's valid and not expired
|
||||
)
|
||||
end
|
||||
|
||||
desc "Increments internal build number and version number"
|
||||
private_lane :fetch_and_bump_versions do
|
||||
app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
|
||||
api_key = lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
|
||||
|
||||
previous_build_number = latest_testflight_build_number(
|
||||
app_identifier: app_identifier,
|
||||
api_key: api_key
|
||||
)
|
||||
|
||||
build_number_int = previous_build_number + 1
|
||||
ENV["EXPO_PUBLIC_BUILD_NUMBER"] = "#{build_number_int}"
|
||||
|
||||
increment_build_number(
|
||||
xcodeproj: IOS_PROJECT,
|
||||
build_number: build_number_int
|
||||
)
|
||||
increment_version_number(
|
||||
xcodeproj: IOS_PROJECT,
|
||||
version_number: ENV["EXPO_PUBLIC_VERSION"]
|
||||
)
|
||||
end
|
||||
|
||||
desc "Build the iOS app for testing"
|
||||
private_lane :build_app_to_distribute do |options|
|
||||
build_scheme = options[:scheme]
|
||||
export_method = options[:export_method]
|
||||
app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
|
||||
|
||||
code_sign_identity = "iPhone Distribution" # sign an app before distributing it through the App Store
|
||||
|
||||
# update the code signing identities to match profile name and app bundle identifier
|
||||
update_code_signing_settings(
|
||||
use_automatic_signing: false, # turn off automatic signing during build so correct code signing identity is guaranteed to be used
|
||||
targets: [build_scheme],
|
||||
code_sign_identity: code_sign_identity,
|
||||
bundle_identifier: app_identifier,
|
||||
profile_name: PROVISIONING_NAME,
|
||||
build_configurations: [build_scheme], # only toggle code signing settings for Release configurations
|
||||
path: IOS_PROJECT
|
||||
)
|
||||
unlock_keychain(
|
||||
path: "#{ENV['TMP_KEYCHAIN_NAME']}-db",
|
||||
password: ENV["TMP_KEYCHAIN_PASSWORD"]
|
||||
)
|
||||
build_app(
|
||||
scheme: build_scheme,
|
||||
export_method: export_method,
|
||||
output_name: "#{build_scheme}-TrezorSuite",
|
||||
workspace: IOS_PROJECT_WORKSPACE,
|
||||
configuration: build_scheme
|
||||
)
|
||||
end
|
||||
|
||||
desc "Sign, build and push a new build to TestFlight"
|
||||
private_lane :build_to_testflight do |options|
|
||||
api_key = lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
|
||||
|
||||
prepare_distribution_signing
|
||||
build_app_to_distribute(scheme: options[:scheme], export_method: options[:export_method])
|
||||
|
||||
upload_to_testflight(
|
||||
api_key: api_key,
|
||||
skip_waiting_for_build_processing: true
|
||||
)
|
||||
end
|
||||
|
||||
desc "Sign, build and push a new build to App Store"
|
||||
private_lane :build_to_app_store do |options|
|
||||
api_key = lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
|
||||
prepare_distribution_signing
|
||||
build_app_to_distribute(scheme: options[:scheme], export_method: options[:export_method])
|
||||
|
||||
upload_to_app_store(
|
||||
api_key: api_key,
|
||||
run_precheck_before_submit: false,
|
||||
force: true, # not to generate HTML report
|
||||
reject_if_possible: true, # if the app is already waiting for the review and not reviewing yet, cancel it
|
||||
skip_metadata: false,
|
||||
skip_screenshots: true,
|
||||
languages: ['en-US'],
|
||||
release_notes: {
|
||||
"default" => "TODO idea - this could be specified from Github action input?",
|
||||
"en-US" => "TODO idea - this could be specified from Github action input?",
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
desc "Sign and build the app locally and get .ipa"
|
||||
private_lane :build_local_ipa do |options|
|
||||
build_scheme = options[:scheme]
|
||||
export_method = options[:export_method]
|
||||
app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
|
||||
|
||||
# 0. get username (to get or generate provisioning profile with a certificate for requesting user)
|
||||
# 1 provisioning profile has to be connected with 1 local certificate so every developer will have own provisioning profile
|
||||
apple_username = prompt(text: "Please, write your Apple ID Username and confirm: ")
|
||||
|
||||
# 1. development signing
|
||||
cert(
|
||||
development: true,
|
||||
username: apple_username
|
||||
)
|
||||
sigh(
|
||||
development: true,
|
||||
username: apple_username,
|
||||
app_identifier: app_identifier,
|
||||
provisioning_name: "#{PROVISIONING_NAME} - #{apple_username}",
|
||||
force: true # always recreate this exact profile to ensure it's valid and not expired
|
||||
)
|
||||
|
||||
# 2. development build
|
||||
code_sign_identity = "Apple Development" # use app services during development and testing
|
||||
|
||||
# Configures Xcode's Codesigning options
|
||||
update_code_signing_settings(
|
||||
use_automatic_signing: true,
|
||||
targets: [build_scheme],
|
||||
code_sign_identity: code_sign_identity,
|
||||
bundle_identifier: app_identifier,
|
||||
build_configurations: [build_scheme], # only toggle code signing settings for Release configurations
|
||||
path: IOS_PROJECT
|
||||
)
|
||||
|
||||
build_app(
|
||||
scheme: build_scheme,
|
||||
export_method: export_method,
|
||||
output_name: "#{build_scheme}-TrezorSuite",
|
||||
workspace: IOS_PROJECT_WORKSPACE,
|
||||
configuration: build_scheme
|
||||
)
|
||||
end
|
||||
desc "Build debug version of the app"
|
||||
lane :debugging do
|
||||
build_local_ipa(scheme: "TrezorSuiteDebug", export_method: "development")
|
||||
end
|
||||
desc "Build develop version of the app"
|
||||
lane :develop do
|
||||
build_to_testflight(scheme: "TrezorSuiteDevelop", export_method: "app-store")
|
||||
end
|
||||
desc "Build staging version of the app and upload to App Store Connect"
|
||||
lane :staging do
|
||||
build_to_testflight(scheme: "TrezorSuiteStaging", export_method: "app-store")
|
||||
end
|
||||
desc "Build production version of the app and upload to App Store Connect"
|
||||
lane :production do
|
||||
build_to_app_store(scheme: "TrezorSuite", export_method: "app-store")
|
||||
end
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
# Autogenerated by fastlane
|
||||
#
|
||||
# Ensure this file is checked in to source control!
|
||||
|
||||
gem 'fastlane-plugin-load_json'
|
||||
gem 'fastlane-plugin-versioning_android'
|
||||
gem 'fastlane-plugin-update_android_strings'
|
||||
gem 'fastlane-plugin-android_versioning'
|
||||
gem 'fastlane-plugin-firebase_app_distribution'
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@suite-native/app",
|
||||
"version": "1.0.0",
|
||||
"suiteNativeVersion": "24.2.0",
|
||||
"suiteNativeVersion": "24.3.1",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"android": "expo run:android",
|
||||
@@ -12,6 +12,8 @@
|
||||
"type-check": "yarn g:tsc -b",
|
||||
"pods": "npx pod-install",
|
||||
"prebuild": "expo prebuild",
|
||||
"eas-build-post-install": "yarn build:libs",
|
||||
"eas-build-on-success": "./upload-to-firebase.sh",
|
||||
"prebuild:clean": "expo prebuild --clean"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -70,6 +72,7 @@
|
||||
"expo-barcode-scanner": "12.9.2",
|
||||
"expo-build-properties": "^0.11.1",
|
||||
"expo-clipboard": "5.0.1",
|
||||
"expo-dev-client": "^3.3.7",
|
||||
"expo-haptics": "12.8.1",
|
||||
"expo-image": "1.10.6",
|
||||
"expo-linear-gradient": "12.7.1",
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-shadow */
|
||||
/*
|
||||
* This plugin is only necessary for support of legacy fastlane setup. It must be removed once EAS is fully adopted.
|
||||
*/
|
||||
const { withAppBuildGradle } = require('expo/config-plugins');
|
||||
|
||||
const newDebugConfig = `
|
||||
storeFile file(System.getenv("SIGNING_KEY_FILE"))
|
||||
storePassword System.getenv("SIGNING_KEY_STORE_PASSWORD")
|
||||
keyAlias System.getenv("SIGNING_KEY_ALIAS")
|
||||
keyPassword System.getenv("SIGNING_KEY_PASSWORD")
|
||||
`;
|
||||
|
||||
function updateAndroidGradleFile(contents) {
|
||||
// Replacement string
|
||||
const replacement = `signingConfigs {
|
||||
debug {${newDebugConfig}
|
||||
}`;
|
||||
|
||||
// Replace the content
|
||||
const updatedGradleCode = contents.replace(
|
||||
/signingConfigs\s*{\s*debug\s*{[^}]*}/,
|
||||
replacement.trim(),
|
||||
);
|
||||
return updatedGradleCode;
|
||||
}
|
||||
|
||||
module.exports = config =>
|
||||
withAppBuildGradle(config, config => {
|
||||
if (process.env.SIGNING_KEY_FILE) {
|
||||
config.modResults.contents = updateAndroidGradleFile(config.modResults.contents);
|
||||
}
|
||||
return config;
|
||||
});
|
||||
@@ -4,12 +4,9 @@ import { useSelector } from 'react-redux';
|
||||
import * as Sentry from '@sentry/react-native';
|
||||
|
||||
import { selectIsAnalyticsEnabled } from '@suite-common/analytics';
|
||||
import { getEnv, isDebugEnv, isDevelopEnv, isStagingEnv } from '@suite-native/config';
|
||||
import { getEnv, isDebugEnv, isDevelopEnv } from '@suite-native/config';
|
||||
import { selectIsOnboardingFinished } from '@suite-native/module-settings';
|
||||
|
||||
// Enforce sentry to be enabled in devs environments (dev,staging) because we want to catch all errors
|
||||
const isAlwaysEnabled = isDevelopEnv() || isStagingEnv();
|
||||
|
||||
const initSentry = () => {
|
||||
if (!isDebugEnv()) {
|
||||
Sentry.init({
|
||||
@@ -29,7 +26,8 @@ export const SentryProvider = ({ children }: { children: ReactNode }) => {
|
||||
const isAnalyticsEnabled = useSelector(selectIsAnalyticsEnabled);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAlwaysEnabled && isOnboardingFinished) {
|
||||
// Enforce sentry to be enabled in dev environment because we want to catch all errors
|
||||
if (!isDevelopEnv() && isOnboardingFinished) {
|
||||
if (!isAnalyticsEnabled) {
|
||||
Sentry.close();
|
||||
} else {
|
||||
|
||||
17
suite-native/app/upload-to-firebase.sh
Executable file
17
suite-native/app/upload-to-firebase.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ "$EAS_BUILD_PLATFORM" == "android" ]]; then
|
||||
curl -sL https://firebase.tools | bash
|
||||
|
||||
commit_hash=$(git log -1 --pretty=format:"%H")
|
||||
release_notes="Bug fixes and improvements. Last commit hash: $commit_hash"
|
||||
|
||||
firebase appdistribution:distribute "$EAS_BUILD_WORKINGDIR"/suite-native/app/android/app/build/outputs/apk/release/app-release.apk \
|
||||
--project pc-api-4710771878548015996-769 \
|
||||
--app 1:191883890128:android:625bcdab76b3b3a644bdd5 \
|
||||
--groups "develop-testers" \
|
||||
--release-notes "$release_notes" \
|
||||
--token "$FIREBASE_TOKEN"
|
||||
elif [[ "$EAS_BUILD_PLATFORM" == "ios" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
@@ -1,3 +0,0 @@
|
||||
export const getBuildVersionNumber = () => process.env.EXPO_PUBLIC_BUILD_NUMBER || '';
|
||||
|
||||
export const getChangelog = () => process.env.EXPO_PUBLIC_CHANGELOG || '';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
export const isDebugEnv = () => process.env.EXPO_PUBLIC_ENVIRONMENT === 'debug';
|
||||
export const isDevelopEnv = () => process.env.EXPO_PUBLIC_ENVIRONMENT === 'develop';
|
||||
export const isStagingEnv = () => process.env.EXPO_PUBLIC_ENVIRONMENT === 'staging';
|
||||
export const isProduction = () => process.env.EXPO_PUBLIC_ENVIRONMENT === 'production';
|
||||
|
||||
export const isDevelopOrDebugEnv = () => isDebugEnv() || isDevelopEnv();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
export * from './debugUtils';
|
||||
export * from './environment';
|
||||
export * from './supportedNetworks';
|
||||
export * from './jws';
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import { getEnv, getChangelog, getBuildVersionNumber } from '@suite-native/config';
|
||||
import { getSuiteVersion, getCommitHash } from '@trezor/env-utils';
|
||||
import { ListItem, VStack } from '@suite-native/atoms';
|
||||
|
||||
export const BuildInfo = () => (
|
||||
<VStack spacing="medium">
|
||||
<ListItem
|
||||
subtitle={`${getEnv()}-${getSuiteVersion()} (${getBuildVersionNumber()}), commit ${getCommitHash()}`}
|
||||
title="Build version"
|
||||
/>
|
||||
<ListItem subtitle={getChangelog()} title="Changelog" />
|
||||
</VStack>
|
||||
);
|
||||
@@ -2,8 +2,8 @@ import { Alert } from 'react-native';
|
||||
|
||||
import * as Sentry from '@sentry/react-native';
|
||||
|
||||
import { isDebugEnv, isDevelopOrDebugEnv, isProduction } from '@suite-native/config';
|
||||
import { Button, Card, VStack } from '@suite-native/atoms';
|
||||
import { getEnv, isDebugEnv, isDevelopOrDebugEnv, isProduction } from '@suite-native/config';
|
||||
import { Button, Card, ListItem, VStack } from '@suite-native/atoms';
|
||||
import {
|
||||
Screen,
|
||||
StackProps,
|
||||
@@ -12,8 +12,8 @@ import {
|
||||
ScreenSubHeader,
|
||||
} from '@suite-native/navigation';
|
||||
import { clearStorage } from '@suite-native/storage';
|
||||
import { getCommitHash, getSuiteVersion } from '@trezor/env-utils';
|
||||
|
||||
import { BuildInfo } from '../components/BuildInfo';
|
||||
import { RenderingUtils } from '../components/RenderingUtils';
|
||||
import { FeatureFlags } from '../components/FeatureFlags';
|
||||
import { TestnetsToggle } from '../components/TestnetsToggle';
|
||||
@@ -26,7 +26,12 @@ export const DevUtilsScreen = ({
|
||||
<VStack>
|
||||
<Card>
|
||||
<VStack spacing="medium">
|
||||
{!isDebugEnv() && <BuildInfo />}
|
||||
{!isDebugEnv() && (
|
||||
<ListItem
|
||||
subtitle={`${getEnv()}-${getSuiteVersion()}, commit ${getCommitHash()}`}
|
||||
title="Build version"
|
||||
/>
|
||||
)}
|
||||
{isDebugEnv() && (
|
||||
<Button onPress={() => navigation.navigate(DevUtilsStackRoutes.Demo)}>
|
||||
See Component Demo
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"@suite-native/navigation": "workspace:*",
|
||||
"@suite-native/storage": "workspace:*",
|
||||
"@suite-native/theme": "workspace:*",
|
||||
"@suite-native/toasts": "workspace:*",
|
||||
"@trezor/connect": "workspace:*",
|
||||
"@trezor/env-utils": "workspace:*",
|
||||
"@trezor/styles": "workspace:*",
|
||||
|
||||
@@ -1,32 +1,25 @@
|
||||
import { S } from '@mobily/ts-belt';
|
||||
|
||||
import { Text, Box, HStack } from '@suite-native/atoms';
|
||||
import { getBuildVersionNumber } from '@suite-native/config';
|
||||
import { getSuiteVersion, getCommitHash } from '@trezor/env-utils';
|
||||
|
||||
import { ProductionDebug } from './ProductionDebug';
|
||||
|
||||
export const AppVersion = () => {
|
||||
const hasVersionAndBuildInfo =
|
||||
S.isNotEmpty(getSuiteVersion()) && S.isNotEmpty(getBuildVersionNumber());
|
||||
|
||||
const hasCommitHash = S.isNotEmpty(getCommitHash());
|
||||
return (
|
||||
<HStack marginHorizontal="medium" justifyContent="space-between">
|
||||
<Box>
|
||||
{hasVersionAndBuildInfo && (
|
||||
<Text variant="hint" color="textDisabled">
|
||||
Version: {`${getSuiteVersion()} (${getBuildVersionNumber()})`}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
<ProductionDebug>
|
||||
{hasCommitHash && (
|
||||
<Text variant="hint" color="textDisabled">
|
||||
Last commit hash: {getCommitHash()}
|
||||
</Text>
|
||||
)}
|
||||
</ProductionDebug>
|
||||
</HStack>
|
||||
);
|
||||
};
|
||||
export const AppVersion = () => (
|
||||
<HStack marginHorizontal="medium" justifyContent="space-between">
|
||||
<Box>
|
||||
{S.isNotEmpty(getSuiteVersion()) && (
|
||||
<Text variant="hint" color="textDisabled">
|
||||
Version: {`${getSuiteVersion()}`}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
<ProductionDebug>
|
||||
{S.isNotEmpty(getCommitHash()) && (
|
||||
<Text variant="hint" color="textDisabled">
|
||||
Last commit hash: {getCommitHash()}
|
||||
</Text>
|
||||
)}
|
||||
</ProductionDebug>
|
||||
</HStack>
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useSetAtom } from 'jotai';
|
||||
|
||||
import { isDevelopOrDebugEnv } from '@suite-native/config';
|
||||
import { atomWithUnecryptedStorage } from '@suite-native/storage';
|
||||
import { useToast } from '@suite-native/toasts';
|
||||
|
||||
type ProductionDebugProps = {
|
||||
children: ReactNode;
|
||||
@@ -18,6 +19,7 @@ export const isDevButtonVisibleAtom = atomWithUnecryptedStorage<boolean>(
|
||||
|
||||
export const ProductionDebug = ({ children }: ProductionDebugProps) => {
|
||||
const setIsDevButtonVisible = useSetAtom(isDevButtonVisibleAtom);
|
||||
const { showToast } = useToast();
|
||||
|
||||
const handleTapsCount = () => {
|
||||
if (tapsCount < 7) {
|
||||
@@ -25,6 +27,11 @@ export const ProductionDebug = ({ children }: ProductionDebugProps) => {
|
||||
}
|
||||
if (tapsCount === 7) {
|
||||
setIsDevButtonVisible(true);
|
||||
showToast({
|
||||
variant: 'default',
|
||||
message: 'Dev utils enabled.',
|
||||
icon: 'check',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
{ "path": "../navigation" },
|
||||
{ "path": "../storage" },
|
||||
{ "path": "../theme" },
|
||||
{ "path": "../toasts" },
|
||||
{ "path": "../../packages/connect" },
|
||||
{ "path": "../../packages/env-utils" },
|
||||
{ "path": "../../packages/styles" },
|
||||
|
||||
102
yarn.lock
102
yarn.lock
@@ -7858,6 +7858,7 @@ __metadata:
|
||||
expo-barcode-scanner: "npm:12.9.2"
|
||||
expo-build-properties: "npm:^0.11.1"
|
||||
expo-clipboard: "npm:5.0.1"
|
||||
expo-dev-client: "npm:^3.3.7"
|
||||
expo-haptics: "npm:12.8.1"
|
||||
expo-image: "npm:1.10.6"
|
||||
expo-linear-gradient: "npm:12.7.1"
|
||||
@@ -8562,6 +8563,7 @@ __metadata:
|
||||
"@suite-native/navigation": "workspace:*"
|
||||
"@suite-native/storage": "workspace:*"
|
||||
"@suite-native/theme": "workspace:*"
|
||||
"@suite-native/toasts": "workspace:*"
|
||||
"@trezor/connect": "workspace:*"
|
||||
"@trezor/env-utils": "workspace:*"
|
||||
"@trezor/styles": "workspace:*"
|
||||
@@ -9565,6 +9567,7 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@trezor/env-utils@workspace:packages/env-utils"
|
||||
dependencies:
|
||||
expo-constants: "npm:15.4.5"
|
||||
ua-parser-js: "npm:^1.0.37"
|
||||
peerDependencies:
|
||||
expo-localization: "*"
|
||||
@@ -12341,6 +12344,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ajv@npm:8.11.0":
|
||||
version: 8.11.0
|
||||
resolution: "ajv@npm:8.11.0"
|
||||
dependencies:
|
||||
fast-deep-equal: "npm:^3.1.1"
|
||||
json-schema-traverse: "npm:^1.0.0"
|
||||
require-from-string: "npm:^2.0.2"
|
||||
uri-js: "npm:^4.2.2"
|
||||
checksum: aa0dfd6cebdedde8e77747e84e7b7c55921930974b8547f54b4156164ff70445819398face32dafda4bd4c61bbc7513d308d4c2bf769f8ea6cb9c8449f9faf54
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ajv@npm:^6.10.0, ajv@npm:^6.12.0, ajv@npm:^6.12.4, ajv@npm:^6.12.5":
|
||||
version: 6.12.6
|
||||
resolution: "ajv@npm:6.12.6"
|
||||
@@ -18382,14 +18397,65 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-constants@npm:~15.4.0":
|
||||
version: 15.4.3
|
||||
resolution: "expo-constants@npm:15.4.3"
|
||||
"expo-constants@npm:15.4.5, expo-constants@npm:~15.4.0":
|
||||
version: 15.4.5
|
||||
resolution: "expo-constants@npm:15.4.5"
|
||||
dependencies:
|
||||
"@expo/config": "npm:~8.5.0"
|
||||
peerDependencies:
|
||||
expo: "*"
|
||||
checksum: ece1bb5d83338874a7061a486ec9ba087f48a3caf12692fe492fa16df9b5b7160ae1b78590c1e98866e15be7d5c05d2fe9e4c597a0653d8c7b4189d0e544ff1e
|
||||
checksum: 9eb256895aa24efd41ca8c48b7dd76c03ecad4662e86c32440ea7d4162397014c80775b73db499add5e9452721f236c6ba333af93d8a277ad964f1fd938305f1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-dev-client@npm:^3.3.7":
|
||||
version: 3.3.8
|
||||
resolution: "expo-dev-client@npm:3.3.8"
|
||||
dependencies:
|
||||
expo-dev-launcher: "npm:3.6.6"
|
||||
expo-dev-menu: "npm:4.5.5"
|
||||
expo-dev-menu-interface: "npm:1.7.2"
|
||||
expo-manifests: "npm:~0.13.0"
|
||||
expo-updates-interface: "npm:~0.15.1"
|
||||
peerDependencies:
|
||||
expo: "*"
|
||||
checksum: 8f37117ceb767b51d442b6895f0ed8a76a719a5b4084e1f081d6711e2a02b0414405514e360ca4696e4916cc1fd9d019b7559200fc35a811a05526db356e60fb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-dev-launcher@npm:3.6.6":
|
||||
version: 3.6.6
|
||||
resolution: "expo-dev-launcher@npm:3.6.6"
|
||||
dependencies:
|
||||
ajv: "npm:8.11.0"
|
||||
expo-dev-menu: "npm:4.5.5"
|
||||
expo-manifests: "npm:~0.13.0"
|
||||
resolve-from: "npm:^5.0.0"
|
||||
semver: "npm:^7.5.3"
|
||||
peerDependencies:
|
||||
expo: "*"
|
||||
checksum: 143cad2bda5d8f82f1f7388ac98f9123d3ad4aea6c0a76d2ca5bb2b5beb48c433b782c732eb695d465f43bb339c3c2c1c09f42cb2ce9d6f1f0110f8aadec6515
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-dev-menu-interface@npm:1.7.2":
|
||||
version: 1.7.2
|
||||
resolution: "expo-dev-menu-interface@npm:1.7.2"
|
||||
peerDependencies:
|
||||
expo: "*"
|
||||
checksum: 28df663590af53ec35014e934f61b61113f9acfdefa11dfded9be98a6f3875e32cd25750a6e1e1cccccef3ec6cc3faf08a2bf61ef02c6950e50327d1e01b84b3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-dev-menu@npm:4.5.5":
|
||||
version: 4.5.5
|
||||
resolution: "expo-dev-menu@npm:4.5.5"
|
||||
dependencies:
|
||||
expo-dev-menu-interface: "npm:1.7.2"
|
||||
semver: "npm:^7.5.3"
|
||||
peerDependencies:
|
||||
expo: "*"
|
||||
checksum: 7389c9a8d00edee6d2490ff4f72117a9dddd22dffa8bc10a2f532e6c0008f82d911d5a8bb0bff20531e0383795f601197233db31c1798e6e00524548af4899f0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -18453,6 +18519,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-json-utils@npm:~0.12.0":
|
||||
version: 0.12.3
|
||||
resolution: "expo-json-utils@npm:0.12.3"
|
||||
checksum: aefaa9fa58514665d4dd761b0f2d09bf9e3b9a36f4dc7b943b1155b1e1f6a45985c9a5370f13ba01d2c38b0a4158e574c6cf7895b3b61e56a6d665696ae0d87b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-keep-awake@npm:~12.8.2":
|
||||
version: 12.8.2
|
||||
resolution: "expo-keep-awake@npm:12.8.2"
|
||||
@@ -18493,6 +18566,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-manifests@npm:~0.13.0":
|
||||
version: 0.13.2
|
||||
resolution: "expo-manifests@npm:0.13.2"
|
||||
dependencies:
|
||||
"@expo/config": "npm:~8.5.0"
|
||||
expo-json-utils: "npm:~0.12.0"
|
||||
peerDependencies:
|
||||
expo: "*"
|
||||
checksum: 446712a856bf91c7034d08ad5dc98a8a0c139271baca1b5dfb8474108228cae79bb9f4d6a93b36dc51b2a03ce1ce6762516349251fdfbf348c30788b9baf1e58
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-modules-autolinking@npm:1.10.3":
|
||||
version: 1.10.3
|
||||
resolution: "expo-modules-autolinking@npm:1.10.3"
|
||||
@@ -18580,6 +18665,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-updates-interface@npm:~0.15.1":
|
||||
version: 0.15.3
|
||||
resolution: "expo-updates-interface@npm:0.15.3"
|
||||
peerDependencies:
|
||||
expo: "*"
|
||||
checksum: 9c6caf30bbf6d0e850decdfde271c61fd2508bad7c6a9649f234c2f8ca949c67647c3d07734bacce6de377cdfa7662d442d2d2e57efa587a35f85a3480436992
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo@npm:50.0.6":
|
||||
version: 50.0.6
|
||||
resolution: "expo@npm:50.0.6"
|
||||
|
||||
Reference in New Issue
Block a user