一、 引言

在现代软件工程中,高效、稳定且可追溯的交付流程是企业研发效能的核心支柱。GitFlow 作为一种成熟的分支管理模型,为团队协作与版本控制提供了清晰的规范;而全链路 CI/CD 自动化则通过无缝串联代码提交、构建、测试、部署等环节,显著提升了交付速度与质量。本文结合企业级实战经验,探讨如何基于 GitFlow 构建端到端的自动化流水线,实现从需求开发到生产上线的闭环管理。

二、 GitFlow 常用分支

分支定义与说明

分支名 说明 来源分支 合并目标 生命周期
main 生产分支。存放线上最稳定的代码。禁止直接提交代码,仅接受从 release 或 hotfix 分支的合并。每个合并点应打上版本 Tag。 - - 永久存在
develop 开发主分支。功能开发的集成地。包含所有即将进入下一个发布周期的代码。合并时触发 SAST 扫描与开发环境集成。 main - 永久存在
feature/* 新功能分支。基于新需求创建。开发完成后需通过 SAST 静态测试,通过 PR/MR 形式合并回 develop 分支。 develop develop 任务完成即删除
release/* 预发布分支。发版前准备。在此分支触发 K8s 测试环境 部署。仅允许 Bug 修复(fix/*)及元数据修改,严禁合并新功能。 develop main, develop 发版成功后删除
hotfix/* 紧急修复分支。用于修复线上(main)发现的紧急 Bug。修复后需同时合并回 main 和 develop,确保代码同步。 main main, develop 修复上线后删除

三、 GitFlow + CI/CD 自动化全流程

接下来我们以一个简单的例子介绍整个自动化实践,假设我现在要开发一个新功能。

准备阶段

项目中维护 main 与 develop 两条主干。 要开发新功能时,需基于最新的 develop 分支切出一个特性分支:feature/xxx

# 切换到 develop 分支
git checkout develop

# 拉取develop分支最新的代码
git pull origin develop

# 基于 develop 检出新分支 (推荐命名规范: feature/功能描述)
git checkout -b feature/xxx

在这里插入图片描述

开发阶段

feature分支下进行代码编写与迭代,写代码 -> 暂存 -> 提交。建议保持高频提交,并在推送前同步主干代码。

# 将变更添加到暂存区
git add .

# 提交到本地仓库
git commit -m "feat: xxx"

# 推送前建议先拉取 develop 分支更新(避免合并冲突)
git pull origin develop

# 推送到远程仓库
git push -u origin feature/xxx

在这里插入图片描述

代码评审与合并

功能开发完成后,发起 Merge Request (MR) / Pull Request (PR)。

  • 前置检查:CI 流水线自动运行 SAST
  • 人工评审:指定 Reviewer(如组长或同事)进行代码审查
  • 合并:评审通过后,代码被合并入 develop 分支。合并成功后,通常删除远程及本地的 feature 分支。
    在这里插入图片描述

提测与预发布

当一组功能开发完毕,准备进入集成测试阶段时,从 develop 分支检出 release 分支。

注意:此分支进入“封版”状态,只修 Bug,不加新功能。

# 确保 develop 是最新的
git checkout develop
git pull origin develop

# 新建分支
git checkout -b release/v1.1.0

# 推送到远程,触发测试环境 CI/CD
git push origin release/v1.1.0

自动化动作:推送 release 分支将触发 CI/CD pipeline:

  • 构建测试镜像(:test-${CI_COMMIT_SHORT_SHA} 将commit hash作为 tag)
  • 推送镜像至 Harbor 仓库
  • 调用 API 自动更新 K8s 测试环境 Deployment

在这里插入图片描述

CI/CD 配置参考 (.gitlab-ci.yml)

stages:
- test
- build
- deploy

variables:
  HARBOR_URL: xxx
  SERVICE_NAME: xxx
  IMAGE_FULL_NAME: "${HARBOR_URL}/xxx/${SERVICE_NAME}"
before_script:
- export IMAGE_TAG="$CI_COMMIT_TAG"
- echo "Current IMAGE_TAG is:$IMAGE_TAG"

include:
- template: Security/SAST.gitlab-ci.yml

.sast-analyzer:
  tags:
  - xxx
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

build_image:
  stage: build
  image:
    name: docker:29.1.2
    pull_policy: if-not-present
  script:
  - unset DOCKER_AUTH_CONFIG
  - export DOCKER_HOST=unix:///var/run/docker.sock
  - echo "Logging into Harbor..."
  - docker login -u "$HARBOR_USERNAME" -p "$HARBOR_PASSWORD" "$HARBOR_URL"
  - echo "Building Docker image..."
  - docker build -t "${IMAGE_FULL_NAME}:${IMAGE_TAG}" .
  - echo "Pushing Docker image..."
  - docker push "${IMAGE_FULL_NAME}:${IMAGE_TAG}"
  only:
  - tags
  tags:
  - xxx
deploy_k8s:
  stage: deploy
  image: curlimages/curl:8.11.1
  script:
  - echo "Deploying to Kubernetes via Kuboard API..."
  - |
    curl -X PUT \
    -H "content-type: application/json" \
    -H "Cookie: KuboardUsername=$KUBOARD_USERNAME; KuboardAccessKey=$KUBOARD_ACCESS_KEY" \
    -d "{\"kind\":\"deployments\",\"namespace\":\"xxx\",\"name\":\"${SERVICE_NAME}\",\"images\":{\"${IMAGE_FULL_NAME}\":\"${IMAGE_FULL_NAME}:${IMAGE_TAG}\"}}" \
    "xxx"
  only:
  - tags
  tags:
  - xxx

build_test_image:
  stage: build
  image:
    name: docker:29.1.2
    pull_policy: if-not-present
  script:
  - unset DOCKER_AUTH_CONFIG
  - export DOCKER_HOST=unix:///var/run/docker.sock
  - export TEST_IMAGE_TAG="test-${CI_COMMIT_SHORT_SHA}"
  - echo "Logging into Harbor..."
  - docker login -u "$HARBOR_USERNAME" -p "$HARBOR_PASSWORD" "$HARBOR_URL"
  - echo "Building Docker image for TEST..."
  - docker build -t "${HARBOR_URL}/xxx/xxx-test:${TEST_IMAGE_TAG}" .
  - echo "Pushing Docker image for TEST..."
  - docker push "${HARBOR_URL}/xxx/xxx-test:${TEST_IMAGE_TAG}"
  only:
  - /^release\/.*$/
  tags:
  - xxx

deploy_test_k8s:
  stage: deploy
  image: curlimages/curl:8.11.1
  script:
  - export TEST_IMAGE_TAG="test-${CI_COMMIT_SHORT_SHA}"
  - echo "Deploying TEST to Kubernetes via Kuboard API with tag ${TEST_IMAGE_TAG}..."
  - |
    curl -X PUT \
    -H "content-type: application/json" \
    -H "Cookie: KuboardUsername=$KUBOARD_USERNAME; KuboardAccessKey=$KUBOARD_ACCESS_KEY" \
    -d "{\"kind\":\"deployments\",\"namespace\":\"xxx\",\"name\":\"xxx\",\"images\":{\"xxx\":\"xxx:${TEST_IMAGE_TAG}\"}}" \
    "xxx"
  only:
  - /^release\/.*$/
  tags:
  - xxx

正式发版

测试通过后,进入正式发版流程:

  1. 发起 MR 将 release 分支合并入 main 分支(触发 SAST + 再次代码审核)。
  2. 合并完成后,在 main 分支上打上版本 Tag(如 v1.1.0)。
  3. GitLab CI 监测到 Tag 推送,触发正式环境的构建与部署流程(见上文 YAML 中的 only: - tags 部分)。
  4. 回填(Merge back):将 release 分支代码回填到 develop 分支,确保开发线包含最新的修复和版本信息。
  5. 删除 release 分支。

在这里插入图片描述

线上紧急修复 (Hotfix)

若正式环境(Main分支)发现紧急 Bug,需启动 Hotfix 流程:

  1. 从 main 分支检出 hotfix 分支(如 hotfix/v1.1.1)。
  2. 修复 Bug 并验证。
  3. 将 hotfix 分支合并回 main,并打上新的 Tag(触发正式环境 CI/CD 进行自动修复上线)。
  4. 将 hotfix 分支回填到 develop 分支,防止 Bug 在下个版本复发。
  5. 删除 hotfix 分支。

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐