135 lines
7.3 KiB
YAML
135 lines
7.3 KiB
YAML
version: 8 # OneDev Build Spec Version
|
||
jobs:
|
||
# --- 后端 Spring Boot 应用作业 ---
|
||
- name: "Backend CI/CD"
|
||
executor: "docker-executor"
|
||
triggers:
|
||
- type: "branch-push"
|
||
branches: "main"
|
||
paths: "springboot-init-main/**"
|
||
steps:
|
||
- checkout
|
||
- group: "Build Backend JAR"
|
||
steps:
|
||
- image: "maven:3.8-openjdk-8"
|
||
shell: "sh"
|
||
commands: |
|
||
echo "Building Spring Boot JAR..."
|
||
cd springboot-init-main
|
||
mvn clean package -DskipTests -B
|
||
- group: "Publish Backend Docker Image"
|
||
steps:
|
||
- shell: "sh"
|
||
commands: |
|
||
echo "Logging in to Docker Registry..."
|
||
echo $env.get(\'DOCKER_PASSWORD\') | docker login -u $env.get(\'DOCKER_USER\') --password-stdin $env.get(\'DOCKER_REGISTRY\', \'docker.io\')
|
||
|
||
echo "Building and Pushing Backend Docker Image..."
|
||
cd springboot-init-main
|
||
IMAGE_NAME="${env.get(\'DOCKER_REGISTRY\', \'docker.io\')}/your-docker-repo/mqtt-springboot-app"
|
||
docker build -t ${IMAGE_NAME}:latest -t ${IMAGE_NAME}:$(echo \"@file:job.commitHash@\" | cut -c1-8) .
|
||
docker push ${IMAGE_NAME}:latest
|
||
docker push ${IMAGE_NAME}:$(echo \"@file:job.commitHash@\" | cut -c1-8)
|
||
|
||
echo "Logging out from Docker Registry..."
|
||
docker logout $env.get(\'DOCKER_REGISTRY\', \'docker.io\')
|
||
|
||
# --- 前端 Next.js 应用作业 ---
|
||
- name: "Frontend CI/CD"
|
||
executor: "docker-executor"
|
||
triggers:
|
||
- type: "branch-push"
|
||
branches: "main"
|
||
paths: "charging_web_app/**"
|
||
steps:
|
||
- checkout
|
||
- group: "Build Frontend App"
|
||
steps:
|
||
- image: "node:18-alpine"
|
||
shell: "sh"
|
||
commands: |
|
||
echo "Building Next.js App..."
|
||
cd charging_web_app
|
||
npm ci
|
||
npm run build
|
||
- group: "Publish Frontend Docker Image"
|
||
steps:
|
||
- shell: "sh"
|
||
commands: |
|
||
echo "Logging in to Docker Registry..."
|
||
echo $env.get(\'DOCKER_PASSWORD\') | docker login -u $env.get(\'DOCKER_USER\') --password-stdin $env.get(\'DOCKER_REGISTRY\', \'docker.io\')
|
||
|
||
echo "Building and Pushing Frontend Docker Image..."
|
||
cd charging_web_app
|
||
IMAGE_NAME="${env.get(\'DOCKER_REGISTRY\', \'docker.io\')}/your-docker-repo/mqtt-nextjs-app"
|
||
docker build -t ${IMAGE_NAME}:latest -t ${IMAGE_NAME}:$(echo \"@file:job.commitHash@\" | cut -c1-8) .
|
||
docker push ${IMAGE_NAME}:latest
|
||
docker push ${IMAGE_NAME}:$(echo \"@file:job.commitHash@\" | cut -c1-8)
|
||
|
||
echo "Logging out from Docker Registry..."
|
||
docker logout $env.get(\'DOCKER_REGISTRY\', \'docker.io\')
|
||
|
||
# --- 统一应用部署作业 ---
|
||
# 这个作业会在任一应用(后端或前端)成功构建并推送镜像后触发
|
||
# 或者也可以配置为仅在特定条件下手动触发,或依赖于两个镜像都构建完成
|
||
- name: "Deploy All Services"
|
||
executor: "docker-executor" # 或一个配置了 SSH client 的 Shell executor
|
||
# 触发器:这里用了一个手动触发的例子,或者可以依赖于前两个job的完成
|
||
# triggers:
|
||
# - type: "manual"
|
||
# 或者更复杂的依赖触发,例如当 backend 和 frontend 的镜像都推送到特定tag后
|
||
# 此处简化,假设在 backend 和 frontend CI/CD job 成功后可以手动触发或自动链式触发 (OneDev支持Job依赖)
|
||
# 如果希望在每次后端或前端更新后都自动部署,可以将此部署逻辑合并到各自的CI/CD作业末尾,
|
||
# 但要注意并发部署可能导致的问题,以及只更新变化部分的需求。
|
||
# 为简单起见,这里假设这是一个独立的部署步骤,手动或通过上游作业触发。
|
||
# 如果要自动触发,可以设置 dependsOn: ["Backend CI/CD", "Frontend CI/CD"] 并调整触发逻辑
|
||
steps:
|
||
- checkout # 获取最新的 docker-compose.yml (如果它在仓库中)
|
||
- group: "Deploy Services to Server"
|
||
steps:
|
||
- shell: "sh"
|
||
# Secrets needed: SERVER_SSH_KEY, SERVER_HOST, SERVER_SSH_USER, DEPLOY_PATH
|
||
# Secrets for .env file: MYSQL_ROOT_PASSWORD_SECRET, MYSQL_DATABASE_SECRET, MYSQL_USER_SECRET, MYSQL_PASSWORD_SECRET
|
||
commands: |
|
||
echo "Preparing deployment to Server..."
|
||
echo "Creating .env file for docker-compose..."
|
||
# 从 OneDev Job Secrets 生成 .env 文件内容
|
||
# 注意:这里的 $env.get 语法和可用性取决于 OneDev Executor 环境
|
||
# 确保 OneDev Secrets 名称与此处使用的 get() 中的名称一致
|
||
# 确保 shell 对多行字符串和特殊字符的处理是正确的
|
||
ENV_CONTENT=""
|
||
ENV_CONTENT="${ENV_CONTENT}MYSQL_ROOT_PASSWORD=\"${env.get('MYSQL_ROOT_PASSWORD_SECRET')}\"\n"
|
||
ENV_CONTENT="${ENV_CONTENT}MYSQL_DATABASE=\"${env.get('MYSQL_DATABASE_SECRET')}\"\n"
|
||
ENV_CONTENT="${ENV_CONTENT}MYSQL_USER=\"${env.get('MYSQL_USER_SECRET')}\"\n"
|
||
ENV_CONTENT="${ENV_CONTENT}MYSQL_PASSWORD=\"${env.get('MYSQL_PASSWORD_SECRET')}\"\n"
|
||
# 添加其他 docker-compose.yml 中需要的环境变量,例如 EMQX 相关的 (如果需要密码)
|
||
# ENV_CONTENT="${ENV_CONTENT}EMQX_ADMIN_PASSWORD=\"${env.get('EMQX_ADMIN_PASSWORD_SECRET')}\"\n"
|
||
|
||
echo "Connecting to server and deploying..."
|
||
# 将 SSH 私钥写入临时文件
|
||
mkdir -p ~/.ssh
|
||
echo "$env.get(\'SERVER_SSH_KEY\')" > ~/.ssh/id_rsa
|
||
chmod 600 ~/.ssh/id_rsa
|
||
|
||
# 1. 将生成的 .env 文件内容发送到服务器的部署目录
|
||
# 2. 将仓库中的 docker-compose.yml (如果已检出) 发送到服务器或确保服务器上有最新版本
|
||
# 3. 执行 docker-compose 命令
|
||
# 注意: scp 和 ssh 命令中的路径和用户需要正确配置
|
||
# DEPLOY_PATH 是服务器上的 /opt/deploy/mqtt-charging-system
|
||
# @workspace@ 是 OneDev executor 中的工作目录,包含了检出的代码
|
||
|
||
# 创建一个包含 .env 内容的临时文件以便 scp
|
||
echo -e "${ENV_CONTENT}" > env_for_server.env
|
||
|
||
# 复制 .env 文件和 docker-compose.yml 到服务器
|
||
# 假设 docker-compose.yml 在仓库根目录
|
||
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa env_for_server.env $env.get(\'SERVER_SSH_USER\')@$env.get(\'SERVER_HOST\'):$env.get(\'DEPLOY_PATH\')/.env
|
||
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa @workspace@/docker-compose.yml $env.get(\'SERVER_SSH_USER\')@$env.get(\'SERVER_HOST\'):$env.get(\'DEPLOY_PATH\')/docker-compose.yml
|
||
|
||
# 在服务器上执行 docker-compose 命令
|
||
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa $env.get(\'SERVER_SSH_USER\')@$env.get(\'SERVER_HOST\') \
|
||
"cd $env.get(\'DEPLOY_PATH\') && docker-compose down --remove-orphans && docker-compose pull && docker-compose up -d"
|
||
|
||
echo "Deployment process initiated on server."
|
||
# 清理 executor 中的临时 .env 文件
|
||
rm env_for_server.env |