Skip to content

feat(Fastlane): Fastlane integration #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e6afe9d
feat(Fastlane): Added documentation
Onix-Ivan Apr 24, 2024
ea680fc
temp
Onix-Ivan Apr 25, 2024
4e7f0ea
feat(Fastlane): Added Fastlane files generator service
Onix-Ivan May 1, 2024
bbdcbf8
feat(Fastlane): Added logic
Onix-Ivan May 3, 2024
7181856
fix(Fastlane): Removed clean line from flavorizr makefile
Onix-Ivan May 3, 2024
f6ea8bb
feat(Fastlane): Added logic for skipping documentation and fastlane g…
Onix-Ivan May 3, 2024
a5ce744
feat(Fastlane): Updated INSTALL_INSTRUCTION
Onix-Ivan May 6, 2024
b8522bd
fix(flavors): command run fix
fedorenkoalex May 6, 2024
2f41623
fix(flavors): command run fix
fedorenkoalex May 6, 2024
b6507d2
fix(flavors): command run fix
fedorenkoalex May 6, 2024
9a20126
fix(flavors): command run fix
fedorenkoalex May 6, 2024
115eb1f
fix(docs): fixed flavr documentation
fedorenkoalex May 6, 2024
9107c47
feat(Fastlane): Fixed bug with copying files, added error output
Onix-Ivan May 6, 2024
34a3df4
Merge branch 'feature/fastlane_documentation' of github.com:Onix-Syst…
Onix-Ivan May 6, 2024
2c1df63
feat(Fastlane): Added .gitignore file instructions
Onix-Ivan May 8, 2024
1d0d032
fix(Fastlane): Fixed async call issue with writeAsStringSync method
Onix-Ivan May 8, 2024
10cd67c
fix(Fastlane): Updated fastlane instructions
Onix-Ivan May 8, 2024
252fe3f
fix(Fastlane): Updated Android Appfile
Onix-Ivan May 8, 2024
01cedaa
fix(Fastlane): Updated Fastfile android and ios
Onix-Ivan May 8, 2024
fc9985e
feat(version): fixed version check
fedorenkoalex May 9, 2024
7d2d7ce
feat(Fastlane): Updated .gitignore
Onix-Ivan May 9, 2024
3c84c0e
Merge branch 'feature/fastlane_documentation' of github.com:Onix-Syst…
Onix-Ivan May 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 70 additions & 15 deletions assets/documentation/docs/INSTALL_INSTRUCTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This section describes different installation options. It consists of the following parts:

* Terminology
* Terminology
* Platforms supported
* Environment variables and setup
* Important installation instructions
Expand All @@ -14,19 +14,14 @@ This section describes different installation options. It consists of the follow

## Terminology

* **Output Type** - platform keyword used in run or build commands to specify for what platform app will be built. Available platforms are:
* **Output Type** - platform keyword used in run or build commands to specify for what platform app will be built. Available platforms are:

```
{output_types}
```
Apk and AppBundle refers to Android and specifies a type of output file (`*.apk` or `*.aab`).


* **Flavor** - type of application configuration. {app_name} supports following flavors:

```
{app_flavors}
```

* **Build type** - type of build process: `release` or `debug`.
* **main.dart** file - main file and entry point of your application. {main_count_description}:
Expand All @@ -36,12 +31,12 @@ Apk and AppBundle refers to Android and specifies a type of output file (`*.apk`
```

When you specifying a flavor in run or build command you also need to specify corresponding `main.dart` file for that flavor.

## Platforms supported

{app_name} application supported on following platforms:

{app_platforms}
{app_platforms}

## Important installation instructions

Expand All @@ -58,14 +53,14 @@ When you sure you installed followed software follow steps to prepare {app_name}

## Environment variables and setup

To add project environment keys need to create `.env` file in root folder for each of flavors:
To add project environment keys need to create `.env` file in root folder for each of flavors:

```
{app_env_files}
```

{app_env_explanation}
Environment file scheme:
{app_env_explanation}
Environment file scheme:

```
STRIPE_KEY=enter_stripe_key
Expand All @@ -86,7 +81,7 @@ You can use commands to run applications also. To run app:

## How to run {app_name} automatic tests

{app_name} application is covered with **unit** and **widgets** tests.
{app_name} application is covered with **unit** and **widgets** tests.
The goal of a unit test is to verify the correctness of a unit of logic under a variety of conditions.
The goal of a widget test is to verify that the widget’s UI looks and interacts as expected.

Expand All @@ -111,15 +106,75 @@ Next step is depending on platform:

* For iOS and MacOS open ios/macos folder of project in XCode and follow instructions How to upload app to AppStore
* For Android you'll see the location of the output file in the terminal after build finished. Follow the instruction to upload build to Play Store
* For Web - after build completed - deploy content of `/web` folder to your server
* For Web - after build completed - deploy content of `/web` folder to your server

## How to build and distribute {app_name} application using fastlane

Before you use fastlane to build and distribute:

1. Make sure you are using **ruby version 3.0 or newer**
2. Using the iOS build, call `xcode-select --install`
3. Install fastlane using `brew install fastlane` or `gem install fastlane`
4. Install the bundler using `gem install bundler`
5. Go to the `android` & `ios` directory and call `[sudo] bundle install`

To submit a build to the App Store or Google Play Console you need:

**For iOS:**

1. If the `.env.{flavor}` file is not created, create it in the `/ios/fastlane/` folder
2. Go to the Apple Developer portal and create an AppStoreConnect API key, save it, then open the file and copy the contents of that file, not including the `BEGIN PRIVATE KEY` and `END PRIVATE KEY` with dashes. Then add this key in `.env.{flavor}` to the `KEY_CONTENT` variable
3. After creating the key, copy the `ISSUER_ID`, `KEY_ID` variables and add them to `.env.{flavor}`
4. After that, add a few more variables `BUNDLE_ID`, `APPLE_DEVELOPER_USERNAME`, `APP_STORE_CONNECT_TEAM_ID`, `DEVELOPER_PORTAL_TEAM_ID`. You can find them on the Apple Developer portal and AppStore Connect

For more information on creating a AppStore Connect API key go to [Creating API Keys for App Store Connect API](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api)

**For Android:**

1. If the `.env.{flavor}` file is not created, create it in the `/android/fastlane/` folder
2. Download and save the service account key and place it in the project folder
3. Specify the relative path to the service account key by adding the `JSON_KEY_FILE` variable to `.env.{flavor}`
4. Specify the applicationId in the `PACKAGE_NAME` variable to `.env.{flavor}`

For more information on creating a service account key go to [Google Play Developer API](https://developers.google.com/android-publisher/getting_started/?hl=en) portal

To submit a build to the Firebase App Distribution you need:

1. Install Firebase CLI using `curl -sL firebase.tools | bash`
2. Sign in using the Firebase CLI `firebase login`
3. Create the `.env.{flavor}` file in `/android/fastlane/` and `/ios/fastlane/` if it was not created earlier
4. Add the `FIREBASE_APP_ID` variable to the file by specifying the `app_id`, which you can find in the Firebase Console

For more detailed information you can go to [Firebase App Distribution Android](https://firebase.google.com/docs/app-distribution/ios/distribute-fastlane) and [Firebase App Distribution iOS](https://firebase.google.com/docs/app-distribution/android/distribute-fastlane)

Now you can build and distribute the build using the Makefile command:

**For iOS:**

* TestFlight and Firebase App Distribution `make build_{flavor}_ios_with_distribution`
* Firebase App Distribution only `make build_{flavor}_ios_firebase_only`
* TestFlight only `make build_{flavor}_ios_test_flight_only`

> Make sure the correct signing method is selected in Xcode under the "Signing & Capabilities" tab, and if signing manually, the correct Provisioning Profile and Certificate are selected as well

**For Android:**

* Play Store and Firebase App Distribution `make build_{flavor}_android_with_distribution`
* Firebase App Distribution only `make build_{flavor}_android_firebase_only`
* Play Store only `make build_{flavor}_android_store_only`

> Make sure when submitting a build to the Play Store android artifact type is "aab"
> Make sure when submitting a build to the Firebase App Distribution android artifact type is "apk" (if you have not set up firebase integration with your Google Play project)

For more flexible build or distribution settings, you can change the parameters specified in `fastlane_config.yaml`

## Possible build errors

### Some files are underlined red in project file tree:

Try to run `dart pub get` command in IDE terminal

### When you build an iOS or MacOS application you might get Pod's issue.
### When you build an iOS or MacOS application you might get Pod's issue.

To fix that run following command in IDE terminal:

Expand Down
2 changes: 2 additions & 0 deletions assets/fastlane/android/Appfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json_key_file(ENV['JSON_KEY_FILE']) # Relative path to google_service_account.json
package_name(ENV['PACKAGE_NAME']) # The application id of your app
125 changes: 125 additions & 0 deletions assets/fastlane/android/Fastfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
require 'yaml'

YAML_PATH = "../../fastlane_config.yaml" # An important note. Default path to configuration
$yaml_vars = {}
$selected_flavor = ""

default_platform(:android)

platform :android do
desc "Build android app"
lane :build do |options|
flavor = options[:flavor]
firebase = options[:firebase]
store = options[:store]
artifact_type = options[:artifact_type]

load_fastlane_vars(flavor)
path = get_artifact_path(artifact_type, flavor)
#gradle(task: "clean assembleRelease")
upload_to_play_store_if_possible(store, path, artifact_type)
upload_to_firebase_if_possible(firebase, path, artifact_type)
end

def load_fastlane_vars(flavor)
$yaml_vars = YAML.load_file(YAML_PATH)
$selected_flavor = flavor.nil? ? $yaml_vars['default_scheme'] : flavor
end

def get_artifact_path(artifact_type, flavor)
if artifact_type == "apk"
return "../build/app/outputs/flutter-apk/#{flavor.nil? ? 'app-release.apk' : "app-#{flavor}-release.apk"}"
elsif artifact_type == "aab"
return "../build/app/outputs/bundle/#{flavor.nil? ? 'release/app-release.aab' : "#{flavor}Release/app-#{flavor}-release.aab"}"
else
UI.user_error!("You must specify artifact type when calling the fastlane build method. Valid value apk or aab")
return
end
end

def upload_to_play_store_if_possible(distribute, path, artifact_type)
if distribute == nil || !distribute
return
end

if $yaml_vars['schemes'] == nil || $yaml_vars['schemes']['android'] == nil
UI.user_error!("distribute_store is specified, but the configuration is incomplete. Check scheme android #{$selected_flavor}")
return
end

play_store = $yaml_vars['schemes']['android']
play_store_flavor_settings = play_store.find { |scheme| scheme['name'] == $selected_flavor }

if play_store_flavor_settings.nil?
UI.user_error!("distribute_store is specified, but the configuration is incomplete. Check scheme android #{$selected_flavor}")
return
end

play_store_config = {
"release_status" => play_store_flavor_settings['release_status'],
"track" => play_store_flavor_settings['track'],
"rollout" => play_store_flavor_settings['rollout'],
}

if artifact_type == "apk"
UI.user_error!("You cannot submit a build to the Play Store using apk artifact")
end

validate_play_store_json_key json_key:CredentialsManager::AppfileConfig.try_fetch_value(:json_key_file)
upload_to_play_store(
package_name: play_store_config['package_name'],
aab: path,
release_status: play_store_config['release_status'],
track: play_store_config['track'],
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true,
skip_upload_changelogs: true,
skip_upload_apk: true,
)
end

def upload_to_firebase_if_possible(distribute, path, artifact_type)
if distribute == nil || !distribute
return
end

if $yaml_vars['firebase'] == nil || $yaml_vars['firebase']['android'] == nil
UI.user_error!("distribute_to_firebase is specified, but the configuration is incomplete. Check fastlane_config firebase")
return
end

firebase_settings = $yaml_vars['firebase']['android']
firebase_flavor_settings = firebase_settings.find { |scheme| scheme['name'] == $selected_flavor }

if firebase_flavor_settings == nil
UI.user_error!("distribute_to_firebase is specified, but the configuration is incomplete. Check fastlane_config firebase")
return
end

firebase_distribution = {
"app_id" => firebase_flavor_settings['app_id'],
"release_notes_file" => firebase_flavor_settings['release_notes_file'],
"testers" => firebase_flavor_settings['testers'],
"groups" => firebase_flavor_settings['groups'],
"deploy_apk_only" => firebase_flavor_settings['deploy_apk_only'],
}

if ENV['FIREBASE_APP_ID'] == nil
UI.user_error!("Using firebase app distribution you must specify a valid FIREBASE_APP_ID in the '.env.flavor_name' file located in the fastlane directory.")
end

if !firebase_distribution['deploy_apk_only'] || (firebase_distribution['deploy_apk_only'] && artifact_type == "apk")
firebase_app_distribution(
app: ENV['FIREBASE_APP_ID'],
release_notes_file: firebase_distribution['release_notes_file'],
testers: firebase_distribution['testers'],
groups: firebase_distribution['groups'],
android_artifact_path: path,
android_artifact_type: artifact_type.upcase,
)
else
UI.important "firebase_app_distribution was skipped because android artifact type is aab, and distribution is specified only for apk"
end
end
end
6 changes: 6 additions & 0 deletions assets/fastlane/android/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
source "https://rubygems.org"

gem "fastlane"

plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)
5 changes: 5 additions & 0 deletions assets/fastlane/android/Pluginfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Autogenerated by fastlane
#
# Ensure this file is checked in to source control!

gem 'fastlane-plugin-firebase_app_distribution'
4 changes: 4 additions & 0 deletions assets/fastlane/ios/Appfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
app_identifier(ENV['BUNDLE_ID']) # The bundle identifier of your app
apple_id(ENV['APPLE_DEVELOPER_USERNAME']) # Your Apple Developer Portal username
itc_team_id(ENV['APP_STORE_CONNECT_TEAM_ID']) # App Store Connect Team ID
team_id(['DEVELOPER_PORTAL_TEAM_ID']) # Developer Portal Team ID
Loading