從Github Action入門自動化技術(shù)也太輕松了吧!

前言

談起 CI/CD,很多同學(xué)的表情可能是這樣的?

怎么說,身為 Android 開發(fā),很多同學(xué)對 CI/CD 的了解少之又少,其實借助 CI/CD,可以做不少有趣的事。

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

CI/CD 包括 CI 和 CD。

CI(Continuous Interaction)是持續(xù)集成的意思,它是屬于開發(fā)人員的自動化流程。在當(dāng)今的 Android 開發(fā)模式中,多人同時維護一個項目已在所難免,所以,每次提交代碼后,我們可以讓機器去做些什么去維護我們項目的安全性和穩(wěn)定性?其實上面的圖中已經(jīng)給出答案,當(dāng)我們提交一份代碼后,自動化工具就會觸發(fā)構(gòu)建、測試,這些都完成以后,再幫我們合并代碼。

CD 通常有兩層意思,一層是(Continuous Delivery),它代表著持續(xù)交付,當(dāng)開發(fā)人員提交代碼后,自動化工具會會自動進行錯誤測試并上傳到存儲庫,最后由運維團隊將其部署在實時的生產(chǎn)環(huán)境中。另一層是(Continuous Deployment),它代表著持續(xù)部署,是將存儲庫發(fā)布到生產(chǎn)環(huán)境。

聽完上面的解釋,各位 Android 開發(fā)仔能弄懂 CI/CD 嗎?

顯然不能啊,這有關(guān)系嗎,沒關(guān)系,反正是從入門到放棄, :)

CI 還比較好理解,用實際的 Android 經(jīng)驗來解釋就是,持續(xù)交付就是將更新后的 Master 分支代碼打包成各個應(yīng)用市場需要的渠道包,持續(xù)部署就是將上一步打好的包,自動上傳到對應(yīng)的應(yīng)用市場。

CI/CD對Android開發(fā)的意義

首先,CI 對于開發(fā)人員來說,可以及早的發(fā)現(xiàn)錯誤,每當(dāng)我們提交一筆代碼,自動化工具就會發(fā)起構(gòu)建、自動化測試,最終會合入代碼,保證我們項目的穩(wěn)定性。別代碼提上去了,編都編不過,還吭呲吭呲往下寫!

其次,對于運維人員來說,CD 可以提升他們的工作效率,自動化工具可以減少他們不必要的工作量。

這個意義有點籠統(tǒng),放到Android上來講:

  1. 標(biāo)準(zhǔn)化管理Android項目
  2. 自動觸發(fā)多渠道打包
  3. 自動上傳到應(yīng)用市場應(yīng)該也是可以的,我看到一些平臺可以把我們的app一鍵上傳到各個應(yīng)用市場。
  4. 我最近研究的組件化下自動上傳AAR
  5. 以及組內(nèi)大佬醫(yī)生分享的精準(zhǔn)化測試系列
  6. ...

CI/CD 工具幫了我們不少忙。

看這里,Bugly 也建議我們將符號表的上傳放入持續(xù)集成中。

最常見的持續(xù)集成工具應(yīng)該是 Jenkins,因為它開源并且免費,你想要的插件在開源社區(qū)幾乎都可以找到,起點之前也是用的 Jenkins,也就最近,才開始從 Jenkins 遷移到騰訊內(nèi)部的藍盾。

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

Github Action 簡介

沒錯,本次的主角就是 Github Action,官方是這么介紹的:

在 GitHub Actions 的倉庫中自動化、自定義和執(zhí)行軟件開發(fā)工作流程。 您可以發(fā)現(xiàn)、創(chuàng)建和共享操作以執(zhí)行您喜歡的任何作業(yè)(包括 CI/CD),并將操作合并到完全自定義的工作流程中。

所以,Github Actions 是 Github 的持續(xù)集成服務(wù),那么它和其他的持續(xù)集成工具有什么不同呢?

所有的一系列操作例如設(shè)置 JDK、運行 Shell 命令或者是執(zhí)行自動化測試都被稱之為 Action,像設(shè)置JDK Action 肯定通用的,所以就有了免費的 Github Action 市場,允許開發(fā)者將他們封裝的 Action 上傳到市場,其他開發(fā)者需要的時候引用即可。

可以看到,當(dāng)前市場的 Action 已經(jīng)快1W個了,能夠滿足開發(fā)的日常需求。

除此以外,Github Action 也為通用的一些項目提供了模板,當(dāng)我們點擊自己項目的 Action 的時候,它會給你推薦一些模板:

image.png

也允許你自己選擇一些熱門的模板。

語法簡介

看到這兒,很多同學(xué)都已經(jīng)開始躍躍欲試了,別急,我們再介紹一下語法!

理解了這些名詞,我們再了解一下它們之間的關(guān)系:

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

有了一定的了解以后,我們看看語法。

Github Action 的配置文件叫做 WorkFlow 文件,存放在代碼倉庫的 .github/workflows 目錄,該文件采用的 yaml 語法。

我們使用一個默認(rèn)的 Android 模板,看看它是什么樣子的:

name: Android CI # 設(shè)置 WorkFlow 名稱

on: # 設(shè)置 Event,
  push:
    branches: [ master ] 
  pull_request:
    branches: [ master ]

jobs:
  build: # 設(shè)置 Job 的名稱

    runs-on: ubuntu-latest # 設(shè)置服務(wù)器

    steps:
    - uses: actions/checkout@v2 # Action 獲取當(dāng)前分支的源碼
    - name: set up JDK 11 # Action 設(shè)置 JDK
      uses: actions/setup-java@v2
      with: # 參數(shù)由 Action 的創(chuàng)建者指定,需要查看創(chuàng)建者的文檔
        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 設(shè)置 WorkFlow 的名字
on 設(shè)置 Event,比如上面的 on.push.branches: [ master ],代表著觸發(fā)的時機是 master 分支發(fā)生 push 的時候
jobs 聲明 Jobs,上述中 jobs 下的 build 字段,則是創(chuàng)建一個 Job,也是該 Job 的名稱
runs-on 聲明 Runner,也就是服務(wù)器,支持 Windows、MacOS 和 Ubuntu,不過需要指定版本
steps 聲明 Steps
steps.- - 代表著當(dāng)前是一個 Step
steps.name 當(dāng)前 Step 的名稱
steps.uses 使用市場中的 Action
steps.run 執(zhí)行 Shell 命令

有了名詞解釋,我們就能明白上面的 Android 模板的大致過程。

Android 實踐

我們有了一定的基礎(chǔ),借助這些,就可以做些有趣的東西的了!

試想一下,當(dāng)我們往 master 分支合入代碼的時候,是不是就要發(fā)版了,這個時候,持續(xù)集成可以幫我們構(gòu)建項目,之后根據(jù)需要,使用生成好的Apk進行加固、多渠道打包、上傳備份文件,最后發(fā)出成功或者失敗的消息。

那同樣的,我們可以在上面的示例中做一些修改,加入上傳APK、將結(jié)果發(fā)送給郵件和釘釘?shù)娜骸?/p>

以我的 AndroidGithubAction 為例,完整的教程是這樣的:

1. 創(chuàng)建一個Action

選中 Github 項目中的 Action 欄,我們將會見到下面的內(nèi)容:

根據(jù)需要選擇自定義方式或者模板方式,這里我們選擇 Android 模板。

2. 修改模版

模板的內(nèi)容我在上面已經(jīng)發(fā)過了,修改一下:

  1. 最外層的 name 可改可不改。
  2. Event 修改為 push 的時候觸發(fā)即可。
  3. 修改一下 Gradle 命令。

修改完的內(nèi)容:

name: Android CI

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    
    - uses: actions/checkout@v2  # 拉取源代碼
    
    - name: set up JDK 1.8 # 設(shè)置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 # 執(zhí)行編譯命令
      run: ./gradlew clean && ./gradlew app:assembleDebug

3. 上傳APK

先說明一下,編寫 WorkFlow 時,左邊是編寫 WorkFlow 的面板,右邊就可以直接在市場上搜索你想使用的Action。

image.png

選中想使用的 Action,就會跳出詳細的說明文檔。

下面這個就是我們想使用的 Action。

有了它,我們可以上傳編譯完的 apk,可以在多個 job 之間共享,或者等持續(xù)集成運行結(jié)束的時候,可以下載生成的產(chǎn)物。

引入代碼:

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

4. 上傳APK到第三方平臺

很多情況下需要將產(chǎn)物上傳到第三方平臺,以蒲公英為例:

- 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服務(wù)器的命令行工具,curl 使用可參考阮一峰的文章:

《curl 的用法指南》

對于一些關(guān)鍵的 key,我們可能不太想將 key 暴露在 Github Action 的 workflow 文件中,Github 推薦我們將這些 key 存在 Secrets 中,添加入口:

5. 獲取構(gòu)建人

上傳完成后,我們會將編譯信息、版本信息、Commit日志發(fā)送到企業(yè)微信、釘釘或者郵箱。

首先是獲取構(gòu)建人信息,默認(rèn)的環(huán)境變量提供如下:

但是我發(fā)現(xiàn)在 curl 命令中有點問題,報了識別不了的錯誤:

于是就把觸發(fā)人寫在了全局變量中:

# 獲取發(fā)送者
- name: Sender
  run: echo "sender=$GITHUB_ACTOR" >> $GITHUB_ENV

之后通過${{ env.sender }} 獲取。

6. 獲取版本信息

版本信息我是通過 grep 命令在 app 目錄下的 build.gradle 文件獲取

如果你有更好的方法,歡迎評論區(qū)交流~

同樣是寫到全局變量中:

# 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 就能獲?。?/p>

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

該命令是獲取最近的提交記錄的日志,以指定格式輸出。

8. 發(fā)送到釘釘群中的小機器人

釘釘小機器人的使用說明就不介紹了,直接看官網(wǎng),命令如下:

# 向釘釘發(fā)送消息
- name: dingtalk
  run: | 
        curl '${{ secrets.DINGDING_WEBHOOK }}' -H 'Content-Type: application/json' -d '{"msgtype": "text", "text": {"content":"吃飯! \n觸發(fā)人:${{ env.sender }} \n版本:${{ env.versionResult }} \n提交內(nèi)容:${{ env.updateLog }} \n下載地址:${{ secrets.PGY_URL }}"}}'

構(gòu)建成功后發(fā)送到群里的截圖:

9. 發(fā)送郵件

通常情況下,觸發(fā)人編譯失敗后是會收到失敗郵件的,如果不夠,我們可以再寫一個發(fā)送郵件的 Action

我們這里引用其他人開源的 Action:

# 發(fā)送郵件
- 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觸發(fā)人:${{ env.sender }} \n版本:${{ env.versionResult }} \n提交內(nèi)容:${{ env.updateLog }} \n下載地址:${{ secrets.PGY_URL }}"

這一步做完,差不多就結(jié)束了。

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

總結(jié)

對于開源用戶來說,Github Action 還有一些比較常見的使用場景。

比如利用 Github Action 自動部署 Hexo 博客,還記得以前使用 Github Page 建立個人博客的時候,每次新增一篇文章以后,要輸入一串命令行,有了 Github Action,這些都可以自動執(zhí)行。

還有,很多人的 Github Porfile 是依賴 Github Action 自動更新的,像這位外國老哥:

他的 Profile 每三個小時會自動獲取一下最新的個人文章和社交媒體,展示在自己的個人簡介上,這個效果確實很贊!最近有時間,打算也來搞一套。

參考

《Github Actions 使用指南和Android 持續(xù)集成示例》
《GitHub Actions 入門教程》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容