使用 GitHub Actions 發佈 Vite 專案到另一個存放庫
使用 GitHub Actions 發佈 Vite 專案到另一個存放庫
前言
本篇文章會以發佈一個 Vite 專案為案例來介紹 GitHub Actions
目標是將一個 Vite 專案的原始碼放在私有的存放庫,
將打包後的靜態網站放在公開的存放庫。
一般網路上的教學都是推送到同一個存放庫,
使用手動或 GitHub Actions 另外開一個 gh-pages 分支,
設定 Github Pages 抓取 gh-pages 分支來抓取靜態網站的內容。
但是當免費仔也是有代價的!
如果要用 Github Pages 來發佈網站,
要將整個存放庫公開或是掏出魔法小卡給微軟
要公開或是花錢二選一,那怎麼辦呢?
小孩子才做選擇!我全都要!
事前準備
建立存放庫
為了本次教學我們先在自己的 GitHub 建立兩個存放庫
一個私有的放 Vite 專案原始碼
一個公開的放 Vite 專案打包完畢的資料夾目錄
建立 Vite 專案
建立 Vite 專案可以參考官方的教學文件
npm create vite@latest
預覽專案
npm run dev
專案如果成功建置會出現這個範例畫面,
咱們就直接拿初始專案來當範例 XD
路徑設定補充說明
因為剛剛我們的測試專案的存放命名是 vite-demo
,
在 Github Pages 發佈的網址規則會是 https://<USERNAME>.github.io/<REPO>
所以要在 Vite 專案設定基本路徑才能正確打包
官方的路徑設定相關教學
GitHub Pages base
推送專案原始碼
把原始碼專案推送到遠端存放庫,
喜歡用 VSCode 的版本控制工具推送,
還是喜歡硬派 CLI 下命令都可以。
到這邊我們已經完成事前準備了
接下來開始準備著手打包後的專案
發佈網站
土法煉鋼
為了避免淪於不求甚解而照抄指令,
所以先不直接進入主題。
一開始先從使用土法煉鋼來達成我們期望的目標,
期望對於之後整個工作流程指令撰寫更清晰。
建置專案
如果要發佈打包後的專案,
最簡單的做法就是在原本的專案下命令建置專案,
然後把打包後的目錄推送到公開的存放庫。
npm run build
執行建置命令打包專案後會出現 dist
資料夾目錄
官方的打包相關教學
GitHub Pages Building the App
推送打包後的專案目錄
直接將 dist
資料夾目錄推送到公開的存放庫,
要用 GUI 介面或 CLI 介面都可以。
設定 Github Pages 的對應分支
到發佈專案的存放庫設定 Github Pages
點進綠框的 Pages 分頁
在紅框的設定要抓取的分支後存檔
稍待片刻就會看到黃框的超連結
段落小結
上面的步驟是手動的方式來部屬專案,
每次改好網站都要重複上面的步驟,
推送原始碼到遠端存放庫之後,
還要記得把打包後的目錄推送到另一個存放庫
久了還是很麻煩,甚至可能會忘記。
如果能把剛剛的土法煉鋼手工活自動執行,
當原始碼更新完畢後自動打包專案並發佈在公開存放庫,
那這樣就太好了。
GitHub Actions
CI/CD 與 DevOps
要談到 GitHub Actions 之前要先簡單談談 CI/CD
當大家去 Google 關鍵字常常看到像這樣的圖
其中以下 CI/CD 指的是以下兩點
- CI(Continuous Integration)持續整合
- CD(Continuous Deployment)持續部署
這是目前軟體開發領域的重要精神,
將 「規劃、開發、建置、測試、發佈、運作、監控」這些頻繁且重複的工作用工具或服務來自動化。
確保開發環境的一致性,也能減少測試的時間成本,進而提升軟體品質,
通常會是由 DevOps
來負責建置這樣的開發環境。
基本介紹
終於來到今天的重點了!!
所以 GitHub Actions 是什麼呢?
其實就是 Github 提供的 CI/CD 自動化服務,
也就是把剛剛土法煉鋼的手動行為變自動執行,
這邊要強調的是 CI/CD 只是一個軟體開發觀念,
GitHub Actions 也只是其中一項工具,
例如外面許多公司都會用 Jenkins 來做部屬,
甚至即便寫 bash 腳本也是可行的一種方案(雖然就現在來看是滿辛苦的)。
官方文件
要知道如何撰寫自動化腳本要先看看官方文件。
雖然右上角有中文翻譯,
但我猜很多人不可能真的去看完(因為我也是 XD),
所以這邊直接講重點。
如何建立
這裡提供兩種方法,大家可以挑自己喜歡的方式。
在 VSCode 上建立
一種是從 VSCode 自己建立
官方文件中的快速入門也是這個方法
在專案目錄建立資料夾 .github/workflows
,並建立一個副檔名為 yml
的檔案。
本次範例我們就建立一個 lgithub-actions-demo.ym
在 GitHub 上建立
在 GitHub 上也是可以直接編輯程式碼並送交,
如果要在 GitHub 上建立自動化流程也是可行的做法,
線上做的好處就是有一些範本可以直接拿來參考,
這邊把圖文步驟放上來。
點擊紅框的選單Actions
的選單
可以選下面的範本或是紅框處自己建立
然後就會進入編輯畫面了,檔名可以自己定義。
右邊的 Marketplace 可以直接使用來簡化指令,
主要是一些可重複使用的指令,例如簽出程式碼、發佈檔案到指定分支,
透過一些參數設定可以更輕鬆完成自動化。
關於可複用指令的官方介紹可以看 jobs.<job_id>.steps[*].uses
右邊還有一些片段的語法可以參考,但建議還是直接去官方文件看比較詳細。
官方語法文件
撰寫建議
撰寫自動化指令的建議順序如下:
- 使用官方提供的指令,點進去可以查看各個功能是否符合需求。
- 使用 Marketplace 找別人寫好的。
- 參考各框架的官方文件的範例,例如 Vite 的範例。
- 真的都沒有才自己動手寫。
撰寫範例
因為是 Vite 專案,所以參考官方的部屬範例,
後面跨存放庫推送則是使用其他人的 Actions,
相關的說明可以參考 cpina/github-action-push-to-another-repository
# workflow 名稱
name: Deploy Vite Project To Vite Page
# 設定觸發條件
on:
# 當推送 main 分支
push:
branches: ["main"]
# 為了方便線上測試允許手動執行 workflow
workflow_dispatch:
# 修改授予 GITHUB_TOKEN 的預設權限,根據需要新增或刪除訪問權限,以便只授予所需的最低訪問權限
permissions:
contents: write
pages: write
id-token: write
# 設定同時併發的處理
concurrency:
group: "pages"
cancel-in-progress: true
# 要執行的工作描述
jobs:
deploy-vite-page:
name: Deploy To Vite Page
# 定義要運行作業的計算機類型。
runs-on: ubuntu-latest
# 定義各項工作的步驟順序
steps:
# 簽出分支
- name: Checkout
uses: actions/checkout@v3
# 下載與設定 Node.js
- name: Set up Node
uses: actions/setup-node@v3
with:
# 指定下載的版本
node-version: 18
# 用於指定套件管理器在預設目錄中進行暫存
cache: "npm"
# 透過 Node.js 安裝前端套件
- name: Install dependencies
run: npm install
# 建置專案
- name: Build
run: npm run build
# 將建置目錄放置到另一個存儲庫
- name: Deploy To Other Oepository
uses: cpina/github-action-push-to-another-repository@main
env:
# 公鑰變數名稱
SSH_DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
with:
source-directory: "dist/"
# 存放庫的使用者名稱
destination-github-username: "pamis-wang"
# 存放庫的專案名稱
destination-repository-name: "vite-demo"
user-name: "Example"
user-email: "example@gmail.com"
target-branch: "main"
# 如果推送分支不存在就建立分支
create-target-branch-if-needed: true
設定權限
如果直接執行會出現以下錯誤
因為沒有設定公鑰私鑰發生權限不足導致推送失敗
新增私鑰
存放庫的設定選單,並在側邊選單選擇 Secrets and variables
內的 Actions
變數名稱要和上面工作流程的變數 ${{ secrets.DEPLOY_KEY }}
相同,
所以標題要命名為 DEPLOY_KEY
。
新增公鑰
由於跨倉庫,所以要把公鑰貼在要部屬的存放庫,
這樣才有推送到目的地存放庫的權限,
存放庫的設定選單,並在側邊選單選擇 Deploy keys
標題一樣要命名為 DEPLOY_KEY
。
使用限制
免費仔還是有些限制的,
公開專案不受限制,
私有專案有每個月免費的時間額度,
不過一般私人使用也用不太到這種用量。