BLogic Systems

Jenkins With Android

Last updated on 
Integrate Jenkins with android project

Targets

  • We will using to build and publish apk file as artifact

Get Started

Setup your android project gradle and build variants

Generate Signed key

  • Except Debug build you wouldn’t need signed key. But with other (Release, Staging) you must having one. Follow this link to guide how to generate Signed Key. #### Adding Build variants and link it with signed key
  • Your build.gradle of app should look like this
signingConfigs {
        staging {
            // You need to specify either an absolute path or include the
            // keystore file in the same directory as the build.gradle file.
            // You should copy signed key into app folder if you want to build it locally
            storeFile file("<signed-key-file>")
            storePassword "<signed-key-password>"
            keyAlias "<signed-key-alias>"
            keyPassword "<signed-key-password>"
        }

        release {
            // You need to specify either an absolute path or include the
            // keystore file in the same directory as the build.gradle file.
            // You should copy signed key into app folder if you want to build it locally

            storeFile file("<signed-key-file>")
            storePassword "<signed-key-password>"
            keyAlias "<signed-key-alias>"
            keyPassword "<signed-key-password>"
        }
    }

    buildTypes {
        staging {
            signingConfig signingConfigs.staging
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }

        release {
            signingConfig signingConfigs.release
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

Test build APK locally

  • Go to terminal, access to project root directory
  • Run .\gradlew assembleStaging or .\gradlew assembleRelease
  • That is all, now you can check apk file in output folder

Build and Publish with jenkins

Setup Jenkins Project

  • Create freestyle project
  • Setup your git repo
  • Build steps add Execute shell

In Build Environment > Use secret text(s) or file(s) > Secret file you can add your keystore file, add Credential file.

image.png
#!/bin/bash
# overwrite JAVA_HOME because if SDK-version > 30 it require JDK17
export JAVA_HOME="/opt/java/openjdk17/jdk-17.0.8"
echo "Copy keystore"
cp $KEYSTORE_PATH ./app/BlogicBookingPayKeyStore.staging.jks
chmod a+x ./gradlew

./gradlew clean
echo "Building"
./gradlew assembleStaging

echo "Rename Build APK"
mv "./app/build/outputs/apk/staging/app-staging.apk" "app/build/outputs/apk/staging/app-staging-$BUILD_ID.apk"
  • And greate that is all for the Build

Edit artifact path in Post-build Action

screenshot_2023-09-21_170113.png

Troubleshooting

  • If you having any problems relate to SDK versions and SDK Build versions, you must install that sdk package for jenkin manual
  • Before install sdk for jenkin you need to know your compileSdk targetSdk in your build.gradle file. This stand for SDK Build version and SDK version
  • Next you must access to jenkin docker with bash, and move to /usr/lib/android-sdk/cmdline-tools/latest/bin directory, run ./sdkmanager --list now you can see all SDKs, and Build versions available to download. Find your SDK, Build tags name. Run ./sdkmanager "<tag-name>" to Install your SDK version
  • Now your jenkin can build your SDK version

Build with multiple env configs

  • One implement i will recommend to run variant configs file with multiple environments
    • Adding new json access files for variant environment Example: configs.staging.json
    • Create class model for config
    • Add Utility class to load config by current environment
    • Now you at the top of Launching activity on onCreate method, you must call AppEnvConfigUtility.configuration(getApplicationContext()) before you can use AppEnvConfigUtility.getInstance()

Follow the steps:

{
  "hostUrl": "http://192.168.1.194:5110/",
  "debuggable": true
  }
public class AppConfig {
  @SerializedName("hostUrl")
  @Expose
  public String hostUrl;

  @SerializedName("debuggable")
  @Expose
  public Boolean debuggable = false;
  }
public class AppEnvConfigUtility {
  public static AppEnvConfigUtility mInstance;
  public static final String BUILD_DEBUG = "debug";
  public static final String BUILD_STAGING = "staging";
  public static final String BUILD_RELEASE = "release";

  public AppConfig mAppConfig;

  public static AppEnvConfigUtility getInstance() {
      return mInstance;
  }

  public static AppEnvConfigUtility configuration(Context context)  {
      if(mInstance != null) {
          return mInstance;
      }
      String configFileName;
      if (BuildConfig.BUILD_TYPE.equals(BUILD_DEBUG)) {
          configFileName = "configs.development.json";
      } else if (BuildConfig.BUILD_TYPE.equals(BUILD_STAGING)) {
          configFileName = "configs.staging.json";
      } else {
          configFileName = "configs.release.json";
      }

      InputStream inputStream = null;
      try {
          inputStream = context.getAssets().open(configFileName);
      } catch (IOException e) {
          throw new RuntimeException("Could not load config file for build " + BuildConfig.BUILD_TYPE);
      }

      Gson gson = new Gson();
      InputStreamReader reader = new InputStreamReader(inputStream);
      mInstance = new AppEnvConfigUtility();
      mInstance.mAppConfig = gson.fromJson(reader, AppConfig.class);

      return mInstance;
  }

  }