Flutter Heyteacher Meta
A Flutter meta project implementing utilities and best practices for Flutter package and app project avoiding Copy & Paste pattern.
- environment setup instructions for
appandpackageprojects andFirebasesetupappprojects gitutilities for manage versions and releases- release app in
Google PlayandFirebase App Distribution - integration test and
Firebase Test Labutilities - backup and restore
Firestoreutilities localizationsetup instructions- documentation utilities
Launcher Icon,Splash,dart builder,ffmpeg,webcryptoutilities
Table of Contents
- Flutter Heyteacher Meta
- Table of Contents
- Installing
- Credits
- Requirements
- Environment Setup
- Create a flutter project
Fastlanelines forappandpackageprojectsFastlanelines forappprojectsgitutilitiesFirebasesetup forappflutter project- Release app
- Integration Test
Firestorebackup, restore and Point-in-time recovery- Firebase Hosting
localizationsetup- documentation utilities
- Launcher Icon
- Splash
- Dart Builders
ffmpegutilities- command-line utility
version webcryptosetup for tests
Installing
-
setup environment following instruction Environment Setup
-
install
flutter_heyteacher_metaas dev package into yourapporpackageproject:flutter pub add dev:flutter_heyteacher_metaor add to your
pubspec.yamldev_dependencies: flutter_heyteacher_meta: -
follow instuctions in Configure
FastLanein order to configure aapporpackageproject. -
test all works fine, running
flwill show command avaiable
Credits
-
yaml_edit: A library for YAML manipulation while preserving comments
-
very_good_analysis: This package provides lint rules for Dart and Flutter which are used at
Very Good Ventures -
auto-changelog: Command line tool for generating a changelog from git tags and commit history
-
vscode-markdownlint: Markdown/CommonMark linting and style checking for Visual Studio Code
-
vscode-markdown: All you need for Markdown (keyboard shortcuts, table of contents, auto preview and more).
Requirements
-
a shell terminal on
Linux,MacOSor WSL onWindows -
git1.7.2 or later -
a
GitHubaccount -
gh2.46.0 or later (GitHub CLI) -
other software and utilities as described in Environment Setup
Environment Setup
Instructions for setup environment installing all software needed to develop a Flutter project.
Flutter
install flutter manually following instructions docs.flutter.dev/install/quick#install
-
setup your
~/.bashrcwith this env variables# flutter export PATH=/usr/local/flutter/bin:$PATH # dart export PATH="$HOME/.pub-cache/bin":$PATH # flutter_heyteacher_meta scripts latest_meta_version=`ls $HOME/.pub-cache/hosted/pub.dev | grep flutter_heyteacher_meta | tail -n 1` project_meta_root="$HOME/.pub-cache/hosted/pub.dev/$latest_meta_version" export PATH="$project_meta_root/scripts":$PATH
Visual Studio Code
install Visual Studio Code 1.77 or later with the Flutter extension for VS Code
You can configure you vscode to execute the command-line utility version in order to automatically update build version every run/debug execution of your code:
-
install
flutter_heyteacher_metapackage as dev dependency ad described in Installing -
create/modify
.vscode/tasks.jsonin the root of your project{ "version": "2.0.0", "tasks": [ { "type": "dart", "command": "dart", "args": [ "run", "flutter_heyteacher_meta:version", "build" ], "group": "build", "problemMatcher": [], "label": "dart: run flutter_heyteacher_meta:version build", "detail": "increment version build number", "presentation": { "close": true, "echo": false, "reveal": "silent", "focus": false, "panel": "shared", "showReuseMessage": false, "clear": false } } ] } -
add
preLaunchTaskin your launch configurations '.vscode/launch.json'... "preLaunchTask": "dart: run flutter_heyteacher_meta:version build"
Android Studio
-
install
Android Studio -
setup your
~/.bashrcwith this env variables and alias#android studio export ANDROID_HOME="$HOME/Android/Sdk/" export PATH="${PATH}:${ANDROID_HOME}tools/:${ANDROID_HOME}platform-tools/" export PATH=/usr/local/android-studio/jbr/bin/:$PATH
auto-changelog
auto-changelog is an utility which generate CHANGELOG.md automatically based
on commits, pull requests and tags.
-
install
npmas described innodeJs -
install
auto-changelognpm install -g auto-changelog -
test the command
auto-changelog
FastLane
-
install rbenv, ruby and bundler
brew install rbenv rbenv init rbenv install -l rbenv install 3.4.3 rbenv local 3.4.3 gem install bundler -
create Genfile in project root containing:
source "https://rubygems.org" gem "fastlane" -
install fastlane via bundle
bundle update -
setup your
~/.bash_aliaseswith this fl alias# alias for fastlane inside flutter projects alias fl='fl.sh'flis an alias offl.shcommand.
#!/bin/bash
#
# Run FastLane Lanes.
#
# Executed without paramenter show lanes available and documentation
if [[ -z ${@} ]]
then
# show lanes avalilable and documentation
bundle exec fastlane lanes
else
# run lane
bundle exec fastlane $@
fi
the execution fl in root project directory without paramenter show all lanes configured and how to use them.
nodeJs
-
install
nodeJscurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash nvm install 22
Firebase CLI
-
install
firebase-toolsnpm install -g firebase-tools
Create a flutter project
-
flutter app project:
flutter create <app project name> -
flutter package projects:
flutter create -t package <app project name>
Configure FastLane
After setup the environment run from root project directory and create the project:
-
for flutter packages:
configure_flutter_package.sh -
for flutter app
configure_flutter_app.shThis scripts create a skeleton of
fastlane/metadatamandatory for release application inGoogle Play. So, before release the application you need to:-
edit
fastlane/metadata/android/en-US/title.txt -
edit
fastlane/metadata/android/en-US/short_description.txt -
edit
fastlane/metadata/android/en-US/full_description.txt -
edit
fastlane/metadata/android/en-US/video.txt -
edit
fastlane/metadata/android/en-US/changelogs/default.txt -
edit
fastlane/metadata/android/en-US/images/icon.png -
edit
fastlane/metadata/android/en-US/images/featureGraphic.png -
add screenshots to
fastlane/metadata/android/en-US/images/phoneScreenshots
For utilize
Firebase Firestorebackup and restore utilities, edit./fastlane/Fastfileuncommenting and setup these environment variable:google_storage_backup_bucketthe Google Storage backup bucket name
For utilize
Firebase App Distribution, edit./fastlane/Fastfileuncommenting and setup these environment variable:firebase_app_distribution_service_credentials_filetheFirebase App Distributionservice credentials file name
-
Fastlane lines for app and package projects
Common Fastlane lines are provided to app and package projects. In details:
- generate dart documentation
- checkout and release on
github - run unit test
doc
fl doc
Generate the dart documentation and run webserver on http://localhost:8080
docweb
fl docweb
Runs local webserver on http://localhost:8080 with dart documentation
test
fl test
Run unit tests of the project.
checkout
fl checkout
Checkout the latest remote branch already created remotely (i.e. in github project ).
Runs git fetch and git checkout to the latest branch fetched.
release
fl release semver:major|minor|patch [suffix:<nmenonic_tag_suffix>] [merge:true|false] [github:false|true]
Release to main branch after you commit and push your changes into your branch.
semver: increments the version intopubspec.yamlfollowing Semantic Versioning, for example:major: move version from1.0.0to2.0.0minor: move version from1.0.0to1.1.0patch: move version from1.0.0to1.0.1
suffix: (optional) add a mnemonic suffix to gittaggreatedmerge: (optional, defaulttrue) make the marge tomainbranchgithub: (optional, defaultfalse) create the github release and update theCHANGELOG.md
These command make several tasks:
- increments the version into
pubspec.yaml - create a
github releaseand updateCHANGELOG.md(ifgithubparam is `true) - create a
pull requestand merge changes intomainbranch - checkout the
mainbranch - delete the branch merged (if
mergeparam is `true) - create a git
tagnamed{package-name}-{version}
github_release
fl github_release
Create a github release and update CHANGELOG.md
bump
fl bump
Commits pubspec.lock and pubspec.yaml without generate a new version and without create a new release.
Creates a github release and update CHANGELOG.md
Fastlane lines for app projects
Specific Fastlane lines are provided for app projects. In details:
- build
AAB - run integration test locally or on
Firebase Test Lab - backup and restore
Firestoredababase - release application in
Google PlayandFirebase App Distribution - build and release web application in
Firebase Hosting
appbundle
fl appbundle
Clean and build the application.
When completed, the AAB is generate into build/app/outputs/bundle/release/app-release.aab.
integration_test
fl integration_test
Run integration tests of app project.
testlab
fl testlab
Run integration test of app project in Firebase Test Lab
firestore_backup
fl firestore_backup [snapshot:YYYY-MM-DDTHH:mm:ss.00Z] [database:<database>]
Backup Firestore dababase. if snapshot is set, create backup at time specified. If database isn't set use (default). For details Firestore backup, restore and Point-in-time recovery.
firestore_restore
fl firestore_restore backup:<YYYY-MM-DDTHH:mm:ss_mi> [database:<database>]
Restore Firestore dababase to specified backup. If database isn't set use (default).
For details Firestore backup, restore and Point-in-time recovery.
firestore_remove_backup
fl firestore_remove_backup backup:<YYYY-MM-DDTHH:mm:ss_mi>
Remove Firestore dababase backup specified.
For details Firestore backup, restore and Point-in-time recovery.
app_distribution
fl app_distribution
Build the release and publish app in Google Play via Firebase App Distribution
playstore
fl playstore track:production|beta|alpha|internal [upload_only:true|false]
Upload app in Google Play via supply on track. if upload_only is true upload app without build. (default false)
playstore_promote
fl playstore_promote from_track:beta|alpha|internal to_track:production|beta|alpha|internal
Promote a release in Google Play via supply from from_track to to_track.
buildweb
fl buildweb [version:profile|debug]
Build web and run local webserver on http://localhost:8080
deployweb
fl deployweb [release_type:release|profile|debug]
Deploy web in Firabase Hosting with release type release_type (default release)
git utilities
checkout and release commands with git hooks for git conventional commit and avoid commit on main branch helps you to work properly with versions, git branches, git tags and github releases.
bump command commit pubspec.lock and pubspec.yaml after a bump version on dependencies without create a new version and without create new release.
git conventional commit
The commit message should follow che conventional commit specification:
<type>[optional scope]: <description>
where <type> MUST be one of:
build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)chore: (updating grunt tasks etc; no production code change)ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)docs: Documentation only changesfeat: A new featurefix: A bug fixperf: A code change that improves performancerefactor: A code change that neither fixes a bug nor adds a featurestyle: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)test: Adding missing tests or correcting existing tests
avoid commit on main branch
main branch is the default branch and user cannot be commit directly on it, but only merge are allowed.
If you try to commit on main this message is show
You can't commit directly to main branch
example: release a patch
-
if you create an
github issueand a branch ongithubfl checkoutotherwise create a branch locally and push it to remote
git branch hotfix git push -u origin hotfix -
make changes to your code, commit and push changes to branch
git add . git commit -m "fix: fix bug ..." git push -
release the patch merging chenges to
mainbranch and create agithub releasefl release version:patch github:true
Firebase setup for app flutter project
-
login in firebase and install flutterfire
firebase login dart pub global activate flutterfire_cli flutterfire configure -
add firebase core and other packages
flutter pub add firebase_core flutter pub add firebase_auth flutter pub add cloud_firestore flutterfire configure -
initialize firestore, and deploy rules and indexes
firebase init firestore firebase deploy --only firestore -
build and run application created
flutter run
Release app
Sign app
-
generate upload keystore
mkdir -p ~/.flutter keytool -genkey -v -keystore ~/.flutter/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload -
create
android/key.propertiescontaining:storePassword=<password-from-previous-step> keyPassword=<password-from-previous-step> keyAlias=upload storeFile=<keystore-file-location> -
configure Gradle following instruction docs.flutter.dev/deployment/android#configure-signing-in-gradle
-
create the ABB file running
flutter build appbundle. The file created is located here:build/app/outputs/bundle/release/app-release.aab -
extract SHA-1 SHA-256 from keystore
keytool -list -v -alias upload -keystore ~/.flutter/upload-keystore.jksor directly from
app-release.aabkeytool -printcert -jarfile build/app/outputs/bundle/release/app-release.aab -
load SHA256 in firebase AppCheck section in (
appcheck/apps) (this istruction doesn't work for firebase.google.com/docs/app-check/android/play-integrity-providerCurrently, the built-in Play Integrity provider only supports Android apps distributed by Google Playand stackoverflow.com/a/78698583/1123065) -
link Google Cloud project to Google Play console follow istructions developer.android.com/google/play/integrity/setup
Firebase App Distribution
-
follow istructions firebase.google.com/docs/app-distribution/android/distribute-fastlane?apptype=aab
-
Copy the AppDistribution JSON keys created in google cloud IAM in:
~/.flutter/<YOUR_PROJECT>-app_distribution.json -
setup your
~/.bashrc# setup for `Firebase App Distribution` in `~/.flutter/` export GOOGLE_APPLICATION_CREDENTIALS=<path_of_app_distribution_json> -
run
firebase login:ciand copy the token generated -
create the file
~/.flutter/firebase_cli_token.jsonand paste the token generate in this json:{ "firebase_cli_token": "<paste here token generated by 'firebase login:ci'>" } -
run fastlane
fl.sh distribute
Google Play
-
create the app and publish for internal test in Google Play following instructions support.google.com/googleplay/android-developer/answer/9859152?hl=en
-
Link Firebase App Distribution to Google Play account following instructions support.google.com/firebase/answer/6392038
-
run fastlane
./fl.sh playstore track:production|beta|alpha|internal
Integration Test
Follow the instruction github.com/flutter/flutter/tree/main/packages/integration_test
with this changes:
-
android/gradle/wrapper/gradle-wrapper.properties- distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip + distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip -
android/settings.gradle- id "com.android.application" version "8.1.0" apply false + id "com.android.application" version "8.7.0" apply false
Run locally on device connected:
flutter test integration_test/main.dart
or
flutter driver --driver=test_driver/main_test.dart --target=integration_test/main.dart
or with gradlew
./gradlew app:connectedAndroidTest -Ptarget=`pwd`/../integration_test/main.dart
Firebase Test Lab
-
buid integration test artifacts using scripts
android/firebaseTestLabBuild.sh, shortcut of:./gradlew app:assembleAndroidTest ./gradlew app:assembleDebug -Ptarget=`pwd`/../integration_test/main.dart -
select device from supported devices:
gcloud firebase test android models list -
you can filter only virtual devices (hight availability, lower cost):
gcloud firebase test android models list --filter=virtual -
start test in Firebase Test Lab on the selected device launching gcloud command. For example, run test in Medium Phone virtual with android 13 (version 33):
gcloud firebase test android run --type instrumentation --app=../build/app/outputs/apk/debug/app-debug.apk --test=../build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk --device model=MediumPhone.arm,version=33,locale=en,orientation=portrait
The lane fl testlab run commands above
Firestore backup, restore and Point-in-time recovery
install gcloud
With Google Cloud CLI you can manage command line Gogle Cloud services.
sudo apt-get install apt-transport-https ca-certificates gnupg curl
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
sudo apt-get update && sudo apt-get install google-cloud-cli
inizialize configuring your project
gcloud init
create the bucket <PROJECT_NAME>-backups which hosts backups here: console.cloud.google.com/storage/browser
Restore a Point-in-time Recovery (PITR)
You can restore the database snapshot since last 15 days specifying snapshot-time in ISO 8601 format.
fl firestore_backup snapshot:<YYYY-MM-DDTHH:mm:ss.00Z>
# restore the backup <YYYY-MM-DDTHH:mm:ss_mi> already created
fl firestore_restore <YYYY-MM-DDTHH:mm:ss_mi>
Backup and Restore database
-
create a backup of current firestore database
fl firestore_backup -
restore a firestore backup
# list all backups fl firestore_restore # restore a backup fl firestore_restore <YYYY-MM-DDTHH:mm:ss_mi> -
remove a firestore backup
# list all backups fl firestore_restore # remove backup fl firestore_remove_backup <YYYY-MM-DDTHH:mm:ss_mi>
Firebase Hosting
Deploy and publish a flutter web app into Firebase Hosting.
Default site:
- Site Id:
<Firebase Project Id> Default URL:<Firebase Project Id>.web.appand<Firebase Project Id>.web.firebaseapp.com/
Deploy default site
-
configure
firebase.jsonadding hosting configuration"hosting": { "public": "build/web", "frameworksBackend": { "region": "<Firebase Region>" } } -
build web and test locally
fl buildweb [--debug:true] -
deploy to default
sitefirebase deploy --only hosting
Default site cannot be deleted, you can disable entire hosting:
firebase hosting:disable
Alternative sites
-
define the alternative site
firebase target:apply hosting <Alternative Site Id> <Alternative Site Id> -
Create the alternative site
firebase hosting:sites:create <Alternative Site Id> -
configure
firebase.jsonaddingtarget"hosting": [ { "target": "<Alternative Site Id>", "public": "build/web", "frameworksBackend": { "region": "<Firebase Region>" } } ] -
deploy to the alternative site
firebase deploy --only hosting
To list all sites created:
firebase hosting:sites:list
To delete an alternative site:
firebase hosting:sites:delete <Alternative Site Id>
localization setup
-
install packages
flutter pub add flutter_localizations --sdk=flutter flutter pub add intl:any -
modify
pubspec.yamlsetting flutter artifact generationflutter: generate: true -
in root project creat
l10n.yamlarb-dir: lib/src/l10n template-arb-file: flutter_heyteacher_locale_en.arb output-localization-file: flutter_heyteacher_locale.dart output-class: FlutterHeyteacherLocaleLocalizations output-dir: lib/src/l10n untranslated-messages-file: untranslated-messages.txt -
create the
arbfiles of your supported languagesmkdir lib/l10n touch lib/l10n/flutter_heyteacher_locale_en.arb touch lib/l10n/flutter_heyteacher_locale_it.arb -
insert in
flutter_heyteacher_locale_en.arbthe translation -
commit
untranslated-messages.txtthe file containing localized strings to be translated, this file should be always emptygit add untranslated-messages.txt git commit -m "chore: localized strings to be translated, this file should be always empty" -
insert localized string into
flutter_heyteacher_locale_en.arb{ "@@locale": "en", "userNotAutenticated": "User not autenticated", "@userNotAutenticated": {}, "notAuthenticated": "Not Authenticated", "@notAuthenticated": {}, "errorOnRetrieveData": "Error on retrieve Data", "@errorOnRetrieveData": {}, "timeoutOnRetrieveData": "Timeout on retieve data", "@timeoutOnRetrieveData": {} } -
regenerate the artifacts
flutter pub get -
create a file
lib/localizations.dartcontaining the exportexport 'package:flutter_heyteacher_locale/src/l10n/flutter_heyteacher_locale.dart' show FlutterHeyteacherLocaleLocalizations; -
add delegate to your app
MaterialApp.router( localizationsDelegates: [ . . . FlutterHeyteacherLocaleLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], ) -
import and use in your code
import 'package:flutter_heyteacher_locale/localizations.dart'; . . . FlutterHeyteacherLocaleLocalizations.of(context)!.userNotAutenticated
documentation utilities
fl doc
Generates dart documentation, run a local web server on http://localhost:8080 and open a browser on it.
fl docweb
Run a local web server on http://localhost:8080 and open a browser on project documentation already generatd
Launcher Icon
-
install flutter_launcher_icons
flutter pub add flutter_launcher_icons -
create or modify 'assets/icon/icon.png' and 'assets/icon/background.png'
-
add configuration to
pubspec.yaml
flutter_launcher_icons:
android: "launcher_icon"
ios: false
remove_alpha_ios: true
image_path: "assets/icon/icon.png"
min_sdk_android: 21 # android min sdk min:16, default 21
adaptive_icon_background: "assets/icon/background.png"
adaptive_icon_foreground: "assets/icon/icon.png"
web:
generate: true
image_path: "assets/icon/icon.png"
background_color: "#000000"
theme_color: "#000000"
windows:
generate: true
image_path: "assets/icon/icon.png"
icon_size: 48 # min:48, max:256, default: 48
macos:
generate: true
image_path: "assets/icon/icon.png"
-
run
dart run flutter_launcher_icons
Splash
-
install flutter_native_splash)
flutter pub add flutter_native_splash -
create or modify 'assets/splash.png'
add configuration to pubspec.yaml
flutter_native_splash:
color: "#000000"
image: assets/splash.png
android_12:
image: assets/splash.png
color: "#000000"
-
run
flutter_splash.shan alias of:
dart run flutter_native_splash:create
Dart Builders
The builders like:
can be gererated using script:
dart_builders.sh
ffmpeg utilities
ffmpeg_cmd is a bash script with utilites for crop, cut, estract and concat.
ffmpeg_cmd.sh
Usage:
-
crop
ffmpeg_cmd.sh crop <input_video> <output_video> <width_in_px> <height_in_px> <x_in_px> <y_in_px> -
cut
ffmpeg_cmd.sh cut <input_video> <output_video> <start_in_sec> <end_in_sec> -
extract
ffmpeg_cmd.sh extract <input_video> <output_video> <start_in_sec> <end_in_sec> -
concat
ffmpeg_cmd.sh concat <input_video_1> <input_video_2> [input_video_3 ...] <output_video> <fade_duration_in_sec>
command-line utility version
From the root of your project, run:
dart run flutter_heyteacher_meta:version major|minor|patch|build|show|show-build [--dry-run]
-
major,minor,patchincrement the version in yourpubsec.yaml.--dry-runshow how the version will be changed without modifypubsec.yaml -
buildset the build version in yourpubsec.yamltoYYMMddHHmbased on the current time. -
dry-runshow how the version will be changed without modifypubsec.yaml -
showprint the version inpubsec.yaml -
show-buildprint only the build version frompubsec.yaml
webcrypto setup for tests
Flutter tests which use webcrypto need to be compiled locally running this command:
flutter_webcrypto_setup
an alias of:
dart run webcrypto:setup
Libraries
- fake_pubspec_version
- main
- pubspec_version
- A command-line utility to manage the version string in
pubspec.yaml.