Android学习

从Github Action入门自动化技术也太轻松了吧!

2021-09-27  本文已影响0人  九心_

前言

谈起 CI/CD,很多同学的表情可能是这样的?

怎么说,身为 Android 开发,很多同学对 CI/CD 的了解少之又少,其实借助 CI/CD,可以做不少有趣的事。

首先,我们得了解什么是 CI/CD?

CI/CD 包括 CI 和 CD。

CI(Continuous Interaction)是持续集成的意思,它是属于开发人员的自动化流程。在当今的 Android 开发模式中,多人同时维护一个项目已在所难免,所以,每次提交代码后,我们可以让机器去做些什么去维护我们项目的安全性和稳定性?其实上面的图中已经给出答案,当我们提交一份代码后,自动化工具就会触发构建、测试,这些都完成以后,再帮我们合并代码。

CD 通常有两层意思,一层是(Continuous Delivery),它代表着持续交付,当开发人员提交代码后,自动化工具会会自动进行错误测试并上传到存储库,最后由运维团队将其部署在实时的生产环境中。另一层是(Continuous Deployment),它代表着持续部署,是将存储库发布到生产环境。

听完上面的解释,各位 Android 开发仔能弄懂 CI/CD 吗?

显然不能啊,这有关系吗,没关系,反正是从入门到放弃, :)

CI 还比较好理解,用实际的 Android 经验来解释就是,持续交付就是将更新后的 Master 分支代码打包成各个应用市场需要的渠道包,持续部署就是将上一步打好的包,自动上传到对应的应用市场。

CI/CD对Android开发的意义

首先,CI 对于开发人员来说,可以及早的发现错误,每当我们提交一笔代码,自动化工具就会发起构建、自动化测试,最终会合入代码,保证我们项目的稳定性。别代码提上去了,编都编不过,还吭呲吭呲往下写!

其次,对于运维人员来说,CD 可以提升他们的工作效率,自动化工具可以减少他们不必要的工作量。

这个意义有点笼统,放到Android上来讲:

  1. 标准化管理Android项目
  2. 自动触发多渠道打包
  3. 自动上传到应用市场应该也是可以的,我看到一些平台可以把我们的app一键上传到各个应用市场。
  4. 我最近研究的组件化下自动上传AAR
  5. 以及组内大佬医生分享的精准化测试系列
  6. ...

CI/CD 工具帮了我们不少忙。

看这里,Bugly 也建议我们将符号表的上传放入持续集成中。

最常见的持续集成工具应该是 Jenkins,因为它开源并且免费,你想要的插件在开源社区几乎都可以找到,起点之前也是用的 Jenkins,也就最近,才开始从 Jenkins 迁移到腾讯内部的蓝盾。

不过,本次的主角并不是 Jenkins。

Github Action 简介

没错,本次的主角就是 Github Action,官方是这么介绍的:

在 GitHub Actions 的仓库中自动化、自定义和执行软件开发工作流程。 您可以发现、创建和共享操作以执行您喜欢的任何作业(包括 CI/CD),并将操作合并到完全自定义的工作流程中。

所以,Github Actions 是 Github 的持续集成服务,那么它和其他的持续集成工具有什么不同呢?

所有的一系列操作例如设置 JDK、运行 Shell 命令或者是执行自动化测试都被称之为 Action,像设置JDK Action 肯定通用的,所以就有了免费的 Github Action 市场,允许开发者将他们封装的 Action 上传到市场,其他开发者需要的时候引用即可。

可以看到,当前市场的 Action 已经快1W个了,能够满足开发的日常需求。

除此以外,Github Action 也为通用的一些项目提供了模板,当我们点击自己项目的 Action 的时候,它会给你推荐一些模板:

image.png

也允许你自己选择一些热门的模板。

语法简介

看到这儿,很多同学都已经开始跃跃欲试了,别急,我们再介绍一下语法!

理解了这些名词,我们再了解一下它们之间的关系:

一个 WorkFlow 由 Event 和 Jobs 组成,每个 Job 由 Runner 和 一系列 Step 组成,每个 Step 都由 Action 或者 Shell Command 组成。

有了一定的了解以后,我们看看语法。

Github Action 的配置文件叫做 WorkFlow 文件,存放在代码仓库的 .github/workflows 目录,该文件采用的 yaml 语法。

我们使用一个默认的 Android 模板,看看它是什么样子的:

name: Android CI # 设置 WorkFlow 名称

on: # 设置 Event,
  push:
    branches: [ master ] 
  pull_request:
    branches: [ master ]

jobs:
  build: # 设置 Job 的名称

    runs-on: ubuntu-latest # 设置服务器

    steps:
    - uses: actions/checkout@v2 # Action 获取当前分支的源码
    - name: set up JDK 11 # Action 设置 JDK
      uses: actions/setup-java@v2
      with: # 参数由 Action 的创建者指定,需要查看创建者的文档
        java-version: '11'
        distribution: 'adopt'
        cache: gradle

    - name: Grant execute permission for gradlew # Shell Command 
      run: chmod +x gradlew
    - name: Build with Gradle
      run: ./gradlew build

从上往下解释:

名词 解释
name 设置 WorkFlow 的名字
on 设置 Event,比如上面的 on.push.branches: [ master ],代表着触发的时机是 master 分支发生 push 的时候
jobs 声明 Jobs,上述中 jobs 下的 build 字段,则是创建一个 Job,也是该 Job 的名称
runs-on 声明 Runner,也就是服务器,支持 Windows、MacOS 和 Ubuntu,不过需要指定版本
steps 声明 Steps
steps.- - 代表着当前是一个 Step
steps.name 当前 Step 的名称
steps.uses 使用市场中的 Action
steps.run 执行 Shell 命令

有了名词解释,我们就能明白上面的 Android 模板的大致过程。

Android 实践

我们有了一定的基础,借助这些,就可以做些有趣的东西的了!

试想一下,当我们往 master 分支合入代码的时候,是不是就要发版了,这个时候,持续集成可以帮我们构建项目,之后根据需要,使用生成好的Apk进行加固、多渠道打包、上传备份文件,最后发出成功或者失败的消息。

那同样的,我们可以在上面的示例中做一些修改,加入上传APK、将结果发送给邮件和钉钉的群。

以我的 AndroidGithubAction 为例,完整的教程是这样的:

1. 创建一个Action

选中 Github 项目中的 Action 栏,我们将会见到下面的内容:

根据需要选择自定义方式或者模板方式,这里我们选择 Android 模板。

2. 修改模版

模板的内容我在上面已经发过了,修改一下:

  1. 最外层的 name 可改可不改。
  2. Event 修改为 push 的时候触发即可。
  3. 修改一下 Gradle 命令。

修改完的内容:

name: Android CI

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    
    - uses: actions/checkout@v2  # 拉取源代码
    
    - name: set up JDK 1.8 # 设置JDK
      uses: actions/setup-java@v2
      with:
        java-version: 8.0.232+9.1
        distribution: 'adopt'
        cache: gradle

    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
      
    - name: Build with Gradle # 执行编译命令
      run: ./gradlew clean && ./gradlew app:assembleDebug

3. 上传APK

先说明一下,编写 WorkFlow 时,左边是编写 WorkFlow 的面板,右边就可以直接在市场上搜索你想使用的Action。

image.png

选中想使用的 Action,就会跳出详细的说明文档。

下面这个就是我们想使用的 Action。

有了它,我们可以上传编译完的 apk,可以在多个 job 之间共享,或者等持续集成运行结束的时候,可以下载生成的产物。

引入代码:

- name: Upload Apk
  uses: actions/upload-artifact@v1
  with: 
    name: qd-info
    path: app/build/outputs/apk/debug/app-debug.apk

4. 上传APK到第三方平台

很多情况下需要将产物上传到第三方平台,以蒲公英为例:

- name: Upload File to Pgyer
  run: curl -F 'file=@app/build/outputs/apk/debug/app-debug.apk' -F "_api_key=${{ secrets.API_KEY }}" -F "uKey=${{ secrets.PGYER_USER_KEY }}" -F "buildInstallType=3" https://www.pgyer.com/apiv2/app/upload

这里面涉及了两个知识点,一是 curl 工具的使用,二是 Github Action 中隐私信息的用法。

curl 是用来请求Web服务器的命令行工具,curl 使用可参考阮一峰的文章:

《curl 的用法指南》

对于一些关键的 key,我们可能不太想将 key 暴露在 Github Action 的 workflow 文件中,Github 推荐我们将这些 key 存在 Secrets 中,添加入口:

5. 获取构建人

上传完成后,我们会将编译信息、版本信息、Commit日志发送到企业微信、钉钉或者邮箱。

首先是获取构建人信息,默认的环境变量提供如下:

但是我发现在 curl 命令中有点问题,报了识别不了的错误:

于是就把触发人写在了全局变量中:

# 获取发送者
- name: Sender
  run: echo "sender=$GITHUB_ACTOR" >> $GITHUB_ENV

之后通过${{ env.sender }} 获取。

6. 获取版本信息

版本信息我是通过 grep 命令在 app 目录下的 build.gradle 文件获取

如果你有更好的方法,欢迎评论区交流~

同样是写到全局变量中:

# step: 获取apk版本号
- name: APK Version
  id: apk_version
  run: |
        versionCode=`grep "versionCode" app/build.gradle | awk -F " " '{print $2}'`
        versionName=`grep "versionName" app/build.gradle | awk -F ''\"'' '{print $2}'`
        echo "versionResult=$versionName.$versionCode"  >> $GITHUB_ENV  

在 Github Action 中,如果需要运行多条命令,需要在 run: 后面加上一个 |

7. 获取提交日志

获取提交日志就比较简单了,通过 git log 就能获取:

# 获取git log
- name: Get git log
  id: git_log
  run: |
        updateLog=`git log --pretty=format:"%s" -1`
        echo "updateLog=$updateLog" >> $GITHUB_ENV

该命令是获取最近的提交记录的日志,以指定格式输出。

8. 发送到钉钉群中的小机器人

钉钉小机器人的使用说明就不介绍了,直接看官网,命令如下:

# 向钉钉发送消息
- name: dingtalk
  run: | 
        curl '${{ secrets.DINGDING_WEBHOOK }}' -H 'Content-Type: application/json' -d '{"msgtype": "text", "text": {"content":"吃饭! \n触发人:${{ env.sender }} \n版本:${{ env.versionResult }} \n提交内容:${{ env.updateLog }} \n下载地址:${{ secrets.PGY_URL }}"}}'

构建成功后发送到群里的截图:

9. 发送邮件

通常情况下,触发人编译失败后是会收到失败邮件的,如果不够,我们可以再写一个发送邮件的 Action

我们这里引用其他人开源的 Action:

# 发送邮件
- name: Send mail
  uses: dawidd6/action-send-mail@v3
  with:
    server_address: smtp.qq.com
    server_port: 465
    username: ${{ secrets.MAILUSERNAME }}
    password: ${{ secrets.MAILPASSWORD }}
    subject: Github Actions job result
    to: 2556536414@qq.com
    from: TeaOf 
    secure: true
    body: "吃饭! \n触发人:${{ env.sender }} \n版本:${{ env.versionResult }} \n提交内容:${{ env.updateLog }} \n下载地址:${{ secrets.PGY_URL }}"

这一步做完,差不多就结束了。

完整代码地址:https://github.com/mCyp/AndroidGithubAction/blob/main/.github/workflows/android.yml

总结

对于开源用户来说,Github Action 还有一些比较常见的使用场景。

比如利用 Github Action 自动部署 Hexo 博客,还记得以前使用 Github Page 建立个人博客的时候,每次新增一篇文章以后,要输入一串命令行,有了 Github Action,这些都可以自动执行。

还有,很多人的 Github Porfile 是依赖 Github Action 自动更新的,像这位外国老哥:

他的 Profile 每三个小时会自动获取一下最新的个人文章和社交媒体,展示在自己的个人简介上,这个效果确实很赞!最近有时间,打算也来搞一套。

参考

《Github Actions 使用指南和Android 持续集成示例》
《GitHub Actions 入门教程》

上一篇 下一篇

猜你喜欢

热点阅读