天天看點

Github Actions 中 Service Container 的使用

利用 Github Actions 的 service container 進行內建測試

Github Actions 中 Service Container 的使用

Intro

之前寫過一個

StackExchange.Redis

的一個擴充,測試項目依賴 redis,是以之前測試一直隻是在本地跑一下,最近通過 Github Action 中的 Service Container 來通過 CI 來跑測試,分享一下如何使用 service container 來跑測試,不僅僅是 Redis,資料庫等依賴也可以使用這樣的方式來測試

Redis Service Container Sample

jobs:
  # Label of the runner job
  runner-job:
    # You must use a Linux environment when using service containers or container jobs
    runs-on: ubuntu-latest

    # Service containers to run with `runner-job`
    services:
      # Label used to access the service container
      redis:
        # Docker image
        image: redis:alpine
        # Set health checks to wait until redis has started
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          # Maps port 6379 on service container to the host
          - 6379:6379
           

上面是一個 redis service container 配置示例的一部分,需要注意的是使用 service container 的時候必須要使用 Linux 環境,因為 service container 的本質就是 docker run 了一個 container,通過一定的規則配置來實作在跑 CI 的環境可以通路的這個 service

上面的示例配置了一個

redis

的 service container,并将容器服務的 6379 端口映射到 host 的 6379 端口,這樣 host 上的服務就可以通過

127.0.0.1:6379

/

localhost:6379

通路到使用 docker 跑起來的

redis

服務(redis service container)了

steps:
  # Downloads a copy of the code in your repository before running CI tests
  - name: Check out repository code
    uses: actions/checkout@v2

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.com/cli/ci.html
  - name: Install dependencies
    run: npm ci

  - name: Connect to Redis
    # Runs a script that creates a Redis client, populates
    # the client with data, and retrieves data
    run: node client.js
    # Environment variable used by the `client.js` script to create
    # a new Redis client.
    env:
      # The hostname used to communicate with the Redis service container
      REDIS_HOST: localhost
      # The default Redis port
      REDIS_PORT: 6379
           

Container Job Sample

上面的這種形式是在 host 上跑的,也就是直接在跑 CI 的伺服器上跑的,有些情況下環境的配置比較麻煩的情況下也可以直接在指定的 docker 鏡像為基礎的 docker container 裡跑 CI,需要注意的是 docker container 裡跑 CI 的時候和直接在 host 上跑 CI 網絡上有差別, host 可能就是直接通路

localhost

,container 通路就是 service 名稱,來看下面的 container 的一個示例:

jobs:
  # Label of the container job
  container-job:
    # Containers must run in Linux based operating systems
    runs-on: ubuntu-latest
    # Docker Hub image that `container-job` executes in
    container: node:10.18-jessie

    # Service containers to run with `container-job`
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: redis
        # Set health checks to wait until redis has started
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
           

可以看到大部分是一樣的,隻是多了一個

container

的配置,這樣實際的 CI 就是在這個 container 裡執行的,建立的執行 CI 的 container 和 service container 是在同一個 network 下,可以直接通過服務名稱來通路

steps:
  # Downloads a copy of the code in your repository before running CI tests
  - name: Check out repository code
    uses: actions/checkout@v2

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.com/cli/ci.html
  - name: Install dependencies
    run: npm ci

  - name: Connect to Redis
    # Runs a script that creates a Redis client, populates
    # the client with data, and retrieves data
    run: node client.js
    # Environment variable used by the `client.js` script to create a new Redis client.
    env:
      # The hostname used to communicate with the Redis service container
      REDIS_HOST: redis
      # The default Redis port
      REDIS_PORT: 6379
           

Sample

提供一個我目前在用的一個 service container,和上面的示例基本是類似的,有需要的可以參考一下:

name: dotnetcore

on: [push]

jobs:
  # Label of the container job
  redis-integration-test:
    # Containers must run in Linux based operating systems
    runs-on: ubuntu-latest
    # # Docker image that `job` executes in
    # container: mcr.microsoft.com/dotnet/sdk:5.0

    # Service containers to run with `container-job`
    # https://docs.github.com/en/free-pro-team@latest/actions/guides/creating-redis-service-containers
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: redis:alpine
        # Set health checks to wait until redis has started
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          # Maps port 6379 on service container to the host
          - 6379:6379

    steps:
    - uses: actions/checkout@v1
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 5.0.x
    - name: dotnet info
      run: dotnet --info
    - name: build
      run: bash build.sh --target=test
           

CI 執行日志:

Github Actions 中 Service Container 的使用

從日志上我們可以看出來比普通的 CI 執行會多出兩個步驟,一個是初始化 container,一個是清理 container

完整的CI 日志可以在這裡看到:https://github.com/WeihanLi/WeihanLi.Redis/runs/1400006789?check_suite_focus=true

More

雖然我的場景是 redis,但是不僅僅是 redis,很多應用外的依賴比如說資料庫,甚至MQ等都是可以通過 service container 來做一個完善的內建測試,沒有嘗試過的快去試試吧~~

References

  • https://docs.github.com/en/free-pro-team@latest/actions/guides/about-service-containers
  • https://docs.github.com/en/free-pro-team@latest/actions/guides/creating-redis-service-containers
  • https://github.com/WeihanLi/WeihanLi.Redis/blob/dev/.github/workflows/dotnetcore.yml

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。