# ═══════════════════════════════════════════════════════════
# SpecCore 部署配置示例（v8.3.91+）
# ═══════════════════════════════════════════════════════════
#
# 使用方式：
#   1. 复制你需要的配置块到 PROJECT.yaml 的 platform.deploy 段
#   2. 或复制到 .speccore/environments/{env}.yaml 的 platform 段
#
# 部署命令：
#   speccore deploy --env staging --platform <端名>
#   speccore deploy --env staging --all
#   speccore deploy --env production --platform h5 --dry-run   # 预览模式
#
# ═══════════════════════════════════════════════════════════
# 公共字段字典（所有部署类型通用，按需选用）
# ═══════════════════════════════════════════════════════════
#   type         → 部署类型：ssh / sftp / static / script / docker / pm2 / k8s / helm / vercel / serverless
#   build_cmd    → 构建命令（部署前执行，如 npm run build:staging）
#   output_dir   → 构建产物目录（上传/部署的对象，如 dist）
#   host         → 远程主机（格式 user@host[:port]，配置后走远程部署）
#   key          → SSH 私钥路径（密钥认证，推荐；与 password 二选一）
#   password     → SSH 密码（v8.3.91+，需安装 sshpass；与 key 二选一）
#   remote_dir   → 远程目录（上传目标，须有写权限）
#   script       → 部署后执行的命令/脚本路径（远程重启服务等）
#   pre_deploy   → 部署前钩子（命令列表，逐条执行）
#   post_deploy  → 部署后钩子（命令列表，逐条执行）
#   target       → 目标位置（static=本地目录/S3/rsync 地址，k8s/helm=namespace，serverless=函数名）
#   dockerfile   → Dockerfile 路径（docker 类型，默认 ./Dockerfile）
#   registry     → 镜像仓库地址（docker 类型，远程部署必须配置）
#   image        → 镜像名（docker 类型）
#   tag          → 镜像标签（docker 类型）
#   pm2_config   → PM2 配置文件（pm2 类型，默认 ecosystem.config.js）
#   backup       → 部署前备份远端旧包（v8.3.348+，ssh/docker 类型，默认 true 开启）
#   backup_keep  → 备份保留份数（v8.3.348+，默认 5，超出自动清理最旧备份）
#
# 备份开关优先级（高→低）：CLI --skip-backup-for 端级排除 > CLI --backup/--no-backup 全局 > 配置 backup 字段 > 默认开启
# 例：speccore deploy --env test --all --backup --skip-backup-for h5-mobile,order-api
# ═══════════════════════════════════════════════════════════

# ─────────────────────────────────────────
# 1. SSH 部署（推荐：有独立服务器的场景）
# ─────────────────────────────────────────
#
# 适用场景：前端构建后上传到 Nginx/Apache 静态目录，或后端上传到服务器重启
#
# 认证方式：
#   方式 A — 密钥认证（推荐，更安全）：
#     1) 本地生成密钥：ssh-keygen -t rsa -b 4096
#     2) 上传公钥到服务器：ssh-copy-id -i ~/.ssh/id_rsa.pub user@host
#     3) 配置 key 字段指向私钥路径
#
#   方式 B — 密码认证（v8.3.91+）：
#     1) 安装 sshpass：
#        macOS: brew install sshpass
#        Ubuntu/Debian: apt-get install sshpass
#     2) 配置 password 字段
#
ssh_key_example:
  # type: 部署类型
  type: ssh
  # build_cmd: 部署前构建命令
  build_cmd: npm run build:staging
  # output_dir: 构建产物目录
  output_dir: dist
  # host: 远程主机（user@host:port）
  host: deployer@192.168.1.100:22
  # key: SSH 私钥路径（密钥认证）
  key: ~/.ssh/id_rsa
  # remote_dir: 远程上传目录
  remote_dir: /var/www/html/h5
  # script: 部署后命令（重载 Nginx）
  script: sudo nginx -s reload
  # backup: 部署前备份远端旧包（v8.3.348+，默认 true 开启；保留最近 backup_keep 份）
  backup: true
  backup_keep: 5
  # pre_deploy: 部署前钩子
  pre_deploy:
    - echo "开始部署到 staging..."
  # post_deploy: 部署后钩子
  post_deploy:
    - echo "部署完成"

# SSH 密码认证示例
ssh_password_example:
  type: ssh
  build_cmd: npm run build:staging
  output_dir: dist
  host: deployer@192.168.1.100:22
  password: your-password-here          # SSH 密码（v8.3.91+，需安装 sshpass；与 key 二选一）
  remote_dir: /var/www/html/h5
  script: sudo nginx -s reload

# ─────────────────────────────────────────
# 2. SFTP 部署（无 SSH 权限，只有 SFTP）
# ─────────────────────────────────────────
#
# 适用场景：共享主机、虚拟主机，只有 SFTP 权限无 SSH 登录权限
#
sftp_example:
  type: sftp
  build_cmd: npm run build
  output_dir: dist
  host: deployer@192.168.1.100           # SFTP 地址（格式 user@host）
  key: ~/.ssh/id_rsa                     # SSH 私钥路径
  remote_dir: /var/www/html/h5           # 远程目录（SFTP 必须有写权限）

# ─────────────────────────────────────────
# 3. 静态资源部署（local / S3 / rsync）
# ─────────────────────────────────────────
#
# 适用场景：CDN、对象存储、共享文件系统、本地目录
#
# target 格式：
#   - 本地路径：/var/www/html/h5
#   - S3 桶：s3://my-bucket/h5/
#   - rsync 远程：rsync://user@host:/var/www/html/h5
#   - rsync 远程（简写）：user@host:/var/www/html/h5
#
static_local_example:
  type: static
  build_cmd: npm run build
  output_dir: dist
  target: /var/www/html/h5               # 本地或挂载的共享目录

static_s3_example:
  type: static
  build_cmd: npm run build
  output_dir: dist
  target: s3://my-cdn-bucket/h5-staging/  # AWS S3（需安装 AWS CLI）

static_rsync_example:
  type: static
  build_cmd: npm run build
  output_dir: dist
  target: deployer@cdn-server:/var/www/html/h5   # rsync 远程同步

# ─────────────────────────────────────────
# 4. 自定义脚本部署（最灵活）
# ─────────────────────────────────────────
#
# 适用场景：Jenkins 触发、FTP 上传、复杂部署流程
#
# script 字段可以是：
#   - 脚本文件路径（相对于 code_path）：./scripts/deploy-staging.sh
#   - 直接命令：curl -X POST http://jenkins/job/build/build
#
script_jenkins_example:
  type: script
  build_cmd: npm run build
  script: ./scripts/trigger-jenkins.sh   # 脚本文件（存在则执行 bash）
  # 或直接写命令：
  # script: "curl -X POST -u user:token http://jenkins.example.com/job/my-job/build"

script_ftp_example:
  type: script
  build_cmd: npm run build
  output_dir: dist
  script: ./scripts/deploy-ftp.sh        # 脚本内容示例见下文

# ─────────────────────────────────────────
# 5. Docker 部署
# ─────────────────────────────────────────
#
# 适用场景：容器化部署，支持本地构建 + 镜像仓库推送 + 远程服务器部署
#
# 远程部署说明（v8.3.96+）：
#   - 配置 host 后，speccore 会自动 SSH 到远程服务器执行 docker pull && run
#   - 远程部署必须配置 registry（否则远程服务器无法获取镜像）
#   - 可通过 script 字段自定义远程命令（默认：stop → rm → pull → run）
#   - 支持密钥认证（key）和密码认证（password + sshpass）
#
# 完整模板见 templates/deploy-docker/（含前端 Dockerfile、Nginx 配置、Compose 编排）

# 基础 Docker：仅本地构建并推送到仓库（适合 CI/CD 场景）
docker_push_only:
  type: docker
  dockerfile: ./Dockerfile                       # Dockerfile 路径
  registry: registry.example.com                 # 镜像仓库地址（远程部署必须配置）
  image: my-project/h5                           # 镜像名
  tag: staging                                   # 镜像标签

# 前端 Docker + 远程部署（Nginx 托管）
docker_frontend_remote:
  type: docker
  build_cmd: npm run build:staging              # 前置构建（可选）
  dockerfile: ./Dockerfile                      # 多阶段构建：Node → Nginx
  registry: registry.example.com
  image: my-project/admin-web
  tag: staging
  host: deployer@staging-server.example.com     # 远程服务器（v8.3.96+）
  key: ~/.ssh/id_rsa
  # backup: true   # v8.3.348+: 部署前把旧镜像打 backup tag（tag 零成本，保留 backup_keep 份；默认开启）
  # backup_keep: 5
  # script 自定义远程命令（可选，以下为默认值示例）
  # script: "docker pull registry.example.com/my-project/admin-web:staging && docker stop admin-web 2>/dev/null; docker rm admin-web 2>/dev/null; docker run -d --name admin-web --restart always -p 80:80 registry.example.com/my-project/admin-web:staging"

# 后端 Java Docker + 远程部署
docker_backend_remote:
  type: docker
  dockerfile: ./Dockerfile                      # 多阶段构建：Maven → JRE
  registry: registry.example.com
  image: my-project/order-service
  tag: staging
  host: deployer@staging-server.example.com
  key: ~/.ssh/id_rsa

# Docker Compose 统一部署（使用 script 类型调用 compose）
docker_compose_example:
  type: script
  script: ./scripts/deploy-compose.sh
  # deploy-compose.sh 内容示例：
  #   cd /opt/deploy && docker-compose pull && docker-compose up -d

# ─────────────────────────────────────────
# 6. PM2 部署（Node.js 后端）
# ─────────────────────────────────────────
#
# 适用场景：Node.js 服务，本地或远程 PM2 进程管理
#
pm2_local_example:
  type: pm2
  build_cmd: npm run build
  output_dir: .
  pm2_config: ecosystem.config.js        # PM2 配置文件（默认 ecosystem.config.js）

pm2_remote_example:
  type: pm2
  build_cmd: npm run build
  pm2_config: ecosystem.config.js
  host: deployer@192.168.1.100           # 远程服务器（可选，配置则 SSH 远程重启）
  key: ~/.ssh/id_rsa
  remote_dir: /opt/services/api

# ─────────────────────────────────────────
# 7. Kubernetes 部署
# ─────────────────────────────────────────
#
# 适用场景：K8s 集群
#
k8s_example:
  type: k8s
  target: staging                        # namespace（默认 default）
  script: k8s/deployment.yaml            # K8s manifest 文件路径（默认 k8s-deployment.yaml）

# ─────────────────────────────────────────
# 8. Helm 部署
# ─────────────────────────────────────────
#
# 适用场景：使用 Helm 管理 K8s 应用
#
helm_example:
  type: helm
  target: staging                        # namespace（默认环境名）
  script: ./helm/h5                      # Chart 路径（默认 ./helm/<端名>）
  output_dir: values-staging.yaml        # values 文件路径（默认 values-<env>.yaml）

# ─────────────────────────────────────────
# 9. Vercel 部署
# ─────────────────────────────────────────
#
# 适用场景：前端项目快速部署到 Vercel
#
vercel_example:
  type: vercel
  # 无需额外配置，执行 npx vercel --prod（production）或 npx vercel（preview）
  # 需提前安装 Vercel CLI 并登录：npm i -g vercel && vercel login

# ─────────────────────────────────────────
# 10. Serverless 部署（函数计算）
# ─────────────────────────────────────────
#
# 适用场景：函数计算、无服务器架构
#
serverless_aliyun_example:
  type: serverless
  provider: aliyun-fc                    # 阿里云函数计算
  target: my-func-name                   # 函数名（默认使用端名）

serverless_aws_example:
  type: serverless
  provider: aws-lambda                   # AWS Lambda
  target: my-lambda-func

serverless_tencent_example:
  type: serverless
  provider: tencent-scf                  # 腾讯云云函数
  target: my-scf-func

# ─────────────────────────────────────────
# 11. Java 后端部署（Spring Boot + systemd）
# ─────────────────────────────────────────
#
# 适用场景：Java 后端服务，通过 systemd 管理 jar 进程
#
# 服务器端准备（只需一次）：
#   1) 将 templates/deploy-java/spring-boot.service 复制到服务器：
#      /etc/systemd/system/order-service.service
#      （文件名必须与 platform.name 一致）
#   2) 创建部署目录：mkdir -p /opt/services/order-service
#   3) 创建日志目录：mkdir -p /var/log/order-service
#   4) 重载 systemd：sudo systemctl daemon-reload
#   5) 启用开机自启：sudo systemctl enable order-service
#
# 数据库 / Redis 配置：
#   通过 Spring Boot profiles 切换，如 application-staging.yml
#   部署时激活 profile：script 中传入 --spring.profiles.active=staging
#
java_systemd_example:
  type: ssh
  build_cmd: mvn clean package -DskipTests -P staging
  output_dir: target
  host: deployer@staging-server.example.com:22
  key: ~/.ssh/id_rsa
  remote_dir: /opt/services/order-service
  # 部署后执行：停止服务 → 替换 jar → 启动服务
  script: sudo systemctl restart order-service
  pre_deploy:
    - echo "开始部署 Java 后端..."
  post_deploy:
    - echo "部署完成，检查状态..."
    - ssh deployer@staging-server.example.com "sudo systemctl status order-service --no-pager"

# ─────────────────────────────────────────
# 12. Java 后端部署（Spring Boot + Docker）
# ─────────────────────────────────────────
#
# 适用场景：Java 服务容器化部署
#
# Dockerfile 示例见 templates/deploy-java/Dockerfile
#
java_docker_example:
  type: docker
  dockerfile: ./Dockerfile
  registry: registry.example.com
  image: my-project/order-service
  tag: staging

# ═══════════════════════════════════════════════════════════
# 13. Nginx 站点配置（纯服务器托管前端，ssh 类型配套）
# ═══════════════════════════════════════════════════════════
#
# 适用场景：前端 ssh 类型部署到服务器后，由服务器 Nginx 托管。
# 服务器端完整站点配置模板见 templates/deploy-nginx/nginx-site.conf
# （含 SPA 回退、gzip、静态缓存、API 反代到本地后端、HTTPS/WebSocket）。
#
# 服务器端准备（只需一次）：
#   sudo cp templates/deploy-nginx/nginx-site.conf /etc/nginx/conf.d/<站点>.conf
#   # 替换 {{DOMAIN}} / {{APP_DIR}} / {{BACKEND_HOST}} 后：
#   sudo nginx -t && sudo nginx -s reload
#
nginx_site_example:
  type: ssh
  build_cmd: npm run build:staging
  output_dir: dist
  host: deployer@staging-server.example.com:22
  key: ~/.ssh/id_rsa
  remote_dir: /var/www/html/admin-web     # 与站点配置的 {{APP_DIR}} 一致
  script: sudo nginx -s reload            # 部署完成后重载 Nginx

# ═══════════════════════════════════════════════════════════
# 14. Go 后端部署（systemd 管理，方式同 Java）
# ═══════════════════════════════════════════════════════════
#
# 适用场景：Go 服务编译为单个二进制，上传服务器由 systemd 管理。
# systemd service 模板参考 templates/deploy-java/spring-boot.service
# （将 ExecStart 改为二进制路径即可）。
#
go_systemd_example:
  type: ssh
  build_cmd: CGO_ENABLED=0 go build -o bin/gateway ./cmd/gateway
  output_dir: bin
  host: deployer@staging-server.example.com:22
  key: ~/.ssh/id_rsa
  remote_dir: /opt/services/gateway
  script: sudo systemctl restart gateway

# Go 服务容器化部署
# Dockerfile 要点：多阶段（golang:1.22-alpine 编译 → alpine 运行），
# 运行阶段仅复制二进制，参考 deploy-java/Dockerfile 结构。
go_docker_example:
  type: docker
  dockerfile: ./Dockerfile
  registry: registry.example.com
  image: my-project/gateway
  tag: staging

# ═══════════════════════════════════════════════════════════
# 15. Python 后端部署（gunicorn + systemd）
# ═══════════════════════════════════════════════════════════
#
# 适用场景：Django / Flask / FastAPI 服务，服务器上用 gunicorn 运行。
# 建议直接使用 ssh 类型 + 自定义脚本完成：构建（打包依赖）→ 上传 → 重启。
#
python_gunicorn_example:
  type: script
  build_cmd: pip install -r requirements.txt -t dist/
  script: ./scripts/deploy-python.sh
  # deploy-python.sh 内容示例（上传 + 重启 gunicorn）：
  #   rsync -az --delete dist/ deployer@server:/opt/services/api/app/
  #   ssh deployer@server "sudo systemctl restart api-gunicorn"

# ═══════════════════════════════════════════════════════════
# 完整 PROJECT.yaml 示例（含部署配置）
# ═══════════════════════════════════════════════════════════

platforms:
  - name: sr-web-operation
    type: frontend
    description: 运营管理前端
    code_path: ./sr-web-operation
    default_branch: main
    requirement_unit: 运营管理
    deploy:
      staging:
        type: ssh
        build_cmd: npm run build:staging
        output_dir: dist
        host: deployer@staging-server.example.com
        key: ~/.ssh/id_rsa
        remote_dir: /var/www/html/sr-web-operation
        script: sudo nginx -s reload
      production:
        type: ssh
        build_cmd: npm run build:prod
        output_dir: dist
        host: deployer@prod-server.example.com
        key: ~/.ssh/id_rsa_production
        remote_dir: /var/www/html/sr-web-operation
        script: sudo nginx -s reload

  - name: api-service
    type: backend
    description: API 服务
    code_path: ./api-service
    default_branch: main
    deploy:
      staging:
        type: pm2
        build_cmd: npm run build
        pm2_config: ecosystem.config.js
        host: deployer@staging-server.example.com
        key: ~/.ssh/id_rsa
        remote_dir: /opt/services/api-service

# ═══════════════════════════════════════════════════════════
# 环境配置文件示例（.speccore/environments/staging.yaml）
# ═══════════════════════════════════════════════════════════
#
# 环境配置会与 PROJECT.yaml 的 deploy 段合并，优先级：环境配置 > PROJECT.yaml
# 部署发起时（v8.3.348+）每次实时读取本文件，改完立即生效，无需重启任何进程。
#
# 目标分支四级回退（v8.3.348+，deploy / pipeline 共用）：
#   1. platforms.{端}.branch   ← 本文件按端指定的分支（优先级最高）
#   2. branch                  ← 本文件环境全局分支
#   3. PROJECT.yaml 的 default_branch
#   4. 子任务 .meta/git-config 的「源分支」
#
# deploy 执行前会打印「部署计划」面板：端 → 分支（含来源）→ 构建命令 → 部署目标，
# 执行中 git checkout/pull 输出透明，结束后汇总报告含各端实际分支。

env: staging

# 环境全局分支：该环境所有端默认切到此分支（按端覆盖见 platforms）
branch: staging

# 构建命令各端各自配置（见 platforms.{端}.build_cmd，Java / Web / 移动端各异）；
# 解析层支持 defaults.build_cmd 作为「端未写时的兜底」，仅全端同构项目适用。

# 按端覆盖配置
platforms:
  # 前端：仅此端切 release 分支（覆盖全局 branch，四级回退第 1 级）
  sr-web-operation:
    branch: release/web-2026
    build_cmd: npm run build:staging
    deploy:
      type: ssh
      host: deployer@staging-server.example.com:22
      key: ~/.ssh/id_rsa
      remote_dir: /var/www/html/sr-web-operation

  # 后端：不写 branch 时回退到本文件全局 branch（第 2 级）
  api-service:
    build_cmd: npm run build
    deploy:
      type: pm2
      pm2_config: ecosystem.config.js
      host: deployer@staging-server.example.com
      key: ~/.ssh/id_rsa
      remote_dir: /opt/services/api-service

# ═══════════════════════════════════════════════════════════
# 常用脚本示例（实体文件见 templates/deploy-scripts/）
# ═══════════════════════════════════════════════════════════
#
# 脚本实体与说明：
#   templates/deploy-scripts/trigger-jenkins.sh       Jenkins 构建触发
#   templates/deploy-scripts/deploy-ftp.sh            lftp FTP 上传
#   templates/deploy-scripts/deploy-password-ssh.sh   sshpass 密码 SSH
#   templates/deploy-scripts/deploy-compose.sh        docker-compose 编排
#   templates/deploy-scripts/deploy-python.sh         Python gunicorn 部署
#   templates/deploy-java/deploy.sh                   服务器端 Java 部署（备份→替换→重启）
#   templates/deploy-docker/deploy-remote.sh          服务器端 Docker 容器管理
#
# 以下为脚本要点摘录（完整版以实体文件为准）：

# --- trigger-jenkins.sh（要点）---
# #!/bin/bash
# curl -X POST \
#   -u "$JENKINS_USER:$JENKINS_TOKEN" \
#   "http://jenkins.example.com/job/my-project-$1/build"

# --- deploy-ftp.sh（要点，完整版含环境变量校验）---
# #!/bin/bash
# # 使用 lftp 进行 FTP 上传（支持密码）
# lftp -u "$FTP_USER,$FTP_PASS" "$FTP_HOST" <<EOF
# set ssl:verify-certificate no
# mirror -R dist /public_html/h5
# bye
# EOF

# --- deploy-password-ssh.sh（要点，完整版含环境变量校验）---
# #!/bin/bash
# # 使用 sshpass 进行密码认证的 SSH 部署（需安装 sshpass）
# # macOS: brew install sshpass
# # Ubuntu: apt-get install sshpass
# sshpass -p "$SSH_PASSWORD" scp -r dist/* "$SSH_USER@$SSH_HOST:$REMOTE_DIR/"
# sshpass -p "$SSH_PASSWORD" ssh "$SSH_USER@$SSH_HOST" "sudo nginx -s reload"

# --- deploy-java.sh（实体：templates/deploy-java/deploy.sh，服务器端执行）---
# #!/bin/bash
# # Java 后端部署脚本（放在服务器上，由 SSH 调用或手动执行）
# APP_NAME="${1:-order-service}"
# DEPLOY_DIR="/opt/services/$APP_NAME"
# BACKUP_DIR="/opt/services/$APP_NAME/backups"
# JAR_FILE="$DEPLOY_DIR/$APP_NAME.jar"
# NEW_JAR="$DEPLOY_DIR/$APP_NAME-new.jar"
#
# # 1. 备份旧版本
# mkdir -p "$BACKUP_DIR"
# if [ -f "$JAR_FILE" ]; then
#   cp "$JAR_FILE" "$BACKUP_DIR/$APP_NAME-$(date +%Y%m%d-%H%M%S).jar"
#   # 只保留最近 5 个备份
#   ls -t "$BACKUP_DIR"/*.jar | tail -n +6 | xargs -r rm -f
# fi
#
# # 2. 替换 jar
# if [ -f "$NEW_JAR" ]; then
#   mv "$NEW_JAR" "$JAR_FILE"
# else
#   echo "错误：未找到新 jar 文件 $NEW_JAR"
#   exit 1
# fi
#
# # 3. 重启服务
# sudo systemctl restart "$APP_NAME"
# sleep 2
# sudo systemctl status "$APP_NAME" --no-pager

# --- systemd service 文件示例（/etc/systemd/system/order-service.service） ---
# [Unit]
# Description=Order Service
# After=network.target
#
# [Service]
# Type=simple
# User=deployer
# Group=deployer
# WorkingDirectory=/opt/services/order-service
# Environment="SPRING_PROFILES_ACTIVE=staging"
# Environment="JAVA_OPTS=-Xms512m -Xmx1024m -Dfile.encoding=UTF-8"
# ExecStart=/usr/bin/java $JAVA_OPTS -jar order-service.jar
# ExecStop=/bin/kill -SIGTERM $MAINPID
# Restart=on-failure
# RestartSec=10
# StandardOutput=append:/var/log/order-service/app.log
# StandardError=append:/var/log/order-service/error.log
#
# [Install]
# WantedBy=multi-user.target
