<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Tharun Balaji R</title>
    <description>The latest articles on Forem by Tharun Balaji R (@tharunbalaji31).</description>
    <link>https://forem.com/tharunbalaji31</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1156823%2F3ddbc734-e96e-45f3-b668-a1d7500b5e34.png</url>
      <title>Forem: Tharun Balaji R</title>
      <link>https://forem.com/tharunbalaji31</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tharunbalaji31"/>
    <language>en</language>
    <item>
      <title>Android DevOps CI/CD Pipeline Architecture 📲⚙️</title>
      <dc:creator>Tharun Balaji R</dc:creator>
      <pubDate>Sun, 24 Dec 2023 02:22:30 +0000</pubDate>
      <link>https://forem.com/tharunbalaji31/android-devops-cicd-pipeline-architecture-4ma8</link>
      <guid>https://forem.com/tharunbalaji31/android-devops-cicd-pipeline-architecture-4ma8</guid>
      <description>&lt;p&gt;
  Hello there! Android devs👋, This article how to develop and maintain easy building, flexible maintenance, automated deployment and other DevOps operations for android applications using GitHub Actions and deployment in Google Play Store! Lets go 🚀  
&lt;/p&gt;

&lt;p&gt;
  Article on Hashnode: https://tharunbalaji2004.hashnode.dev/android-ci-cd
&lt;/p&gt;

&lt;h3&gt;
  
  
  What is meant by CI ?
&lt;/h3&gt;

&lt;p&gt;CI stands for &lt;strong&gt;&lt;em&gt;Continuous Integration&lt;/em&gt;&lt;/strong&gt;, which is a development practice that delivers software to the end user with production reliability. The Continuous Integration (CI) is an &lt;strong&gt;&lt;em&gt;automated integration process&lt;/em&gt;&lt;/strong&gt; which generates a build and runs automates tests against it. Usually, a CI is attached with a Repository or Codebase and all the changes are merged before starting it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is meant by CD ?
&lt;/h3&gt;

&lt;p&gt;CD stands for &lt;strong&gt;&lt;em&gt;Continuous Delivery&lt;/em&gt;&lt;/strong&gt;, which is an automated process of deploying and making the application available successfully to use. The CD process is started only when the application has passed through the integration process and tested with no critical issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD for Android App
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1pqpqpx3ksbq3tif8j0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1pqpqpx3ksbq3tif8j0.png" alt="Pasted image 20230626231334" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Figure: CI/CD Pipeline Architecture for Android)&lt;/p&gt;

&lt;h1&gt;
  
  
  CI pipeline
&lt;/h1&gt;

&lt;p&gt;Now let us design our CI pipeline flow so that we are clear what we want to achieve. For any Android project I would recommend the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android Lint Check&lt;/li&gt;
&lt;li&gt;Unit Tests&lt;/li&gt;
&lt;li&gt;Instrumentation Tests&lt;/li&gt;
&lt;li&gt;Static Code Analysis&lt;/li&gt;
&lt;li&gt;Build Debug apk (Packaging)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Setup GitHub Actions for repository
&lt;/h3&gt;

&lt;p&gt;To add GitHub Actions workflow file to your repository you need to create a yaml file &lt;code&gt;.github/workflows/ci.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout the code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run sample script&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo Hello, world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;name&lt;/strong&gt; - refers the action name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;on push, pull_request&lt;/strong&gt; - It states the branch to be used for CI process when push or pull_request to the specified branch happens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jobs&lt;/strong&gt; - used for specifying the jobs to be performed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sample&lt;/strong&gt; - the name of job to be performed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;runs-on&lt;/strong&gt; - it specifies on which serves should the process be performed &lt;em&gt;say ubuntu&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;steps&lt;/strong&gt; &lt;strong&gt;(name, uses)&lt;/strong&gt; - Each step has its own name and uses, and the first step should be to checkout the code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Perform Android Lint check
&lt;/h3&gt;

&lt;p&gt;🤔 &lt;em&gt;What is meant by Lint ?&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;😎 &lt;em&gt;The lint tool checks your Android project source files for potential bugs and optimization improvements for correctness, security, performance, usability, accessibility, and internationalization. Basically it's an basic code correction and suggestion tool&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now that our basic configuration is in place, we will add Lint check as our first job. Let us understand what the following configuration does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;code&gt;runs-on: ubuntu-latest&lt;/code&gt; tells to run the job on latest ubuntu machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;code&gt;actions/checkout@v2&lt;/code&gt; action checks out the codebase on the machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; Once we have the codebase on the machine, run &lt;code&gt;./gradlew lintDebug&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 4:&lt;/strong&gt; Publish the lint report as a github artifact&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Perform lint check&lt;/span&gt;
  &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout the code&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run lint&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew lintDebug&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload html test report&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lint.html&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/build/reports/lint-results-debug.html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;with&lt;/strong&gt; - it uploads the artifact as the specified name to the path&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Perform Android Unit Tests
&lt;/h3&gt;

&lt;p&gt;🤔 &lt;em&gt;What is meant by Unit Testing ?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;😎 &lt;em&gt;Unit tests in Android are used to test individual units or components of an application in isolation. These tests focus on verifying the functionality of a specific class, method, or module without external dependencies.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Unit Tests reference: &lt;a href="https://developer.android.com/training/testing/local-tests" rel="noopener noreferrer"&gt;https://developer.android.com/training/testing/local-tests&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our second job would be to run the unit tests. This job will run after the &lt;code&gt;lint&lt;/code&gt; job and that is why you see &lt;code&gt;needs: [lint]&lt;/code&gt; in the below config.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;code&gt;runs-on: ubuntu-latest&lt;/code&gt; tells to run the job on latest ubuntu machine&lt;br&gt; &lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;code&gt;actions/checkout@v2&lt;/code&gt; action checks out the codebase on the machine &lt;br&gt; &lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; Run &lt;code&gt;./gradlew test&lt;/code&gt; will run the unit tests&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 4:&lt;/strong&gt; Publish the test report folder as a github artifact&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;unit-test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Perform Unit Testing&lt;/span&gt;
  &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout the code&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew test&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload test report&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions.upload-artifact@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unit_test_report&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/build/reports/test/testDebugUnitTest/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;needs&lt;/strong&gt; - the keyword states that the current job as to be executed only when the specified job is been completed &lt;em&gt;say lint&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Perform Android Instrumentation Tests
&lt;/h3&gt;

&lt;p&gt;🤔 &lt;em&gt;What is meant by Instrumnetation Testing in Android ?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;😎 &lt;em&gt;Instrumentation tests in Android are used to test the behavior of an application in a real device or emulator environment. These tests simulate user interactions and validate the integration between different components of the application. It also includes UI testing and functionality binding with UI&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Our 3rd job would run Android instrumentation tests. We are running this job on mac-latest machine. That is because the modern Intel Atom (x86 and x86_64) emulators require hardware acceleration from the host to run fast. The macOS VM provided by GitHub Actions has HAXM installed so we are able to create a new AVD instance, launch an emulator with hardware acceleration, and run our Android tests directly on the VM.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important:&lt;/strong&gt; Since macOS machines hosted by GitHub consumes more time compared to Linux and Windows machine. Make sure that you don't consume more amount of time spending instrumentation test, exceeding free plan. Checkout this official page for more reference: &lt;a href="https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#minute-multipliers" rel="noopener noreferrer"&gt;GitHub Actions Minute multipliers&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A 3rd party tool would be used for running Android Emulators &lt;code&gt;reactivecircus/android-emulator-runner@v2&lt;/code&gt; and running the instrumentation tests using &lt;code&gt;./gradlew connectedCheck&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;instrumentation-test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Perform Instrumentation Testing&lt;/span&gt;
  &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;macos-latest&lt;/span&gt; &lt;span class="c1"&gt;# MacOS runs faster&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout the code&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="c1"&gt;# Gradle v8.0.0 requires java JDK v17&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Java JDK &lt;/span&gt;&lt;span class="m"&gt;17&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-java@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;17'&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run espresso tests&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reactivecircus/android-emulator-runner@v2&lt;/span&gt; &lt;span class="c1"&gt;# 3rd party tool&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;api-level&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;29&lt;/span&gt;
        &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew connectedCheck&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload Instrumentation Test report&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;instrumentation_test_report&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/build/reports/androidTests/connected&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Static Code Analysis using Sonarqube
&lt;/h3&gt;

&lt;p&gt;🤔 &lt;em&gt;How can check my code quality using external tools ?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;😎 &lt;em&gt;Static code analysis is a technique used to analyze the source code of a program without actually executing it. It helps identify potential bugs, security vulnerabilities, code smells, and other issues in the codebase. Static code analysis tools analyze the code for patterns, best practices, and potential issues based on predefined rules or heuristics&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In order to perform Static Code Analaysis, we will be using &lt;a href="https://www.sonarsource.com/products/sonarqube/" rel="noopener noreferrer"&gt;Sonarqube&lt;/a&gt; and SonarCloud. The minimum version required for sonar scanner is Java 11 and that is why you see a step to setup Java 11 jdk on the machine. To utilize Sonar scanner for analyzing code, a new account and project has to be created in &lt;a href="https://sonarcloud.io/" rel="noopener noreferrer"&gt;Sonarcloud&lt;/a&gt; to integrate with GitHub Actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;code&gt;runs-on: ubuntu-latest&lt;/code&gt; tells to run the job on latest ubuntu machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;code&gt;actions/checkout@v2&lt;/code&gt; action checks out the codebase on the machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; Modify &lt;code&gt;gradle.properties&lt;/code&gt; with sonarcloud project details&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 4:&lt;/strong&gt; Create a &lt;code&gt;SONAR_TOKEN&lt;/code&gt; for the project in Sonarcloud website&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 5:&lt;/strong&gt; Add the token to GitHub secrets and title with desired token name&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 6:&lt;/strong&gt; Run &lt;code&gt;./gradlew app:sonarqube -Dsonar.login=${{ secrets.SONAR_TOKEN }}&lt;/code&gt; to allow sonarqube to scand and perform code analysis&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Add the following code to &lt;code&gt;gradle.properties&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;...&lt;/span&gt;
&lt;span class="c"&gt;# Sonarqube
&lt;/span&gt;&lt;span class="py"&gt;systemProp.sonar.sources&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;./src/main&lt;/span&gt;
&lt;span class="py"&gt;systemProp.sonar.host.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://sonarcloud.io/&lt;/span&gt;
&lt;span class="py"&gt;systemProp.sonar.organization&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;tharunbalaji2004  # As per your sonarcloud profile&lt;/span&gt;
&lt;span class="py"&gt;systemProp.sonar.projectKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;TharunBalaji2004_android-ci-cd  # As per your sonarcloud profile&lt;/span&gt;
&lt;span class="py"&gt;systemProp.sonar.projectName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;android-ci-cd  # As per your sonarcloud profile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running sonar cloud scan command in &lt;code&gt;ci.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;static-code-analysis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Perform static code analysis&lt;/span&gt;
  &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout the code&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Java JDK &lt;/span&gt;&lt;span class="m"&gt;17&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-java@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;17'&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SonarCloud Scan&lt;/span&gt; &lt;span class="c1"&gt;# sonarcloud properties in gradle.properties file&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew app:sonarqube -Dsonar.login=${{ secrets.SONAR_TOKEN }}&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Build Debug APK
&lt;/h3&gt;

&lt;p&gt;Reaching the last section of &lt;strong&gt;Android CI&lt;/strong&gt; Pipeline 😎✅&lt;/p&gt;

&lt;p&gt;The last step of Android CI ends with building up &lt;code&gt;.apk&lt;/code&gt; debug package after passing all tests along the pipeline.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;code&gt;runs-on: ubuntu-latest&lt;/code&gt; tells to run the job on latest ubuntu machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;code&gt;actions/checkout@v2&lt;/code&gt; action checks out the codebase on the machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; Once we have the codebase on the machine, run &lt;code&gt;./gradlew assembleDebug --stacktrace&lt;/code&gt; &lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 4:&lt;/strong&gt; Upload the apk packkage to GitHub as artifact&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;debug-apk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate Debug APK&lt;/span&gt;
  &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout the code&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Java JDK &lt;/span&gt;&lt;span class="m"&gt;17&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-java@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;17'&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build debug APK&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew assembleDebug --stacktrace&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload APK&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sample-app.apk&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/build/outputs/apk/debug/app-debug.apk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  CD pipeline
&lt;/h1&gt;

&lt;p&gt;After lots of testing and validating the debug apk, lets design our CD pipeline. This involves creating release package to public users. I would recommend these methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Functional Testing&lt;/li&gt;
&lt;li&gt;Build signed APK&lt;/li&gt;
&lt;li&gt;Build signed AAB
&lt;/li&gt;
&lt;li&gt;Deploy app using Google Play Console&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Functional Testing
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Functional testing for Android applications involves testing the application's functionality to ensure that it meets the desired requirements and behaves correctly. It also covers app UI testing, Navigation testing, Performance and Compatability Testing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To perform functional testing for Android applications, you can use various tools and frameworks, such as Espresso, UI Automator, Appium, and Robolectric. These tools assist in automating the testing process and provide features for simulating user interactions, capturing test results, and generating reports. Also considering real-world scenarios and user workflows to ensure the application meets user expectations and delivers a positive user experience.&lt;/p&gt;

&lt;p&gt;🚧 Working on it 🚧&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Build signed APK
&lt;/h3&gt;

&lt;p&gt;🤔 &lt;em&gt;Signing process of APKs&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;😎 &lt;em&gt;Signing an APK (Android Package) is the process of adding a digital signature to the APK file. The digital signature serves as a way to verify the authenticity and integrity of the APK and ensure that it has not been tampered with since it was signed. The signing process involves generating a private key and a corresponding public key certificate&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now lets create a new workflow &lt;code&gt;.yaml&lt;/code&gt; file for CD pipeline, we will be building signed release &lt;code&gt;.apk&lt;/code&gt; as out first job. Lets discuss about signing the apk:  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;code&gt;runs-on: ubuntu-latest&lt;/code&gt; tells to run the job on latest ubuntu machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;code&gt;actions/checkout@v2&lt;/code&gt; action checks out the codebase on the machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; Once we have the codebase on the machine, run &lt;code&gt;./gradlew assembleRelease&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 4:&lt;/strong&gt; Using &lt;code&gt;r0adkll/sign-android-release@v1&lt;/code&gt; sign the app from secret variables&lt;/p&gt;

&lt;p&gt;Add GitHub Actions CD workflow file to your repository you need to create a yaml file &lt;code&gt;.github/workflows/cd.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Release signed APK&lt;/span&gt;
  &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout the code&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up JDK&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-java@v3&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;distribution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;temurin&lt;/span&gt;
        &lt;span class="na"&gt;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;17'&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Release APK&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew assembleRelease&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Sign APK&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;r0adkll/sign-android-release@v1&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sign_app&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;releaseDirectory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/build/outputs/apk/release&lt;/span&gt;
        &lt;span class="na"&gt;signingKeyBase64&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SIGNING_KEY }}&lt;/span&gt;
        &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.KEY_ALIAS }}&lt;/span&gt;
        &lt;span class="na"&gt;keyStorePassword&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.KEY_STORE_PASSWORD }}&lt;/span&gt;
        &lt;span class="na"&gt;keyPassword&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.KEY_PASSWORD }}&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;BUILD_TOOLS_VERSION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;30.0.2"&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload Signed APK&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sample-app-signed&lt;/span&gt;  &lt;span class="c1"&gt;# Artifact Name&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/build/outputs/apk/release/*.apk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Build signed AAB
&lt;/h3&gt;

&lt;p&gt;🤔 &lt;em&gt;What does Android Application Bundle(AAB) mean ?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;😎 &lt;em&gt;AAB stands for Android App Bundle. It is a publishing format introduced by Google for Android applications, developers can use the AAB format to publish their apps on the Google Play Store. It also allows for more efficient updates and enables developers to take advantage of dynamic delivery features provided by the Google Play Store&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now lets create a new workflow &lt;code&gt;.yaml&lt;/code&gt; file for CD pipeline, we will be building signed release &lt;code&gt;.aab&lt;/code&gt; as out first job. Lets discuss about signing the bundle:  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;code&gt;runs-on: ubuntu-latest&lt;/code&gt; tells to run the job on latest ubuntu machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;code&gt;actions/checkout@v2&lt;/code&gt; action checks out the codebase on the machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; Once we have the codebase on the machine, run &lt;code&gt;./gradlew assembleRelease&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 4:&lt;/strong&gt; Using &lt;code&gt;r0adkll/sign-android-release@v1&lt;/code&gt; sign the app from secret variables&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;bundle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Release AAB&lt;/span&gt;
  &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout the code&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up JDK&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-java@v3&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;distribution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;temurin&lt;/span&gt;
        &lt;span class="na"&gt;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;17'&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Release AAB&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew bundleRelease&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Sign app bundle&lt;/span&gt;      
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;r0adkll/sign-android-release@v1&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sign_app&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;releaseDirectory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/build/outputs/bundle/release&lt;/span&gt;
        &lt;span class="na"&gt;signingKeyBase64&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SIGNING_KEY }}&lt;/span&gt;
        &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.KEY_ALIAS }}&lt;/span&gt;
        &lt;span class="na"&gt;keyStorePassword&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.KEY_STORE_PASSWORD }}&lt;/span&gt;
        &lt;span class="na"&gt;keyPassword&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.KEY_PASSWORD }}&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;BUILD_TOOLS_VERSION&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;30.0.2"&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload Signed AAB&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sample-app-bundle&lt;/span&gt;  &lt;span class="c1"&gt;# Artifact Name&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/build/outputs/bundle/release/app-release.aab&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Deploy app using Google Play Console
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;For making a release to PlayStore, we need a service account json file, which is created from Google Play Console. And Play Store publisher permission access, which is created from Google Cloud. Kindy refer this &lt;a href="https://www.skoumal.com/en/generate-json-key-for-google-play-deployment/" rel="noopener noreferrer"&gt;article&lt;/a&gt; to create service account and grant permission for CD pipeline to deploy in play store&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After creating the service account &lt;code&gt;.json&lt;/code&gt; file, upload it to GitHub secrets and specify the value in workflow file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;code&gt;runs-on: ubuntu-latest&lt;/code&gt; tells to run the job on latest ubuntu machine&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; Specify the service account json secret file&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; Using predefined action &lt;code&gt;r0adkll/upload-google-play@v1&lt;/code&gt; to deploy app on playstore&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy release AAB on Playstore&lt;/span&gt;
  &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create service_account.json&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo '${{ secrets.SERVICE_ACCOUNT_JSON }}' &amp;gt; service_account.json&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Play Store&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;r0adkll/upload-google-play@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;serviceAccountJson&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_account.json&lt;/span&gt;
        &lt;span class="na"&gt;packageName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.inputs.app_id }}&lt;/span&gt;
        &lt;span class="na"&gt;releaseFiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/build/outputs/bundle/release/*.aab&lt;/span&gt;
        &lt;span class="na"&gt;track&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thats it! Congrats for deploying you Android app on Play Store 😀✅&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>githubactions</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
