-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrelease_builds.sh
executable file
·282 lines (235 loc) · 8.08 KB
/
release_builds.sh
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#!/bin/bash
#! DEFAULTS
#! Change these to your own
#! PASS --use-defaults FLAG, TO USE THESE DEFAULTS
default_num_flavors=2
default_flavors=("dev" "lib/main_dev.dart" "prod" "lib/main_prod.dart")
default_build_types=("apk" "appbundle" "ipa")
# DESCRIPTION
# Automates Flutter project builds with flavor and type options.
# Prerequisites:
# - Flutter installed and configured.
# - Bash shell environment.
# Options:
# --use-defaults: Use default values.
# --no-flavor: Build without flavors.
# Usage:
# - Default: ./build_script.sh
# - Custom: ./build_script.sh --use-defaults
# - No Flavor: ./build_script.sh --no-flavor
# How To Guide:
# - Run the script and follow prompts for custom builds.
# - Number of flavors
# - Flavor name and entry point for each flavor
# - Build types to generate
# - Script creates timestamped build directories.
# Exit on any error, unbound variable, or error in a pipeline
set -euo pipefail
#! +--------------------------+
#! | GLOBAL VARIABLES |
#! +--------------------------+
# Define variables to store states of both flags
use_defaults=false
no_flavor=false
# Define available flags
valid_flags="use-defaults,h,no-flavor"
# Get the current date and time
current_date_time=$(date "+%Y-%m-%d_%H-%M-%S")
#+---------------------------------+
#| Function Declarations |
#+---------------------------------+
#! Function to run flutter commands, ALTER COMMANDS AS NEEDED (project specific)
run_flutter_commands() {
echo "🚀 Cleaning, fetching dependencies, and running build processes..."
flutter clean
flutter pub get
dart pub get
#! Uncomment the following line if you are using build_runner
# dart run build_runner build --delete-conflicting-outputs
}
# Function to display an interactive menu for build types
select_build_types() {
if [[ $use_defaults == true ]]; then
build_types=("${default_build_types[@]}")
return
fi
echo "️ Select the build type(s) you want to generate:"
echo " 1. APK"
echo " 2. AAB (App Bundle)"
echo " 3. IPA"
read -p "Enter your choice (comma-separated numbers): " build_type_choice
# Split the user input into an array of individual choices
IFS=',' read -r -a build_type_choices <<<"$build_type_choice"
build_types=()
# Loop through each choice and validate it
for choice in "${build_type_choices[@]}"; do
case "$choice" in
1) build_types+=("apk") ;;
2) build_types+=("appbundle") ;;
3) build_types+=("ipa") ;;
*) echo "Invalid choice: '$choice'. Ignoring." ;;
esac
done
# Check if any valid choices were selected
if [[ ${#build_types[@]} -eq 0 ]]; then
echo "No valid build types selected. Exiting." && exit 1
fi
}
# Function to build and copy files
build_and_copy_files() {
if [ "$1" == "apk" ]; then
flutter build $1 --flavor $2 -t $3 --split-per-abi
else
flutter build $1 --flavor $2 -t $3
fi
# Create a directory for the build
mkdir -p builds/$current_date_time/[$2-$1]
cp -r $4* builds/$current_date_time/[$2-$1]
echo "✅ Build completed for $2 flavor and type $1"
}
#function to call if no flavor is selected
no_flavor_build(){
select_build_types
run_flutter_commands
# Directly run commands for each build type
for build_type in "${build_types[@]}"; do
case "$build_type" in
"apk")
flutter build apk --split-per-abi
# Create a directory for the build
mkdir -p builds/$current_date_time/[no-flavor-$build_type]
# Copy files for each build type
cp -r build/app/outputs/flutter-apk/* builds/$current_date_time/[no-flavor-$build_type]
;;
"appbundle")
flutter build appbundle
# Create a directory for the build
mkdir -p builds/$current_date_time/[no-flavor-$build_type]
# Copy files over
cp -r build/app/outputs/bundle/* builds/$current_date_time/[no-flavor-$build_type]
;;
"ipa")
flutter build ipa
# Create a directory for the build
mkdir -p builds/$current_date_time/[no-flavor-$build_type]
# Copy files over
cp -r build/ios/ipa/* builds/$current_date_time/[no-flavor-$build_type]
;;
esac
# Create a directory for the build
mkdir -p builds/$current_date_time/[no-flavor-$build_type]
# Copy files for each build type
case "$build_type" in
"apk")
cp -r build/app/outputs/flutter-apk/* builds/$current_date_time/[no-flavor-$build_type]
;;
"appbundle")
cp -r build/app/outputs/bundle/* builds/$current_date_time/[no-flavor-$build_type]
;;
"ipa")
cp -r build/ios/ipa/* builds/$current_date_time/[no-flavor-$build_type]
;;
esac
done
echo "🎉 All builds completed successfully!, you can find all the builds in /builds folder"
open builds/$current_date_time
exit 0
}
#+-------------------------+
#| Process flags |
#+-------------------------+
# Process options using getopts
while getopts ":h-:" opt; do
case $opt in
-)
case $OPTARG in
use-defaults)
use_defaults=true
;;
h)
echo "Usage: $0 [--$valid_flags]"
exit 0
;;
no-flavor)
no_flavor=true
;;
*)
echo "Invalid option: --$OPTARG" >&2
echo "Available options: $valid_flags" >&2
exit 1
;;
esac
;;
h)
echo "Usage: $0 [--$valid_flags]"
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
echo "Available options: $valid_flags" >&2
exit 1
;;
esac
done
# Check if the no-flavor flag is set
if [[ $no_flavor == true ]]; then
no_flavor_build
fi
#+-------------------------+
#| Get arguments |
#+-------------------------+
# Check if the flag is set and take appropriate action
if [[ $use_defaults == true ]]; then
num_flavors=$default_num_flavors
flavors=("${default_flavors[@]}")
select_build_types
else
# if no-flavor, then skip this step
if [[ $no_flavor == false ]]; then
read -p "🤔 Number of flavors? " num_flavors
#if flavor is 0, then call
if [[ $num_flavors -eq 0 ]]; then
no_flavor_build
fi
# Array to store flavor information
declare -a flavors
# Prompt the user for flavor information
for ((i = 1; i <= num_flavors; i++)); do
read -p "🍦 Flavor $i name: " flavor_name
read -p "📄 Entry point location of flavor $i (eg. lib/main_dev.dart): " main_dart_location
#check if the file exists
#if it does not exist, then ask again
while [[ ! -f $main_dart_location ]]; do
echo "🚫 File $main_dart_location does not exist, try again"
read -p "📄 Entry point location of flavor $i (eg. lib/main_dev.dart): " main_dart_location
done
# Add flavor information to the array
flavors+=("$flavor_name" "$main_dart_location")
done
select_build_types
fi
fi
run_flutter_commands
# Build and copy files for each flavor
for ((i = 0; i < ${#flavors[@]}; i += 2)); do
flavor_name=${flavors[i]}
main_dart_location=${flavors[i + 1]}
# Build and copy files for each build type
for build_type in "${build_types[@]}"; do
case "$build_type" in
"apk")
output_directory="build/app/outputs/flutter-apk/"
;;
"appbundle")
output_directory="build/app/outputs/bundle/"
;;
"ipa")
output_directory="build/ios/ipa/"
;;
esac
# Build and copy files for the flavor and build type
build_and_copy_files $build_type $flavor_name $main_dart_location $output_directory
done
done
open builds/$current_date_time
echo "🎉 All builds completed successfully!, you can find all the builds in /builds folder"