kind: pipeline type: docker name: DEV-frontend-monorepo-ci clone: depth: 20 steps: - name: build-and-run-apps image: docker:cli pull: if-not-exists volumes: - name: docker_sock path: /var/run/docker.sock - name: configs_dir path: /bluetti/frontend_project/bluetti-shop-configs environment: DOCKER_BUILDKIT: "1" COMPOSE_DOCKER_CLI_BUILD: "1" DRONE_COMMIT: ${DRONE_COMMIT} DRONE_COMMIT_BEFORE: ${DRONE_COMMIT_BEFORE} DRONE_COMMIT_AFTER: ${DRONE_COMMIT_AFTER} DRONE_BUILD_EVENT: ${DRONE_BUILD_EVENT} # 引入事件类型判断 PROJECT_NAME: from_secret: PROJECT_NAME commands: - docker version - docker info - docker buildx version || true - | if [ "${DRONE_BUILD_EVENT}" = "pull_request" ] || [ "${DRONE_BUILD_EVENT}" = "merge_request" ]; then # 如果是 MR,直接对比目标分支(假设是 dev) git fetch origin dev:dev changed_files=$(git diff --name-only dev...HEAD) elif [ "${DRONE_COMMIT_BEFORE}" = "0000000000000000000000000000000000000000" ] || [ -z "${DRONE_COMMIT_BEFORE}" ]; then changed_files=$(git diff-tree --no-commit-id --name-only -r ${DRONE_COMMIT_AFTER}) else changed_files=$(git diff --name-only ${DRONE_COMMIT_BEFORE} ${DRONE_COMMIT_AFTER}) fi # 2. 判断构建范围 echo "本次变更文件:" echo "$changed_files" # 只有影响所有站点的关键共享文件/目录变动时,才做全量构建 full_build_changes=$(echo "$changed_files" | grep -E "^(package\.json|pnpm-lock\.yaml|pnpm-workspace\.yaml|turbo\.json|docker-compose.*\.ya?ml|packages/|patches/)" | wc -l) if [ "$full_build_changes" -gt 0 ]; then echo "检测到关键共享变动,准备全量构建..." build_list=$(docker compose -p "$PROJECT_NAME" config --services) else echo "执行定向增量构建..." build_list=$(echo "$changed_files" | grep "^apps/" | cut -d/ -f2 | sort -u) fi compose_services=$(docker compose -p "$PROJECT_NAME" config --services) original_build_list="$build_list" build_list="" skipped_list="" for svc in $original_build_list; do if echo "$compose_services" | grep -q "^$svc$"; then build_list="$build_list $svc" else skipped_list="$skipped_list $svc" fi done build_list=$(echo "$build_list" | xargs) skipped_list=$(echo "$skipped_list" | xargs) if [ -n "$skipped_list" ]; then echo "以下 apps 变更未在 docker-compose 中定义,已跳过: $skipped_list" fi if [ -z "$build_list" ]; then echo "未命中可构建服务(仅文档或非关键文件改动),跳过构建。" exit 0 fi # 3. 设置部署环境变量 export BUILD_ENV="development" export CONTAINER_SUFFIX="" export IMAGE_TAG="dev" export TRAEFIK_PREFIX="shoptest" for svc in $build_list; do echo ">>>>>> 开始增量构建部署服务: $svc <<<<<<" cp /bluetti/frontend_project/bluetti-shop-configs/"$svc"-development.env apps/$svc/.env.development done docker compose --parallel 1 -p "$PROJECT_NAME" up -d --build $build_list echo ">>>>>> 清理悬空镜像 <<<<<<" docker image prune -f volumes: - name: pnpm_store host: path: /tmp/pnpm-cache - name: configs_dir host: path: /bluetti/frontend_project/bluetti-shop-configs - name: docker_sock host: path: /var/run/docker.sock trigger: branch: - dev event: include: - push - merge_request paths: include: - "apps/**" - "packages/**" - "patches/**" - "package.json" - "pnpm-lock.yaml" - "pnpm-workspace.yaml" - "turbo.json" - "docker-compose*.yml" --- kind: pipeline type: docker name: TEST-frontend-monorepo-ci clone: depth: 22 steps: - name: build-and-run-apps image: docker:cli volumes: - name: docker_sock path: /var/run/docker.sock # 允许在容器内调用宿主机的 Docker - name: configs_dir path: /bluetti/frontend_project/bluetti-shop-configs environment: DRONE_COMMIT: ${DRONE_COMMIT} DRONE_COMMIT_BEFORE: ${DRONE_COMMIT_BEFORE} DRONE_COMMIT_AFTER: ${DRONE_COMMIT_AFTER} DOCKER_BUILDKIT: "1" COMPOSE_DOCKER_CLI_BUILD: "1" PROJECT_NAME: from_secret: PROJECT_NAME # SHOP_AU: shop-test-au.bluettipower.com commands: - | # 1. 路径变动检测逻辑 if [ "${DRONE_COMMIT_BEFORE}" = "0000000000000000000000000000000000000000" ]; then changed_files=$(git diff-tree --no-commit-id --name-only -r ${DRONE_COMMIT_AFTER}) else changed_files=$(git diff --name-only ${DRONE_COMMIT_BEFORE} ${DRONE_COMMIT_AFTER}) fi # 2. 判断构建范围 echo "本次变更文件:" echo "$changed_files" full_build_changes=$(echo "$changed_files" | grep -E "^(package\.json|pnpm-lock\.yaml|.dockerignore|pnpm-workspace\.yaml|turbo\.json|docker-compose.*\.ya?ml|packages/|patches/)" | wc -l) PROJECT_NAME_TEST="${PROJECT_NAME}test" COMPOSE_FILE="docker-compose-test.yml" if [ "$full_build_changes" -gt 0 ]; then echo "检测到关键共享变动,准备全量构建..." build_list=$(docker compose -f "$COMPOSE_FILE" config --services) else echo "执行定向增量构建..." build_list=$(echo "$changed_files" | grep "^apps/" | cut -d/ -f2 | sort -u) fi compose_services=$(docker compose -f "$COMPOSE_FILE" config --services) original_build_list="$build_list" build_list="" skipped_list="" for svc in $original_build_list; do if echo "$compose_services" | grep -q "^$svc$"; then build_list="$build_list $svc" else skipped_list="$skipped_list $svc" fi done build_list=$(echo "$build_list" | xargs) skipped_list=$(echo "$skipped_list" | xargs) if [ -n "$skipped_list" ]; then echo "以下 apps 变更未在 docker-compose 中定义,已跳过: $skipped_list" fi if [ -z "$build_list" ]; then echo "未命中可构建服务(仅文档或非关键文件改动),跳过构建。" exit 0 fi export BUILD_ENV="test" for svc in $build_list; do echo ">>>>>> 构建服务: $svc $PROJECT_NAME_TEST <<<<<<" cp /bluetti/frontend_project/bluetti-shop-configs/"$svc"-test.env apps/$svc/.env.test # docker compose -f "$COMPOSE_FILE" -p "$PROJECT_NAME_TEST" up -d "$svc" --build done docker compose --parallel 1 -f "$COMPOSE_FILE" -p "$PROJECT_NAME_TEST" up -d --build $build_list echo ">>>>>> 清理悬空镜像 <<<<<<" docker image prune -f volumes: - name: pnpm_store host: path: /tmp/pnpm-cache # 宿主机路径,用于跨流水线共享 node_modules - name: configs_dir host: path: /bluetti/frontend_project/bluetti-shop-configs - name: docker_sock host: path: /var/run/docker.sock trigger: branch: - test event: include: - push - merge_request paths: include: - "apps/**" - "packages/**" - "patches/**" - "package.json" - "pnpm-lock.yaml" - "pnpm-workspace.yaml" - "turbo.json" - "docker-compose*.yml" - ".dockerignore" --- kind: pipeline type: docker name: RC-frontend-monorepo-ci clone: depth: 22 steps: - name: build-and-push-apps image: docker:cli volumes: - name: docker_sock path: /var/run/docker.sock - name: configs_dir path: /bluetti/frontend_project/bluetti-shop-configs environment: DRONE_COMMIT: ${DRONE_COMMIT} DRONE_COMMIT_BEFORE: ${DRONE_COMMIT_BEFORE} DRONE_COMMIT_AFTER: ${DRONE_COMMIT_AFTER} DOCKER_BUILDKIT: "1" COMPOSE_DOCKER_CLI_BUILD: "1" commands: - | if [ "${DRONE_COMMIT_BEFORE}" = "0000000000000000000000000000000000000000" ]; then changed_files=$(git diff-tree --no-commit-id --name-only -r ${DRONE_COMMIT_AFTER}) else changed_files=$(git diff --name-only ${DRONE_COMMIT_BEFORE} ${DRONE_COMMIT_AFTER}) fi echo "本次变更文件:" echo "$changed_files" full_build_changes=$(echo "$changed_files" | grep -E "^(package\.json|pnpm-lock\.yaml|pnpm-workspace\.yaml|turbo\.json|docker-compose.*\.ya?ml|packages/|patches/)" | wc -l) if [ "$full_build_changes" -gt 0 ]; then echo "检测到关键共享变动,准备全量构建..." build_list=$(docker compose -f docker-compose.yml config --services) else echo "执行定向增量构建..." build_list=$(echo "$changed_files" | grep "^apps/" | cut -d/ -f2 | sort -u) fi compose_services=$(docker compose -f docker-compose.yml config --services) original_build_list="$build_list" build_list="" skipped_list="" for svc in $original_build_list; do if echo "$compose_services" | grep -q "^$svc$"; then build_list="$build_list $svc" else skipped_list="$skipped_list $svc" fi done build_list=$(echo "$build_list" | xargs) skipped_list=$(echo "$skipped_list" | xargs) if [ -n "$skipped_list" ]; then echo "以下 apps 变更未在 docker-compose 中定义,已跳过: $skipped_list" fi if [ -z "$build_list" ]; then echo "未命中可构建服务(仅文档或非关键文件改动),跳过构建。" exit 0 fi > .deploy_list docker login 127.0.0.1:5000 -u bluetti -p cjJXBbkHlvVWH2B echo ">>>>>> 并行构建服务: $build_list <<<<<<" docker compose -p "$PROJECT_NAME" build $build_list for svc in $build_list; do if docker compose -p "$PROJECT_NAME" config --services | grep -q "^$svc$"; then harbor_tag="127.0.0.1:5000/bluetti-frontend/$svc:${DRONE_COMMIT:0:10}" docker tag "$svc:latest" "$harbor_tag" echo ">>>>>> 推送服务: $svc <<<<<<" docker push "$harbor_tag" echo "$svc" >> .deploy_list echo ">>>>>> 推送完成,$svc 服务版本号: ${DRONE_COMMIT:0:10}" fi done - name: ssh-deploy image: appleboy/drone-ssh settings: host: 47.253.60.94 username: root key: from_secret: remote_ssh_key port: 22 environment: - COMMIT_SHA=${DRONE_COMMIT:0:10} - BUILD_ENV="production" command_timeout: 15m script: - echo ">>>>>> 开始连接远程服务器 <<<<<<" - cd /bluetti/frontend_project/bluetti-shop - git pull origin release - docker login harbor.bluettipower.com -u bluetti -p cjJXBbkHlvVWH2B - | diff_failed=0 if [ "${DRONE_COMMIT_BEFORE}" = "0000000000000000000000000000000000000000" ]; then changed_files=$(git diff-tree --no-commit-id --name-only -r ${DRONE_COMMIT_AFTER}) || diff_failed=1 else changed_files=$(git diff --name-only ${DRONE_COMMIT_BEFORE} ${DRONE_COMMIT_AFTER}) || diff_failed=1 fi export TARGET_SITES="shopify-australia shopify-x" export SHOP_US="shop-rc-us.bluettipower.com" export SHOP_AU="shop-rc-au.bluettipower.com" export SHOP_IT="shop-rc-it.bluettipower.com" export SHOP_ES="shop-rc-es.bluettipower.com" export SHOP_EU="shop-rc-eu.bluettipower.com" export SHOP_DE="shop-rc-de.bluettipower.com" export SHOP_CA="shop-rc-ca.bluettipower.com" export SHOP_UK="shop-rc-uk.bluettipower.com" export SHOP_IE="shop-rc-ie.bluettipower.com" export SHOP_BR="shop-rc-br.bluettipower.com" export SHOP_MX="shop-rc-mx.bluettipower.com" export SHOP_FR="shop-rc-fr.bluettipower.com" export SHOP_PH="shop-rc-ph.bluettipower.com" export SHOP_KR="shop-rc-kr.bluettipower.com" export SHOP_JP="shop-rc-jp.bluettipower.com" export BUILD_ENV="production" export COMMIT_SHA=${DRONE_COMMIT:0:10} echo "本次变更文件:" if [ "$diff_failed" -eq 1 ]; then echo "⚠️ 变更范围计算失败,回退为全量部署。" changed_files="packages/__force_full_deploy__" fi echo "$changed_files" full_build_changes=$(echo "$changed_files" | grep -E "^(package\.json|pnpm-lock\.yaml|pnpm-workspace\.yaml|turbo\.json|docker-compose.*\.ya?ml|packages/|patches/)" | wc -l) if [ "$full_build_changes" -gt 0 ]; then echo "检测到关键共享变动,远程全量更新..." deploy_list=$(docker compose -f docker-compose-release.yml config --services) else deploy_list=$(echo "$changed_files" | grep "^apps/" | cut -d/ -f2 | sort -u) fi compose_services=$(docker compose -f docker-compose-release.yml config --services) original_deploy_list="$deploy_list" deploy_list="" skipped_list="" for svc in $original_deploy_list; do if echo "$compose_services" | grep -q "^$svc$"; then deploy_list="$deploy_list $svc" else skipped_list="$skipped_list $svc" fi done deploy_list=$(echo "$deploy_list" | xargs) skipped_list=$(echo "$skipped_list" | xargs) if [ -n "$skipped_list" ]; then echo "以下 apps 变更未在 docker-compose 中定义,已跳过: $skipped_list" fi if [ -z "$deploy_list" ]; then echo "未命中可部署服务(仅文档或非关键文件改动),跳过远程部署。" exit 0 fi for svc in $deploy_list; do cp /bluetti/frontend_project/bluetti-shop-configs/"$svc"-production.env apps/$svc/.env.production done echo ">>>>>> 远程并行拉取镜像: $deploy_list <<<<<<" docker compose -f docker-compose-release.yml pull $deploy_list for svc in $deploy_list; do echo ">>>>>> 远程更新服务: $svc <<<<<<" docker compose -f docker-compose-release.yml up -d --force-recreate "$svc" echo ">>>>>> 部署完成: $svc 版本号: $COMMIT_SHA, 环境: $BUILD_ENV <<<<<<" done volumes: - name: pnpm_store host: path: /tmp/pnpm-cache - name: docker_sock host: path: /var/run/docker.sock - name: configs_dir host: path: /bluetti/frontend_project/bluetti-shop-configs trigger: branch: - release event: include: - push paths: include: - "apps/**" - "packages/**" - "patches/**" - "package.json" - "pnpm-lock.yaml" - "pnpm-workspace.yaml" - "turbo.json" - "docker-compose*.yml" --- kind: pipeline type: docker name: PROD-frontend-monorepo-ci clone: depth: 22 steps: - name: build-and-push-apps image: docker:cli pull: if-not-exists volumes: - name: docker_sock path: /var/run/docker.sock - name: configs_dir path: /bluetti/frontend_project/bluetti-shop-configs environment: DOCKER_BUILDKIT: "1" COMPOSE_DOCKER_CLI_BUILD: "1" DRONE_COMMIT: ${DRONE_COMMIT} DRONE_COMMIT_BEFORE: ${DRONE_COMMIT_BEFORE} DRONE_COMMIT_AFTER: ${DRONE_COMMIT_AFTER} DRONE_BUILD_EVENT: ${DRONE_BUILD_EVENT} # 引入事件类型判断 PROJECT_NAME: from_secret: PROJECT_NAME commands: - | if [ "${DRONE_COMMIT_BEFORE}" = "0000000000000000000000000000000000000000" ]; then changed_files=$(git diff-tree --no-commit-id --name-only -r ${DRONE_COMMIT_AFTER}) else changed_files=$(git diff --name-only ${DRONE_COMMIT_BEFORE} ${DRONE_COMMIT_AFTER}) fi echo "本次变更文件:" echo "$changed_files" full_build_changes=$(echo "$changed_files" | grep -E "^(package\.json|pnpm-lock\.yaml|pnpm-workspace\.yaml|turbo\.json|docker-compose.*\.ya?ml|packages/|patches/)" | wc -l) if [ "$full_build_changes" -gt 0 ]; then echo "检测到关键共享变动,准备全量构建..." build_list=$(docker compose -f docker-compose.yml config --services) else echo "执行定向增量构建..." build_list=$(echo "$changed_files" | grep "^apps/" | cut -d/ -f2 | sort -u) fi compose_services=$(docker compose -f docker-compose.yml config --services) original_build_list="$build_list" build_list="" skipped_list="" for svc in $original_build_list; do if echo "$compose_services" | grep -q "^$svc$"; then build_list="$build_list $svc" else skipped_list="$skipped_list $svc" fi done build_list=$(echo "$build_list" | xargs) skipped_list=$(echo "$skipped_list" | xargs) if [ -n "$skipped_list" ]; then echo "以下 apps 变更未在 docker-compose 中定义,已跳过: $skipped_list" fi if [ -z "$build_list" ]; then echo "未命中可构建服务(仅文档或非关键文件改动),跳过构建。" exit 0 fi > .deploy_list docker login 127.0.0.1:5000 -u bluetti -p cjJXBbkHlvVWH2B echo ">>>>>> 并行构建服务: $build_list <<<<<<" docker compose -p "$PROJECT_NAME" build $build_list for svc in $build_list; do if docker compose -p "$PROJECT_NAME" config --services | grep -q "^$svc$"; then harbor_tag="127.0.0.1:5000/bluetti-frontend/$svc:${DRONE_COMMIT:0:10}" docker tag "$svc:latest" "$harbor_tag" echo ">>>>>> 推送服务: $svc <<<<<<" docker push "$harbor_tag" echo "$svc" >> .deploy_list echo ">>>>>> 推送完成,$svc 服务版本号: ${DRONE_COMMIT:0:10}" fi done - name: ssh-deploy image: appleboy/drone-ssh settings: # 这里SSH 日本服务器 10.16.16.130:10007 德国服务踌躇10.16.16.130:10008 host: 10.16.16.130 username: cloudapp key: from_secret: remote_ssh_key port: 10008 environment: - COMMIT_SHA=${DRONE_COMMIT:0:10} - BUILD_ENV="production" command_timeout: 15m script: - echo ">>>>>> 开始连接远程服务器 <<<<<<" - cd /bluetti/frontend_project/bluetti-shop - git pull origin main - docker login harbor.bluettipower.com -u bluetti -p cjJXBbkHlvVWH2B - | diff_failed=0 if [ "${DRONE_COMMIT_BEFORE}" = "0000000000000000000000000000000000000000" ]; then changed_files=$(git diff-tree --no-commit-id --name-only -r ${DRONE_COMMIT_AFTER}) || diff_failed=1 else changed_files=$(git diff --name-only ${DRONE_COMMIT_BEFORE} ${DRONE_COMMIT_AFTER}) || diff_failed=1 fi export TARGET_SITES="shopify-australia shopify-x" export SHOP_US="shop-us.bluettipower.com" export SHOP_AU="shop-au.bluettipower.com" export BUILD_ENV="production" export COMMIT_SHA=${DRONE_COMMIT:0:10} echo "本次变更文件:" if [ "$diff_failed" -eq 1 ]; then echo "⚠️ 变更范围计算失败,回退为全量部署。" changed_files="packages/__force_full_deploy__" fi echo "$changed_files" full_build_changes=$(echo "$changed_files" | grep -E "^(package\.json|pnpm-lock\.yaml|pnpm-workspace\.yaml|turbo\.json|docker-compose.*\.ya?ml|packages/|patches/)" | wc -l) if [ "$full_build_changes" -gt 0 ]; then echo "检测到关键共享变动,远程全量更新..." deploy_list=$(docker compose -f docker-compose-prod.yml config --services) else deploy_list=$(echo "$changed_files" | grep "^apps/" | cut -d/ -f2 | sort -u) fi compose_services=$(docker compose -f docker-compose-prod.yml config --services) original_deploy_list="$deploy_list" deploy_list="" skipped_list="" for svc in $original_deploy_list; do if echo "$compose_services" | grep -q "^$svc$"; then deploy_list="$deploy_list $svc" else skipped_list="$skipped_list $svc" fi done deploy_list=$(echo "$deploy_list" | xargs) skipped_list=$(echo "$skipped_list" | xargs) if [ -n "$skipped_list" ]; then echo "以下 apps 变更未在 docker-compose 中定义,已跳过: $skipped_list" fi if [ -z "$deploy_list" ]; then echo "未命中可部署服务(仅文档或非关键文件改动),跳过远程部署。" exit 0 fi for svc in $deploy_list; do cp /bluetti/frontend_project/bluetti-shop-configs/"$svc"-production.env apps/$svc/.env.production done echo ">>>>>> 远程并行拉取镜像: $deploy_list <<<<<<" docker compose -f docker-compose-prod.yml pull $deploy_list for svc in $deploy_list; do echo ">>>>>> 远程更新服务: $svc <<<<<<" docker compose -f docker-compose-prod.yml up -d --force-recreate "$svc" echo ">>>>>> 部署完成: $svc 版本号: $COMMIT_SHA, 环境: $BUILD_ENV <<<<<<" done volumes: - name: pnpm_store host: path: /tmp/pnpm-cache - name: docker_sock host: path: /var/run/docker.sock - name: configs_dir host: path: /bluetti/frontend_project/bluetti-shop-configs trigger: branch: - main event: include: - push paths: include: - "apps/**" - "packages/**" - "patches/**" - "package.json" - "pnpm-lock.yaml" - "pnpm-workspace.yaml" - "turbo.json" - "docker-compose*.yml" --- kind: pipeline type: docker name: CI-notify clone: disable: true depends_on: - DEV-frontend-monorepo-ci - TEST-frontend-monorepo-ci - RC-frontend-monorepo-ci - PROD-frontend-monorepo-ci trigger: event: - push - promote - rollback branch: - dev - test - release - main steps: - name: send-dingtalk-notification image: lddsb/drone-dingtalk-message volumes: - name: dingtalk-tpl path: /data settings: # token: 95b118a31f95c328b1c5f7f52622997d77b69da9d393b0700fc8eb33ed551713 # secret: SECb355ff4ba5b05b5325d4c67d3f6637c75613668c248ad9cc97355fe266fe1b6a # token: 8a47605751760b1b1af660e67c2f39bdf9f83c672a18ab872412e99c78b0e5c0 # secret: SEC0dfa30e4e8acfae69e7bf42b19c2feff5d302d2667de3aa4ba8cff46e867758a token: 94892495526ab4eddf5796170c8cf388697526180588f0b4cc2c8aefd3b85eb2 secret: SECbb3d7f34ee21f0268fcb093357033e94a2a0cd340be02d36ac2a59a8001b5ffa type: markdown debug: false tpl: /data/dingtalk_${DRONE_BUILD_EVENT}.tpl tips_title: 构建通知 - ${DRONE_BRANCH} when: status: - success - failure volumes: - name: dingtalk-tpl host: path: /bluetti/drone/data