EVER Wallet Flutter app
Install melos:
$ dart pub global activate melos
Using melos makes it very easy to work with the project, so enjoy.
Boostrap packages recursively:
$ melos bs
This thing will run all code generators for all packages:
$ melos run codegen
This thing will run localization code generator for all packages:
$ melos run codegen:locale
$ melos run check-format
$ melos run analyze
To clean up all packages just run:
$ melos clean
To run all unit and widget tests use the following command:
$ melos test
Also you can run dart, flutter and integration tests separately:
$ melos test:dart
$ melos test:flutter
$ melos test:integration
To run code format check, analyzer and all tests use the following command:
$ melos check-all
To build storybook:
$ melos build:storybook
This project contains 3 flavors:
- development
- staging
- production
To run the desired flavor either use the launch configuration in VSCode/Android Studio or use the following commands:
# Development
$ flutter run --flavor development --target lib/main_development.dart
# Staging
$ flutter run --flavor staging --target lib/main_staging.dart
# Production
$ flutter run --flavor production --target lib/main_production.dart
*App works on iOS and Android. It should run on macOS, Linux and Windows, but we have no tests nor UI kit for desktop platforms.
App version is defined in pubspec.yaml
file. To bump the version use the following command:
# For development releases:
$ melos version -a --yes --prerelease
# For production releases:
$ melos version -a --yes --graduate
You can use version workflow in GitHub actions to bump the version automatically. This workflow will create a new branch and PR (because push to main is prohibited) with the new version. Don't forget to merge the PR to main! Note: you should use conventional commits to make it work.
App build number is defined in pubspec.yaml
file. However, there is a tools/get_build_number.dart
tool that generates the build number by incrementing it transactionally in Firebase Realtime Database. So, you don't need to worry about the build number, it's always unique and increases monotonously. Every time you build the app, the build number will be incremented.
Just copy secrets/.secrets.example
to secrets/.secrets
and fill it with your secrets.
Warning: don't commit this file!
Warning: FASTLANE_USER and is YOUR OWN credentials, that will be used only to renew iOS certificates and provisioning profiles
Other secrets you can get from your teammates:
SECRET_PASSPHRASE
: passphrase the GPG tarball (with secrets)
MATCH_PASSWORD
: passphrase for iOS provisioning profiles and certificates
BOT_ACCESS_TOKEN
: Personal access token (PAT) used to fetch the repository. We should use PAT and not default GITHUB_TOKEN because "When you use the repository's GITHUB_TOKEN to perform tasks, events triggered by the GITHUB_TOKEN, with the exception of workflow_dispatch and repository_dispatch, will not create a new workflow run". We want to trigger a workflow from the workflow (to run tests), so we need to use PAT. This thing is used in version
workflow.
SECRET_PASSPHRASE
and MATCH_PASSWORD
is the same as in local .secrets
file.
This file contains all secrets and is encrypted with GPG. To decrypt it, run the following command:
$ melos decrypt-secrets
To update the file with secrets, create directory structure as mentioned above, cd to it and run the following command:
$ tar c * > secrets.tar
$ gpg --symmetric --cipher-algo AES256 secrets.tar
You will be asked to enter the passphrase. This passphrase should be SECRET_PASSPHRASE
from .secrets
file.
Resulting secrets.tar.gpg file should be placed in secrets
directory in the root of the project.
For iOS we use match to manage certificates and provisioning profiles. It's configured in ios/fastlane/Matchfile
. To renew certificates and provisioning profiles after adding new devices to the Apple Developer Account, run the following command:
$ melos build:ios_match_new_devices
If you configuring a new machine, you should run the following command to install certificates and provisioning profiles:
$ melos build:ios_match_assure
We prefer to deploy the app using GitHub Actions, but you can also deploy it from your local machine.
All deployment scripts are gathering changelog from git commits and adding it to the release notes. Note: google play limits the release notes, so don't be surprised that it is simplified and shortened.
We already have a workflow for deploying main app to Firebase App Distribution, TestFlight and Google Play closed testing. It's called app=deploy
and it's triggered by pushing to the main branch or manually from any branch. You can choose the desired deployment when triggering the workflow manually. It will deploy to FAD when its triggered by pushing to the main branch.
We also have a workflow for deploying storybook to GitHub Pages. It's called storybook-gh-pages-deploy
and it's triggered by pushing to the main branch or manually from any branch.
# To deploy to Firebase App Distribution just run the following command:
$ melos build:deploy_fad
# To deploy to TestFlight and Google Play closed testing just run the following command:
$ melos build:deploy_store
# Also you can deploy it to Firebase App Distribution, TestFlight and Google Play closed testing at once:
$ melos build:deploy_fad_store
Each of these commands will increment the build number before building the app.
To view the generated coverage report you can use lcov.
# Generate Coverage Report
$ genhtml coverage/lcov.info -o coverage/
# Open Coverage Report
$ open coverage/index.html
The app can be built with several flavors. Each of them determines the logging level. The defining map is in logs/logs.dart
.
We also have logs from nekoton, and level transformation matrix is in packages/nekoton_repository/lib/src/nekoton_repository.dart
.
Console colors are defined in fancy_logger package.
This project relies on flutter_localizations and follows the official internationalization guide for Flutter. However, we use easy_localization package to simplify the internationalization process.
- To add a new localizable string, open the
en.json
file atassets/translations/en.json
.
{
"confirm": "Confirm"
}
- Then add a new key/value
{
"confirm": "Confirm",
"continueWord": "Continue"
}
- Use the new string
import 'package:app/generated/generated.dart';
@override
Widget build(BuildContext context) {
return Text(LocaleKeys.continueWord.tr());
}
Update the CFBundleLocalizations
array in the Info.plist
at ios/Runner/Info.plist
to include the new locale.
...
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>es</string>
</array>
...
- For each supported locale, add a new JSON file in
assets/translations
.
βββ assets
β βββ translations
β β βββ en.json
β β βββ es.json
- Add the translated strings to each
.json
file:
es.json
{
"confirm": "Confirmar",
"continueWord": "Continuar"
}
- Provide flag icon asset
Put new vector icon to assets/images/lang_icons/spanish.svg
.
- Add the locale to
SupportedLocaleCodes
enum inlib/app/service/localization/service/supported_locale_codes.dart
(yes, don't forget the language string).
...
es(LocaleKeys.langSpanish),
...
- Provide flag icon asset and iconPath in
SupportedLocaleCodes
enum
...
SupportedLocaleCodes.ko => Assets.images.langIcons.spainsh.path,
...