Skip to content

Commit

Permalink
Apply changes for unified CI compatibility, readme updates. (#66)
Browse files Browse the repository at this point in the history
-  Separated test workflow, added debug workflow
-  Added Java 11 selection before running integration tests
-  Refreshed readme using new template,
-  Renaming keystore secrets
  • Loading branch information
lpusok authored Apr 30, 2021
1 parent 59a1c55 commit c4490a0
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 92 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.gows*
_tmp
_keystores
steps-sign-apk
137 changes: 130 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,133 @@
# steps-sign-apk
# Android Sign ![Bitrise Build Status](https://app.bitrise.io/app/3b968e65d584db2a.svg?token=Yk1LUEjLZtIjeIW4OOZvKw&branch=master) [![Bitrise Step Version](https://shields.io/github/v/release/bitrise-steplib/steps-sign-apk?include_prereleases)](https://github.com/bitrise-steplib/steps-sign-apk/releases) ![GitHub License](https://img.shields.io/badge/license-MIT-lightgrey.svg) [![Bitrise Community](https://img.shields.io/badge/community-Bitrise%20Discuss-lightgrey)](https://discuss.bitrise.io/)

## How to use this Step
Signs your APK or Android App Bundle before uploading it to Google Play Store.

Can be run directly with the [bitrise CLI](https://github.com/bitrise-io/bitrise),
just `git clone` this repository, `cd` into it's folder in your Terminal/Command Line
and call `bitrise run test`.
Once you have uploaded your keystore file and provided your keystore credentials on the **Code Signing** tab of the Workflow Editor, the **Android Sign** Step signs your APK digitally.
Bitrise assigns Environment Variables to the uploaded file and credentials, and uses those in the respective fields of the **Android Sign** Step.
Once the Step runs, it produces a signed APK or App Bundle which will be used as the input value of the **App file path** field in the **Google Play Deploy** Step.

*Check the `bitrise.yml` file for required inputs which have to be
added to your `.bitrise.secrets.yml` file!*
### Configuring the Step

1. Add the **Android Sign** Step after a build Step in your deploy workflow.
2. Upload the keystore file to the **Upload file** field on the **Code Signing** tab.
3. Provide your keystore password, keystore alias and private key password to the relevant fields on the **Code Signing** tab.
4. Run your build.


### Troubleshooting
Make sure you have the **Android Sign** Step right after a build Steps but before **Deploy to Google Play** Step in your deploy workflow.
If you wish to get your Android project signed automatically, use the **Android Sign** Step and do not set any gradle task for the signing, otherwise, the Step will fail.


### Useful links
- [Android code signing using Android Sign Step](https://devcenter.bitrise.io/code-signing/android-code-signing/android-code-signing-using-bitrise-sign-apk-step/)
- [Android deployment](https://devcenter.bitrise.io/deploy/android-deploy/android-deployment-index/)


### Related Steps
- [Android Build](https://www.bitrise.io/integrations/steps/android-build)
- [Gradle Runner](https://www.bitrise.io/integrations/steps/gradle-runner)
- [Deploy to Bitrise.io](https://www.bitrise.io/integrations/steps/deploy-to-bitrise-io)

## Examples

### Building a bundle and signing it

1. Build an Android App Bundle:
```
---
format_version: '8'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
project_type: android
workflows:
release:
envs:
- PROJECT_LOCATION: .
- MODULE:
- VARIANT: release
# If the Android keystore is configured in the workflow editor, BITRISEIO_ANDROID_KEYSTORE* envs will be set automatically
- BITRISEIO_ANDROID_KEYSTORE_URL: $BITRISEIO_ANDROID_KEYSTORE_URL
- BITRISEIO_ANDROID_KEYSTORE_PASSWORD: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD
- BITRISEIO_ANDROID_KEYSTORE_ALIAS: $BITRISEIO_ANDROID_KEYSTORE_ALIAS
- BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD
steps:
- activate-ssh-key:
run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
- git-clone: {}
- script:
title: "Select Java 11"
run_if: $.IsCI
inputs:
- content: |-
#!/usr/bin/env bash
set -ex
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
sudo update-alternatives --set javac /usr/lib/jvm/java-11-openjdk-amd64/bin/javac
sudo update-alternatives --set java /usr/lib/jvm/java-11-openjdk-amd64/bin/java
export JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64"
envman add --key JAVA_HOME --value "/usr/lib/jvm/java-11-openjdk-amd64"
elif [[ "$OSTYPE" == "darwin"* ]]; then
jenv global 11
export JAVA_HOME="$(jenv prefix)"
envman add --key JAVA_HOME --value "$(jenv prefix)"
fi
- install-missing-android-tools:
inputs:
- gradlew_path: $PROJECT_LOCATION/gradlew
- android-build:
inputs:
- project_location: $PROJECT_LOCATION
- module: $MODULE
- variant: $VARIANT
- build_type: aab
```
2. Sign the App Bundle:
```yml
- sign-apk:
inputs:
- use_apk_signer: true
```
3. Deploy the signed App Bundle to Bitrise:
```
- deploy-to-bitrise-io: {}
```
## Configuration
### Inputs
| Parameter | Description | Required | Default |
| --- | --- | --- | --- |
| android_app | Path(s) to the build artifact file to sign (`.aab` or `.apk`). You can provide multiple build artifact file paths separated by `\|` character. Format examples: `/path/to/my/app.apk`; `/path/to/my/app1.apk\|/path/to/my/app2.apk`. | ✔️ | *$BITRISE_APK_PATH\n$BITRISE_AAB_PATH* |
| keystore_url | Keystore URL. For remote keystores you can provide any download location (example: `https://URL/TO/keystore.jks`). For local keystores provide file path url. (example: `file://PATH/TO/keystore.jks`). | ✔️ | *$BITRISEIO_ANDROID_KEYSTORE_URL* |
| keystore_password | Keystore password | ✔️ | *$BITRISEIO_ANDROID_KEYSTORE_PASSWORD* |
| keystore_alias | Key alias | ✔️ | *$BITRISEIO_ANDROID_KEYSTORE_ALIAS* |
| private_key_password | Key password. If key password equals to keystore password (not recommended), you can leave it empty. | - | *$BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD* |
| page_align | If enabled, it tells zipalign to use memory page alignment for stored shared object files. Options: `automatic` (Enable page alignment for .so files, unless attribute *extractNativeLibs="true"* is set in the AndroidManifest.xml); `true`; `false` | ✔️ | `automatic` |
| use_apk_signer | Indicates if the signature should be done using apksigner instead of jarsigner. Options: `true`, `false`. | ✔️ | `false` |
| signer_scheme | APK Signature Scheme. `automatic` uses the values of --min-sdk-version and --max-sdk-version to decide which Signature Scheme to use. Options: `v2`, `v3`, `v4`, `automatic`. | ✔️ | `automatic` |
| debuggable_permitted | Whether to permit signing android:debuggable="true" APKs. Android disables some of its security protections for such apps. Options: `true`, `false`. | ✔️ | `true` |
| output_name | Name of the produced output artifact. By default the output name is *app-release-bitrise-signed*. Else it's the specified name. Do not add extensions. | - | "" |
| verbose_log | Enables verbose logging. Options: `true`, `false`. | ✔️ | `false` |
| apk_path | *deprecated* | - | - |

### Outputs

| Environment Variable | Description |
| --- | --- |
| BITRISE_SIGNED_APK_PATH | This output will include the path of the signed APK. If the build generates more than one APK this output will contain the last one's path. |
| BITRISE_SIGNED_APK_PATH_LIST | This output will include the paths of the generated APKs. If multiple APKs are provided for signing the output paths are separated with `\|` character, for example, `app-armeabi-v7a-debug.apk\|app-mips-debug.apk\|app-x86-debug.apk` |
| BITRISE_SIGNED_AAB_PATH | This output will include the path of the signed AAB. If the build generates more than one AAB this output will contain the last one's path. |
| BITRISE_SIGNED_AAB_PATH_LIST | This output will include the paths of the generated AABs. If multiple AABs are provided for signing the output paths are separated with `\|` character, for example, `app-armeabi-v7a-debug.aab\|app-mips-debug.aab\|app-x86-debug.aab` |
| BITRISE_APK_PATH | *deprecated* |
| BITRISE_AAB_PATH | *deprecated* |

## Contributing

We welcome [pull requests](https://github.com/bitrise-steplib/steps-sign-apk/pulls) and [issues](https://github.com/bitrise-steplib/steps-sign-apk/issues) against this repository.

For pull requests, work on your changes in a forked repository and use the bitrise cli to [run your tests locally](https://devcenter.bitrise.io/bitrise-cli/run-your-first-build/).

### Creating your own steps

Follow [this guide](https://devcenter.bitrise.io/contributors/create-your-own-step/) if you would like to create your own step.
174 changes: 89 additions & 85 deletions bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,29 @@ app:
- SAMPLE_APP_REPOSITORY_URL: https://github.com/bitrise-io/sample-apps-android-abi-split.git
- BRANCH: master
- GRADLEW_PATH: "./gradlew"

# define these in your .bitrise.secrets.yml
- BITRISEIO_ANDROID_KEYSTORE_1_URL: $BITRISEIO_ANDROID_KEYSTORE_1_URL
- BITRISEIO_ANDROID_KEYSTORE_PASSWORD_1: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_1
- BITRISEIO_ANDROID_KEYSTORE_ALIAS_1: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_1
- BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_1: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_1
- BITRISEIO_ANDROID_KEYSTORE_2_URL: $BITRISEIO_ANDROID_KEYSTORE_2_URL
- BITRISEIO_ANDROID_KEYSTORE_PASSWORD_2: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_2
- BITRISEIO_ANDROID_KEYSTORE_ALIAS_2: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_2
- BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_2: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_2
- BITRISEIO_ANDROID_KEYSTORE_3_URL: $BITRISEIO_ANDROID_KEYSTORE_3_URL
- BITRISEIO_ANDROID_KEYSTORE_PASSWORD_3: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_3
- BITRISEIO_ANDROID_KEYSTORE_ALIAS_3: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_3
- BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_3: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_3
- BITRISEIO_ANDROID_KEYSTORE_4_URL: $BITRISEIO_ANDROID_KEYSTORE_4_URL
- BITRISEIO_ANDROID_KEYSTORE_PASSWORD_4: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_4
- BITRISEIO_ANDROID_KEYSTORE_ALIAS_4: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_4
- BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_4: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_4
# Keystore password == key password
- SAME_PASS_ANDROID_KEYSTORE_URL: $SAME_PASS_ANDROID_KEYSTORE_URL
- SAME_PASS_ANDROID_KEYSTORE_PASSWORD: $SAME_PASS_ANDROID_KEYSTORE_PASSWORD
- SAME_PASS_ANDROID_KEY_ALIAS: $SAME_PASS_ANDROID_KEY_ALIAS
- SAME_PASS_ANDROID_KEY_PASSWORD: $SAME_PASS_ANDROID_KEY_PASSWORD
# Keystore password != key password
- DIFF_PASS_ANDROID_KEYSTORE_URL: $DIFF_PASS_ANDROID_KEYSTORE_URL
- DIFF_PASS_ANDROID_KEYSTORE_PASSWORD: $DIFF_PASS_ANDROID_KEYSTORE_PASSWORD
- DIFF_PASS_ANDROID_KEY_ALIAS: $DIFF_PASS_ANDROID_KEY_ALIAS
- DIFF_PASS_ANDROID_KEY_PASSWORD: $DIFF_PASS_ANDROID_KEY_PASSWORD
# Default alias ('mykey')
- DEFAULT_ALIAS_ANDROID_KEYSTORE_URL: $DEFAULT_ALIAS_ANDROID_KEYSTORE_URL
- DEFAULT_ALIAS_ANDROID_KEYSTORE_PASSWORD: $DEFAULT_ALIAS_ANDROID_KEYSTORE_PASSWORD
- DEFAULT_ALIAS_ANDROID_KEY_ALIAS: $DEFAULT_ALIAS_ANDROID_KEY_ALIAS
- DEFAULT_ALIAS_ANDROID_KEY_PASSWORD: $DEFAULT_ALIAS_ANDROID_KEY_PASSWORD
# Android Studio generated keystore
- STUDIO_GEN_ANDROID_KEYSTORE_URL: $STUDIO_GEN_ANDROID_KEYSTORE_URL
- STUDIO_GEN_ANDROID_KEYSTORE_PASSWORD: $STUDIO_GEN_ANDROID_KEYSTORE_PASSWORD
- STUDIO_GEN_ANDROID_KEY_ALIAS: $STUDIO_GEN_ANDROID_KEY_ALIAS
- STUDIO_GEN_ANDROID_KEY_PASSWORD: $STUDIO_GEN_ANDROID_KEY_PASSWORD

workflows:
# ----------------------------------------------------------------
# --- workflow to Test this Step
ci:
before_run:
- audit-this-step
Expand All @@ -37,10 +38,51 @@ workflows:
- errcheck:
- go-test:
after_run:
- test

test:
steps:
- script:
run_if: $.IsCI
inputs:
- content: |-
#!/usr/bin/env bash
set -ex
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
sudo update-alternatives --set javac /usr/lib/jvm/java-11-openjdk-amd64/bin/javac
sudo update-alternatives --set java /usr/lib/jvm/java-11-openjdk-amd64/bin/java
export JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64"
envman add --key JAVA_HOME --value "/usr/lib/jvm/java-11-openjdk-amd64"
elif [[ "$OSTYPE" == "darwin"* ]]; then
jenv global 11
export JAVA_HOME="$(jenv prefix)"
envman add --key JAVA_HOME --value "$(jenv prefix)"
fi
after_run:
- test_apk
- test_apk_debug
- test_bundle

debug:
envs:
- APK_SIGNER: "true"
# Must define these envs in .bitrise.secrets.yml
- BITRISE_APK_PATH: $BITRISE_APK_PATH
- BITRISEIO_ANDROID_KEYSTORE_URL: $BITRISEIO_ANDROID_KEYSTORE_URL
- BITRISEIO_ANDROID_KEYSTORE_PASSWORD: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD
- BITRISEIO_ANDROID_KEYSTORE_ALIAS: $BITRISEIO_ANDROID_KEYSTORE_ALIAS
- BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD
steps:
- path::./:
title: Debug sign-apk Step
inputs:
- keystore_url: $BITRISEIO_ANDROID_KEYSTORE_URL
- keystore_password: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD
- keystore_alias: $BITRISEIO_ANDROID_KEYSTORE_ALIAS
- private_key_password: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD
- use_apk_signer: $APK_SIGNER


test_apk:
envs:
- GRADLE_TASK: assembleRelease
Expand Down Expand Up @@ -83,24 +125,11 @@ workflows:
inputs:
- path: ./_tmp
- is_create_path: true
- script:
- git::https://github.com/bitrise-steplib/bitrise-step-simple-git-clone.git@master:
inputs:
- content: |-
#!/usr/bin/env bash
set -x
if [[ -z "${SAMPLE_APP_REPOSITORY_URL}" ]]; then
echo "error: there is no SAMPLE_APP_URL env var specified"
exit 1
elif [[ -z "${COMMIT}" && -z "${BRANCH}" ]]; then
echo "error: can't checkout: there is no BRANCH or COMMIT env var specified"
exit 1
fi
git init
git remote add origin "${SAMPLE_APP_REPOSITORY_URL}"
git fetch || exit 1
[[ -n "${COMMIT}" ]] && git checkout "${COMMIT}" || git checkout "${BRANCH}"
- repository_url: $SAMPLE_APP_REPOSITORY_URL
- clone_into_dir: .
- branch: $BRANCH
- install-missing-android-tools:
inputs:
- ndk_revision: '16'
Expand Down Expand Up @@ -177,54 +206,54 @@ workflows:
- path::./:
title: Step Test - keystore pass == key pass
inputs:
- keystore_url: $BITRISEIO_ANDROID_KEYSTORE_1_URL
- keystore_password: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_1
- keystore_alias: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_1
- private_key_password: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_1
- keystore_url: $SAME_PASS_ANDROID_KEYSTORE_URL
- keystore_password: $SAME_PASS_ANDROID_KEYSTORE_PASSWORD
- keystore_alias: $SAME_PASS_ANDROID_KEY_ALIAS
- private_key_password: $SAME_PASS_ANDROID_KEY_PASSWORD
- use_apk_signer: $APK_SIGNER

test2:
steps:
- path::./:
title: Step Test - keystore pass != key pass
inputs:
- keystore_url: $BITRISEIO_ANDROID_KEYSTORE_2_URL
- keystore_password: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_2
- keystore_alias: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_2
- private_key_password: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_2
- keystore_url: $DIFF_PASS_ANDROID_KEYSTORE_URL
- keystore_password: $DIFF_PASS_ANDROID_KEYSTORE_PASSWORD
- keystore_alias: $DIFF_PASS_ANDROID_KEY_ALIAS
- private_key_password: $DIFF_PASS_ANDROID_KEY_PASSWORD
- use_apk_signer: $APK_SIGNER

test3:
steps:
- path::./:
title: Step Test - default alias
inputs:
- keystore_url: $BITRISEIO_ANDROID_KEYSTORE_3_URL
- keystore_password: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_3
- keystore_alias: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_3
- private_key_password: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_3
- keystore_url: $DEFAULT_ALIAS_ANDROID_KEYSTORE_URL
- keystore_password: $DEFAULT_ALIAS_ANDROID_KEYSTORE_PASSWORD
- keystore_alias: $DEFAULT_ALIAS_ANDROID_KEY_ALIAS
- private_key_password: $DEFAULT_ALIAS_ANDROID_KEY_PASSWORD
- use_apk_signer: $APK_SIGNER

test4:
steps:
- path::./:
title: Step Test - android studio generated keystore (jks)
inputs:
- keystore_url: $BITRISEIO_ANDROID_KEYSTORE_4_URL
- keystore_password: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_4
- keystore_alias: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_4
- private_key_password: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_4
- keystore_url: $STUDIO_GEN_ANDROID_KEYSTORE_URL
- keystore_password: $STUDIO_GEN_ANDROID_KEYSTORE_PASSWORD
- keystore_alias: $STUDIO_GEN_ANDROID_KEY_ALIAS
- private_key_password: $STUDIO_GEN_ANDROID_KEY_PASSWORD
- use_apk_signer: $APK_SIGNER

test5:
steps:
- path::./:
title: Step Test - android studio generated keystore (jks) + custom artifact name
inputs:
- keystore_url: $BITRISEIO_ANDROID_KEYSTORE_4_URL
- keystore_password: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_4
- keystore_alias: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_4
- private_key_password: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_4
- keystore_url: $STUDIO_GEN_ANDROID_KEYSTORE_URL
- keystore_password: $STUDIO_GEN_ANDROID_KEYSTORE_PASSWORD
- keystore_alias: $STUDIO_GEN_ANDROID_KEY_ALIAS
- private_key_password: $STUDIO_GEN_ANDROID_KEY_PASSWORD
- output_name: "test-artifact-name"
- use_apk_signer: $APK_SIGNER

Expand All @@ -233,37 +262,12 @@ workflows:
- path::./:
title: Step Test - android studio generated keystore (jks) + custom artifact name second time to see collisions if any
inputs:
- keystore_url: $BITRISEIO_ANDROID_KEYSTORE_4_URL
- keystore_password: $BITRISEIO_ANDROID_KEYSTORE_PASSWORD_4
- keystore_alias: $BITRISEIO_ANDROID_KEYSTORE_ALIAS_4
- private_key_password: $BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD_4
- keystore_url: $STUDIO_GEN_ANDROID_KEYSTORE_URL
- keystore_password: $STUDIO_GEN_ANDROID_KEYSTORE_PASSWORD
- keystore_alias: $STUDIO_GEN_ANDROID_KEY_ALIAS
- private_key_password: $STUDIO_GEN_ANDROID_KEY_PASSWORD
- output_name: "test-artifact-name"
- use_apk_signer: $APK_SIGNER

_go_tests:
steps:
- go-list:
- golint:
- errcheck:
- go-test:

# ----------------------------------------------------------------
# --- Utility workflows

dep-update:
title: Dep update
description: |
Used for updating bitrise dependencies with dep
steps:
- script:
title: Dependency update
inputs:
- content: |-
#!/usr/bin/env bash
set -ex
go get -u -v github.com/golang/dep/cmd/dep
dep ensure -v
dep ensure -v -update

# ----------------------------------------------------------------
# --- workflows to Share this step into a Step Library
Expand Down

0 comments on commit c4490a0

Please sign in to comment.