├── .gitignore ├── LICENSE ├── README.md ├── defold-deployer.png ├── deployer.sh └── settings_deployer.template /.gitignore: -------------------------------------------------------------------------------- 1 | settings_deployer -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Maxim Tuprikov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](defold-deployer.png) 2 | 3 | [![GitHub release (latest by date)](https://img.shields.io/github/v/release/insality/defold-deployer?style=for-the-badge)](https://github.com/Insality/defold-deployer/releases) 4 | 5 | # Defold Deployer 6 | Universal build && deploy script for *Defold* projects (Android, iOS, HTML5, Linux, MacOS, Windows) 7 | **Deployer** is configurable via settings_deployer file. It's allow use single deployer script for different projects 8 | 9 | ## Features 10 | - Single deployment script on all Defold projects (Android, iOS, HTML5, Linux, MacOS, Windows) 11 | - One command to build, deploy and read logs from the mobile 12 | - Global and custom settings on project (provisions, bob version, etc) 13 | - Useful build output 14 | - Save your time on preparing debug && release builds 15 | - Nice naming builds to save history of product versions 16 | - Auto *bob.jar* downloading. Flag **use_latest_bob** for using always last version of *Defold* 17 | - Select Bob channel (stable/beta/alpha) and Defold build server via settings file 18 | - Headless build && run for your unit-tests on CI _[here example](https://github.com/Insality/druid/blob/develop/.github/workflows/ci-workflow.yml#L20)_ 19 | - Add additional info to *game.project*: *project.commit_sha* and *project.build time* 20 | - Android Instant build in one command (`deployer abr --instant`) 21 | - Redownload dependencies, if they are corrupted 22 | - [Optional] Build stats history with build size, build time and other info 23 | - [Optional] Local build cache and separate build folder to prevent cache reset 24 | - [Optional] Use incremental value for last number in version and android.version_code (enable via _enable incremental version_, _enable_incremental_android_version_code_) 25 | - [Optional] Pre and post build hooks 26 | 27 | ## Install 28 | For bob build tool you need to install java JDK: https://openjdk.java.net/projects/jdk/11/ 29 | 30 | For ios deploy by cable you need to install: 31 | - *ios-deploy*: https://github.com/ios-control/ios-deploy 32 | 33 | For android deploy and read logs you need to install: 34 | - *adb*: https://developer.android.com/studio/releases/platform-tools 35 | 36 | For running `bob.jar` you need to install: 37 | - *java*: https://openjdk.java.net/projects/jdk/11/ 38 | 39 | For HTML5 builds you need to install: 40 | - Deployer use `zip` command to pack HTML5 build into zip file 41 | - Deployer use `python 2` to run HTTP Server for deploy 42 | 43 | For building Android Instant you need to make prepare: 44 | - *Insctructions*: [https://forum.defold.com/t/instruction-android-instant-app-creation/48471](https://forum.defold.com/t/instruction-android-instant-app-creation/48471) 45 | - Deployer use `zip` command to prepare bundle for _Google Play_ 46 | 47 | 48 | ## Setup 49 | Run `deployer.sh` inside your `game.project` folder. 50 | 51 | To create your settings file, just copy `setting_deployer.template` with name `settings_deployer` and place it in right place: 52 | 53 | - **Global settings** - `settings_deployer` file nearby `deployer.sh` script 54 | - **Custom project settings** - `settings_deployer` file nearby `game.project` file 55 | 56 | Custom projects settings will override your global settings 57 | 58 | #### Recommendation 59 | Make link to `deployer.sh` file in your system path with name `deployer` (via `ln -s deployer.sh deployer`) 60 | 61 | Add execution mode to it via `chmod +x` 62 | 63 | Place your **global settings** file nearby new `deployer` file link 64 | 65 | Call it in your project folder like: `deployer abd` 66 | 67 | 68 | ## Usage 69 | `bash deployer.sh [a][i][h][w][l][m][r][b][d] [--fast] [--resolve] [--instant] [--settings {filename}] [--headless]` 70 | - `a` - add target platform Android 71 | - `i` - add target platform iOS 72 | - `h` - add target platform HTML5 73 | - `w` - add target platform Windows 74 | - `l`- add target platform Linux 75 | - `m` - add target platform MacOS 76 | - `r` - set build mode to Release 77 | - `b` - build project (game bundle will be in ./dist/bundle/ folder) 78 | - `d` - deploy bundle && run to connected device. Auto start logging from connected device 79 | - `--settings {filename}` - add settings file to build params. Can be used several times 80 | - `--fast` - build only one Android platform (for faster builds) 81 | - `--headless` - set mode to headless. Override release mode 82 | - `--resolve` - build with dependency resolve 83 | - `--instant` - it preparing bundle for Android Instant Apps. Always in release mode 84 | 85 | Bundle files will be located at *./dist/bundle/{Version}/* 86 | 87 | If no version found in `game.project`, it will be *0.0.0* as default 88 | 89 | Deployer need to run on root of your Defold project 90 | 91 | Filename will be name {ProjectName}\_{Version}\_{BuildMode}.[apk|ipa] 92 | 93 | ## Examples 94 | ```bash 95 | # Build, deploy and run Android bundle 96 | deployer.sh abd 97 | # Deploy and run iOS release bundle 98 | deployer.sh ird 99 | # Build Android and iOS release bundles 100 | deployer.sh aibr 101 | # Build and run HTML5 debug build 102 | deployer.sh hdb 103 | # Build and preparing Android Instant Apps bundle 104 | deployer.sh ab --instant 105 | # Build, deploy and run Android bundle in fast mode (useful for testing) 106 | deployer.sh abd --fast 107 | # You can pass params in any order you want, for example: 108 | # Same behaviour as aibr 109 | deployer.sh riba 110 | # Build MacOS debug build and run it 111 | deployer.sh mbd 112 | # Build linux headless build with unit_test.txt settings and run it 113 | deployer.sh lbd --settings unit_test.txt --headless 114 | # Build Windows release build 115 | deployer.sh wbr 116 | ``` 117 | 118 | ## Deployer parameters 119 | - **Global settings** setup by `settings_deployer` file nearby with deployer script 120 | - **Custom project settings** setup by `settings_deployer` file nearby your `game.project` file on root of your project: 121 | 122 | Copy `settings_deployer.template` with name `settings_deployer` and change it for your needs 123 | 124 | Deployer parameters: 125 | ```bash 126 | # Path to bob folder. It will find and save new bob.jar files inside 127 | bob_folder={path_to_bob_folder} 128 | 129 | # Path to android keystore for debug 130 | android_keystore_dev={path_to_keystore.jks} 131 | 132 | # Path to android keystore for release 133 | android_keystore_dist={path_to_keystore.jks} 134 | 135 | # Path to android keystore password for debug. This file should contains keystore password 136 | android_keystore_password_dev="{path_to_keystore_password.txt}" 137 | 138 | # Path to android keystore password for release. This file should contains keystore password 139 | android_keystore_password_dist="{path_to_keystore_password.txt}" 140 | 141 | # Name of alias from provided keystore to use for android development build 142 | android_keystore_alias_dev="keystore_alias" 143 | 144 | # Name of alias from provided keystore to use for android release build 145 | android_keystore_alias_dist="keystore_alias" 146 | 147 | # ID of your ios development identity 148 | ios_identity_dev="AAXBBYY" 149 | 150 | # ID of your iod distribution identity 151 | ios_identity_dist="YYBBXXAA" 152 | 153 | # Path to ios development mobileprovision 154 | ios_prov_dev={path_to_ios_dev.mobileprovision} 155 | 156 | # Path to ios distribution mobileprovision 157 | ios_prov_dist={path_to_ios_dist.mobileprovision} 158 | 159 | # You can point bob version for project in format "filename:sha" 160 | bob_sha="184:1f5712609c345f870b691a85d611d4825d22a718" 161 | 162 | # Select Defold channel. Values: stable, beta, alpha 163 | bob_channel="stable" 164 | 165 | # If true, it will check and download latest bob version. It will ignore bob_sha param 166 | use_latest_bob=false 167 | 168 | # Select Defold build server 169 | build_server="https://build.defold.com" 170 | 171 | # Pre-build hook bash script path. The path relative from game project folder 172 | pre_build_script=false 173 | 174 | # Post-build hook bash script path. The path relative from game project folder 175 | post_build_script=false 176 | 177 | # Set patch (last value after dot) game version value as total git commits count (1.2.0 -> 1.2.{commits_count}) 178 | # You allow to get SHA commit from version via: git rev-list --all --reverse | sed -n {N}p 179 | enable_incremental_version=false 180 | 181 | # Use git commits count as android.version_code on build 182 | enable_incremental_android_version_code=false 183 | 184 | # Local resource cache folder for deployer script. This folder will be added to gitignore if exists 185 | resource_cache_local=".cache_deployer" 186 | 187 | # If true, add `-l yes` build param for publish live content 188 | is_live_content=false 189 | 190 | # Set to true, if you do not need to strip executables 191 | no_strip_executable=false 192 | 193 | # Is need to build html report 194 | is_build_html_report=false 195 | 196 | # Enable to start record build stats of every deployer build in csv format 197 | build_stats_report_file="./deployer_build_stats.csv" 198 | 199 | # Android instant app settings.ini path to override 200 | # (Usually, you need it to override AndroidManifest.xml) 201 | # See instruction here: https://forum.defold.com/t/instruction-android-instant-app-creation/48471 202 | android_instant_app_settings={path_to_android_settings_ini} 203 | 204 | # SDK path to build Android Instant app 205 | sdk_path={path_to_android_sdk} 206 | 207 | # Path to android signature key for release (Since Defold 174 only using for Android Instant games) 208 | android_key_dist={path_to_key.pk8} 209 | 210 | # Path to android signature certificate for release (Since Defold 174 only using for Android Instant games) 211 | android_cer_dist={path_to_certificate.pem} 212 | ``` 213 | 214 | ## Author 215 | Maxim Tuprikov, [Insality](http://github.com/Insality) 216 | **MIT** License 217 | 218 | 219 | ## Issues and suggestions 220 | 221 | If you have any issues, questions or suggestions please [create an issue](https://github.com/Insality/druid/issues) or contact me: [insality@gmail.com](mailto:insality@gmail.com) 222 | 223 | -------------------------------------------------------------------------------- /defold-deployer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Insality/defold-deployer/4442f97dbeb12e9e140f641dcd6673004b578722/defold-deployer.png -------------------------------------------------------------------------------- /deployer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### Author: Insality , 04.2019 3 | ## (c) Insality Games 4 | ## 5 | ## Universal build && deploy script for Defold projects (Android, iOS, HTML5, Linux, MacOS, Windows) 6 | ## Deployer has own settings, described in separate file settings_deployer 7 | ## See full deployer settings here: https://github.com/Insality/defold-deployer/blob/master/settings_deployer.template 8 | ## 9 | ## Install: 10 | ## See full instructions here: https://github.com/Insality/defold-deployer/blob/master/README.md 11 | ## 12 | ## Usage: 13 | ## bash deployer.sh [a][i][h][w][l][m][r][b][d] [--fast] [--no-resolve] [--instant] [--settings {filename}] [--headless] [--param {x}] 14 | ## a - add target platform Android 15 | ## i - add target platform iOS 16 | ## h - add target platform HTML5 17 | ## w - add target platform Windows 18 | ## l - add target platform Linux 19 | ## m - add target platform MacOS 20 | ## r - set build mode to Release 21 | ## b - build project (game bundle will be in ./dist folder) 22 | ## d - deploy bundle to connected device 23 | ## it will deploy && run bundle on Android/iOS with reading logs to terminal 24 | ## --fast - only one Android platform, without resolve (for faster builds) 25 | ## --no-resolve - build without dependency resolve 26 | ## --headless - set mode to headless. Override release mode 27 | ## --settings {filename} - add settings file to build params. Can be used several times 28 | ## --param {x} - add flag {x} to bob.jar. Can be used several times 29 | ## --instant - it preparing bundle for Android Instant Apps. Always in release mode 30 | ## 31 | ## Example: 32 | ## ./deployer.sh abd - build, deploy and run Android bundle 33 | ## ./deployer.sh ibdr - build, deploy and run iOS release bundle 34 | ## ./deployer.sh aibr - build Android and iOS release bundles 35 | ## ./deployer.sh mbd - build MacOS debug build and run it 36 | ## ./deployer.sh lbd --settings unit_test.txt --headless Build linux headless build with unit_test.txt settings and run it 37 | ## ./deployer.sh wbr - build Windows release build 38 | ## ./deployer.sh ab --instant - build Android release build for Android Instant Apps 39 | ## 40 | ## You can pass params in any order you want, for example: 41 | ## ./deployer.sh riba - same behaviour as aibr 42 | ## 43 | ## MIT License 44 | ### 45 | 46 | ### Exit on Cmd+C / Ctrl+C 47 | trap "exit" INT 48 | trap clean EXIT 49 | set -e 50 | 51 | if [ ! -f ./game.project ]; then 52 | echo -e "\x1B[31m[ERROR]: ./game.project not exist\x1B[0m" 53 | exit 54 | fi 55 | 56 | ### Export values 57 | # DEPLOYER_ARTIFACT_PATH - path to build artifact (for example, .app file) 58 | 59 | ### Default variables 60 | use_latest_bob=false 61 | is_live_content=false 62 | pre_build_script=false 63 | post_build_script=false 64 | no_strip_executable=false 65 | is_build_html_report=false 66 | enable_incremental_version=false 67 | enable_incremental_android_version_code=false 68 | 69 | ### Settings loading 70 | settings_filename="settings_deployer" 71 | script_path="`dirname \"$0\"`" 72 | is_settings_exist=false 73 | 74 | if [ -f ${script_path}/${settings_filename} ]; then 75 | is_settings_exist=true 76 | echo -e "Using default deployer settings from \x1B[33m${script_path}/${settings_filename}\x1B[0m" 77 | source ${script_path}/${settings_filename} 78 | fi 79 | 80 | if [ -f ./${settings_filename} ]; then 81 | is_settings_exist=true 82 | echo -e "Using custom deployer settings from \x1B[33m${PWD}/${settings_filename}\x1B[0m" 83 | source ./${settings_filename} 84 | fi 85 | 86 | if ! $is_settings_exist ; then 87 | echo -e "\x1B[31m[ERROR]: No deployer settings file founded\x1B[0m" 88 | echo "Place your default deployer settings at ${script_path}/" 89 | echo "Place your project settings at root of your game project (./)" 90 | echo "File name should be '${settings_filename}'" 91 | echo "See settings template here: https://github.com/Insality/defold-deployer" 92 | exit 93 | fi 94 | 95 | 96 | ### Constants 97 | build_date=`date -u +"%Y-%m-%dT%H:%M:%SZ"` 98 | android_platform="armv7-android" 99 | ios_platform="arm64-ios" 100 | html_platform="js-web" 101 | linux_platform="x86_64-linux" 102 | windows_platform="x86_64-win32" 103 | macos_platform="x86_64-macos" 104 | version_settings_filename="deployer_version_settings.txt" 105 | build_output_folder="./build/default_deployer" 106 | dist_folder="./dist" 107 | bundle_folder="${dist_folder}/bundle" 108 | commit_sha="unknown" 109 | commits_count=0 110 | is_git=false 111 | is_cache_using=false 112 | 113 | if [ -d .git ]; then 114 | commit_sha=`git rev-parse --verify HEAD` 115 | commits_count=`git rev-list --all --count` 116 | is_git=true 117 | fi 118 | 119 | 120 | ### Runtime 121 | is_build_success=false 122 | is_build_started=false 123 | build_time=false 124 | 125 | ### Game project settings for deployer script 126 | title=$(less game.project | grep "^title = " | cut -d "=" -f2 | sed -e 's/^[[:space:]]*//') 127 | version=$(less game.project | grep "^version = " | cut -d "=" -f2 | sed -e 's/^[[:space:]]*//') 128 | version=${version:='0.0.0'} 129 | title_no_space=$(echo -e "${title}" | tr -d '[[:space:]]') 130 | title_no_space=$(echo -e "${title_no_space}" | tr -d '[\-]') 131 | bundle_id=$(less game.project | grep "^package = " | cut -d "=" -f2 | sed -e 's/^[[:space:]]*//') 132 | 133 | ### Override last version number with commits count 134 | if $enable_incremental_version; then 135 | version="${version%.*}.$commits_count" 136 | fi 137 | 138 | file_prefix_name="${title_no_space}_${version}" 139 | version_folder="${bundle_folder}/${version}" 140 | echo -e "\nProject: \x1B[36m${title} v${version}\x1B[0m" 141 | echo -e "Commit SHA: \x1B[35m${commit_sha}\x1B[0m" 142 | echo -e "Commits amount: \x1B[33m${commits_count}\x1B[0m" 143 | 144 | ### Bob select 145 | bob_version="$(cut -d ":" -f1 <<< "$bob_sha")" 146 | bob_sha="$(cut -d ":" -f2 <<< "$bob_sha")" 147 | bob_channel="${bob_channel:-"stable"}" 148 | 149 | if $use_latest_bob; then 150 | INFO=$(curl -s http://d.defold.com/${bob_channel}/info.json) 151 | echo "Using latest bob: ${INFO}" 152 | bob_sha=$(sed 's/.*sha1": "\(.*\)".*/\1/' <<< $INFO) 153 | bob_version=$(sed 's/[^0-9.]*\([0-9.]*\).*/\1/' <<< $INFO) 154 | bob_version="$(cut -d "." -f3 <<< "$bob_version")" 155 | fi 156 | 157 | echo -e "Using Bob version \x1B[35m${bob_version}\x1B[0m SHA: \x1B[35m${bob_sha}\x1B[0m" 158 | 159 | bob_path="${bob_folder}bob${bob_version}.jar" 160 | download_bob() { 161 | if [ ! -f ${bob_path} ]; then 162 | BOB_URL="https://d.defold.com/archive/${bob_channel}/${bob_sha}/bob/bob.jar" 163 | echo "Unable to find bob${bob_version}.jar. Downloading it from d.defold.com: ${BOB_URL}}" 164 | echo "curl -L -o ${bob_path} ${BOB_URL}" 165 | curl -L -o ${bob_path} ${BOB_URL} 166 | fi 167 | } 168 | download_bob 169 | 170 | real_bob_sha=$(java -jar ${bob_path} --version | cut -d ":" -f3 | cut -d " " -f2) 171 | if [ ! ${real_bob_sha} == ${bob_sha} ]; then 172 | echo "Bob SHA mismatch (file bob SHA and settings bob SHA). Redownloading..." 173 | rm ${bob_path} 174 | download_bob 175 | fi 176 | 177 | 178 | try_fix_libraries() { 179 | echo "Possibly, libs was corrupted (script interrupted while resolving libraries)" 180 | echo "Trying to delete and redownload it (./.internal/lib/)" 181 | rm -r ./.internal/lib/ 182 | java -jar ${bob_path} --email foo@bar.com --auth 12345 resolve 183 | } 184 | 185 | 186 | add_to_gitignore() { 187 | if [ ! $is_git ]; then 188 | return 0 189 | fi 190 | 191 | if [ ! -f ./.gitignore ]; then 192 | touch .gitignore 193 | echo -e "\Create .gitignore file" 194 | fi 195 | 196 | if ! grep -Fxq "$1" .gitignore; then 197 | echo "Add $1 to .gitignore" 198 | echo -e "\n$1" >> .gitignore 199 | fi 200 | } 201 | 202 | 203 | write_report() { 204 | if [ -z "$build_stats_report_file" ]; then 205 | return 0 206 | fi 207 | 208 | if [ ! -f $build_stats_report_file ]; then 209 | touch $build_stats_report_file 210 | echo -e "Create build report file: $build_stats_report_file" 211 | 212 | echo "date,sha,version,build_size,build_time,platform,mode,is_cache_using,commits_count" >> $build_stats_report_file 213 | fi 214 | 215 | platform=$1 216 | mode=$2 217 | target_path=$3 218 | build_size=$(du -sh -k ${target_path} | cut -f1) 219 | echo "$build_date,$commit_sha,$version,$build_size,$build_time,$platform,$mode,$is_cache_using,$commits_count" >> $build_stats_report_file 220 | } 221 | 222 | 223 | resolve_bob() { 224 | echo "Resolving libraries..." 225 | java -jar ${bob_path} --email foo@bar.com --auth 12345 resolve || try_fix_libraries 226 | echo "" 227 | } 228 | 229 | 230 | bob() { 231 | mode=$1 232 | java --version 233 | java -jar ${bob_path} --version 234 | 235 | args="-jar ${bob_path} --archive --output ${build_output_folder} --bundle-output ${dist_folder} --variant $@" 236 | 237 | if ! $no_strip_executable; then 238 | args+=" --strip-executable" 239 | fi 240 | 241 | if [ ${mode} == "debug" ]; then 242 | echo -e "\nBuild without distclean and compression. Debug mode" 243 | args+=" build bundle" 244 | fi 245 | 246 | if [ ${mode} == "release" ]; then 247 | echo -e "\nBuild with distclean and compression. Release mode" 248 | args+=" --texture-compression true build bundle distclean" 249 | fi 250 | 251 | if [ ${mode} == "headless" ]; then 252 | echo -e "\nBuild with distclean and without compression. Headless mode" 253 | args+=" build bundle distclean" 254 | fi 255 | 256 | start_build_time=`date +%s` 257 | 258 | echo -e "Build command: java ${args}" 259 | java ${args} 260 | 261 | build_time=$((`date +%s`-start_build_time)) 262 | echo -e "Build time: $build_time seconds\n" 263 | } 264 | 265 | 266 | build() { 267 | if [ -f ./${pre_build_script} ]; then 268 | echo "Run pre-build script: $pre_build_script" 269 | source ./$pre_build_script 270 | fi 271 | 272 | mkdir -p ${version_folder} 273 | 274 | platform=$1 275 | mode=$2 276 | additional_params="${build_params} ${settings_params} $3" 277 | is_build_success=false 278 | is_build_started=true 279 | 280 | if [ ${mode} == "release" ]; then 281 | ident=${ios_identity_dist} 282 | prov=${ios_prov_dist} 283 | android_keystore=${android_keystore_dist} 284 | android_keystore_password=${android_keystore_password_dist} 285 | android_keystore_alias=${android_keystore_alias_dist} 286 | echo -e "\x1B[32mBuild in Release mode\x1B[0m" 287 | fi 288 | if [ ${mode} == "debug" ]; then 289 | ident=${ios_identity_dev} 290 | prov=${ios_prov_dev} 291 | android_keystore=${android_keystore_dev} 292 | android_keystore_password=${android_keystore_password_dev} 293 | android_keystore_alias=${android_keystore_alias_dev} 294 | echo -e "\x1B[31mBuild in Debug mode\x1B[0m" 295 | fi 296 | if [ ${mode} == "headless" ]; then 297 | ident=${ios_identity_dev} 298 | prov=${ios_prov_dev} 299 | android_keystore=${android_keystore_dev} 300 | android_keystore_password=${android_keystore_password_dev} 301 | android_keystore_alias=${android_keystore_alias_dev} 302 | echo -e "\x1B[34mBuild in Headless mode\x1B[0m" 303 | fi 304 | 305 | if $is_resolve; then 306 | resolve_bob 307 | fi 308 | 309 | if [ ! -z "$exclude_folders" ]; then 310 | additional_params=" --exclude-build-folder $exclude_folders $additional_params" 311 | fi 312 | 313 | if [ ! -z "$resource_cache_local" ]; then 314 | echo "Use resource local cache for bob builder: $resource_cache_local" 315 | additional_params=" --resource-cache-local $resource_cache_local $additional_params" 316 | is_cache_using=true 317 | add_to_gitignore $resource_cache_local 318 | fi 319 | 320 | filename="${file_prefix_name}_${mode}" 321 | target_path=false 322 | 323 | # Android platform 324 | if [ ${platform} == ${android_platform} ]; then 325 | line="${dist_folder}/${title}/${title}" 326 | 327 | if $is_fast_debug; then 328 | echo "Build only one platform for faster build" 329 | additional_params=" -ar armv7-android $additional_params" 330 | fi 331 | 332 | if $is_live_content; then 333 | echo "Add publishing live content to build" 334 | additional_params=" -l yes $additional_params" 335 | fi 336 | 337 | if [ ! -z "$android_keystore_alias" ]; then 338 | additional_params=" --keystore-alias $android_keystore_alias $additional_params" 339 | fi 340 | 341 | if $is_build_html_report; then 342 | additional_params=" -brhtml ${version_folder}/${filename}_android_report.html $additional_params" 343 | fi 344 | 345 | if [ ! -z "$settings_android" ]; then 346 | additional_params="$additional_params --settings $settings_android" 347 | fi 348 | 349 | bob ${mode} --platform ${platform} --bundle-format apk,aab --keystore ${android_keystore} \ 350 | --keystore-pass ${android_keystore_password} \ 351 | --build-server ${build_server} ${additional_params} 352 | 353 | target_path="${version_folder}/${filename}.apk" 354 | mv "${line}.apk" ${target_path} && is_build_success=true 355 | 356 | export DEPLOYER_ARTIFACT_PATH="${target_path}" 357 | 358 | target_path="${version_folder}/${filename}.aab" 359 | mv "${line}.aab" ${target_path} && is_build_success=true 360 | fi 361 | 362 | # iOS platform 363 | if [ ${platform} == ${ios_platform} ]; then 364 | line="${dist_folder}/${title}" 365 | 366 | if $is_build_html_report; then 367 | additional_params=" -brhtml ${version_folder}/${filename}_ios_report.html $additional_params" 368 | fi 369 | 370 | if [ ! -z "$settings_ios" ]; then 371 | additional_params="$additional_params --settings $settings_ios" 372 | fi 373 | 374 | bob ${mode} --platform ${platform} --architectures arm64-ios --identity ${ident} --mobileprovisioning ${prov} \ 375 | --build-server ${build_server} ${additional_params} 376 | 377 | target_path="${version_folder}/${filename}.ipa" 378 | 379 | rm -rf "${version_folder}/${filename}.app" 380 | mv "${line}.app" "${version_folder}/${filename}.app" 381 | mv "${line}.ipa" ${target_path} && is_build_success=true 382 | 383 | export DEPLOYER_ARTIFACT_PATH="${target_path}" 384 | fi 385 | 386 | # HTML5 platform 387 | if [ ${platform} == ${html_platform} ]; then 388 | line="${dist_folder}/${title}" 389 | 390 | if $is_build_html_report; then 391 | additional_params=" -brhtml ${version_folder}/${filename}_html_report.html $additional_params" 392 | fi 393 | 394 | if [ ! -z "$settings_html" ]; then 395 | additional_params="$additional_params --settings $settings_html" 396 | fi 397 | 398 | echo "Start build HTML5 ${mode}" 399 | bob ${mode} --platform ${platform} --architectures js-web ${additional_params} 400 | 401 | target_path="${version_folder}/${filename}_html.zip" 402 | 403 | rm -rf "${version_folder}/${filename}_html" 404 | rm -f "${target_path}" 405 | mv "${line}" "${version_folder}/${filename}_html" 406 | 407 | previous_folder=`pwd` 408 | cd "${version_folder}" 409 | zip "${filename}_html.zip" -r "${filename}_html" && is_build_success=true 410 | cd "${previous_folder}" 411 | 412 | export DEPLOYER_ARTIFACT_PATH="${target_path}" 413 | fi 414 | 415 | # Linux platform 416 | if [ ${platform} == ${linux_platform} ]; then 417 | line="${dist_folder}/${title}" 418 | 419 | if $is_build_html_report; then 420 | additional_params=" -brhtml ${version_folder}/${filename}_linux_report.html $additional_params" 421 | fi 422 | 423 | if [ ! -z "$settings_linux" ]; then 424 | additional_params="$additional_params --settings $settings_linux" 425 | fi 426 | 427 | echo "Start build Linux ${mode}" 428 | bob ${mode} --platform ${platform} ${additional_params} 429 | 430 | target_path="${version_folder}/${filename}_linux" 431 | 432 | rm -rf ${target_path} 433 | mv "${line}" ${target_path} && is_build_success=true 434 | 435 | export DEPLOYER_ARTIFACT_PATH="${target_path}" 436 | fi 437 | 438 | # MacOS platform 439 | if [ ${platform} == ${macos_platform} ]; then 440 | line="${dist_folder}/${title}.app" 441 | 442 | if $is_build_html_report; then 443 | additional_params=" -brhtml ${version_folder}/${filename}_macos_report.html $additional_params" 444 | fi 445 | 446 | if [ ! -z "$settings_macos" ]; then 447 | additional_params="$additional_params --settings $settings_macos" 448 | fi 449 | 450 | echo "Start build MacOS ${mode}" 451 | bob ${mode} --platform ${platform} ${additional_params} 452 | 453 | target_path="${version_folder}/${filename}_macos.app" 454 | 455 | rm -rf ${target_path} 456 | mv "${line}" ${target_path} && is_build_success=true 457 | 458 | export DEPLOYER_ARTIFACT_PATH="${target_path}" 459 | fi 460 | 461 | # Windows platform 462 | if [ ${platform} == ${windows_platform} ]; then 463 | line="${dist_folder}/${title}" 464 | 465 | if $is_build_html_report; then 466 | additional_params=" -brhtml ${version_folder}/${filename}_windows_report.html $additional_params" 467 | fi 468 | 469 | if [ ! -z "$settings_windows" ]; then 470 | additional_params="$additional_params --settings $settings_windows" 471 | fi 472 | 473 | echo "Start build Windows ${mode}" 474 | bob ${mode} --platform ${platform} ${additional_params} 475 | 476 | target_path="${version_folder}/${filename}_windows" 477 | 478 | rm -rf ${target_path} 479 | mv "${line}" ${target_path} && is_build_success=true 480 | 481 | export DEPLOYER_ARTIFACT_PATH="${target_path}" 482 | fi 483 | 484 | if $is_build_success; then 485 | echo -e "\x1B[32mSave bundle at ${version_folder}/${filename}\x1B[0m" 486 | if [ -f ./${post_build_script} ]; then 487 | echo "Run post-build script: $post_build_script" 488 | source ./$post_build_script 489 | fi 490 | 491 | write_report ${platform} ${mode} ${target_path} 492 | else 493 | echo -e "\x1B[31mError during building...\x1B[0m" 494 | fi 495 | } 496 | 497 | 498 | make_instant() { 499 | mode=$1 500 | echo -e "\nPreparing APK for Android Instant game" 501 | filename="${version_folder}/${file_prefix_name}_${mode}.apk" 502 | filename_instant="${version_folder}/${file_prefix_name}_${mode}_align.apk" 503 | filename_instant_zip="${version_folder}/${file_prefix_name}_${mode}.apk.zip" 504 | ${sdk_path}/zipalign -f 4 ${filename} ${filename_instant} 505 | ${sdk_path}/apksigner sign --key ${android_key_dist} --cert ${android_cer_dist} ${filename_instant} 506 | zip -j ${filename_instant_zip} ${filename_instant} 507 | rm ${filename} 508 | rm ${filename_instant} 509 | echo -e "\x1B[32mZip file for Android instant ready: ${filename_instant_zip}\x1B[0m" 510 | } 511 | 512 | 513 | deploy() { 514 | platform=$1 515 | mode=$2 516 | clean_build_settings 517 | 518 | if [ ${platform} == ${android_platform} ]; then 519 | filename="${version_folder}/${file_prefix_name}_${mode}.apk" 520 | echo "Deploy to Android from ${filename}" 521 | adb install -r -d "${filename}" 522 | fi 523 | 524 | if [ ${platform} == ${ios_platform} ]; then 525 | filename="${version_folder}/${file_prefix_name}_${mode}.ipa" 526 | echo "Deploy to iOS from ${filename}" 527 | echo "Deploy command: ios-deploy --bundle ${filename} --bundle_id ${bundle_id}" 528 | ios-deploy --bundle "${filename}" --bundle_id "${bundle_id}" 529 | fi 530 | 531 | if [ ${platform} == ${html_platform} ]; then 532 | filename="${version_folder}/${file_prefix_name}_${mode}_html/" 533 | echo "Start python server and open in browser ${filename:1}" 534 | 535 | open "http://localhost:8000${filename:1}" 536 | python3 --version 537 | python3 -m "http.server" 538 | fi 539 | } 540 | 541 | 542 | run() { 543 | platform=$1 544 | mode=$2 545 | clean_build_settings 546 | 547 | if [ ${platform} == ${android_platform} ]; then 548 | adb shell am start -n ${bundle_id}/com.dynamo.android.DefoldActivity 549 | adb logcat -s defold 550 | fi 551 | 552 | if [ ${platform} == ${ios_platform} ]; then 553 | filename_app="${version_folder}/${file_prefix_name}_${mode}.app" 554 | ios-deploy -I -m -b ${filename_app} | grep ${title_no_space} 555 | fi 556 | 557 | if [ ${platform} == ${linux_platform} ]; then 558 | filename="${version_folder}/${file_prefix_name}_${mode}_linux/${title_no_space}.x86_64" 559 | 560 | echo "Start Linux build: $filename" 561 | ./$filename 562 | fi 563 | 564 | if [ ${platform} == ${macos_platform} ]; then 565 | filename="${version_folder}/${file_prefix_name}_${mode}_macos.app" 566 | 567 | echo "Start MacOS build: $filename" 568 | open $filename 569 | fi 570 | 571 | if [ ${platform} == ${windows_platform} ]; then 572 | filename="${version_folder}/${file_prefix_name}_${mode}_windows/${title_no_space}.exe" 573 | 574 | echo "Start Windows build: $filename" 575 | ./$filename 576 | fi 577 | } 578 | 579 | 580 | clean_build_settings() { 581 | rm -f ${version_settings_filename} 582 | } 583 | 584 | 585 | clean() { 586 | clean_build_settings 587 | 588 | if $is_build_started; then 589 | if $is_build_success; then 590 | echo -e "\x1B[32m[SUCCESS]: Build succesfully created\x1B[0m" 591 | echo -e "\x1B[32m[SUCCESS]: Build time: ${build_time} seconds\x1B[0m" 592 | echo -e "\x1B[32m[SUCCESS]: Build artifact: ${DEPLOYER_ARTIFACT_PATH}\x1B[0m" 593 | else 594 | echo -e "\x1B[31m[ERROR]: Build finished with errors\x1B[0m" 595 | fi 596 | else 597 | echo -e "Deployer end" 598 | fi 599 | } 600 | 601 | 602 | ### ARGS PARSING 603 | arg=$1 604 | is_build=false 605 | is_deploy=false 606 | is_android=false 607 | is_ios=false 608 | is_html=false 609 | is_linux=false 610 | is_macos=false 611 | is_windows=false 612 | is_resolve=true 613 | is_android_instant=false 614 | is_fast_debug=false 615 | mode="debug" 616 | settings_params="" 617 | build_params="" 618 | build_server=${build_server:-"https://build.defold.com"} 619 | 620 | for (( i=0; i<${#arg}; i++ )); do 621 | a=${arg:$i:1} 622 | if [ $a == "b" ]; then 623 | is_build=true 624 | fi 625 | if [ $a == "d" ]; then 626 | is_deploy=true 627 | fi 628 | if [ $a == "r" ]; then 629 | mode="release" 630 | fi 631 | if [ $a == "a" ]; then 632 | is_android=true 633 | fi 634 | if [ $a == "i" ]; then 635 | is_ios=true 636 | fi 637 | if [ $a == "h" ]; then 638 | is_html=true 639 | fi 640 | if [ $a == "l" ]; then 641 | is_linux=true 642 | fi 643 | if [ $a == "w" ]; then 644 | is_windows=true 645 | fi 646 | if [ $a == "m" ]; then 647 | is_macos=true 648 | fi 649 | done 650 | 651 | shift 652 | while [[ $# -gt 0 ]] 653 | do 654 | key=$1 655 | 656 | case $key in 657 | --instant) 658 | is_android_instant=true 659 | mode="release" 660 | file_prefix_name+="_instant" 661 | shift 662 | ;; 663 | --fast) 664 | is_fast_debug=true 665 | shift 666 | ;; 667 | --no-resolve) 668 | is_resolve=false 669 | shift 670 | ;; 671 | --settings) 672 | settings_params="${settings_params} --settings $2" 673 | shift 674 | shift 675 | ;; 676 | --param) 677 | build_params="${build_params} $2" 678 | shift 679 | shift 680 | ;; 681 | --headless) 682 | mode="headless" 683 | shift 684 | ;; 685 | *) # Unknown option 686 | shift 687 | ;; 688 | esac 689 | done 690 | 691 | 692 | ### Create deployer additional info project settings 693 | echo "[project] 694 | version = ${version} 695 | commit_sha = ${commit_sha} 696 | build_date = ${build_date}" > ${version_settings_filename} 697 | 698 | if $enable_incremental_android_version_code; then 699 | echo " 700 | 701 | [android] 702 | version_code = ${commits_count}" >> ${version_settings_filename} 703 | fi 704 | 705 | settings_params="${settings_params} --settings ${version_settings_filename}" 706 | add_to_gitignore $version_settings_filename 707 | 708 | 709 | ### Deployer run 710 | if $is_ios; then 711 | if $is_build; then 712 | echo -e "\nStart build on \x1B[36m${ios_platform}\x1B[0m" 713 | build ${ios_platform} ${mode} 714 | fi 715 | 716 | if $is_deploy; then 717 | echo "Start deploy project to device" 718 | deploy ${ios_platform} ${mode} 719 | run ${ios_platform} ${mode} 720 | fi 721 | fi 722 | 723 | if $is_android; then 724 | if ! $is_android_instant; then 725 | # Just build usual Android build 726 | if $is_build; then 727 | echo -e "\nStart build on \x1B[34m${android_platform}\x1B[0m" 728 | build ${android_platform} ${mode} 729 | fi 730 | 731 | if $is_deploy; then 732 | echo "Start deploy project to device" 733 | deploy ${android_platform} ${mode} 734 | run ${android_platform} ${mode} 735 | fi 736 | else 737 | # Build Android Instant APK 738 | echo -e "\nStart build on \x1B[34m${android_platform} Instant APK\x1B[0m" 739 | build ${android_platform} ${mode} "--settings ${android_instant_app_settings}" 740 | make_instant ${mode} 741 | 742 | if $is_deploy; then 743 | echo "No autodeploy for Instant APK builds..." 744 | fi 745 | fi 746 | fi 747 | 748 | if $is_html; then 749 | if $is_build; then 750 | echo -e "\nStart build on \x1B[33m${html_platform}\x1B[0m" 751 | build ${html_platform} ${mode} 752 | fi 753 | 754 | if $is_deploy; then 755 | deploy ${html_platform} ${mode} 756 | fi 757 | fi 758 | 759 | if $is_linux; then 760 | if $is_build; then 761 | echo -e "\nStart build on \x1B[33m${linux_platform}\x1B[0m" 762 | build ${linux_platform} ${mode} 763 | fi 764 | 765 | if $is_deploy; then 766 | run ${linux_platform} ${mode} 767 | fi 768 | fi 769 | 770 | if $is_macos; then 771 | if $is_build; then 772 | echo -e "\nStart build on \x1B[33m${macos_platform}\x1B[0m" 773 | build ${macos_platform} ${mode} 774 | fi 775 | 776 | if $is_deploy; then 777 | run ${macos_platform} ${mode} 778 | fi 779 | fi 780 | 781 | if $is_windows; then 782 | if $is_build; then 783 | echo -e "\nStart build on \x1B[33m${windows_platform}\x1B[0m" 784 | build ${windows_platform} ${mode} 785 | fi 786 | 787 | if $is_deploy; then 788 | run ${windows_platform} ${mode} 789 | fi 790 | fi 791 | -------------------------------------------------------------------------------- /settings_deployer.template: -------------------------------------------------------------------------------- 1 | # Path to bob folder. It will find and save new bob.jar files inside 2 | bob_folder={path_to_bob_folder} 3 | 4 | # Path to android keystore for debug 5 | android_keystore_dev={path_to_keystore.jks} 6 | 7 | # Path to android keystore for release 8 | android_keystore_dist={path_to_keystore.jks} 9 | 10 | # Path to android keystore password for debug. This file should contains keystore password 11 | android_keystore_password_dev="{path_to_keystore_password.txt}" 12 | 13 | # Path to android keystore password for release. This file should contains keystore password 14 | android_keystore_password_dist="{path_to_keystore_password.txt}" 15 | 16 | # Name of alias from provided keystore to use for android development build 17 | android_keystore_alias_dev="keystore_alias" 18 | 19 | # Name of alias from provided keystore to use for android release build 20 | android_keystore_alias_dist="keystore_alias" 21 | 22 | # ID of your ios development identity 23 | ios_identity_dev="AAXBBYY" 24 | 25 | # ID of your iod distribution identity 26 | ios_identity_dist="YYBBXXAA" 27 | 28 | # Path to ios development mobileprovision 29 | ios_prov_dev={path_to_ios_dev.mobileprovision} 30 | 31 | # Path to ios distribution mobileprovision 32 | ios_prov_dist={path_to_ios_dist.mobileprovision} 33 | 34 | # You can point bob version for project in format "filename:sha" 35 | bob_sha="184:1f5712609c345f870b691a85d611d4825d22a718" 36 | 37 | # Select Defold channel. Values: stable, beta, alpha 38 | bob_channel="stable" 39 | 40 | # If true, it will check and download latest bob version. It will ignore bob_sha param 41 | use_latest_bob=false 42 | 43 | # Select Defold build server 44 | build_server="https://build.defold.com" 45 | 46 | # Pre-build hook bash script path. The path relative from game project folder 47 | pre_build_script=false 48 | 49 | # Post-build hook bash script path. The path relative from game project folder 50 | post_build_script=false 51 | 52 | # Exclude folders from build 53 | exclude_folders="" 54 | 55 | # Set patch (last value after dot) game version value as total git commits count (1.2.0 -> 1.2.{commits_count}) 56 | # You allow to get SHA commit from version via: git rev-list --all --reverse | sed -n {N}p 57 | enable_incremental_version=false 58 | 59 | # Use git commits count as android.version_code on build 60 | enable_incremental_android_version_code=false 61 | 62 | # Local resource cache folder for deployer script. This folder will be added to gitignore if exists 63 | resource_cache_local=".deployer_cache" 64 | 65 | # If true, add `-l yes` build param for publish live content 66 | is_live_content=false 67 | 68 | # Set to true, if you do not need to strip executables 69 | no_strip_executable=false 70 | 71 | # Is need to build html report 72 | is_build_html_report=false 73 | 74 | # Enable to start record build stats of every deployer build in csv format 75 | build_stats_report_file="./deployer_build_stats.csv" 76 | 77 | # Android instant app settings.ini path to override 78 | # (Usually, you need it to override AndroidManifest.xml) 79 | # See instruction here: https://forum.defold.com/t/instruction-android-instant-app-creation/48471 80 | android_instant_app_settings={path_to_android_settings_ini} 81 | 82 | # SDK path to build Android Instant app 83 | sdk_path={path_to_android_sdk} 84 | 85 | # Path to android signature key for release (Since Defold 174 only using for Android Instant games) 86 | android_key_dist={path_to_key.pk8} 87 | 88 | # Path to android signature certificate for release (Since Defold 174 only using for Android Instant games) 89 | android_cer_dist={path_to_certificate.pem} 90 | 91 | # Use settings file for Android platform 92 | # settings_android={path_to_android_ini} 93 | 94 | # Use settings file for iOS platform 95 | # settings_ios={path_to_ios_ini} 96 | 97 | # Use settings file for HTML platform 98 | # settings_html={path_to_html_ini} 99 | 100 | # Use settings file for MacOS platform 101 | # settings_macos={path_to_macos_ini} 102 | 103 | # Use settings file for Windows platform 104 | # settings_windows={path_to_windows_ini} 105 | 106 | # Use settings file for Linux platform 107 | # settings_linux={path_to_linux_ini} 108 | --------------------------------------------------------------------------------