10 個你該了解的 GitHub Actions 進階技巧
本文轉載自微信公眾號「問其」,作者陳少文。轉載本文請聯(lián)系問其公眾號。
1. workflow 執(zhí)行時,傳入?yún)?shù)
在執(zhí)行 workflow 時, 允許在 GitHub Actions 頁面輸入?yún)?shù),控制執(zhí)行邏輯。我們可以將人工處理的邏輯,在 GitHub Actions 參數(shù)化執(zhí)行,適用于持續(xù)部署場景。
- on:
- workflow_dispatch:
- inputs:
- logLevel:
- description: 'Log level'
- required: true
- default: 'warning'
- tags:
- description: 'Test scenario tags'
- jobs:
- printInputs:
- runs-on: ubuntu-latest
- steps:
- - run: |
- echo "Log level: ${{ github.event.inputs.logLevel }}"
- echo "Tags: ${{ github.event.inputs.tags }}"
上面的 workflow 執(zhí)行時,會彈出如下對話框。
2. Job 編排控制執(zhí)行順序
一個 workflow 由很多個 job 組成,借助于 needs 參數(shù),我們可以管理這些 job 之間的依賴,控制其執(zhí)行流程。
- on: push
- jobs:
- job1:
- runs-on: ubuntu-latest
- steps:
- - run: echo "job1"
- job2:
- runs-on: ubuntu-latest
- steps:
- - run: sleep 5
- needs: job1
- job3:
- runs-on: ubuntu-latest
- steps:
- - run: sleep 10
- needs: job1
- job4:
- runs-on: ubuntu-latest
- steps:
- - run: echo "job4"
- needs: [job2, job3]
上面的 workflows 執(zhí)行時,job2 和 job3 會等 job1 執(zhí)行成功時才執(zhí)行,job4 會等 job2 和 job3 執(zhí)行成功時才執(zhí)行。
3. 用于項目管理
Kubernetes 基于 ChatOps 使用 Prow 協(xié)調社區(qū)有序協(xié)作。但并不是每個團隊,都愿意搭建并維護一套 Prow 機器人系統(tǒng)。ChatOps 實現(xiàn)的核心是事件驅動,這在 GitHub 中使用 Actions 也能實現(xiàn)。
下面是幾個項目管理相關的 action
- 根據(jù)修改的目錄添加標簽
- - uses: actions/labeler@main
- with:
- repo-token: "${{ secrets.GITHUB_TOKEN }}"
在配置文件 .github/workflows/labeler.yml 中添加規(guī)則,給對 docs 目錄進行修改的 Pull Requests(以下簡稱 PR) 自動添加 docs_label 標簽:
- docs_label:
- - ./docs/*
- 根據(jù)標簽添加 Issues 到 Projects
使用 srggrs/assign-one-project-github-action , 我們可以將新增的 Issues 或者 PR 添加到指定的 Projects 中。
- - name: Assign NEW issues and NEW pull requests to project 2
- uses: srggrs/assign-one-project-github-action@1.2.0
- if: github.event.action == 'opened'
- with:
- project: 'https://github.com/srggrs/assign-one-project-github-action/projects/2'
也可以將包含指定標簽的 Issues 或 PR 添加到指定 Project 的指定 Column 中。
- - name: Assign issues and pull requests with `bug` label to project 3
- uses: srggrs/assign-one-project-github-action@1.2.0
- if: |
- contains(github.event.issue.labels.*.name, 'bug') ||
- contains(github.event.pull_request.labels.*.name, 'bug')
- with:
- project: 'https://github.com/srggrs/assign-one-project-github-action/projects/3'
- column_name: 'Labeled'
- 清理長時間無人跟進的 Issues
如果一個 Issue 長達 30 天沒有更新,那么下面的 workflow 將會再等 5 天,然后將其關閉。
- name: 'Close stale issues and PRs'
- on:
- schedule:
- - cron: '30 1 * * *'
- jobs:
- stale:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/stale@v3
- with:
- stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
- days-before-stale: 30
- days-before-close: 5
GitHub 上的項目管理,主要是圍繞 Issues、Projects、Labels、Pull Requests 展開,可以在 GitHub Actions 的 Marketplace 中搜索相關的 Action 使用。
4. 在線調試
在使用 GitHub Actions 的過程中,如果需要登錄到 Runner 上調試命令,那么下面這個技巧你一定會感興趣。
- - uses: shaowenchen/debugger-action@v2
- name: debugger
- timeout-minutes: 30
- continue-on-error: true
- with:
- ngrok_token: ${{ secrets.NGROK_TOKEN }}
只需要去 Ngrok 官網(wǎng)申請一個 token,就可以通過 ssh 遠程登錄到 Runner。當然,也可以暴露 Runner 上的服務,提供外網(wǎng)訪問的鏈接,最長可達 6 小時。
在執(zhí)行日志中,我們可以找到 ssh 的登錄鏈接,使用 root/root 即可登錄 Runner。如果配置了 web 的端口映射,還可以查看到相關的服務鏈接。
5. 設置緩存
緩存能有效地加快構建速度,減少網(wǎng)絡請求,復用中間碼。這對于 Java、Nodejs、Python 等項目,非常有用。
- - name: Get yarn cache directory path
- id: yarn-cache-dir-path
- run: echo "::set-output name=dir::$(yarn cache dir)"
- - uses: actions/cache@v2
- id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
- with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
6. 檢測項目中的問題鏈接
項目維護時間長了之后,最令人頭疼的就是文檔。研發(fā)、測試跟進的是代碼、功能,而文檔卻時常無人更新。缺少維護的文檔,會讓潛在參與者流失。下面這個 Action 能檢測文檔中的 Broken 鏈接。
- name: Check Markdown links
- on: push
- jobs:
- markdown-link-check:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@master
- - uses: gaurav-nelson/github-action-markdown-link-check@v1
- with:
- use-quiet-mode: 'yes'
- config-file: '.github/workflows/checklink_config.json'
- max-depth: 3
gaurav-nelson/github-action-markdown-link-check 支持自定義配置,非常靈活易用,堪稱必備 Action。
下面是一個 .github/workflows/checklink_config.json 的示例:
- {
- "replacementPatterns": [
- {
- "pattern": "^/",
- "replacement": "/github/workspace/"
- }
- ],
- "aliveStatusCodes": [
- 429,
- 200
- ]
- }
最后在 GitHub Actions 日志頁面,會輸出這樣的檢測結果:
- =========================> MARKDOWN LINK CHECK <=========================
- FILE: ./docs/governance.md
- 4 links checked.
- FILE: ./docs/configuration/cri.md
- [✖] https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable
- 7 links checked.
- ERROR: 1 dead links found!
- [✖] https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable → Status: 404
- FILE: ./docs/configuration/kubeedge.md
- 21 links checked.
- =========================================================================
7. Job 批量執(zhí)行,參數(shù)排列組合執(zhí)行任務
數(shù)據(jù)驅動測試的場景下,可以通過輸入的參數(shù)控制測試的流程。在 GitHub Actions 中,我們也可以通過參數(shù)化的方式,批量地執(zhí)行或編排流程。
GitHub Actions 會將 matrix 中的每個參數(shù)排列組合,產(chǎn)生一個新的運行實例。
- on: push
- jobs:
- node:
- runs-on: ${{ matrix.os }}
- strategy:
- matrix:
- os: [ubuntu-16.04, ubuntu-18.04]
- node: [6, 8, 10]
- steps:
- - uses: actions/setup-node@v1
- with:
- node-version: ${{ matrix.node }}
- - run: node --version
上面的 workflow 執(zhí)行時, 會執(zhí)行 6 個 job。
無論是用來測試兼容性, 還是批量執(zhí)行 Job, 都是非常好的。
8. 拷貝 Action 的 Badge 狀態(tài)顯示在文檔中
通常,我們使用 GitHub Actions 對項目進行代碼分析、執(zhí)行測試、編譯、打包、構建、推送鏡像等。這些行為對于保證項目的穩(wěn)定,至關重要。
但并不是每個人都會關注 Actions 的執(zhí)行細節(jié)。我們可以在顯眼的地方,給出這些過程的最終實時狀態(tài),以提醒用戶和開發(fā)者。如果 main 分支構建失敗了,能提醒用戶謹慎使用,能提醒研發(fā)盡快修復問題。
在 GitHub Actions 頁面中, 點擊 Create status badge。
將彈框中的 URL 鏈接,增加在 Readme 文檔中,即可實時快速地查看到 workflow 的執(zhí)行結果。
9. 精準 hook GitHub 上的行為
workflow 通過 on 關鍵字定義觸發(fā)條件。主要有三類觸發(fā)事件:
- 人工觸發(fā)
- on: workflow_dispatch
- 定時觸發(fā)
每隔 15 分鐘觸發(fā)一次 workflows。
- on:
- schedule:
- - cron: '*/15 * * * *'
- Webhook 觸發(fā)
我們在 GitHub 上的操作,比如創(chuàng)建 Issues、新增 Deployment 等,都能夠通過 API 獲取到相關的事件。通過這些事件,我們可以精準地定制 workflow 的行為。通常我們都是基于 push 或者 pull requests 觸發(fā),下面列舉幾個不常見的示例:
當有人 fork 倉庫時觸發(fā)
- on:
- fork
當有人 star 倉庫時觸發(fā)
- on:
- watch:
- types: [started]
當有新建的 Issue 時觸發(fā)
- on:
- issues:
- types: [opened]
10. 開發(fā)一個 Action 很簡單
如果在 Marketplace 找不到合適的 Action,那么自己開發(fā) Action 也是一個不錯的選擇。
其實,開發(fā)一個 Action 沒有想象中那么難。一個 Action 就是一個處理邏輯,接收輸入?yún)?shù),執(zhí)行一定的邏輯,然后輸出參數(shù)。有三種類型的 Action:
- Docker container, 適用 Linux 系統(tǒng)
通過 Docker 容器,提供 Action 的執(zhí)行邏輯處理。比如下面這個例子:
Dockerfile
- FROM appleboy/drone-scp:1.6.2-linux-amd64
- ADD entrypoint.sh /entrypoint.sh
- RUN chmod +x /entrypoint.sh
- ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
- #!/bin/sh
- set -eu
- [ -n "$INPUT_STRIP_COMPONENTS" ] && export INPUT_STRIP_COMPONENTS=$((INPUT_STRIP_COMPONENTS + 0))
- sh -c "/bin/drone-scp $*"
通過 dron-scp 鏡像,快速開發(fā)了一個提供 scp 文件拷貝的 Action。
- JavaScript, 適用 Linux、macOS、Windows 系統(tǒng)
通過執(zhí)行 JavaScript 處理 Action 邏輯。官方提供了 JavaScript 和 TypeScript 的 Action 模板。在創(chuàng)建項目時,使用模板創(chuàng)建,然后編寫處理邏輯,發(fā)布自己的 Action 即可。
GitHub Actions 提供了工具包,以支持這種方式的擴展,例如執(zhí)行命令、操作 GitHub 等,都可以通過引用包,直接調用相關函數(shù)實現(xiàn)。下面是其中幾個工具包:
- @actions/exec, 執(zhí)行命令
- @actions/core, 輸入、輸出、日志、秘鑰相關
- @actions/io, 操作文件
- Composite run steps, 適用 Linux, macOS, Windows 系統(tǒng)
這種類型,允許將一連串的 Shell 操作作為一個 Action 使用。
- name: 'Hello World'
- description: 'Greet someone'
- inputs:
- who-to-greet: # id of input
- description: 'Who to greet'
- required: true
- default: 'World'
- outputs:
- random-number:
- description: "Random number"
- value: ${{ steps.random-number-generator.outputs.random-id }}
- runs:
- using: "composite"
- steps:
- - run: echo Hello ${{ inputs.who-to-greet }}.
- shell: bash
- - id: random-number-generator
- run: echo "::set-output name=random-id::$(echo $RANDOM)"
- shell: bash
- - run: ${{ github.action_path }}/goodbye.sh
- shell: bash
11. 參考
?https://github.com/actions/typescript-action
?https://github.com/shaowenchen/debugger-action