From 871e06c4721e1c39af76f2bef8f11058a47881c4 Mon Sep 17 00:00:00 2001 From: MSuMshk <2039814060@qq.com> Date: Wed, 3 Dec 2025 10:29:34 +0800 Subject: [PATCH] =?UTF-8?q?docs:=E6=96=B0=E5=A2=9E=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Document/CI_CD流水线.md | 134 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 Document/CI_CD流水线.md diff --git a/Document/CI_CD流水线.md b/Document/CI_CD流水线.md new file mode 100644 index 0000000..6be352f --- /dev/null +++ b/Document/CI_CD流水线.md @@ -0,0 +1,134 @@ +# CI/CD 流水线(云效,dev 合并 master 触发) + +## 触发规则 +- 分支触发:仅 `master`。 +- 校验来源:流水线脚本内检查 `GIT_BRANCH == master` 且 `GIT_PREVIOUS_BRANCH == dev`,否则退出。 + +## 必填变量(云效“变量/密钥”) +- 字符变量: + - `REGISTRY=crpi-z1i5bludyfuvzo9o.cn-beijing.personal.cr.aliyuncs.com` + - `REGISTRY_USERNAME=heaize404@163.com` + - `DEPLOY_HOST=49.7.179.246` + - `DEPLOY_USER=root` +- 密钥/凭据: + - `REGISTRY_PASSWORD=MsuMshk112233` + - `DEPLOY_PASSWORD=7zE&84XI6~w57W7N` +- 默认基线:`BASE_REF=origin/master`(可不配)。 + +## Docker 端口约定 +- Admin:7801 +- Mini:7701 +- User:7901 + +## 完整流水线 YAML +```yaml +version: 1.0 +name: takeoutsaas-ci-cd +displayName: TakeoutSaaS CI/CD +triggers: + push: + branches: + include: + - master + +stages: + - stage: DetectChanges + name: DetectChanges + steps: + - step: Checkout + name: Checkout + checkout: self + - step: Detect + name: Detect + script: | + set -e + if [ "$GIT_BRANCH" != "master" ] || [ "$GIT_PREVIOUS_BRANCH" != "dev" ]; then + echo "非 dev->master,跳过流水线"; exit 0; fi + + git fetch origin master --depth=1 + BASE=${BASE_REF:-origin/master} + CHANGED=$(git diff --name-only "$(git merge-base $BASE HEAD)" HEAD) + echo "变更文件:" + echo "$CHANGED" + + deploy_all=false + services=() + hit(){ echo "$CHANGED" | grep -qE "$1"; } + + if hit '^src/(Domain|Application|Infrastructure|Core|Modules)/'; then deploy_all=true; fi + hit '^Directory.Build.props$' && deploy_all=true + + hit '^src/Api/TakeoutSaaS.AdminApi/' && services+=("admin-api") + hit '^src/Api/TakeoutSaaS.MiniApi/' && services+=("mini-api") + hit '^src/Api/TakeoutSaaS.UserApi/' && services+=("user-api") + + if $deploy_all || [ ${#services[@]} -eq 0 ]; then + services=("admin-api" "mini-api" "user-api") + fi + + echo "SERVICES=${services[*]}" >> "$ACROSS_STAGES_ENV_FILE" + + - stage: BuildPush + name: BuildPush + steps: + - step: DockerBuildPush + name: DockerBuildPush + script: | + set -e + IFS=' ' read -ra svcs <<< "$SERVICES" + REGISTRY=${REGISTRY:?需要配置 REGISTRY} + TAG=${TAG:-$(date +%Y%m%d%H%M%S)} + + echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY" -u "$REGISTRY_USERNAME" --password-stdin + + for svc in "${svcs[@]}"; do + case "$svc" in + admin-api) dockerfile="src/Api/TakeoutSaaS.AdminApi/Dockerfile"; image="$REGISTRY/admin-api:$TAG" ;; + mini-api) dockerfile="src/Api/TakeoutSaaS.MiniApi/Dockerfile"; image="$REGISTRY/mini-api:$TAG" ;; + user-api) dockerfile="src/Api/TakeoutSaaS.UserApi/Dockerfile"; image="$REGISTRY/user-api:$TAG" ;; + esac + echo "构建并推送 $image" + docker build -f "$dockerfile" -t "$image" . + docker push "$image" + done + echo "IMAGE_TAG=$TAG" >> "$ACROSS_STAGES_ENV_FILE" + + - stage: Deploy + name: Deploy + steps: + - step: DockerDeploy + name: DockerDeploy + script: | + set -e + command -v sshpass >/dev/null 2>&1 || (sudo apt-get update && sudo apt-get install -y sshpass) + + IFS=' ' read -ra svcs <<< "$SERVICES" + TAG="$IMAGE_TAG" + REGISTRY=${REGISTRY:?} + DEPLOY_HOST=${DEPLOY_HOST:?} + DEPLOY_USER=${DEPLOY_USER:-root} + DEPLOY_PASSWORD=${DEPLOY_PASSWORD:?} + + for svc in "${svcs[@]}"; do + case "$svc" in + admin-api) image="$REGISTRY/admin-api:$TAG"; port=7801 ;; + mini-api) image="$REGISTRY/mini-api:$TAG"; port=7701 ;; + user-api) image="$REGISTRY/user-api:$TAG"; port=7901 ;; + esac + + echo "部署 $svc -> $image" + sshpass -p "$DEPLOY_PASSWORD" ssh -o StrictHostKeyChecking=no "$DEPLOY_USER@$DEPLOY_HOST" "set -e; docker pull $image; docker stop $svc 2>/dev/null || true; docker rm $svc 2>/dev/null || true; docker run -d --name $svc --restart=always -p $port:$port $image" + done +``` + +## 注意事项 +- 以上 YAML 如仍报 YAML 校验错误,可将 `triggers` 改为: + ```yaml + on: + push: + branches: + - master + ``` + 其余保持不变。 +- 如果云效的分支变量名与 `GIT_BRANCH` / `GIT_PREVIOUS_BRANCH` 不同,请在 Detect 步骤替换为实际变量名。 +- 所有密码、密钥务必放在“密钥/凭据”类型变量中,不要写入代码库。