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

工作流同步需求:如何实现多服务同时部署?

解决同一提交触发的多Github Actions工作流同步部署问题

针对同一提交触发多个服务工作流时部署不同步导致的Bug问题,这里提供两种可行的实现方案,核心思路是让所有关联工作流在部署前完成前置阶段(构建、测试),再统一执行部署操作。

方案一:在每个工作流中添加等待同步阶段

给每个服务的工作流新增一个等待作业,在部署前检查同提交SHA下的其他关联工作流是否都完成了构建测试,只有当所有工作流就绪后才执行部署。

示例:Frontend工作流修改

name: Frontend
on:
  push:
    branches: [main]
    paths: ['frontend/**']

jobs:
  build-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      # 这里保留你原有的构建、测试步骤
      - name: Install dependencies
        run: cd frontend && npm install
      - name: Build frontend
        run: cd frontend && npm run build
      - name: Run tests
        run: cd frontend && npm test

  wait-for-other-workflows:
    needs: build-test
    runs-on: ubuntu-latest
    steps:
      - name: Install GitHub CLI
        run: |
          type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)
          curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
          sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
          echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
          sudo apt update && sudo apt install gh -y

      - name: Authenticate GH CLI
        run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token

      - name: Wait for all related workflows to complete
        run: |
          COMMIT_SHA="${{ github.sha }}"
          OWNER="${{ github.repository_owner }}"
          REPO="${{ github.event.repository.name }}"
          CURRENT_RUN_ID="${{ github.run_id }}"
          # 指定需要等待的工作流名称,根据你的实际情况修改
          TARGET_WORKFLOWS=("Frontend" "API")

          while true; do
            ALL_READY=true
            for WORKFLOW_NAME in "${TARGET_WORKFLOWS[@]}"; do
              # 跳过当前工作流
              if [ "$WORKFLOW_NAME" == "${{ github.workflow }}" ]; then
                continue
              fi
              # 检查该工作流的最新运行状态
              RUN_STATUS=$(gh run list --repo "$OWNER/$REPO" --sha "$COMMIT_SHA" --workflow "$WORKFLOW_NAME" --json conclusion --jq '.[0].conclusion')
              if [ -z "$RUN_STATUS" ] || [ "$RUN_STATUS" != "success" ]; then
                ALL_READY=false
                echo "Waiting for workflow '$WORKFLOW_NAME' to finish successfully..."
                break
              fi
            done

            if $ALL_READY; then
              echo "All required workflows are ready. Proceeding to deployment."
              break
            else
              sleep 30
            fi
          done

  deploy:
    needs: wait-for-other-workflows
    runs-on: ubuntu-latest
    steps:
      # 这里保留你原有的部署步骤
      - name: Deploy frontend to server
        run: |
          # 你的部署命令,比如通过SSH更新Docker容器
          ssh user@your-server "cd /path/to/project && docker-compose up -d --build frontend"

注意事项

  • 默认的GITHUB_TOKEN已具备读取工作流状态的权限,无需额外配置
  • 可根据实际情况调整等待间隔(示例中为30秒)
  • 如果有新增服务,只需在TARGET_WORKFLOWS数组中添加对应的工作流名称

方案二:使用统一的同步部署工作流

设置一个独立的"同步部署"工作流,每个服务工作流完成构建测试后触发该工作流,由它等待所有服务就绪后统一执行部署。这种方案更易维护,适合服务较多的场景。

步骤1:修改各服务工作流,完成后触发同步部署

以Frontend工作流为例:

name: Frontend
on:
  push:
    branches: [main]
    paths: ['frontend/**']

jobs:
  build-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      # 构建、测试步骤...
      - name: Upload frontend build artifact
        uses: actions/upload-artifact@v4
        with:
          name: frontend-build
          path: frontend/dist/

  trigger-sync-deploy:
    needs: build-test
    runs-on: ubuntu-latest
    steps:
      - name: Trigger sync deployment
        uses: peter-evans/repository-dispatch@v3
        with:
          token: ${{ secrets.PAT_TOKEN }} # 需要具备repo权限的个人访问令牌
          event-type: sync-deploy
          client-payload: |
            {
              "commit_sha": "${{ github.sha }}"
            }

步骤2:创建同步部署工作流

新建.github/workflows/sync-deploy.yml:

name: Sync Deploy
on:
  repository_dispatch:
    types: [sync-deploy]

jobs:
  wait-for-all-services:
    runs-on: ubuntu-latest
    steps:
      - name: Install GitHub CLI
        run: |
          # 同方案一的GH CLI安装命令
          type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)
          curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
          sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
          echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
          sudo apt update && sudo apt install gh -y

      - name: Authenticate GH CLI
        run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token

      - name: Wait for all services to complete build-test
        run: |
          COMMIT_SHA="${{ github.event.client_payload.commit_sha }}"
          OWNER="${{ github.repository_owner }}"
          REPO="${{ github.event.repository.name }}"
          REQUIRED_WORKFLOWS=("Frontend" "API") # 列出所有需要同步的服务工作流
          TIMEOUT=3600 # 超时时间(1小时),避免无限等待
          START_TIME=$(date +%s)

          while true; do
            CURRENT_TIME=$(date +%s)
            if [ $((CURRENT_TIME - START_TIME)) -ge $TIMEOUT ]; then
              echo "Timeout waiting for workflows to complete. Exiting."
              exit 1
            fi

            ALL_COMPLETED=true
            for WORKFLOW in "${REQUIRED_WORKFLOWS[@]}"; do
              RUN_STATUS=$(gh run list --repo "$OWNER/$REPO" --sha "$COMMIT_SHA" --workflow "$WORKFLOW" --json conclusion --jq '.[0].conclusion')
              if [ "$RUN_STATUS" != "success" ]; then
                ALL_COMPLETED=false
                echo "Waiting for $WORKFLOW (current status: ${RUN_STATUS:-in progress})"
                break
              fi
            done

            if $ALL_COMPLETED; then
              echo "All services are ready. Starting deployment."
              break
            else
              sleep 30
            fi
          done

  deploy-all:
    needs: wait-for-all-services
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Download frontend artifact
        uses: actions/download-artifact@v4
        with:
          name: frontend-build
          path: frontend/dist/
      - name: Download API artifact
        uses: actions/download-artifact@v4
        with:
          name: api-build
          path: api/dist/
      - name: Deploy all services
        run: |
          # 统一部署命令,例如更新多个Docker容器
          ssh user@your-server "cd /path/to/project && docker-compose up -d --build frontend api"

注意事项

  • 需要创建一个具备repo权限的个人访问令牌(PAT),存储为PAT_TOKEN仓库密钥
  • 同步部署工作流添加了超时机制,避免因某个工作流失败导致无限等待
  • 所有服务工作流都需要上传构建产物到Artifacts,供同步部署工作流使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:05:59