├── .gitignore ├── fastlane ├── Appfile ├── Pluginfile └── Fastfile ├── Gemfile ├── LICENSE ├── CHANGELOG.md ├── README.md └── action.yml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn-error.log 3 | -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | package_name ENV["ANDROID_PACKAGE_NAME"] 2 | json_key_data_raw ENV["PLAY_STORE_JSON_KEY_DATA"] -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 4 | eval(File.read(plugins_path), binding) if File.exist?(plugins_path) 5 | -------------------------------------------------------------------------------- /fastlane/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-browserstack' 6 | gem 'fastlane-plugin-increment_version_code' 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 SparkFabrik 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 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [1.5.0] - 2023-26-05 4 | - Add `fastlane-version` input. 5 | 6 | ## [1.4.0] - 2023-18-04 7 | - Add `release-track` and `release-status` inputs. 8 | 9 | ## [1.3.4] - 2023-08-02 10 | 11 | - Fix `build.sh` input checks when uploading to Play Store. 12 | 13 | ## [1.3.3] - 2023-31-01 14 | 15 | Now `gemfile.lock` will be checked and if it contains a `BUNDLED WITH` section it will install and use that specific version of bundler. 16 | The default value of `bundler-version` is now set to `2.3` so that the fallback value is compatible with fastlane plugins used by the action. 17 | 18 | ## [1.3.2] - 2023-30-01 19 | 20 | Bundler is now configured with `setup-ruby`. 21 | 22 | ## [1.3.1] - 2023-30-01 23 | 24 | Minor README.md updates. 25 | 26 | ## [1.3.0] - 2023-30-01 27 | 28 | Added optional Ruby and bundler version. 29 | 30 | ### Added 31 | 32 | - Optional Ruby version: using the `ruby-version` property you can specify Ruby version you wish to use. If missing latest Ruby version available will be used. 33 | - Optional bundler version: using the `bundler-version` property you can specify bundler version you wish to use. If missing latest bundler version will be used. 34 | - Optional fastlane env parameter: using `fastlane-env` parameter you can specify wich env fastlane should load while executing the lane. 35 | 36 | ## [1.2.0] - 2022-17-06 37 | 38 | Added signed builds and optional upload to Play Store. 39 | 40 | ### Added 41 | 42 | - Optional build format: you can build an unsigned APK (`build-type: assemble`) or a signed AAB (`build-type: bundle`). In case of a signed AAB you will also need to provide the `package-name` and the `keystore-content`, `keystore-password` and `keystore-alias` 43 | - Optional upload to the "internal" track of the Google Play Store: set the `upload-to-play-store` property to `true` and be sure to add the `json-key-data` property as a one-line JSON content of your Key file. 44 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | default_platform(:android) 2 | 3 | platform :android do 4 | desc "Assemble debug APK" 5 | lane :assemble do 6 | if ENV['INCREMENT_BUILD_NUMBER'] == 'true' 7 | increment_version_code() 8 | end 9 | 10 | gradle( 11 | task: ENV["GRADLE_TASK"], 12 | project_dir: ENV["PROJECT_PATH"], 13 | flags: "--no-daemon", 14 | ) 15 | 16 | APK_LOCATION = "#{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}" 17 | sh("cp", "#{APK_LOCATION}", ENV["OUTPUT_PATH"]) 18 | 19 | if ENV["BROWSERSTACK_UPLOAD"] == 'true' 20 | upload_to_browserstack_app_live( 21 | browserstack_username: ENV["BROWSERSTACK_USERNAME"], 22 | browserstack_access_key: ENV["BROWSERSTACK_ACCESS_KEY"], 23 | file_path: ENV["OUTPUT_PATH"] 24 | ) 25 | end 26 | 27 | if ENV["UPLOAD_TO_PLAY_STORE"] == 'true' 28 | upload_to_play_store( 29 | apk: ENV["OUTPUT_PATH"], 30 | package_name: ENV["ANDROID_PACKAGE_NAME"], 31 | release_status: ENV["RELEASE_STATUS"], 32 | track: ENV["RELEASE_TRACK"], 33 | json_key_data: ENV["PLAY_STORE_JSON_KEY_DATA"], 34 | ) 35 | end 36 | end 37 | 38 | desc "Bundle release AAB" 39 | lane :bundle do 40 | if ENV['INCREMENT_BUILD_NUMBER'] == 'true' 41 | previous_build_number = google_play_track_version_codes( 42 | package_name: ENV["PACKAGE_NAME"], 43 | track: ENV["RELEASE_TRACK"], 44 | json_key_data: ENV["PLAY_STORE_JSON_KEY_DATA"], 45 | )[0] 46 | 47 | current_build_number = previous_build_number + 1 48 | 49 | increment_version_code( 50 | version_code: current_build_number 51 | ) 52 | end 53 | 54 | puts "Gradle task: #{ENV["GRADLE_TASK"]}" 55 | sh("ls", "-la", "..") 56 | sh("ls", "-la") 57 | 58 | gradle( 59 | task: ENV["GRADLE_TASK"], 60 | project_dir: ENV["PROJECT_PATH"], 61 | flags: "--no-daemon", 62 | properties: { 63 | "android.injected.signing.store.file" => File.join(Dir.pwd, "..", "keystore.jks"), 64 | "android.injected.signing.store.password" => ENV["KEYSTORE_PASSWORD"], 65 | "android.injected.signing.key.alias" => ENV["KEYSTORE_ALIAS"], 66 | "android.injected.signing.key.password" => ENV["KEYSTORE_PASSWORD"], 67 | } 68 | ) 69 | 70 | AAB_LOCATION = "#{lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH]}" 71 | sh("cp", "#{AAB_LOCATION}", ENV["OUTPUT_PATH"]) 72 | 73 | if ENV["BROWSERSTACK_UPLOAD"] == 'true' 74 | upload_to_browserstack_app_live( 75 | browserstack_username: ENV["BROWSERSTACK_USERNAME"], 76 | browserstack_access_key: ENV["BROWSERSTACK_ACCESS_KEY"], 77 | file_path: ENV["OUTPUT_PATH"] 78 | ) 79 | end 80 | 81 | if ENV["UPLOAD_TO_PLAY_STORE"] == 'true' 82 | upload_to_play_store( 83 | aab: ENV["OUTPUT_PATH"], 84 | package_name: ENV["PACKAGE_NAME"], 85 | release_status: ENV["RELEASE_STATUS"], 86 | track: ENV["RELEASE_TRACK"], 87 | json_key_data: ENV["PLAY_STORE_JSON_KEY_DATA"], 88 | ) 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Build Android App 2 | 3 | This action build Android project, export .apk file as GitHub artifact, with optional automatic upload to BrowserStack AppLive. 4 | 5 | Tested with Ionic, React Native and native android projects. 6 | 7 | ## New in 1.4.0 8 | 9 | - New properties `release-track` and `release-status` for Android 10 | 11 | ## New in 1.3.4 12 | 13 | - Fix build.sh input checks when uploading to Play Store 14 | 15 | ## New in 1.3.3 16 | 17 | - Now `gemfile.lock` will be checked and if it contains a `BUNDLED WITH` section it will install and use that specific version of bundler. 18 | - The default value of `bundler-version` is now set to `2.3` so that the fallback value is compatible with fastlane plugins. 19 | 20 | ## New in 1.3.2 21 | 22 | - Bundler is now installed with `setup-ruby` action. 23 | 24 | ## New in 1.3.0 25 | 26 | - Optional Ruby version: using the `ruby-version` property you can specify Ruby version you wish to use. If missing latest Ruby version available will be used. 27 | - Optional bundler version: using the `bundler-version` property you can specify bundler version you wish to use. If missing latest bundler version will be used. 28 | - Optional fastlane env parameter: using `fastlane-env` parameter you can specify wich env fastlane should load while executing the lane. 29 | 30 | ## New in 1.2.0 31 | 32 | - Optional build format: you can build an unsigned APK (`build-type: assemble`) or a signed AAB (`build-type: bundle`). In case of a signed AAB you will also need to provide the `package-name` and the `keystore-content`, `keystore-password` and `keystore-alias` 33 | - Optional upload to the "internal" track of the Google Play Store: set the `upload-to-play-store` property to `true` and be sure to add the `json-key-data` property as a one-line JSON content of your Key file. 34 | 35 | ## Inputs 36 | 37 | ### `project-path` 38 | 39 | **(Required)** Android folder (where `gradlew` is) 40 | 41 | ### `output-path` 42 | 43 | Output path of apk. Default `"output.apk"`. 44 | 45 | ### `gradle-task` 46 | 47 | Name of the gradle task to run. Default `"assembleDebug"`. 48 | 49 | ### `ruby-version` 50 | 51 | Ruby version to be used. Default `"head"`. 52 | 53 | ### `bundler-version` 54 | 55 | Bundler version to be used. Default `"2.3"`. 56 | 57 | ### `fastlane-version` 58 | 59 | Fastlane version to be used. If not specified, the default value will be used. 60 | 61 | ### `fastlane-env` 62 | 63 | Specify the env that fastlane should load. 64 | 65 | ### `release-track` 66 | 67 | Release track to target. Default `"internal"`. 68 | 69 | ### `release-status` 70 | 71 | Status of the uploaded release. Default `"draft"`. 72 | 73 | ## Example usage 74 | 75 | ```yaml 76 | - uses: sparkfabrik/android-build-action@v1.5.0 77 | with: 78 | project-path: android 79 | output-path: my-app.apk 80 | browserstack-upload: true 81 | browserstack-username: ${{ secrets.BROWSERSTACK_USERNAME }} 82 | browserstack-access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} 83 | ruby-version: "2.7.5" 84 | bundler-version: "2.3.26" 85 | fastlane-env: "debug" 86 | ``` 87 | 88 | ## Contributions Welcome! 89 | 90 | If you have any other inputs you'd like to add, feel free to create PR. 91 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: "Build Android App" 2 | author: "SparkFabrik" 3 | branding: 4 | icon: "smartphone" 5 | color: "green" 6 | description: "Build Android (gradle), export .apk or .aab, optional upload to Play Store, optional upload to BrowserStack App Live." 7 | 8 | inputs: 9 | build-type: 10 | description: "You can build an unsigned APK (assemble) or a signed AAB (bundle)." 11 | required: false 12 | default: "assemble" 13 | gradle-task: 14 | description: "Name of the gradle task to exec (eg. assembleDebug, assembleRelease, bundleRelease)" 15 | required: false 16 | default: "assembleDebug" 17 | increment-build-number: 18 | description: "Increment build number" 19 | required: false 20 | default: false 21 | package-name: 22 | description: "Package name" 23 | required: false 24 | keystore-content: 25 | description: "Keystore file content as base64 encoded string" 26 | required: false 27 | keystore-password: 28 | description: "Keystore password" 29 | required: false 30 | keystore-alias: 31 | description: "Keystore alias" 32 | required: false 33 | json-key-data: 34 | description: "JSON keystore file content" 35 | required: false 36 | upload-to-play-store: 37 | description: "Upload to Play Store" 38 | required: false 39 | default: false 40 | project-path: 41 | description: "Project path" 42 | required: true 43 | output-path: 44 | description: "Output path of the build" 45 | required: false 46 | default: "output.apk" 47 | browserstack-upload: 48 | description: "Boolean to tell the Action to upload the .ipa to Browserstack App Live after the build." 49 | required: false 50 | default: false 51 | browserstack-username: 52 | description: "Browserstack username (required if browserstack-upload == true)" 53 | required: false 54 | default: "" 55 | browserstack-access-key: 56 | description: "Browserstack access key (required if browserstack-upload == true)" 57 | required: false 58 | default: "" 59 | fastlane-env: 60 | description: "Name of the env file name to pass to fastlane --env" 61 | required: false 62 | ruby-version: 63 | description: "Specify the Ruby version you wish to use" 64 | required: false 65 | default: "head" 66 | bundler-version: 67 | description: "Specify the Bundler version you wish to use" 68 | default: "2.3" 69 | required: false 70 | fastlane-version: 71 | description: "Specify the Fastlane version you wish to use" 72 | default: "2.213.0" 73 | required: false 74 | release-track: 75 | description: "Release track to target" 76 | default: "internal" 77 | required: false 78 | release-status: 79 | description: "Status of the release" 80 | default: "draft" 81 | required: false 82 | runs: 83 | using: "composite" 84 | steps: 85 | - id: "SETUP_RUBY" 86 | uses: ruby/setup-ruby@v1 87 | with: 88 | ruby-version: ${{ inputs.ruby-version }} 89 | bundler: ${{ inputs.bundler-version }} 90 | - id: "SETUP_NODE" 91 | uses: actions/setup-node@v3 92 | with: 93 | node-version: 16 94 | - id: "RUN_INDEX" 95 | env: 96 | BUILD_TYPE: ${{ inputs.build-type }} 97 | GRADLE_TASK: ${{ inputs.gradle-task }} 98 | INCREMENT_BUILD_NUMBER: ${{ inputs.increment-build-number }} 99 | PACKAGE_NAME: ${{ inputs.package-name }} 100 | KEYSTORE_CONTENT: ${{ inputs.keystore-content }} 101 | KEYSTORE_PASSWORD: ${{ inputs.keystore-password }} 102 | KEYSTORE_ALIAS: ${{ inputs.keystore-alias }} 103 | JSON_KEY_DATA: ${{ inputs.json-key-data }} 104 | UPLOAD_TO_PLAY_STORE: ${{ inputs.upload-to-play-store }} 105 | PROJECT_PATH: ${{ inputs.project-path }} 106 | OUTPUT_PATH: ${{ inputs.output-path }} 107 | BROWSERSTACK_UPLOAD: ${{ inputs.browserstack-upload }} 108 | BROWSERSTACK_USERNAME: ${{ inputs.browserstack-username }} 109 | BROWSERSTACK_ACCESS_KEY: ${{ inputs.browserstack-access-key }} 110 | FASTLANE_VERSION: ${{ inputs.fastlane-version }} 111 | FASTLANE_ENV: ${{ inputs.fastlane-env }} 112 | RELEASE_TRACK: ${{ inputs.release-track }} 113 | RELEASE_STATUS: ${{ inputs.release-status }} 114 | ACTION_PATH: ${{ github.action_path }} 115 | run: . ${{ github.action_path }}/build.sh 116 | shell: sh 117 | --------------------------------------------------------------------------------