GitHub Actions 指南

GitHub Actions 指南

GitHub Actions 使你能夠直接在你的 GitHub 庫中建立自定義的工做流,工做流指的就是自動化的流程,好比構建、測試、打包、發佈、部署等等,也就是說你能夠直接進行 CI(持續集成)和 CD (持續部署)。javascript


基本概念

  • workflow : 一個 workflow 工做流就是一個完整的過程,每一個 workflow 包含一組 jobs 任務。
  • job : jobs 任務包含一個或多個 job ,每一個 job 包含一系列的 steps 步驟。
  • step : 每一個 step 步驟能夠執行指令或者使用一個 action 動做。
  • action : 每一個 action 動做就是一個通用的基本單元。

配置 workflow

workflow 必須存儲在你的項目庫根路徑下的 .github/workflows 目錄中,每個 workflow 對應一個具體的 .yml 文件(或者 .yaml)。java

workflow 示例:node

name: Greet Everyone
# This workflow is triggered on pushes to the repository.
on: [push]

jobs:
  your_job_id:
    # Job name is Greeting
    name: Greeting
    # This job runs on Linux
    runs-on: ubuntu-latest
    steps:
      # This step uses GitHub's hello-world-javascript-action: https://github.com/actions/hello-world-javascript-action
      - name: Hello world
        uses: actions/hello-world-javascript-action@v1
        with:
          who-to-greet: 'Mona the Octocat'
        id: hello
      # This step prints an output (time) from the previous step's action.
      - name: Echo the greeting's time
        run: echo 'The time was ${{ steps.hello.outputs.time }}.'

說明:linux

  • 最外層的 name 指定了 workflow 的名稱。
  • on 聲明瞭一旦發生了 push 操做就會觸發這個 workflow 。
  • jobs 定義了任務集,其中能夠有一個或多個 job 任務,示例中只有一個。
  • runs-on 聲明瞭運行的環境。
  • steps 定義須要執行哪些步驟。
  • 每一個 step 能夠定義本身的 nameid ,經過 uses 能夠聲明使用一個具體的 action ,經過 run 聲明須要執行哪些指令。
  • ${{ }} 可使用上下文參數。

上述示例能夠抽象爲:git

name: <workflow name>

on: <events that trigger workflows>

jobs:
  <job_id>:
    name: <job_name>
    runs-on: <runner>
    steps:
      - name: <step_name>
        uses: <action>
        with:
          <parameter_name>: <parameter_value>
        id: <step_id>

      - name: <step_name>
        run: <commands>

on

on 聲明瞭什麼時候觸發 workflow ,它能夠是:github

  • 一個或多個 GitHub 事件,好比 push 了一個 commit、建立了一個 issue、產生了一次 pull request 等等,示例:
on: [push, pull_request]
  • 預約的時間,示例(天天零點零分觸發):
on:
  schedule:
    - cron:  '0 0 * * *'
  • 某個外部事件。所謂外部事件觸發,簡而言之就是你能夠經過 REST API 向 GitHub 發送請求去觸發,具體請查閱官方文檔: repository-dispatch-event

配置多個事件,示例:docker

on:
  # Trigger the workflow on push or pull request,
  # but only for the master branch
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
  # Also trigger on page_build, as well as release created events
  page_build:
  release:
    types: # This configuration does not affect the page_build event above
      - created

詳細文檔請參考: 觸發事件express


jobs

jobs 能夠包含一個或多個 job ,如:macos

jobs:
  my_first_job:
    name: My first job
  my_second_job:
    name: My second job

若是多個 job 之間存在依賴關係,那麼你可能須要使用 needs :npm

jobs:
  job1:
  job2:
    needs: job1
  job3:
    needs: [job1, job2]

這裏的 needs 聲明瞭 job2 必須等待 job1 成功完成,job3 必須等待 job1 和 job2 依次成功完成。

每一個任務默認超時時間最長爲 360 分鐘,你能夠經過 timeout-minutes 進行配置:

jobs:
  job1:
    timeout-minutes:

runs-on & strategy

runs-on 指定了任務的 runner 即執行環境,runner 分兩種:GitHub-hosted runner 和 self-hosted runner 。

所謂的 self-hosted runner 就是用你本身的機器,可是須要 GitHub 能進行訪問並給與其所需的機器權限,這個不在本文描述範圍內,有興趣可參考 self-hosted runner

GitHub-hosted runner 其實就是 GitHub 提供的虛擬環境,目前有如下四種:

  • windows-latest : Windows Server 2019
  • ubuntu-latestubuntu-18.04 : Ubuntu 18.04
  • ubuntu-16.04 : Ubuntu 16.04
  • macos-latest : macOS Catalina 10.15

比較常見的:

runs-on: ubuntu-latest

runs-on 多環境

有時候咱們經常須要對多個操做系統、多個平臺、多個編程語言版本進行測試,爲此咱們能夠配置一個構建矩陣。

例如:

runs-on: ${{ matrix.os }}
strategy:
  matrix:
    os: [ubuntu-16.04, ubuntu-18.04]
    node: [6, 8, 10]

示例中配置了兩種 os 操做系統和三種 node 版本即總共六種狀況的構建矩陣,${{ matrix.os }} 是一個上下文參數。

strategy 策略,包括:

  • matrix : 構建矩陣。
  • fail-fast : 默認爲 true ,即一旦某個矩陣任務失敗則當即取消全部還在進行中的任務。
  • max-paraller : 可同時執行的最大併發數,默認狀況下 GitHub 會動態調整。

示例:

runs-on: ${{ matrix.os }}
strategy:
  matrix:
    os: [macos-latest, windows-latest, ubuntu-18.04]
    node: [4, 6, 8, 10]
    include:
      # includes a new variable of npm with a value of 2 for the matrix leg matching the os and version
      - os: windows-latest
        node: 4
        npm: 2

include 聲明瞭 os 爲 windows-latest 時,增長一個 node 和 npm 分別使用特定的版本的矩陣環境。

include 相反的就是 exclude

runs-on: ${{ matrix.os }}
strategy:
  matrix:
    os: [macos-latest, windows-latest, ubuntu-18.04]
    node: [4, 6, 8, 10]
    exclude:
      # excludes node 4 on macOS
      - os: macos-latest
        node: 4

exclude 用來刪除特定的配置項,好比這裏當 os 爲 macos-latest ,將 node 爲 4 的版本從構建矩陣中移除。


steps

steps 的通用格式相似於:

steps:
  - name: <step_name>
    uses: <action>
    with:
      <parameter_name>: <parameter_value>
    id: <step_id>
    continue-on-error: true

  - name: <step_name>
    timeout-minutes:
    run: <commands>

每一個 step 步驟能夠有:

  • id : 每一個步驟的惟一標識符
  • name : 步驟的名稱
  • uses : 使用哪一個 action
  • run : 執行哪些指令
  • with : 指定某個 action 可能須要輸入的參數
  • continue-on-error : 設置爲 true 容許此步驟失敗 job 仍然經過
  • timeout-minutes : step 的超時時間

action

action 動做一般是能夠通用的,這意味着你能夠直接使用別人定義好的 action 。

checkout action

checkout action 是一個標準動做,當如下狀況時必須且須要率先使用:

  • workflow 須要項目庫的代碼副本,好比構建、測試、或持續集成這些操做。
  • workflow 中至少有一個 action 是在同一個項目庫下定義的。

使用示例:

- uses: actions/checkout@v1

若是你只想淺克隆你的庫,或者只複製最新的版本,你能夠在 with 中使用 fetch-depth 聲明,例如:

- uses: actions/checkout@v1
  with:
    fetch-depth: 1

引用 action

一、引用公有庫中的 action

引用 action 的格式是 {owner}/{repo}@{ref}{owner}/{repo}/{path}@{ref} ,例如上例的中 actions/checkout@v1 ,你還可使用標準庫中的其它 action ,如設置 node 版本:

jobs:
  my_first_job:
    name: My Job Name
      steps:
        - uses: actions/setup-node@v1
          with:
            node-version: 10.x

二、引用同一個庫中的 action

引用格式:{owner}/{repo}@{ref}./path/to/dir

例如項目文件結構爲:

|-- hello-world (repository)
|   |__ .github
|       └── workflows
|           └── my-first-workflow.yml
|       └── actions
|           |__ hello-world-action
|               └── action.yml

當你想要在 workflow 中引用本身的 action 時能夠:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # This step checks out a copy of your repository.
      - uses: actions/checkout@v1
      # This step references the directory that contains the action.
      - uses: ./.github/actions/hello-world-action

三、引用 Docker Hub 上的 container

若是某個 action 定義在了一個 docker container image 中且推送到了 Docker Hub 上,你也能夠引入它,格式是 docker://{image}:{tag} ,示例:

jobs:
  my_first_job:
    steps:
      - name: My first step
        uses: docker://alpine:3.8

更多信息參考: Docker-image.yml workflowCreating a Docker container action

構建 actions

請參考:building-actions


env

環境變量能夠配置在如下地方:

  • env
  • jobs.<job_id>.env
  • jobs.<job_id>.steps.env

示例:

env:
  NODE_ENV: dev

jobs:
  job1:
    env:
      NODE_ENV: test

    steps:
      - name:
        env:
          NODE_ENV: prod

若是重複,優先使用最近的那個。


if & context

你能夠在 job 和 step 中使用 if 條件語句,只有知足條件時才執行具體的 job 或 step :

  • jobs.<job_id>.if
  • jobs.<job_id>.steps.if

任務狀態檢查函數:

  • success() : 當上一步執行成功時返回 true
  • always() : 老是返回 true
  • cancelled() : 當 workflow 被取消時返回 true
  • failure() : 當上一步執行失敗時返回 true

例如:

steps:
  - name: step1
    if: always()

  - name: step2
    if: success()

  - name: step3
    if: failure()

意思就是 step1 老是執行,step2 須要上一步執行成功才執行,step3 只有當上一步執行失敗才執行。

${{ <expression> }}

上下文和表達式: ${{ <expression> }}

有時候咱們須要與第三方平臺進行交互,這時候一般須要配置一個 token ,可是顯然這個 token 不可能明文使用,這種個狀況下咱們要作的就是:

  1. 在具體 repository 庫 SettingsSecrets 中添加一個密鑰,如 SOMEONE_TOKEN
  2. 而後在 workflow 中就能夠經過 ${{ secrets.SOMEONE_TOKEN }} 將 token 安全地傳遞給環境變量。
steps:
  - name: My first action
    env:
      SOMEONE_TOKEN: ${{ secrets.SOMEONE_TOKEN }}

這裏的 secrets 就是一個上下文,除此以外還有不少,好比:

  • github.event_name : 觸發 workflow 的事件名稱
  • job.status : 當前 job 的狀態,如 success, failure, or cancelled
  • steps.<step id>.outputs : 某個 action 的輸出
  • runner.os : runner 的操做系統如 Linux, Windows, or macOS

這裏只列舉了少數幾個。

另外在 if 中使用時不須要 ${{ }} 符號,好比:

steps:
 - name: My first step
   if: github.event_name == 'pull_request' && github.event.action == 'unassigned'
   run: echo This event is a pull request that had an assignee removed.

上下文和表達式詳細信息請參考: contexts-and-expression


結語

最後給個本身寫的示例,僅供參考:

name: GitHub Actions CI

on: [push]

jobs:
  build-test-deploy:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [8.x, 10.x, 12.x]

    steps:
    - uses: actions/checkout@v1

    - name: install linux packages
      run: sudo apt-get install -y --no-install-recommends libevent-dev

    - name: install memcached
      if: success()
      run: |
        wget -O memcached.tar.gz http://memcached.org/files/memcached-1.5.20.tar.gz
        tar -zxvf memcached.tar.gz
        cd memcached-1.5.20
        ./configure && make && sudo make install
        memcached -d

    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      if: success()
      with:
        node-version: ${{ matrix.node-version }}

    - name: npm install, build, and test
      env:
        CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
      if: success()
      run: |
        npm ci
        npm test
        npm run report-coverage

qrcode_for_gh_9ccbe5e0dfb3_258.jpg

相關文章
相關標籤/搜索