跳轉到內容

Git 工作流與 CI/CD 集成實戰 2026 | 團隊協作完全指南

Git 工作流與 CI/CD 集成實戰

優秀的 Git 工作流和自動化 CI/CD 是團隊高效協作的基石。本文將系統講解主流 Git 工作流、分支策略、代碼審查規範,以及基於 GitHub Actions 的完整 CI/CD 流水線搭建。


一、主流 Git 工作流對比

1.1 Git Flow

main(生產環境)

develop(開發環境)

feature/*    release/*    hotfix/*

特點:

  • 嚴格的分支模型,適合版本發佈週期長的項目
  • 有明確的 maindevelopfeaturereleasehotfix 分支
  • 適合傳統軟件團隊,有明確版本號管理

適用場景: 大型企業項目、桌面軟件、有明確版本週期的產品

操作流程:

bash
# 1. 從 develop 創建功能分支
git checkout develop
git checkout -b feature/user-login

# 2. 開發完成後合併回 develop
git checkout develop
git merge --no-ff feature/user-login
git branch -d feature/user-login

# 3. 發佈版本
git checkout develop
git checkout -b release/1.2.0
# ... 修復 bug ...
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0

git checkout develop
git merge --no-ff release/1.2.0
git branch -d release/1.2.0

# 4. 緊急修復
git checkout main
git checkout -b hotfix/1.2.1
# ... 修復 ...
git checkout main
git merge --no-ff hotfix/1.2.1
git tag -a v1.2.1

git checkout develop
git merge --no-ff hotfix/1.2.1
git branch -d hotfix/1.2.1

1.2 GitHub Flow

main

feature/xxx  →  PR →  Code Review →  Merge

特點:

  • 簡單直接,只有 main 分支 + 功能分支
  • 通過 Pull Request 進行代碼審查
  • 適合持續部署,main 分支隨時可發佈
  • 是目前最流行的工作流

適用場景: Web 應用、SaaS 產品、持續部署項目

操作流程:

bash
# 1. 從 main 創建分支
git checkout main
git pull origin main
git checkout -b feature/new-dashboard

# 2. 提交代碼
git add .
git commit -m "feat: add new dashboard"

# 3. 推送到遠程
git push origin feature/new-dashboard

# 4. 創建 Pull Request
# 在 GitHub/GitLab 上操作

# 5. Code Review 通過後合併
# 使用 Squash merge 或 Merge commit

# 6. 刪除分支
git checkout main
git pull origin main
git branch -d feature/new-dashboard

1.3 Trunk-Based Development

main (trunk)

short-lived feature branches (max 1-2 days)

特點:

  • 所有人直接向主幹(main)提交
  • 功能分支生命週期極短(1-2 天)
  • 配合功能開關(Feature Flag)控制發佈
  • CI/CD 要求極高,必須有完善的自動化測試

適用場景: 高績效團隊、快速迭代產品、有完善測試體系的團隊

1.4 工作流對比

特性Git FlowGitHub FlowTrunk-Based
複雜度
分支數量
發佈頻率低(按版本)中(按 PR)高(持續部署)
代碼審查可選核心機制快速審查
回滾難度低(版本清晰)
適合團隊傳統企業團隊大多數團隊高績效團隊
CI 依賴度極高

二、分支命名規範

2.1 分支命名約定

<類型>/<描述>-<工單ID>

常用類型:

類型說明示例
feature/新功能feature/user-login-#123
fix/Bug 修復fix/login-error-#456
hotfix/緊急修復hotfix/payment-bug-#789
refactor/代碼重構refactor/auth-module
docs/文檔更新docs/api-update
style/格式調整style/format-code
perf/性能優化perf/query-optimization
chore/構建/工具chore/update-deps

2.2 提交信息規範(Conventional Commits)

<type>(<scope>): <subject>

<body>

<footer>

type 類型:

類型說明
feat新功能
fixBug 修復
docs文檔變更
style代碼格式(不影響功能)
refactor重構(非新功能也非修 bug)
perf性能優化
test測試相關
chore構建/工具/依賴
ciCI 配置

示例:

feat(auth): add OAuth2 login support

- 實現 Google/GitHub OAuth 登錄
- 添加登錄狀態持久化
- 增加登錄失敗錯誤提示

Closes #123
fix(api): handle empty response from user endpoint

當用戶未設置頭像時返回空字符串導致前端報錯,
現在返回默認頭像 URL。

Fixes #456

2.3 Commitlint 配置

javascript
// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [2, 'always', [
      'feat', 'fix', 'docs', 'style', 'refactor',
      'perf', 'test', 'chore', 'ci', 'build', 'revert'
    ]],
    'subject-case': [0],
    'subject-max-length': [2, 'always', 72]
  }
}
json
// package.json
{
  "scripts": {
    "prepare": "husky install"
  },
  "devDependencies": {
    "@commitlint/cli": "^19.0.0",
    "@commitlint/config-conventional": "^19.0.0",
    "husky": "^9.0.0"
  }
}
bash
# 安裝
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'

三、代碼審查(Code Review)

3.1 PR/MR 模板

markdown
<!-- pull_request_template.md -->

## 變更描述

<!-- 簡要描述本次變更的內容和目的 -->

## 類型

- [ ] feat: 新功能
- [ ] fix: Bug 修復
- [ ] docs: 文檔更新
- [ ] refactor: 代碼重構
- [ ] perf: 性能優化
- [ ] test: 測試補充
- [ ] chore: 構建/工具

## 關聯 Issue

<!-- Closes #123 -->

## 測試

- [ ] 單元測試通過
- [ ] 集成測試通過
- [ ] E2E 測試通過
- [ ] 已在測試環境驗證

## 截圖/錄屏

<!-- 如有 UI 變更,請附上截圖 -->

## 注意事項

<!-- 部署注意事項、數據庫遷移等 -->

3.2 代碼審查清單

審查者檢查清單:

3.3 審查禮儀

  • 對事不對人:評論代碼,不評論人
  • 提供建議而非命令:用「建議」「可以考慮」代替「必須」
  • 明確優先級:區分「必須修改」和「可選改進」
  • 及時響應:收到審查請求後儘快處理
  • 小步提交:PR 不要太大,控制在 400 行以內

四、GitHub Actions CI/CD

4.1 基礎 CI 流水線

yaml
# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v3
        with:
          version: 9

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Lint
        run: pnpm lint

      - name: Type check
        run: pnpm typecheck

      - name: Test
        run: pnpm test -- --coverage

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

4.2 構建並部署到 GitHub Pages

yaml
# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v3
        with:
          version: 9

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - run: pnpm install --frozen-lockfile
      - run: pnpm build

      - uses: actions/configure-pages@v5
      - uses: actions/upload-pages-artifact@v3
        with:
          path: dist

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - id: deployment
        uses: actions/deploy-pages@v4

4.3 Docker 構建與推送

yaml
# .github/workflows/docker.yml
name: Docker Build

on:
  push:
    tags: ['v*']
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=sha

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

4.4 矩陣測試

yaml
# .github/workflows/test-matrix.yml
name: Test Matrix

on: [push, pull_request]

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node-version: [18, 20, 22]
        exclude:
          - os: windows-latest
            node-version: 18

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'pnpm'

      - name: Install
        run: pnpm install --frozen-lockfile

      - name: Test
        run: pnpm test

4.5 自動發佈 npm 包

yaml
# .github/workflows/release.yml
name: Release

on:
  push:
    tags: ['v*']

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v3
        with:
          version: 9

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'
          registry-url: 'https://registry.npmjs.org'

      - run: pnpm install --frozen-lockfile
      - run: pnpm build

      - name: Publish
        run: pnpm publish --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true

五、高級 CI/CD 配置

5.1 緩存優化

yaml
# 依賴緩存
- uses: actions/cache@v4
  with:
    path: |
      ~/.pnpm-store
      **/node_modules
    key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
    restore-keys: |
      ${{ runner.os }}-pnpm-

# 構建緩存(Vite)
- uses: actions/cache@v4
  with:
    path: .vite
    key: ${{ runner.os }}-vite-${{ hashFiles('**/vite.config.*') }}
    restore-keys: |
      ${{ runner.os }}-vite-

5.2 條件執行

yaml
jobs:
  test:
    runs-on: ubuntu-latest
    if: |
      github.event_name == 'pull_request' ||
      contains(github.event.head_commit.message, '[ci]')
    steps:
      - uses: actions/checkout@v4
      # ...

  deploy-staging:
    runs-on: ubuntu-latest
    needs: [test]
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy to Staging
        run: echo "Deploying..."

5.3 環境變量與 Secrets

yaml
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production  # 環境保護規則
    env:
      API_URL: ${{ vars.API_URL }}
      DB_HOST: ${{ secrets.DB_HOST }}
    steps:
      - run: echo "$API_URL"

5.4 手動觸發

yaml
on:
  workflow_dispatch:
    inputs:
      environment:
        description: '部署環境'
        required: true
        default: 'staging'
        type: choice
        options:
          - staging
          - production
      version:
        description: '版本號'
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - run: |
          echo "部署到: ${{ github.event.inputs.environment }}"
          echo "版本: ${{ github.event.inputs.version }}"

六、Git 高級技巧

6.1 交互式變基

bash
# 合併多個提交
git rebase -i HEAD~5

# 常用操作:
# p, pick = 使用該提交
# s, squash = 合併到前一個提交
# f, fixup = 合併到前一個提交(丟棄提交信息)
# r, reword = 修改提交信息
# e, edit = 編輯該提交
# d, drop = 刪除該提交

6.2 Cherry-pick

bash
# 挑選某個提交應用到當前分支
git cherry-pick <commit-hash>

# 挑選多個提交
git cherry-pick <commit1> <commit2>

# 挑選一個範圍
git cherry-pick <start>..<end>

6.3 Bisect 二分查找 Bug

bash
# 開始二分查找
git bisect start

# 標記當前版本為壞
git bisect bad

# 標記某個版本為好
git bisect good v1.0.0

# 測試當前版本,標記好/壞
git bisect good   # 好版本
git bisect bad    # 壞版本

# 找到引入 bug 的提交後,結束
git bisect reset

6.4 工作暫存

bash
# 暫存當前工作
git stash push -m "wip: user login"

# 查看暫存列表
git stash list

# 應用最新暫存
git stash pop

# 應用指定暫存
git stash apply stash@{1}

# 刪除暫存
git stash drop stash@{0}

# 清空所有暫存
git stash clear

七、團隊協作最佳實踐

7.1 保護主分支

yaml
# GitHub 分支保護規則建議
# Settings → Branches → Branch protection rules

Branch name pattern: main

✅ Require a pull request before merging
   ✅ Require approvals: 1

✅ Require status checks to pass before merging
   ✅ Require branches to be up to date before merging
   Status checks: lint, test, build

✅ Require signed commits
✅ Require linear history
✅ Include administrators

7.2 Git 配置建議

bash
# 全局配置
git config --global user.name "Your Name"
git config --global user.email "your@email.com"

# 默認推送當前分支
git config --global push.default current

# 拉取時自動變基(避免無謂的 merge commit)
git config --global pull.rebase true

# 自動設置上游分支
git config --global push.autoSetupRemote true

# 設置默認分支名
git config --global init.defaultBranch main

# 換行符處理
git config --global core.autocrlf input  # macOS/Linux
git config --global core.autocrlf true   # Windows

# 編輯器
git config --global core.editor "code --wait"

7.3 .gitignore 最佳實踐

gitignore
# Dependencies
node_modules/
.pnp
.pnp.js

# Build output
dist/
build/
.next/
.nuxt/

# Environment files
.env
.env.local
.env.*.local

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Logs
logs/
*.log
npm-debug.log*

# Testing
coverage/
.nyc_output/

# Cache
.cache/
.parcel-cache/
.turbo/

八、總結

  • ✅ 掌握三種主流 Git 工作流(Git Flow、GitHub Flow、Trunk-Based)
  • ✅ 規範的分支命名與 Conventional Commits 提交規範
  • ✅ 代碼審查流程與審查清單
  • ✅ GitHub Actions 完整 CI/CD 流水線(測試、構建、部署、Docker)
  • ✅ 高級 CI/CD 配置(緩存、條件執行、環境變量、手動觸發)
  • ✅ Git 高級技巧(變基、cherry-pick、bisect、stash)
  • ✅ 團隊協作最佳實踐(分支保護、Git 配置、.gitignore)

優秀的 Git 工作流和 CI/CD 不是一蹴而就的,需要根據團隊規模和項目特點持續迭代優化。


相關閱讀:

最後更新於: