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

如何配置GitHub Actions仅构建修改的微服务并管理版本?

问题与解决方案:微服务镜像构建优化与版本管理

背景

我有一个将不同微服务托管在独立文件夹中的单体应用,目录结构示例:

/project/service1
/project/service2

已为每个服务创建独立AWS ECR仓库,编写了GitHub Actions代码,在GitHub创建Release时构建每个服务的Docker镜像并推送到对应ECR仓库。每个服务有独立的GitHub Actions代码,将GitHub Release版本号作为ECR镜像的版本标签。

问题

  1. 不想每次创建Release时都构建推送所有服务镜像,只想构建推送有修改的服务(文件夹),该如何实现?采用什么方案?
  2. 由于不再为每个服务都构建镜像,各服务会有不同版本,无法再使用Release中输入的版本号,该如何管理版本?

项目语言:NodeJS

单个服务的GitHub Actions YAML示例

name: Deploy core to Amazon ECS

on:
  release:
    types: ["published"]

env:
  AWS_REGION: eu-central-1
  ECR_REPOSITORY: lake-core
  CONTAINER_NAME: core

permissions:
  contents: read

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    environment: production

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1
      
      - name: Build, tag, and push image to Amazon ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          IMAGE_TAG: ${{ github.ref_name }}
          WORKSPACE: ${{ github.workspace }} 
        run: |
          cd core
          cp -r ../shared/ ./shared
          sed 's/\.\.\/shared/\.\/shared/g' package.json > package-tmp.json 
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -t $ECR_REGISTRY/$ECR_REPOSITORY:latest .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY --all-tags
          rm -r ./shared
          rm package-tmp.json
          echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

解决方案

针对问题1:只构建推送有修改的服务

可以通过以下步骤实现:

  1. 合并为单份统一工作流
    取消每个服务的独立工作流,在项目根目录创建deploy-services.yml,统一管理所有服务的构建逻辑。

  2. 检测代码目录变化
    拉取完整代码历史后,用路径过滤工具检测哪些服务目录或共享目录有修改:

    - name: Checkout full code history
      uses: actions/checkout@v3
      with:
        fetch-depth: 0
    
    - name: Detect changed services
      id: changes
      uses: dorny/paths-filter@v2
      with:
        filters: |
          service1:
            - 'service1/**'
          service2:
            - 'service2/**'
          shared:
            - 'shared/**' # 共享代码修改时,所有依赖的服务都需要重新构建
    
  3. 动态触发对应服务的构建
    为每个服务定义单独的作业,通过条件判断决定是否执行:

    jobs:
      build-service1:
        if: steps.changes.outputs.service1 == 'true' || steps.changes.outputs.shared == 'true'
        runs-on: ubuntu-latest
        environment: production
        steps:
          # 复用原有的AWS配置、ECR登录、镜像构建推送逻辑,替换为service1对应的ECR仓库名等变量
    
      build-service2:
        if: steps.changes.outputs.service2 == 'true' || steps.changes.outputs.shared == 'true'
        runs-on: ubuntu-latest
        environment: production
        steps:
          # service2对应的构建推送步骤
    

针对问题2:多服务版本管理方案

可以采用以下两种可行方式:

方式1:服务独立版本号

  • 在每个服务目录的package.json中维护独立的version字段,作为该服务的版本标识。
  • 构建时读取该版本号作为镜像标签:
    IMAGE_TAG=$(jq -r '.version' service1/package.json)
    
  • 发布Release时,自动更新所有有修改的服务的package.json版本号(比如用npm version patch/minor/major命令),并提交到仓库。

方式2:复合版本号

  • 保留GitHub Release的主版本号,附加服务专属标识,格式如v1.0.0-service1-1,其中v1.0.0是Release版本,service1-1是该服务的修订次数。
  • 或者用服务目录的最新提交哈希作为标签补充:v1.0.0-abc123,其中abc123是服务目录的提交哈希,既关联Release版本,又能区分服务的具体修改。

额外建议:维护版本清单

在项目根目录创建versions.json文件,记录每个服务的当前镜像版本,每次构建后自动更新并提交:

{
  "service1": "v1.2.0",
  "service2": "v1.1.3"
}

方便统一查看所有服务的版本状态。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:15:08