跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • 世界
  • 用户
  • 群组
皮肤
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠

乐达

  1. 主页
  2. 团队公告
  3. 基于分支的完整工作流程示例

基于分支的完整工作流程示例

已定时 已固定 已锁定 已移动 团队公告
6 帖子 1 发布者 42 浏览 1 关注中
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • Z 离线
    Z 离线
    zhongfangxiong
    写于 最后由 编辑
    #1

    基于分支的完整工作流程示例

    场景1:功能开发分支

    分支创建

    git checkout master
    git pull
    git checkout -b feature/TG-1022-add-tel-to-sale
    

    开发完成后签入

    git add .
    git commit -m "feat: add telephone field to sale module"
    git push origin feature/TG-1022-add-tel-to-sale
    

    CI/CD 流程

    1. Setup 阶段

    • 生成版本号:2855.2026.104.12345
    • 判断分支:feature/TG-1022-add-tel-to-sale → ENVIRONMENT=development
    • 下载配置:https://version.lodatone.com/erp1.0/development/urls.txt

    2. Build 阶段

    • 使用开发环境的 Directory.Build.props
    • 构建 NuGet 包:Loda.Erp.Sales.2855.2026.104.12345.nupkg

    3. Push NuGet 阶段

    • 推送到 NuGet 仓库

    4. Update Version 阶段

    • 调用 API:
      GET /updateversion/erp1.0/Loda.Erp.Sales/2855.2026.104.12345/development
      
    • 更新文件:
      wwwroot/erp1.0/development/version-numbers/Loda.Erp.Sales.props
      wwwroot/erp1.0/development/Directory.Build.props
      

    5. Deploy 阶段(Docker 示例)

    deploy-dev(自动执行)

    部署到开发环境:
      stage: deploy-dev
      extends: .deploy-docker-base
      environment:
        name: development
      variables:
        DEPLOY_SSH_HOST: "10.0.3.204"
        HOST_PORT_OFFSET: "0"
      rules:
        - if: '$CI_COMMIT_BRANCH =~ /^(develop|next|feature\/|bugfix\/|fix\/)/'
          when: on_success
    

    deploy-test(手动执行)

    部署到测试环境:
      stage: deploy-test
      extends: .deploy-docker-base
      environment:
        name: test
      variables:
        DEPLOY_SSH_HOST: "10.0.3.204"
        HOST_PORT_OFFSET: "1"
      when: manual
      rules:
        - if: '$CI_COMMIT_BRANCH =~ /^(develop|next|feature\/|bugfix\/|fix\/)/'
    

    场景2:生产分支发布

    代码合并到 master

    git checkout master
    git pull
    git merge feature/TG-1022-add-tel-to-sale
    git push origin master
    

    CI/CD 流程

    1. Setup 阶段

    • 生成版本号:2855.2026.104.12346
    • 判断分支:master → ENVIRONMENT=production
    • 下载配置:https://version.lodatone.com/erp1.0/production/urls.txt

    2. Build 阶段

    • 使用生产环境的 Directory.Build.props
    • 构建 NuGet 包:Loda.Erp.Sales.2855.2026.104.12346.nupkg

    3. Push NuGet 阶段

    • 推送到 NuGet 仓库

    4. Update Version 阶段

    • 调用 API:
      GET /updateversion/erp1.0/Loda.Erp.Sales/2855.2026.104.12346/production
      
    • 更新文件:
      wwwroot/erp1.0/production/version-numbers/Loda.Erp.Sales.props
      wwwroot/erp1.0/production/Directory.Build.props
      

    5. Deploy 阶段(Docker 示例)

    deploy-staging(手动执行)

    部署到准正式环境:
      stage: deploy-staging
      extends: .deploy-docker-base
      environment:
        name: staging
      variables:
        DEPLOY_SSH_HOST: "10.0.3.202"
        HOST_PORT_OFFSET: "2"
      when: manual
      rules:
        - if: '$CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "main"'
    

    deploy-production(手动执行)

    部署到正式环境-服务器1:
      stage: deploy-production
      extends: .deploy-docker-base
      environment:
        name: production
      variables:
        DEPLOY_SSH_HOST: "10.0.3.201"
        HOST_PORT_OFFSET: "3"
      when: manual
      rules:
        - if: '$CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "main"'
    
    部署到正式环境-服务器2:
      stage: deploy-production
      extends: .deploy-docker-base
      environment:
        name: production
      variables:
        DEPLOY_SSH_HOST: "10.0.3.202"
        HOST_PORT_OFFSET: "3"
      when: manual
      rules:
        - if: '$CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "main"'
    

    场景3:紧急修复(hotfix)

    创建 hotfix 分支

    git checkout master
    git pull
    git checkout -b hotfix/TG-1025-fix-critical-bug
    

    CI/CD 流程

    • 环境判断:hotfix/* → ENVIRONMENT=production
    • 版本号写入:wwwroot/erp1.0/production/
    • 部署 stage:只有 deploy-staging 和 deploy-production

    完整的 .gitlab-ci.yml 示例

    include:
      - remote: 'https://gitee.com/dotnet-geek/gitlab-ci/raw/master/docker-deploy.yml'
      - project: 'deploy/env-config'
        ref: master
        file: 'docker/products/erp1.0-sales/all.yml'
    
    variables:
      PRODUCT_NAME: "erp1.0"
      COMPONENT_NAME: "Loda.Erp.Sales"
      DOCKERFILE_PATH: "src/Loda.Erp.Sales.Web/Dockerfile"
      DOCKER_IMAGE_REPO: "docker.lodatone.com/erp1.0-sales"
      CONTAINER_BASENAME: "erp1.0-sales"
      CONTAINER_PORT: "8080"
    
    # stages 会从 docker-deploy.yml 继承
    # - setup
    # - build
    # - push-nupkg
    # - update-version
    # - deploy-dev
    # - deploy-test
    # - deploy-staging
    # - deploy-production
    

    版本号文件结构

    开发环境

    wwwroot/erp1.0/development/
    ├── Directory.Build.props          # 包含所有组件的版本号
    ├── urls.txt                       # 所有 .props 文件的 URL 列表
    └── version-numbers/
        ├── Loda.Erp.Sales.props      # 2855.2026.104.12345
        ├── Loda.Erp.Purchase.props   # 2855.2026.103.12300
        └── ...
    

    生产环境

    wwwroot/erp1.0/production/
    ├── Directory.Build.props          # 包含所有组件的版本号
    ├── urls.txt                       # 所有 .props 文件的 URL 列表
    └── version-numbers/
        ├── Loda.Erp.Sales.props      # 2855.2026.104.12346
        ├── Loda.Erp.Purchase.props   # 2855.2026.103.12301
        └── ...
    

    优势总结

    1. 环境隔离:开发分支不会影响生产环境的版本号
    2. 并行开发:多个 feature 分支可以同时开发,共享开发环境的版本号
    3. 灵活部署:
      • 开发分支:自动部署到 dev,手动部署到 test
      • 生产分支:手动部署到 staging 和 production(安全考虑,需要人工确认)
    4. 版本追溯:每个环境都有独立的版本号历史
    5. 安全性:生产环境的部署必须手动触发

    注意事项

    1. 开发环境版本号更新频繁:每次 feature 分支推送都会更新
    2. 生产环境版本号稳定:只有 master/main/hotfix 分支才会更新
    3. 版本号独立演进:开发和生产环境的版本号各自独立,无需同步
    4. 分支命名规范:严格遵守分支命名规范,确保自动判断正确

    常见问题

    Q1: 为什么 staging 不自动部署?

    A: 出于安全考虑:

    • staging 是生产环境的镜像,是最后的质量关卡
    • 需要团队 leader 或 QA 人工确认后再部署
    • 防止未经验证的代码进入类生产环境

    如果你的团队有不同的流程,可以修改为自动部署:

    部署到准正式环境:
      when: on_success  # 改为自动部署
    

    Q2: 开发环境和生产环境的版本号是什么关系?

    A: 两个环境的版本号完全独立,各自演进:

    工作流程:

    1. 新功能开发时,必须从 master 分支创建 feature 分支
    2. feature 分支第一次构建时,会下载开发环境的 Directory.Build.props
    3. 这个开发环境的配置文件,最初应该是从生产环境复制过来的(手动初始化)
    4. 之后,开发环境和生产环境各自独立更新

    初始化开发环境(只需要做一次):

    # 在版本号服务器上执行(首次设置时)
    # 将生产环境的稳定版本复制到开发环境作为起点
    xcopy wwwroot\erp1.0\production\*.* wwwroot\erp1.0\development\ /E /I /Y
    

    之后的演进:

    • 开发环境:每次 feature 分支推送都会更新版本号(快速迭代)
    • 生产环境:只有 master 分支推送才会更新版本号(稳定版本)
    • 两者不需要再同步,各自独立

    Q3: 如果多个 feature 分支同时开发,版本号会冲突吗?

    A: 不会冲突,因为:

    • 每个分支推送时都会生成新的版本号(基于 pipeline ID)
    • 所有 feature 分支共享开发环境的版本号
    • 后推送的分支会使用最新的版本号
    • 这是正常的并行开发模式

    Q4: 开发分支部署,只需要 dev 和 test,不需要 staging 和 production 吗?这是最佳实践吗?

    A: 大多数团队的“默认最佳实践”确实是:

    • 开发分支(develop/feature/bugfix) 主要面向研发自测与联调,所以一般只需要 dev/test。
    • staging/production 更偏向“发布链路”,通常由 master/main/hotfix 触发。

    背后的行业共识是:

    • 环境职责清晰:dev/test 用于快速迭代;staging 用于发布前的最后验收;production 用于真实用户。
    • 风险隔离:feature 分支不应该占用发布资源/发布窗口,也不应该频繁污染 staging。
    • 权限与审计:staging/production 通常需要更严格的权限控制、审批和变更记录。

    但也有例外(不算“反常”):

    • 你希望每次合并到 develop 都自动部署到 staging 做持续验收(有专门的 QA 流程)。
    • 你们没有 staging,只用 test 充当准正式。

    所以它算是业界常见的默认实践,但不是唯一答案;关键是让环境的“职责”稳定、团队共识一致。

    Q5: master/main/hotfix 分支,就不需要 dev 和 test 了吗?这是最佳实践吗?

    A: 通常是的:

    • master/main/hotfix 代表“可发布”的稳定线,部署链路一般是 staging -> production。
    • dev/test 主要服务开发过程,master/main/hotfix 不一定需要再走一遍。

    不过这里有一个容易混淆的点:

    • master/main 的构建产物(镜像/包)仍然建议先部署到 staging 做一次最终验证。
    • dev/test 更像“开发过程环境”,staging/production 更像“发布过程环境”。

    如果你们想更严格,也可以要求 master/main 在进入 staging 前,必须保证:

    • MR/PR 已经在 feature 分支通过 dev/test 验证;
    • master/main pipeline 只做“复现式验证”(staging)+ “发布”。

    生产 Docker 回滚:如何优雅地通过流水线回滚到上一个版本?

    原则(最佳实践)

    1. 镜像不可变:生产环境部署必须使用不可变标识。

      • 推荐使用 镜像 digest(例如 repo@sha256:...),或者使用永不复用的 tag(例如 v2026.0104.12345 / ${CI_PIPELINE_ID})。
      • 不推荐用 latest 这种会漂移的 tag 作为生产部署依据。
    2. 回滚=重新部署一个“已知好的镜像”:生产回滚不做“源码回退再重发”,而是直接把服务切回上一个稳定镜像。

    3. 把“上一次成功部署的镜像标识”记录下来:

      • 记录到服务器(如 /data/<app>/last_successful_image.txt)
      • 或记录到版本号服务/配置仓库
      • 或记录到 GitLab Environment/Deployment(如果你们用 GitLab Environments)

    一种可落地的流水线方案(推荐)

    在生产部署 job 成功后:

    • 把本次部署使用的 IMAGE(tag 或 digest)写到远端服务器某个文件(例如:current_image.txt)
    • 同时把上一次的 current_image.txt 备份为 previous_image.txt

    当需要回滚时:

    • 触发一个 手动 job:回滚到上一个版本
    • 它读取 previous_image.txt,然后用该镜像重新 docker compose up -d 或 docker service update

    回滚 job 在流水线里的表现

    你可以提供两种回滚方式:

    • 回滚到上一个版本:无需输入参数(最常用)
    • 回滚到指定版本:手动输入 TARGET_IMAGE(应急时非常好用)

    注意事项

    • 回滚前最好先做一次健康检查确认“当前版本确实异常”。
    • 回滚成功后,建议把“故障版本”标记出来(例如打一个 Git tag 或在变更记录里写清楚)。
    • 如果你的部署模板目前没有“记录 current/previous 镜像”能力,那么需要在 docker/deploy.yml 中增加这段能力(这属于模板层的增强)。
    1 条回复 最后回复
    0
    • Z 离线
      Z 离线
      zhongfangxiong
      写于 最后由 编辑
      #2

      我在WindSurf里,设置了“全局规则”以后,IDE会自动为我准备完美git语句:

      image.png

      1 条回复 最后回复
      0
      • Z 离线
        Z 离线
        zhongfangxiong
        写于 最后由 编辑
        #3

        WindSurf自动感知/使用工作区的规则,为我生成了有Key的注释:

        image.png

        因为我更新(保存)了工作区的规则如下:

        image.png

        1 条回复 最后回复
        0
        • Z 离线
          Z 离线
          zhongfangxiong
          写于 最后由 编辑
          #4

          但是hotfix的代码,最终也是要合并到develop和master?

          是的,流程是这样的:

          • hotfix 分支代表紧急修复,通常从 master 切出(确保基准与线上一致)。
          • 完成修复后,先合并回 master(恢复线上),同时需要把同一修复再合并回 develop,否则开发分支缺少这次补丁,后续再从 develop 合回 master 时容易把修复覆盖掉。

          所以“最终 master 和 develop 都要包含 hotfix 的代码”是硬性要求,这样才能保持所有环境一致、避免回归。

          1 条回复 最后回复
          0
          • Z 离线
            Z 离线
            zhongfangxiong
            写于 最后由 编辑
            #5

            这个如何监管呢?感觉非常容易失控

            要防止 hotfix(或任何分支)漏合、乱合,可以用这几层手段来“硬管控”:

            1. CI 强校验(GitLab CI / Pipelines)

              • 在所有 MR Pipeline 里检查:
                • 分支名必须匹配 hotfix/<KEY>-...、feature/<KEY>-... 等;
                • Commit message 第一行含合法 Key;
                • MR 的目标分支符合策略(hotfix 指向 master,但合并后有后续任务指向 develop)。
              • 若校验不通过直接失败,阻止合并。
            2. Protected Branch + Merge Request 流程

              • 保护 master/develop 分支,只允许通过 MR(且 Pipeline 通过)才能合并;
              • 禁止直接 push到受保护分支;
              • 设定最少一名 Reviewer 审核,确保每次 hotfix 在 master 合并后,会马上安排一个“同步 develop”的 MR(可用模板提醒)。
            3. 自动化同步提醒

              • 在仓库里加脚本或机器人(如 GitLab Bot)检测 hotfix MR 合并后,若一定时间内没有对应 develop MR,就自动发提醒/创建 issue;
              • 或者把“同步 develop”写进 MR 模板、Checklist,审核人必须勾选才能通过。
            4. 分支策略文档化 + 周会 Review

              • 把流程写进规则(已经有),再结合例行的改动审查(如周会 review 最近 master 合并),一旦发现直接在 master 改动,就定位责任人并要求补齐流程,形成约束氛围。
            5. 工具辅助

              • 使用 GitLab Hooks/服务器端脚本,在 master 合并后自动检测是否存在同一 Key 的 develop MR,如果没有,自动创建任务/issue。
              • 若资源允许,可引入 “multi-target merge” 脚本:hotfix MR 合并 master 后自动触发一个脚本,把同一 commit cherry-pick 到 develop 并发 MR。

            只要 CI + 受保护分支 + 审核流程严格执行,再辅以提醒/自动化,就能把“确保 master/develop 都包含 hotfix”变成硬性要求,基本不会失控。

            1 条回复 最后回复
            0
            • Z 离线
              Z 离线
              zhongfangxiong
              写于 最后由 编辑
              #6

              Git 中常见的三种整合策略简单说明如下(都是把功能分支合进目标分支,只是历史呈现不同):

              1. Merge(普通合并)

                • 保留双方原始提交,再生成一个新的合并提交。
                • 优点:历史完整、不改写已有提交;缺点:分支图会出现分叉。
                • 场景:多人协作、需要保留完整记录时的默认做法。
              2. Rebase(变基)

                • 把功能分支的提交“搬到”目标分支最新提交之后,好像一直基于它开发。
                • 优点:历史呈线性,很干净;缺点:会改写提交哈希,容易引发冲突,不适合已推送共享的分支。
              3. Squash(压缩合并)

                • 把功能分支所有提交压成一个提交再合并。
                • 优点:目标分支历史简洁;缺点:功能分支内部的细节提交丢失,回溯困难。
                • 场景:功能分支提交非常琐碎、只想留一个总结提交时使用。

              如果你没有特别需求,建议直接使用 Merge,操作相对安全,也符合大多数团队习惯。
              下一步请告诉我要合并的功能分支是哪个(比如 feature/LT-94-friendly-timeout-error),我就按 Merge 流程帮你在 develop、master 分支各合并一次并提交。

              1 条回复 最后回复
              0
              回复
              • 在新帖中回复
              登录后回复
              • 从旧到新
              • 从新到旧
              • 最多赞同


              • 登录

              • 登录或注册以进行搜索。
              • 第一个帖子
                最后一个帖子
              0
              • 版块
              • 最新
              • 标签
              • 热门
              • 世界
              • 用户
              • 群组