Skip to content

Mobile application built on React Native to serve residents of Helsingborg.

License

Notifications You must be signed in to change notification settings

helsingborg-stad/app-mitt-helsingborg

Repository files navigation

Contributors Forks Stargazers Issues License

Logo

Mitt Helsingborg banner

Mitt Helsingborg

App for Helsingborg E-services.
Report Bug · Request Feature

Table of Contents

About Mitt Helsingborg

Mitt Helsingborg is an iOS and Android app used by citizens in Helsingborg, Sweden. This app allow citizens to interact with various Helsingborg E-services.

The app is built with React Native using TypeScript. Other tech choices includes:

Getting Started

To get a local copy up and running follow these simple steps.

Prerequisites

Note: in general the supported version of any given dependency is the same as the version used by the CI.

Installation

  1. Clone the repo
git clone https://github.com/helsingborg-stad/app-mitt-helsingborg.git
  1. Install packages
yarn install
  1. Copy .example.env to .env and fill in the required variables.

  2. Run app on iOS simulator

yarn ios
  1. Run app on Android emulator
yarn android

Setup environment variables

The app uses dotenv (.env) files to read environment variables during build-time. Copy example.env to .env replace the values to get started.

Backend selector

Set MITTHELSINGBORG_IO to an MH-compatible url (see helsingborg-io-sls-api) and set MITTHELSINGBORG_IO_APIKEY to the API key required to authorize against it. This will be used as the default environment when using the app.

After starting the app, at the Login Screen, you can optionally provide additional environment(s) to override the default environment. To do so click the gear icon in the top-right corner and enter a value for the "App Konfiguration".

The format of the configuration is:

{ "envName": ["apiUrl", "apiKey"] }

For example, to provide two environments, develop and release, enter:

{
  "develop": ["https://myapi.com/dev", "123"],
  "release": ["https://myapi.com/release", "abc"]
}

If multiple endpoints are specified like the example, a dropdown-picker will be shown on the Login Screen where you can choose which environment to use.

If only one environment is specified then it will be used instead of the default environment specified in the .env file.

Component library (Storybook)

  1. Set env variabel IS_STORYBOOK to true in .env
  2. Launch application in simulator by running command "yarn ios".
  3. Now you should see storybook running in the simulator.

Deploy

Android

Add upload key

To be able to sign the app you need to add an upload key to the project.

  1. Open 1Password app and enter vault: Mitt Helsingborg.
  2. Download mitt-helsingborg-upload-key.keystore.
  3. Place the mitt-helsingborg-upload-key.keystore file under the android/app directory in your project folder.
  4. Create a keystore.properties file:
cd android && cp example.keystore.properties keystore.properties
  1. Update keystore.properties with passwords.

Important: Make sure to never push mitt-helsingborg-upload-key.keystore or keystore.properties to Git.

Generate AAB (Android App Bundle)

  1. Open android/app/build.gradle
  2. Update versionCode by taking the latest published versionCode and increase it by 1. You can find previous uploaded versions at Google Play Console.
  3. Update versionName. This is displayed publicly when downloading the app.
  4. Generate release AAB:
cd android
./gradlew bundleRelease

The generated AAB can be found under android/app/build/outputs/bundle/release/app.aab.

Test the release build

Before uploading the release build to the Play Store, make sure you test it thoroughly. First uninstall any previous version of the app you already have installed.

npx react-native run-android --variant=release

Upload AAB to Google Play Console

  1. Go to Google Play Console and navigate to the project app.
  2. Click on Production in the menu.
  3. Click Create New Release button and follow the instructions.

CI / Automated Builds

This project uses GitHub actions in combination with Fastlane to automatically build and upload builds (currently iOS only).

CI builds are built as production-ready by default. For testing CI builds you can specify custom environments in-app (see Backend selector).

General

A distinct process (e.g. "build an iOS app") is denoted as a "workflow". Each workflow is a separate yaml file in .github/workflows. Most workflows can be manually run from the actions tab if you have access. Previous workflow runs with logs and artifacts can also be found there.

Configuration (environment variables) are provided through GitHub secrets.

Many operation are done with Fastlane. Fastlane is a tool used to simplify many actions (such as handling certificates and profiles, creating and uploading builds, etc.). Fastlane is used through ruby files that are run in a Fastlane context with fastlane run <lane>. A lane is a single contained process, such as creating and uploading a build.

iOS build (TestFlight)

The workflow file for iOS builds is ./github/workflows/ios-build.yml. It can be run manually, and runs automatically for any push to branches matching release/** (e.g. release/1.4.0). It automatically tries to determine the version and build number to set based on the branch name, and defaults to incrementing the latest from TestFlight.

Version number and build number can optionally be forced for manual runs.

The workflow sets up dependencies and variables and then calls a specific Fastlane lane defined in ios/fastlane/Fastfile.

Environment variables (secrets)

Variables used by the workflow and Fastlane are documented in the Fastlane example.env. The other variables used by the build workflow are:

Variable Contents
BUILD_CERTIFICATE_BASE64 Base64 representation of the Apple distribution certificate .p12 file. Generate with cat cert.p12 | base64.
P12_PASSWORD Password to unlock the contents of BUILD_CERTIFICATE_BASE64 (the password entered during the certificate export).
CACHE_KEY_PREFIX Used to change the id for the caching of node modules and cocoapods. Changing this will essentially invalidate the cache. The actual value is not important but it's a good praxis to use the current date, to avoid future conflicts.
CERT_KEYCHAIN_PASSWORD Password used for the ephemeral keychain used to store the certificate. This variable is mostly unimportant as the keychain is not persistent.
DOTENV_CONTENTS_BASE64 Contents of the .env file. See example.env. Generate with cat .env | base64.
SENTRY_PROPERTIES_BASE64 Contents of the sentry.properties file (see Sentry).

Other workflows

In addition to builds there the following workflows:

  • automated-tests.yml - runs yarn test for pull requests
  • styling-linting.yml - checks styling consistency and linting errors for pull requests
  • tag-master.yml - can be used to tag a branch based on the name of a ref (e.g. release/1.4.0 => 1.4.0)

Sentry

Sentry is used for live error reporting in deployed builds. To use Sentry add your Sentry DSN as an environment variable:

SENTRY_DSN=https://1234@sentry.mydomain.se/0

Additionally, to get correct symbols and sourcemaps for release builds add a file called android/sentry.properties or ios/sentry.properties and add your credentials:

defaults.url=https://sentry.mydomain.se/
defaults.org=sentry
defaults.project=my-sentry-project
auth.token=my-auth-token

These files can be automatically generated by running the Sentry Wizard:

npx @sentry/wizard -i reactNative -p ios android -u https://sentry.mydomain.se/

For CI it is recommended to generate a Internal Integration Token instead of using a user-token for auth.token. An Internal Integration can be created from your Sentry dashboard under Settings -> Developer Settings.

Roadmap

See the project backlog for a complete list of upcoming features, known issues and releases.

Contributing

Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request