GitHub Actions 跟 GitLab CI 有著不少差異,雖然在這類工具中不外乎就是生產線(Pipeline)和任務(Task)的搭配使用,然而每套系統都還是有著不同的設計可以使用。
因為我比較常使用 GitLab CI 因此有著完整的樣板專案可以使用,目前還在建置 GitHub Actions 的樣板,這篇文章主要是我在 GitHub 上面的專案所彙整出來的使用技巧。
GitHub Actions 基礎概念
跟 GitLab CI 不同的地方在於,整個 GitHub Actions 允許有多個工作流程(Workflows)的存在,我們可以理解為允許多個生產線(也就是 .gitlab-ci.yml
設定)的狀態,基於這樣的前提我們就能把不同的任務拆分出來處理。
GitLab CI 其實也能夠利用 Child Pipeline 的方式來實現這件事情。
基本結構
我們只需要在 .github/workflows/
目錄下增加像是 containerize.yml
的設定檔即可。
1name: Containerize # 名稱
2
3on: # 啟動條件
4 push:
5 branches:
6 - main
7
8jobs: # 任務
9 assets:
10 runs-on: ubuntu-latest # 運行環境
11 steps:
12 # ...
基本結構大致上是類似的,然而我們沒有了階段(Stage)的設定,每個工作流程基本上是會同步的進行,但是可以利用 on
的觸發來設定要在什麼情況下才運行。
至於 Job(任務)的使用基本上是類似的,只不過在 GitHub Actions 中不是使用容器而是直接使用 Runner 來運行。
自動建置 Rails 鏡像
想在 GitHub Actions 自動建置鏡像某方面來說比在 GitLab CI 來說是更容易的,因為有許多現成的 Action(動作)模組可以使用,然而每個模組的作者在文件上的撰寫品質不一,因此也不一定容易使用,這邊我們使用的基本上都是官方的套件,因此還不算難使用。
Assets Precompile
同樣的,我們希望在容器化之前就先把素材預先編譯完畢,因此第一個加入的就是 Assets Precompile 的任務。
1name: Containerize
2
3on:
4 push:
5 branches:
6 - main
7
8env: # 共通環境變數
9 RUBY_VERSION: '2.7.5'
10 NODE_VERSION: '16'
11 RAILS_ENV: production
12 RAILS_MASTER_KEY: ${{ secrets.RAILS_SECRET_KEY }}
13
14jobs:
15 assets:
16 runs-on: ubuntu-latest
17 steps:
18 - uses: actions/checkout@v2 # 預先做成腳本的動作,不需要自己下命令
19 - name: Set up Ruby
20 uses: ruby/setup-ruby@v1
21 with: # 預先動作的額外設定,這邊是設定 Ruby 版本
22 ruby-version: ${{ env.RUBY_VERSION }}
23 bundler-cache: true
24 - name: Set up Node
25 uses: actions/setup-node@v2
26 with:
27 node-version: ${{ env.NODE_VERSION }}
28 cache: 'yarn'
29 - run: yarn install # 直接執行命令的情況
30 - run: bundle exec rake assets:precompile
31 - name: Archive precompiled assets
32 uses: actions/upload-artifact@v3
33 with:
34 name: assets
35 path: public/
36 retention-days: 7
在上面這段大多是使用 GitHub、Ruby、Node.js 官方預先準備好的動作來處理,假設是一些主流的語言、工具大多都已經有先寫好的動作,可以直接當作是模組載入使用。
在這個階段我們基本上就是把 Ruby、Node.js 都安裝一遍,然後執行 rake assets:precompile
預先編譯素材,最後使用 Artifacts(生成物)功能將編譯好的檔案上傳。
製作容器
接下來我們要進行容器化的處理,基本上大部分的命令都已經有預先製作好的版本,我們只需要套用正確的設定即可。雖然 Docker 可以使用 Buildx(Buildkit 的封裝)然而卻無法使用 Registry 版本的封裝,這會讓容器化的速度稍微變慢,不過還在可以接受的範圍之內。
1# ...
2
3env:
4 # ...
5 REGISTRY: ghcr.io
6 IMAGE_NAME: ${{ github.repository }}
7
8jobs:
9 # ...
10 build-and-push-image:
11 runs-on: ubuntu-latest
12 needs: assets
13 permissions:
14 contents: read
15 packages: write
16
17 steps:
18 - name: Checkout repository
19 uses: actions/checkout@v2
20
21 - name: Download precompiled assets
22 uses: actions/download-artifact@v3
23 with:
24 name: assets
25 path: public/
26
27 - name: Log in to the Container registry
28 uses: docker/login-action@v1
29 with:
30 registry: ${{ env.REGISTRY }}
31 username: ${{ github.actor }}
32 password: ${{ secrets.GITHUB_TOKEN }}
33
34 - name: Extract metadata (tags, labels) for Docker
35 id: meta
36 uses: docker/metadata-action@v3
37 with:
38 images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
39 tags: |
40 type=sha
41 type=semver,pattern={{version}}
42 type=semver,pattern={{major}}.{{minor}}
43 type=ref,event=branch
44 - name: Build and push Docker image
45 uses: docker/build-push-action@v2
46 with:
47 context: .
48 push: true
49 tags: ${{ steps.meta.outputs.tags }}
50 labels: ${{ steps.meta.outputs.labels }}
51 cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main
52 cache-to: type=inline
因為 GitHub 有也提供 Registry 的伺服器,因此我們可以直接使用自動設定好的帳號密碼登入來上傳,跟 GitLab CI 版本不太一樣的地方是我們的鏡像標籤。
在 GitLab CI 的版本中,我們會產生類似 registry.gitlab.com/example/example:c5e6528
的鏡像標籤,然而在 GitHub Actions 預先製作好的命令中,產生的是 sha-c5e6528
這樣的標籤,然而這不影響我們使用以及控制版本來進行部署。
在這裡我們對 tags
做了三個選想,分別是 sha
為基礎的標籤、1.0.0
和 1.0
以版本為主的標籤,以及以 Branch 名稱的標籤,這個規則基本上是對應大部分 Docker 鏡像的規則,可以依照自己的需求調整。
完成這些設定之後,我們就可以在 GitHub 上面自動的產生 Rails 的容器鏡像,如果是公開的專案就能夠直接透過 GitHub 提供的 Registry 來直接使用。
如果想在第一時間收到更新,歡迎訂閱弦而時習之在這系列文章更新時收到通知,如果有希望了解的知識,可以利用Rails 部署實踐回饋表單告訴我。
如果對這篇文章有興趣,可以透過以下連結繼續閱讀這系列的其他文章。
- Rails 部署實踐 - 補上 Rails 教學缺少的一塊
- Rails 部署實踐 - 以容器部署 Rails 的方案
- Rails 部署實踐 - 部署前置準備
- Rails 部署實踐 - 容器化 Rails 專案概述
- Rails 部署實踐 - 上傳容器鏡像
- Rails 部署實踐 - 伺服器搭建
- Rails 部署實踐 - 撰寫 Docker Compose
- Rails 部署實踐 - 使用 HTTPS 協定加密連線
- Rails 部署實踐 - 健康檢查
- Rails 部署實踐 - 滾動更新
- Rails 實踐部署 - 使用 Alpine 製作容器鏡像
- Rails 部署實踐 - 容器化的 Bundler 最佳設定
- Rails 部署實踐 - 多階段建置
- Rails 部署實踐 - 素材預先編譯
- Rails 部署實踐 - 容器進入點
- Rails 部署實踐 - 容器相關工具
- Rails 部署實踐 - 持續部署
- Rails 部署實踐 - 使用 GitLab CI 自動化建置
- Rails 部署實踐 - 使用 GitHub Actions 自動化建置
- Rails 部署實踐 - 使用 Watchtower 自動更新
- Rails 部署實踐 - Docker Swarm 與 Docker Compose
- Rails 部署實踐 - Docker Swarm 安裝與設定
- Rails 部署實踐 - 部署到 Docker Swarm
- Rails 部署實踐 - 整合 GitLab CI 自動部署
- Rails 部署實踐 - 使用 GitLab 的 Review Apps 機制
- Rails 部署實踐 - 部署不是終點