GitHub Actions 使你能夠直接在你的 GitHub 庫中建立自定義的工做流,工做流指的就是自動化的流程,好比構建、測試、打包、發佈、部署等等,也就是說你能夠直接進行 CI(持續集成)和 CD (持續部署)。javascript
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
能夠定義本身的 name
和 id
,經過 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
聲明瞭什麼時候觸發 workflow ,它能夠是:github
on: [push, pull_request]
on: schedule: - cron: '0 0 * * *'
配置多個事件,示例: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 能夠包含一個或多個 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
指定了任務的 runner 即執行環境,runner 分兩種:GitHub-hosted runner 和 self-hosted runner 。
所謂的 self-hosted runner 就是用你本身的機器,可是須要 GitHub 能進行訪問並給與其所需的機器權限,這個不在本文描述範圍內,有興趣可參考 self-hosted runner 。
GitHub-hosted runner 其實就是 GitHub 提供的虛擬環境,目前有如下四種:
windows-latest
: Windows Server 2019ubuntu-latest
或 ubuntu-18.04
: Ubuntu 18.04ubuntu-16.04
: Ubuntu 16.04macos-latest
: macOS Catalina 10.15比較常見的:
runs-on: ubuntu-latest
有時候咱們經常須要對多個操做系統、多個平臺、多個編程語言版本進行測試,爲此咱們能夠配置一個構建矩陣。
例如:
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: - 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
: 使用哪一個 actionrun
: 執行哪些指令with
: 指定某個 action 可能須要輸入的參數continue-on-error
: 設置爲 true 容許此步驟失敗 job 仍然經過timeout-minutes
: step 的超時時間action 動做一般是能夠通用的,這意味着你能夠直接使用別人定義好的 action 。
checkout action 是一個標準動做,當如下狀況時必須且須要率先使用:
使用示例:
- uses: actions/checkout@v1
若是你只想淺克隆你的庫,或者只複製最新的版本,你能夠在 with
中使用 fetch-depth
聲明,例如:
- uses: actions/checkout@v1 with: fetch-depth: 1
引用 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
引用格式:{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
若是某個 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 workflow 和 Creating a Docker container action 。
請參考:building-actions
環境變量能夠配置在如下地方:
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
若是重複,優先使用最近的那個。
你能夠在 job 和 step 中使用 if
條件語句,只有知足條件時才執行具體的 job 或 step :
jobs.<job_id>.if
jobs.<job_id>.steps.if
任務狀態檢查函數:
success()
: 當上一步執行成功時返回 truealways()
: 老是返回 truecancelled()
: 當 workflow 被取消時返回 truefailure()
: 當上一步執行失敗時返回 true例如:
steps: - name: step1 if: always() - name: step2 if: success() - name: step3 if: failure()
意思就是 step1 老是執行,step2 須要上一步執行成功才執行,step3 只有當上一步執行失敗才執行。
${{ <expression> }}
上下文和表達式: ${{ <expression> }}
。
有時候咱們須要與第三方平臺進行交互,這時候一般須要配置一個 token ,可是顯然這個 token 不可能明文使用,這種個狀況下咱們要作的就是:
Settings
的 Secrets
中添加一個密鑰,如 SOMEONE_TOKEN
${{ 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 cancelledsteps.<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