配置(#6): 新增 release-acceptance workflow

This commit is contained in:
2026-06-04 02:45:15 -07:00
committed by GitHub
parent 5e4cc33ff6
commit 377f13da48
+244
View File
@@ -0,0 +1,244 @@
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: acceptance-artifacts
ACCEPTANCE_REPORT_PATH: acceptance-artifacts/acceptance-report.json
ACCEPTANCE_TEST_JSON: acceptance-artifacts/go-test.json
ACCEPTANCE_FAILURE_LOG: 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 }}
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 }}
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
missing=()
required=(
ACCEPTANCE_ADMIN_EMAIL
ACCEPTANCE_ADMIN_PASSWORD
ACCEPTANCE_USER_EMAIL
ACCEPTANCE_USER_PASSWORD
STAGING_BASE_URL
STAGING_DB_HOST
STAGING_DB_USER
STAGING_DB_PASSWORD
STAGING_DB_NAME
STAGING_REDIS_ADDR
STAGING_REDIS_PASSWORD
)
for key in "${required[@]}"; do
if [ -z "${!key:-}" ]; then
missing+=("$key")
fi
done
if [ "${#missing[@]}" -gt 0 ]; then
printf '缺少必需 GitHub Actions secrets/vars\n' | tee "$ACCEPTANCE_FAILURE_LOG"
printf -- '- %s\n' "${missing[@]}" | tee -a "$ACCEPTANCE_FAILURE_LOG"
{
echo "## 发布验收测试"
echo
echo "状态:配置缺失"
echo
echo "缺少以下 secrets/vars"
printf -- '- `%s`\n' "${missing[@]}"
} >> "$GITHUB_STEP_SUMMARY"
exit 1
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 通知发送失败,工作流失败状态已记录。"