-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathFastfile
More file actions
155 lines (124 loc) · 5.24 KB
/
Fastfile
File metadata and controls
155 lines (124 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
opt_out_usage
# Have an easy way to get the root of the project
def root_path
Dir.pwd.sub(/.*\Kfastlane/, '').sub(/.*\Kandroid/, '').sub(/.*\Kios/, '').sub(/.*\K\/\//, '')
end
# Have an easy way to run flutter tasks on the root of the project
lane :sh_on_root do |options|
command = options[:command]
sh("cd #{root_path} && #{command}")
end
# Tasks to be reused on each platform flow
lane :fetch_dependencies do
sh_on_root(command: "flutter pub get --suppress-analytics")
end
# Tasks to be reused on each platform flow
lane :build_autogenerated_code do
sh_on_root(command: "flutter pub run build_runner build --delete-conflicting-outputs")
end
# Tasks to be reused on each platform flow
lane :lint do
sh_on_root(command: "flutter format --suppress-analytics --set-exit-if-changed -n lib/main.dart lib/src/ test/")
end
lane :build_flutter_app do |options|
type = options[:type]
app_identifier_arg = options[:app_identifier]
build_number = options[:build_number] || get_build_number(options[:store], app_identifier_arg)
version_number = options[:version_number] || get_version_from_tag_or_pubspec()
no_codesign = options[:no_codesign] || false
config_only = options[:config_only] || false
commit = last_git_commit
# Determine environment and flavor - default to dev/production, allow override
environment = options[:environment] || 'dev'
flavor = options[:flavor] || 'production'
target = options[:target]
command = "flutter build #{type} --release --no-pub --suppress-analytics"
command += " --flavor #{flavor}" if flavor.to_s != ""
command += " --target #{target}" if target.to_s != ""
command += " --build-number=#{build_number}" if build_number.to_s != ""
command += " --build-name=#{version_number}" if version_number.to_s != ""
command += " --no-codesign" if no_codesign
command += " --config-only" if config_only
UI.message("Building #{type} - version: #{version_number} - build: #{build_number} - commit: #{commit[:abbreviated_commit_hash]} - env: #{environment} - flavor: #{flavor}")
fetch_dependencies
# Check if build_runner exists in pubspec.yaml
# If it does, run the build_runner command
if File.exist?("#{root_path}/pubspec.yaml")
pubspec_content = File.read("#{root_path}/pubspec.yaml")
if pubspec_content.include?("build_runner:")
build_autogenerated_code
end
end
sh_on_root(command: command)
end
# Tasks to be reused on each platform flow
lane :test do |options|
sh_on_root(command: "flutter test --no-pub --coverage --suppress-analytics")
end
# Private lane to verify all environment variables are set
private_lane :verify_env do |options|
# array of ENVS to check
envs = options.fetch(:envs, [])
envs.each do |env|
if ENV[env].nil? || ENV[env].empty?
UI.user_error!("ENV \"#{env}\" is not set. Please set it in your environment variables (e.g. ios/fastlane/.env)")
end
end
end
# A helper method to get the path to the firebase service account json file
def google_service_account_json_path
root_path + '/' + (ENV["GOOGLE_SERVICE_ACCOUNT_JSON_PATH"] || 'google_service_account.json')
end
# A helper method to get the path to the firebase service account json file
def google_firebase_service_account_json_path
root_path + '/' + (ENV["GOOGLE_FIREBASE_SERVICE_ACCOUNT_JSON_PATH"] || 'service_credentials_content.json')
end
# Build number is a unique identifier for each build that is uploaded to the app store.
# This method will get the latest build number from the app store and increment it by 1.
# Ensure authenticate_apple_store is called before this method.
# app_identifier: optional; for appstore use this bundle id (e.g. dev app); for playstore use as package name.
def get_build_number(store, app_identifier = nil)
return get_new_build_number(
bundle_identifier: store == "appstore" ? (app_identifier || ENV["APP_BUNDLE_ID"]) : nil,
package_name: store == "playstore" ? (app_identifier || ENV["APP_PACKAGE_NAME"]) : nil,
google_play_json_key_path: google_service_account_json_path
).to_s
end
def get_version_from_pubspec
require 'yaml'
# Define the correct path to pubspec.yaml relative to the Fastlane directory
pubspec_path = File.expand_path("#{root_path}/pubspec.yaml")
# Check if the file exists to avoid errors
unless File.exist?(pubspec_path)
UI.error("pubspec.yaml file not found at path: #{pubspec_path}")
return nil
end
# Parse the pubspec.yaml file
pubspec_content = File.read(pubspec_path)
# Use regex to find the version number line and extract both version number and build number
version_line = pubspec_content.match(/version:\s*(\d+\.\d+\.\d+)\+(\d+)/)
if version_line
version_number = version_line[1]
else
UI.error("Version number not found in pubspec.yaml")
return nil
end
return version_number
end
def get_version_from_tag_or_pubspec
# Prefer tag version in CI tag-triggered workflows.
raw_tag = ENV["GITHUB_REF_NAME"]
if raw_tag.to_s.empty?
begin
raw_tag = last_git_tag
rescue StandardError
raw_tag = nil
end
end
if raw_tag.to_s != ""
normalized = raw_tag.sub(/\Av/, "").split("-").first
return normalized if normalized.match?(/^\d+\.\d+\.\d+$/)
UI.message("Tag '#{raw_tag}' is not a semantic version. Falling back to pubspec.yaml version.")
end
get_version_from_pubspec
end