由于需求不一致,有的时候需要给所有应用商店打包,有的时候需要指定应用商店打包,所以在gitlab-ci文件里面需要将构建单独的应用商店的job全部列出来,在加上构建所有应用商店的job,一共13个job。打包完apk需要上传到oss上,并给相关的人员发送邮件,这部分用Python来实现的。
gitlab-ci.yaml文件如下:
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false" # 禁用 gradle 守护进程
before_script:
# 配置 gradle 的缓存目录
- export GRADLE_USER_HOME=cache/.gradle
# 获取权限
- chmod +x ./gradlew
stages:
- 构建apk包
- uploadOssAndSendMail
.构建apk: &buildApk
stage: 构建apk包
tags:
- android
only:
- /^release-pro-.*$/
artifacts:
paths:
# 设置输出路径
- app/build/outputs/
构建所有apk包:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleRelease
木蚂蚁:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleMumayiRelease
联想:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleLianxiangRelease
酷安:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleKuanRelease
阿里:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleAliRelease
应用宝:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleYingyongbaoRelease
oppo:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleOppoRelease
华为:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleHuaweiRelease
vivo:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleVivoRelease
百度:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleBaiduRelease
三星:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleSanxingRelease
魅族:
<<: *buildApk
when: manual
script:
# 创建apk输出路径
- mkdir -p app/build/outputs
- ./gradlew assembleMeizuRelease
uploadOssAndSendMail:
stage: uploadOssAndSendMail
tags:
- android
when: manual
only:
- /^release-pro-.*$/
script:
- cd app/build/outputs
- /usr/bin/python3 /home/gitlab-runner/zip_GetUrl_SendMail.py
- rm -rf *
编写python文件实现apk文件压缩打包,并上传到指定oss上,并给相关人员发送邮件,对应人员在邮件中点击下载链接即可对apk的压缩文件进行下载。
import oss2
import zipfile
import os
import datetime
from smtplib import SMTP_SSL
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
access_key_id = 'my_key_id'
access_key_secret = 'my_key_secret'
bucket_name = 'my_bucket_name'
endpoint = 'https://oss-cn-xxx.aliyuncs.com'
filename = "apk-" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + ".zip"
oss_file_path = "apk/" + filename
def zipDir(dirpath, outFullName):
"""
压缩指定文件夹
:param dirpath: 目标文件夹路径
:param outFullName: 压缩文件保存路径+xxxx.zip
:return: 无
"""
zip = zipfile.ZipFile(outFullName, "w", zipfile.ZIP_DEFLATED)
for path, dirnames, filenames in os.walk(dirpath):
# 去掉目标跟路径,只对目标文件夹下边的文件及文件夹进行压缩
fpath = path.replace(dirpath, '')
for filename in filenames:
zip.write(os.path.join(path, filename), os.path.join(fpath, filename))
zip.close()
def uploadOss_getUrl():
# 创建对象
bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)
# 上传
with open(filename, "rb") as fileobj:
# Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。
fileobj.seek(0, os.SEEK_SET)
# Tell方法用于返回当前位置。
current = fileobj.tell()
# 填写Object完整路径。Object完整路径中不能包含Bucket名称。
res = bucket.put_object("apk/" + filename, fileobj)
print(res)
file_url = "https://" + bucket_name + ".oss-cn-xxx.aliyuncs.com/apk/" + filename
print(file_url)
return file_url
def sendMail(url):
# smtplib模块主要负责发送邮件:是一个发送邮件的动作,连接邮箱服务器,登录邮箱,发送邮件(有发件人,收信人,邮件内容)。
# email模块主要负责构造邮件:指的是邮箱页面显示的一些构造,如发件人,收件人,主题,正文,附件等。
host_server = 'smtp.exmail.qq.com' # qq邮箱smtp服务器
sender_qq = 'xxx@xxx.com' # 发件人邮箱
pwd = 'password'
receiver = ['xxx@xxx.com',"xxx@xxx.com"] # 收件人邮箱
mail_title = '安卓apk打包成功' # 邮件标题
# 添加链接
html_data = f'''
<p>您好,安卓apk打包成功,请点击链接进行下载</p>
<p><a href='{url}'>点这里</a></p>
'''
# mail_content = "您好,安卓apk打包成功,请点击链接进行下载" + url # 邮件正文内容
# 初始化一个邮件主体
msg = MIMEMultipart()
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_qq
# msg["To"] = Header("测试邮箱",'utf-8')
msg['To'] = ";".join(receiver)
# 邮件正文内容
msg.attach(MIMEText(html_data, 'html', 'utf-8'))
smtp = SMTP_SSL(host_server) # ssl登录
# login(user,password):
# user:登录邮箱的用户名。
# password:登录邮箱的密码,像笔者用的是网易邮箱,网易邮箱一般是网页版,需要用到客户端密码,需要在网页版的网易邮箱中设置授权码,该授权码即为客户端密码。
smtp.login(sender_qq, pwd)
# sendmail(from_addr,to_addrs,msg,...):
# from_addr:邮件发送者地址
# to_addrs:邮件接收者地址。字符串列表['接收地址1','接收地址2','接收地址3',...]或'接收地址'
# msg:发送消息:邮件内容。一般是msg.as_string():as_string()是将msg(MIMEText对象或者MIMEMultipart对象)变为str。
smtp.sendmail(sender_qq, receiver, msg.as_string())
# quit():用于结束SMTP会话。
smtp.quit()
if __name__ == "__main__":
input_path = "./abc"
output_path = filename
zipDir(input_path, output_path)
url = uploadOss_getUrl()
sendMail(url)