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 執行日誌:
從日誌上我們可以看出來比普通的 CI 執行會多出兩個步驟,一個是初始化 container,一個是清理 container
完整的CI 日誌可以在這裡看到:https://github.com/WeihanLi/WeihanLi.Redis/runs/1400006789?check_suite_focus=true
More
雖然我的場景是 redis,但是不僅僅是 redis,很多應用外的依賴比如說資料庫,甚至MQ等都是可以通過 service container 來做一個完善的整合測試,沒有嘗試過的快去試試吧~~