2023/10/07 # GitHub Actions 實現自動化部署流程 (Deploy Workflow for GitHub Pages) ## 前言 承[上一篇文章](https://hackmd.io/@pericode/BkcNtoPl6)手動部署 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 ## 使用工具及前置作業 - 以下示範的專案是採用`vite`及`pnpm`作為開發工具,實際請依照自己使用的工具修改。 - 已建立好的 GitHub Repository 遠端庫 - 生成一個 GitHub 令牌: Personal access tokens ## Environments 設定 ![](https://hackmd.io/_uploads/rkHVcb9-p.png) - DEPLOY_TOKEN 設置了GitHub令牌。 - VITE_API 設置Vite專案中使用到的API key。 ## Workflow 工作流程 Workflow 的檔案名稱可以任意取,只要副檔名為`.yml`或`.yaml`都可,以我設置的`static.yml`為例,使用的套件管理工具為`pnpm`,以下是這次為自動部署 GitHub Pages 設置的 Workflow 內容,參考[Vite官方文件](https://vitejs.dev/guide/static-deploy.html#github-pages): ``` # 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 ([參考上一篇文章](https://hackmd.io/@pericode/BkcNtoPl6)), 這個過程中並不需要在 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`。 ## 參考 - vite官方文件: https://cn.vitejs.dev/guide/static-deploy.html#github-pages - GitHub Token: https://docs.github.com/en/actions/security-guides/automatic-token-authentication - https://juejin.cn/post/7202127250643796024 - https://juejin.cn/post/7213548316981526586