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.
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 fir1.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 - "\n"
println(result)
currentBuild.description="
"
}
}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.
DevOps Cloud Academy
Exploring industry DevOps practices and technical expertise.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.