Github Repositories 建立與維運教學手冊 — 企業級實戰指南

版本:v2.0(2026-05-08)
適用對象:技術主管 / 架構師 / 資深工程師 / DevOps 團隊 / 專案經理
定位:企業標準技術白皮書
參考標準:GitHub Docs(2026) / GitHub Enterprise Best Practices / DevSecOps / SSDLC
最後審閱日期:2026-05-08
變更紀錄:v2.0 — 新增 Repository 限制與配額、Rulesets 深入指南、Merge Queue、Git LFS、Codespaces、Packages、Private Vulnerability Reporting 等章節;全面校閱並對齊 GitHub 官方文件(2026 年版)


閱讀指引

本手冊涵蓋 GitHub Repository 從建立到維運的完整生命週期,依讀者角色建議閱讀路徑:

角色建議章節重點
開發工程師第 4、5、6、7、8 章Repository 建立、Git 操作、Branch 策略、CI/CD
架構師第 2、5、9、13、16 章管理架構、標準結構、DevSecOps、AI 整合、企業範例
DevOps 工程師第 7、8、9、12、14 章Branch 策略、Actions、安全、Release、維運
技術主管 / PM第 2、3、11、14、15 章管理架構、Organization、Issue 管理、治理、企業實踐
資安人員第 9、14、15 章DevSecOps、SSDLC、維運治理、合規

⚠️ 標記說明:本文中 ⚠️ 需 GitHub Enterprise 表示該功能僅在 GitHub Enterprise Cloud / Server 版本可用。


目錄


第 1 章 GitHub Repositories 概述

1.1 GitHub Repositories 是什麼

GitHub Repository(簡稱 Repo)是 GitHub 平台上的版本控制儲存庫,基於 Git 分散式版本控制系統。它不僅是存放程式碼的空間,更是整個軟體開發生命週期的核心協作平台。

核心能力

  • 版本控制:追蹤每一次變更的完整歷史
  • 協作開發:支援多人並行開發、Code Review、Pull Request
  • 自動化:透過 GitHub Actions 實現 CI/CD、安全掃描、自動部署
  • 專案管理:Issues、Projects、Milestones 整合敏捷開發
  • 安全性:Secret Scanning、Dependabot、CodeQL、GHAS
  • 文件管理:Wiki、GitHub Pages、README 生態系

1.2 Repository 用途與類型

用途分類說明範例
Source Code應用程式原始碼backend-apifrontend-web
InfrastructureIaC / 部署配置infra-terraformk8s-manifests
Documentation技術文件 / ADRdocs-architectureapi-specs
Template專案範本template-spring-boottemplate-vue
CI/CD Workflows可重用 Workflowshared-workflowsgithub-actions
AI AssetsPrompt / Agent / Instructionsai-assetsprompt-library
Configuration組織級設定.github(Organization 特殊 Repo)

1.3 Public vs Private vs Internal

類型可見性適用場景費用考量
Public所有人可見開源專案、公開文件免費(含 Actions 額度)
Private僅組織成員Source Code、內部工具需付費(依方案)
Internal組織內所有成員共用工具、規範文件⚠️ 需 GitHub Enterprise

企業建議:預設使用 Private,共用規範類使用 Internal,嚴禁將機密程式碼設為 Public。

1.4 適合管理哪些內容

適合放入 Repository 的內容

  • ✅ 原始碼(Source Code)
  • ✅ 設定檔(Configuration)
  • ✅ Infrastructure as Code
  • ✅ 技術文件(Markdown / AsciiDoc)
  • ✅ API 規格(OpenAPI / Protobuf)
  • ✅ 測試程式與測試資料
  • ✅ CI/CD Pipeline 定義
  • ✅ Database Migration Scripts
  • ✅ AI Prompt Templates

不適合放入 Repository 的內容

  • ❌ 密碼 / API Key / Token(使用 GitHub Secrets)
  • ❌ 大型二進制檔案 > 100MB(使用 Git LFS)
  • ❌ Build 產出物(使用 GitHub Packages / Artifact)
  • ❌ 生產環境資料庫備份
  • ❌ 個人識別資訊(PII)

1.5 GitHub 生態系總覽

graph TB
    subgraph "GitHub Platform"
        REPO[Repository] --> ACTIONS[GitHub Actions
CI/CD 自動化] REPO --> SECURITY[Security
GHAS / Dependabot / CodeQL] REPO --> PROJECTS[Projects
專案管理] REPO --> PACKAGES[Packages
套件發佈] REPO --> PAGES[Pages
靜態網站] REPO --> WIKI[Wiki
文件協作] REPO --> DISCUSSIONS[Discussions
社群討論] REPO --> COPILOT[Copilot
AI 輔助開發] end subgraph "開發工具整合" VSCODE[VS Code] --> REPO CLI[GitHub CLI] --> REPO DESKTOP[GitHub Desktop] --> REPO CODESPACE[Codespaces] --> REPO end subgraph "企業治理" ORG[Organization] --> TEAM[Teams] ORG --> RBAC[RBAC 權限] ORG --> AUDIT[Audit Log] ORG --> POLICY[Policy / Ruleset] end

實務建議:企業應將 GitHub 視為「開發平台」而非僅是「程式碼倉庫」,充分利用 Actions、Security、Projects 等功能建立完整的開發生態系。

1.6 Repository 限制與配額

GitHub 對 Repository 設有明確的效能與容量限制,企業在規劃架構時須將這些限制納入考量,避免因超出上限導致效能下降或操作受阻。

儲存庫大小與結構限制

限制項目建議上限強制上限影響與說明
Repository 磁碟大小1 GB10 GB超過後 clone / fetch 速度明顯下降,應使用 Git LFS 管理大型二進制檔
單一檔案大小1 MB100 MB超過 100 MB 將被 GitHub 拒絕 Push;需改用 Git LFS
單一目錄檔案數3,000過多檔案會增加 Git 維護成本並降低效能
目錄深度50 層過深的目錄結構會拖慢歷史走訪操作
Branch 數量5,000過多分支會導致 fetch 傳輸緩慢
Tag 數量5,000與 Branch 同理

操作頻率限制

操作類型建議上限說明
Push 大小強制上限 2 GB
Git 讀取操作15 次/秒/RepoCI 大量讀取可能觸發限流,建議使用 shallow clone
Push 頻率6 次/分鐘/Repo超過可能被暫時限流
PR 合併頻率1 次/分鐘每次合併觸發所有開啟 PR 的合併檢查
同一分支開啟 PR1,000超過會導致合併檢查延遲

Diff 與 Commit 限制

項目限制值
PR 總 Diff 行數20,000 行可載入,或 1 MB 原始資料
單一檔案 Diff20,000 行,或 500 KB
單一 Diff 檔案數300 個檔案
可渲染檔案數(圖片、PDF)25 個
Commit 列表顯示上限250 筆(PR / Compare 頁面)
Commits 頁籤上限10,000 筆
Rebase & Merge100 筆 commit

帳號與組織限制

項目限制值
每個帳號/組織 Repository 數100,000(50,000 時開始警告)
每個 Repository Rulesets 數75
組織層級 Rulesets 數75

企業建議

  • Repository 大小控制在 1 GB 以內,超過即檢視是否有大型檔案應移至 Git LFS
  • CI/CD 使用 --depth 1 淺層 clone 減少讀取負擔
  • 定期清理已合併分支,保持 Branch 數量在合理範圍
  • 大型 Monorepo 需特別注意 Diff 限制,可能影響 PR Review 體驗

1.7 GitHub 方案與功能比較

根據團隊規模與需求選擇適合的 GitHub 方案:

功能FreeTeamEnterprise Cloud
Public Repos✅ 無限✅ 無限✅ 無限
Private Repos✅ 無限✅ 無限✅ 無限
Collaborators(Private)有限✅ 無限✅ 無限
GitHub Actions 分鐘2,000/月3,000/月50,000/月
Packages Storage500 MB2 GB50 GB
Branch Protection✅ Public
Repository Rulesets✅ Public✅ + Org-level
Push Rulesets
CODEOWNERS
Required Reviews✅ Public
Draft PRs
Merge Queue
GitHub Pages✅ Public
Environments✅ Public
Dependabot Alerts
Secret Scanning✅ Public✅ + Custom Patterns
Push Protection✅ Public
CodeQL✅ Public
Security Overview
SAML SSO
SCIM Provisioning
Audit Log API
Internal Repos
Custom Repo Roles
IP Allow List

企業建議:中大型企業建議直接選擇 Enterprise Cloud,獲得完整的安全功能(GHAS)、合規工具(Audit Log)、身分管理(SSO/SCIM)與組織治理(Rulesets / Custom Roles)。小型團隊可從 Team 方案起步,視需求升級。


第 2 章 企業 Repository 管理架構

2.1 Enterprise Repository Strategy

企業級 Repository 管理需要系統性的分層策略,確保數百個 Repository 有序管理。

graph TB
    subgraph "Enterprise GitHub Organization"
        direction TB
        L1[Layer 1: Platform
共用平台 / 框架 / 工具] L2[Layer 2: Domain
業務領域 / 微服務] L3[Layer 3: Application
應用程式 / 前端] L4[Layer 4: Infrastructure
IaC / 部署 / 監控] L5[Layer 5: Documentation
文件 / 規範 / AI 資產] end L1 --> L2 L2 --> L3 L3 --> L4 L4 --> L5 subgraph "橫向支援" T1[Template Repos] T2[Shared Workflows] T3[Security Policies] end T1 -.-> L2 T2 -.-> L3 T3 -.-> L4

分層說明

Layer定位變更頻率權限範例
Platform共用基礎設施核心架構團隊platform-coreshared-lib
Domain業務微服務各業務團隊svc-ordersvc-payment
Application前端應用前端團隊app-customer-portalapp-admin
Infrastructure部署配置DevOps 團隊infra-k8sinfra-terraform
Documentation文件規範全體docs-architectureai-assets

2.2 Monorepo vs Polyrepo

面向MonorepoPolyrepo
定義多個專案在同一 Repo每個專案獨立 Repo
適用強耦合微服務、前端 Monorepo獨立部署服務、跨團隊專案
優點原子性變更、共用程式碼容易獨立部署、權限隔離、CI 獨立
缺點CI 複雜、權限粗糙、Repo 肥大共用程式碼困難、版本同步成本
CI/CD需 path filter / affected detection獨立 Pipeline
工具Nx、Turborepo、BazelGitHub Actions per repo
企業建議同一團隊緊密協作的服務群跨團隊、不同部署週期的服務

企業建議:大多數企業採用「混合策略」— 以 Polyrepo 為主,特定領域(如前端 Micro-frontend)使用 Monorepo。

2.3 Repository 命名規範

命名格式{layer}-{domain}-{type}-{name}

# 範例
platform-java-lib-core          # 平台層 Java 核心庫
svc-order-api                    # 業務服務:訂單 API
svc-payment-worker               # 業務服務:支付 Worker
app-customer-portal              # 應用層:客戶入口
app-admin-dashboard              # 應用層:管理後台
infra-k8s-manifests              # 基礎設施:K8s 配置
infra-terraform-aws              # 基礎設施:Terraform
docs-architecture                # 文件:架構文件
docs-api-specs                   # 文件:API 規格
tmpl-spring-boot                 # 範本:Spring Boot
tmpl-vue-app                     # 範本:Vue 應用
wf-shared-actions                # Workflow:共用 Actions
ai-prompt-library                # AI:Prompt 庫

命名規則

  1. 全部小寫,使用 - 連接
  2. 不超過 50 字元
  3. 禁止使用底線 _、空格、中文
  4. 前綴表示分層(svc- / app- / infra- / docs- / tmpl- / wf- / ai-
  5. 包含語意,讀名稱即知用途

2.4 Team Repository Strategy

graph LR
    subgraph "Organization: company-dev"
        subgraph "Team: backend-core"
            R1[platform-java-lib-core]
            R2[svc-order-api]
            R3[svc-payment-api]
        end
        subgraph "Team: frontend"
            R4[app-customer-portal]
            R5[app-admin-dashboard]
        end
        subgraph "Team: devops"
            R6[infra-k8s-manifests]
            R7[wf-shared-actions]
        end
        subgraph "Team: architecture"
            R8[docs-architecture]
            R9[ai-prompt-library]
        end
    end

2.5 Environment Strategy

環境Branch部署觸發用途
DevelopmentdevelopPush to develop開發測試
Stagingrelease/*PR merged to releaseUAT / 整合測試
ProductionmainManual approval + Tag正式環境
# GitHub Environments 設定範例
environments:
  development:
    protection_rules: []
  staging:
    protection_rules:
      - required_reviewers: 1
    deployment_branch_policy:
      protected_branches: true
  production:
    protection_rules:
      - required_reviewers: 2
      - wait_timer: 30  # 30 分鐘冷卻期
    deployment_branch_policy:
      custom_branch_policies:
        - "main"
        - "hotfix/*"

實務建議:Production 環境務必設定至少 2 人審核 + 等待時間,並限制可部署的分支。


第 3 章 公司 GitHub Organization 規劃

3.1 Organization 建立

建立步驟

  1. 前往 https://github.com/organizations/plan
  2. 選擇方案(建議 GitHub Enterprise Cloud)
  3. 填寫組織名稱(如 acme-bank
  4. 設定 Organization Profile

Organization 設定建議

設定項目建議值說明
Default repository permissionNone最小權限原則
Repository creationDisabled for members集中管控 Repo 建立
Two-factor authenticationRequired強制 2FA
Base permissionsNone透過 Team 授權
Fork policyDisabled禁止 Fork(企業內部)
Actions permissionsSelected repositories限制 Actions 使用範圍
Dependabot alertsEnabled for all全面啟用弱點告警

3.2 Team 建立與管理

建議團隊結構

organization: acme-bank
├── team: org-admins              # 組織管理員(2-3人)
├── team: security-team           # 資安團隊
├── team: architecture-team       # 架構團隊
├── team: devops-team             # DevOps 團隊
├── team: backend-core            # 後端核心團隊
│   ├── team: backend-order       # 訂單子團隊
│   └── team: backend-payment     # 支付子團隊
├── team: frontend-team           # 前端團隊
├── team: qa-team                 # QA 團隊
└── team: docs-team               # 文件團隊

Team 權限對應

# 使用 GitHub CLI 建立 Team
gh api orgs/acme-bank/teams -f name="backend-core" \
  -f description="後端核心開發團隊" \
  -f privacy="closed" \
  -f notification_setting="notifications_enabled"

# 賦予 Team Repository 權限
gh api orgs/acme-bank/teams/backend-core/repos/acme-bank/svc-order-api \
  -X PUT -f permission="push"

3.3 權限設計與 RBAC

角色Repository 權限適用對象
Admin完整管理權限org-admins
Maintain管理 Issues/PR + Push(不可刪 Repo)Tech Lead
Write (Push)Push + 建立 Branch + 管理 Issues開發人員
Triage管理 Issues/PR(不可 Push)PM / QA
Read唯讀跨團隊參考

Custom Repository Roles ⚠️ 需 GitHub Enterprise:

{
  "name": "senior-developer",
  "description": "資深開發者 - 可 Push + 管理 Branch + 審核 PR",
  "base_role": "write",
  "permissions": [
    "delete_alerts_code_scanning",
    "manage_deploy_keys",
    "bypass_branch_protections"
  ]
}

3.4 Repository Governance

Repository Rulesets ⚠️ 需 GitHub Enterprise:

# Organization-level Ruleset
name: "enterprise-branch-protection"
target: branch
enforcement: active
conditions:
  ref_name:
    include: ["~DEFAULT_BRANCH", "release/*"]
rules:
  - type: required_pull_request
    parameters:
      required_approving_review_count: 2
      dismiss_stale_reviews_on_push: true
      require_code_owner_review: true
      require_last_push_approval: true
  - type: required_status_checks
    parameters:
      strict_required_status_checks_policy: true
      required_status_checks:
        - context: "ci/build"
        - context: "ci/test"
        - context: "security/codeql"
  - type: required_signatures
  - type: non_fast_forward

3.5 Repository Lifecycle

stateDiagram-v2
    [*] --> Proposed: 提出需求
    Proposed --> Approved: 架構審查通過
    Approved --> Active: 建立 Repository
    Active --> Maintained: 穩定維護
    Maintained --> Deprecated: 標記棄用
    Deprecated --> Archived: 封存
    Archived --> [*]: 刪除(極少)
    
    Active --> Active: 持續開發
    Maintained --> Active: 重大改版

各階段管控

階段動作負責人產出
Proposed填寫 Repo 申請表申請人Issue (Repo Request)
Approved架構審查 + 命名確認架構師Approval Comment
Active建立 Repo + 初始化DevOps完整 Repo 結構
Maintained定期更新依賴 + 安全修補維護團隊Dependabot PRs
Deprecated加入 Deprecated 標記架構師README 警告
Archived設定 Archive + 唯讀AdminArchived Repo

實務建議:每季進行一次 Repository 盤點,識別長期無活動(> 6 個月無 commit)的 Repo,評估是否進入 Deprecated 流程。


第 4 章 如何建立 Repository

4.1 建立 Repository 完整流程

方法一:GitHub Web UI

  1. 登入 GitHub → Organization 頁面
  2. 點選 New Repository
  3. 設定:
    • Owner: acme-bank
    • Repository name: svc-order-api
    • Description: 訂單服務 API - Spring Boot
    • Visibility: Private
    • Initialize: ✅ Add a README
    • .gitignore: Java
    • License: 依公司政策

方法二:GitHub CLI(推薦)

# 從 Template 建立(推薦)
gh repo create acme-bank/svc-order-api \
  --template acme-bank/tmpl-spring-boot \
  --private \
  --description "訂單服務 API - Spring Boot" \
  --clone

# 或空白建立
gh repo create acme-bank/svc-order-api \
  --private \
  --description "訂單服務 API" \
  --gitignore Java \
  --license Apache-2.0

方法三:Terraform(IaC 管理)

resource "github_repository" "svc_order_api" {
  name         = "svc-order-api"
  description  = "訂單服務 API - Spring Boot"
  visibility   = "private"
  
  has_issues      = true
  has_projects    = true
  has_wiki        = false
  has_downloads   = false
  
  allow_merge_commit = false
  allow_squash_merge = true
  allow_rebase_merge = false
  
  delete_branch_on_merge = true
  
  template {
    owner      = "acme-bank"
    repository = "tmpl-spring-boot"
  }

  vulnerability_alerts = true
}

resource "github_branch_protection" "main" {
  repository_id = github_repository.svc_order_api.node_id
  pattern       = "main"
  
  required_pull_request_reviews {
    required_approving_review_count = 2
    require_code_owner_reviews      = true
    dismiss_stale_reviews           = true
  }
  
  required_status_checks {
    strict   = true
    contexts = ["ci/build", "ci/test", "security/scan"]
  }
  
  enforce_admins = true
}

4.2 README 設計

# svc-order-api

> 訂單服務 API — 處理訂單建立、查詢、修改、取消等核心業務邏輯

[![CI](https://github.com/acme-bank/svc-order-api/actions/workflows/ci.yml/badge.svg)](https://github.com/acme-bank/svc-order-api/actions/workflows/ci.yml)
[![Security](https://github.com/acme-bank/svc-order-api/actions/workflows/security.yml/badge.svg)](https://github.com/acme-bank/svc-order-api/actions/workflows/security.yml)

## 快速開始

### 前置需求
- Java 21+
- Maven 3.9+
- Docker(for integration tests)

### 本地啟動
\```bash
git clone git@github.com:acme-bank/svc-order-api.git
cd svc-order-api
mvn spring-boot:run -Dspring.profiles.active=local
\```

### 執行測試
\```bash
mvn verify
\```

## 技術棧
| 項目 | 版本 |
|------|------|
| Java | 21 |
| Spring Boot | 3.4.x |
| Database | PostgreSQL 16 |
| Message Queue | Kafka 3.x |

## API 文件
- Swagger UI: `http://localhost:8080/swagger-ui.html`
- OpenAPI Spec: `docs/openapi.yaml`

## 聯絡人
- Tech Lead: @john-doe
- Team: @acme-bank/backend-order

4.3 LICENSE 選擇

License適用企業建議
Proprietary公司內部專案✅ 預設選擇
Apache-2.0計畫開源的專案允許商業使用
MIT工具類開源最寬鬆
AGPL-3.0避免會污染使用者程式碼

企業建議:內部專案統一使用公司自訂 LICENSE 檔,標明版權歸屬與使用限制。

4.4 .gitignore 配置

# === Java / Maven ===
target/
*.class
*.jar
*.war
*.ear
.mvn/wrapper/maven-wrapper.jar

# === IDE ===
.idea/
*.iml
.vscode/
.settings/
.project
.classpath

# === OS ===
.DS_Store
Thumbs.db
*.swp

# === Environment ===
.env
.env.local
*.env
application-local.yml
application-secret.yml

# === Build & Logs ===
build/
dist/
logs/
*.log

# === Security - 絕對不可上傳 ===
*.pem
*.key
*.p12
*.jks
credentials.json
service-account.json

4.5 CODEOWNERS 設定

# CODEOWNERS — 定義程式碼審查責任人
# 語法: pattern   @owner

# 預設:所有檔案需 Tech Lead 審查
*                           @acme-bank/backend-order-leads

# 架構相關變更需架構師審查
/src/main/java/**/config/   @acme-bank/architecture-team
/docs/architecture/         @acme-bank/architecture-team

# API 規格變更需 API 負責人審查
/docs/openapi.yaml          @acme-bank/api-governance
/src/main/java/**/controller/ @acme-bank/backend-order-leads

# CI/CD 變更需 DevOps 審查
/.github/workflows/         @acme-bank/devops-team
/Dockerfile                 @acme-bank/devops-team
/docker-compose*.yml        @acme-bank/devops-team

# 安全相關需資安審查
/src/main/java/**/security/ @acme-bank/security-team
SECURITY.md                 @acme-bank/security-team

# 依賴變更需 Tech Lead + 資安
pom.xml                     @acme-bank/backend-order-leads @acme-bank/security-team
package.json                @acme-bank/frontend-leads @acme-bank/security-team

4.6 SECURITY.md 與 CONTRIBUTING.md

SECURITY.md

# Security Policy

## Supported Versions

| Version | Supported          |
|---------|--------------------|
| 2.x     | ✅ Active support  |
| 1.x     | ⚠️ Security fixes only |
| < 1.0   | ❌ End of life     |

## Reporting a Vulnerability

**請勿在 Public Issue 中揭露安全漏洞。**

請透過以下方式通報:
1. Email: security@acme-bank.com
2. GitHub Security Advisory(Private)

### 回應時間
- 確認收到:24 小時內
- 初步評估:72 小時內
- 修補計畫:7 個工作天內

## Security Practices
- 所有 PR 需通過 CodeQL 掃描
- 依賴套件每週自動更新(Dependabot)
- Secret Scanning 已啟用

CONTRIBUTING.md

# Contributing Guide

## 開發流程

1. 從 `develop` 建立 feature branch
2. 遵循 Conventional Commits 格式
3. 確保所有測試通過
4. 提交 Pull Request 至 `develop`
5. 等待 Code Review(至少 2 人 Approve)

## Commit Message 格式

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

<body>

<footer>
\```

Type: feat | fix | docs | style | refactor | test | chore | ci

## Code Style
- Java: Google Java Style Guide
- 使用 EditorConfig 統一格式
- PR 前執行 `mvn spotless:check`

## Branch Naming
- feature/JIRA-123-add-order-api
- fix/JIRA-456-fix-null-pointer
- hotfix/JIRA-789-security-patch

4.7 Issue Template 與 PR Template

Issue Template (.github/ISSUE_TEMPLATE/bug_report.yml):

name: Bug Report
description: 回報程式錯誤
title: "[Bug]: "
labels: ["bug", "triage"]
assignees: []
body:
  - type: markdown
    attributes:
      value: "## 錯誤回報"
  - type: textarea
    id: description
    attributes:
      label: 問題描述
      description: 清楚描述發生了什麼問題
    validations:
      required: true
  - type: textarea
    id: steps
    attributes:
      label: 重現步驟
      description: 如何重現此問題
      value: |
        1. 
        2. 
        3. 
    validations:
      required: true
  - type: textarea
    id: expected
    attributes:
      label: 預期行為
    validations:
      required: true
  - type: dropdown
    id: severity
    attributes:
      label: 嚴重程度
      options:
        - Critical(系統停擺)
        - High(主要功能異常)
        - Medium(次要功能異常)
        - Low(外觀/體驗問題)
    validations:
      required: true
  - type: input
    id: environment
    attributes:
      label: 環境
      placeholder: "Production / Staging / Development"

PR Template (.github/pull_request_template.md):

## 變更說明

<!-- 描述此 PR 的目的與變更內容 -->

## 變更類型

- [ ] 🐛 Bug Fix
- [ ] ✨ New Feature
- [ ] 🔨 Refactoring
- [ ] 📝 Documentation
- [ ] 🔒 Security Fix
- [ ] ⚡ Performance

## 關聯 Issue

Closes #

## 檢查清單

- [ ] 程式碼遵循專案 Code Style
- [ ] 已新增/更新對應的單元測試
- [ ] 所有既有測試通過
- [ ] 已更新相關文件
- [ ] 無硬編碼的敏感資訊
- [ ] 已考慮向後相容性

## 測試方式

<!-- 描述如何驗證此變更 -->

## 截圖(如適用)

## 部署注意事項

<!-- 是否需要 DB migration / 環境變數 / 特殊部署步驟 -->

4.8 Repository 初始化完整範例

#!/bin/bash
# === Repository 初始化腳本 ===
# 用法: ./init-repo.sh <repo-name> <template>

REPO_NAME=$1
TEMPLATE=${2:-"tmpl-spring-boot"}
ORG="acme-bank"

echo "📦 建立 Repository: ${ORG}/${REPO_NAME}"

# 1. 從 Template 建立
gh repo create "${ORG}/${REPO_NAME}" \
  --template "${ORG}/${TEMPLATE}" \
  --private \
  --clone

cd "${REPO_NAME}" || exit 1

# 2. 設定 Branch Protection
gh api repos/${ORG}/${REPO_NAME}/branches/main/protection \
  -X PUT \
  -f required_status_checks='{"strict":true,"contexts":["ci/build","ci/test"]}' \
  -f enforce_admins=true \
  -f required_pull_request_reviews='{"required_approving_review_count":2,"require_code_owner_reviews":true}'

# 3. 啟用安全功能
gh api repos/${ORG}/${REPO_NAME}/vulnerability-alerts -X PUT
gh api repos/${ORG}/${REPO_NAME}/automated-security-fixes -X PUT

# 4. 設定 Team 權限
gh api orgs/${ORG}/teams/backend-core/repos/${ORG}/${REPO_NAME} \
  -X PUT -f permission="push"
gh api orgs/${ORG}/teams/devops-team/repos/${ORG}/${REPO_NAME} \
  -X PUT -f permission="maintain"

# 5. 建立 develop branch
git checkout -b develop
git push origin develop

# 6. 設定預設 branch
gh api repos/${ORG}/${REPO_NAME} -X PATCH -f default_branch="main"

echo "✅ Repository ${REPO_NAME} 初始化完成"

實務建議:將初始化腳本放入 wf-shared-actions Repository,搭配 GitHub Actions 實現「自助式 Repository 建立」,開發者填寫 Issue 表單即可自動建立符合規範的 Repository。

Repository Topics(標籤分類)

Topics 是 GitHub 提供的標籤機制,用於分類與搜尋 Repository。企業可利用 Topics 建立統一的 Repo 分類體系。

# 使用 GitHub CLI 設定 Topics
gh repo edit acme-bank/svc-order-api --add-topic "spring-boot,java,microservice,order-domain,team-backend"

企業 Topics 規範

Topic 類別範例用途
技術棧java, spring-boot, vue, typescript技術搜尋
業務領域order-domain, payment-domain業務歸屬
團隊team-backend, team-frontend團隊負責
類型microservice, library, templateRepo 類型
狀態active, deprecated, archived生命週期
環境production-ready, experimental成熟度

Autolinks(自動連結外部資源)

Autolinks 可將特定文字模式自動轉換為外部系統連結,例如將 JIRA-123 自動連結至 Jira Issue。

# 設定 Autolink — 連結至 Jira
gh api repos/acme-bank/svc-order-api/autolinks \
  -X POST \
  -f key_prefix="JIRA-" \
  -f url_template="https://acme-bank.atlassian.net/browse/JIRA-<num>" \
  -F is_alphanumeric=false

# 設定 Autolink — 連結至內部 Wiki
gh api repos/acme-bank/svc-order-api/autolinks \
  -X POST \
  -f key_prefix="WIKI-" \
  -f url_template="https://wiki.acme-bank.com/pages/<num>" \
  -F is_alphanumeric=false

Autolinks 使用效果

Commit / PR 中輸入自動轉換為
JIRA-1234https://acme-bank.atlassian.net/browse/JIRA-1234
WIKI-5678https://wiki.acme-bank.com/pages/5678

企業建議:在組織層級統一建立 Autolinks,確保所有 Repo 都能自動連結至 Jira、Confluence 等內部系統,提升跨工具追溯性。

4.10 Repository 從 Template 建立

GitHub Template Repository 功能允許將一個 Repo 設定為範本,其他新 Repo 可以從此範本快速建立,繼承完整的檔案結構但不繼承 Git 歷史。

建立 Template Repository

  1. 前往 Repository → Settings
  2. 勾選 Template repository
  3. 該 Repo 即可作為範本被引用
# 使用 GitHub CLI 將 Repo 設為 Template
gh api repos/acme-bank/tmpl-spring-boot \
  -X PATCH \
  -F is_template=true

Template Repository 最佳實踐

項目建議
命名使用 tmpl- 前綴(如 tmpl-spring-boot
內容包含標準目錄結構、CI/CD Workflow、.gitignore、CODEOWNERS
排除不包含業務程式碼、環境變數、Secret
文件README 需說明如何使用此 Template
維護定期更新依賴版本與 Workflow
版本使用 Release Tag 標記 Template 版本

Template vs Fork 比較

面向TemplateFork
Git 歷史不繼承(全新起點)完整繼承
上游同步不支援支援 Pull from upstream
適用場景建立全新獨立專案貢獻回上游 / 保持同步
企業建議✅ 新專案起點⚠️ 企業內建議限制使用

第 5 章 Repository 標準結構設計

5.1 Backend Repository(Clean Architecture)

svc-order-api/
├── .github/
│   ├── workflows/
│   │   ├── ci.yml
│   │   ├── cd.yml
│   │   └── security.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   └── feature_request.yml
│   ├── pull_request_template.md
│   └── CODEOWNERS
├── docs/
│   ├── architecture/
│   │   ├── adr/
│   │   │   ├── 001-use-clean-architecture.md
│   │   │   └── 002-use-kafka-for-events.md
│   │   └── diagrams/
│   ├── api/
│   │   └── openapi.yaml
│   └── runbook/
│       └── deployment.md
├── src/
│   ├── main/
│   │   ├── java/com/acme/order/
│   │   │   ├── Application.java
│   │   │   ├── domain/                # 領域層(Entity / Value Object)
│   │   │   │   ├── model/
│   │   │   │   │   ├── Order.java
│   │   │   │   │   └── OrderStatus.java
│   │   │   │   ├── repository/        # Repository Interface
│   │   │   │   │   └── OrderRepository.java
│   │   │   │   └── service/           # Domain Service
│   │   │   │       └── OrderDomainService.java
│   │   │   ├── application/           # 應用層(Use Case)
│   │   │   │   ├── usecase/
│   │   │   │   │   ├── CreateOrderUseCase.java
│   │   │   │   │   └── CancelOrderUseCase.java
│   │   │   │   ├── dto/
│   │   │   │   │   ├── CreateOrderRequest.java
│   │   │   │   │   └── OrderResponse.java
│   │   │   │   └── port/
│   │   │   │       ├── in/            # Input Port
│   │   │   │       └── out/           # Output Port
│   │   │   ├── infrastructure/        # 基礎設施層
│   │   │   │   ├── persistence/
│   │   │   │   │   ├── entity/
│   │   │   │   │   ├── mapper/
│   │   │   │   │   └── JpaOrderRepository.java
│   │   │   │   ├── messaging/
│   │   │   │   │   └── KafkaOrderEventPublisher.java
│   │   │   │   └── external/
│   │   │   │       └── PaymentServiceClient.java
│   │   │   └── adapter/              # 介面層(Controller / Gateway)
│   │   │       ├── rest/
│   │   │       │   └── OrderController.java
│   │   │       └── event/
│   │   │           └── OrderEventListener.java
│   │   └── resources/
│   │       ├── application.yml
│   │       ├── application-local.yml
│   │       ├── application-dev.yml
│   │       └── db/migration/
│   │           └── V1__create_order_table.sql
│   └── test/
│       └── java/com/acme/order/
│           ├── domain/
│           ├── application/
│           ├── infrastructure/
│           └── adapter/
├── Dockerfile
├── docker-compose.yml
├── pom.xml
├── .editorconfig
├── .gitignore
├── CODEOWNERS
├── README.md
├── SECURITY.md
├── CONTRIBUTING.md
└── LICENSE

Clean Architecture 依賴規則

graph TB
    subgraph "Clean Architecture Layers"
        A[Adapter Layer
Controller / Event Listener] --> B[Application Layer
Use Case / Port] B --> C[Domain Layer
Entity / Value Object / Service] D[Infrastructure Layer
DB / MQ / External API] --> B end C -.->|不依賴任何外層| C style C fill:#e1f5fe style B fill:#fff3e0 style A fill:#f3e5f5 style D fill:#e8f5e9

5.2 Frontend Repository

app-customer-portal/
├── .github/
│   ├── workflows/
│   │   ├── ci.yml
│   │   ├── deploy.yml
│   │   └── lighthouse.yml
│   └── CODEOWNERS
├── public/
│   ├── favicon.ico
│   └── index.html
├── src/
│   ├── assets/
│   ├── components/
│   │   ├── common/           # 共用元件
│   │   │   ├── Button.vue
│   │   │   └── Modal.vue
│   │   └── features/        # 功能元件
│   │       └── order/
│   │           ├── OrderList.vue
│   │           └── OrderDetail.vue
│   ├── composables/          # Composition API
│   │   ├── useAuth.ts
│   │   └── useOrder.ts
│   ├── layouts/
│   │   ├── DefaultLayout.vue
│   │   └── AuthLayout.vue
│   ├── pages/                # 路由頁面
│   │   ├── index.vue
│   │   └── orders/
│   │       ├── index.vue
│   │       └── [id].vue
│   ├── stores/               # Pinia Store
│   │   ├── auth.ts
│   │   └── order.ts
│   ├── services/             # API 呼叫
│   │   ├── api.ts
│   │   └── orderService.ts
│   ├── types/                # TypeScript 型別
│   │   └── order.d.ts
│   ├── utils/
│   ├── App.vue
│   └── main.ts
├── tests/
│   ├── unit/
│   ├── e2e/
│   └── fixtures/
├── .env.example
├── .eslintrc.cjs
├── .prettierrc
├── Dockerfile
├── nginx.conf
├── package.json
├── tsconfig.json
├── vite.config.ts
└── README.md

5.3 Monorepo 結構

monorepo-order-system/
├── .github/
│   └── workflows/
│       ├── ci-api.yml          # Path filter: apps/api/**
│       ├── ci-web.yml          # Path filter: apps/web/**
│       └── ci-shared.yml       # Path filter: packages/**
├── apps/
│   ├── api/                    # 後端 API
│   │   ├── src/
│   │   ├── pom.xml
│   │   └── Dockerfile
│   ├── web/                    # 前端 Web
│   │   ├── src/
│   │   ├── package.json
│   │   └── Dockerfile
│   └── admin/                  # 管理後台
│       ├── src/
│       └── package.json
├── packages/                   # 共用套件
│   ├── shared-types/
│   │   └── package.json
│   ├── ui-components/
│   │   └── package.json
│   └── utils/
│       └── package.json
├── infrastructure/
│   ├── docker-compose.yml
│   ├── k8s/
│   └── terraform/
├── docs/
├── nx.json                     # Nx 配置
├── package.json                # Root package
├── pnpm-workspace.yaml
└── README.md

5.4 Microservices Repository

每個微服務獨立 Repo 的標準結構

# Organization 層級視角
acme-bank/
├── svc-order-api/              # 訂單服務
├── svc-payment-api/            # 支付服務
├── svc-inventory-api/          # 庫存服務
├── svc-notification-worker/    # 通知 Worker
├── gateway-api/                # API Gateway
├── platform-java-lib-core/     # 共用核心庫
├── platform-java-lib-security/ # 共用安全庫
├── infra-k8s-manifests/        # K8s 部署配置
├── infra-helm-charts/          # Helm Charts
└── docs-service-catalog/       # 服務目錄文件

5.5 Documentation Repository

docs-architecture/
├── .github/
│   └── workflows/
│       └── publish-docs.yml    # 自動發佈至 GitHub Pages
├── adr/                        # Architecture Decision Records
│   ├── template.md
│   ├── 001-microservices-architecture.md
│   ├── 002-event-driven-design.md
│   └── 003-database-per-service.md
├── architecture/
│   ├── system-context.md       # C4 Model - System Context
│   ├── containers.md           # C4 Model - Container
│   ├── components.md           # C4 Model - Component
│   └── diagrams/
│       ├── system-overview.mmd
│       └── sequence-order-flow.mmd
├── api/
│   ├── order-api.yaml          # OpenAPI Spec
│   └── payment-api.yaml
├── runbook/
│   ├── deployment.md
│   ├── rollback.md
│   └── incident-response.md
├── standards/
│   ├── coding-standards.md
│   ├── api-design-guide.md
│   └── security-guidelines.md
├── mkdocs.yml                  # MkDocs 配置
└── README.md

實務建議:使用 MkDocs + Material Theme 或 Docusaurus 將文件 Repo 自動發佈為內部網站,搭配 GitHub Actions 實現「Push to main → 自動部署文件網站」。


第 6 章 Source Code 上架與管理

6.1 Git 基本流程

日常開發完整流程

# 1. Clone 專案(首次)
git clone git@github.com:acme-bank/svc-order-api.git
cd svc-order-api

# 2. 建立 Feature Branch
git checkout develop
git pull origin develop
git checkout -b feature/JIRA-123-add-order-api

# 3. 開發 & 提交
git add src/main/java/com/acme/order/
git commit -m "feat(order): add create order API endpoint"

git add src/test/java/com/acme/order/
git commit -m "test(order): add unit tests for CreateOrderUseCase"

# 4. 同步遠端最新變更
git fetch origin
git rebase origin/develop

# 5. 推送到遠端
git push origin feature/JIRA-123-add-order-api

# 6. 建立 Pull Request
gh pr create --base develop \
  --title "feat(order): add create order API endpoint" \
  --body "Closes #123"

# 7. PR 合併後清理
git checkout develop
git pull origin develop
git branch -d feature/JIRA-123-add-order-api

常用指令速查

操作指令說明
查看狀態git status檢視工作區變更
查看歷史git log --oneline -20最近 20 筆提交
暫存變更git stash臨時保存未提交的變更
恢復暫存git stash pop恢復暫存的變更
取消修改git checkout -- <file>還原單一檔案
修改最後 commitgit commit --amend修正最近一次提交
查看差異git diff --cached已 stage 的變更差異
互動式 rebasegit rebase -i HEAD~3整理最近 3 次提交

6.2 Commit Message 規範

採用 Conventional Commits 標準:

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

[optional body]

[optional footer]

Type 定義

Type說明範例
feat新功能feat(order): add cancel order endpoint
fix修復 Bugfix(payment): resolve null pointer in refund
docs文件更新docs: update API documentation
style格式調整(不影響邏輯)style: format code with spotless
refactor重構(不改功能)refactor(order): extract validation logic
test測試相關test(order): add integration test for create
chore維護性工作chore: update dependencies
ciCI/CD 配置ci: add security scanning workflow
perf效能優化perf(query): add index for order lookup
security安全修復security: patch CVE-2024-xxxx

Breaking Change 標記

feat(api)!: change order response format

BREAKING CHANGE: OrderResponse now uses ISO 8601 date format
instead of Unix timestamp. All API consumers must update.

Refs: JIRA-456

6.3 Git Flow

gitGraph
    commit id: "init"
    branch develop
    checkout develop
    commit id: "setup"
    
    branch feature/order-api
    checkout feature/order-api
    commit id: "feat: add model"
    commit id: "feat: add service"
    commit id: "test: add tests"
    checkout develop
    merge feature/order-api id: "merge feature"
    
    branch release/1.0.0
    checkout release/1.0.0
    commit id: "chore: bump version"
    commit id: "fix: minor bug"
    checkout main
    merge release/1.0.0 id: "release 1.0.0" tag: "v1.0.0"
    checkout develop
    merge release/1.0.0 id: "back-merge"
    
    checkout main
    branch hotfix/1.0.1
    commit id: "fix: critical bug"
    checkout main
    merge hotfix/1.0.1 id: "hotfix" tag: "v1.0.1"
    checkout develop
    merge hotfix/1.0.1 id: "back-merge hotfix"

Git Flow 分支定義

分支用途來源合併至生命週期
main正式版本release / hotfix永久
develop開發整合featurerelease永久
feature/*功能開發developdevelop短期
release/*版本準備developmain + develop短期
hotfix/*緊急修復mainmain + develop極短

6.4 GitHub Flow

gitGraph
    commit id: "v1.0"
    branch feature/add-search
    commit id: "implement search"
    commit id: "add tests"
    checkout main
    merge feature/add-search id: "PR #42 merged" tag: "v1.1"
    
    branch feature/fix-perf
    commit id: "optimize query"
    checkout main
    merge feature/fix-perf id: "PR #43 merged" tag: "v1.2"

GitHub Flow 規則(僅 2 類分支):

  1. main 永遠可部署
  2. 所有開發在 feature branch 進行
  3. 透過 Pull Request 合併回 main
  4. 合併後立即部署

適用場景:持續部署(CD)、Web 應用、SaaS 產品

6.5 Trunk Based Development

gitGraph
    commit id: "feat: A" tag: "deploy"
    commit id: "feat: B" tag: "deploy"
    branch release/1.0
    checkout main
    commit id: "feat: C" tag: "deploy"
    commit id: "fix: D" tag: "deploy"
    checkout release/1.0
    commit id: "cherry-pick fix"
    checkout main
    commit id: "feat: E" tag: "deploy"

Trunk Based 規則

  1. 所有開發者直接提交到 main(或極短 feature branch < 1 天)
  2. 使用 Feature Flag 控制未完成功能
  3. 每次提交即觸發 CI/CD
  4. Release Branch 僅用於穩定版本維護

6.6 三種策略比較與選擇

面向Git FlowGitHub FlowTrunk Based
複雜度
適合版本化發佈產品Web SaaS高頻部署
部署頻率週/月天/週時/天
團隊規模大型中小型任何規模
Feature Flag不需要不需要必須
分支數量極少
Code ReviewPR to developPR to mainPR to main(短)
金融業建議✅ 推薦⚠️ 需搭配環境控管⚠️ 需完善 Feature Flag

企業建議:金融業建議使用 Git Flow(穩定可控),搭配嚴格的 Branch Protection 與 Release 管理。若團隊成熟度高、CI/CD 完善,可逐步過渡至 GitHub Flow。

6.7 Git Large File Storage(LFS)

Git LFS 是 GitHub 官方推薦的大型檔案管理方案,透過將大型二進制檔案替換為輕量指標(pointer),實際檔案存放於 LFS 伺服器,避免 Repository 膨脹。

何時需要 Git LFS

  • 單一檔案超過 50 MB(GitHub 警告)或 100 MB(GitHub 拒絕)
  • 頻繁變更的二進制檔案(圖片、設計稿、編譯產物)
  • 機器學習模型檔、資料集
  • 影音多媒體資源

安裝與配置

# 1. 安裝 Git LFS
git lfs install

# 2. 追蹤特定檔案類型
git lfs track "*.psd"
git lfs track "*.zip"
git lfs track "*.jar"
git lfs track "*.model"
git lfs track "docs/assets/**/*.png"

# 3. 確認 .gitattributes 已更新
cat .gitattributes
# *.psd filter=lfs diff=lfs merge=lfs -text
# *.zip filter=lfs diff=lfs merge=lfs -text

# 4. 提交 .gitattributes
git add .gitattributes
git commit -m "chore: configure Git LFS tracking"

# 5. 正常使用 git add / commit / push
git add design/mockup.psd
git commit -m "docs: add UI mockup"
git push origin main

Git LFS 儲存配額

GitHub 方案LFS 儲存空間LFS 頻寬(月)額外購買
Free1 GB1 GB$5/50GB
Team1 GB1 GB$5/50GB
Enterprise1 GB1 GB$5/50GB

企業 .gitattributes 參考配置

# === Git LFS 追蹤規則 ===
# 圖片
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.svg filter=lfs diff=lfs merge=lfs -text

# 設計稿
*.psd filter=lfs diff=lfs merge=lfs -text
*.sketch filter=lfs diff=lfs merge=lfs -text
*.figma filter=lfs diff=lfs merge=lfs -text

# 壓縮檔
*.zip filter=lfs diff=lfs merge=lfs -text
*.tar.gz filter=lfs diff=lfs merge=lfs -text

# 文件
*.pdf filter=lfs diff=lfs merge=lfs -text

# 機器學習
*.model filter=lfs diff=lfs merge=lfs -text
*.h5 filter=lfs diff=lfs merge=lfs -text
*.onnx filter=lfs diff=lfs merge=lfs -text

常用指令

指令用途
git lfs ls-files列出 LFS 追蹤的檔案
git lfs status查看 LFS 檔案狀態
git lfs fetch --all下載所有 LFS 檔案
git lfs prune清理本地過期 LFS 快取
git lfs migrate import --include="*.psd"將既有大檔案遷移至 LFS

企業建議

  • 在 Template Repo 中預先配置 .gitattributes,確保新專案從一開始就正確使用 LFS
  • CI/CD 中使用 git lfs install && git lfs pull 確保 Runner 取得 LFS 檔案
  • 定期使用 git lfs prune 清理本地快取
  • 若 Repository Archive 包含 LFS 物件,需在 Repository Settings 中啟用「Include Git LFS objects in archives」

第 7 章 Branch Strategy

7.1 分支命名規範

# 格式: <type>/<ticket-id>-<short-description>

# Feature
feature/JIRA-123-add-order-api
feature/JIRA-456-implement-payment-gateway

# Bug Fix
fix/JIRA-789-null-pointer-in-order-service
fix/JIRA-012-incorrect-amount-calculation

# Hotfix(緊急修復)
hotfix/JIRA-999-security-vulnerability-patch
hotfix/CVE-2024-12345-fix

# Release
release/1.2.0
release/2.0.0-rc.1

# Chore
chore/upgrade-spring-boot-3.4
chore/update-dependencies-2024-q4

命名規則

  • 全部小寫
  • 使用 - 連接單字
  • 必須包含 Ticket ID(JIRA / Issue #)
  • 不超過 60 字元
  • 禁止中文字元

7.2 Branch Protection Rules

main branch 保護設定

# 使用 GitHub CLI 設定 Branch Protection
gh api repos/acme-bank/svc-order-api/branches/main/protection \
  -X PUT \
  --input - << 'EOF'
{
  "required_status_checks": {
    "strict": true,
    "contexts": [
      "ci/build",
      "ci/test",
      "ci/integration-test",
      "security/codeql",
      "security/dependency-check"
    ]
  },
  "enforce_admins": true,
  "required_pull_request_reviews": {
    "required_approving_review_count": 2,
    "dismiss_stale_reviews": true,
    "require_code_owner_reviews": true,
    "require_last_push_approval": true,
    "dismissal_restrictions": {
      "teams": ["org-admins"]
    }
  },
  "restrictions": {
    "users": [],
    "teams": ["org-admins", "devops-team"]
  },
  "required_linear_history": true,
  "allow_force_pushes": false,
  "allow_deletions": false,
  "required_conversation_resolution": true
}
EOF

各分支保護等級

分支Required ReviewsStatus ChecksForce PushDelete
main2 + CODEOWNERS全部通過❌ 禁止❌ 禁止
develop1Build + Test❌ 禁止❌ 禁止
release/*2全部通過❌ 禁止✅ 合併後刪
feature/*0(建議 1)Build✅ 允許✅ 合併後刪
hotfix/*2 + CODEOWNERS全部通過❌ 禁止✅ 合併後刪

7.3 Pull Request Review 流程

sequenceDiagram
    participant Dev as 開發者
    participant PR as Pull Request
    participant CI as CI Pipeline
    participant Rev as Reviewer
    participant CO as CODEOWNERS
    participant Main as main branch

    Dev->>PR: 建立 PR(feature → develop)
    PR->>CI: 觸發 CI 檢查
    CI-->>PR: Build ✅ / Test ✅ / Security ✅
    PR->>Rev: 請求 Review
    Rev-->>PR: Review(Comments / Approve)
    
    alt 需要修改
        PR-->>Dev: Request Changes
        Dev->>PR: Push 修正
        PR->>CI: 重新檢查
    end
    
    PR->>CO: CODEOWNERS 自動指派
    CO-->>PR: Approve ✅
    
    alt 所有條件滿足
        PR->>Main: Squash & Merge
        Main-->>Dev: 通知合併完成
    end

Review Checklist(給 Reviewer)

  • 程式碼邏輯正確
  • 遵循 Clean Architecture 分層
  • 無硬編碼敏感資訊
  • 有對應的單元測試
  • API 變更有更新 OpenAPI Spec
  • 無 N+1 Query 問題
  • 例外處理完善
  • Log 層級適當
  • 向後相容(或有 Migration Plan)

7.4 CODEOWNERS 進階配置

# === 全域規則 ===
# 所有 PR 預設需要 Tech Lead 審查
*                                   @acme-bank/tech-leads

# === 分層審查 ===
# Domain Layer 變更 — 架構師
**/domain/**                        @acme-bank/architecture-team

# Infrastructure Layer — DevOps
**/infrastructure/**                @acme-bank/devops-team
Dockerfile                          @acme-bank/devops-team
docker-compose*.yml                 @acme-bank/devops-team

# Security 相關
**/security/**                      @acme-bank/security-team
**/auth/**                          @acme-bank/security-team

# === CI/CD 變更 ===
.github/workflows/**                @acme-bank/devops-team @acme-bank/security-team

# === 依賴管理 ===
pom.xml                             @acme-bank/tech-leads @acme-bank/security-team
build.gradle*                       @acme-bank/tech-leads @acme-bank/security-team
package.json                        @acme-bank/tech-leads @acme-bank/security-team
package-lock.json                   @acme-bank/tech-leads

# === 資料庫 Migration ===
**/db/migration/**                  @acme-bank/dba-team @acme-bank/tech-leads

# === API 規格 ===
**/openapi*.yaml                    @acme-bank/api-governance
**/openapi*.json                    @acme-bank/api-governance

7.5 Merge Strategy 選擇

策略指令歷史記錄適用場景
Squash & Merge多次 commit 合成 1 個乾淨線性✅ Feature → develop/main
Merge Commit保留所有 commit + 合併節點完整但複雜Release → main
Rebase & Merge重寫 commit 至目標之上線性無合併節點小型 fix

企業建議

  • Feature PR → Squash & Merge(保持歷史乾淨)
  • Release → main → Merge Commit(保留版本合併記錄)
  • Repository 設定:禁用 Merge Commit for feature PR,僅允許 Squash

7.6 Repository Rulesets 深入指南

Rulesets 是 GitHub 推出的新一代分支保護機制,相較傳統 Branch Protection Rules 具有顯著優勢。自 2024 年起,GitHub 官方建議企業逐步從 Branch Protection 遷移至 Rulesets。

Rulesets vs Branch Protection Rules

面向Branch Protection RulesRepository Rulesets
多規則疊加每個分支僅一組規則多組 Ruleset 可同時生效並疊加
狀態管理啟用/停用需刪除重建Active / Disabled 狀態切換
可見性僅 Admin 可查看所有 Read 權限使用者可查看
組織層級❌ 僅 Repo 層級✅ 可在 Organization 層級設定
Push Rulesets❌ 不支援✅ 支援檔案路徑/大小/副檔名限制
Commit Metadata✅ 可限制 Commit Message 格式
Bypass 機制Admin 可覆寫明確指定 bypass 角色/團隊
Fork 保護✅ Push Rulesets 延伸至 Fork
適用方案Free(Public)/ TeamFree(Public)/ Team / Enterprise

Rule Layering(規則疊加)機制

當多個 Rulesets 針對同一分支時,所有規則會聚合生效,衝突時以最嚴格的版本為準。

Ruleset A: main branch → 要求 Signed Commits + 3 Reviews
Ruleset B: main branch → 要求 Linear History + 2 Reviews
═══════════════════════════════════════════
聚合結果: main branch → Signed Commits + Linear History + 3 Reviews(取最嚴格)

Branch & Tag Rulesets 配置範例

# 使用 GitHub CLI 建立 Ruleset
gh api repos/acme-bank/svc-order-api/rulesets \
  -X POST \
  --input - << 'EOF'
{
  "name": "main-protection",
  "target": "branch",
  "enforcement": "active",
  "conditions": {
    "ref_name": {
      "include": ["~DEFAULT_BRANCH"],
      "exclude": []
    }
  },
  "bypass_actors": [
    {
      "actor_id": 1,
      "actor_type": "OrganizationAdmin",
      "bypass_mode": "always"
    }
  ],
  "rules": [
    {
      "type": "pull_request",
      "parameters": {
        "required_approving_review_count": 2,
        "dismiss_stale_reviews_on_push": true,
        "require_code_owner_review": true,
        "require_last_push_approval": true,
        "required_review_thread_resolution": true
      }
    },
    {
      "type": "required_status_checks",
      "parameters": {
        "strict_required_status_checks_policy": true,
        "required_status_checks": [
          {"context": "ci/build"},
          {"context": "ci/test"},
          {"context": "security/codeql"}
        ]
      }
    },
    {
      "type": "non_fast_forward"
    },
    {
      "type": "deletion"
    }
  ]
}
EOF

Push Rulesets(檔案推送限制)

Push Rulesets 可在整個 Repository(含 Fork 網路)層級限制推送行為,無需指定分支。

{
  "name": "push-restrictions",
  "target": "push",
  "enforcement": "active",
  "rules": [
    {
      "type": "file_path_restriction",
      "parameters": {
        "restricted_file_paths": [
          ".github/workflows/**",
          "Dockerfile",
          "*.pem",
          "*.key"
        ]
      }
    },
    {
      "type": "max_file_path_length",
      "parameters": {
        "max_file_path_length": 256
      }
    },
    {
      "type": "file_extension_restriction",
      "parameters": {
        "restricted_file_extensions": [".exe", ".dll", ".so", ".bin"]
      }
    },
    {
      "type": "max_file_size",
      "parameters": {
        "max_file_size": 10485760
      }
    }
  ]
}

企業建議

  • 新建 Repository 優先使用 Rulesets 而非 Branch Protection Rules
  • 在 Organization 層級建立基線 Ruleset(如:所有 Repo 的 default branch 至少需 1 Review)
  • 善用 Push Rulesets 阻擋敏感檔案(金鑰、憑證)和不允許的檔案類型進入 Repo
  • 使用 Disabled 狀態暫時停用規則,避免刪除後難以還原

7.7 Merge Queue 管理

Merge Queue 是 GitHub 提供的自動化合併佇列機制,解決「多個 PR 同時等待合併時需反覆更新基底分支」的問題,確保合併至目標分支的程式碼始終通過最新的 CI 檢查。

Merge Queue 運作流程

sequenceDiagram
    participant D1 as 開發者 A
    participant D2 as 開發者 B
    participant MQ as Merge Queue
    participant CI as CI Pipeline
    participant Main as main branch

    D1->>MQ: PR #1 加入 Queue
    D2->>MQ: PR #2 加入 Queue
    
    MQ->>MQ: 建立合併組(PR#1 + main)
    MQ->>CI: 觸發 CI 檢查
    CI-->>MQ: CI 通過 ✅
    MQ->>Main: 合併 PR #1
    
    MQ->>MQ: 建立合併組(PR#2 + 新 main)
    MQ->>CI: 觸發 CI 檢查
    CI-->>MQ: CI 通過 ✅
    MQ->>Main: 合併 PR #2

啟用 Merge Queue

  1. 前往 Repository → Settings → General → Pull Requests
  2. 勾選 Allow merge queue(需 GitHub Team 或 Enterprise 方案)
  3. 在 Branch Protection 或 Ruleset 中啟用「Require merge queue」

Merge Queue 配置參數

參數說明建議值
Merge method合併方式Squash merge
Build concurrency同時建置的 PR 群組數5
Minimum group size最小合併群組大小1
Maximum group size最大合併群組大小5
Wait time等待更多 PR 加入群組的時間5 分鐘
Status check timeoutCI 檢查逾時時間60 分鐘

在 Ruleset 中啟用 Merge Queue

{
  "type": "merge_queue",
  "parameters": {
    "check_response_timeout_minutes": 60,
    "grouping_strategy": "ALLGREEN",
    "max_entries_to_build": 5,
    "max_entries_to_merge": 5,
    "merge_method": "SQUASH",
    "min_entries_to_merge": 1,
    "min_entries_to_merge_wait_minutes": 5
  }
}

企業建議

  • 高頻合併的 Repository(如核心服務的 develop / main)強烈建議啟用 Merge Queue
  • 搭配「Require branches to be up to date before merging」使用,Merge Queue 會自動處理基底更新
  • Merge Queue 特別適合搭配 Trunk Based Development,確保每次合併都經過完整 CI 驗證

第 8 章 GitHub Actions 自動化 Workflow

8.1 GitHub Actions 架構概述

graph LR
    subgraph "Triggers"
        T1[Push]
        T2[Pull Request]
        T3[Schedule]
        T4[Manual]
        T5[Release]
    end
    
    subgraph "Workflow Pipeline"
        W1[Build] --> W2[Test]
        W2 --> W3[Security Scan]
        W3 --> W4[Package]
        W4 --> W5[Deploy]
    end
    
    subgraph "Environments"
        E1[Development]
        E2[Staging]
        E3[Production]
    end
    
    T1 --> W1
    T2 --> W1
    W5 --> E1
    W5 --> E2
    W5 --> E3

核心概念

概念說明
Workflow一個完整的自動化流程(.yml 檔)
JobWorkflow 中的一組步驟(可平行)
StepJob 中的單一動作
Action可重用的動作單元
Runner執行環境(GitHub-hosted / Self-hosted)
Secret加密的環境變數
Environment部署目標(含保護規則)

8.2 CI Workflow — Java Spring Boot

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

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

permissions:
  contents: read
  checks: write
  pull-requests: write

env:
  JAVA_VERSION: '21'
  MAVEN_OPTS: '-Xmx1024m'

jobs:
  build:
    name: Build & Test
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_DB: testdb
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # SonarQube 需要完整歷史

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: ${{ env.JAVA_VERSION }}
          cache: 'maven'

      - name: Build
        run: mvn compile -B -q

      - name: Unit Tests
        run: mvn test -B

      - name: Integration Tests
        run: mvn verify -P integration-test -B
        env:
          SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/testdb
          SPRING_DATASOURCE_USERNAME: test
          SPRING_DATASOURCE_PASSWORD: test

      - name: Code Coverage
        run: mvn jacoco:report -B

      - name: Upload Coverage
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report
          path: target/site/jacoco/

      - name: Publish Test Results
        uses: dorny/test-reporter@v1
        if: always()
        with:
          name: Test Results
          path: target/surefire-reports/*.xml
          reporter: java-junit

  code-quality:
    name: Code Quality
    runs-on: ubuntu-latest
    needs: build
    
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: ${{ env.JAVA_VERSION }}
          cache: 'maven'

      - name: SonarQube Analysis
        run: |
          mvn sonar:sonar \
            -Dsonar.projectKey=svc-order-api \
            -Dsonar.host.url=${{ secrets.SONAR_HOST_URL }} \
            -Dsonar.token=${{ secrets.SONAR_TOKEN }}

      - name: Checkstyle
        run: mvn checkstyle:check -B

      - name: SpotBugs
        run: mvn spotbugs:check -B

8.3 CI Workflow — Vue 專案

# .github/workflows/ci-frontend.yml
name: Frontend CI

on:
  push:
    branches: [develop, main]
    paths:
      - 'src/**'
      - 'package.json'
      - 'vite.config.ts'
  pull_request:
    branches: [develop, main]

jobs:
  lint-and-test:
    name: Lint & Test
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        node-version: [20, 22]
    
    steps:
      - uses: actions/checkout@v4

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

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

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

      - name: Lint
        run: pnpm lint

      - name: Type Check
        run: pnpm type-check

      - name: Unit Tests
        run: pnpm test:unit --coverage

      - name: Build
        run: pnpm build

      - name: Upload Build Artifact
        uses: actions/upload-artifact@v4
        with:
          name: dist-${{ matrix.node-version }}
          path: dist/

  e2e:
    name: E2E Tests
    runs-on: ubuntu-latest
    needs: lint-and-test
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'pnpm'
      - uses: pnpm/action-setup@v4
        with:
          version: 9
      - run: pnpm install --frozen-lockfile
      
      - name: Playwright Install
        run: pnpm exec playwright install --with-deps

      - name: E2E Tests
        run: pnpm test:e2e

      - name: Upload E2E Report
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

8.4 CD Workflow — Docker Build & Deploy

# .github/workflows/cd.yml
name: CD Pipeline

on:
  push:
    tags:
      - 'v*'

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

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

jobs:
  build-and-push:
    name: Build & Push Docker Image
    runs-on: ubuntu-latest
    outputs:
      image-tag: ${{ steps.meta.outputs.tags }}
      image-digest: ${{ steps.build.outputs.digest }}
    
    steps:
      - uses: actions/checkout@v4

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

      - name: Login to GHCR
        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=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha

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

  deploy-staging:
    name: Deploy to Staging
    runs-on: ubuntu-latest
    needs: build-and-push
    environment: staging
    
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to K8s (Staging)
        uses: azure/k8s-deploy@v5
        with:
          manifests: |
            infra/k8s/staging/
          images: |
            ${{ needs.build-and-push.outputs.image-tag }}
          namespace: staging

  deploy-production:
    name: Deploy to Production
    runs-on: ubuntu-latest
    needs: [build-and-push, deploy-staging]
    environment: production
    
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to K8s (Production)
        uses: azure/k8s-deploy@v5
        with:
          manifests: |
            infra/k8s/production/
          images: |
            ${{ needs.build-and-push.outputs.image-tag }}
          namespace: production
          strategy: canary
          percentage: 20

8.5 Security Workflow

# .github/workflows/security.yml
name: Security Scan

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 6 * * 1'  # 每週一 UTC 6:00

permissions:
  contents: read
  security-events: write

jobs:
  codeql:
    name: CodeQL Analysis
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        language: ['java']
    
    steps:
      - uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          queries: +security-extended,security-and-quality

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '21'

      - name: Build
        run: mvn compile -B -q -DskipTests

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3
        with:
          category: "/language:${{ matrix.language }}"

  dependency-check:
    name: Dependency Vulnerability Scan
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4

      - name: OWASP Dependency Check
        uses: dependency-check/Dependency-Check_Action@main
        with:
          project: 'svc-order-api'
          path: '.'
          format: 'HTML'
          args: >-
            --failOnCVSS 7
            --enableRetired

      - name: Upload Report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: dependency-check-report
          path: reports/

  secret-scan:
    name: Secret Detection
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: TruffleHog Secret Scan
        uses: trufflesecurity/trufflehog@main
        with:
          extra_args: --only-verified

8.6 Release Workflow

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

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Release version (e.g., 1.2.0)'
        required: true
        type: string
      prerelease:
        description: 'Pre-release?'
        required: false
        type: boolean
        default: false

permissions:
  contents: write
  packages: write

jobs:
  release:
    name: Create Release
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '21'
          cache: 'maven'

      - name: Set Version
        run: mvn versions:set -DnewVersion=${{ inputs.version }} -B

      - name: Build & Verify
        run: mvn verify -B

      - name: Generate Changelog
        id: changelog
        uses: mikepenz/release-changelog-builder-action@v5
        with:
          configuration: ".github/changelog-config.json"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Create Tag & Release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: v${{ inputs.version }}
          name: Release v${{ inputs.version }}
          body: ${{ steps.changelog.outputs.changelog }}
          prerelease: ${{ inputs.prerelease }}
          files: |
            target/*.jar

8.7 Reusable Workflows 與 Composite Actions

Reusable Workflow(放在 wf-shared-actions Repo):

# .github/workflows/java-ci.yml(Reusable)
name: Java CI Template

on:
  workflow_call:
    inputs:
      java-version:
        required: false
        type: string
        default: '21'
      maven-goals:
        required: false
        type: string
        default: 'verify'
    secrets:
      SONAR_TOKEN:
        required: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: ${{ inputs.java-version }}
          cache: 'maven'
      - run: mvn ${{ inputs.maven-goals }} -B

在其他 Repo 呼叫

# svc-order-api/.github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  java-ci:
    uses: acme-bank/wf-shared-actions/.github/workflows/java-ci.yml@main
    with:
      java-version: '21'
      maven-goals: 'verify'
    secrets:
      SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

實務建議

  1. 將共用 Workflow 集中管理在 wf-shared-actions Repo
  2. 使用 @v1 Tag 版本控制,避免 breaking change 影響所有下游
  3. Self-hosted Runner 建議用於:大型 build(需高規格機器)、需存取內網資源、需特殊軟體授權

第 9 章 DevSecOps 與 SSDLC

9.1 SSDLC 流程總覽

Secure Software Development Lifecycle(SSDLC) 將安全活動嵌入軟體開發每個階段:

graph LR
    subgraph "SSDLC Phases"
        P1[需求
Threat Modeling] --> P2[設計
Security Architecture Review] P2 --> P3[開發
SAST / Linting] P3 --> P4[測試
DAST / Pen Test] P4 --> P5[部署
Container Scan / SBOM] P5 --> P6[維運
Monitoring / Incident Response] P6 --> P1 end subgraph "GitHub Security Tools" G1[CodeQL
SAST] G2[Dependabot
SCA] G3[Secret Scanning] G4[Security Advisories] G5[SBOM Export] end P3 --> G1 P3 --> G2 P3 --> G3 P5 --> G5 P6 --> G4

GitHub Advanced Security (GHAS) 功能矩陣

功能Free/TeamGHAS ⚠️ 需 GitHub Enterprise說明
Dependabot Alerts依賴漏洞告警
Dependabot Updates自動建立更新 PR
Secret Scanning偵測洩漏的密鑰
Push Protection阻擋含密鑰的 Push
CodeQL✅(Public)語意級 SAST
Security Overview組織級安全儀表板
Custom Patterns自訂 Secret 偵測規則

9.2 SAST — 靜態應用程式安全測試

CodeQL 配置

# .github/codeql/codeql-config.yml
name: "Enterprise CodeQL Config"
disable-default-queries: false

queries:
  - uses: security-extended
  - uses: security-and-quality

paths-ignore:
  - '**/test/**'
  - '**/generated/**'

query-filters:
  - exclude:
      tags: /correctness/  # 排除正確性類(僅聚焦安全)

常見 Java 安全漏洞偵測

CWE漏洞類型CodeQL 偵測修復方式
CWE-89SQL Injection使用 Prepared Statement
CWE-79XSSOutput Encoding
CWE-502Deserialization白名單反序列化
CWE-611XXE禁用外部實體
CWE-22Path Traversal正規化路徑檢查
CWE-327Weak Crypto使用 AES-256-GCM
CWE-798Hard-coded Credentials使用 Vault / Secrets

9.3 Dependency Scan — Dependabot

# .github/dependabot.yml
version: 2
updates:
  # Maven 依賴
  - package-ecosystem: "maven"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "06:00"
      timezone: "Asia/Taipei"
    open-pull-requests-limit: 10
    labels:
      - "dependencies"
      - "security"
    reviewers:
      - "acme-bank/tech-leads"
    commit-message:
      prefix: "deps"
      include: "scope"
    # 安全更新永遠建立 PR
    allow:
      - dependency-type: "all"
    ignore:
      - dependency-name: "org.springframework.boot"
        update-types: ["version-update:semver-major"]
    groups:
      spring:
        patterns:
          - "org.springframework*"
      testing:
        patterns:
          - "org.junit*"
          - "org.mockito*"
          - "org.assertj*"

  # GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    labels:
      - "ci"
      - "dependencies"

  # Docker
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"

9.4 Secret Scanning

啟用與配置 ⚠️ 需 GitHub Enterprise:

# 啟用 Secret Scanning
gh api repos/acme-bank/svc-order-api \
  -X PATCH \
  -f security_and_analysis.secret_scanning.status="enabled" \
  -f security_and_analysis.secret_scanning_push_protection.status="enabled"

自訂 Secret Pattern

# Organization 層級自訂模式
patterns:
  - name: "Internal API Key"
    pattern: "ACME-KEY-[A-Za-z0-9]{32}"
    description: "內部 API Key 格式"
    
  - name: "Database Connection String"
    pattern: "jdbc:(postgresql|mysql)://[^\\s]+"
    description: "資料庫連線字串"
    
  - name: "JWT Secret"
    pattern: "jwt[_-]?secret[\"'=:\\s]+[A-Za-z0-9+/]{32,}"
    description: "JWT 密鑰"

Secret 洩漏處理 SOP

  1. 收到 Secret Scanning Alert
  2. 立即 Rotate(輪換)該 Secret
  3. 檢查 Audit Log 確認是否被濫用
  4. 從 Git 歷史移除(git filter-branch 或 BFG Repo-Cleaner)
  5. 通報資安團隊
  6. 更新 .gitignore 防止再次發生

9.5 CodeQL 進階分析

自訂 Query(偵測特定模式)

/**
 * @name Hardcoded database password
 * @description Finds hardcoded passwords in database configuration
 * @kind problem
 * @problem.severity error
 * @security-severity 9.0
 * @id java/hardcoded-db-password
 * @tags security
 */

import java
import semmle.code.java.dataflow.DataFlow

from StringLiteral literal, MethodAccess call
where
  call.getMethod().getName().matches("%password%") and
  DataFlow::localFlow(DataFlow::exprNode(literal), DataFlow::exprNode(call.getAnArgument())) and
  literal.getValue().length() > 3
select literal, "Hardcoded password found: potential security risk"

9.6 Container Security

# .github/workflows/container-security.yml
name: Container Security

on:
  push:
    paths:
      - 'Dockerfile'
      - '.dockerignore'

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

      - name: Build Image
        run: docker build -t app:scan .

      - name: Trivy Vulnerability Scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'app:scan'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'

      - name: Upload Trivy Results
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: 'trivy-results.sarif'

      - name: Hadolint - Dockerfile Lint
        uses: hadolint/hadolint-action@v3.1.0
        with:
          dockerfile: Dockerfile
          failure-threshold: warning

      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          image: 'app:scan'
          format: spdx-json
          output-file: sbom.spdx.json

      - name: Upload SBOM
        uses: actions/upload-artifact@v4
        with:
          name: sbom
          path: sbom.spdx.json

9.7 完整 Security Pipeline YAML

# .github/workflows/security-full.yml
name: Full Security Pipeline

on:
  push:
    branches: [main]
  schedule:
    - cron: '0 2 * * *'  # 每日凌晨 2:00 完整掃描

jobs:
  sast:
    name: SAST (CodeQL)
    uses: acme-bank/wf-shared-actions/.github/workflows/codeql.yml@v1
    
  sca:
    name: SCA (Dependency Check)
    uses: acme-bank/wf-shared-actions/.github/workflows/dependency-check.yml@v1
    
  secret:
    name: Secret Detection
    uses: acme-bank/wf-shared-actions/.github/workflows/secret-scan.yml@v1
    
  container:
    name: Container Scan
    needs: [sast, sca]
    uses: acme-bank/wf-shared-actions/.github/workflows/container-scan.yml@v1
    
  report:
    name: Security Report
    needs: [sast, sca, secret, container]
    runs-on: ubuntu-latest
    steps:
      - name: Aggregate Results
        run: echo "All security checks passed ✅"
      
      - name: Notify on Failure
        if: failure()
        uses: slackapi/slack-github-action@v2
        with:
          webhook: ${{ secrets.SECURITY_SLACK_WEBHOOK }}
          payload: |
            {
              "text": "🚨 Security scan failed for ${{ github.repository }}"
            }

實務建議:安全掃描應同時在 PR 和定期排程執行。PR 掃描確保新程式碼安全,排程掃描捕捉新發現的 CVE 對既有程式碼的影響。

9.8 Private Vulnerability Reporting

GitHub 提供 Private Vulnerability Reporting(私密漏洞通報) 功能,允許安全研究者透過標準化流程向 Repository 維護者私密通報安全漏洞,避免在 Public Issue 中公開揭露。

啟用方式

# 在 Repository 層級啟用
gh api repos/acme-bank/svc-order-api \
  -X PATCH \
  -F security_and_analysis.secret_scanning.status="enabled"

# 在 Organization 層級統一啟用
# Settings → Code security and analysis → Private vulnerability reporting → Enable all

通報流程

sequenceDiagram
    participant Researcher as 安全研究者
    participant Advisory as Security Advisory
    participant Team as 維護團隊
    participant Fix as 修補流程
    participant Public as 公開揭露

    Researcher->>Advisory: 建立 Private Advisory
(描述漏洞詳情) Advisory->>Team: 通知維護團隊 Team->>Advisory: 確認收到 + 評估嚴重性 Team->>Fix: 在 Private Fork 開發修補 Fix->>Advisory: 關聯修補 PR Team->>Advisory: 申請 CVE 編號(選用) Team->>Public: 發佈修補 + 公開 Advisory

Security Advisory 範本

## 漏洞摘要
[簡要描述漏洞類型與影響]

## 影響版本
- v2.0.0 ~ v2.3.1

## 嚴重性
CVSS 3.1 Score: 8.5 (High)

## 重現步驟
1. [步驟一]
2. [步驟二]
3. [觀察到的安全問題]

## 修補建議
升級至 v2.3.2 或以上版本

## 時間軸
- 2026-01-15: 收到通報
- 2026-01-17: 確認漏洞
- 2026-01-24: 修補完成
- 2026-01-25: 公開揭露

企業 Security Advisory 管理策略

階段SLA負責人產出
收到通報24 小時內確認資安團隊確認回覆
嚴重性評估72 小時內資安 + 開發CVSS 評分
修補開發7 天(Critical)/ 30 天(High)開發團隊修補 PR
驗證測試修補後 48 小時QA 團隊測試報告
公開揭露修補發佈後資安團隊Public Advisory

企業建議:所有 Production Repository 務必啟用 Private Vulnerability Reporting,並在 SECURITY.md 中清楚說明通報管道與回應 SLA。這不僅是安全最佳實踐,也展現組織對資安的重視。


第 10 章 文件管理策略

10.1 README Strategy

README 分層策略

層級位置內容目標讀者
Organization.github repo 的 profile/README.md公司簡介、導覽所有成員
Repository根目錄 README.md專案說明、快速開始開發者
Directory各目錄 README.md目錄用途說明維護者
APIdocs/api/README.mdAPI 使用指南API 消費者

README 品質評分標準

  • 有清楚的一句話描述專案用途
  • 有 CI/CD Badge
  • 有「快速開始」步驟(< 5 步)
  • 有技術棧列表
  • 有 API 文件連結
  • 有聯絡人 / 負責團隊
  • 有架構圖或流程圖
  • 有貢獻指南連結

10.2 Architecture Decision Record(ADR)

ADR Template

# ADR-{number}: {title}

## Status
{Proposed | Accepted | Deprecated | Superseded by ADR-xxx}

## Context
描述面臨的問題或決策背景。

## Decision
說明做出的決策。

## Consequences
### Positive
- 正面影響

### Negative
- 負面影響 / 取捨

### Risks
- 潛在風險

## Alternatives Considered
| 方案 | 優點 | 缺點 | 結論 |
|------|------|------|------|
| 方案 A | ... | ... | ✅ 採用 |
| 方案 B | ... | ... | ❌ 排除 |

## References
- 相關文件連結

ADR 範例 — 選擇 Event-Driven Architecture

# ADR-002: 採用 Event-Driven Architecture

## Status
Accepted (2024-03-15)

## Context
訂單系統需要通知支付、庫存、通知等多個下游服務。
目前使用同步 REST 呼叫,導致:
1. 強耦合
2. 延遲累加
3. 單點故障風險

## Decision
採用 Apache Kafka 實現 Event-Driven Architecture。
- 訂單狀態變更發佈 Domain Event
- 下游服務各自訂閱所需事件
- 使用 Outbox Pattern 確保一致性

## Consequences
### Positive
- 服務解耦,獨立部署
- 非同步處理,提升回應速度
- 天然支援 Event Sourcing

### Negative
- 增加系統複雜度(Kafka 維運)
- Eventual Consistency(需處理最終一致性)
- Debug 難度增加

## References
- [Event-Driven Architecture Pattern](https://microservices.io/patterns/data/event-driven-architecture.html)
- [Transactional Outbox](https://microservices.io/patterns/data/transactional-outbox.html)

10.3 API 文件管理

OpenAPI Spec 管理策略

# docs/api/openapi.yaml
openapi: 3.1.0
info:
  title: Order Service API
  version: 2.1.0
  description: |
    訂單服務 API — 處理訂單完整生命週期
  contact:
    name: Backend Order Team
    email: backend-order@acme-bank.com

servers:
  - url: https://api.acme-bank.com/orders/v2
    description: Production
  - url: https://api-staging.acme-bank.com/orders/v2
    description: Staging

paths:
  /orders:
    post:
      operationId: createOrder
      summary: 建立訂單
      tags: [Orders]
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrderRequest'
      responses:
        '201':
          description: 訂單建立成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

API 文件自動化 Workflow

# .github/workflows/api-docs.yml
name: API Documentation

on:
  push:
    paths:
      - 'docs/api/**'
      - 'src/**/controller/**'

jobs:
  validate-and-publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Validate OpenAPI Spec
        uses: char0n/swagger-editor-validate@v1
        with:
          definition-file: docs/api/openapi.yaml

      - name: Generate API Diff
        uses: oasdiff/oasdiff-action/breaking@main
        if: github.event_name == 'pull_request'
        with:
          base: docs/api/openapi.yaml
          revision: docs/api/openapi.yaml

      - name: Publish to Swagger UI
        if: github.ref == 'refs/heads/main'
        run: |
          # 發佈至內部 API Portal
          echo "Publishing API docs..."

10.4 Wiki vs Docs Repository

面向GitHub WikiDocs Repository
版本控制獨立 Git Repo(弱)與程式碼同 Repo
PR Review❌ 不支援✅ 支援
CI/CD❌ 無法自動化✅ 可自動發佈
搜尋GitHub 內建需自建(Algolia / DocSearch)
適用簡單文件、FAQ正式技術文件
企業建議❌ 不建議✅ 推薦

企業建議:正式文件放在 Repository 中(docs/ 目錄或獨立 docs repo),使用 PR Review 流程管控品質。Wiki 僅用於非正式知識分享。

10.5 文件自動化生成

# .github/workflows/docs-publish.yml
name: Publish Documentation

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
      - 'mkdocs.yml'

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      pages: write
      id-token: write
    
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install MkDocs
        run: |
          pip install mkdocs-material \
            mkdocs-mermaid2-plugin \
            mkdocs-git-revision-date-localized-plugin

      - name: Build Docs
        run: mkdocs build

      - name: Deploy to GitHub Pages
        uses: actions/deploy-pages@v4

10.6 GitHub Pages 靜態網站發佈

GitHub Pages 提供直接從 Repository 發佈靜態網站的功能,適合用於技術文件、API 文件、團隊入口網站等。

發佈來源選擇

來源說明適用場景
Branch(Legacy)從特定分支(如 gh-pages)發佈簡單靜態網站
GitHub Actions(推薦)透過 Workflow 建置後發佈MkDocs / Docusaurus / 自訂建置

使用 GitHub Actions 發佈(推薦)

# .github/workflows/deploy-pages.yml
name: Deploy to GitHub Pages

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
      - 'mkdocs.yml'

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: actions/setup-python@v5
        with:
          python-version: '3.12'
      
      - name: Install Dependencies
        run: pip install mkdocs-material mkdocs-mermaid2-plugin

      - name: Build
        run: mkdocs build --strict

      - name: Upload Artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: site/

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

企業 Pages 使用規範

項目建議
存取控制Private Repo 的 Pages 僅組織成員可存取(Enterprise)
自訂域名使用公司子域名(如 docs.acme-bank.com
HTTPS強制啟用(GitHub 預設支援)
內容限制僅發佈文件網站,不放置敏感資訊
CI 整合PR 預覽部署(Preview Deployments)

企業建議:使用 GitHub Pages 搭配 MkDocs Material 或 Docusaurus 建立內部技術文件網站。透過 GitHub Actions 實現「Push to main → 自動建置 → 自動部署」的完全自動化流程。


第 11 章 Issue / Project 管理

11.1 GitHub Issues 設計

Issue Template 完整組合

.github/ISSUE_TEMPLATE/
├── bug_report.yml          # Bug 回報
├── feature_request.yml     # 功能需求
├── tech_debt.yml           # 技術債務
├── security_report.yml     # 安全問題
└── config.yml              # Template 選擇器配置

config.yml

blank_issues_enabled: false  # 禁止空白 Issue
contact_links:
  - name: 🔒 安全漏洞回報
    url: https://github.com/acme-bank/svc-order-api/security/advisories/new
    about: 安全漏洞請透過 Security Advisory 回報
  - name: 💬 一般問題
    url: https://github.com/acme-bank/svc-order-api/discussions
    about: 一般技術問題請至 Discussions 討論

Feature Request Template

name: Feature Request
description: 提出功能需求
title: "[Feature]: "
labels: ["enhancement", "triage"]
body:
  - type: textarea
    id: problem
    attributes:
      label: 問題描述
      description: 描述目前遇到的問題或需求背景
    validations:
      required: true
  - type: textarea
    id: solution
    attributes:
      label: 建議方案
      description: 描述希望如何解決此問題
    validations:
      required: true
  - type: textarea
    id: alternatives
    attributes:
      label: 替代方案
      description: 考慮過的其他方案
  - type: dropdown
    id: priority
    attributes:
      label: 業務優先級
      options:
        - P0 - 緊急(阻礙業務)
        - P1 - 高(本季必須)
        - P2 - 中(可規劃)
        - P3 - 低(Nice to have)
    validations:
      required: true
  - type: textarea
    id: acceptance
    attributes:
      label: 驗收條件
      value: |
        - [ ] 條件 1
        - [ ] 條件 2
        - [ ] 條件 3

11.2 GitHub Projects(V2)

Projects V2 建立

# 建立組織級 Project
gh project create --owner acme-bank --title "Order Service Sprint Board"

# 新增自訂欄位
gh project field-create 1 --owner acme-bank \
  --name "Sprint" --data-type "ITERATION" \
  --iteration-duration 14  # 2 週 Sprint

gh project field-create 1 --owner acme-bank \
  --name "Story Points" --data-type "NUMBER"

gh project field-create 1 --owner acme-bank \
  --name "Priority" --data-type "SINGLE_SELECT" \
  --single-select-options "P0-Critical,P1-High,P2-Medium,P3-Low"

Project View 設計

View類型分組篩選用途
Sprint BoardBoardStatusCurrent Sprint每日站會
BacklogTablePriorityStatus != Done需求池管理
My TasksTableAssignee = @me個人工作追蹤
Release PlanTableMilestoneRelease 規劃
Bug TriageBoardSeverityLabel = bugBug 分診

11.3 Label 系統設計

#!/bin/bash
# 標準化 Label 建立腳本
ORG="acme-bank"
REPO="svc-order-api"

# Type Labels
gh label create "type: bug" --color "d73a4a" --description "程式錯誤" -R ${ORG}/${REPO}
gh label create "type: feature" --color "0075ca" --description "新功能" -R ${ORG}/${REPO}
gh label create "type: tech-debt" --color "fbca04" --description "技術債務" -R ${ORG}/${REPO}
gh label create "type: docs" --color "0e8a16" --description "文件更新" -R ${ORG}/${REPO}
gh label create "type: ci" --color "e4e669" --description "CI/CD 改善" -R ${ORG}/${REPO}
gh label create "type: security" --color "b60205" --description "安全修復" -R ${ORG}/${REPO}

# Priority Labels
gh label create "priority: P0" --color "b60205" --description "緊急 - 阻礙營運" -R ${ORG}/${REPO}
gh label create "priority: P1" --color "d93f0b" --description "高 - 本 Sprint" -R ${ORG}/${REPO}
gh label create "priority: P2" --color "fbca04" --description "中 - 可規劃" -R ${ORG}/${REPO}
gh label create "priority: P3" --color "0e8a16" --description "低 - Nice to have" -R ${ORG}/${REPO}

# Status Labels
gh label create "status: triage" --color "d4c5f9" --description "等待分診" -R ${ORG}/${REPO}
gh label create "status: in-progress" --color "1d76db" --description "進行中" -R ${ORG}/${REPO}
gh label create "status: blocked" --color "b60205" --description "被阻擋" -R ${ORG}/${REPO}
gh label create "status: review" --color "f9d0c4" --description "等待審查" -R ${ORG}/${REPO}

# Component Labels
gh label create "component: api" --color "c5def5" --description "API 層" -R ${ORG}/${REPO}
gh label create "component: domain" --color "c5def5" --description "Domain 層" -R ${ORG}/${REPO}
gh label create "component: infra" --color "c5def5" --description "基礎設施層" -R ${ORG}/${REPO}
gh label create "component: db" --color "c5def5" --description "資料庫" -R ${ORG}/${REPO}

11.4 Milestone 與 Sprint Planning

Milestone 設計

# 建立 Milestone(對應 Release 版本)
gh api repos/acme-bank/svc-order-api/milestones \
  -f title="v2.1.0" \
  -f description="訂單服務 2.1 版 - 新增取消功能" \
  -f due_on="2024-06-30T00:00:00Z"

Sprint Planning 自動化

# .github/workflows/sprint-automation.yml
name: Sprint Automation

on:
  schedule:
    - cron: '0 1 * * 1'  # 每週一凌晨

jobs:
  sprint-report:
    runs-on: ubuntu-latest
    steps:
      - name: Generate Sprint Summary
        uses: actions/github-script@v7
        with:
          script: |
            const issues = await github.rest.issues.listForRepo({
              owner: 'acme-bank',
              repo: 'svc-order-api',
              state: 'all',
              since: new Date(Date.now() - 14 * 24 * 60 * 60 * 1000).toISOString()
            });
            
            const closed = issues.data.filter(i => i.state === 'closed').length;
            const opened = issues.data.filter(i => i.state === 'open').length;
            
            console.log(`Sprint Summary: ${closed} closed, ${opened} open`);

11.5 Agile Workflow 整合

graph TD
    subgraph "Agile Lifecycle on GitHub"
        A[Backlog
Issues with labels] --> B[Sprint Planning
Assign to Milestone] B --> C[Development
Feature Branch] C --> D[Pull Request
Linked to Issue] D --> E[Code Review
CODEOWNERS] E --> F[Merge & Deploy
Auto-close Issue] F --> G[Sprint Review
GitHub Project Board] G --> A end

Issue ↔ PR 自動連結

# PR 描述中使用關鍵字自動關閉 Issue
Closes #123
Fixes #456
Resolves #789

實務建議:善用 GitHub Projects V2 的 Automation 功能 — Issue 建立自動加入 Board、PR 合併自動移至 Done、Sprint 結束未完成自動移至下一 Sprint。


第 12 章 Release Management

12.1 Semantic Versioning

遵循 Semantic Versioning 2.0.0 規範:

MAJOR.MINOR.PATCH[-prerelease][+buildmetadata]

範例:
1.0.0          # 首次正式發佈
1.1.0          # 新增功能(向後相容)
1.1.1          # Bug 修復
2.0.0          # Breaking Change
2.0.0-rc.1     # Release Candidate
2.0.0-beta.1   # Beta 版

版本升級規則

變更類型版本升級範例
Breaking API ChangeMAJOR1.x → 2.0.0
新增功能(向後相容)MINOR1.1.x → 1.2.0
Bug 修復PATCH1.1.1 → 1.1.2
依賴安全更新PATCH1.1.1 → 1.1.2
重構(無行為變更)不升版
文件更新不升版

12.2 Conventional Commits

自動版本判斷(基於 Commit Message)

Commit Type對應版本升級
featMINOR
fixPATCH
feat! / BREAKING CHANGEMAJOR
perfPATCH
docs / style / chore不升版

commitlint 配置

// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore', 'ci', 'perf', 'security']
    ],
    'scope-enum': [
      1,
      'always',
      ['order', 'payment', 'inventory', 'auth', 'api', 'db', 'ci', 'deps']
    ],
    'subject-max-length': [2, 'always', 72],
    'body-max-line-length': [1, 'always', 100]
  }
};

12.3 Changelog 自動生成

Changelog 配置

// .github/changelog-config.json
{
  "categories": [
    {
      "title": "## 🚀 新功能",
      "labels": ["type: feature", "enhancement"]
    },
    {
      "title": "## 🐛 Bug 修復",
      "labels": ["type: bug", "fix"]
    },
    {
      "title": "## 🔒 安全修復",
      "labels": ["type: security"]
    },
    {
      "title": "## 📝 文件",
      "labels": ["type: docs"]
    },
    {
      "title": "## 🔧 維護",
      "labels": ["type: tech-debt", "type: ci", "dependencies"]
    }
  ],
  "template": "#{{CHANGELOG}}\n\n**Full Changelog**: #{{RELEASE_DIFF}}",
  "pr_template": "- #{{TITLE}} (#{{NUMBER}}) @#{{AUTHOR}}"
}

自動生成範例

# Changelog

## [2.1.0] - 2024-06-30

### 🚀 新功能
- feat(order): add cancel order endpoint (#142) @john-doe
- feat(order): add order status webhook (#145) @jane-doe

### 🐛 Bug 修復
- fix(payment): resolve race condition in refund (#148) @bob

### 🔒 安全修復
- security: upgrade Spring Boot to 3.4.1 (CVE-2024-xxxx) (#150) @dependabot

### 🔧 維護
- chore(deps): update test dependencies (#147) @dependabot

**Full Changelog**: v2.0.0...v2.1.0

12.4 GitHub Release 與 Tag

Tag 命名規範

# Annotated Tag(推薦)
git tag -a v2.1.0 -m "Release v2.1.0 - Add cancel order feature"
git push origin v2.1.0

# 預發佈
git tag -a v2.1.0-rc.1 -m "Release Candidate 1 for v2.1.0"

Release 建立

# 使用 GitHub CLI
gh release create v2.1.0 \
  --title "Release v2.1.0" \
  --generate-notes \
  --target main \
  ./target/svc-order-api-2.1.0.jar

12.5 Release Workflow 自動化

# .github/workflows/release-please.yml
name: Release Please

on:
  push:
    branches: [main]

permissions:
  contents: write
  pull-requests: write

jobs:
  release-please:
    runs-on: ubuntu-latest
    outputs:
      release_created: ${{ steps.release.outputs.release_created }}
      tag_name: ${{ steps.release.outputs.tag_name }}
    
    steps:
      - uses: googleapis/release-please-action@v4
        id: release
        with:
          release-type: maven
          package-name: svc-order-api

  publish:
    needs: release-please
    if: ${{ needs.release-please.outputs.release_created }}
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '21'
          cache: 'maven'

      - name: Publish to GitHub Packages
        run: mvn deploy -B -DskipTests
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

實務建議:使用 release-pleasesemantic-release 實現全自動版本管理 — 每次 merge to main 自動判斷版本升級、生成 Changelog、建立 Release Tag。人工只需 merge PR,其餘全部自動化。


第 13 章 AI 時代 Repository 管理

13.1 GitHub Copilot 整合

Copilot 企業配置 ⚠️ 需 GitHub Enterprise:

設定項目建議值說明
Copilot in IDE✅ 啟用程式碼補全
Copilot Chat✅ 啟用對話式開發
Copilot in CLI✅ 啟用指令建議
Copilot in PR✅ 啟用PR Summary & Review
Content Exclusion設定排除清單排除敏感 Repo
Suggestions matching public code❌ 關閉避免授權風險

Copilot Instructions 配置

<!-- .github/copilot-instructions.md -->
# Copilot Instructions for svc-order-api

## Architecture
- Follow Clean Architecture (Domain → Application → Infrastructure → Adapter)
- Domain layer must not depend on any external framework

## Code Style
- Use Java 21 features (Records, Pattern Matching, Virtual Threads)
- Follow Google Java Style Guide
- All public methods must have JavaDoc

## Security
- Never hardcode credentials
- Use PreparedStatement for all SQL
- Validate all input at Controller layer
- Use @Valid annotation for request DTOs

## Testing
- Unit test coverage > 80%
- Use JUnit 5 + Mockito + AssertJ
- Integration tests use TestContainers
- Name pattern: should_expectedBehavior_when_condition

## Dependencies
- Spring Boot 3.4.x
- PostgreSQL (no other DB)
- Apache Kafka for events
- Redis for caching

13.2 Claude Code 整合

CLAUDE.md 配置

<!-- CLAUDE.md -->
# Claude Code Guidelines

## Project Context
This is a Spring Boot microservice for order management.
Tech stack: Java 21, Spring Boot 3.4, PostgreSQL, Kafka.

## Architecture Rules
1. Never import infrastructure classes from domain layer
2. Use case classes should be single-purpose
3. All external calls go through Port/Adapter pattern

## Coding Standards
- Commit messages follow Conventional Commits
- PR title format: type(scope): description
- Always include unit tests with changes
- Run `mvn verify` before committing

## File Organization
- Domain models: src/main/java/.../domain/model/
- Use cases: src/main/java/.../application/usecase/
- Controllers: src/main/java/.../adapter/rest/
- Repository implementations: src/main/java/.../infrastructure/persistence/

## Common Commands
- Build: `mvn compile`
- Test: `mvn test`
- Full verify: `mvn verify`
- Run locally: `mvn spring-boot:run -Dspring.profiles.active=local`
- Format check: `mvn spotless:check`

13.3 AI Agent Workflow

graph TB
    subgraph "AI-Assisted Development Workflow"
        A[Developer writes intent
in Issue/PR description] --> B[AI Agent picks up task] B --> C{Task Type} C -->|Code Generation| D[Copilot generates code
+ tests] C -->|Code Review| E[Copilot reviews PR
+ suggests fixes] C -->|Documentation| F[AI generates/updates
documentation] C -->|Bug Fix| G[AI analyzes logs
+ suggests fix] D --> H[Developer reviews
AI output] E --> H F --> H G --> H H --> I[PR merged] end

GitHub Copilot Workspace ⚠️ 需 GitHub Enterprise:

# .github/workflows/copilot-autofix.yml
name: Copilot Autofix

on:
  issues:
    types: [labeled]

jobs:
  autofix:
    if: contains(github.event.label.name, 'copilot-fix')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Trigger Copilot Workspace
        # 使用 Copilot Workspace API 自動修復
        run: echo "Copilot Workspace triggered for Issue #${{ github.event.issue.number }}"

13.4 Prompt Repository 設計

AI Assets Repository 結構

ai-prompt-library/
├── .github/
│   └── workflows/
│       └── validate-prompts.yml
├── prompts/
│   ├── code-review/
│   │   ├── java-review.prompt.md
│   │   ├── security-review.prompt.md
│   │   └── performance-review.prompt.md
│   ├── code-generation/
│   │   ├── spring-controller.prompt.md
│   │   ├── unit-test.prompt.md
│   │   └── integration-test.prompt.md
│   ├── documentation/
│   │   ├── adr-generation.prompt.md
│   │   ├── api-docs.prompt.md
│   │   └── readme-generation.prompt.md
│   └── devops/
│       ├── dockerfile.prompt.md
│       ├── github-action.prompt.md
│       └── k8s-manifest.prompt.md
├── agents/
│   ├── code-reviewer.agent.md
│   ├── test-writer.agent.md
│   └── doc-generator.agent.md
├── instructions/
│   ├── java-backend.instructions.md
│   ├── vue-frontend.instructions.md
│   └── devops.instructions.md
├── templates/
│   └── prompt-template.md
├── CONTRIBUTING.md
└── README.md

13.5 AI Governance 規範

規範項目策略落實方式
程式碼審查AI 生成程式碼必須人工審查PR Review 強制
敏感排除敏感 Repo 排除 AI 存取Content Exclusion
授權合規禁用匹配公開程式碼建議Organization 設定
品質保證AI 生成需通過 CI 全部檢查Branch Protection
可追蹤AI 輔助開發標記Commit footer: AI-assisted: true
Prompt 版控Prompt 視為程式碼管理獨立 Repo + PR Review

實務建議:AI 是加速器而非替代者。所有 AI 生成的程式碼必須通過與人工撰寫相同的品質關卡(Code Review、CI、Security Scan)。建立 Prompt Library 作為團隊知識資產。

13.6 GitHub Copilot Coding Agent

GitHub Copilot Coding Agent(2025 年推出)是 Copilot 的自主代理模式,可自動完成從 Issue 到 Pull Request 的完整開發流程。

Coding Agent 運作流程

graph LR
    A[Assign Issue
to Copilot] --> B[Agent 建立
Feature Branch] B --> C[Agent 分析
Code Context] C --> D[Agent 撰寫程式碼
+ 測試] D --> E[Agent 執行 CI
+ 修正] E --> F[Agent 建立 PR
供人工審查] F --> G[Developer
Review & Merge]

啟用方式

步驟操作
1. Organization 設定Settings → Copilot → Agent → Enable
2. 指派 Issue在 Issue 中 Assign 給 @copilot
3. 或使用 Label加上 copilot label 觸發
4. 監控進度Agent 會在 PR 中回報進度

適用場景與限制

適合交給 Agent不適合交給 Agent
新增 REST API endpoint大規模架構重構
撰寫單元測試跨多個服務的變更
修正明確的 Bug涉及外部系統整合
增加日誌記錄安全性相關修改
更新文件資料庫 Schema 變更
Refactor 小範圍程式碼效能關鍵路徑優化

Coding Agent 配置最佳實務

<!-- .github/copilot-instructions.md — 增加 Agent 專用指引 -->

## Agent Guidelines
- Always create tests for new code
- Run `mvn verify` before submitting PR
- Follow existing code patterns in the same package
- Do not modify database migration files
- Do not change security configurations
- Include JavaDoc for all public methods

企業 Coding Agent 治理策略

控管項目策略
可使用 Agent 的 Repo白名單制,僅允許非關鍵系統
Agent PR 審查至少 2 位人工 Reviewer
Agent 可修改範圍透過 CODEOWNERS 限制
執行環境使用 GitHub-hosted Runner(沙箱隔離)
稽核追蹤所有 Agent 活動記錄於 Audit Log

13.7 GitHub Copilot Extensions 與 MCP

Copilot Extensions

GitHub Copilot Extensions 允許第三方工具直接整合進 Copilot Chat,開發者可在對話中直接呼叫外部服務。

Extension 類型說明範例
GitHub Marketplace Extensions官方與社群開發Docker、Sentry、Datadog
Private Extensions企業自建內部 API 文件查詢、部署工具
Skillsets輕量化的自訂技能簡單 API 呼叫、資料查詢

MCP(Model Context Protocol)整合

MCP 是一種開放協定,讓 AI Agent 能與外部工具和資料來源互動。VS Code 已原生支援 MCP Server 配置。

// .vscode/mcp.json — 專案級 MCP 配置
{
  "servers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github-token}"
      }
    },
    "database": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "${input:db-url}"
      }
    }
  },
  "inputs": [
    {
      "id": "github-token",
      "type": "promptString",
      "description": "GitHub Personal Access Token",
      "password": true
    },
    {
      "id": "db-url",
      "type": "promptString",
      "description": "PostgreSQL Connection URL"
    }
  ]
}

GitHub Models

GitHub Models 提供直接在 GitHub 上試用和整合 AI 模型的功能,支援 OpenAI、Anthropic、Mistral 等模型:

功能說明
Playground在 github.com/marketplace/models 直接試用模型
API 存取使用 GitHub Token 呼叫模型 API
Codespaces 整合在開發環境中直接使用 AI 模型
支援模型GPT-4o、Claude、Mistral、Llama 等

企業建議

  • Copilot Coding Agent 適合低風險、定義明確的任務,始終要求人工審查
  • 建立 MCP Server 封裝內部工具(Jira、Confluence、內部 API),提升 AI 開發體驗
  • 評估 Copilot Extensions 取代部分自建工具整合
  • GitHub Models 可用於 PoC 階段的 AI 功能原型開發

第 14 章 Repository 維運與治理

14.1 Repository Cleanup

大型檔案清理

# 找出 Repository 中的大型檔案
git rev-list --objects --all | \
  git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
  sed -n 's/^blob //p' | \
  sort -rnk2 | \
  head -20

# 使用 BFG Repo-Cleaner 移除大型檔案
java -jar bfg.jar --strip-blobs-bigger-than 50M
git reflog expire --expire=now --all
git gc --prune=now --aggressive

Repository Health Check 腳本

#!/bin/bash
# repo-health-check.sh
REPO=$1

echo "=== Repository Health Check: ${REPO} ==="

# 1. 檢查 Repo 大小
SIZE=$(gh api repos/acme-bank/${REPO} --jq '.size')
echo "📦 Repo Size: ${SIZE} KB"
if [ "$SIZE" -gt 500000 ]; then
  echo "⚠️ WARNING: Repository size exceeds 500MB"
fi

# 2. 檢查最後活動時間
LAST_PUSH=$(gh api repos/acme-bank/${REPO} --jq '.pushed_at')
echo "📅 Last Push: ${LAST_PUSH}"

# 3. 檢查 Branch 數量
BRANCHES=$(gh api repos/acme-bank/${REPO}/branches --jq 'length')
echo "🌿 Active Branches: ${BRANCHES}"
if [ "$BRANCHES" -gt 50 ]; then
  echo "⚠️ WARNING: Too many branches (${BRANCHES}), consider cleanup"
fi

# 4. 檢查開啟的 PR 數量
OPEN_PRS=$(gh pr list -R acme-bank/${REPO} --state open --json number --jq 'length')
echo "🔀 Open PRs: ${OPEN_PRS}"

# 5. 檢查安全告警
ALERTS=$(gh api repos/acme-bank/${REPO}/vulnerability-alerts 2>/dev/null && echo "enabled" || echo "disabled")
echo "🔒 Vulnerability Alerts: ${ALERTS}"

# 6. 檢查 Branch Protection
PROTECTION=$(gh api repos/acme-bank/${REPO}/branches/main/protection 2>/dev/null && echo "✅" || echo "❌")
echo "🛡️ Branch Protection (main): ${PROTECTION}"

14.2 Branch Cleanup 自動化

# .github/workflows/branch-cleanup.yml
name: Branch Cleanup

on:
  schedule:
    - cron: '0 3 * * 0'  # 每週日凌晨 3:00
  workflow_dispatch:

jobs:
  cleanup:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Delete Merged Branches
        uses: actions/github-script@v7
        with:
          script: |
            const { data: branches } = await github.rest.repos.listBranches({
              owner: context.repo.owner,
              repo: context.repo.repo,
              per_page: 100
            });
            
            const protectedBranches = ['main', 'develop', 'release'];
            const staleDays = 30;
            const now = new Date();
            
            for (const branch of branches) {
              // 跳過受保護分支
              if (protectedBranches.some(p => branch.name.startsWith(p))) continue;
              
              // 檢查是否已合併
              try {
                const { data: comparison } = await github.rest.repos.compareCommits({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  base: 'main',
                  head: branch.name
                });
                
                if (comparison.status === 'behind' || comparison.status === 'identical') {
                  console.log(`Deleting merged branch: ${branch.name}`);
                  await github.rest.git.deleteRef({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    ref: `heads/${branch.name}`
                  });
                }
              } catch (e) {
                console.log(`Skipping ${branch.name}: ${e.message}`);
              }
            }

14.3 Secret Rotation

Secret Rotation 策略

Secret 類型輪換頻率方式
API Key90 天自動輪換
Database Password90 天Vault + 自動輪換
JWT Secret180 天雙 Key 輪換
SSH Deploy Key365 天手動輪換
GitHub Token不輪換使用 GITHUB_TOKEN(自動)
# .github/workflows/secret-rotation-reminder.yml
name: Secret Rotation Reminder

on:
  schedule:
    - cron: '0 9 1 */3 *'  # 每季第一天提醒

jobs:
  remind:
    runs-on: ubuntu-latest
    steps:
      - name: Create Rotation Reminder Issue
        uses: actions/github-script@v7
        with:
          script: |
            await github.rest.issues.create({
              owner: context.repo.owner,
              repo: context.repo.repo,
              title: '🔑 季度 Secret Rotation 提醒',
              body: `## Secret 輪換清單\n\n- [ ] 確認所有 API Key 已輪換\n- [ ] 確認資料庫密碼已輪換\n- [ ] 確認 JWT Secret 狀態\n- [ ] 更新 Vault 中的 Secrets\n- [ ] 驗證服務正常運作`,
              labels: ['security', 'maintenance']
            });

14.4 Access Review 與 Audit

定期權限審查 ⚠️ 需 GitHub Enterprise:

#!/bin/bash
# access-review.sh — 季度權限盤點
ORG="acme-bank"

echo "=== Quarterly Access Review ==="

# 1. 列出所有外部協作者
echo "--- External Collaborators ---"
gh api orgs/${ORG}/outside_collaborators --jq '.[].login'

# 2. 列出每個 Repo 的 Admin 權限持有者
echo "--- Repository Admins ---"
for repo in $(gh repo list ${ORG} --json name --jq '.[].name' --limit 100); do
  ADMINS=$(gh api repos/${ORG}/${repo}/collaborators \
    --jq '[.[] | select(.permissions.admin == true)] | length')
  if [ "$ADMINS" -gt 3 ]; then
    echo "⚠️ ${repo}: ${ADMINS} admins (too many)"
  fi
done

# 3. 列出 90 天無活動的成員
echo "--- Inactive Members (90 days) ---"
gh api orgs/${ORG}/members --jq '.[].login' | while read member; do
  LAST_EVENT=$(gh api users/${member}/events --jq '.[0].created_at' 2>/dev/null)
  if [ -z "$LAST_EVENT" ]; then
    echo "❓ ${member}: No recent activity"
  fi
done

Audit Log 監控 ⚠️ 需 GitHub Enterprise:

# 查詢最近的敏感操作
gh api orgs/acme-bank/audit-log \
  --jq '.[] | select(.action | startswith("repo.")) | {action, actor, repo, created_at}' \
  -f phrase="action:repo.destroy OR action:repo.access OR action:org.remove_member"

14.5 Backup 與 Disaster Recovery

Repository Backup 策略

# .github/workflows/backup.yml
name: Repository Backup

on:
  schedule:
    - cron: '0 4 * * *'  # 每日凌晨 4:00

jobs:
  backup:
    runs-on: self-hosted  # 使用內部 Runner
    steps:
      - name: Clone with full history
        run: |
          git clone --mirror git@github.com:acme-bank/svc-order-api.git
          
      - name: Upload to Backup Storage
        run: |
          # 上傳至 Azure Blob / AWS S3
          tar czf svc-order-api-$(date +%Y%m%d).tar.gz svc-order-api.git
          az storage blob upload \
            --container-name github-backups \
            --file svc-order-api-$(date +%Y%m%d).tar.gz \
            --name "repos/svc-order-api/$(date +%Y%m%d).tar.gz"
          
      - name: Cleanup old backups (keep 30 days)
        run: |
          az storage blob delete-batch \
            --source github-backups \
            --pattern "repos/svc-order-api/*" \
            --if-unmodified-since $(date -d '-30 days' +%Y-%m-%dT%H:%M:%SZ)

14.6 Governance Checklist

每季 Repository 治理檢查清單

  • 權限審查:移除不需要的存取權限
  • Branch 清理:刪除已合併 / 過期分支
  • Secret Rotation:輪換所有到期密鑰
  • 安全掃描:確認無未處理的 Critical/High 告警
  • 依賴更新:合併 Dependabot PR
  • 文件更新:確認 README 與 ADR 為最新
  • 效能監控:檢查 CI/CD Pipeline 執行時間
  • 儲存空間:檢查 Repo 大小,清理不必要資源
  • 活動評估:標記無活動 Repo 為 Deprecated
  • 合規確認:確認符合公司安全政策

第 15 章 大型企業最佳實踐

15.1 金融業 Repository 治理

金融業特殊需求

需求GitHub 對應方案說明
變更審計Audit Log + Branch Protection所有變更可追溯
職責分離CODEOWNERS + Required Reviews開發/審查/部署分離
合規掃描GHAS + 自訂 CodeQL Rule符合 PCI-DSS / GDPR
災難恢復Mirror + Backup WorkflowRPO < 24hr
存取控制SAML SSO + SCIM Provisioning集中身分管理
秘密管理Secret Scanning + Vault防止洩漏

金融業 Branch Strategy

graph LR
    subgraph "Development"
        F[feature/*] --> D[develop]
    end
    subgraph "Quality Gate"
        D --> R[release/*]
        R --> |UAT 通過| S[staging]
    end
    subgraph "Production"
        S --> |雙人審核 + 冷卻期| M[main]
        M --> |緊急| H[hotfix/*]
        H --> M
    end
    
    style M fill:#f9f,stroke:#333
    style S fill:#ff9,stroke:#333

15.2 Repository 分層治理

治理層級管轄範圍負責角色主要職責
Enterprise全組織策略CTO / CISO政策制定、合規要求
Organization所有 ReposPlatform TeamRuleset、Template、Shared Workflow
Team團隊 ReposTech Lead具體實施、Code Review
Repository單一 RepoMaintainer日常維護、Issue 管理

Organization-level Ruleset(跨 Repo 統一規則) ⚠️ 需 GitHub Enterprise:

# 適用於所有 Repo 的 main branch
name: "org-wide-main-protection"
target: branch
enforcement: active
bypass_actors:
  - actor_type: OrganizationAdmin
    bypass_mode: always
conditions:
  repository_name:
    include: ["*"]
    exclude: ["docs-*", "tmpl-*"]  # 文件/範本 Repo 除外
  ref_name:
    include: ["~DEFAULT_BRANCH"]
rules:
  - type: required_pull_request
    parameters:
      required_approving_review_count: 1
  - type: required_status_checks
    parameters:
      required_status_checks:
        - context: "ci/build"
  - type: non_fast_forward

15.3 權限隔離設計

graph TB
    subgraph "Production Repos"
        P1[svc-order-api]
        P2[svc-payment-api]
    end
    
    subgraph "Dev/Test Repos"
        D1[svc-order-api-sandbox]
        D2[poc-new-feature]
    end
    
    subgraph "Teams"
        T1[developers] -->|Write| D1
        T1 -->|Write| D2
        T1 -->|Write| P1
        T1 -->|Write| P2
        
        T2[tech-leads] -->|Maintain| P1
        T2 -->|Maintain| P2
        
        T3[release-managers] -->|Admin| P1
        T3 -->|Admin| P2
    end
    
    subgraph "Controls"
        C1[Branch Protection
2 Reviews for main] C2[Environment Protection
Manual Approval] C3[CODEOWNERS
Auto-assign reviewers] end P1 --- C1 P1 --- C2 P1 --- C3

15.4 Compliance 與稽核

合規自動化 Workflow

# .github/workflows/compliance-check.yml
name: Compliance Check

on:
  pull_request:
    branches: [main, release/*]

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

      - name: Check LICENSE exists
        run: test -f LICENSE || (echo "❌ LICENSE file missing" && exit 1)

      - name: Check SECURITY.md exists
        run: test -f SECURITY.md || (echo "❌ SECURITY.md missing" && exit 1)

      - name: Check CODEOWNERS exists
        run: test -f CODEOWNERS || test -f .github/CODEOWNERS || (echo "❌ CODEOWNERS missing" && exit 1)

      - name: Verify no secrets in code
        run: |
          # 檢查常見密碼模式
          if grep -rn "password\s*=\s*['\"][^'\"]*['\"]" src/; then
            echo "❌ Hardcoded password detected"
            exit 1
          fi

      - name: Check commit signature
        run: |
          # 驗證最近 commit 是否有簽名
          UNSIGNED=$(git log --format='%H %G?' origin/main..HEAD | grep -c 'N' || true)
          if [ "$UNSIGNED" -gt 0 ]; then
            echo "⚠️ ${UNSIGNED} unsigned commits detected"
          fi

      - name: SBOM Generation
        uses: anchore/sbom-action@v0
        with:
          path: .
          format: spdx-json

實務建議:金融業的「職責分離」原則在 GitHub 上的體現是:寫程式碼的人不能 Approve 自己的 PRApprove PR 的人不能觸發部署部署的人不能修改 Pipeline。透過 CODEOWNERS + Branch Protection + Environment Protection 三層機制實現。


第 16 章 完整企業範例

16.1 Organization 架構設計

以虛構的「艾可銀行(Acme Bank)」為例:

GitHub Enterprise Cloud
└── Organization: acme-bank
    ├── Plan: Enterprise Cloud
    ├── SSO: Azure AD (SAML)
    ├── SCIM: Enabled (自動同步人員)
    ├── 2FA: Required
    ├── Default Permission: None
    ├── Fork Policy: Disabled
    └── Teams:
        ├── org-admins (3 人)
        ├── security-team (5 人)
        ├── architecture-team (4 人)
        ├── platform-team (6 人)
        ├── devops-team (8 人)
        ├── backend-core (15 人)
        │   ├── backend-order (5 人)
        │   ├── backend-payment (5 人)
        │   └── backend-account (5 人)
        ├── frontend-team (10 人)
        ├── mobile-team (6 人)
        ├── qa-team (8 人)
        └── data-team (6 人)

16.2 Repository 命名與分類

acme-bank/
│
├── 🏗️ Platform Layer
│   ├── platform-java-lib-core         # Java 核心共用庫
│   ├── platform-java-lib-security     # 安全框架
│   ├── platform-java-lib-messaging    # Kafka 抽象層
│   ├── platform-java-starter-web      # Spring Boot Starter
│   └── platform-ui-component-lib      # UI Component Library
│
├── 🔧 Service Layer
│   ├── svc-order-api                  # 訂單服務
│   ├── svc-payment-api                # 支付服務
│   ├── svc-account-api                # 帳戶服務
│   ├── svc-notification-worker        # 通知 Worker
│   ├── svc-auth-api                   # 認證服務
│   └── gateway-api                    # API Gateway
│
├── 🖥️ Application Layer
│   ├── app-internet-banking           # 網路銀行
│   ├── app-mobile-banking             # 行動銀行
│   ├── app-admin-portal               # 管理後台
│   └── app-merchant-portal            # 商戶平台
│
├── 🏭 Infrastructure Layer
│   ├── infra-terraform-aws            # Terraform (AWS)
│   ├── infra-k8s-manifests            # K8s 部署配置
│   ├── infra-helm-charts              # Helm Charts
│   ├── infra-monitoring               # 監控配置
│   └── infra-database-migrations      # DB Schema 管理
│
├── 📚 Documentation Layer
│   ├── docs-architecture              # 架構文件 + ADR
│   ├── docs-api-specs                 # API 規格集中管理
│   ├── docs-runbook                   # 維運手冊
│   └── docs-onboarding               # 新人入職指南
│
├── 📋 Template Layer
│   ├── tmpl-spring-boot               # Spring Boot Template
│   ├── tmpl-vue-app                   # Vue 應用 Template
│   └── tmpl-github-action             # Action Template
│
├── 🔄 Workflow Layer
│   ├── wf-shared-actions              # 共用 GitHub Actions
│   ├── wf-reusable-workflows          # 可重用 Workflows
│   └── .github                        # Organization 預設設定
│
└── 🤖 AI Layer
    ├── ai-prompt-library              # Prompt 庫
    ├── ai-copilot-instructions        # Copilot 指引集
    └── ai-agent-configs               # Agent 配置

16.3 CI/CD Pipeline 完整設計

graph TB
    subgraph "Developer"
        A[Push to feature branch]
    end
    
    subgraph "CI Pipeline"
        B[Compile] --> C[Unit Test]
        C --> D[Integration Test]
        D --> E[Code Quality
SonarQube] E --> F[Security Scan
CodeQL + Dependabot] F --> G[Build Docker Image] end subgraph "CD Pipeline" G --> H[Push to GHCR] H --> I[Deploy to Dev] I --> J[Smoke Test] J --> K[Deploy to Staging] K --> L[E2E Test + UAT] L --> M{Approval
2 人審核} M -->|Approved| N[Deploy to Production] N --> O[Canary 20%] O --> P[Monitor 30min] P --> Q[Full Rollout 100%] end A --> B style N fill:#f9f,stroke:#333 style M fill:#ff9,stroke:#333

16.4 DevSecOps 整合架構

# 完整 DevSecOps Pipeline 概覽
stages:
  pre-commit:
    tools:
      - commitlint          # Commit 格式檢查
      - husky               # Git Hooks
      - secret-detection    # 本地 Secret 掃描
    
  ci-build:
    tools:
      - Maven/Gradle        # 編譯
      - JUnit/Mockito       # 單元測試
      - JaCoCo              # 覆蓋率 > 80%
      - Checkstyle          # 程式碼風格
    
  ci-security:
    tools:
      - CodeQL              # SAST
      - Dependabot          # SCA (依賴弱點)
      - TruffleHog          # Secret Detection
      - SpotBugs + FindSecBugs  # Java 安全 Bug
    
  ci-quality:
    tools:
      - SonarQube           # 品質閘道
      - Spotless            # 格式化
      - ArchUnit            # 架構規則檢查
    
  cd-build:
    tools:
      - Docker Build        # 容器映像
      - Trivy               # 容器弱點掃描
      - Hadolint            # Dockerfile Lint
      - SBOM (Syft)         # 軟體清單
    
  cd-deploy:
    tools:
      - Helm/Kustomize      # K8s 部署
      - ArgoCD              # GitOps
      - Canary Release      # 漸進式發佈
    
  post-deploy:
    tools:
      - DAST (OWASP ZAP)   # 動態安全測試
      - Lighthouse          # 效能測試
      - Chaos Engineering   # 韌性測試

16.5 AI Workflow 整合

AI 輔助開發全流程

階段AI 工具用途
規劃Copilot Chat技術方案討論、Architecture Review
開發Copilot / Claude程式碼生成、補全、重構
測試Copilot自動生成單元測試
ReviewCopilot PR Review自動 Review + 建議
文件CopilotADR 生成、API 文件
維運Copilot CLI指令建議、Log 分析

16.6 SSDLC 完整流程

graph LR
    subgraph "Plan"
        A1[Threat Modeling
STRIDE] A2[Security Requirements
ASVS] end subgraph "Develop" B1[Secure Coding
OWASP Top 10] B2[SAST
CodeQL] B3[SCA
Dependabot] B4[Secret Scan] end subgraph "Verify" C1[DAST
OWASP ZAP] C2[Pen Test] C3[Container Scan
Trivy] end subgraph "Release" D1[SBOM] D2[Signed Image] D3[Compliance Check] end subgraph "Operate" E1[Runtime Protection] E2[Incident Response] E3[Vulnerability Management] end A1 --> B1 A2 --> B1 B1 --> B2 B2 --> B3 B3 --> B4 B4 --> C1 C1 --> C2 C2 --> C3 C3 --> D1 D1 --> D2 D2 --> D3 D3 --> E1 E1 --> E2 E2 --> E3 E3 --> A1

實務建議:完整 SSDLC 不需要一次到位。建議分三階段推進:(1) 先建立 CI 安全基線(CodeQL + Dependabot + Secret Scan),(2) 加入容器安全與 SBOM,(3) 完善 DAST + 合規自動化。


第 17 章 常見問題與最佳實踐

17.1 常見錯誤與 Anti-pattern

Anti-pattern問題正確做法
💀 密碼硬編碼洩漏至 Git 歷史使用 GitHub Secrets / Vault
💀 main 直接 Push無審查、易出錯強制 PR + Branch Protection
💀 巨型 Commit難以 Review、難以 Rollback小而頻繁的 Commit
💀 無 .gitignore垃圾檔案進入 Repo建立時即設定 .gitignore
💀 無 CI品質無保證最少要有 Build + Test
💀 永不清理 Branch混亂、找不到有效分支合併後自動刪除
💀 權限過大安全風險最小權限原則
💀 無 CODEOWNERSPR 無人審查設定明確的 Code Owner
💀 單一超大 MonorepoCI 慢、權限無法隔離依業務拆分
💀 忽略 Dependabot PR累積安全債務每週固定處理

17.2 Security Risk 防範

Top 10 Repository Security Risks

  1. Credential Leakage → Secret Scanning + Push Protection
  2. Vulnerable Dependencies → Dependabot + Auto-merge for patch
  3. Code Injection (CI) → Pin Actions to SHA + Restrict permissions
  4. Unauthorized Access → SSO + RBAC + Regular Access Review
  5. Supply Chain Attack → SBOM + Signed Commits + Verified Actions
  6. Misconfigured Permissions → Organization Rulesets
  7. Stale Credentials → Secret Rotation Automation
  8. Missing Security Patches → Scheduled Security Scan
  9. Insider Threats → Audit Log Monitoring + Alerts
  10. Shadow IT Repos → Fork Policy + Repository Creation Policy

GitHub Actions 安全最佳實踐

# ✅ 安全的 Actions 寫法
jobs:
  build:
    permissions:
      contents: read       # 最小權限
      packages: write
    runs-on: ubuntu-latest
    steps:
      # ✅ Pin to specific SHA(防止 Supply Chain Attack)
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v4.1.1
      
      # ✅ 限制 GITHUB_TOKEN 權限
      # ✅ 不在 log 中印出 Secret
      - name: Deploy
        run: |
          echo "Deploying..."
        env:
          API_KEY: ${{ secrets.API_KEY }}  # 不要用 echo ${{ secrets.X }}

17.3 Repository 治理 Best Practices

成功的 Repository 管理十大原則

  1. Template First:所有新 Repo 必須從 Template 建立
  2. Automate Everything:能自動化的都自動化(CI/CD、Branch Cleanup、Release)
  3. Shift Left Security:安全檢查越早執行越好
  4. Minimum Viable Documentation:至少要有 README + ADR + CODEOWNERS
  5. Consistent Naming:嚴格遵循命名規範
  6. Regular Hygiene:每季做 Repo 健康檢查
  7. Least Privilege:權限永遠給最小的
  8. Code Review Culture:PR Review 是品質的最後防線
  9. Metric Driven:追蹤 Lead Time、MTTR、Deploy Frequency
  10. Continuous Improvement:定期 Retrospective,持續優化流程

17.4 最終 Governance Checklist

新 Repository 建立 Checklist(必須全部通過)

  • 命名符合 {layer}-{domain}-{type}-{name} 規範
  • Visibility 設定正確(預設 Private)
  • README.md 完整(描述 + 技術棧 + 快速開始)
  • .gitignore 已配置
  • CODEOWNERS 已設定
  • SECURITY.md 已建立
  • Branch Protection 已啟用(main + develop)
  • CI Workflow 已設定(至少 Build + Test)
  • Security Scan 已啟用(CodeQL + Dependabot)
  • Secret Scanning 已啟用
  • Team 權限已正確分配
  • Issue Template 已建立
  • PR Template 已建立

第 18 章 GitHub Codespaces 與 Packages

18.1 GitHub Codespaces 雲端開發環境

GitHub Codespaces 提供完全託管的雲端開發環境,開發者可在瀏覽器或本地 VS Code 中連線至雲端容器,無需在本機安裝開發工具即可立即開始開發。

核心價值

優勢說明
零配置上手新成員無需花費數小時配置開發環境
環境一致性所有人使用相同的容器化環境,消除「在我機器上可以跑」問題
安全性原始碼不需下載至個人電腦
效能可選擇高規格雲端機器(最高 32 核心 / 64 GB RAM)
多專案切換同時維護多個 Codespace,各自獨立

Dev Container 配置

// .devcontainer/devcontainer.json
{
  "name": "Order Service Development",
  "image": "mcr.microsoft.com/devcontainers/java:21-bookworm",
  "features": {
    "ghcr.io/devcontainers/features/java:1": {
      "version": "21",
      "installMaven": "true",
      "installGradle": "false"
    },
    "ghcr.io/devcontainers/features/docker-in-docker:2": {},
    "ghcr.io/devcontainers/features/github-cli:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "vscjava.vscode-java-pack",
        "redhat.vscode-xml",
        "GitHub.copilot",
        "GitHub.copilot-chat",
        "ms-azuretools.vscode-docker"
      ],
      "settings": {
        "java.compile.nullAnalysis.mode": "automatic",
        "editor.formatOnSave": true
      }
    }
  },
  "forwardPorts": [8080, 5432],
  "postCreateCommand": "mvn install -DskipTests -q",
  "remoteUser": "vscode"
}

Docker Compose 整合(含依賴服務)

// .devcontainer/devcontainer.json(多容器版)
{
  "name": "Full Stack Development",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",
  "forwardPorts": [8080, 5432, 6379],
  "postCreateCommand": "mvn install -DskipTests"
}
# .devcontainer/docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ../..:/workspace:cached
    command: sleep infinity
  
  db:
    image: postgres:16
    environment:
      POSTGRES_DB: orderdb
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: devpass
    volumes:
      - postgres-data:/var/lib/postgresql/data
  
  redis:
    image: redis:7-alpine

volumes:
  postgres-data:

18.2 Codespaces 企業配置

Organization 層級 Codespaces 策略 ⚠️ 需 GitHub Enterprise:

設定項目建議值說明
啟用 Codespaces指定 Repo非所有 Repo 都需要
Machine Type 限制4-core / 8 GB控制成本
Idle Timeout30 分鐘閒置自動停止
Retention Period14 天未使用的 Codespace 自動刪除
Prebuild 配置核心 Repo 啟用加速 Codespace 建立
Secret 管理Organization Secrets集中管理敏感設定

Prebuild 配置(加速啟動)

# .github/workflows/codespace-prebuild.yml
name: Codespace Prebuild

on:
  push:
    branches: [main]
    paths:
      - '.devcontainer/**'
      - 'pom.xml'

jobs:
  prebuild:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build Prebuild Image
        run: echo "Prebuild triggered for Codespaces"

費用控管策略

機器類型每小時費用(USD)適用場景
2 核心 / 8 GB~$0.18文件編輯、輕量開發
4 核心 / 16 GB~$0.36一般後端開發
8 核心 / 32 GB~$0.72大型專案建置
16 核心 / 64 GB~$1.44機器學習、重度編譯

企業建議

  • 在 Template Repo 中預先配置 .devcontainer,確保所有新專案支援 Codespaces
  • 設定 Idle Timeout 和機器類型上限控制成本
  • 核心專案啟用 Prebuild 減少等待時間
  • 配合 Secret Management 確保 Codespace 中不暴露生產環境憑證

18.3 GitHub Packages 套件管理

GitHub Packages 是 GitHub 內建的套件託管服務,支援多種套件格式,與 Repository 和 Actions 深度整合。

支援的套件格式

格式Registry用途
Container(Docker)ghcr.ioDocker / OCI 映像
Mavenmaven.pkg.github.comJava / Kotlin 套件
npmnpm.pkg.github.comJavaScript / TypeScript
NuGetnuget.pkg.github.com.NET 套件
RubyGemsrubygems.pkg.github.comRuby 套件

Maven 套件發佈配置

<!-- pom.xml -->
<distributionManagement>
  <repository>
    <id>github</id>
    <name>GitHub Packages</name>
    <url>https://maven.pkg.github.com/acme-bank/platform-java-lib-core</url>
  </repository>
</distributionManagement>
<!-- settings.xml -->
<servers>
  <server>
    <id>github</id>
    <username>${env.GITHUB_ACTOR}</username>
    <password>${env.GITHUB_TOKEN}</password>
  </server>
</servers>

自動發佈 Workflow

# .github/workflows/publish-package.yml
name: Publish Package

on:
  release:
    types: [published]

permissions:
  contents: read
  packages: write

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '21'
          cache: 'maven'

      - name: Publish to GitHub Packages
        run: mvn deploy -B -DskipTests
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Container Image 發佈

# .github/workflows/publish-container.yml
name: Publish Container Image

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

permissions:
  contents: read
  packages: write

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

      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build & Push
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: |
            ghcr.io/${{ github.repository }}:${{ github.ref_name }}
            ghcr.io/${{ github.repository }}:latest

Packages 儲存配額

GitHub 方案儲存空間傳輸頻寬(月)
Free500 MB1 GB
Team2 GB10 GB
Enterprise50 GB100 GB

企業建議:使用 GitHub Packages 作為內部共用庫的統一發佈平台,搭配 Release Workflow 實現「Tag → Build → Test → Publish」全自動化。Container Image 統一使用 ghcr.io 避免外部 Registry 依賴。

18.4 GitHub Discussions 社群協作

GitHub Discussions 提供結構化的社群討論空間,適合用於技術問答、設計提案、公告等非 Issue 性質的交流。

Discussions vs Issues

面向IssuesDiscussions
用途可追蹤的工作項目(Bug / Feature)開放式討論、問答、公告
狀態追蹤Open / ClosedOpen / Answered / Closed
Assignee
Label
轉換可轉換為 Issue
投票Reactions✅ 正式投票功能
分類LabelCategory(結構化分類)

建議的 Discussion Category 設計

CategoryEmoji用途格式
Announcements📣團隊公告、重大變更Announcement
Architecture🏗️架構設計討論、RFCOpen-ended
Q&A💬技術問題與解答Question / Answer
Ideas💡功能建議、改善想法Open-ended
Show and Tell🎉分享成果、DemoOpen-ended
RFC📝Request for CommentsPoll
# 使用 GitHub CLI 建立 Discussion
gh discussion create \
  --repo acme-bank/svc-order-api \
  --title "RFC: 訂單服務 Event Schema 設計" \
  --body "提案內容..." \
  --category "Architecture"

企業建議

  • 使用 Discussions 取代非正式的 Slack / Email 技術討論,確保知識可被搜尋與沉澱
  • 架構決策先在 Discussions 討論,達成共識後轉為 ADR
  • 啟用 Announcements 類別作為團隊正式公告管道
  • 善用「轉換為 Issue」功能,將討論中產生的行動項目轉為可追蹤的工作

附錄 A:快速檢查清單

A.1 Repository 建立快速清單

□ 確認 Repository 名稱符合規範
□ 從 Template 建立(非空白建立)
□ 設定 Visibility(Private)
□ 初始化 README / .gitignore / LICENSE
□ 設定 CODEOWNERS
□ 啟用 Branch Protection
□ 配置 CI/CD Workflow
□ 啟用 Dependabot
□ 啟用 Secret Scanning
□ 啟用 CodeQL
□ 設定 Team 權限
□ 建立 develop branch
□ 建立 Issue Template + PR Template

A.2 Pull Request 審查清單

□ PR Title 符合 Conventional Commits
□ PR 描述清楚說明變更目的
□ 關聯對應的 Issue
□ CI 全部通過
□ 無安全告警
□ 有對應的測試
□ 程式碼遵循架構規範
□ 無硬編碼敏感資訊
□ 文件已更新(如適用)
□ CODEOWNERS 已 Approve

A.3 Release 檢查清單

□ 所有 CI 檢查通過
□ Security Scan 無 Critical/High 漏洞
□ 版本號符合 Semantic Versioning
□ Changelog 已生成
□ Tag 已建立(Annotated Tag)
□ Release Notes 已撰寫
□ Staging 環境驗證通過
□ Production 部署計畫已審核
□ Rollback 計畫已備妥
□ 相關團隊已通知

A.4 季度 Repository 治理清單

□ 權限審查完成(移除離職/轉調人員)
□ 已合併的 Branch 已清理
□ Secret 輪換完成
□ Dependabot PR 已處理
□ 無活動 Repo 已標記 Deprecated
□ Branch Protection 規則確認
□ CI/CD Pipeline 效能檢視
□ Security Alert 清零(Critical/High)
□ 文件更新確認(README / ADR)
□ 團隊 CODEOWNERS 更新

結語:本手冊涵蓋了 GitHub Repository 從建立到維運的完整生命週期。GitHub 平台持續演進,建議團隊每半年審閱本手冊並更新內容。Repository 管理的核心精神是:自動化 > 人工預防 > 修復一致性 > 靈活性


Document End — Total 18 Chapters + Appendix