Deploying Android Apps Using GitHub Actions

May 4 2023 · Kotlin 1.7.21, Android 13, Android Studio Electric Eel

Part 1: Automate Releases with GitHub Actions

04. Generate a Signed Build

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 03. Run Unit & Instrumented Tests Next episode: 05. Trigger a Workflow

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 04. Generate a Signed Build

Generating a release build on a remote system is quite different from doing it locally. One of the main aspects is to make sure that the signing data remains secret.

Generate a Keystore

To sign your release build, you first need a keystore.

Open the Terminal tab inside Android Studio and run the following code:

keytool -genkey -v -keystore my-app-release-key.keystore -alias alias_name -keypass hello123 -storepass hello123 -keyalg RSA -sigalg SHA256withRSA -keysize 2048 -validity 7500

In the code above,

  • my-app-release-key.keystore is the name of your keystore. You can give it any name you like.
  • alias_name is the alias for your key
  • keypass is the password for this particular key
  • storepass is the password for this keystore. These weak passwords are for illustration only. Remember to use strong passwords instead and it’s also recommended to use different passwords for you key and keystore.
  • validity sets the expiry date of the key which is set 7500 days from the current date

After you enter the code, you’ll be asked to provide a password which is at least 6 characters long. Remember this password as you’ll need it in a later step.

You’ll also be asked to enter a few details about you and your organization. Enter the appropriate details.

After providing all the details, you’ll see a message similar to the one below:

[Storing my-app-release-key.keystore]

You have successfully created a new keystore.

Store Secrets

For security’s sake, it’s important not to hard code secrets inside the codebase. A good way to avoid this is by using environment variables to refer to the secrets. GitHub Actions provides a similar mechanism.

Open your repository on GitHub and go to the Settings tab.

On the left navigation bar, click Secrets and variables▸ Actions.

Click New repository secret. Enter ALIAS into the Name field and the alias of your signing key in the Secreat field.

Click Add secret. You’ll see the secreat listed in the Repository secrets section.

Similarly add the following 3 secrets:

  1. KEY_STORE_PASSWORD: The password to your signing keystore.
  2. KEY_PASSWORD: The private key password for your signing keystore.
  3. SIGNING_KEY: The base 64-encoded signing key used to sign your app.

To generate the base 64-encoded key, run the following command in the Terminal and copy the output string:

openssl base64 < path_to_signing_key | tr -d '\n' | tee some_signing_key.jks.base64.txt

Go back to GitHub and paste the copied string as the value for SIGNING_KEY.

Next, you have to add a job to build the app.

Write a Job to Generate a Signed Build

Add a new job named build to the workflow:

  build:
    needs: [unit_tests, android_tests]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: set up JDK
        uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: 11
      - name: Generate Release APK
        run: ./gradlew assembleRelease
      - name: Sign APK
        uses: ilharp/sign-android-release@v1
        # ID used to access action output
        id: sign_app
        with:
          releaseDir: app/build/outputs/apk/release
          signingKey: ${{ secrets.SIGNING_KEY }}
          keykeyAlias: ${{ secrets.ALIAS }}
          keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
          keyPassword: ${{ secrets.KEY_PASSWORD }}
          buildToolsVersion: 33.0.0
      - uses: actions/upload-artifact@v3
        with:
          name: release.apk
          path: ${{steps.sign_app.outputs.signedFile}}
      - uses: actions/upload-artifact@v3
        with:
          name: mapping.txt
          path: app/build/outputs/mapping/release/mapping.txt

In this code, the build job performs multiple steps:

  1. Checks out the code.
  2. Generates a release APK using the assembleRelease Gradle task.
  3. Signs the APK using the ilharp/sign-android-release action, which is a third-party action. This step uses the four secrets you added in the previous section. It also has an ID: sign_app.
  4. Uploads the signed APK as an artifact to GitHub. This step uses the ID from the previous step to access its output, named signedFile.
  5. Uploads the mapping file as an artifact. You’ll use this in a later step when you upload to the Play Store.

Commit the file to your project and push it to GitHub.

git commit -m "Add build job"
git push origin master

In the next episode, you’ll learn how to add conditions to run this job.