# Nona - React Native Template <!-- omit in toc -->

React Native Template that can be initialised with the react-native CLI tool.

- [Features](#features)
- [Quickstart](#quickstart)
- [Splashscreen Customisation](#splashscreen-customisation)
- [Android Build Notes](#android-build-notes)
- [Husky](#husky)
- [CircleCI](#circleci)
- [Fastlane](#fastlane)
  - [Setup Notes](#setup-notes)
  - [Screenshot Generation](#screenshot-generation)
- [Sentry](#sentry)
- [Semantic Release](#semantic-release)

---

## Features

- Use with [React Native CLI](https://github.com/react-native-community/cli)
- Consistent with the default React Native template
- Has the following built in:
  - [Typescript](https://www.typescriptlang.org/)
  - [React Navigation](https://reactnavigation.org/)
  - [Redux Toolkit](https://redux-toolkit.js.org/)
  - [Redux Observable](https://redux-observable.js.org/)
  - [React Native SVG](https://github.com/react-native-svg/react-native-svg)
  - [Storybook](https://storybook.js.org/tutorials/intro-to-storybook/react-native/en/get-started/) with examples∂
  - Documentation with comprehensive README.md, gotchas, project structure etc.
  - Example [CircleCI](https://circleci.com/) deploy scripts which can be edited, tailored to your needs
  - [Semantic Release](https://github.com/semantic-release/semantic-release) to generate releases based on commit messages as well as release notes for Testflight/Google Play
  - All Nona [linting](https://www.npmjs.com/package/@nona-creative/eslint-config) and [prettier](@nona-creative/prettier-config) standards with some changes
  - [Editorconfig](https://editorconfig.org/) defined
  - Github Pull Request Template and CODEOWNERS file defined.
  - [Sentry](https://sentry.io/welcome/) integrated with [Redux Breadcrumbs](https://www.npmjs.com/package/redux-sentry-middleware) (You just need to fill in the credentials)
  - [Flipper](https://fbflipper.com/docs/getting-started/react-native/) support with [Redux Debugger](https://github.com/jk-gan/flipper-plugin-redux-debugger) plugin installed for viewing of Redux actions in Flipper
  - [Unimodule Suport](https://docs.expo.dev/bare/installing-unimodules/) allowing use and easy installation of Expo modules.
  - [Expo Splash Screen](https://github.com/expo/expo/tree/master/packages/expo-splash-screen)

**[⬆ back to top](#table-of-contents)**

---

## Quickstart

Init the project with the following command:

```sh
npx react-native init MyApp --template @nona-creative/react-native-template
```

Read your new project's README.md and docs to get started, and edit if you want to change anything.

The quickest way to run the application:

- Install ruby gems that the project required from the root with `bundle install`
- Run `npm run env:development` to generate an env file
- Run `npm run start` to start your bundler
- Run `npm run ios` or `npm run android`

**[⬆ back to top](#table-of-contents)**

---

## Splashscreen Customisation

- This template makes use of [expo-splash-screen](https://docs.expo.dev/versions/latest/sdk/splash-screen/) to show a splashscreen on startup. You can refer to the documentation [here](https://github.com/expo/expo/tree/master/packages/expo-splash-screen) for where to change this in your project.

**[⬆ back to top](#table-of-contents)**

---

## Android Build Notes

Some changes have been made to the Android build settings via setting certain properties in gradle.properties. At present they are:

```groovy
org.gradle.daemon=true
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xmx2048M -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
```

Feel free to change them as you see fit. Mostly they relate to memory settings for the JVM to prevent Android builds running out of memory on CircleCI

**[⬆ back to top](#table-of-contents)**

---

## Husky

This project has husky hooks defined at .husky. You should follow the guide setting up [Husky](https://typicode.github.io/husky/#/) here. To avoid installing these hooks on ci you can add the following to your scripts.

`"prepare": "is-ci || husky install"`

**[⬆ back to top](#table-of-contents)**

---

## CircleCI

The CircleCI config is included as an example of how you might go about setting up the project to build and deploy. Feel free to change it as you see fit. Things to note include:

- In this config, the keystore files are hosted on an S3 bucket and downloaded at build time. You can see from config.yml that this is defined as:

`echo 'export S3_URL=s3://$ANDROID_KEYSTORE_BUCKET/<< parameters.stage >>/' >> $BASH_ENV`

You would need to define that in your environment, and store the [keystore](https://developer.android.com/studio/publish/app-signing) in that bucket. You can also see that from `template/android/fastlane/Fastfile` that it is copying from the region eu-west-1, so if your bucket is in a different region you will have to change that.

Environment variables that you will need set in your project in CircleCI and what they do:

- GH_TOKEN - A GitHub [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line), that Semantic release will use to create release commits.
- ANDROID_KEYSTORE_BUCKET - bucket name that houses your Android keystore files
- ANDROID_KEYSTORE_PASSWORD - Android Keystore Password
- AWS_ACCESS_KEY_ID - AWS access key
- AWS_SECRET_ACCESS_KEY - AWS secret access key
- APP_STORE_CONNECT_KEY_ID - The Appstore Connect Key ID That you are using. (see [here](https://docs.fastlane.tools/actions/app_store_connect_api_key/))
- APP_STORE_CONNECT_ISSUER_ID - See [here](https://docs.fastlane.tools/actions/app_store_connect_api_key/)
- APP_STORE_CONNECT_API_KEY_B64 - The Base64 encoded Appstore Connect API key - See [here](https://docs.fastlane.tools/actions/app_store_connect_api_key/).

Environment variables to change in config.yml and what their purpose:

- KEY_FILE - Key file for the [Android Keystore](https://developer.android.com/studio/publish/app-signing)
- KEY_ALIAS - Alias for the [Android Keystore](https://developer.android.com/studio/publish/app-signing)

**[⬆ back to top](#table-of-contents)**

---

## Fastlane

### Setup Notes

Fastfiles are provided but you will have to change some of the details to get things to work, and go through setting up [Match](https://docs.fastlane.tools/actions/match/). The following are a list of files you will need to edit:

- ios/fastlane/Appfile - Change to your Team ID.
- ios/fastlane/MatchFile - Change all the details to your repo. You will also need to setup a [match repo](https://docs.fastlane.tools/actions/match/) to house your certs/provisioning profiles and go through the process of setting it up.

You might also want to store [metadata](https://docs.fastlane.tools/actions/deliver/) for your application in your version control system.

### Screenshot Generation

This project is automatically set up to [generate screenshots](https://docs.fastlane.tools/getting-started/ios/screenshots/) for iOS. To change what screenshots are captured, you need to edit the UI Test Defined in XCode (in this template they are at template/ios/NonaTemplateUITests/NonaTemplateUITests.swift, but they will be renamed to your project name on creation). It can save a huge amount of time if you do this, and you can upload Screenshots automatically as part of your Fastlane delivery process. Android is not supported at this time.

[Here is the guide to setting this up](https://docs.fastlane.tools/getting-started/ios/screenshots/), if you want to add more tests/gain greater understanding of the process

A note on using testID to identify items. This works for TouchableOpacity, but not for Button in React Native.

**[⬆ back to top](#table-of-contents)**

---

## Sentry

Sentry is set up with the project, but needs a few more things to be provided for it to work.

- ios/sentry.properties - Change the values in that file to match your team and project.
- Open the project in XCode via the .workspace file. Go to build phases, and edit **Upload Debug Symbols To Sentry** and uncomment `#../node_modules/@sentry/cli/bin/sentry-cli upload-dsym`
- Set your Sentry DSN value in `env/common.json` and re-init your environment with the env command.

**[⬆ back to top](#table-of-contents)**

---

## Semantic Release

For semantic release to work using the example CircleCI config you are going to need to run your jobs as a [Machine User](https://circleci.com/docs/2.0/gh-bb-integration/). That user should have the ability to push new commits on the branch that releases are created on (in the template it's develop), as it will create a release commit when doing so.

You're also going to need to follow the guide [here](https://semantic-release.gitbook.io/semantic-release/usage/ci-configuration) to create a token that you can set in Circle as an environment variable, allowing this user to create and push release commits.

**[⬆ back to top](#table-of-contents)**
