Android Project Configuration and CI/CD Pipeline with Jenkins for APK Upload

This guide explains how to configure an Android project, write Python scripts for uploading APKs to Fir.im and Pgyer, create a Jenkinsfile with checkout, build, and upload stages, and set up Jenkins global variables and pipeline parameters for automated CI/CD deployment.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
Android Project Configuration and CI/CD Pipeline with Jenkins for APK Upload

1. Project Configuration

1.1 Project Structure – All build outputs are stored under app/build/outputs/apk/[debug|release].

1.2 Upload Script (supports Fir.im and Pgyer) – The script uses the Fir.im API or Pgyer API to obtain an upload token and then posts the APK file. The reference documentation for both platforms is listed.

#coding:utf8

import requests
import sys
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

class ApkManage(object):
    def __init__(self):
        self.url = "http://api.fir.im/apps"

    def getCert(self):
        dataargs = {'type' : 'android',
                    'bundle_id' : bundleid,
                    'api_token' : apitoken}
        response = requests.post(self.url,data=dataargs)
        cert = json.loads(response.text)
        return cert['cert']['binary']

    def uploadFir(self):
        certdata = self.getCert()
        try:
            print("upload apk to fir......")
            apkfile = {'file' : open(apkpath,'rb')}
            params = {"key"   : certdata['key'],
                      "token" : certdata['token'],
                      "x:name": appname ,
                      "x:build" : buildid,
                      "x:version" : appversion}
            response = requests.post(certdata['upload_url'],files=apkfile,data=params,verify=False)
            print(response.text)
            if int(response.status_code) == 200 :
                print("upload success!  return -->" + str(response.status_code))
            else:
                print("upload error! return -->" + str(response.status_code))
        except Exception as e:
            print("error: " + str(e))

    def uploadPgyer(self):
        url = 'https://qiniu-storage.pgyer.com/apiv1/app/upload'
        try:
            apkfile = {'file' : open(apkpath,'rb')}
            params = {"uKey" : '7b70873bb4d6xxxxx1d2ae5',
                      "_api_key" : 'a9acab611e1xxxxxxx5cae360a5ab'}
            response = requests.post(url,files=apkfile,data=params,verify=False)
            qrcodes = json.loads(response.text)['data']['appQRCodeURL']
            if int(response.status_code) == 200 :
                print(qrcodes)
            else:
                print("upload error! return -->" + str(response.status_code))
        except Exception as e:
            raise

if __name__ == '__main__':
    bundleid = sys.argv[1]
    apitoken = sys.argv[2]
    apkpath = sys.argv[3]
    appname = sys.argv[4]
    buildid = sys.argv[5]
    appversion = sys.argv[6]
    platform= sys.argv[7]
    server = ApkManage()
    if platform == 'fir':
        server.uploadFir()
    elif platform == 'pgyer':
        server.uploadPgyer()

Usage example:

python upapk.py demo-android-app-10 65d7edxxxxxxx7c4fabda25 app.apk  demo-android-app 10 10.12 fir

1.3 Jenkinsfile – The Jenkinsfile defines three stages: Checkout (retrieves the code), Build (executes Gradle commands), and Upload (renames the APK and calls the Python upload script).

node("master"){
  stage("Checkout"){
    checkout scm
  }

  stage("Build"){
    sh 'chmod +x ./gradlew '
    sh " ${params.buildShell} "
  }
  
  stage("Upload"){
      sh "mv app/build/outputs/apk/debug/app-debug.apk ./${params.apkName}.apk"
      def result
      result = sh returnStdout: true, script: """python uploadapk.py ${params.bundleId} \
                                                 ${params.apiToken} \"${params.apkName}.apk\" \
                                                 \"${params.apkName}\" \"${BUILD_ID}\" \
                                                 \"${params.apkVersion}\" \"${params.appPlatform}\" """
      result = result - "
"
      println(result)
      currentBuild.description="<img src=${result}>"
  }
}

2. Jenkins Configuration

2.1 Global Variables (Android SDK) – Set in Jenkins System Settings.

2.2 Create Pipeline – Define pipeline parameters such as buildShell (e.g., ./gradlew clean assembleDebug or ./gradlew clean assembleRelease), bundleId, apiToken, apkVersion, and apkName.

The guide also includes screenshots illustrating each step (checkout, build, upload, Fir platform, Pgyer platform, and QR code generation).

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Pythonci/cdAndroidautomationAPKJenkinsMobile Deployment
DevOps Cloud Academy
Written by

DevOps Cloud Academy

Exploring industry DevOps practices and technical expertise.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.