Try   HackMD

2023/10/07

GitHub Actions 實現自動化部署流程 (Deploy Workflow for GitHub Pages)

前言

上一篇文章手動部署 GitHub Pages,專案在 GitHub 遠端儲存庫已有main、gh-pages兩個分支,其中 main 作為開發更新的主要分支,gh-pages作為遠端部署 github pages 的來源,那麼我在本地更新程式碼並遞交程式碼,然後執行推送到遠端部署分支的命令:git subtree push --prefix dist origin gh-pages,每次部署都要重複同樣的瑣碎命令和流程,能不能將這個部署流程自動化? 當然可以! 只要撰寫腳本就行了。

實現自動部署功能

建立自動部署腳本的常見方式包含在本地專案創建deploy.sh腳本文件,或是藉由建立以 YAML (.yml)文件編寫的 Workflow 來控制一連串 GitHub Actions 來達到目的。
以本次專案為例,這個自動部署的功能如下:
當本地專案更新push推送至 GitHub 遠端庫 main 分支時,利用Workflow自動觸發 GitHub Actions 建構及部署等等指令,來達成程式碼更新並自動部署 GitHub Pages 靜態網頁的目的。

GitHub Actions

簡單來說,每個 Action 都是功能獨立的腳本,例如抓取程式碼、執行測試、登入遠端伺服器、設定指定 Node 環境等,GitHub Actions 就是各種 Action 操作集合而成。
GitHub Actions 的 Workflow 是以 YAML 文件進行設定 (副檔名為.yml.yaml)。
如果想更多了解關於 GitHub Actions ,推薦一篇不錯的文章: https://www.ruanyifeng.com/blog/2019/09/getting-started-with-github-actions.html

使用工具及前置作業

  • 以下示範的專案是採用vitepnpm作為開發工具,實際請依照自己使用的工具修改。
  • 已建立好的 GitHub Repository 遠端庫
  • 生成一個 GitHub 令牌: Personal access tokens

Environments 設定

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  • DEPLOY_TOKEN 設置了GitHub令牌。
  • VITE_API 設置Vite專案中使用到的API key。

Workflow 工作流程

Workflow 的檔案名稱可以任意取,只要副檔名為.yml.yaml都可,以我設置的static.yml為例,使用的套件管理工具為pnpm,以下是這次為自動部署 GitHub Pages 設置的 Workflow 內容,參考Vite官方文件:

 # Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages

on:
  # Runs on pushes targeting the default branch
  push:
    branches: ['main']

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

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow one concurrent deployment
concurrency:
  group: 'pages'
  cancel-in-progress: true

jobs:
  # Single deploy job since we're just deploying
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set up Node
        uses: actions/setup-node@v3
        with:
          node-version: 18
      - name: Install PNPM
        run: npm i -g pnpm
      - name: Install dependencies
        run: pnpm install
      - name: Build
        run: pnpm build
        env:
          VITE_API: ${{ secrets.VITE_API }}
      - name: Setup Pages
        uses: actions/configure-pages@v3
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v2
        with:
          # Upload entire repository
          path: './dist'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v2

以上需要注意的是:

  • YAML 以換行符號與縮排方式進行語法區隔,多餘的空白或Tab是不被允許的,我是先在 VSCode 編輯器裡編輯修改,完成後和程式碼一起推送到遠端庫。
  • 使用 pnpm 必須在安裝專案套件指令之前增加一個安裝 pnpm 的指令,否則部署會失敗。如果使用 npm 則不需要這個指令。
      - name: Install PNPM
        run: npm i -g pnpm
  • 若本地專案中有使用環境變數設定(.env.local),在本地手動用 vite 打包生成 dist 目錄,推送至遠端並成功部署 Github Pages (參考上一篇文章), 這個過程中並不需要在 GitHub 設 Environment secrets,網頁可以正常運作,這是因為 vite 在build打包的過程中已經將環境變數包進去。
    所以在規劃部署流程時,這個環境變數必須要在build時提供,否則網頁會無法正常顯示或執行。
    - name: Build
        run: pnpm build
        env:
          VITE_API: ${{ secrets.VITE_API }}
  • 即使上述 Workflow 內容並未明確將 GITHUB_TOKEN 傳遞給 GitHub Actions,GitHub Actions 仍然可以通過github.token上下文訪問 GITHUB_TOKEN。我們只要設置權限即可:
permissions:
  contents: read
  pages: write
  id-token: write

可能遇到的問題

git push 失敗

console 報錯如下:

To https://github.com/periondev/vue-project.git
 ! [remote rejected] main -> main (refusing to allow an OAuth App to create or update workflow `.github/workflows/static.yml` without `workflow` scope)
error: failed to push some refs to 'https://github.com/periondev/vue-project.git'

FIX

  • 首先檢查 github Token 勾選的權限設定,務必包含workflow,確認勾選後儲存,再次執行git push
  • 若 github Token 早已勾選workflow,那麼問題可能與本地登入驗證有關,命令列執行:

gh auth login scopes workflow

之後需回覆一連串設定,按照流程驗證並登入之後,再執行git push

參考