GitHub Actions 是 GitHub 的持續集成服務,於2018年10月推出。
這些天,我一直在試用,覺得它非常強大,有創意,比 Travis CI 玩法更多。
本文是一個簡單教程,演示如何使用 GitHub Actions 自動發佈一個 React 應用到 GitHub Pages。

一、GitHub Actions 是什麼?
大家知道,持續集成由很多操作組成,比如抓取代碼、運行測試、登錄遠程服務器,發佈到第三方服務等等。GitHub 把這些操作就稱為 actions。
很多操作在不同項目裡面是類似的,完全可以共享。GitHub 注意到了這一點,想出了一個很妙的點子,允許開發者把每個操作寫成獨立的腳本文件,存放到代碼倉庫,使得其他開發者可以引用。
如果你需要某個 action,不必自己寫複雜的腳本,直接引用他人寫好的 action 即可,整個持續集成過程,就變成了一個 actions 的組合。這就是 GitHub Actions 最特別的地方。
GitHub 做了一個官方市場,可以搜索到他人提交的 actions。另外,還有一個 awesome actions 的倉庫,也可以找到不少 action。

上面說了,每個 action 就是一個獨立腳本,因此可以做成代碼倉庫,使用userName/repoName的語法引用 action。比如,actions/setup-node就表示github.com/actions/setup-node這個倉庫,它代表一個 action,作用是安裝 Node.js。事實上,GitHub 官方的 actions 都放在 github.com/actions 裡面。
既然 actions 是代碼倉庫,當然就有版本的概念,用戶可以引用某個具體版本的 action。下面都是合法的 action 引用,用的就是 Git 的指針概念,詳見官方文檔。
actions/setup-node@74bc508 # 指向一個 commit actions/[email protected] # 指向一個標籤 actions/setup-node@master # 指向一個分支
二、基本概念
GitHub Actions 有一些自己的術語。
(1)workflow (工作流程):持續集成一次運行的過程,就是一個 workflow。
(2)job (任務):一個 workflow 由一個或多個 jobs 構成,含義是一次持續集成的運行,可以完成多個任務。
(3)step(步驟):每個 job 由多個 step 構成,一步步完成。
(4)action (動作):每個 step 可以依次執行一個或多個命令(action)。
三、workflow 文件
GitHub Actions 的配置文件叫做 workflow 文件,存放在代碼倉庫的.github/workflows目錄。
workflow 文件採用 YAML 格式,文件名可以任意取,但是後綴名統一為.yml,比如foo.yml。一個庫可以有多個 workflow 文件。GitHub 只要發現.github/workflows目錄裡面有.yml文件,就會自動運行該文件。
workflow 文件的配置字段非常多,詳見官方文檔。下面是一些基本字段。
(1)name
name字段是 workflow 的名稱。如果省略該字段,默認為當前 workflow 的文件名。
name: GitHub Actions Demo
(2)on
on字段指定觸發 workflow 的條件,通常是某些事件。
on: push
上面代碼指定,push事件觸發 workflow。
on字段也可以是事件的數組。
on: [push, pull_request]
上面代碼指定,push事件或pull_request事件都可以觸發 workflow。
完整的事件列表,請查看官方文檔。除了代碼庫事件,GitHub Actions 也支持外部事件觸發,或者定時運行。
(3)on.<push|pull_request>.<tags|branches>
指定觸發事件時,可以限定分支或標籤。
on: push: branches: - master
上面代碼指定,只有master分支發生push事件時,才會觸發 workflow。
(4)jobs.<job_id>.name
workflow 文件的主體是jobs字段,表示要執行的一項或多項任務。
jobs字段裡面,需要寫出每一項任務的job_id,具體名稱自定義。job_id裡面的name字段是任務的說明。
jobs: my_first_job: name: My first job my_second_job: name: My second job
上面代碼的jobs字段包含兩項任務,job_id分別是my_first_job和my_second_job。
(5)jobs.<job_id>.needs
needs字段指定當前任務的依賴關係,即運行順序。
jobs: job1: job2: needs: job1 job3: needs: [job1, job2]
上面代碼中,job1必須先於job2完成,而job3等待job1和job2的完成才能運行。因此,這個 workflow 的運行順序依次為:job1、job2、job3。
(6)jobs.<job_id>.runs-on
runs-on字段指定運行所需要的虛擬機環境。它是必填字段。目前可用的虛擬機如下。
ubuntu-latest,ubuntu-18.04或ubuntu-16.04windows-latest,windows-2019或windows-2016macOS-latest或macOS-10.14
下面代碼指定虛擬機環境為ubuntu-18.04。
runs-on: ubuntu-18.04
(7)jobs.<job_id>.steps
steps字段指定每個 Job 的運行步驟,可以包含一個或多個步驟。每個步驟都可以指定以下三個字段。
jobs.<job_id>.steps.name:步驟名稱。jobs.<job_id>.steps.run:該步驟運行的命令或者 action。jobs.<job_id>.steps.env:該步驟所需的環境變量。
下面是一個完整的 workflow 文件的範例。
name: Greeting from Mona on: push jobs: my-job: name: My Job runs-on: ubuntu-latest steps: - name: Print a greeting env: MY_VAR: Hi there! My name is FIRST_NAME: Mona MIDDLE_NAME: The LAST_NAME: Octocat run: | echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.
上面代碼中,steps字段只包括一個步驟。該步驟先注入四個環境變量,然後執行一條 Bash 命令。
四、實例:React 項目發佈到 GitHub Pages
下面是一個實例,通過 GitHub Actions 構建一個 React 項目,併發布到 GitHub Pages。最終代碼都在這個倉庫裡面,發佈後的參考網址為ruanyf.github.io/github-actions-demo。
第一步,GitHub Actions 目前還處在測試階段,需要到這個網址申請測試資格。申請以後,可能需要幾天才能通過。據說,2019年11月就會放開。
獲得資格後,倉庫頂部的菜單會出現Actions一項。

第二步,這個示例需要將構建成果發到 GitHub 倉庫,因此需要 GitHub 密鑰。按照官方文檔,生成一個密鑰。然後,將這個密鑰儲存到當前倉庫的Settings/Secrets裡面。

上圖是儲存秘密的環境變量的地方。環境變量的名字可以隨便起,這裡用的是ACCESS_TOKEN。如果你不用這個名字,後面腳本里的變量名也要跟著改。
第三步,本地計算機使用create-react-app,生成一個標準的 React 應用。
$ npx create-react-app github-actions-demo $ cd github-actions-demo
然後,打開package.json文件,加一個homepage字段,表示該應用發佈後的根目錄(參見官方文檔)。
"homepage": "https://[username].github.io/github-actions-demo",
上面代碼中,將[username]替換成你的 GitHub 用戶名,參見範例。
第四步,在這個倉庫的.github/workflows目錄,生成一個 workflow 文件,名字可以隨便取,這個示例是ci.yml。
我們選用一個別人已經寫好的 action:JamesIves/github-pages-deploy-action,它提供了 workflow 的範例文件,直接拷貝過來就行了(查看源碼)。
name: GitHub Actions Build and Deploy Demo on: push: branches: - master jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@master - name: Build and Deploy uses: JamesIves/github-pages-deploy-action@master env: ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} BRANCH: gh-pages FOLDER: build BUILD_SCRIPT: npm install && npm run build
上面這個 workflow 文件的要點如下。
- 整個流程在
master分支發生push事件時觸發。- 只有一個
job,運行在虛擬機環境ubuntu-latest。- 第一步是獲取源碼,使用的 action 是
actions/checkout。- 第二步是構建和部署,使用的 action 是
JamesIves/github-pages-deploy-action。- 第二步需要四個環境變量,分別為 GitHub 密鑰、發佈分支、構建成果所在目錄、構建腳本。其中,只有 GitHub 密鑰是秘密變量,需要寫在雙括號裡面,其他三個都可以直接寫在文件裡。
第五步,保存上面的文件後,將整個倉庫推送到 GitHub。
GitHub 發現了 workflow 文件以後,就會自動運行。你可以在網站上實時查看運行日誌,日誌默認保存30天。

等到 workflow 運行結束,訪問 GitHub Page,會看到構建成果已經發上網了。

以後,每次修改後推送源碼,GitHub Actions 都會自動運行,將構建產物發佈到網頁。
五、參考鏈接
- GitHub Pages 官方文檔
- Github Actions for web apps, Luke Boyle
- My First Week With GitHub Actions, Adam Zolyak
(完)












