一文會用 github 新利器——github ci

tangding12發表於2020-11-23

github ci 是什麼

  github ci 是 github 提供的一個依據 git 相關事件觸發的自動化指令碼服務。簡單的說,當觸發github的事件(push/pull request等)後,github官方會提供一個伺服器環境,自動的執行先前配置的指令碼,差不多近似於 gitlab 的 ci。

為專案建立 github ci

  github 來檢測專案是否存在 github ci 就是檢視該專案根目錄下的.github/workflows是否存在yml的配置檔案。因此可以通過在根目錄下建立 .github/workFlows 資料夾,再建立對應的 .yml 結尾的檔案的方式,來為專案建立 github ci。

  github 官網支援在專案中用視覺化的方式來建立 github ci。如下圖,在專案主目錄的 Actions 欄目下,點選藍色的 set up a workflow yourself 可以直接為專案建立 github ci。
Actions

  點選後可以發現,github 建立了一個預設名為 [分支名].yml 的ci模板檔案,該檔案位於專案的 /.github/workflows 檔案目錄下。
workflows
  github ci 配置採用 yml 的語法。yml 類似於 json,是一種標準化資料格式常用於專案的配置。它近似於python的語法,使用 tab 來標識縮排,用 # 來表示註釋。具體語法可以看這裡

  在 github 上面建立配置檔案的時候,github會生成預設的範例。

# name 標識一下這個 ci 檔名稱,純語義化的項,沒有配置意義
name: demo

# on 配置項用於配置該倉庫的什麼分支觸發什麼事件後進行該 ci 的呼叫
on:
  # master 分支 push 後觸發
  push:
    branches: [ master ]
  # master 分支 pull_request 後觸發
  pull_request:
    branches: [ master ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# jobs是一個功能指令碼的維度集合。比如配置檢測庫語法,釋出庫,可以作為兩個工作(job)。一個yml檔案可以執行多個job。
jobs:
  # 一個jobs擁有 setup / build / test 的秩序執行單元。這個維度大於 steps 小於 jobs。
  build:
    # 該操作跑在什麼環境之下,支援 Ubuntu/Windows/macOS。
    runs-on: ubuntu-latest

    # step 標識一系列按續執行的最小工作單元
    steps:
      # uses 標識使用建立好的功能指令碼,actions/ 標識了這是github公開的指令碼庫
      # 這裡使用了一個名為 checkout@v2 的指令碼檔案。
      - uses: actions/checkout@v2

      # 執行單個的 shell
      - name: Run a one-line script
        run: echo Hello, world!

      # 執行多個 shell
      - name: Run a multi-line script
        run: |
          echo Add other actions to build,
          echo test, and deploy your project.

  再具體的書寫方法和配置資訊可以點選這裡檢視 github 官方文件。

  瞭解預設配置之後,試著書寫一個最簡單的 ci 配置資訊檢視一下執行的情況。這裡設定一個名為echo demo的檔案在 master 分支 push 的時候觸發。輸出一個pwdls -al來檢視一下實際的執行環境。順帶一提,由於某些今年的原因,github的預設分支不在使用 master,而更改為 main 分支。實際操作的時候注意操作的分支和配置的分支一致。

name: echo demo
on:
  push:
    branches: [ master ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: run demo
        run: pwd
        run: ls -al

  配置完畢後使用push提交。這時候切換到Actions分欄下,可以看到對應的ci執行資訊。
Actions

  點選進入 ci 的 workflow 可以看到這次命令的執行結果。github ci 實際上是分配給了專案一小塊伺服器空間,在這個伺服器空間中可以對專案進行任何對應的命令操作。pwd 輸出值顯示目前位於/home/runner/work/actions-demo/actions-demo檔案下,ls -al顯示檔案內沒有任何檔案,目前的操作位於 docker 環境。
github ci

  接下來深入一下,看看github到底給予了多少許可權。修改配置檔案嘗試進入到 root 目錄去新建一個檔案。

name: echo demo
on:
  push:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: move to root
        run: |
          cd /
          touch demo.txt

github ci shell

  結果可以看到cd /成功,但是操作檔案失敗了。github ci 提供了一個完整的伺服器環境和專案維度下的子賬號許可權。實際上ci也可以使用 sudo 許可權,僅僅需要在配置檔案進行配置,具體內容可以點選這裡檢視。

github ci 應用例項

  這一章例項來實現一個github ci的自動化部落格部署。實現的功能大致為:當在本地更新推送一篇博文之後,github ci能連結到伺服器對應網站拉取最新的程式碼,然後執行npm構建,把最新更新的博文釋出出去。

  與 gitlab 不同, github 的指令碼執行環境實在github提供的官方伺服器上面,不能像gitlab那樣擁有直接操作配置伺服器的能力,更多是偏向公共包的一些應用。根據 github 文件,github ci 的本意是對於一些公共包的處理,比如上傳一些公共的 npm 包後自動進行程式碼的格式檢測,檢測無誤後進行包的釋出,或者使用者對公開的庫提 pull request 或者 issue 之後,進行基本的樣式檢驗和處理。

  其次github是一個開源網站,配置的 .github/workflows 會以明文的方式暴露到開源庫中。使用 ssh 方式進行伺服器連結的時候使用者名稱和密碼會被暴露到庫當中。

  這裡使用 github 提供的 Secrets 功能來解決問題。在專案的setting 欄目下 選中 Secrets 即可進入 Secrets 配置頁面。Secrets 可以在專案維度下以key - value的形式儲存一些值,這些值不會在庫中公開,也不會被 pull request 拉取。在使用github ci的時候,可以用
${{secrets}}.[key]的方式來宣告 Secrets 中的 key,這些宣告的部分會被替換為 value。

github Secrets

  現在來編寫部落格庫的 github ci 檔案完成這個例項。首先新建 .github.workflows 目錄建立 buildblog.js.yml 檔案。完成基本的配置,監聽的事件為 push 事件,分支為 master 分支。

  其次來編寫對應的指令碼檔案。連線到釋出伺服器需要使用到 sshpass 命令,它能夠直接把伺服器密碼傳遞給ssh指令,還不是在輸入ssh指令之後敲回車再次進行密碼的輸入。接著在 ssh 指令後面加上-o StrictHostKeyChecking=no引數,github 每次分配 ci 執行的伺服器 ip 是不同的,防止首次 ssh 連線的時候安全策略讓你輸入確認連線輸入 yes。最後在 ssh 命令後面加上需要繼續執行的指令碼 'cd 目錄 && git pull && npm run build'。然後在使用者名稱和密碼的部分使用剛才所說的 Secrets 中配置的key - value 中的 key 即可完成自動化構建部落格的功能了。具體配置檔案資訊如下,也可以點選這裡檢視部落格專案的具體配置。

name: build-blog CI

on:
  push:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [14x]

    steps:
      - run: sshpass -p ${{secrets.SECRET}} ssh -o StrictHostKeyChecking=no ${{secrets.NAME_USER}} 'cd ${{secrets.PATH}} && git pull && npm run build'

  如果是在個人部落格觀看的話,這篇 github ci 的博文就是使用自動化部署上去的哦~

相關文章