From 60054ba5f62a7db5fc80c7981ee0b61a73c7a08a Mon Sep 17 00:00:00 2001 From: An Nguyen Date: Mon, 19 Feb 2024 13:23:18 -0600 Subject: [PATCH 1/6] add github workflow to sync envs to bitrise as well as local script to fetch envs from aws --- .github/workflows/bitrise-envs-sync.yml | 48 +++++++++++++++ packages/core-mobile/package.json | 1 + .../scripts/common/writeEnvsToFile.sh | 32 ++++++++++ packages/core-mobile/scripts/getEnvs.sh | 52 ++++++++++++++++ .../scripts/github/uploadEnvsToBitrise.sh | 61 +++++++++++++++++++ 5 files changed, 194 insertions(+) create mode 100644 .github/workflows/bitrise-envs-sync.yml create mode 100755 packages/core-mobile/scripts/common/writeEnvsToFile.sh create mode 100755 packages/core-mobile/scripts/getEnvs.sh create mode 100755 packages/core-mobile/scripts/github/uploadEnvsToBitrise.sh diff --git a/.github/workflows/bitrise-envs-sync.yml b/.github/workflows/bitrise-envs-sync.yml new file mode 100644 index 0000000000..4c9faf8194 --- /dev/null +++ b/.github/workflows/bitrise-envs-sync.yml @@ -0,0 +1,48 @@ +name: Bitrise Envs Sync + +on: + pull_request: + # The branches below must be a subset of the branches above + branches: ['development'] + workflow_dispatch: + +jobs: + upload-envs-to-bitrise: + name: Upload envs to Bitrise + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + + steps: + - name: Check out repo + uses: actions/checkout@v3 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4.0.2 + with: + aws-region: us-east-2 + role-to-assume: arn:aws:iam::975050371175:role/github-sa-role + role-session-name: githubsa + + - name: Get envs from AWS + uses: aws-actions/aws-secretsmanager-get-secrets@v1 + with: + secret-ids: | + ENV_DEV, core/dev/mobile/.env.development + ENV_DEV_E2E, core/dev/mobile/.env.development.e2e + ENV_PROD, core/dev/mobile/.env.production + ENV_PROD_E2E, core/dev/mobile/.env.production.e2e + + - name: Wrtie envs to files + working-directory: packages/core-mobile/scripts/github + run: | + ../common/writeEnvsToFile.sh "$ENV_DEV" ".env.development" + ../common/writeEnvsToFile.sh "$ENV_DEV_E2E" ".env.development.e2e" + ../common/writeEnvsToFile.sh "$ENV_PROD" ".env.production" + ../common/writeEnvsToFile.sh "$ENV_PROD_E2E" ".env.production.e2e" + + - name: Upload envs to Bitrise + working-directory: packages/core-mobile/scripts/github + run: | + ./uploadEnvsToBitrise.sh ${{ secrets.BITRISE_ACCESS_TOKEN }} diff --git a/packages/core-mobile/package.json b/packages/core-mobile/package.json index 9f66a2803b..8d89762af3 100644 --- a/packages/core-mobile/package.json +++ b/packages/core-mobile/package.json @@ -3,6 +3,7 @@ "private": true, "scripts": { "setup": "yarn allow-scripts", + "envs": "./scripts/getEnvs.sh", "android": "ENVFILE=.env.development react-native run-android --variant=internalDebug", "podInstall": "bundle _2.1.4_ install && cd ios && bundle exec pod install", "ios": "ENVFILE=.env.development react-native run-ios", diff --git a/packages/core-mobile/scripts/common/writeEnvsToFile.sh b/packages/core-mobile/scripts/common/writeEnvsToFile.sh new file mode 100755 index 0000000000..149dce5913 --- /dev/null +++ b/packages/core-mobile/scripts/common/writeEnvsToFile.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -e + +# Check if the correct number of parameters are provided +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Retrieve the env value and assign it to the data variable +data=$1 + +output_file=$2 + +# Check if the secret value is empty +if [ -z "$data" ]; then + echo "Error: Failed to retrieve secret value" + exit 1 +fi + +# Parse the string to extract key-value pairs +pairs=$(echo "$data" | sed 's/[{}"]//g' | tr ',' '\n' | sed 's/:/=/') + +# Erase the content of the output file +> "$output_file" + +# Write the key-value pairs to the output file +echo "$pairs" | while IFS= read -r line; do + echo "$line" | sed 's/\\//g' >> "$output_file" +done + +echo "envs saved to $output_file" \ No newline at end of file diff --git a/packages/core-mobile/scripts/getEnvs.sh b/packages/core-mobile/scripts/getEnvs.sh new file mode 100755 index 0000000000..dc4c510969 --- /dev/null +++ b/packages/core-mobile/scripts/getEnvs.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Retrieve secret by id from AWS Secrets Manager +getSecretFromAWS() { + local secret_id="$1" + sudo aws secretsmanager get-secret-value --secret-id "$secret_id" | grep SecretString | sed 's/.*"SecretString": "\(.*\)".*/\1/' +} + +# Check if a AWS profile exists +awsConfigurationExists() { + local profile_name="${1}" + local profile_status=$( (sudo aws configure --profile ${1} list) 2>&1) + + if [[ $profile_status = *'could not be found'* ]]; then + return 1 + else + return 0 + fi +} + +# Check if profile "default" exists. If not, ask to create one +if ! $(awsConfigurationExists "default"); then + echo 'Profile "default" does not exist. Please create one first!' + sudo aws configure sso +fi + +# Check if the session is still valid. If not, ask to re-login +ACCOUNT=$(sudo aws sts get-caller-identity --query "Account") + +# Account is valid if account is a 12 digit account number plus surrounding double-quotes +if [ ${#ACCOUNT} -ne 14 ]; then + echo 'logging in with profile "default"' + sudo aws sso login --profile default +fi + +# Retrieve all envs from AWS +echo "retrieving envs from AWS Secrets Manager..." +ENV_DEV=$(getSecretFromAWS "core/dev/mobile/.env.development") +ENV_DEV_E2E=$(getSecretFromAWS "core/dev/mobile/.env.development.e2e") +ENV_PROD=$(getSecretFromAWS "core/dev/mobile/.env.production") +ENV_PROD_E2E=$(getSecretFromAWS "core/dev/mobile/.env.production.e2e") + +# Write to .env files +./scripts/common/writeEnvsToFile.sh "$ENV_DEV" ".env.development" +./scripts/common/writeEnvsToFile.sh "$ENV_DEV_E2E" ".env.development.e2e" +./scripts/common/writeEnvsToFile.sh "$ENV_PROD" ".env.production" +./scripts/common/writeEnvsToFile.sh "$ENV_PROD_E2E" ".env.production.e2e" + +# Use .env.development as the default +cp .env.development .env +echo ".env.development copied to .env" +echo "envs successfully retrieved and saved 🥳" diff --git a/packages/core-mobile/scripts/github/uploadEnvsToBitrise.sh b/packages/core-mobile/scripts/github/uploadEnvsToBitrise.sh new file mode 100755 index 0000000000..38d44f20fe --- /dev/null +++ b/packages/core-mobile/scripts/github/uploadEnvsToBitrise.sh @@ -0,0 +1,61 @@ +#!/bin/bash +set -e + +# Get the value of a key +function getJsonVal () { + python -c "import json,sys;sys.stdout.write(json.dumps(json.load(sys.stdin)$1))"; +} + +# Search for a value when key matches the provided condition +function searchJsonVal () { + python -c " +import json, sys + +# Load JSON data from stdin +data = json.load(sys.stdin)['data'] + +# Filter data based on the provided condition +filtered_data = [x for x in data if x.get('$1') == '$2'] + +# Print the filtered data as JSON +sys.stdout.write(json.dumps(filtered_data)) +" +} + +# Check if the correct number of parameters are provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +app_slug="7d7ca5af7066e290" +file_name="env-files.zip" +bitrise_file_name=ENV_FILES +access_token=$1 +base_url="https://api.bitrise.io/v0.1/apps/$app_slug" + +# get all generic profile files +# if the bitrise_file_name already exists, delete it +all_files=$(curl -X GET -H "Authorization: $access_token" "$base_url/generic-project-files") +existing_file_slug=$( echo $all_files | searchJsonVal "user_env_key" $bitrise_file_name | getJsonVal "[0]['slug']" | tr -d '"') +curl -X DELETE "$base_url/generic-project-files/$existing_file_slug" -H "Authorization: $access_token" + +# compress all env files into a single zip file +zip $file_name .env.* + +# upload the zip file to bitrise https://devcenter.bitrise.io/en/api/managing-files-in-generic-file-storage.html + +# 1. create a temporary pre-signed upload URL +file_size=$(ls -l $file_name | awk '{print $5}') +response_1=$(curl -H "Authorization: $access_token" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"upload_file_name\": \"$file_name\", \"upload_file_size\": $file_size, \"user_env_key\": \"$bitrise_file_name\"}" -X POST "$base_url/generic-project-files") + +# 2. upload the file to the pre-signed URL +upload_url=$( echo $response_1 | getJsonVal "['data']['upload_url']" | tr -d '"' ) + +curl -T $file_name $upload_url + +# 3. confirm the file upload +file_slug=$( echo $response_1 | getJsonVal "['data']['slug']" | tr -d '"' ) +curl -X POST -H "Authorization: $access_token" "$base_url/generic-project-files/$file_slug/uploaded" + +echo "envs uploaded to bitrise successfully" \ No newline at end of file From 54ddeabd8aec9562de0d6aed8eea94ec8296a1d6 Mon Sep 17 00:00:00 2001 From: An Nguyen Date: Thu, 22 Feb 2024 22:33:46 -0600 Subject: [PATCH 2/6] remove on pull request trigger --- .github/workflows/bitrise-envs-sync.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/bitrise-envs-sync.yml b/.github/workflows/bitrise-envs-sync.yml index 4c9faf8194..fc06f383da 100644 --- a/.github/workflows/bitrise-envs-sync.yml +++ b/.github/workflows/bitrise-envs-sync.yml @@ -1,9 +1,6 @@ name: Bitrise Envs Sync on: - pull_request: - # The branches below must be a subset of the branches above - branches: ['development'] workflow_dispatch: jobs: From 4baeffe1c5e1da1d793c95f0444dbe09bdb99719 Mon Sep 17 00:00:00 2001 From: An Nguyen Date: Thu, 22 Feb 2024 23:04:12 -0600 Subject: [PATCH 3/6] update readme --- README.md | 22 +++++--- packages/core-mobile/README.md | 96 +++++++++++----------------------- 2 files changed, 45 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 5d1bb023a1..7f15873e53 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,12 @@ Ava Labs Mobile This repository is a monorepo that we manage using [Yarn workspaces](https://yarnpkg.com/features/workspaces). -| Package | Description | -| :--- | :--- | -| [@avalabs/core-mobile](https://github.com/ava-labs/avalanche-wallet-apps/tree/develop/packages/core-mobile) | Core Mobile app | -| [@avalabs/k2-mobile](https://github.com/ava-labs/avalanche-wallet-apps/tree/develop/packages/k2-mobile) | Mobile Design System (under 🚧👷‍♂️🚧) | -| [eslint-plugin-avalabs-mobile](https://github.com/ava-labs/avalanche-wallet-apps/tree/develop/packages/eslint-mobile) | Shared Eslint plugin | -| [@avalabs/tsconfig-mobile](https://github.com/ava-labs/avalanche-wallet-apps/tree/develop/packages/tsconfig-mobile) | Shared Typescript config | +| Package | Description | +| :-------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | +| [@avalabs/core-mobile](https://github.com/ava-labs/avalanche-wallet-apps/tree/develop/packages/core-mobile) | Core Mobile app | +| [@avalabs/k2-mobile](https://github.com/ava-labs/avalanche-wallet-apps/tree/develop/packages/k2-mobile) | Mobile Design System (under 🚧👷‍♂️🚧) | +| [eslint-plugin-avalabs-mobile](https://github.com/ava-labs/avalanche-wallet-apps/tree/develop/packages/eslint-mobile) | Shared Eslint plugin | +| [@avalabs/tsconfig-mobile](https://github.com/ava-labs/avalanche-wallet-apps/tree/develop/packages/tsconfig-mobile) | Shared Typescript config | ## ⚡ Quickstart @@ -25,12 +25,18 @@ This repository is a monorepo that we manage using [Yarn workspaces](https://yar ``` brew install yarn ``` -4. Install required dependencies for all packages +3. Set up `$NPM_TOKEN` + + To install all dependencies, you will need to generate an `NPM token` from your NPM.js account and add that as an environment variable named `NPM_TOKEN` on your machine (for example, `.zshenv` if using zsh or `.bash_profile` if not). + +4. Install dependencies for all packages In the root directory, run: + ``` yarn install && yarn setup ``` + 5. Follow the specific instructions in each package to build/run it ## 📖 Tips @@ -47,4 +53,4 @@ This repository is a monorepo that we manage using [Yarn workspaces](https://yar 2. To quickly remove all the node_modules folders, you can run ``` ./scripts/remove-node-modules.sh - ``` \ No newline at end of file + ``` diff --git a/packages/core-mobile/README.md b/packages/core-mobile/README.md index b0cd89d10b..242bb84b45 100644 --- a/packages/core-mobile/README.md +++ b/packages/core-mobile/README.md @@ -1,71 +1,58 @@ -# Core X Mobile +# Core Mobile ## Setup dev environment -Follow [these](https://reactnative.dev/docs/environment-setup) steps to setup dev environment; make sure to select -**React Native CLI Quickstart** tab and select appropriate Development & Target OS. +1. Set up React Native environment (https://reactnative.dev/docs/environment-setup) -## Getting Started +2. Run `yarn envs` to fetch and create all the necessary .env files -### 1. Clone the repo. +3. Run `yarn install && yarn setup` if you haven't -```zsh -git clone git@github.com:ava-labs/avalanche-wallet-apps.git -cd avalanche-wallet-apps/ -``` - -**NOTE:** If you're using IDE to initiate this action you will need `github access token` registered with Jumpcloud SSO. -To do that, go to https://github.com/settings/tokens, generate access token and authorize it with Jumpcloud. Finally, import that token to your favorite IDE. - -### 2. Setup environment. -1. To access all project's dependencies you will need to generate an `NPM token` from your npmjs account and add that as an environment variable named `NPM_TOKEN` on your mac (for example, `.zshenv` if using zsh or `.bash_profile` if not). -2. Create a `.env.development` file in the root of the project. The contents of the .env file is in 1Password. Ask permission to access it (the vault name is Mobile team). Once access is given copy and paste the contents from the 1Password Secure Note into your local .env file. -3. Download `keystore.properties` from 1Password and place it in the `android` folder - -**IMPORTANT:** the `.env` files are never to be committed to the repo, and are already added to .gitignore. +## Build the app +#### For iOS -### 3. Install the dependencies. +1. Install iOS dependencies: -```zsh -yarn setup -``` + ```zsh + yarn podInstall + ``` -### 4. Launch the app +2. Launch iOS simulator and build -#### For iOS + ```zsh + yarn ios + ``` -First install iOS dependencies: -```zsh -yarn podInstall -``` +#### For Android -Now you can run the app +Launch android emulator and build ```zsh -# launch iOS simulator and start the app -yarn ios +yarn android ``` -**Note:** if you run into `"Your session has expired. Please log in."` issue, go to `XCode > Preferences > Accounts` and sign in with your account. +## Common commands -#### For Android ```zsh -# launch android emulator and start the app -yarn android -``` +# run unit tests +yarn test -## Tests +# run typescript check +yarn tsc -You can run the test suite with +# run lint check +yarn lint -```zsh -yarn test +# fetch envs from aws and populate .env files +# do this when you first set up the project and whenever you need to sync the .env files +yarn envs ``` ## Custom fonts -To add custom font, add it to src/assets folder and then run: +To add custom fonts, add it to app/assets/fonts folder and then run: + ```zsh yarn link ``` @@ -79,30 +66,9 @@ https://whimsical.com/mobile-navigation-system-4WaXLt2DgAutCmbfFF6wpS https://whimsical.com/wallet-connect-flows-9QqTTDNdktBePx6vDR9oeX ## App Signing + [Documentation](docs/app_signing.md) ## Release Process -[Documentation](docs/release_process.md) - -## Known issues -### Apple M1 chips -Exclude arch `arm64` - -Prefix all comands with `arch -x86_64` - -Examples: -```zsh -arch -x86_64 pod install -``` - -```zsh -arch -x86_64 yarn ios -``` - -### `pod install` fails on Apple M1 chips - -Install ffi -```zsh -sudo arch -x86_64 gem install ffi -``` +[Documentation](docs/release_process.md) From 8f0b7e4ff65d40ca43d65c26f514c42e8d031756 Mon Sep 17 00:00:00 2001 From: An Nguyen Date: Fri, 23 Feb 2024 07:54:02 -0600 Subject: [PATCH 4/6] Update README.md --- packages/core-mobile/README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/core-mobile/README.md b/packages/core-mobile/README.md index 242bb84b45..878ecf79f4 100644 --- a/packages/core-mobile/README.md +++ b/packages/core-mobile/README.md @@ -51,19 +51,23 @@ yarn envs ## Custom fonts -To add custom fonts, add it to app/assets/fonts folder and then run: +To add custom fonts, add it to `app/assets/fonts` folder and then run: ```zsh yarn link ``` +## Env Workflows + +[Documentation](https://ava-labs.atlassian.net/wiki/spaces/EN/pages/2500493313/Env+Workflows) + ## Navigation System -https://whimsical.com/mobile-navigation-system-4WaXLt2DgAutCmbfFF6wpS +[Documentation](https://whimsical.com/mobile-navigation-system-4WaXLt2DgAutCmbfFF6wpS) ## Wallet Connect Flows -https://whimsical.com/wallet-connect-flows-9QqTTDNdktBePx6vDR9oeX +[Documentation](https://whimsical.com/wallet-connect-flows-9QqTTDNdktBePx6vDR9oeX) ## App Signing From ad3b6df138141232b7b275dcece6d1a0148a1419 Mon Sep 17 00:00:00 2001 From: An Nguyen Date: Fri, 23 Feb 2024 19:29:15 -0600 Subject: [PATCH 5/6] Update .github/workflows/bitrise-envs-sync.yml Co-authored-by: Ray Lin <137183702+ruijialin-avalabs@users.noreply.github.com> Signed-off-by: An Nguyen --- .github/workflows/bitrise-envs-sync.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bitrise-envs-sync.yml b/.github/workflows/bitrise-envs-sync.yml index fc06f383da..76359577a4 100644 --- a/.github/workflows/bitrise-envs-sync.yml +++ b/.github/workflows/bitrise-envs-sync.yml @@ -31,7 +31,7 @@ jobs: ENV_PROD, core/dev/mobile/.env.production ENV_PROD_E2E, core/dev/mobile/.env.production.e2e - - name: Wrtie envs to files + - name: Write envs to files working-directory: packages/core-mobile/scripts/github run: | ../common/writeEnvsToFile.sh "$ENV_DEV" ".env.development" From 466dffa5c81c6a5b44ec0dc54ad61119f5198383 Mon Sep 17 00:00:00 2001 From: An Nguyen Date: Mon, 26 Feb 2024 08:24:27 -0600 Subject: [PATCH 6/6] use sso profile instead of default --- packages/core-mobile/README.md | 8 +++++--- packages/core-mobile/scripts/getEnvs.sh | 16 +++++++++------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/core-mobile/README.md b/packages/core-mobile/README.md index 878ecf79f4..6236e732ed 100644 --- a/packages/core-mobile/README.md +++ b/packages/core-mobile/README.md @@ -2,11 +2,13 @@ ## Setup dev environment -1. Set up React Native environment (https://reactnative.dev/docs/environment-setup) +1. Set up [React Native environment](https://reactnative.dev/docs/environment-setup) -2. Run `yarn envs` to fetch and create all the necessary .env files +2. Set up [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) -3. Run `yarn install && yarn setup` if you haven't +3. Run `yarn envs` to fetch and create all the necessary .env files + +4. Run `yarn install && yarn setup` if you haven't ## Build the app diff --git a/packages/core-mobile/scripts/getEnvs.sh b/packages/core-mobile/scripts/getEnvs.sh index dc4c510969..07ad51edba 100755 --- a/packages/core-mobile/scripts/getEnvs.sh +++ b/packages/core-mobile/scripts/getEnvs.sh @@ -1,9 +1,11 @@ #!/bin/bash +PROFILE_NAME="sso" + # Retrieve secret by id from AWS Secrets Manager getSecretFromAWS() { local secret_id="$1" - sudo aws secretsmanager get-secret-value --secret-id "$secret_id" | grep SecretString | sed 's/.*"SecretString": "\(.*\)".*/\1/' + sudo aws --profile $PROFILE_NAME secretsmanager get-secret-value --secret-id "$secret_id" | grep SecretString | sed 's/.*"SecretString": "\(.*\)".*/\1/' } # Check if a AWS profile exists @@ -19,18 +21,18 @@ awsConfigurationExists() { } # Check if profile "default" exists. If not, ask to create one -if ! $(awsConfigurationExists "default"); then - echo 'Profile "default" does not exist. Please create one first!' - sudo aws configure sso +if ! $(awsConfigurationExists $PROFILE_NAME); then + echo "Profile '$PROFILE_NAME' does not exist. Please create one first!" + sudo aws configure sso --profile $PROFILE_NAME fi # Check if the session is still valid. If not, ask to re-login -ACCOUNT=$(sudo aws sts get-caller-identity --query "Account") +ACCOUNT=$(sudo aws --profile $PROFILE_NAME sts get-caller-identity --query "Account") # Account is valid if account is a 12 digit account number plus surrounding double-quotes if [ ${#ACCOUNT} -ne 14 ]; then - echo 'logging in with profile "default"' - sudo aws sso login --profile default + echo "logging in with profile '$PROFILE_NAME'" + sudo aws sso login --profile $PROFILE_NAME fi # Retrieve all envs from AWS