iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
自我挑戰組

30天打造自己的RSS閱讀器:Go語言與DevOps的實戰應用系列 第 19

Day 19:番外篇 - GitHub Actions 跟 GitLab CI/CD 執行方式有些不同

  • 分享至 

  • xImage
  •  

昨天開始評估如何從 GitLab CI/CD Pipelines 轉移至 GitHub Actions,我們過去是採用「runner 在 container 內、job 也在獨立的 container 內執行」的執行模式,如果 GitHub 有一樣的模式可以照搬,那就可以省很多功夫在 porting 上。

我評估了一下,執行 CI/CD job 的方式若以「是否採用容器化技術」來做區別的話,有 4 種組合:

  1. runner 不在 container 內,job 執行不另外開 container
    • 官方文件的最基本設定方式,我們在 Day 17 的旅程中已確定可行
  2. runner 位於 container 內,job 執行不另外開 container
    • 執行環境與 host 有基本的隔離,至少 host 不會輕易地被 shell 指令 (run:) 給弄亂
    • 我們在 Day 18 已確定可行
  3. runner 不在 container 內,job 執行於另一個 container 內
    • 官方文件有教學
  4. runner 位於 container 內,job 執行於另一個 container 內 (Docker in Docker)
    • 目前我們部門的 GitLab CI/CD Pipeline 使用此方式執行
    • 能不能執行是個未知數

今天先來玩看看 3.,也就是讓 job 執行於另一個 container 內。
這需要寫一個新的 workflow,如果還要設定 self-hosted runner 有點麻煩,我先使用 GitHub 提供的 runner 來執行我的 workflow,等 workflow 確定準備好後再改用 self-hosted runner 來執行。

準備實驗用 repo

先建立一個簡單的 .NET 6.0 專案,盡量貼近公司的 tech stack。此 solution 包含一個 library、一個 unit test suite、一個 app:

https://ithelp.ithome.com.tw/upload/images/20230922/20162813Ob7qzJTKnv.png

其中 workflow 定義如下:

name: .NET Core CI/CD in Container

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    container:
      image: mcr.microsoft.com/dotnet/sdk:6.0

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Restore dependencies
      run: dotnet restore

    - name: Build solution
      run: dotnet build --configuration Release --no-restore

    - name: Run unit tests
      run: dotnet test --no-restore --verbosity normal

    - name: Publish console app
      run: dotnet publish MyConsoleApp/MyConsoleApp.csproj --configuration Release --no-build --output ./publish/

    - name: Upload artifact
      uses: actions/upload-artifact@v3
      with:
        name: MyConsoleApp
        path: ./publish/

  validate:
    needs: build
    runs-on: ubuntu-latest
    steps:
    - name: Download artifact
      uses: actions/download-artifact@v3
      with:
        name: MyConsoleApp
        path: ./publish

    - name: Check current working directory
      run: pwd

    - name: List files in current working directory
      run: ls -la

    - name: Try running the console app
      run: |
        chmod +x ./publish/MyConsoleApp
        ./publish/MyConsoleApp

包含兩個 job:buildvalidate

build 作業:

  1. 設定容器環境:此作業會在 Docker 容器內運行,使用 .NET 6.0 SDK 的映像檔。
  2. 取得代碼:從 GitHub checkout code。
  3. 還原依賴關係:執行 dotnet restore 以還原 NuGet 套件。
  4. 建置解決方案:執行 dotnet build 以建置整個解決方案。
  5. 運行單元測試:執行 dotnet test 以執行單元測試。
  6. 發佈控制台應用程式:執行 dotnet publish 以發佈控制台應用程式。
  7. **上傳 artifact:將發佈的控制台應用程式作為 GitHub 工作流程的一部分上傳。

validate 作業:

  1. **下載 artifact:使用 actions/download-artifact@v2 來下載 build 作業中創建的 artifact。
  2. 執行控制台應用程式**:使用 chmod +x 來給予應用程式執行權限,然後執行它。

這個工作流程能夠在同一個容器環境中自動建置、測試、發佈,並驗證 .NET 解決方案。它首先建置和測試解決方案,然後發佈控制台應用程式並作為 artifact 上傳。之後,它會下載這個 artifact 並跑起來,以確保它可以正確執行。

執行 workflow

廢話不多說,直接上。

來看 build 流程,可以看到有 Initializa containers 還有 'Stop containers` 兩個 step

https://ithelp.ithome.com.tw/upload/images/20230922/20162813zLoh7B5WSI.png

Upload artifact 可以看到成功上傳了我們 build 出來的東西:

Run actions/upload-artifact@v3
  with:
    name: MyConsoleApp
    path: ./publish/
    if-no-files-found: warn
/usr/bin/docker exec  b63...ea20 sh -c "cat /etc/*release | grep ^ID"
With the provided path, there will be 7 files uploaded
Starting artifact upload
For more detailed logs during the artifact upload process, enable step-debugging: https://docs.github.com/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging#enabling-step-debug-logging
Artifact name is valid!
Container for artifact "MyConsoleApp" successfully created. Starting upload of file(s)
Total size of all the files uploaded is 70402 bytes
File upload process has finished. Finalizing the artifact upload
Artifact has been finalized. All files have been successfully uploaded!

The raw size of all the files that were specified for upload is 173101 bytes
The size of all the files that were uploaded is 70402 bytes. This takes into account any gzip compression used to reduce the upload size, time and storage

Note: The size of downloaded zips can differ significantly from the reported size. For more information see: https://github.com/actions/upload-artifact#zipped-artifact-downloads 

Artifact MyConsoleApp has been successfully uploaded!

![[Pasted image 20230921224436.png]]

來看 validate job,由於只是要跑程式而已,此 job 就未使用 container 了。

https://ithelp.ithome.com.tw/upload/images/20230922/201628135nWyxWTkmS.png

Download artifact 可以看到有下載 artifact 的行為

Run actions/download-artifact@v3
  with:
    name: MyConsoleApp
    path: ./publish
Starting download for MyConsoleApp
Directory structure has been setup for the artifact
Total number of files that will be downloaded: 7
Artifact MyConsoleApp was downloaded to /home/runner/work/dotnet-cicd-eval/dotnet-cicd-eval/publish
Artifact download has finished successfully

Try running the console app 輸出了我們剛剛建置的 app 的內容!

Run chmod +x ./publish/MyConsoleApp
Addition: 2 + 3 = 5
Subtraction: 3 - 2 = 1

今天的實驗證明 runner 是可以在 container 內執行並且上傳 artifact 作為其他用途。這個 artifact 也可以用來給 infra team 部署到正式環境用。

就這個 workflow 就做了一個小時,累了 XD。
明天我們再來看一下是否能在 self-hosted runner 執行這個 workflow。

https://ithelp.ithome.com.tw/upload/images/20230922/20162813yyXNZUEzNb.png


上一篇
Day 18:番外篇 - 要從 GitLab CI/CD 遷移到 GitHub Actions,頭好痛...
下一篇
Day 20:番外篇 - 自架的 GitHub Actions Runner 如何在 container 內執行工作
系列文
30天打造自己的RSS閱讀器:Go語言與DevOps的實戰應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言