RabbitMQ: GitHub Actions & GitLab CI
通过您的 GitHub Actions 或 GitLab CI 流水线启动一个真实的 RabbitMQ 服务,运行测试并自动销毁
本指南将带您了解如何在 GitHub Actions 或 GitLab CI 的 CI 流水线中运行一个真实、专用的 RabbitMQ 服务。按照以下步骤,您可以在接近生产环境的条件下,对您的代码进行真实的 RabbitMQ 实例测试,无需再依赖 mock 或模拟环境。RabbitMQ is a widely-deployed open source message broker that moves work between your services reliably and at scale.
每次流水线运行时,都会为您创建一个全新的 RabbitMQ 实例。这意味着您的测试将与生产环境中用户实际使用的服务类型完全一致。该工作流会自动创建一个临时 stack,添加 RabbitMQ,等待其就绪,获取生成的凭据,使用 curl 进行 smoke test,并在运行结束后始终自动清理所有资源。
您将使用 Stackhero CLI,这是一个独立的命令行工具,可帮助您快速便捷地启动和管理 Stackhero 服务。
1. 创建访问令牌并作为 CI 密钥存储
为了让 CLI 能够以非交互方式运行,您需要一个访问令牌(格式:usr-xxxxxx:tokenId)。该令牌只需创建一次,然后作为安全加密的密钥添加到您的 CI 流水线中。
- 创建令牌: 在您的 Stackhero 控制台,点击右上角的头像,进入您的账户,然后选择Access tokens,点击Create token。
- GitHub Actions: 在您的代码仓库,进入 Settings > Secrets and variables > Actions > New repository secret,将令牌填写为
STACKHERO_TOKEN。 - GitLab CI: 在您的项目中,进入 Settings > CI/CD > Variables > Add variable,将 key 设置为
STACKHERO_TOKEN,并勾选 Masked(如果您的 CI 只在受保护分支运行,也可勾选 Protected)。
请勿将访问令牌直接写入流水线 YAML 文件。如果令牌出现在 YAML 中,任何有仓库访问权限的人都可能看到,并且可能会出现在构建日志中。将其作为 CI 密钥存储可以确保其加密和隐藏,从而保障您的令牌安全。
2. 生命周期脚本
以下是一个完整的服务生命周期管理脚本示例。它展示了只需极少的配置和几条命令即可完成全部流程。您可以在下方各平台专属部分复制对应的 YAML 配置。
#!/bin/bash
set -euo pipefail
# STACKHERO_TOKEN 由 CI 密钥提供,CLI 会自动读取。
stackName="ci-rabbitmq-$$" # 每次运行唯一的 stack 名称
serviceStore="rabbitmq" # RabbitMQ 服务 store
instance="200" # 如有需要可修改(见第 3 步)
region="europe" # 区域名称(可通过 stackhero regions-list 查看)
# 1. 在 runner 上安装 CLI
curl -fsSL https://www.stackhero.io/install.sh | sh
# 2. 安装 smoke test 所需客户端(jq + curl 为基础)
apt-get update && apt-get install -y --no-install-recommends jq curl
# 3. 为本次运行创建专用 stack
stackId=$(stackhero --format=script stack-create --name="$stackName")
echo "Stack created: $stackId"
# 4. 添加 RabbitMQ 并获取其 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.password')
# 8. Smoke test: Call the management API (health check, falling back to overview).
curl -fsS -u "admin:$password" "https://$host/api/health/checks/alarms" | grep -q '"status":"ok"' \
|| curl -fsS -u "admin:$password" "https://$host/api/overview" | grep -q '"rabbitmq_version"'
echo "✅ RabbitMQ 已可从 CI 访问。"
销毁步骤(删除服务、等待其移除、再删除 stack)请参见下方各平台专属部分。此方式确保即使 smoke test 失败也能始终完成清理。
stack 只能在为空时删除。请务必先删除服务并等待其移除,再删除 stack。
service-wait-for命令可确保服务已运行或已删除,是等待删除的最佳工具。
3. 选择实例规格
以下示例默认使用 RabbitMQ 的入门级实例 200。该规格适用于大多数场景,您也可根据需要调整。如需查看 RabbitMQ 的所有可用实例类型,可运行:
# NAME 列显示可传递给 --instance 的值
stackhero instances-store-list --service-store=rabbitmq
4. GitHub Actions
您可以将以下内容保存为 .github/workflows/ci.yml。此后,每次 push 或 pull request 都会针对真实的 RabbitMQ 实例运行测试。
name: CI with RabbitMQ
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
env:
STACKHERO_TOKEN: ${{ secrets.STACKHERO_TOKEN }}
STACK_NAME: ci-rabbitmq-${{ github.run_id }}-${{ github.run_attempt }}
INSTANCE: "200" # 如有需要可修改(见第 3 步)
REGION: europe
steps:
- uses: actions/checkout@v4
- name: 安装 Stackhero CLI 及客户端
run: |
curl -fsSL https://www.stackhero.io/install.sh | sh
apt-get update && apt-get install -y --no-install-recommends jq curl
- name: 创建 RabbitMQ 服务
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="rabbitmq" \
--instance="$INSTANCE" \
--region="$REGION")
echo "SERVICE_ID=$SERVICE_ID" >> "$GITHUB_ENV"
stackhero service-wait-for --service="$SERVICE_ID"
- name: 运行 RabbitMQ 测试
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.password')
# Call the management API (health check, falling back to overview).
curl -fsS -u "admin:$password" "https://$host/api/health/checks/alarms" | grep -q '"status":"ok"' \
|| curl -fsS -u "admin:$password" "https://$host/api/overview" | grep -q '"rabbitmq_version"'
echo "✅ RabbitMQ 已可从 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(),确保无论结果如何都会执行,保证您的 RabbitMQ 实例被删除,避免因未使用资源而产生费用。
5. GitLab CI
您可以将以下配置保存为 .gitlab-ci.yml。每次流水线运行时,都会为您的测试启动一个全新的真实 RabbitMQ 实例。
test:
image: ubuntu:24.04
variables:
STACK_NAME: "ci-rabbitmq-$CI_PIPELINE_ID-$CI_JOB_ID"
INSTANCE: "200" # 如有需要可修改(见第 3 步)
REGION: "europe"
SERVICE_STORE: "rabbitmq"
# 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
- 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.password')
# Call the management API (health check, falling back to overview).
- curl -fsS -u "admin:$password" "https://$host/api/health/checks/alarms" | grep -q '"status":"ok"' \
|| curl -fsS -u "admin:$password" "https://$host/api/overview" | grep -q '"rabbitmq_version"'
- echo "✅ RabbitMQ 已可从 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 中执行。该部分无论作业是否失败都会被执行,确保您的 RabbitMQ 资源被及时移除,避免不必要的费用。
在 GitLab 中,
after_script会在全新 shell中运行。为此,脚本会在作业过程中将服务和 stack 的 ID 写入deploy.env,并在清理前重新加载。这样即使作业中途失败,也能确保资源被正确清理。
这就是 RabbitMQ 的完整 CI 生命周期:创建 stack,添加服务,等待,获取凭据,smoke test,并始终清理。每次流水线运行都能获得一个真实、隔离的服务,结束后不会有任何资源遗留。如需了解更多可用命令及非交互式 STACKHERO_TOKEN 认证,欢迎查阅 完整 CLI 文档。