GitHub Actions CI:導入與優化 ESLint 檢查

目錄

  1. 基本配置
  2. GitHub Actions 權限配置
  3. 速度優化
  4. 完整範例腳本

1. 基本配置

步驟 1:安裝必要的套件

首先,安裝 ESLint 和相關的插件。由於我們的專案是基於 React 的,所以多安裝 eslint-plugin-react:

npm install eslint eslint-plugin-react --save-dev

步驟 2:配置文件

接下來,我們需要建立幾個配置文件:

GitHub Actions 工作流程文件(.github/workflows/check.yml

這個文件負責在每次 Pull Request 時進行 ESLint 檢查。

name: ESLint Check # 工作流程名稱
on:
  pull_request:
    branches: [master] #  Pull Request 針對 master 分支進行時觸發此工作流程
jobs:
  eslint:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14.21.2] # 指定 Node 版本
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # 完整Clone倉庫以確保獲取所有歷史紀錄
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install Packages # 安裝專案所需的 npm 依賴
        run: npm install
      - name: Lint check # 執行 ESLint 檢查
        # 僅檢查與 master 分支不同的文件
        run: git diff --name-only --diff-filter=d origin/master...HEAD | grep -E '\.(js|jsx|ts|tsx)$' | xargs npx eslint --quiet -c .eslintrc.js

最後 ESLint 檢查的指令有點長,
git diff --name-only --diff-filter=d origin/master...HEAD | grep -E '\.(js|jsx|ts|tsx)$' | xargs npx eslint --quiet -c .eslintrc.js

它要做的是只檢查此次的修改(也就是與 master 分支不同的文件),且只對 js 相關檔案做檢查

  • git diff 列出與 master 分支不同的文件
  • –name-only 只顯示文件名
  • –diff-filter=d 過濾掉被刪除的文件
  • origin/master…HEAD 用於比對當前分支和 master 分支之間的變化
  • grep 過濾出 JavaScript 和 TypeScript 文件 (.js, .jsx, .ts, .tsx)
  • xargs 將文件名傳給 ESLint 進行靜態檢查
  • –quiet 讓 ESLint 只顯示錯誤,不顯示警告
  • -c .eslintrc.js 指定 ESLint 的配置文件

當然,這部分你可以依據你的需求去調整

ESLint 忽略文件(.eslintignore

這個文件用來指定哪些文件或目錄不需要進行 ESLint 檢查。

.next
node_modules
package.json
package-lock.json
.eslintrc.js
.eslintignore
next.config.js

ESLint 配置文件(.eslintrc.js

ESLint 的規則。

module.exports = {
  root: true,
  // 指定程式運行的環境
  env: {
    browser: true,
    node: true,
    es2021: true,
  },
  // 擴展
  extends: [
    "eslint:recommended", // 使用 ESLint 官方推薦的基本規則
    "plugin:react/recommended", // 使用 React 插件推薦的基本規則
    "plugin:react/jsx-runtime",
  ],
  // 解析器選項
  parserOptions: {
    ecmaVersion: "latest", // 使用最新的 ECMAScript 語法
    sourceType: "module", // 指定使用 ES 模組
    requireConfigFile: false, // 不需要這些額外的配置文件,直接使用 ESLint 本身的配置
  },
  settings: {
    react: {
      version: "detect", // 自動檢測正在使用的 React 版本
    },
  },
  rules: {
    // ESLint 規則
  },
};

另外如果是 next.js 專案,預設會在 build 時 run ESLint 檢查,如想關掉,在 next.config 加上

eslint: {
    ignoreDuringBuilds: true,
},

2. GitHub Actions 權限配置

公司內部有共用的模組獨立出來是很常見的事。但如果在 package.json 中,有私人的 repo 要安裝,我們就得為 GitHub Action 配置權限,不然 GitHub Action 在執行 npm install 時,會因為沒權限下載 repo 而報錯

步驟 1:生成 GitHub PAT (Personal Access Token)

  1. 登錄 repo 管理者的 GitHub 賬戶,進入「Settings」→「Developer settings」→「Personal access tokens」→「Tokens (classic)」。
  2. 點擊「Generate new token」,輸入描述並選擇所需權限。
  3. 生成並保存 Token。注意:Token 只會顯示一次,請妥善保存。

步驟 2:在 GitHub repo 中添加 Secret

  1. 進入需要配置 CI 的 repo 的「Settings」→「Secrets and variables」→「Actions」。
  2. 點擊「New repository secret」,設置名稱(如 TOKEN)並輸入 PAT,保存。

步驟 3:修改工作流程文件

在工作流程文件中添加:

- run: git config --global url."https://${{ secrets.TOKEN }}@github.com/".insteadOf "https://github.com/"

步驟 4:憑證設置

actions/checkout@v3 步驟中設置 persist-credentials: false
這個用途是不使用 GitHub Actions 自動生成的憑證。確保工作流程使用我們設置的 PAT (Personal Access Token) 進行認證。

3. 速度優化

身為工程師,看到每次 CI 都得執行 npm install,實在感覺有優化的必要,不然太浪費時間和資源了。

優化方案

  1. 使用npm ci替換npm install
    npm ci 如其名,專門給 CI 用的,速度快很多。
  2. 添加緩存機制
    如果 node_modules 已經存在,且 package-lock.json 沒有變化,那我們直接使用就好了,不需要再做npm ci的動作
- name: Cache Node Modules
  uses: actions/cache@v2
  with:
    path: node_modules
    key: node-modules-${{ runner.os }}-${{ matrix.node-version }}-${{ hashFiles('package-lock.json') }}
- name: Install Packages
  run: test -d node_modules && echo "node_modules exists" || npm ci

4. 完整範例腳本

name: Check
on:
  pull_request:
    branches: [master]
jobs:
  check:
    name: Check
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14.21.2]
    steps:
      - uses: actions/checkout@v3
        with:
          persist-credentials: false
          fetch-depth: 0
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - run: git config --global url."https://${{ secrets.TOKEN }}@github.com/".insteadOf "https://github.com/"

      - name: Cache Node Modules
        uses: actions/cache@v2
        with:
          path: node_modules
          key: node-modules-${{ runner.os }}-${{ matrix.node-version }}-${{ hashFiles('package-lock.json') }}
      - name: Install Packages
        run: test -d node_modules && echo "node_modules exists" || npm ci
      - name: Lint check
        run: git diff --name-only --diff-filter=d origin/master...HEAD | grep -E '\.(js|jsx|ts|tsx)$' | xargs npx eslint --quiet -c .eslintrc.js

Reference:
在 GitHub Action 優化 Node.js App 的環境建置

Similar Posts