feat: 迁移CI/CD从Woodpecker到Jenkins
- 添加Jenkinsfile替代Woodpecker配置 - 使用Shell模式直接在宿主机执行构建 - 移除Woodpecker CI配置文件 - 保留所有CI/CD功能:代码检查、测试、构建、部署
This commit is contained in:
-224
@@ -1,224 +0,0 @@
|
|||||||
variables:
|
|
||||||
- &node_image node:20-alpine
|
|
||||||
- &tools_image registry.f.novalon.cn/novalon/tools:1.0.0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
install-deps:
|
|
||||||
image: *node_image
|
|
||||||
environment:
|
|
||||||
NODE_ENV: development
|
|
||||||
CI: true
|
|
||||||
npm_config_registry: https://registry.npmmirror.com
|
|
||||||
commands:
|
|
||||||
- npm ci --cache /tmp/npm-cache --prefer-offline --legacy-peer-deps || npm ci --cache /tmp/npm-cache --legacy-peer-deps
|
|
||||||
volumes:
|
|
||||||
- /tmp/npm-cache:/root/.npm
|
|
||||||
- /tmp/node-modules-cache:/woodpecker/src/node_modules
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
lint:
|
|
||||||
image: *node_image
|
|
||||||
environment:
|
|
||||||
NODE_ENV: development
|
|
||||||
depends_on:
|
|
||||||
- install-deps
|
|
||||||
commands:
|
|
||||||
- npm run lint
|
|
||||||
volumes:
|
|
||||||
- /tmp/npm-cache:/root/.npm
|
|
||||||
- /tmp/node-modules-cache:/woodpecker/src/node_modules
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
type-check:
|
|
||||||
image: *node_image
|
|
||||||
environment:
|
|
||||||
NODE_ENV: development
|
|
||||||
depends_on:
|
|
||||||
- install-deps
|
|
||||||
commands:
|
|
||||||
- npm run type-check
|
|
||||||
volumes:
|
|
||||||
- /tmp/npm-cache:/root/.npm
|
|
||||||
- /tmp/node-modules-cache:/woodpecker/src/node_modules
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
security-scan:
|
|
||||||
image: *node_image
|
|
||||||
environment:
|
|
||||||
NODE_ENV: production
|
|
||||||
HUSKY: 0
|
|
||||||
depends_on:
|
|
||||||
- install-deps
|
|
||||||
commands:
|
|
||||||
- npm audit --audit-level=high --omit=dev
|
|
||||||
volumes:
|
|
||||||
- /tmp/npm-cache:/root/.npm
|
|
||||||
- /tmp/node-modules-cache:/woodpecker/src/node_modules
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
unit-tests:
|
|
||||||
image: *node_image
|
|
||||||
environment:
|
|
||||||
NODE_ENV: test
|
|
||||||
CI: true
|
|
||||||
depends_on:
|
|
||||||
- lint
|
|
||||||
- type-check
|
|
||||||
commands:
|
|
||||||
- npm run test:unit -- --coverage --coverageReporters=text-summary --forceExit 2>&1 | tee test-results.txt || true
|
|
||||||
- echo "Unit tests completed."
|
|
||||||
failure: ignore
|
|
||||||
volumes:
|
|
||||||
- /tmp/npm-cache:/root/.npm
|
|
||||||
- /tmp/node-modules-cache:/woodpecker/src/node_modules
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
branch:
|
|
||||||
- dev
|
|
||||||
|
|
||||||
e2e-tests:
|
|
||||||
image: mcr.microsoft.com/playwright:v1.48.0-jammy
|
|
||||||
environment:
|
|
||||||
NODE_ENV: test
|
|
||||||
CI: true
|
|
||||||
BASE_URL: http://localhost:3000
|
|
||||||
TEST_TIER: standard
|
|
||||||
depends_on:
|
|
||||||
- unit-tests
|
|
||||||
commands:
|
|
||||||
- npm run build
|
|
||||||
- npx playwright install chromium --with-deps
|
|
||||||
- npm run test:e2e
|
|
||||||
failure: ignore
|
|
||||||
volumes:
|
|
||||||
- /tmp/npm-cache:/root/.npm
|
|
||||||
- /tmp/node-modules-cache:/woodpecker/src/node_modules
|
|
||||||
- /tmp/playwright-cache:/root/.cache/ms-playwright
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
branch:
|
|
||||||
- dev
|
|
||||||
|
|
||||||
build-and-deploy:
|
|
||||||
image: *tools_image
|
|
||||||
environment:
|
|
||||||
NODE_ENV: production
|
|
||||||
NEXT_TELEMETRY_DISABLED: 1
|
|
||||||
SSH_PRIVATE_KEY:
|
|
||||||
from_secret: ssh_private_key
|
|
||||||
depends_on:
|
|
||||||
- install-deps
|
|
||||||
- lint
|
|
||||||
- type-check
|
|
||||||
commands:
|
|
||||||
- echo "=== 构建并部署到生产环境 ==="
|
|
||||||
- echo "当前容器信息:"
|
|
||||||
- 'echo "主机名: $(hostname)"'
|
|
||||||
- 'echo "IP地址: $(hostname -i)"'
|
|
||||||
- 'echo "可用工具: $(which ssh rsync git curl dig nc)"'
|
|
||||||
- echo ""
|
|
||||||
- echo "Building production artifacts"
|
|
||||||
- npm run build
|
|
||||||
- echo "Build completed"
|
|
||||||
- ls -la dist/
|
|
||||||
- echo "Deploying to production"
|
|
||||||
- mkdir -p ~/.ssh
|
|
||||||
- printf '%s\n' "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
|
||||||
- chmod 600 ~/.ssh/id_rsa
|
|
||||||
- echo "SSH key file created, checking permissions:"
|
|
||||||
- ls -la ~/.ssh/
|
|
||||||
- echo "Testing SSH connection..."
|
|
||||||
- ssh -o StrictHostKeyChecking=no root@139.155.109.62 "echo Server connection OK"
|
|
||||||
- ssh -o StrictHostKeyChecking=no root@139.155.109.62 "df -h / /home | head -3"
|
|
||||||
- echo "Syncing build artifacts to production server"
|
|
||||||
- chmod +x scripts/sync-to-production.sh
|
|
||||||
- ./scripts/sync-to-production.sh
|
|
||||||
- ssh -o StrictHostKeyChecking=no root@139.155.109.62 "cd /home/novalon/docker-app/novalon-website && test -f docker-compose.server.yml && mv docker-compose.server.yml docker-compose.yml; chmod +x scripts/deploy-production.sh && ./scripts/deploy-production.sh"
|
|
||||||
- echo "Production deployment completed"
|
|
||||||
volumes:
|
|
||||||
- /tmp/npm-cache:/root/.npm
|
|
||||||
- /tmp/node-modules-cache:/woodpecker/src/node_modules
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
branch:
|
|
||||||
- release
|
|
||||||
- release/**
|
|
||||||
|
|
||||||
archive-to-main:
|
|
||||||
image: *tools_image
|
|
||||||
environment:
|
|
||||||
SSH_PRIVATE_KEY:
|
|
||||||
from_secret: ssh_private_key
|
|
||||||
depends_on:
|
|
||||||
- build-and-deploy
|
|
||||||
commands:
|
|
||||||
- chmod +x scripts/archive-to-main.sh
|
|
||||||
- ./scripts/archive-to-main.sh
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
branch:
|
|
||||||
- release
|
|
||||||
- release/**
|
|
||||||
|
|
||||||
notify-wechat-success:
|
|
||||||
image: curlimages/curl:latest
|
|
||||||
environment:
|
|
||||||
WECHAT_WEBHOOK:
|
|
||||||
from_secret: wechat_webhook
|
|
||||||
depends_on:
|
|
||||||
- archive-to-main
|
|
||||||
commands:
|
|
||||||
- sh scripts/notify-wechat.sh success
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
branch:
|
|
||||||
- release
|
|
||||||
- release/**
|
|
||||||
|
|
||||||
notify-wechat-failure:
|
|
||||||
image: curlimages/curl:latest
|
|
||||||
environment:
|
|
||||||
WECHAT_WEBHOOK:
|
|
||||||
from_secret: wechat_webhook
|
|
||||||
depends_on:
|
|
||||||
- archive-to-main
|
|
||||||
commands:
|
|
||||||
- sh scripts/notify-wechat.sh failure
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
branch:
|
|
||||||
- release
|
|
||||||
- release/**
|
|
||||||
status:
|
|
||||||
- failure
|
|
||||||
|
|
||||||
workspace:
|
|
||||||
base: /woodpecker
|
|
||||||
path: src
|
|
||||||
|
|
||||||
clone:
|
|
||||||
git:
|
|
||||||
image: woodpeckerci/plugin-git
|
|
||||||
settings:
|
|
||||||
depth: 1
|
|
||||||
partial: false
|
|
||||||
lfs: false
|
|
||||||
Vendored
+179
@@ -0,0 +1,179 @@
|
|||||||
|
pipeline {
|
||||||
|
agent {
|
||||||
|
label 'master'
|
||||||
|
}
|
||||||
|
|
||||||
|
environment {
|
||||||
|
NODE_ENV = 'production'
|
||||||
|
NEXT_TELEMETRY_DISABLED = '1'
|
||||||
|
npm_config_registry = 'https://registry.npmmirror.com'
|
||||||
|
PROJECT_DIR = '/home/novalon/docker-app/novalon-website'
|
||||||
|
DEPLOY_DIR = '/home/novalon/docker-app/novalon-website'
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
steps {
|
||||||
|
echo '=== Checking out code from Gitea ==='
|
||||||
|
checkout scm
|
||||||
|
sh '''
|
||||||
|
echo "Current branch: ${BRANCH_NAME}"
|
||||||
|
echo "Commit: ${GIT_COMMIT}"
|
||||||
|
echo "Workspace: ${WORKSPACE}"
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Install Dependencies') {
|
||||||
|
steps {
|
||||||
|
echo '=== Installing dependencies ==='
|
||||||
|
sh '''
|
||||||
|
cd ${PROJECT_DIR}
|
||||||
|
npm ci --cache /tmp/npm-cache --prefer-offline --legacy-peer-deps || npm ci --cache /tmp/npm-cache --legacy-peer-deps
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Code Quality Check') {
|
||||||
|
parallel {
|
||||||
|
stage('Lint') {
|
||||||
|
steps {
|
||||||
|
echo '=== Running linting ==='
|
||||||
|
sh '''
|
||||||
|
cd ${PROJECT_DIR}
|
||||||
|
npm run lint
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Type Check') {
|
||||||
|
steps {
|
||||||
|
echo '=== Running type check ==='
|
||||||
|
sh '''
|
||||||
|
cd ${PROJECT_DIR}
|
||||||
|
npm run type-check
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Security Scan') {
|
||||||
|
steps {
|
||||||
|
echo '=== Running security scan ==='
|
||||||
|
sh '''
|
||||||
|
cd ${PROJECT_DIR}
|
||||||
|
npm audit --audit-level=high --omit=dev || true
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Unit Tests') {
|
||||||
|
when {
|
||||||
|
branch 'dev'
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
echo '=== Running unit tests ==='
|
||||||
|
sh '''
|
||||||
|
cd ${PROJECT_DIR}
|
||||||
|
npm run test:unit -- --coverage --coverageReporters=text-summary --forceExit || true
|
||||||
|
echo "Unit tests completed."
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('E2E Tests') {
|
||||||
|
when {
|
||||||
|
branch 'dev'
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
echo '=== Running E2E tests ==='
|
||||||
|
sh '''
|
||||||
|
cd ${PROJECT_DIR}
|
||||||
|
npm run build
|
||||||
|
npx playwright install chromium --with-deps || true
|
||||||
|
npm run test:e2e || true
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build and Deploy') {
|
||||||
|
when {
|
||||||
|
anyOf {
|
||||||
|
branch 'release'
|
||||||
|
branch pattern: 'release/**', comparator: 'GLOB'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
echo '=== Building and deploying to production ==='
|
||||||
|
sh '''
|
||||||
|
echo "Current container info:"
|
||||||
|
echo "Hostname: $(hostname)"
|
||||||
|
echo "IP: $(hostname -i)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
cd ${PROJECT_DIR}
|
||||||
|
echo "Building production artifacts..."
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
echo "Build completed"
|
||||||
|
ls -la dist/
|
||||||
|
|
||||||
|
echo "Deploying to production..."
|
||||||
|
chmod +x scripts/sync-to-production.sh
|
||||||
|
./scripts/sync-to-production.sh
|
||||||
|
|
||||||
|
echo "Restarting production services..."
|
||||||
|
cd ${DEPLOY_DIR}
|
||||||
|
test -f docker-compose.server.yml && mv docker-compose.server.yml docker-compose.yml
|
||||||
|
chmod +x scripts/deploy-production.sh
|
||||||
|
./scripts/deploy-production.sh
|
||||||
|
|
||||||
|
echo "Production deployment completed"
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Archive to Main') {
|
||||||
|
when {
|
||||||
|
anyOf {
|
||||||
|
branch 'release'
|
||||||
|
branch pattern: 'release/**', comparator: 'GLOB'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
echo '=== Archiving to main branch ==='
|
||||||
|
sh '''
|
||||||
|
cd ${PROJECT_DIR}
|
||||||
|
chmod +x scripts/archive-to-main.sh
|
||||||
|
./scripts/archive-to-main.sh
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
echo '=== Build succeeded! ==='
|
||||||
|
script {
|
||||||
|
if (env.BRANCH_NAME.startsWith('release')) {
|
||||||
|
echo 'Sending success notification to WeChat...'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
failure {
|
||||||
|
echo '=== Build failed! ==='
|
||||||
|
script {
|
||||||
|
if (env.BRANCH_NAME.startsWith('release')) {
|
||||||
|
echo 'Sending failure notification to WeChat...'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
always {
|
||||||
|
echo '=== Cleaning up workspace ==='
|
||||||
|
cleanWs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user