You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Git单体仓库中仅部署发生变更的微服务?

仅部署Git单体仓库中变更的Gradle微服务的CI/CD配置方案

一、核心思路:先检测变更,再定向构建部署

要实现只部署变更的微服务,核心是两步:精准识别哪些子模块有代码变更,然后只对这些模块执行构建和部署任务。以下是具体落地方案:

二、Git变更检测(基础环节)

首先需要通过Git命令筛选出本次提交中发生变更的微服务模块,同时要兼顾根项目核心配置变更的情况(这类变更会影响所有子模块,需全量部署)。

常用检测命令

假设你的微服务都放在services/目录下,每个子目录对应一个服务(如services/user-service、services/order-service):

# 检测根目录核心配置是否变更(build.gradle、settings.gradle等)
ROOT_CHANGED=$(git diff --name-only HEAD^ HEAD | grep -E '^(build.gradle|settings.gradle|gradle.properties|gradle/wrapper/)' | wc -l)

# 若根配置无变更,提取变更的服务列表
if [ $ROOT_CHANGED -eq 0 ]; then
  CHANGED_SERVICES=$(git diff --name-only HEAD^ HEAD | grep -E 'services/[^/]+/' | cut -d'/' -f2 | uniq)
fi
  • 命令说明:通过git diff对比当前提交与上一次提交的差异,筛选出变更的服务目录名并去重;若根项目核心配置有变更,则标记为全量部署。

三、Gradle层面适配

确保Gradle支持单独构建指定子模块,避免全量构建浪费资源:

  • 直接指定模块路径执行构建/部署任务:
    # 构建并发布user-service
    ./gradlew :services:user-service:build :services:user-service:publish
    
  • 每个微服务模块的build.gradle需定义独立的部署任务(如publish到镜像仓库、deploy到K8s),避免依赖无关模块的任务。
  • 若服务间存在依赖(如A依赖B的API模块),需额外编写脚本分析依赖关系,当B的API变更时,自动将A加入部署列表。

四、主流CI/CD平台配置示例

1. GitHub Actions

name: Deploy Changed Services
on:
  push:
    branches: [ main ]

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      changed-services: ${{ steps.filter.outputs.changed-services }}
      root-changed: ${{ steps.filter.outputs.root-changed }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2
      - id: filter
        run: |
          ROOT_CHANGED=$(git diff --name-only HEAD^ HEAD | grep -E '^(build.gradle|settings.gradle|gradle.properties|gradle/wrapper/)' | wc -l)
          if [ $ROOT_CHANGED -gt 0 ]; then
            echo "root-changed=true" >> $GITHUB_OUTPUT
            echo "changed-services=all" >> $GITHUB_OUTPUT
          else
            echo "root-changed=false" >> $GITHUB_OUTPUT
            CHANGED_SERVICES=$(git diff --name-only HEAD^ HEAD | grep -E 'services/[^/]+/' | cut -d'/' -f2 | uniq | tr '\n' ',')
            CHANGED_SERVICES=${CHANGED_SERVICES%,}
            echo "changed-services=$CHANGED_SERVICES" >> $GITHUB_OUTPUT
          fi

  deploy-services:
    needs: detect-changes
    runs-on: ubuntu-latest
    if: ${{ needs.detect-changes.outputs.changed-services != '' }}
    strategy:
      matrix:
        service: ${{ fromJson('["' + replace(needs.detect-changes.outputs.changed-services, ',', '","') + '"]') }}
    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
      - name: Build and deploy ${{ matrix.service }}
        run: |
          ./gradlew :services:${{ matrix.service }}:build :services:${{ matrix.service }}:publish
          # 此处添加具体部署命令,如kubectl apply、云厂商部署API调用等

2. GitLab CI

stages:
  - detect-changes
  - deploy

detect-changes:
  stage: detect-changes
  image: alpine/git:latest
  script:
    - |
      ROOT_CHANGED=$(git diff --name-only HEAD^ HEAD | grep -E '^(build.gradle|settings.gradle|gradle.properties|gradle/wrapper/)' | wc -l)
      if [ $ROOT_CHANGED -gt 0 ]; then
        echo "CHANGED_SERVICES=all" > variables.env
      else
        CHANGED_SERVICES=$(git diff --name-only HEAD^ HEAD | grep -E 'services/[^/]+/' | cut -d'/' -f2 | uniq | tr '\n' ',')
        CHANGED_SERVICES=${CHANGED_SERVICES%,}
        echo "CHANGED_SERVICES=$CHANGED_SERVICES" > variables.env
      fi
  artifacts:
    reports:
      dotenv: variables.env

deploy-services:
  stage: deploy
  image: gradle:jdk17-alpine
  needs: [detect-changes]
  parallel:
    matrix:
      - SERVICE: $[[ split(CHANGED_SERVICES, ',') ]]
  script:
    - chmod +x gradlew
    - ./gradlew :services:$SERVICE:build :services:$SERVICE:publish
    # 添加具体部署命令,如kubectl apply等
  only:
    - main

五、关键注意事项

  • 依赖关联处理:若服务A依赖服务B的API模块,需在变更检测脚本中加入依赖分析逻辑,当B的API变更时自动触发A的部署。
  • 缓存优化:在CI/CD中配置Gradle缓存(如缓存~/.gradle/caches和~/.gradle/wrapper),减少依赖下载时间。
  • 版本管理:建议给每个服务配置独立版本号,或用Git提交哈希作为版本后缀,确保变更服务的版本唯一可追溯。
  • 定向测试:构建前仅运行变更服务的测试用例,如./gradlew :services:user-service:test,缩短测试周期。

内容的提问来源于stack exchange,提问作者KMV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 23:33:22