39bd36b2f8
Co-authored-by: multica-agent <github@multica.ai>
267 lines
10 KiB
YAML
267 lines
10 KiB
YAML
name: 发布验收测试
|
||
|
||
on:
|
||
workflow_run:
|
||
workflows:
|
||
- 测试环境部署
|
||
types:
|
||
- completed
|
||
branches:
|
||
- internal
|
||
- main
|
||
workflow_dispatch:
|
||
|
||
permissions:
|
||
contents: read
|
||
actions: read
|
||
|
||
concurrency:
|
||
group: release-acceptance
|
||
cancel-in-progress: false
|
||
|
||
env:
|
||
ACCEPTANCE_ARTIFACT_NAME: release-acceptance-${{ github.run_id }}-${{ github.run_attempt }}
|
||
ACCEPTANCE_REPORT_DIR: ${{ github.workspace }}/acceptance-artifacts
|
||
ACCEPTANCE_REPORT_PATH: ${{ github.workspace }}/acceptance-artifacts/acceptance-report.json
|
||
ACCEPTANCE_TEST_JSON: ${{ github.workspace }}/acceptance-artifacts/go-test.json
|
||
ACCEPTANCE_FAILURE_LOG: ${{ github.workspace }}/acceptance-artifacts/failure.log
|
||
ACCEPTANCE_NODE_SERVER_ID: ${{ vars.ACCEPTANCE_NODE_SERVER_ID || '31' }}
|
||
ACCEPTANCE_NODE_PROTOCOL: ${{ vars.ACCEPTANCE_NODE_PROTOCOL || 'trojan' }}
|
||
|
||
jobs:
|
||
acceptance:
|
||
name: Staging acceptance
|
||
runs-on: ubuntu-latest
|
||
timeout-minutes: 20
|
||
env:
|
||
STAGING_BASE_URL: ${{ secrets.STAGING_BASE_URL || vars.STAGING_BASE_URL || 'https://tapi.hifast.biz' }}
|
||
if: >-
|
||
${{
|
||
github.event_name == 'workflow_dispatch' ||
|
||
(
|
||
github.event.workflow_run.conclusion == 'success' &&
|
||
github.event.workflow_run.event == 'push'
|
||
)
|
||
}}
|
||
|
||
steps:
|
||
- name: 检出代码
|
||
uses: actions/checkout@v6
|
||
with:
|
||
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||
|
||
- name: 配置 Go 环境
|
||
uses: actions/setup-go@v6
|
||
with:
|
||
go-version-file: go.mod
|
||
cache: true
|
||
|
||
- name: 准备报告目录
|
||
run: mkdir -p "$ACCEPTANCE_REPORT_DIR"
|
||
|
||
- name: 校验必需配置
|
||
env:
|
||
ACCEPTANCE_ADMIN_EMAIL: ${{ secrets.ACCEPTANCE_ADMIN_EMAIL }}
|
||
ACCEPTANCE_ADMIN_PASSWORD: ${{ secrets.ACCEPTANCE_ADMIN_PASSWORD }}
|
||
ACCEPTANCE_USER_EMAIL: ${{ secrets.ACCEPTANCE_USER_EMAIL }}
|
||
ACCEPTANCE_USER_PASSWORD: ${{ secrets.ACCEPTANCE_USER_PASSWORD }}
|
||
STAGING_BASE_URL: ${{ secrets.STAGING_BASE_URL || vars.STAGING_BASE_URL || 'https://tapi.hifast.biz' }}
|
||
STAGING_DB_HOST: ${{ secrets.STAGING_DB_HOST }}
|
||
STAGING_DB_USER: ${{ secrets.STAGING_DB_USER }}
|
||
STAGING_DB_PASSWORD: ${{ secrets.STAGING_DB_PASSWORD }}
|
||
STAGING_DB_NAME: ${{ secrets.STAGING_DB_NAME }}
|
||
STAGING_REDIS_ADDR: ${{ secrets.STAGING_REDIS_ADDR }}
|
||
STAGING_REDIS_PASSWORD: ${{ secrets.STAGING_REDIS_PASSWORD }}
|
||
run: |
|
||
set -euo pipefail
|
||
|
||
if [ -z "${STAGING_BASE_URL:-}" ]; then
|
||
echo "STAGING_BASE_URL 未配置且默认值不可用" | tee "$ACCEPTANCE_FAILURE_LOG"
|
||
{
|
||
echo "## 发布验收测试"
|
||
echo
|
||
echo "状态:配置错误"
|
||
echo
|
||
echo "- `STAGING_BASE_URL` 不能为空。"
|
||
} >> "$GITHUB_STEP_SUMMARY"
|
||
exit 1
|
||
fi
|
||
|
||
missing_optional=()
|
||
optional=(
|
||
ACCEPTANCE_ADMIN_EMAIL
|
||
ACCEPTANCE_ADMIN_PASSWORD
|
||
ACCEPTANCE_USER_EMAIL
|
||
ACCEPTANCE_USER_PASSWORD
|
||
STAGING_DB_HOST
|
||
STAGING_DB_USER
|
||
STAGING_DB_PASSWORD
|
||
STAGING_DB_NAME
|
||
STAGING_REDIS_ADDR
|
||
STAGING_REDIS_PASSWORD
|
||
)
|
||
|
||
for key in "${optional[@]}"; do
|
||
if [ -z "${!key:-}" ]; then
|
||
missing_optional+=("$key")
|
||
fi
|
||
done
|
||
|
||
: > "$ACCEPTANCE_FAILURE_LOG"
|
||
|
||
if [ "${#missing_optional[@]}" -gt 0 ]; then
|
||
printf '缺少可选 GitHub Actions secrets/vars,部分验收用例将被跳过:\n' | tee -a "$ACCEPTANCE_FAILURE_LOG"
|
||
printf -- '- %s\n' "${missing_optional[@]}" | tee -a "$ACCEPTANCE_FAILURE_LOG"
|
||
{
|
||
echo "## 发布验收测试"
|
||
echo
|
||
echo "状态:部分配置缺失"
|
||
echo
|
||
echo "缺少以下可选 secrets/vars,对应验收用例会在测试阶段自动跳过:"
|
||
printf -- '- `%s`\n' "${missing_optional[@]}"
|
||
echo
|
||
echo "- `STAGING_BASE_URL`:${STAGING_BASE_URL}"
|
||
} >> "$GITHUB_STEP_SUMMARY"
|
||
else
|
||
{
|
||
echo "## 发布验收测试"
|
||
echo
|
||
echo "状态:配置检查通过"
|
||
echo
|
||
echo "- `STAGING_BASE_URL`:${STAGING_BASE_URL}"
|
||
} >> "$GITHUB_STEP_SUMMARY"
|
||
fi
|
||
|
||
- name: 下载依赖模块
|
||
run: go mod download
|
||
|
||
- name: 运行 acceptance 测试
|
||
env:
|
||
ACCEPTANCE_ADMIN_EMAIL: ${{ secrets.ACCEPTANCE_ADMIN_EMAIL }}
|
||
ACCEPTANCE_ADMIN_PASSWORD: ${{ secrets.ACCEPTANCE_ADMIN_PASSWORD }}
|
||
ACCEPTANCE_USER_EMAIL: ${{ secrets.ACCEPTANCE_USER_EMAIL }}
|
||
ACCEPTANCE_USER_PASSWORD: ${{ secrets.ACCEPTANCE_USER_PASSWORD }}
|
||
ACCEPTANCE_NODE_SECRET: ${{ secrets.ACCEPTANCE_NODE_SECRET }}
|
||
ACCEPTANCE_RUN_ID: qa_${{ github.run_id }}_${{ github.run_attempt }}
|
||
STAGING_DB_HOST: ${{ secrets.STAGING_DB_HOST }}
|
||
STAGING_DB_USER: ${{ secrets.STAGING_DB_USER }}
|
||
STAGING_DB_PASSWORD: ${{ secrets.STAGING_DB_PASSWORD }}
|
||
STAGING_DB_NAME: ${{ secrets.STAGING_DB_NAME }}
|
||
STAGING_REDIS_ADDR: ${{ secrets.STAGING_REDIS_ADDR }}
|
||
STAGING_REDIS_PASSWORD: ${{ secrets.STAGING_REDIS_PASSWORD }}
|
||
STAGING_REDIS_DB: ${{ vars.STAGING_REDIS_DB || '0' }}
|
||
run: |
|
||
set -o pipefail
|
||
|
||
go test -json ./tests/acceptance/... \
|
||
-staging-url="$STAGING_BASE_URL" \
|
||
-report-path="$ACCEPTANCE_REPORT_PATH" \
|
||
> >(tee "$ACCEPTANCE_TEST_JSON") \
|
||
2> >(tee "$ACCEPTANCE_FAILURE_LOG" >&2)
|
||
|
||
- name: 生成测试摘要
|
||
if: always()
|
||
run: |
|
||
set -euo pipefail
|
||
|
||
{
|
||
echo "## 发布验收测试"
|
||
echo
|
||
echo "- 状态:${{ job.status }}"
|
||
echo "- Staging URL:${STAGING_BASE_URL}"
|
||
echo "- Artifact:${ACCEPTANCE_ARTIFACT_NAME}"
|
||
echo "- Run URL:${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||
if [ "${{ github.event_name }}" = "workflow_run" ]; then
|
||
echo "- Deploy run:${{ github.event.workflow_run.html_url }}"
|
||
echo "- Deploy SHA:${{ github.event.workflow_run.head_sha }}"
|
||
else
|
||
echo "- 手动触发 SHA:${{ github.sha }}"
|
||
fi
|
||
echo
|
||
} | tee "$ACCEPTANCE_REPORT_DIR/summary.md" >> "$GITHUB_STEP_SUMMARY"
|
||
|
||
if [ "${{ job.status }}" = "failure" ]; then
|
||
if [ -s "$ACCEPTANCE_FAILURE_LOG" ]; then
|
||
{
|
||
echo
|
||
echo "Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||
echo "Artifact: ${ACCEPTANCE_ARTIFACT_NAME}"
|
||
} >> "$ACCEPTANCE_FAILURE_LOG"
|
||
else
|
||
{
|
||
echo "Acceptance 测试失败。"
|
||
echo "Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||
echo "Artifact: ${ACCEPTANCE_ARTIFACT_NAME}"
|
||
echo
|
||
tail -100 "$ACCEPTANCE_TEST_JSON" 2>/dev/null || true
|
||
} > "$ACCEPTANCE_FAILURE_LOG"
|
||
fi
|
||
elif [ ! -f "$ACCEPTANCE_FAILURE_LOG" ]; then
|
||
: > "$ACCEPTANCE_FAILURE_LOG"
|
||
fi
|
||
|
||
- name: 上传 acceptance artifact
|
||
if: always()
|
||
uses: actions/upload-artifact@v6
|
||
with:
|
||
name: ${{ env.ACCEPTANCE_ARTIFACT_NAME }}
|
||
path: |
|
||
${{ env.ACCEPTANCE_REPORT_PATH }}
|
||
${{ env.ACCEPTANCE_TEST_JSON }}
|
||
${{ env.ACCEPTANCE_FAILURE_LOG }}
|
||
${{ env.ACCEPTANCE_REPORT_DIR }}/summary.md
|
||
if-no-files-found: warn
|
||
retention-days: 14
|
||
|
||
- name: Telegram 成功通知
|
||
if: success()
|
||
env:
|
||
TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
|
||
TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}
|
||
run: |
|
||
if [ -z "${TG_BOT_TOKEN:-}" ] || [ -z "${TG_CHAT_ID:-}" ]; then
|
||
echo "Telegram 密钥未配置,跳过通知。"
|
||
exit 0
|
||
fi
|
||
|
||
MESSAGE="$(cat <<'EOF'
|
||
✅ 发布验收测试通过
|
||
仓库:${{ github.repository }}
|
||
分支:${{ github.event.workflow_run.head_branch || github.ref_name }}
|
||
提交:${{ github.event.workflow_run.head_sha || github.sha }}
|
||
Staging:${{ env.STAGING_BASE_URL }}
|
||
Artifact:${{ env.ACCEPTANCE_ARTIFACT_NAME }}
|
||
运行记录:${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||
EOF
|
||
)"
|
||
|
||
curl -fsS -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
|
||
--data-urlencode "chat_id=${TG_CHAT_ID}" \
|
||
--data-urlencode "text=${MESSAGE}" || echo "Telegram 通知发送失败,但验收结果不受影响。"
|
||
|
||
- name: Telegram 失败通知
|
||
if: failure()
|
||
env:
|
||
TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
|
||
TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}
|
||
run: |
|
||
if [ -z "${TG_BOT_TOKEN:-}" ] || [ -z "${TG_CHAT_ID:-}" ]; then
|
||
echo "Telegram 密钥未配置,跳过通知。"
|
||
exit 0
|
||
fi
|
||
|
||
MESSAGE="$(cat <<'EOF'
|
||
❌ 发布验收测试失败
|
||
仓库:${{ github.repository }}
|
||
分支:${{ github.event.workflow_run.head_branch || github.ref_name }}
|
||
提交:${{ github.event.workflow_run.head_sha || github.sha }}
|
||
Staging:${{ env.STAGING_BASE_URL }}
|
||
Artifact:${{ env.ACCEPTANCE_ARTIFACT_NAME }}
|
||
运行记录:${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||
EOF
|
||
)"
|
||
|
||
curl -fsS -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
|
||
--data-urlencode "chat_id=${TG_CHAT_ID}" \
|
||
--data-urlencode "text=${MESSAGE}" || echo "Telegram 通知发送失败,工作流失败状态已记录。"
|