|
1637
|
1032
|
6
|
5
|
68528dce9b8c543283a675374b5a23bc2e46c935
|
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"]
|
1021
|
2
|
1772148766
|
1772148810
|
1772148752
|
1772148810
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
672
|
83
|
6
|
5
|
c75a655fbcae4e4a5f0f675e72c422c5c3ff5a72
|
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"]
|
72
|
2
|
1771866020
|
1771866217
|
1771864209
|
1771866217
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
671
|
83
|
6
|
5
|
c75a655fbcae4e4a5f0f675e72c422c5c3ff5a72
|
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"]
|
71
|
2
|
1771865990
|
1771866020
|
1771864209
|
1771866020
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
482
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
发布测试报告
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
publish-reports:
name: 发布测试报告
runs-on: ubuntu-latest
if: always()
steps:
- name: 下载所有制品
uses: actions/download-artifact@v3
- name: 生成汇总报告
run: |
mkdir -p reports
# 合并所有报告
echo "生成 HTML 汇总报告..."
- if: github.ref == 'refs/heads/main'
name: 部署报告到 GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
destination_dir: test-reports/${{ github.run_number }}
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./reports
- name: 发布报告链接
run: "echo \"\U0001F4CA 测试报告已发布:\"\necho \"https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/test-reports/${{ github.run_number }}\"\n"
...
|
publish-reports
|
["unit-tests","integration-tests", ["unit-tests","integration-tests","e2e-tests"]...
|
["ubuntu-latest"]
|
74
|
2
|
1771866248
|
1771866278
|
1771863142
|
1771866278
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
481
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
质量门禁检查
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
quality-gate:
name: 质量门禁检查
runs-on: ubuntu-latest
if: always()
steps:
- name: 下载所有测试结果
uses: actions/download-artifact@v3
- name: 汇总测试结果
run: |
echo "## 测试汇总报告" > summary.md
echo "" >> summary.md
echo "### 单元测试" >> summary.md
# 解析单元测试结果
echo "### 集成测试" >> summary.md
# 解析集成测试结果
echo "### E2E 测试" >> summary.md
# 解析 E2E 测试结果
- name: 检查所有测试是否通过
run: |
if [[ "${{ needs.unit-tests.result }}" != "success" ]]; then
echo "❌ 单元测试失败"
exit 1
fi
if [[ "${{ needs.integration-tests.result }}" != "success" ]]; then
echo "❌ 集成测试失败"
exit 1
fi
if [[ "${{ needs.e2e-tests.result }}" != "success" ]]; then
echo "❌ E2E 测试失败"
exit 1
fi
echo "✅ 所有测试通过,质量门禁检查成功"
- if: failure()
name: 发送通知
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 测试失败!请查看详情。
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
...
|
quality-gate
|
["unit-tests","integration-tests", ["unit-tests","integration-tests","e2e-tests"]...
|
["ubuntu-latest"]
|
73
|
2
|
1771866218
|
1771866248
|
1771863142
|
1771866248
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
480
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
性能测试(K6)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
performance-tests:
name: 性能测试(K6)
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || github.event_name == 'schedule'
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 K6
run: |
curl https://github.com/grafana/k6/releases/download/v0.47.0/k6-v0.47.0-linux-amd64.tar.gz -L | tar xvz
sudo mv k6-v0.47.0-linux-amd64/k6 /usr/bin/k6
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖并启动服务
run: |
pnpm install --frozen-lockfile
cd backend && pnpm start &
sleep 10
- name: 运行性能测试
run: pnpm test:performance:ci
env:
API_URL: http://localhost:3000
AUTH_TOKEN: ${{ secrets.TEST_AUTH_TOKEN }}
- name: 分析性能结果
run: |
P95=$(jq '.metrics.http_req_duration.values.["p(95)"]' performance-results.json)
echo "P95 响应时间: ${P95}ms"
if (( $(echo "$P95 > 200" | bc -l) )); then
echo "❌ P95 响应时间超过 200ms"
exit 1
fi
echo "✅ 性能测试通过"
- if: always()
name: 上传性能报告
uses: actions/upload-artifact@v3
with:
name: performance-results
path: performance-results.json
timeout-minutes: "30"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
redis:
image: redis:7-alpine
ports:
- 6379:6379
...
|
performance-tests
|
null
|
["ubuntu-latest"]
|
70
|
2
|
1771865959
|
1771865989
|
1771863142
|
1771865990
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
479
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (webkit, service-ticket)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (webkit, service-ticket)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- webkit
flow:
- service-ticket
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
69
|
2
|
1771865929
|
1771865959
|
1771863142
|
1771865959
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
478
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (webkit, renewal)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (webkit, renewal)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- webkit
flow:
- renewal
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
68
|
2
|
1771865838
|
1771865929
|
1771863142
|
1771865929
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
477
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (webkit, lead-to-cash)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (webkit, lead-to-cash)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- webkit
flow:
- lead-to-cash
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
67
|
2
|
1771865669
|
1771865838
|
1771863142
|
1771865838
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
476
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (webkit, approval)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (webkit, approval)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- webkit
flow:
- approval
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
66
|
2
|
1771865579
|
1771865669
|
1771863142
|
1771865669
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
475
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (firefox, service-ticket)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (firefox, service-ticket)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- firefox
flow:
- service-ticket
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
65
|
2
|
1771865488
|
1771865578
|
1771863142
|
1771865578
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
474
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (firefox, renewal)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (firefox, renewal)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- firefox
flow:
- renewal
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
64
|
2
|
1771865198
|
1771865488
|
1771863142
|
1771865488
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
473
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (firefox, lead-to-cash)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (firefox, lead-to-cash)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- firefox
flow:
- lead-to-cash
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
63
|
2
|
1771864704
|
1771865198
|
1771863142
|
1771865198
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
472
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (firefox, approval)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (firefox, approval)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- firefox
flow:
- approval
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
62
|
2
|
1771864272
|
1771864704
|
1771863142
|
1771864704
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
471
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (chromium, service-ticket)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (chromium, service-ticket)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- chromium
flow:
- service-ticket
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
61
|
2
|
1771864181
|
1771864271
|
1771863142
|
1771864272
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
470
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (chromium, renewal)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (chromium, renewal)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- chromium
flow:
- renewal
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
60
|
2
|
1771863748
|
1771864181
|
1771863142
|
1771864181
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
469
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (chromium, lead-to-cash)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (chromium, lead-to-cash)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- chromium
flow:
- lead-to-cash
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
59
|
2
|
1771863467
|
1771863748
|
1771863142
|
1771863748
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
468
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
E2E 测试(Playwright) (chromium, approval)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
e2e-tests:
name: E2E 测试(Playwright) (chromium, approval)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 安装 Playwright 浏览器
run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
- name: 构建前端
run: cd frontend && pnpm build
- name: 启动服务
run: |
cd backend && pnpm start &
cd frontend && pnpm preview &
sleep 10
- name: 运行 E2E 测试
run: pnpm test:e2e --project=${{ matrix.browser }} --grep="${{ matrix.flow }}"
- if: always()
name: 上传 Playwright 报告
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-report
path: e2e/playwright-report/
- if: failure()
name: 上传失败截图
uses: actions/upload-artifact@v3
with:
name: e2e-${{ matrix.browser }}-${{ matrix.flow }}-screenshots
path: e2e/screenshots/
timeout-minutes: "45"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s
strategy:
matrix:
browser:
- chromium
flow:
- approval
...
|
e2e-tests
|
null
|
["ubuntu-latest"]
|
58
|
2
|
1771863410
|
1771863467
|
1771863142
|
1771863467
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
467
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
集成测试(API + DB + Events)
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
integration-tests:
name: 集成测试(API + DB + Events)
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 设置测试环境变量
run: |
cd backend
cat > .env.test <<EOF
NODE_ENV=test
DATABASE_URL=postgresql://test:test@localhost:5432/juhi_test
REDIS_URL=redis://localhost:6379/1
KAFKA_BROKERS=localhost:9092
JWT_SECRET=test-secret-key
EOF
- name: 执行数据库迁移
run: |
cd backend
DATABASE_URL=$DATABASE_URL_TEST npx prisma migrate deploy
- name: 运行集成测试
run: cd backend && pnpm test:integration:coverage
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_test
REDIS_URL: redis://localhost:6379/1
KAFKA_BROKERS: localhost:9092
- if: always()
name: 上传集成测试结果
uses: actions/upload-artifact@v3
with:
name: integration-test-results
path: backend/test-results/
- name: 上传覆盖率报告
uses: codecov/codecov-action@v3
with:
files: ./backend/coverage/lcov.info
flags: integration
name: integration-coverage
timeout-minutes: "30"
services:
kafka:
image: confluentinc/cp-kafka:7.5.0
env:
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
KAFKA_BROKER_ID: "1"
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1"
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
ports:
- 9092:9092
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_test
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
zookeeper:
image: confluentinc/cp-zookeeper:7.5.0
env:
ZOOKEEPER_CLIENT_PORT: "2181"
ports:
- 2181:2181
...
|
integration-tests
|
null
|
["ubuntu-latest"]
|
57
|
2
|
1771863352
|
1771863410
|
1771863142
|
1771863410
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
466
|
70
|
6
|
5
|
07ea713c1feff2e0f7d2b91d5ca68f2e0140a963
|
0
|
单元测试 & 覆盖率
|
1
|
name: 深度完整全面自动化测试
"on":
push:
name: 深度完整全面自动化测试
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# 每天凌晨 2 点运行完整测试
- cron: '0 2 * * *'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
unit-tests:
name: 单元测试 & 覆盖率
runs-on: ubuntu-latest
steps:
- name: Checkout 代码
uses: actions/checkout@v3
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 运行单元测试
run: cd backend && pnpm test:unit:coverage
- name: 生成覆盖率报告
run: cd backend && pnpm test:coverage:json
- name: 上传覆盖率到 Codecov
uses: codecov/codecov-action@v3
with:
files: ./backend/coverage/lcov.info
flags: unittests
name: unit-coverage
- name: 检查覆盖率阈值
run: |
cd backend
COVERAGE=$(jq '.total.lines.pct' coverage/coverage.json)
echo "当前覆盖率: $COVERAGE%"
if (( $(echo "$COVERAGE < 85" | bc -l) )); then
echo "❌ 覆盖率低于 85%"
exit 1
fi
echo "✅ 覆盖率达标"
- if: always()
name: 上传测试结果
uses: actions/upload-artifact@v3
with:
name: unit-test-results
path: backend/test-results/
- if: always()
name: 上传覆盖率报告
uses: actions/upload-artifact@v3
with:
name: unit-coverage-report
path: backend/coverage/
timeout-minutes: "15"
...
|
unit-tests
|
null
|
["ubuntu-latest"]
|
56
|
2
|
1771863178
|
1771863352
|
1771863142
|
1771863352
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
416
|
67
|
6
|
5
|
14c4cca40c3b21a5247fd9117fc9af829acc8ea7
|
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"]
|
54
|
2
|
1771863065
|
1771863095
|
1771863032
|
1771863095
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
415
|
67
|
6
|
5
|
14c4cca40c3b21a5247fd9117fc9af829acc8ea7
|
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"]
|
53
|
2
|
1771863035
|
1771863065
|
1771863032
|
1771863065
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
381
|
64
|
6
|
5
|
546659ec60e857bdf77619972d1b3e4333b621ac
|
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"]
|
50
|
2
|
1771862978
|
1771863008
|
1771862945
|
1771863008
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
380
|
64
|
6
|
5
|
546659ec60e857bdf77619972d1b3e4333b621ac
|
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"]
|
49
|
2
|
1771862947
|
1771862977
|
1771862945
|
1771862978
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
278
|
58
|
6
|
5
|
18a5bb9c67c571fc2cad6ffe61e70633bcec36a8
|
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"]
|
45
|
2
|
1771862815
|
1771862849
|
1771862813
|
1771862849
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
123
|
47
|
6
|
5
|
a7c22fc0f5e2d113210bb58646dcdbf7381be245
|
0
|
quality-check
|
1
|
name: Code Quality Check
"on":
push:
name: Code Quality Check
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
quality-check:
name: quality-check
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: "18"
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- name: "\U0001F50D Multi-tenant Security Audit"
run: |
cd backend
npm run audit:tenant
- name: "\U0001F50D TypeScript Type Check"
run: |
cd frontend
npm run type-check
- name: "\U0001F50D Prisma Schema Validation"
run: |
cd backend
npx prisma validate
- name: "\U0001F50D Backend Tests"
run: |
cd backend
npm run test:run
- name: "\U0001F50D Frontend Type Safety Check"
run: |
cd frontend
# 检查是否存在 any 类型
! grep -r ": any" src/ --include="*.ts" --include="*.vue" || {
echo "❌ 发现 any 类型使用"
exit 1
}
continue-on-error: true
- name: "\U0001F50D Zod-Prisma Consistency Check"
run: |
# 运行自动修复脚本的 dry-run 模式检查一致性
npm run auto-fix:dry-run -- --type zod
continue-on-error: true
- if: always()
name: "\U0001F4CA Upload Quality Report"
uses: actions/upload-artifact@v3
with:
name: quality-report
path: |
docs/AUTO-FIX-REPORT.md
docs/BACKEND-QUALITY-AUDIT-REPORT.md
- if: github.event_name == 'pull_request' && failure()
name: "\U0001F4AC Comment PR"
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '❌ 代码质量检查失败,请查看 [CI 日志](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) 了解详情。'
})
timeout-minutes: "30"
...
|
quality-check
|
null
|
["ubuntu-latest"]
|
39
|
2
|
1771862498
|
1771862758
|
1771862412
|
1771862759
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
35
|
34
|
2
|
2
|
65caede278c2e8e14c0612ec8d8f7d26aec24ec9
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file (HARDCODED for test)
run: |
echo "m9QNiLJ8LIqBozXwmsoKdNXa23xia34R" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created with password 'm9QNiLJ8LIqBozXwmsoKdNXa23xia34R'"
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: "172.17.70.241"
RSYNC_USER: "ahead_rsync_user"
RSYNC_MODULE: "ftp"
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
27
|
2
|
1770889156
|
1770889164
|
1770889156
|
1770889164
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
34
|
33
|
2
|
2
|
1263656b62ab1dad57c56f8d004cb615f4ed02ba
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file (HARDCODED for test)
run: |
echo "m9QNiLJ8LIqBozXwmsoKdNXa23xia34R" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created with password 'm9QNiLJ8LIqBozXwmsoKdNXa23xia34R'"
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete --no-group \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: "172.17.70.241"
RSYNC_USER: "ahead_rsync_user"
RSYNC_MODULE: "ftp"
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
26
|
2
|
1770888557
|
1770888565
|
1770888557
|
1770888565
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
33
|
32
|
2
|
2
|
5b02704031563f678f5ef2cb09446cc806b2d32b
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file (HARDCODED for test)
run: |
echo "m9QNiLJ8LIqBozXwmsoKdNXa23xia34R" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created with password 'm9QNiLJ8LIqBozXwmsoKdNXa23xia34R'"
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: "172.17.70.241"
RSYNC_USER: "ahead_rsync_user"
RSYNC_MODULE: "ftp"
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
25
|
2
|
1770888366
|
1770888372
|
1770888366
|
1770888372
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
32
|
31
|
2
|
2
|
db8eda4b4696ee119fdb6d2f03804ccdf33ebcbb
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file (HARDCODED for test)
run: |
echo "m9QNiLJ8LIqBozXwmsoKdNXa23xia34R" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created with password 'm9QNiLJ8LIqBozXwmsoKdNXa23xia34R'"
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: "172.17.70.241"
RSYNC_USER: "ahead_rsync_user"
RSYNC_MODULE: "ftp"
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
24
|
2
|
1770887288
|
1770887291
|
1770887286
|
1770887291
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
31
|
30
|
2
|
2
|
c00cc2f80acf2f84906f0fc4dd7ec19e4d3016ab
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file (HARDCODED for test)
run: |
echo "testrsync123" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created with password 'testrsync123'"
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: "172.17.70.241"
RSYNC_USER: "ahead_rsync_user"
RSYNC_MODULE: "ftp"
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
23
|
2
|
1770887199
|
1770887201
|
1770887199
|
1770887202
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
30
|
29
|
2
|
2
|
6ccdfdf78088ebb3a5e0bd64de10053b9c881f60
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
if [ -z "$RSYNC_PASSWORD" ]; then
echo "❌ TEST_RSYNC_SECRETS is empty or not set!"
ls -la /tmp/
exit 1
fi
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created (size: $(wc -c < /tmp/rsync.pass) bytes)"
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
22
|
2
|
1770886646
|
1770886649
|
1770886646
|
1770886649
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
29
|
28
|
2
|
2
|
bf96a4043fd32b24b5270f87165856c672c826ef
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
if [ -z "$RSYNC_PASSWORD" ]; then
echo "❌ TEST_RSYNC_SECRETS is empty or not set!"
ls -la /tmp/
exit 1
fi
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created (size: $(wc -c < /tmp/rsync.pass) bytes)"
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
21
|
2
|
1770886491
|
1770886494
|
1770886490
|
1770886494
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
28
|
27
|
2
|
2
|
99892b593bb6a634103b6fd62b6ca5665f93f2a5
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
if [ -z "$RSYNC_PASSWORD" ]; then
echo "❌ TEST_RSYNC_SECRETS is empty or not set!"
ls -la /tmp/
exit 1
fi
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created (size: $(wc -c < /tmp/rsync.pass) bytes)"
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
20
|
2
|
1770886440
|
1770886443
|
1770886439
|
1770886443
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
27
|
26
|
2
|
2
|
db265e985719016459800733229be1943b1efaef
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
if [ -z "$RSYNC_PASSWORD" ]; then
echo "❌ TEST_RSYNC_SECRETS is empty or not set!"
ls -la /tmp/
exit 1
fi
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created (size: $(wc -c < /tmp/rsync.pass) bytes)"
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
19
|
2
|
1770885756
|
1770885759
|
1770885756
|
1770885760
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
26
|
25
|
2
|
2
|
978522e3a6160abd60eefca39accc9791fcd4ff0
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
if [ -z "$RSYNC_PASSWORD" ]; then
echo "❌ TEST_RSYNC_SECRETS is empty or not set!"
ls -la /tmp/
exit 1
fi
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
echo "✅ /tmp/rsync.pass created (size: $(wc -c < /tmp/rsync.pass) bytes)"
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
18
|
2
|
1770885693
|
1770885696
|
1770885693
|
1770885697
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
25
|
24
|
2
|
2
|
f98b8cb65887cd9ea97ec74d24dca6f43e8f15ff
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n /usr/bin/rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n /usr/bin/rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
17
|
2
|
1770885475
|
1770885478
|
1770885473
|
1770885478
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
23
|
22
|
2
|
2
|
9bbc92b4f9f21e5efef46a53f1d89fd7e752d327
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
16
|
2
|
1770882286
|
1770882302
|
1770882162
|
1770882303
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
22
|
21
|
2
|
2
|
ac9571bc40f603c832247b982b1f4181e6a3e297
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
15
|
2
|
1770878387
|
1770878407
|
1770878387
|
1770878407
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
15
|
14
|
2
|
2
|
b895cbd8b188037f0f5dbfb0fcfef056dfc36ebc
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 调试输出
echo "GITEA_HOST: $GITEA_HOST"
echo "GITHUB_REPOSITORY: ${{ github.repository }}"
echo "GITHUB_SHA: ${{ github.sha }}"
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
# 使用 github 上下文变量
REPO="${{ github.repository }}"
SHA="${{ github.sha }}"
if [ -z "$REPO" ] || [ -z "$SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${REPO}.git"
echo "Cloning from: ${REPO_URL//${GITEA_TOKEN}/***REDACTED***} (SHA: $SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$SHA"
git checkout "$SHA"
env:
GITEA_HOST: ${{ secrets.GITEAS_HOST }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f -not -path './.git/*' -not -path './.gitea/*' | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n echo \"Files to sync:\"\n cat /tmp/changed.txt\n \n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- if: always()
name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
14
|
2
|
1770802531
|
1770802550
|
1770802529
|
1770802550
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
14
|
13
|
2
|
2
|
646aa1dc79636bb90dbfec0b6b9fb9aef11c7556
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
# 构建完整 URL
if [ -z "$GITEA_HOST" ]; then
echo "❌ GITEA_HOST secret is missing!"
exit 1
fi
if [ -z "$GITHUB_REPOSITORY" ] || [ -z "$GITHUB_SHA" ]; then
echo "❌ Missing GITHUB_REPOSITORY or GITHUB_SHA"
exit 1
fi
REPO_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${GITHUB_REPOSITORY}.git"
echo "Cloning from: $REPO_URL (SHA: $GITHUB_SHA)"
git init
git remote add origin "$REPO_URL"
git fetch --depth=1 origin "$GITHUB_SHA"
git checkout "$GITHUB_SHA"
env:
# 从 Secrets 获取你的 Gitea 地址(避免依赖 env.GITEA_SERVER_URL)
GITEA_HOST: ${{ secrets.GITEAS_HOST }} # 例如: gitea.g-hi.com
GITHUB_REPOSITORY: ${{ env.GITHUB_REPOSITORY }}
GITHUB_SHA: ${{ env.GITHUB_SHA }}
GITEA_TOKEN: ${{ secrets.GITEAS_TOKEN }}
- name: Prepare rsync password file
run: |
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- name: Clean up
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
13
|
2
|
1770802313
|
1770802318
|
1770802312
|
1770802318
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
13
|
12
|
2
|
2
|
4dfa289ffffceaeca9d550f8e594eb56a3c414be
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: "echo \"\U0001F50D Cloning repository from: ${GITEA_SERVER_URL}/${GITEA_REPOSITORY}\"\n\n# 检查关键变量是否存在\nif [ -z \"$GITEA_SERVER_URL\" ] || [ -z \"$GITEA_REPOSITORY\" ] || [ -z \"$GITEA_SHA\" ]; then\n echo \"❌ Error: Missing required Gitea environment variables.\"\n exit 1\nfi\n\n# 移除 URL 中的 https:// 前缀,以便拼接 token\nHOST_AND_PATH=\"${GITEA_SERVER_URL#https://}\"\nREPO_URL=\"https://${GITEA_TOKEN}@${HOST_AND_PATH}/${GITEA_REPOSITORY}.git\"\n\ngit init\ngit remote add origin \"$REPO_URL\"\ngit fetch --depth=1 origin \"$GITEA_SHA\"\ngit checkout \"$GITEA_SHA\"\n"
env:
GITEA_SERVER_URL: ${{ env.GITEA_SERVER_URL }}
GITEA_REPOSITORY: ${{ env.GITEA_REPOSITORY }}
GITEA_SHA: ${{ env.GITEA_SHA }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} # ← 必须在 Secrets 中配置
- name: Prepare rsync password file
run: |
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested. Syncing all files...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync (changed files only)...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- name: Clean up password file
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
12
|
2
|
1770801845
|
1770801850
|
1770801845
|
1770801850
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
12
|
11
|
2
|
2
|
86003a30fcfeb3966084629ff6b4530693a642fa
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code manually
run: |
echo "Cloning repository: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}"
git init
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
git fetch --depth=1 origin "${GITHUB_SHA}"
git checkout "${GITHUB_SHA}"
env:
# Gitea Actions 自动提供这些环境变量
GITHUB_SERVER_URL: ${{ env.GITHUB_SERVER_URL }} # 会是 https://gitea.g-hi.com
GITHUB_REPOSITORY: ${{ env.GITHUB_REPOSITORY }}
GITHUB_SHA: ${{ env.GITHUB_SHA }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Gitea 自动生成的临时 token
- name: Prepare rsync password file
run: |
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested. Syncing all files...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync (changed files only)...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }}
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }}
RSYNC_MODULE: ftp
- name: Clean up password file
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
11
|
2
|
1770801593
|
1770801598
|
1770801592
|
1770801598
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
11
|
10
|
2
|
2
|
bbba1e40297c5378b23d53b0161cc6a10581ccf1
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- uses: https://gitea.com/gitea/checkout@v1
- name: Prepare rsync password file
run: |
# 将密码写入文件(rsync 要求权限为 600)
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\n# 构建 rsync 目标地址\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested. Syncing all files...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync (changed files only)...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }} # 如: 192.168.1.100
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }} # 如: ahead_rsync_user
RSYNC_MODULE: ftp # 对应 rsyncd.conf 中的 [ftp]
- name: Clean up password file (optional but safe)
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
10
|
2
|
1770801411
|
1770801416
|
1770801410
|
1770801416
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
10
|
9
|
2
|
2
|
9ea10aada78365404579933ba4df771f312ad652
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- uses: https://gitea.com/gitea/checkout@v1
- name: Prepare rsync password file
run: |
# 将密码写入文件(rsync 要求权限为 600)
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\n# 构建 rsync 目标地址\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested. Syncing all files...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync (changed files only)...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }} # 如: 192.168.1.100
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }} # 如: ahead_rsync_user
RSYNC_MODULE: ftp # 对应 rsyncd.conf 中的 [ftp]
- name: Clean up password file (optional but safe)
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
9
|
2
|
1770801383
|
1770801388
|
1770801383
|
1770801388
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
9
|
8
|
2
|
2
|
265f1b4a557b2a64464bc98e1e418e0e01298d31
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- uses: gitea/checkout@v1
- name: Prepare rsync password file
run: |
# 将密码写入文件(rsync 要求权限为 600)
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\n# 构建 rsync 目标地址\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested. Syncing all files...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync (changed files only)...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }} # 如: 192.168.1.100
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }} # 如: ahead_rsync_user
RSYNC_MODULE: ftp # 对应 rsyncd.conf 中的 [ftp]
- name: Clean up password file (optional but safe)
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
8
|
2
|
1770800735
|
1770800740
|
1770800734
|
1770800740
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
8
|
7
|
2
|
2
|
a931e51a2c8c1e80aab44673de58b17e14e7b34e
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- uses: gitea/checkout@v1
- name: Prepare rsync password file
run: |
# 将密码写入文件(rsync 要求权限为 600)
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\n# 构建 rsync 目标地址\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested. Syncing all files...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync (changed files only)...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }} # 如: 192.168.1.100
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }} # 如: ahead_rsync_user
RSYNC_MODULE: ftp # 对应 rsyncd.conf 中的 [ftp]
- name: Clean up password file (optional but safe)
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
7
|
2
|
1770800679
|
1770800684
|
1770800679
|
1770800685
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
7
|
6
|
2
|
2
|
ce36f880dce499ef2d3c804c32a1b8ba04ffbcc2
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- uses: checkout@v1
- name: Prepare rsync password file
run: |
# 将密码写入文件(rsync 要求权限为 600)
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\n# 构建 rsync 目标地址\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested. Syncing all files...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync (changed files only)...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }} # 如: 192.168.1.100
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }} # 如: ahead_rsync_user
RSYNC_MODULE: ftp # 对应 rsyncd.conf 中的 [ftp]
- name: Clean up password file (optional but safe)
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
6
|
2
|
1770800339
|
1770800343
|
1770800337
|
1770800344
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
6
|
5
|
2
|
2
|
7d4d920368182d2222ed4f7dd18933b433f88ec2
|
0
|
deploy
|
1
|
name: Smart Deploy via Rsync Daemon
"on": name: Smart Deploy via Rsync Daemon
"on": [push]
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
steps:
- uses: checkout@v1
- name: Prepare rsync password file
run: |
# 将密码写入文件(rsync 要求权限为 600)
echo "$RSYNC_PASSWORD" > /tmp/rsync.pass
chmod 600 /tmp/rsync.pass
env:
RSYNC_PASSWORD: ${{ secrets.TEST_RSYNC_SECRETS }}
- name: Get commit message and decide sync mode
run: "COMMIT_MSG=$(git log -1 --pretty=%B | head -n1)\necho \"Commit message: $COMMIT_MSG\"\n\n# 构建 rsync 目标地址\nRSYNC_TARGET=\"rsync://${RSYNC_USER}@${RSYNC_HOST}/${RSYNC_MODULE}/\"\n\nif [[ \"$COMMIT_MSG\" == *\"全量同步\"* ]] || [[ \"$COMMIT_MSG\" == *\"full sync\"* ]]; then\n echo \"\U0001F50D Full sync requested. Syncing all files...\"\n rsync -avz --delete \\\n --exclude='.git' \\\n --exclude='.gitea' \\\n --exclude='node_modules/' \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\nelse\n echo \"\U0001F504 Incremental sync (changed files only)...\"\n\n if git rev-parse HEAD~1 >/dev/null 2>&1; then\n git diff --name-only HEAD~1 HEAD > /tmp/changed.txt\n else\n find . -type f | sed 's|^\\./||' > /tmp/changed.txt\n fi\n\n if [ -s /tmp/changed.txt ]; then\n rsync -avz --relative \\\n --files-from=/tmp/changed.txt \\\n --password-file=/tmp/rsync.pass \\\n ./ \\\n \"$RSYNC_TARGET\"\n else\n echo \"✅ No files changed.\"\n fi\nfi\n"
env:
RSYNC_HOST: ${{ secrets.TEST_RSYNC_HOST }} # 如: 192.168.1.100
RSYNC_USER: ${{ secrets.TEST_RSYNC_USER }} # 如: ahead_rsync_user
RSYNC_MODULE: ftp # 对应 rsyncd.conf 中的 [ftp]
- name: Clean up password file (optional but safe)
run: rm -f /tmp/rsync.pass
...
|
deploy
|
null
|
["ubuntu-latest"]
|
5
|
2
|
1770800269
|
1770800277
|
1770800268
|
1770800277
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|
|
4
|
3
|
2
|
2
|
74f43da4be5c177e5405226efa5f1f7303a4b2bb
|
0
|
hello
|
1
|
name: Hello World
"on": [push]
jobs:
h name: Hello World
"on": [push]
jobs:
hello:
name: hello
runs-on: ubuntu-latest
steps:
- name: Say hello
run: echo "Hello, Gitea CI/CD!"
- name: Show environment info
run: |
echo "Runner OS: $(uname -a)"
echo "Current directory: $(pwd)"
echo "Files in repo:"
ls -la
...
|
hello
|
null
|
["ubuntu-latest"]
|
3
|
2
|
1770363134
|
1770363134
|
1770363133
|
1770363135
|
NULL
|
NULL
|
|
0
|
Edit
Delete
|