08ea5fbe98
添加用户管理视图、API和状态管理文件
400 lines
11 KiB
YAML
400 lines
11 KiB
YAML
clone:
|
|
git:
|
|
image: woodpeckerci/plugin-git
|
|
settings:
|
|
depth: 1
|
|
|
|
pipeline:
|
|
lint-api:
|
|
image: maven:3.9.9-eclipse-temurin-21
|
|
commands:
|
|
- cd everything-is-suitable-api
|
|
- mvn checkstyle:check
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
test-api:
|
|
image: maven:3.9.9-eclipse-temurin-21
|
|
commands:
|
|
- cd everything-is-suitable-api
|
|
- mvn test
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
build-api:
|
|
image: woodpeckerci/plugin-docker
|
|
settings:
|
|
registry: ${DOCKER_REGISTRY}
|
|
username: ${DOCKER_USERNAME}
|
|
password: ${DOCKER_PASSWORD}
|
|
repo: ${DOCKER_REGISTRY}/everything-is-suitable-api
|
|
tags: latest, ${CI_COMMIT_SHA:0:8}
|
|
dockerfile: everything-is-suitable-api/Dockerfile
|
|
context: .
|
|
when:
|
|
event: [push, tag]
|
|
branch: [main, develop]
|
|
|
|
lint-admin:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-admin
|
|
- npm ci
|
|
- npm run lint
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
test-admin:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-admin
|
|
- npm ci
|
|
- npm run test
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
smart-test-selection:
|
|
image: node:20-alpine
|
|
commands:
|
|
- npm ci
|
|
- |
|
|
# 获取变更文件
|
|
if [ "$CI_BUILD_EVENT" = "cron" ]; then
|
|
echo "[]" > changed-files.txt
|
|
else
|
|
git diff --name-only origin/main...HEAD > changed-files.txt || echo "[]" > changed-files.txt
|
|
fi
|
|
- |
|
|
# 智能选择测试用例
|
|
node dist/scripts/scripts/cli/smart-test-selector-cli.js \
|
|
--input changed-files.txt \
|
|
--output selected-tests.json \
|
|
--report test-selection-report.md
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
smart-test-execution:
|
|
image: node:20-alpine
|
|
environment:
|
|
- TEST_ENV=ci
|
|
- API_BASE_URL=http://localhost:8083
|
|
- FRONTEND_BASE_URL=http://localhost:5174
|
|
commands:
|
|
- npm ci
|
|
- npx playwright install --with-deps chromium
|
|
- |
|
|
if [ -f selected-tests.json ]; then
|
|
npm run test:smart selected-tests.json
|
|
else
|
|
npm run test:all
|
|
fi
|
|
when:
|
|
event: [push, pull_request]
|
|
depends_on:
|
|
- smart-test-selection
|
|
|
|
e2e-test-admin:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-admin
|
|
- npm ci
|
|
- npx playwright install --with-deps
|
|
- npm run test:e2e
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
build-admin:
|
|
image: woodpeckerci/plugin-docker
|
|
settings:
|
|
registry: ${DOCKER_REGISTRY}
|
|
username: ${DOCKER_USERNAME}
|
|
password: ${DOCKER_PASSWORD}
|
|
repo: ${DOCKER_REGISTRY}/everything-is-suitable-admin
|
|
tags: latest, ${CI_COMMIT_SHA:0:8}
|
|
dockerfile: everything-is-suitable-admin/Dockerfile
|
|
context: .
|
|
when:
|
|
event: [push, tag]
|
|
branch: [main, develop]
|
|
|
|
lint-uniapp:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-uniapp
|
|
- npm ci
|
|
- npm run lint
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
test-uniapp:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-uniapp
|
|
- npm ci
|
|
- npm run test
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
e2e-test-uniapp:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-uniapp
|
|
- npm ci
|
|
- npx playwright install --with-deps
|
|
- npm run test:e2e
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
build-uniapp:
|
|
image: woodpeckerci/plugin-docker
|
|
settings:
|
|
registry: ${DOCKER_REGISTRY}
|
|
username: ${DOCKER_USERNAME}
|
|
password: ${DOCKER_PASSWORD}
|
|
repo: ${DOCKER_REGISTRY}/everything-is-suitable-uniapp
|
|
tags: latest, ${CI_COMMIT_SHA:0:8}
|
|
dockerfile: everything-is-suitable-uniapp/Dockerfile
|
|
context: .
|
|
when:
|
|
event: [push, tag]
|
|
branch: [main, develop]
|
|
|
|
deploy:
|
|
image: alpine:3.19
|
|
commands:
|
|
- apk add --no-cache openssh-client
|
|
- mkdir -p ~/.ssh
|
|
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
|
- chmod 600 ~/.ssh/id_rsa
|
|
- ssh-keyscan -H ${DEPLOY_HOST} >> ~/.ssh/known_hosts
|
|
- ssh ${DEPLOY_USER}@${DEPLOY_HOST} "cd ${DEPLOY_PATH} && docker-compose pull && docker-compose up -d"
|
|
environment:
|
|
SSH_PRIVATE_KEY:
|
|
from_secret: ssh_private_key
|
|
DEPLOY_HOST:
|
|
from_secret: deploy_host
|
|
DEPLOY_USER:
|
|
from_secret: deploy_user
|
|
DEPLOY_PATH:
|
|
from_secret: deploy_path
|
|
when:
|
|
event: [push, tag]
|
|
branch: [main]
|
|
|
|
test-env-setup:
|
|
image: docker:24-cli
|
|
commands:
|
|
- apk add --no-cache docker-compose
|
|
- docker-compose -f docker-compose.test-new.yml --env-file .env.test up -d
|
|
- sleep 30
|
|
- docker-compose -f docker-compose.test-new.yml --env-file .env.test ps
|
|
when:
|
|
event: [push, pull_request]
|
|
branch: [main, develop]
|
|
|
|
integration-test:
|
|
image: node:20-alpine
|
|
commands:
|
|
- apk add --no-cache python3 py3-pip
|
|
- pip3 install psycopg2-binary requests
|
|
- cd everything-is-suitable-admin
|
|
- npm ci
|
|
- npm run test:integration
|
|
environment:
|
|
TEST_API_URL: http://test-api-gateway:8080
|
|
TEST_ADMIN_URL: http://test-admin-backend:8081
|
|
when:
|
|
event: [push, pull_request]
|
|
branch: [main, develop]
|
|
|
|
test-env-cleanup:
|
|
image: docker:24-cli
|
|
commands:
|
|
- apk add --no-cache docker-compose
|
|
- docker-compose -f docker-compose.test-new.yml --env-file .env.test down -v
|
|
when:
|
|
event: [push, pull_request]
|
|
branch: [main, develop]
|
|
status: [success, failure]
|
|
|
|
lint-e2e-test:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-test
|
|
- npm ci
|
|
- npm run lint
|
|
when:
|
|
event: [push, pull_request]
|
|
|
|
test-e2e-smoke:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-test
|
|
- npm ci
|
|
- npx playwright install --with-deps
|
|
- npm run test:e2e:smoke
|
|
environment:
|
|
E2E_BASE_URL: http://test-admin-backend:8081
|
|
E2E_API_URL: http://test-api-gateway:8080
|
|
CI: true
|
|
when:
|
|
event: [push, pull_request]
|
|
branch: [main, develop]
|
|
|
|
test-e2e-regression:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-test
|
|
- npm ci
|
|
- npx playwright install --with-deps
|
|
- npm run test:e2e:regression
|
|
environment:
|
|
E2E_BASE_URL: http://test-admin-backend:8081
|
|
E2E_API_URL: http://test-api-gateway:8080
|
|
CI: true
|
|
when:
|
|
event: [push, pull_request]
|
|
branch: [main, develop]
|
|
|
|
test-e2e-full:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd everything-is-suitable-test
|
|
- npm ci
|
|
- npx playwright install --with-deps
|
|
- npm run test:e2e:full
|
|
environment:
|
|
E2E_BASE_URL: http://test-admin-backend:8081
|
|
E2E_API_URL: http://test-api-gateway:8080
|
|
CI: true
|
|
when:
|
|
event: [push]
|
|
branch: [main, develop]
|
|
|
|
test-report-upload:
|
|
image: alpine:3.19
|
|
commands:
|
|
- apk add --no-cache curl
|
|
- cd everything-is-suitable-test
|
|
- |
|
|
if [ -d "test-results" ]; then
|
|
echo "Uploading test reports..."
|
|
curl -X POST -H "Authorization: Bearer $REPORT_UPLOAD_TOKEN" \
|
|
-F "report=@test-results/results.json" \
|
|
-F "junit=@test-results/junit.xml" \
|
|
$REPORT_UPLOAD_URL || echo "Report upload failed"
|
|
fi
|
|
environment:
|
|
REPORT_UPLOAD_TOKEN:
|
|
from_secret: report_upload_token
|
|
REPORT_UPLOAD_URL:
|
|
from_secret: report_upload_url
|
|
when:
|
|
event: [push, pull_request]
|
|
branch: [main, develop]
|
|
status: [success, failure]
|
|
|
|
test-failure-notification:
|
|
image: alpine:3.19
|
|
commands:
|
|
- apk add --no-cache curl
|
|
- |
|
|
echo "Checking test results..."
|
|
if [ -f "everything-is-suitable-test/test-results/results.json" ]; then
|
|
FAILED_COUNT=$(grep -o '"status":"failed"' everything-is-suitable-test/test-results/results.json | wc -l)
|
|
if [ "$FAILED_COUNT" -gt 0 ]; then
|
|
echo "E2E tests failed: $FAILED_COUNT tests failed"
|
|
curl -X POST -H "Authorization: Bearer $NOTIFICATION_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"title\":\"E2E测试失败\",\"message\":\"$FAILED_COUNT个测试失败\",\"priority\":\"high\"}" \
|
|
$NOTIFICATION_URL || echo "Notification failed"
|
|
exit 1
|
|
else
|
|
echo "All E2E tests passed"
|
|
fi
|
|
fi
|
|
environment:
|
|
NOTIFICATION_TOKEN:
|
|
from_secret: notification_token
|
|
NOTIFICATION_URL:
|
|
from_secret: notification_url
|
|
when:
|
|
event: [push, pull_request]
|
|
branch: [main, develop]
|
|
status: [failure]
|
|
|
|
test-success-notification:
|
|
image: alpine:3.19
|
|
commands:
|
|
- apk add --no-cache curl
|
|
- |
|
|
echo "E2E tests passed successfully"
|
|
curl -X POST -H "Authorization: Bearer $NOTIFICATION_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"title\":\"E2E测试通过\",\"message\":\"所有E2E测试通过\",\"priority\":\"low\"}" \
|
|
$NOTIFICATION_URL || echo "Notification failed"
|
|
environment:
|
|
NOTIFICATION_TOKEN:
|
|
from_secret: notification_token
|
|
NOTIFICATION_URL:
|
|
from_secret: notification_url
|
|
when:
|
|
event: [push, pull_request]
|
|
branch: [main, develop]
|
|
status: [success]
|
|
|
|
test-coverage-report:
|
|
image: alpine:3.19
|
|
commands:
|
|
- apk add --no-cache nodejs npm
|
|
- cd everything-is-suitable-test
|
|
- |
|
|
echo "Generating test coverage report..."
|
|
|
|
# Create coverage report directory
|
|
mkdir -p test-results/coverage
|
|
|
|
# Generate coverage report
|
|
node -e "
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const coverageData = {
|
|
totalTests: 0,
|
|
passedTests: 0,
|
|
failedTests: 0,
|
|
skippedTests: 0,
|
|
passRate: 0,
|
|
testSuites: [],
|
|
executionTime: 0,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
// Read test results
|
|
if (fs.existsSync('test-results/results.json')) {
|
|
const testResults = JSON.parse(fs.readFileSync('test-results/results.json', 'utf-8'));
|
|
coverageData.totalTests = testResults.stats?.expected || 0;
|
|
coverageData.passedTests = testResults.stats?.passed || 0;
|
|
coverageData.failedTests = testResults.stats?.failed || 0;
|
|
coverageData.skippedTests = testResults.stats?.skipped || 0;
|
|
coverageData.passRate = coverageData.totalTests > 0 ? (coverageData.passedTests / coverageData.totalTests) * 100 : 0;
|
|
coverageData.executionTime = testResults.stats?.duration || 0;
|
|
}
|
|
|
|
// Write coverage report
|
|
fs.writeFileSync('test-results/coverage/coverage.json', JSON.stringify(coverageData, null, 2));
|
|
console.log('Coverage report generated successfully');
|
|
console.log('Total tests:', coverageData.totalTests);
|
|
console.log('Passed tests:', coverageData.passedTests);
|
|
console.log('Failed tests:', coverageData.failedTests);
|
|
console.log('Skipped tests:', coverageData.skippedTests);
|
|
console.log('Pass rate:', coverageData.passRate.toFixed(2) + '%');
|
|
"
|
|
environment:
|
|
COVERAGE_THRESHOLD:
|
|
from_secret: coverage_threshold
|
|
when:
|
|
event: [push, pull_request]
|
|
branch: [main, develop]
|
|
status: [success, failure]
|