GitHub Actions 入門教程

作者: 阮一峰

日期: 2019年9月12日

騰訊課堂 NEXT 學院

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/[email protected] # 指向一個 commit
actions/[email protected]    # 指向一個標簽
actions/[email protected]  # 指向一個分支

二、基本概念

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_jobmy_second_job

(5)jobs.<job_id>.needs

needs字段指定當前任務的依賴關系,即運行順序。


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

上面代碼中,job1必須先于job2完成,而job3等待job1job2的完成才能運行。因此,這個 workflow 的運行順序依次為:job1job2job3

(6)jobs.<job_id>.runs-on

runs-on字段指定運行所需要的虛擬機環境。它是必填字段。目前可用的虛擬機如下。

  • ubuntu-latestubuntu-18.04ubuntu-16.04
  • windows-latestwindows-2019windows-2016
  • macOS-latestmacOS-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/[email protected]

    - name: Build and Deploy
      uses: JamesIves/[email protected]
      env:
        ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
        BRANCH: gh-pages
        FOLDER: build
        BUILD_SCRIPT: npm install && npm run build

上面這個 workflow 文件的要點如下。

  1. 整個流程在master分支發生push事件時觸發。
  2. 只有一個job,運行在虛擬機環境ubuntu-latest
  3. 第一步是獲取源碼,使用的 action 是actions/checkout
  4. 第二步是構建和部署,使用的 action 是JamesIves/github-pages-deploy-action
  5. 第二步需要四個環境變量,分別為 GitHub 密鑰、發布分支、構建成果所在目錄、構建腳本。其中,只有 GitHub 密鑰是秘密變量,需要寫在雙括號里面,其他三個都可以直接寫在文件里。

第五步,保存上面的文件后,將整個倉庫推送到 GitHub。

GitHub 發現了 workflow 文件以后,就會自動運行。你可以在網站上實時查看運行日志,日志默認保存30天。

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

以后,每次修改后推送源碼,GitHub Actions 都會自動運行,將構建產物發布到網頁。

五、參考鏈接

(完)

留言(32條)

這樣貌似可以制作靜態博客網站

現在使用 netlify 和 GitHub Pages 配合 actions 搭建個人站點,再加上公共 CDN,體驗很好了。

引用Rw的發言:

這樣貌似可以制作靜態博客網站

甚至可以動態吧

為啥我在github上還看不到action

我的Hexo博客 終于可以不用自己那一套Hook了.... 這個方法感覺優雅多了。

引用小兵的發言:

為啥我在github上還看不到action

要github審核通過才有

我之前用的hook 加jenkins.這個action 看起來能替代我之前的流程

正驚訝今天怎么沒等到科技愛好者周刊,才想起來還沒到周五呢

阮老師中秋快樂!

runs-on 可以使用自定義的image嗎?如果test任務依賴mysql,如何解決呢?

要是介紹一波自己寫的 action 就好了, 我現在一直卡死在 push 處, 上不去.

感覺和Travis CI區別不大

自定義的trigger? Server less?

阮大神可以講講react+dva-cli嗎,我最近在寫但是,看了官方文檔還是,不太懂

剛剛試了,action權限秒開....突然萌生出一個想法,舍棄hexo,用react自己寫個。這樣我的博客主題我做主。哈哈哈哈哈哈哈。

阮一峰老師,您有一個地方沒寫,就是要在 package.json 中加入 homepage 字段,否則github pages會找不到 js 和 css 文件。

發現Fork之后不會運行,可以自己建個倉庫再把阮老師的代碼push上去,我運行的效果https://github.com/gaohanghang/github-actions-demo/actions

@鄭明遠:

謝謝指出,我確實忘了,已經補上。

請問這個怎么配置到github pages上呢?

申請就通過

感謝阮大大分享。說的很詳細很清晰,立馬申請個action試試!

另外,提一點個人淺見。 文中提到的“秘密變量”,如果改成叫“私密變量” 會不會好理解一些? 出現地方有:

1:

```
上圖是儲存[秘密]的環境變量的地方。環境變量的名字可以隨便起,這里用的是ACCESS_TOKEN。
```

改成=》

```
上圖是存儲私密的環境變量的地方。…………
```

2:

```
第二步需要四個環境變量,分別為 GitHub 密鑰、發布分支、構建成果所在目錄、構建腳本。其中,只有 GitHub 密鑰是[秘密變量],需要寫在雙括號里面,其他三個都可以直接寫在文件里。
```

改成=>

```
…………其中,只有 GitHub 密鑰是私密變量,…………
```

個人淺見,說的不對的地方還請見諒。

有個問題:僅執行 npm install && npm run build 沒有運行 gh-pages -d build 為什么會自動生成 gh-pages 分支呢?(我的 https://[user.name].github.io 是新建的一個項目名字叫做 [user.name].github.io )

感謝大佬。嘗試做一個基于vuepress的靜態博客,自己寫的action腳本老出問題,參考這個一次成功。

引用simon-woo的發言:

有個問題:僅執行 npm install && npm run build 沒有運行 gh-pages -d build 為什么會自動生成 gh-pages 分支呢?(我的 https://[user.name].github.io 是新建的一個項目名字叫做 [user.name].github.io )

分支和推送分支包括一些目錄對應之類的處理都在引用的那個action腳本里JamesIves/[email protected]

如果是常規的開發流程,打包好Push到Github,自動發布到公司服務器,怎么建立Github與公司服務器的聯系?

可以執行CI,但是怎么在gitpage查看到效果呢

為什么CI執行action完成之后,gitpage要刷新好久才能出來

引用simon-woo的發言:

如果是常規的開發流程,打包好Push到Github,自動發布到公司服務器,怎么建立Github與公司服務器的聯系?

我用這個插件 easingthemes/[email protected] 可以打包發到服務器

老師您好,我想請問一下如果我之前使用hexo部署了我的博客,地址是我的[username].github.io,現在再使用action部署上去訪問就會404,我是應該把原先的博客也使用action的方式部署么?謝謝老師解惑

我的情況看來和@Echo一樣,部署完也是404

我用github action 搭建了自己的hexo blog https://dev4mobiles.com,
源碼在develop 分支上: https://github.com/dev4mobile/dev4mobile.github.io

引用Echo的發言:

老師您好,我想請問一下如果我之前使用hexo部署了我的博客,地址是我的[username].github.io,現在再使用action部署上去訪問就會404,我是應該把原先的博客也使用action的方式部署么?謝謝老師解惑

同樣的問題...

我要發表看法

«-必填

«-必填,不公開

«-我信任你,不會填寫廣告鏈接

上海时时乐彩经网