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]