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 設定  - 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
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.