Operations 6 min read

Android CI/CD Pipeline with Jenkins and Automated APK Upload to Fir.im and Pgyer

This guide explains how to configure an Android project, write Python upload scripts for Fir.im and Pgyer, create a Jenkinsfile with checkout, build, and upload stages, set up Jenkins global variables and pipeline parameters, and run a full build‑test cycle to publish APKs via QR codes.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
Android CI/CD Pipeline with Jenkins and Automated APK Upload to Fir.im and Pgyer

1. Project configuration: define the package storage path (app/build/outputs/apk/[debug|release]) and create upload scripts that support both Fir.im and Pgyer platforms.

1.2 Upload script (Python) – reference the Fir.im and Pgyer API documentation, obtain the upload certificate from cert.binary, and upload the APK using HTTP POST requests.

#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: defines three stages – Checkout (retrieve code), Build (run Gradle to assemble the APK), and Upload (rename the APK and invoke 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: add a global Android SDK variable via System Settings, create a pipeline, and configure parameters such as buildShell (debug or release Gradle commands), bundleId, apiToken, apkVersion, and apkName.

4. Build test: demonstrates the steps of checking out the code, building the APK, and publishing it to Fir.im and Pgyer, with QR code screenshots for each platform.

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/cdAndroidAutomationDevOpsAPKJenkins
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.