|
8503
|
7077
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
📈 趋势分析
|
1
|
name: Test Report
"on":
workflow_run:
name: Test Report
"on":
workflow_run:
workflows:
- 'Test Suite'
- 'E2E Tests'
- 'Performance Tests'
types:
- completed
env:
NODE_VERSION: "18"
jobs:
trend-analysis:
name: "\U0001F4C8 趋势分析"
runs-on: ubuntu-latest
if: github.event.workflow_run.name == 'Test Suite'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4CA 分析测试趋势"
uses: actions/github-script@v7
with:
script: "// 获取最近 20 次运行记录\nconst runs = await github.rest.actions.listWorkflowRuns({\n owner: context.repo.owner,\n repo: context.repo.repo,\n workflow_id: 'test.yml',\n per_page: 20,\n});\n\nlet successCount = 0;\nlet failureCount = 0;\nconst durations = [];\n\nfor (const run of runs.data.workflow_runs) {\n if (run.conclusion === 'success') {\n successCount++;\n } else if (run.conclusion === 'failure') {\n failureCount++;\n }\n\n if (run.updated_at && run.created_at) {\n const duration = new Date(run.updated_at) - new Date(run.created_at);\n durations.push(duration / 1000 / 60); // 转换为分钟\n }\n}\n\nconst total = successCount + failureCount;\nconst successRate = total > 0 ? (successCount / total * 100).toFixed(1) : 0;\nconst avgDuration = durations.length > 0\n ? (durations.reduce((a, b) => a + b, 0) / durations.length).toFixed(1)\n : 0;\n\nconsole.log(`最近 ${total} 次运行:`);\nconsole.log(`- 成功: ${successCount}`);\nconsole.log(`- 失败: ${failureCount}`);\nconsole.log(`- 成功率: ${successRate}%`);\nconsole.log(`- 平均耗时: ${avgDuration} 分钟`);\n\n// 写入 summary\nconst fs = require('fs');\nconst summary = `## \U0001F4C8 测试趋势分析\n\n| 指标 | 值 |\n|------|------|\n| 分析样本 | 最近 ${total} 次运行 |\n| 成功次数 | ${successCount} |\n| 失败次数 | ${failureCount} |\n| 成功率 | ${successRate}% |\n| 平均耗时 | ${avgDuration} 分钟 |\n\n${successRate >= 90 ? '✅ 测试稳定性良好' : successRate >= 70 ? '⚠️ 测试稳定性一般' : '❌ 测试稳定性较差,需要关注'}\n`;\n\nfs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, summary);\n"
...
|
trend-analysis
|
["collect-results"]
|
["ubuntu-latest"]
|
7321
|
4
|
1773930005
|
1773930005
|
1773929920
|
1773930006
|
|
1
|
|
0
|
Edit
Delete
|
|
8504
|
7078
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
📥 收集测试结果
|
1
|
name: Test Report
"on":
workflow_run:
name: Test Report
"on":
workflow_run:
workflows:
- 'Test Suite'
- 'E2E Tests'
- 'Performance Tests'
types:
- completed
env:
NODE_VERSION: "18"
jobs:
collect-results:
name: "\U0001F4E5 收集测试结果"
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion != 'cancelled'
steps:
- name: "\U0001F4DD 记录工作流信息"
run: |
echo "工作流: ${{ github.event.workflow_run.name }}"
echo "结果: ${{ github.event.workflow_run.conclusion }}"
echo "运行 ID: ${{ github.event.workflow_run.id }}"
echo "分支: ${{ github.event.workflow_run.head_branch }}"
- name: "\U0001F4E5 下载测试结果 artifacts"
uses: actions/github-script@v7
with:
script: |
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }},
});
console.log('找到的 artifacts:');
for (const artifact of artifacts.data.artifacts) {
console.log(`- ${artifact.name} (${artifact.size_in_bytes} bytes)`);
}
// 保存 artifact 列表
const fs = require('fs');
fs.writeFileSync('artifacts.json', JSON.stringify(artifacts.data.artifacts, null, 2));
- name: "\U0001F4E4 上传 artifact 清单"
uses: actions/upload-artifact@v4
with:
name: artifact-list-${{ github.event.workflow_run.id }}
path: artifacts.json
retention-days: "7"
outputs:
run_id: ${{ github.event.workflow_run.id }}
workflow_conclusion: ${{ github.event.workflow_run.conclusion }}
workflow_name: ${{ github.event.workflow_run.name }}
...
|
collect-results
|
null
|
["ubuntu-latest"]
|
7322
|
2
|
1773930007
|
1773930010
|
1773929996
|
1773930010
|
|
0
|
|
0
|
Edit
Delete
|
|
8459
|
7069
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
自动回滚
|
1
|
name: Deploy
"on":
push:
branc name: Deploy
"on":
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- rollback
skip_tests:
description: '跳过测试(紧急修复时使用)'
required: false
default: false
type: boolean
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback:
name: 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- name: 配置 SSH
uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行自动回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "=========================================="
echo "检测到部署失败,执行自动回滚..."
echo "=========================================="
# 使用项目回滚脚本
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
# 备用回滚逻辑:读取最近一条部署历史
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API_IMAGE=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FRONTEND_IMAGE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API_IMAGE" ] && [ "$PREV_API_IMAGE" != "none" ]; then
echo "回滚到: API=$PREV_API_IMAGE, Frontend=$PREV_FRONTEND_IMAGE"
export API_IMAGE="$PREV_API_IMAGE"
export FRONTEND_IMAGE="$PREV_FRONTEND_IMAGE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
# 健康检查(带重试)
RETRY=0
MAX_RETRY=12
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
if [ $RETRY -ge $MAX_RETRY ]; then
echo "回滚后健康检查失败(60s),请手动介入"
docker compose -f docker-compose.prod.yml logs --tail=30 api
exit 1
fi
sleep 5
done
echo "回滚成功!"
else
echo "无法获取上一版本信息,需要手动回滚"
echo "部署历史:"
cat .deploy-history 2>/dev/null || echo "(空)"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
- if: always()
name: 发送回滚通知
uses: 8398a7/action-slack@v3
with:
custom_payload: |
{
"attachments": [{
"color": "${{ job.status == 'success' && 'warning' || 'danger' }}",
"title": "生产环境自动回滚",
"text": "部署失败触发自动回滚\n回滚状态: ${{ job.status }}",
"fields": [
{ "title": "环境", "value": "Production", "short": true },
{ "title": "触发者", "value": "${{ github.actor }}", "short": true },
{ "title": "版本", "value": "${{ needs.build-and-push.outputs.version }}", "short": true }
]
}]
}
status: custom
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
timeout-minutes: "10"
...
|
auto-rollback
|
["deploy-production"]
|
["ubuntu-latest"]
|
7323
|
4
|
1773930010
|
1773930011
|
1773929408
|
1773930011
|
|
1
|
|
0
|
Edit
Delete
|
|
8505
|
7078
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
📊 生成综合报告
|
0
|
name: Test Report
"on":
workflow_run:
name: Test Report
"on":
workflow_run:
workflows:
- 'Test Suite'
- 'E2E Tests'
- 'Performance Tests'
types:
- completed
env:
NODE_VERSION: "18"
jobs:
generate-report:
name: "\U0001F4CA 生成综合报告"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E5 下载触发工作流的 artifacts"
uses: dawidd6/action-download-artifact@v3
with:
path: downloaded-artifacts
run_id: ${{ github.event.workflow_run.id }}
workflow: ${{ github.event.workflow_run.workflow_id }}
continue-on-error: true
- name: "\U0001F4CA 生成综合测试报告"
run: "echo \"# \U0001F4CA 测试报告\" > test-report.md\necho \"\" >> test-report.md\necho \"**生成时间**: $(date)\" >> test-report.md\necho \"**触发工作流**: ${{ github.event.workflow_run.name }}\" >> test-report.md\necho \"**运行 ID**: ${{ github.event.workflow_run.id }}\" >> test-report.md\necho \"**分支**: ${{ github.event.workflow_run.head_branch }}\" >> test-report.md\necho \"**结果**: ${{ github.event.workflow_run.conclusion }}\" >> test-report.md\necho \"\" >> test-report.md\n\necho \"## \U0001F4C1 测试结果\" >> test-report.md\necho \"\" >> test-report.md\n\n# 遍历下载的 artifacts\nif [ -d \"downloaded-artifacts\" ]; then\n echo \"### 已下载的测试结果\" >> test-report.md\n echo \"\" >> test-report.md\n\n for dir in downloaded-artifacts/*; do\n if [ -d \"$dir\" ]; then\n name=$(basename \"$dir\")\n echo \"- **$name**\" >> test-report.md\n\n # 检查是否有 JSON 结果文件\n for json in \"$dir\"/*.json; do\n if [ -f \"$json\" ]; then\n echo \" - $(basename \"$json\")\" >> test-report.md\n fi\n done\n fi\n done\nelse\n echo \"暂无测试结果下载\" >> test-report.md\nfi\n\necho \"\" >> test-report.md\necho \"---\" >> test-report.md\necho \"*此报告由 CI/CD 自动生成*\" >> test-report.md\n"
- name: "\U0001F4DD 生成 GitHub Summary"
run: "echo \"## \U0001F4CA 测试报告汇总\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"| 项目 | 值 |\" >> $GITHUB_STEP_SUMMARY\necho \"|------|------|\" >> $GITHUB_STEP_SUMMARY\necho \"| 触发工作流 | ${{ github.event.workflow_run.name }} |\" >> $GITHUB_STEP_SUMMARY\necho \"| 运行 ID | ${{ github.event.workflow_run.id }} |\" >> $GITHUB_STEP_SUMMARY\necho \"| 分支 | ${{ github.event.workflow_run.head_branch }} |\" >> $GITHUB_STEP_SUMMARY\necho \"| 结果 | ${{ github.event.workflow_run.conclusion }} |\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ \"${{ github.event.workflow_run.conclusion }}\" == \"success\" ]; then\n echo \"### ✅ 测试通过\" >> $GITHUB_STEP_SUMMARY\nelse\n echo \"### ❌ 测试失败\" >> $GITHUB_STEP_SUMMARY\n echo \"\" >> $GITHUB_STEP_SUMMARY\n echo \"请查看 [运行详情](https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}) 了解更多信息。\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传综合报告"
uses: actions/upload-artifact@v4
with:
name: test-report-${{ github.event.workflow_run.id }}
path: test-report.md
retention-days: "30"
...
|
generate-report
|
["collect-results"]
|
["ubuntu-latest"]
|
0
|
4
|
0
|
0
|
1773929996
|
1773930012
|
|
1
|
|
0
|
Edit
Delete
|
|
8473
|
7071
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
测试总结
|
1
|
name: Integration Tests
"on":
push:
name: Integration Tests
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
run_all_tests:
description: '运行所有集成测试(包括慢速测试)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
test-summary:
name: 测试总结
runs-on: ubuntu-latest
if: always()
steps:
- name: 生成测试报告
run: "echo \"## \U0001F9EA 集成测试结果总结\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"| 测试类型 | 状态 |\" >> $GITHUB_STEP_SUMMARY\necho \"|----------|------|\" >> $GITHUB_STEP_SUMMARY\n\n# 单元测试\nif [ \"${{ needs.unit-tests.result }}\" == \"success\" ]; then\n echo \"| ✅ 单元测试 | 通过 |\" >> $GITHUB_STEP_SUMMARY\nelif [ \"${{ needs.unit-tests.result }}\" == \"skipped\" ]; then\n echo \"| ⏭️ 单元测试 | 跳过 |\" >> $GITHUB_STEP_SUMMARY\nelse\n echo \"| ❌ 单元测试 | 失败 |\" >> $GITHUB_STEP_SUMMARY\nfi\n\n# 集成测试\nif [ \"${{ needs.integration-tests.result }}\" == \"success\" ]; then\n echo \"| ✅ 集成测试 | 通过 |\" >> $GITHUB_STEP_SUMMARY\nelif [ \"${{ needs.integration-tests.result }}\" == \"skipped\" ]; then\n echo \"| ⏭️ 集成测试 | 跳过 |\" >> $GITHUB_STEP_SUMMARY\nelse\n echo \"| ❌ 集成测试 | 失败 |\" >> $GITHUB_STEP_SUMMARY\nfi\n\n# API E2E 测试\nif [ \"${{ needs.api-e2e-tests.result }}\" == \"success\" ]; then\n echo \"| ✅ API E2E 测试 | 通过 |\" >> $GITHUB_STEP_SUMMARY\nelif [ \"${{ needs.api-e2e-tests.result }}\" == \"skipped\" ]; then\n echo \"| ⏭️ API E2E 测试 | 跳过 |\" >> $GITHUB_STEP_SUMMARY\nelse\n echo \"| ❌ API E2E 测试 | 失败 |\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: 检查测试结果
run: |
UNIT="${{ needs.unit-tests.result }}"
INTEGRATION="${{ needs.integration-tests.result }}"
API="${{ needs.api-e2e-tests.result }}"
if [ "$UNIT" == "failure" ] || [ "$INTEGRATION" == "failure" ] || [ "$API" == "failure" ]; then
echo "❌ 有测试失败"
exit 1
fi
echo "✅ 所有测试通过"
...
|
test-summary
|
["unit-tests","integration-tests", ["unit-tests","integration-tests","api-e2e-tests"]...
|
["ubuntu-latest"]
|
7324
|
2
|
1773930012
|
1773930013
|
1773929409
|
1773930013
|
|
1
|
|
0
|
Edit
Delete
|
|
8506
|
7078
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
📢 发送通知
|
1
|
name: Test Report
"on":
workflow_run:
name: Test Report
"on":
workflow_run:
workflows:
- 'Test Suite'
- 'E2E Tests'
- 'Performance Tests'
types:
- completed
env:
NODE_VERSION: "18"
jobs:
notify:
name: "\U0001F4E2 发送通知"
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'failure'
steps:
- name: "\U0001F4E2 创建失败 Issue(可选)"
uses: actions/github-script@v7
with:
script: "// 检查是否已经存在相关 issue\nconst issues = await github.rest.issues.listForRepo({\n owner: context.repo.owner,\n repo: context.repo.repo,\n labels: 'test-failure',\n state: 'open',\n});\n\nconst workflowName = '${{ github.event.workflow_run.name }}';\nconst runId = '${{ github.event.workflow_run.id }}';\nconst branch = '${{ github.event.workflow_run.head_branch }}';\n\n// 如果是主分支失败,创建 issue\nif (branch === 'main' || branch === 'develop') {\n const existingIssue = issues.data.find(i =>\n i.title.includes(workflowName) && i.title.includes(branch)\n );\n\n if (!existingIssue) {\n await github.rest.issues.create({\n owner: context.repo.owner,\n repo: context.repo.repo,\n title: `\U0001F6A8 ${workflowName} 测试失败 (${branch})`,\n body: `## 测试失败通知\n\n**工作流**: ${workflowName}\n**分支**: ${branch}\n**运行 ID**: ${runId}\n\n### 详情\n\n请查看 [运行详情](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}) 了解更多信息。\n\n### 后续步骤\n\n1. 查看失败的测试用例\n2. 修复问题\n3. 重新运行测试\n4. 关闭此 issue\n\n---\n*此 issue 由 CI/CD 自动创建*`,\n labels: ['test-failure', 'automated'],\n });\n console.log('已创建测试失败 issue');\n } else {\n // 添加评论\n await github.rest.issues.createComment({\n owner: context.repo.owner,\n repo: context.repo.repo,\n issue_number: existingIssue.number,\n body: `测试再次失败。运行 ID: ${runId}\\n\\n[查看详情](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId})`,\n });\n console.log('已在现有 issue 中添加评论');\n }\n}\n"
...
|
notify
|
["collect-results","generate-report ["collect-results","generate-report"]...
|
["ubuntu-latest"]
|
7325
|
4
|
1773930014
|
1773930015
|
1773929996
|
1773930015
|
|
1
|
|
0
|
Edit
Delete
|
|
8507
|
7078
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
📈 趋势分析
|
1
|
name: Test Report
"on":
workflow_run:
name: Test Report
"on":
workflow_run:
workflows:
- 'Test Suite'
- 'E2E Tests'
- 'Performance Tests'
types:
- completed
env:
NODE_VERSION: "18"
jobs:
trend-analysis:
name: "\U0001F4C8 趋势分析"
runs-on: ubuntu-latest
if: github.event.workflow_run.name == 'Test Suite'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4CA 分析测试趋势"
uses: actions/github-script@v7
with:
script: "// 获取最近 20 次运行记录\nconst runs = await github.rest.actions.listWorkflowRuns({\n owner: context.repo.owner,\n repo: context.repo.repo,\n workflow_id: 'test.yml',\n per_page: 20,\n});\n\nlet successCount = 0;\nlet failureCount = 0;\nconst durations = [];\n\nfor (const run of runs.data.workflow_runs) {\n if (run.conclusion === 'success') {\n successCount++;\n } else if (run.conclusion === 'failure') {\n failureCount++;\n }\n\n if (run.updated_at && run.created_at) {\n const duration = new Date(run.updated_at) - new Date(run.created_at);\n durations.push(duration / 1000 / 60); // 转换为分钟\n }\n}\n\nconst total = successCount + failureCount;\nconst successRate = total > 0 ? (successCount / total * 100).toFixed(1) : 0;\nconst avgDuration = durations.length > 0\n ? (durations.reduce((a, b) => a + b, 0) / durations.length).toFixed(1)\n : 0;\n\nconsole.log(`最近 ${total} 次运行:`);\nconsole.log(`- 成功: ${successCount}`);\nconsole.log(`- 失败: ${failureCount}`);\nconsole.log(`- 成功率: ${successRate}%`);\nconsole.log(`- 平均耗时: ${avgDuration} 分钟`);\n\n// 写入 summary\nconst fs = require('fs');\nconst summary = `## \U0001F4C8 测试趋势分析\n\n| 指标 | 值 |\n|------|------|\n| 分析样本 | 最近 ${total} 次运行 |\n| 成功次数 | ${successCount} |\n| 失败次数 | ${failureCount} |\n| 成功率 | ${successRate}% |\n| 平均耗时 | ${avgDuration} 分钟 |\n\n${successRate >= 90 ? '✅ 测试稳定性良好' : successRate >= 70 ? '⚠️ 测试稳定性一般' : '❌ 测试稳定性较差,需要关注'}\n`;\n\nfs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, summary);\n"
...
|
trend-analysis
|
["collect-results"]
|
["ubuntu-latest"]
|
7326
|
4
|
1773930016
|
1773930017
|
1773929996
|
1773930017
|
|
1
|
|
0
|
Edit
Delete
|
|
8508
|
7079
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7327
|
4
|
1773930034
|
1773930035
|
1773930033
|
1773930035
|
|
0
|
|
0
|
Edit
Delete
|
|
8509
|
7080
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7328
|
4
|
1773930334
|
1773930335
|
1773930333
|
1773930335
|
|
0
|
|
0
|
Edit
Delete
|
|
8510
|
7081
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7329
|
4
|
1773930634
|
1773930635
|
1773930633
|
1773930635
|
|
0
|
|
0
|
Edit
Delete
|
|
8511
|
7082
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7330
|
4
|
1773930934
|
1773930935
|
1773930933
|
1773930935
|
|
0
|
|
0
|
Edit
Delete
|
|
8512
|
7083
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7331
|
4
|
1773931234
|
1773931235
|
1773931233
|
1773931235
|
|
0
|
|
0
|
Edit
Delete
|
|
8513
|
7084
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7332
|
4
|
1773931534
|
1773931535
|
1773931533
|
1773931535
|
|
0
|
|
0
|
Edit
Delete
|
|
8514
|
7085
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7333
|
4
|
1773931834
|
1773931835
|
1773931833
|
1773931835
|
|
0
|
|
0
|
Edit
Delete
|
|
8515
|
7086
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7334
|
4
|
1773932134
|
1773932135
|
1773932133
|
1773932135
|
|
0
|
|
0
|
Edit
Delete
|
|
8516
|
7087
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7335
|
4
|
1773932434
|
1773932435
|
1773932433
|
1773932435
|
|
0
|
|
0
|
Edit
Delete
|
|
8517
|
7088
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7336
|
4
|
1773932734
|
1773932735
|
1773932733
|
1773932735
|
|
0
|
|
0
|
Edit
Delete
|
|
8518
|
7089
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7337
|
4
|
1773933034
|
1773933035
|
1773933033
|
1773933035
|
|
0
|
|
0
|
Edit
Delete
|
|
8519
|
7090
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7338
|
4
|
1773933334
|
1773933335
|
1773933333
|
1773933335
|
|
0
|
|
0
|
Edit
Delete
|
|
8520
|
7091
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7339
|
4
|
1773933634
|
1773933635
|
1773933633
|
1773933635
|
|
0
|
|
0
|
Edit
Delete
|
|
8521
|
7092
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7340
|
4
|
1773933934
|
1773933935
|
1773933933
|
1773933935
|
|
0
|
|
0
|
Edit
Delete
|
|
8522
|
7093
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7341
|
4
|
1773934234
|
1773934235
|
1773934233
|
1773934235
|
|
0
|
|
0
|
Edit
Delete
|
|
8523
|
7094
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7342
|
4
|
1773934534
|
1773934535
|
1773934533
|
1773934535
|
|
0
|
|
0
|
Edit
Delete
|
|
8524
|
7095
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7343
|
4
|
1773934834
|
1773934835
|
1773934833
|
1773934835
|
|
0
|
|
0
|
Edit
Delete
|
|
8525
|
7096
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7344
|
4
|
1773935134
|
1773935135
|
1773935133
|
1773935135
|
|
0
|
|
0
|
Edit
Delete
|
|
8526
|
7097
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7345
|
4
|
1773935434
|
1773935435
|
1773935433
|
1773935435
|
|
0
|
|
0
|
Edit
Delete
|
|
8527
|
7098
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7346
|
4
|
1773935734
|
1773935735
|
1773935733
|
1773935735
|
|
0
|
|
0
|
Edit
Delete
|
|
8528
|
7099
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7347
|
4
|
1773936034
|
1773936035
|
1773936033
|
1773936035
|
|
0
|
|
0
|
Edit
Delete
|
|
8529
|
7100
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7348
|
4
|
1773936334
|
1773936335
|
1773936333
|
1773936335
|
|
0
|
|
0
|
Edit
Delete
|
|
8530
|
7101
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7349
|
4
|
1773936634
|
1773936635
|
1773936633
|
1773936635
|
|
0
|
|
0
|
Edit
Delete
|
|
8531
|
7102
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7350
|
4
|
1773936934
|
1773936935
|
1773936933
|
1773936935
|
|
0
|
|
0
|
Edit
Delete
|
|
8532
|
7103
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7351
|
4
|
1773937234
|
1773937235
|
1773937233
|
1773937235
|
|
0
|
|
0
|
Edit
Delete
|
|
8533
|
7104
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7352
|
4
|
1773937534
|
1773937535
|
1773937533
|
1773937535
|
|
0
|
|
0
|
Edit
Delete
|
|
8534
|
7105
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7353
|
4
|
1773937834
|
1773937835
|
1773937833
|
1773937835
|
|
0
|
|
0
|
Edit
Delete
|
|
8535
|
7106
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7354
|
4
|
1773938134
|
1773938135
|
1773938133
|
1773938135
|
|
0
|
|
0
|
Edit
Delete
|
|
8536
|
7107
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7355
|
4
|
1773938434
|
1773938435
|
1773938433
|
1773938435
|
|
0
|
|
0
|
Edit
Delete
|
|
8537
|
7108
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7356
|
4
|
1773938734
|
1773938735
|
1773938733
|
1773938735
|
|
0
|
|
0
|
Edit
Delete
|
|
8538
|
7109
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7357
|
4
|
1773939034
|
1773939035
|
1773939033
|
1773939035
|
|
0
|
|
0
|
Edit
Delete
|
|
8539
|
7110
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7358
|
4
|
1773939334
|
1773939335
|
1773939333
|
1773939335
|
|
0
|
|
0
|
Edit
Delete
|
|
8540
|
7111
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
生产环境健康检查
|
1
|
name: Health Check
"on":
schedule:
name: Health Check
"on":
schedule:
# 每 5 分钟检查一次
- cron: '*/5 * * * *'
workflow_dispatch:
jobs:
health-check:
name: 生产环境健康检查
runs-on: ubuntu-latest
if: github.repository == 'your-org/juhi' # 替换为实际仓库
steps:
- id: api-health
name: API 健康检查
run: |
RESPONSE=$(curl -sf https://juhi.example.com/v1/health || echo '{"status":"error"}')
echo "response=$RESPONSE" >> $GITHUB_OUTPUT
STATUS=$(echo $RESPONSE | jq -r '.status // "error"')
if [ "$STATUS" != "ok" ]; then
echo "API 健康检查失败"
exit 1
fi
echo "API 健康检查通过"
- name: 前端可访问性检查
run: |
HTTP_STATUS=$(curl -so /dev/null -w "%{http_code}" https://juhi.example.com/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "前端返回 HTTP $HTTP_STATUS"
exit 1
fi
echo "前端可访问性检查通过"
- name: SSL 证书检查
run: |
EXPIRY_DATE=$(echo | openssl s_client -servername juhi.example.com -connect juhi.example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
echo "SSL 证书剩余 $DAYS_LEFT 天"
if [ $DAYS_LEFT -lt 7 ]; then
echo "::warning::SSL 证书将在 $DAYS_LEFT 天后过期!"
fi
if [ $DAYS_LEFT -lt 0 ]; then
echo "SSL 证书已过期"
exit 1
fi
- name: 响应时间检查
run: |
RESPONSE_TIME=$(curl -so /dev/null -w "%{time_total}" https://juhi.example.com/v1/health)
echo "API 响应时间: ${RESPONSE_TIME}s"
# 响应时间超过 5 秒告警
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "::warning::API 响应时间过长: ${RESPONSE_TIME}s"
fi
- if: failure()
name: Slack 通知(失败时)
uses: 8398a7/action-slack@v3
with:
fields: repo,message,commit,author,action,eventName,workflow
status: ${{ job.status }}
text: "\U0001F6A8 生产环境健康检查失败!请立即检查。"
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
health-check
|
null
|
["ubuntu-latest"]
|
7359
|
4
|
1773939634
|
1773939635
|
1773939633
|
1773939635
|
|
0
|
|
0
|
Edit
Delete
|
|
8541
|
7112
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
检测代码变更
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
detect-changes:
name: 检测代码变更
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: filter
uses: dorny/paths-filter@v3
with:
filters: |
backend:
- 'backend/**'
- 'shared/**'
frontend:
- 'frontend/**'
- 'shared/**'
mobile:
- 'mobile/**'
- 'shared/**'
shared:
- 'shared/**'
workflows:
- '.github/workflows/**'
outputs:
backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }}
mobile: ${{ steps.filter.outputs.mobile }}
shared: ${{ steps.filter.outputs.shared }}
workflows: ${{ steps.filter.outputs.workflows }}
...
|
detect-changes
|
null
|
["ubuntu-latest"]
|
7360
|
1
|
1773939780
|
1773939796
|
1773939779
|
1773939796
|
|
0
|
|
0
|
Edit
Delete
|
|
8542
|
7112
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
安装依赖
|
1
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
setup:
name: 安装依赖
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 构建共享包
run: pnpm --filter @juhi/shared run build
- name: 缓存 node_modules
uses: actions/cache/save@v4
with:
key: deps-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
path: |
node_modules
backend/node_modules
frontend/node_modules
mobile/node_modules
shared/node_modules
shared/dist
e2e/node_modules
...
|
setup
|
null
|
["ubuntu-latest"]
|
7361
|
2
|
1773939796
|
1773939813
|
1773939779
|
1773939813
|
|
0
|
|
0
|
Edit
Delete
|
|
8552
|
7112
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
依赖安全审计
|
0
|
name: CI
"on":
push:
branches: name: CI
"on":
push:
branches: [main, develop, 'feature/**', 'claude/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
dependency-audit:
name: 依赖安全审计
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: pnpm 依赖审计
run: pnpm audit --audit-level high || true
...
|
dependency-audit
|
["setup"]
|
["ubuntu-latest"]
|
0
|
4
|
0
|
0
|
1773939779
|
1773939815
|
|
1
|
|
0
|
Edit
Delete
|
|
8558
|
7113
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
🔒 多租户安全审计
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: tenant-audit
name: "\U0001F50D 多租户隔离检查"
run: |
cd backend
npm run audit:tenant 2>&1 | tee tenant-audit.log
# 检查是否有 P0 级别问题
if grep -q "P0" tenant-audit.log; then
echo "has_p0_issues=true" >> $GITHUB_OUTPUT
else
echo "has_p0_issues=false" >> $GITHUB_OUTPUT
fi
- name: "\U0001F4CA 上传审计报告"
uses: actions/upload-artifact@v4
with:
name: tenant-security-report
path: backend/tenant-audit.log
- if: steps.tenant-audit.outputs.has_p0_issues == 'true'
name: ❌ P0 问题阻断
run: |
echo "::error::发现 P0 级别多租户安全问题,禁止合并!"
exit 1
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7362
|
2
|
1773939813
|
1773939835
|
1773939780
|
1773939835
|
|
0
|
|
0
|
Edit
Delete
|
|
8559
|
7113
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
⚡ N+1 查询检测
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
n1-query-detection:
name: ⚡ N+1 查询检测
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: n1-audit
name: "\U0001F50D N+1 查询检测"
run: |
cd backend
npm run audit:n1 --fix 2>&1 | tee n1-audit.log
# 提取 HIGH 问题数量
HIGH_COUNT=$(grep -c "HIGH" n1-audit.log || echo "0")
echo "high_count=$HIGH_COUNT" >> $GITHUB_OUTPUT
- name: "\U0001F4CA 上传 N+1 报告"
uses: actions/upload-artifact@v4
with:
name: n1-query-report
path: backend/n1-audit.log
- if: steps.n1-audit.outputs.high_count > 0
name: ⚠️ N+1 问题警告
run: |
echo "::warning::发现 ${{ steps.n1-audit.outputs.high_count }} 个 HIGH 级别 N+1 查询问题"
timeout-minutes: "10"
...
|
n1-query-detection
|
null
|
["ubuntu-latest"]
|
7363
|
2
|
1773939835
|
1773939861
|
1773939780
|
1773939861
|
|
0
|
|
0
|
Edit
Delete
|
|
8560
|
7113
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
🛡️ RLS 覆盖分析
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
rls-coverage:
name: "\U0001F6E1️ RLS 覆盖分析"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: rls-analysis
name: "\U0001F50D RLS 策略分析"
run: |
cd backend
npm run rls:analyze 2>&1 | tee rls-analysis.log
# 提取覆盖率
COVERAGE=$(grep -oP 'RLS 覆盖率: \K[\d.]+%' rls-analysis.log || echo "0%")
echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT
- name: "\U0001F4CA 上传 RLS 分析报告"
uses: actions/upload-artifact@v4
with:
name: rls-coverage-report
path: backend/rls-analysis.log
- name: "\U0001F4C8 RLS 覆盖率检查"
run: |
COVERAGE="${{ steps.rls-analysis.outputs.coverage }}"
echo "当前 RLS 覆盖率: $COVERAGE"
# 提取数字部分
PERCENT=$(echo $COVERAGE | grep -oP '[\d.]+' || echo "0")
if (( $(echo "$PERCENT < 80" | bc -l) )); then
echo "::warning::RLS 覆盖率低于 80%,建议增加 RLS 策略"
fi
timeout-minutes: "10"
...
|
rls-coverage
|
null
|
["ubuntu-latest"]
|
7364
|
2
|
1773939861
|
1773939880
|
1773939780
|
1773939881
|
|
0
|
|
0
|
Edit
Delete
|
|
8561
|
7113
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
🔐 权限安全审计
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
permission-security:
name: "\U0001F510 权限安全审计"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: permission-audit
name: "\U0001F50D 权限配置审计"
run: |
cd backend
npm run audit:permission --json 2>&1 | tee permission-audit.json
continue-on-error: true
- name: "\U0001F4CA 上传权限审计报告"
uses: actions/upload-artifact@v4
with:
name: permission-audit-report
path: backend/permission-audit.json
timeout-minutes: "10"
...
|
permission-security
|
null
|
["ubuntu-latest"]
|
7365
|
2
|
1773939881
|
1773939900
|
1773939780
|
1773939900
|
|
0
|
|
0
|
Edit
Delete
|
|
8564
|
7114
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
质量门禁
|
1
|
name: Deploy
"on":
push:
branc name: Deploy
"on":
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- rollback
skip_tests:
description: '跳过测试(紧急修复时使用)'
required: false
default: false
type: boolean
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
quality-check:
name: 质量门禁
runs-on: ubuntu-latest
if: >-
!(github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'rollback') && !(github.event_name == 'workflow_dispatch' && github.event.inputs.skip_tests == 'true')
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 后端类型检查
run: npx tsc --noEmit
working-directory: backend
- name: 前端类型检查
run: npx vue-tsc --noEmit
working-directory: frontend
- name: 后端测试
run: npm run test:run -- --reporter=default --reporter=junit --outputFile=test-results.xml
working-directory: backend
env:
NODE_ENV: test
- if: always()
name: 上传测试结果
uses: actions/upload-artifact@v4
with:
name: test-results
path: backend/test-results.xml
retention-days: "7"
timeout-minutes: "15"
...
|
quality-check
|
null
|
["ubuntu-latest"]
|
7366
|
2
|
1773939901
|
1773939923
|
1773939780
|
1773939923
|
|
0
|
|
0
|
Edit
Delete
|
|
8569
|
7114
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
手动回滚
|
1
|
name: Deploy
"on":
push:
branc name: Deploy
"on":
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- rollback
skip_tests:
description: '跳过测试(紧急修复时使用)'
required: false
default: false
type: boolean
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
manual-rollback:
name: 手动回滚
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'rollback'
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 配置 SSH
uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 列出可用版本
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "可用版本历史:"
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --list
else
echo "最近部署记录:"
tail -10 .deploy-history 2>/dev/null || echo "(无记录)"
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
- name: 执行手动回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
# 执行回滚到上一版本
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --version 1 --confirm
else
echo "rollback.sh 不存在,请手动回滚"
exit 1
fi
# 执行部署后验证
if [ -f "./scripts/post-deploy-verify.sh" ]; then
chmod +x ./scripts/post-deploy-verify.sh
./scripts/post-deploy-verify.sh --quick
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
- if: always()
name: Slack 通知
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 手动回滚 ${{ job.status }}
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
timeout-minutes: "10"
...
|
manual-rollback
|
null
|
["ubuntu-latest"]
|
7367
|
4
|
1773939923
|
1773939924
|
1773939780
|
1773939924
|
|
0
|
|
0
|
Edit
Delete
|
|
8570
|
7115
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
pr-validation
|
1
|
name: E2E Tests
"on":
# PR validation name: E2E Tests
"on":
# PR validation - 运行关键测试
pull_request:
branches: [main, develop]
paths:
- 'frontend/**'
- 'backend/**'
- 'e2e/**'
- 'package.json'
- 'pnpm-lock.yaml'
# Push to main - 运行完整测试套件
push:
branches: [main]
# 每日定时全量测试 (UTC 时间 00:00 = 北京时间 08:00)
schedule:
- cron: '0 0 * * *'
# 手动触发
workflow_dispatch:
inputs:
test_suite:
description: 'Test suite to run'
required: true
default: 'all'
type: choice
options:
- all
- critical
- business-flows
- visual-regression
- performance
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
pr-validation:
name: pr-validation
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Setup test database
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/juhi_test
- name: Build backend
run: |
cd backend
npm run build
- name: Build frontend
run: |
cd frontend
npm run build
- name: Install Playwright Browsers
run: npx playwright install --with-deps chromium
- name: Start backend server
run: |
cd backend
npm run start &
sleep 10
env:
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/juhi_test
REDIS_URL: redis://localhost:6379
NODE_ENV: test
- name: Start frontend server
run: |
cd frontend
npm run preview &
sleep 5
env:
VITE_API_URL: http://localhost:3000
- name: Run critical E2E tests
run: |
cd e2e
npx playwright test \
tests/auth/login.spec.ts \
tests/navigation/full-menu-click.spec.ts \
tests/multi-tenant/data-isolation.spec.ts \
--reporter=html
env:
E2E_BASE_URL: http://localhost:5173
E2E_TEST_USER: admin@juhi.com
E2E_TEST_PASSWORD: Admin@123
- if: always()
name: Upload test results
uses: actions/upload-artifact@v4
with:
name: playwright-report-pr
path: e2e/playwright-report/
retention-days: "7"
- if: always() && github.event_name == 'pull_request'
name: Comment PR with test results
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const reportPath = 'e2e/playwright-report/index.html';
const testsPassed = !fs.existsSync('e2e/test-results/');
const comment = testsPassed
? '✅ E2E 测试通过!'
: '❌ E2E 测试失败,请查看报告';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
timeout-minutes: "30"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test_password
POSTGRES_USER: test_user
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
...
|
pr-validation
|
null
|
["ubuntu-latest"]
|
7368
|
4
|
1773939925
|
1773939926
|
1773939781
|
1773939926
|
|
0
|
|
0
|
Edit
Delete
|