Redis®*: GitHub Actions 与 GitLab CI

通过您的 GitHub Actions 或 GitLab CI pipeline 启动一个真实的 Redis 服务,运行测试并自动销毁

👋 欢迎来到 Stackhero 文档!

Stackhero 提供即用型 Redis 云 解决方案,带来众多优势,包括:

  • 包含 Redis Commander 网页界面
  • 无限消息大小和传输。
  • 只需点击即可轻松更新
  • 私有和专用 VM提供的最佳性能和强大安全性

节省时间简化生活:只需 5 分钟即可试用 Stackhero 的 Redis 云托管 解决方案!

本指南将引导您在 CI pipeline 中运行一个真实、专用的 Redis 服务,支持 GitHub ActionsGitLab CI。按照以下步骤,您可以在接近生产环境的条件下,将代码直接对接到一个真实的 Redis 实例进行测试,无需再依赖 mock 或模拟环境。Redis is a blazing-fast in-memory data store used as a cache, key-value store and message broker.

每次 pipeline 执行时,都会为您创建一个全新的 Redis 实例。这意味着您的测试将与生产环境中用户实际使用的服务类型完全一致。该工作流会自动创建一个临时 stack,添加 Redis,等待服务就绪,获取自动生成的凭证,使用 redis-cli 进行 smoke test,最后在流程结束后始终进行资源清理。

您将使用 Stackhero CLI,这是一个独立的命令行工具,可帮助您快速便捷地启动和管理 Stackhero 服务。

为了让 CLI 能以非交互方式运行,您需要一个访问令牌(格式:usr-xxxxxx:tokenId)。该令牌只需创建一次,然后作为安全加密的 CI 密钥添加到您的 pipeline。

  1. 创建令牌: 在您的 Stackhero 控制台,点击右上角的头像,进入 Your account,选择 Access tokens,点击 Create token
  2. GitHub Actions: 在您的代码仓库,进入 Settings > Secrets and variables > Actions > New repository secret,将令牌填入 STACKHERO_TOKEN
  3. GitLab CI: 在您的项目中,进入 Settings > CI/CD > Variables > Add variable,设置 key 为 STACKHERO_TOKEN,勾选 Masked(如您的 CI 仅在受保护分支运行,也可勾选 Protected)。

请勿将访问令牌直接写入 pipeline 的 YAML 文件。如果令牌出现在 YAML 中,任何有仓库访问权限的人都可能看到,并且可能会出现在构建日志中。将其作为 CI 密钥存储可确保加密和隐藏,保障您的令牌安全。

以下是一个完整的服务生命周期管理脚本示例。只需几条命令即可完成全部配置。您可以直接复制下方各平台的 YAML 示例。

#!/bin/bash
set -euo pipefail

# STACKHERO_TOKEN 由 CI 密钥提供,CLI 会自动读取。

stackName="ci-redis-$$"          # 每次运行唯一的 stack 名称
serviceStore="redis"             # Redis 服务 store
instance="1G"        # 如有需要可修改(见第 3 步)
region="europe"                         # 区域名称(可通过 stackhero regions-list 查看)

# 1. 在 runner 上安装 CLI
curl -fsSL https://www.stackhero.io/install.sh | sh

# 2. 安装 smoke test 所需的 client(jq + curl 为基础)
apt-get update && apt-get install -y --no-install-recommends jq curl redis-tools

# 3. 为本次运行创建专用 stack
stackId=$(stackhero --format=script stack-create --name="$stackName")
echo "Stack created: $stackId"

# 4. 添加 Redis 并获取其 service id
serviceId=$(stackhero --format=script service-add \
  --stack="$stackId" \
  --service-store="$serviceStore" \
  --instance="$instance" \
  --region="$region")
echo "Service added: $serviceId"

# 5. 等待服务运行(可能需要几分钟)
stackhero service-wait-for --service="$serviceId"

# 6. 读取配置(包含自动生成的凭证)
config=$(stackhero service-configuration-get --service="$serviceId" --format=json)

# 7. 提取所需凭证
host=$(echo "$config" | jq -r '.configuration.domain')
password=$(echo "$config" | jq -r '.configuration.credentials.password')

# 8. Smoke test: Send a PING and expect a PONG.
redis-cli -h "$host" -p 6380 -a "$password" --tls --no-auth-warning PING | grep -q PONG

echo "✅ Redis 已可从 CI 访问。"

销毁步骤(删除服务、等待其移除、再删除 stack)请参考下方各平台专属部分。这样可以确保即使 smoke test 失败也能始终完成资源清理。

Stack 只有在为空时才能被删除。请务必先删除服务并等待其移除,再删除 stack。service-wait-for 命令可确保服务已运行或已删除,是等待删除的推荐工具。

以下示例默认使用 Redis 的入门级实例 1G。该规格适用于大多数场景,您也可根据需求调整。如需查看 Redis 的所有可用实例类型,可运行:

# NAME 列显示可传递给 --instance 的值
stackhero instances-store-list --service-store=redis

您可以将以下内容保存为 .github/workflows/ci.yml。此后,每次 push 或 pull request 都会针对真实的 Redis 实例运行测试。

name: CI with Redis

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      STACKHERO_TOKEN: ${{ secrets.STACKHERO_TOKEN }}
      STACK_NAME: ci-redis-${{ github.run_id }}-${{ github.run_attempt }}
      INSTANCE: "1G"   # 如有需要可修改(见第 3 步)
      REGION: europe
    steps:
      - uses: actions/checkout@v4

      - name: 安装 Stackhero CLI  client
        run: |
          curl -fsSL https://www.stackhero.io/install.sh | sh
          apt-get update && apt-get install -y --no-install-recommends jq curl redis-tools

      - name: 创建 Redis 服务
        run: |
          set -euo pipefail
          STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
          echo "STACK_ID=$STACK_ID" >> "$GITHUB_ENV"
          SERVICE_ID=$(stackhero --format=script service-add \
            --stack="$STACK_ID" \
            --service-store="redis" \
            --instance="$INSTANCE" \
            --region="$REGION")
          echo "SERVICE_ID=$SERVICE_ID" >> "$GITHUB_ENV"
          stackhero service-wait-for --service="$SERVICE_ID"

      - name: 针对 Redis 运行测试
        run: |
          set -euo pipefail
          config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
          host=$(echo "$config" | jq -r '.configuration.domain')
password=$(echo "$config" | jq -r '.configuration.credentials.password')
          # Send a PING and expect a PONG.
          redis-cli -h "$host" -p 6380 -a "$password" --tls --no-auth-warning PING | grep -q PONG
          echo "✅ Redis 已可从 CI 访问。"
          # 您也可以在此处使用上述凭证运行自定义测试套件 ...

      - name: 资源清理(始终执行,包括失败时)
        if: always()
        run: |
          if [ -n "${SERVICE_ID:-}" ]; then
            stackhero service-delete --service="$SERVICE_ID" --confirm
            stackhero service-wait-for --service="$SERVICE_ID"
          fi
          if [ -n "${STACK_ID:-}" ]; then
            stackhero stack-delete --stack="$STACK_ID" --confirm
          fi

资源清理步骤配置了 if: always(),确保无论流程是否失败都会执行,及时删除 Redis 实例,避免因未使用资源而产生费用。

您可以将以下配置保存为 .gitlab-ci.yml。每次 pipeline 运行时,都会为测试启动一个全新的真实 Redis 实例。

test:
  image: ubuntu:24.04
  variables:
    STACK_NAME: "ci-redis-$CI_PIPELINE_ID-$CI_JOB_ID"
    INSTANCE: "1G"   # 如有需要可修改(见第 3 步)
    REGION: "europe"
    SERVICE_STORE: "redis"
  # STACKHERO_TOKEN 来源于第 1 步创建的 CI/CD 变量。
  script:
    - set -euo pipefail
    - curl -fsSL https://www.stackhero.io/install.sh | sh
    - apt-get update && apt-get install -y --no-install-recommends jq curl redis-tools
    - STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
    - echo "STACK_ID=$STACK_ID" >> deploy.env
    - SERVICE_ID=$(stackhero --format=script service-add --stack="$STACK_ID" --service-store="$SERVICE_STORE" --instance="$INSTANCE" --region="$REGION")
    - echo "SERVICE_ID=$SERVICE_ID" >> deploy.env
    - stackhero service-wait-for --service="$SERVICE_ID"
    - config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
    - host=$(echo "$config" | jq -r '.configuration.domain')
password=$(echo "$config" | jq -r '.configuration.credentials.password')
    # Send a PING and expect a PONG.
    - redis-cli -h "$host" -p 6380 -a "$password" --tls --no-auth-warning PING | grep -q PONG
    - echo "✅ Redis 已可从 CI 访问。"
    # 您也可以在此处使用上述凭证运行自定义测试套件 ...
  after_script:
    - test -f deploy.env && . ./deploy.env || true
    - >
      if [ -n "${SERVICE_ID:-}" ]; then
        stackhero service-delete --service="$SERVICE_ID" --confirm
        stackhero service-wait-for --service="$SERVICE_ID"
      fi
    - >
      if [ -n "${STACK_ID:-}" ]; then
        stackhero stack-delete --stack="$STACK_ID" --confirm
      fi

在 GitLab 中,资源清理通过 after_script 实现。该部分无论作业是否失败都会执行,确保您的 Redis 资源被及时移除,避免产生不必要的费用。

在 GitLab 中,after_script 会在一个全新 shell中运行。为此,脚本会在作业期间将服务和 stack 的 ID 写入 deploy.env,清理前再重新加载。这样即使作业中途失败,也能确保资源被正确清理。

这就是 Redis 的完整 CI 生命周期:创建 stack、添加服务、等待、获取凭证、smoke test,并始终进行资源清理。每次 pipeline 运行都能获得一个真实、隔离的服务,流程结束后不会有任何资源遗留。如需了解更多可用命令及非交互式 STACKHERO_TOKEN 认证方式,欢迎查阅 完整 CLI 文档