gitlab-ci添加安卓项目构建流程

慕宪
2023-12-01

描述:

由于需求不一致,有的时候需要给所有应用商店打包,有的时候需要指定应用商店打包,所以在gitlab-ci文件里面需要将构建单独的应用商店的job全部列出来,在加上构建所有应用商店的job,一共13个job。打包完apk需要上传到oss上,并给相关的人员发送邮件,这部分用Python来实现的。

编写gitlab-ci.yaml文件

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文件

编写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)
 类似资料: