# บทที่ 10: Build Automation Pipeline

## หัวข้อหลัก

- Build Tools และ Automation
- Continuous Integration (CI)
- Build Pipeline Architecture
- Tool Chains และ Best Practices

---

## 📑 สารบัญ

1. [บทบาทของ Build Automation](#1-บทบาทของ-build-automation)
2. [Build Tools สำหรับ JavaScript/Node.js](#2-build-tools-สำหรับ-javascriptnodejs)
   - [2.1 npm](#21-npm-node-package-manager)
   - [2.2 Webpack](#22-webpack)
   - [2.3 Vite](#23-vite)
   - [2.4 เปรียบเทียบ](#24-เปรียบเทียบ-build-tools)

3. [Continuous Integration (CI)](#3-continuous-integration-ci)
   - [3.1 CI Pipeline Stages](#31-ci-pipeline-stages)
   - [3.2 GitHub Actions Quick Start](#32-github-actions-quick-start)
   - [3.3 GitHub Actions Example](#33-github-actions-ci-example)
   - [3.4 GitLab CI](#34-gitlab-ci-example)
   - [3.5 Jenkins](#35-jenkins-pipeline-example)

4. [Code Quality Tools](#4-code-quality-tools)
   - [4.1 ESLint](#41-eslint-linting)
   - [4.2 Prettier](#42-prettier-code-formatting)

5. [Build Artifacts & Docker](#5-build-artifacts--docker)

6. [Best Practices](#6-best-practices)

7. [Troubleshooting](#7-troubleshooting-common-build-issues)

8. [Complete CI/CD Configuration](#8-complete-cicd-configuration)

---

## 1. บทบาทของ Build Automation

### 1.1 Definition

Build Automation คือ กระบวนการอัตโนมัติที่รวบรวม (compile), test, package, และ deploy source code โดยไม่ต้องแทรกแซงจากมนุษย์

### 1.2 ประโยชน์

```
┌─────────────────────────────────────┐
│   Build Automation Benefits         │
├─────────────────────────────────────┤
│ 1. ลด Human Error                   │
│ 2. เพิ่ม Build Consistency            │
│ 3. เร็ว Feedback Loop                 │
│ 4. Scalable Build Process           │
│ 5. Reproducible Builds              │
│ 6. Faster Integration               │
│ 7. Early Bug Detection              │
└─────────────────────────────────────┘
```

---

## 2. Build Tools สำหรับ JavaScript/Node.js

### 2.1 npm (Node Package Manager)

**npm scripts คือ Build Tool พื้นฐาน**

```json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "test": "jest",
    "test:watch": "jest --watch",
    "lint": "eslint src/**/*.ts",
    "lint:fix": "eslint src/**/*.ts --fix",
    "format": "prettier --write src/",
    "type-check": "tsc --noEmit",
    "pretest": "npm run lint && npm run type-check",
    "prepare": "npm run build"
  }
}
```

**ข้อดี:**

- Built-in ใน Node.js
- Simple และ flexible
- ใช้ได้ทั้ง build, test, lint, deploy

**ข้อเสีย:**

- ไม่มี Task Dependencies ตรงๆ
- Script สามารถซับซ้อนได้ขึ้น
- Cross-platform Issues

### 2.2 Webpack

Build bundler ที่ powerful สำหรับ Web Applications

**webpack.config.js:**

```javascript
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const TerserPlugin = require("terser-webpack-plugin");

module.exports = {
  mode: "production", // Minify + Optimize สำหรับ production
  entry: "./src/index.ts", // จุดเริ่มต้นของ project

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].[contenthash].js", // Cache busting
  },

  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: "ts-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },

  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()],
    splitChunks: {
      // แยก vendor code เป็น file แยก
      chunks: "all",
      cacheGroups: {
        vendor: {
          // node_modules → vendors.js
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
          priority: 10,
        },
      },
    },
  },

  devtool: "source-map", // ให้ debug ได้

  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css",
    }),
  ],
};
```

**ข้อดี:**

- Powerful และ flexible
- Code Splitting
- Source Maps
- Plugin ecosystem ใหญ่

**ข้อเสีย:**

- Configuration ซับซ้อน
- Learning Curve สูง
- Build Time อาจนาน

### 2.3 Vite

Modern Build Tool สำหรับ Development ที่รวดเร็ว

**vite.config.ts:**

```typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  build: {
    target: "es2020",
    outDir: "dist",
    sourcemap: true,
  },
  server: {
    port: 3000,
    proxy: {
      "/api": "http://localhost:5000",
    },
  },
});
```

**ข้อดี:**

- ESM native ⚡
- HMR (Hot Module Replacement) ที่ fast
- ถูกและง่ายต่อการ configure
- ดีกับ Modern Project

**ข้อเสีย:**

- ยังใหม่ ecosystem น้อย
- Legacy project อาจต้อง Webpack

### 2.4 เปรียบเทียบ Build Tools

| Tool        | Use Case                 | Learning Curve | Speed         |
| ----------- | ------------------------ | -------------- | ------------- |
| npm scripts | Simple projects          | Easy           | Fast Setup    |
| Webpack     | Large, complex projects  | Steep          | Slower builds |
| Vite        | Modern, fast development | Easy           | Very Fast     |

**คำแนะนำเลือก Tools:**

- **npm scripts**: เก่ง JavaScript แล้ว แค่ต้องการ simple automation
- **Webpack**: Project โต + ต้อง code splitting, advanced optimization
- **Vite**: เริ่มต้น modern project, ต้องการ fast dev server

---

## 3. Continuous Integration (CI)

### 3.1 CI Pipeline Stages

```
┌──────────────┐
│  Code Push   │
└──────┬───────┘
       │ (Webhook: Push Event)
       ↓
┌──────────────────────────────────┐
│  1. Checkout Code                │
│     - Clone Repository           │
│     - Checkout Specific Branch   │
└──────┬───────────────────────────┘
       ↓
┌──────────────────────────────────┐
│  2. Install Dependencies         │
│     - npm install                │
│     - npm ci (Recommended)       │
└──────┬───────────────────────────┘
       ↓
┌──────────────────────────────────┐
│  3. Lint & Format Check          │
│     - ESLint                     │
│     - Prettier                   │
│     - TypeScript Compilation     │
└──────┬───────────────────────────┘
       │        ❌ Fail → Reject PR
       ↓
┌──────────────────────────────────┐
│  4. Unit Tests                   │
│     - Jest                       │
│     - Vitest                     │
│     - Code Coverage Check        │
└──────┬───────────────────────────┘
       │        ❌ Fail → Reject PR
       ↓
┌──────────────────────────────────┐
│  5. Build                        │
│     - npm run build              │
│     - Artifact Generation        │
└──────┬───────────────────────────┘
       │        ❌ Fail → Reject PR
       ↓
┌──────────────────────────────────┐
│  6. Integration Tests (Optional) │
│     - e2e Tests                  │
│     - API Tests                  │
└──────┬───────────────────────────┘
       │        ❌ Fail → Reject PR
       ↓
┌──────────────────────────────────┐
│  7. Security Scan (Optional)     │
│     - Dependency Check           │
│     - SAST                       │
│     - Secret Scan                │
└──────┬───────────────────────────┘
       │        ❌ Fail → Reject PR
       ↓
┌──────────────────────────────────┐
│  8. Code Quality Analysis        │
│     - SonarQube                  │
│     - CodeClimate                │
└──────┬───────────────────────────┘
       │        ❌ Fail → Reject PR
       ↓
✅ All Passed → Approve PR
```

**คำอธิบาย:**

- **Webhook**: Code push → GitHub auto trigger pipeline ทันที
- **❌ Fail → Reject PR**: ถ้า step ไหนล้มเหลง ก็บล็อก PR → ป้องกัน bad code เข้า main
- **✅ All Passed**: ทุก step ผ่าน → PR ได้ approve + merge

### 3.2 GitHub Actions Quick Start

**สำหรับผู้เริ่มต้น:** ขั้นตอน 3 ข้อสำหรับ setup GitHub Actions:

```bash
# 1. สร้าง folder
mkdir -p .github/workflows

# 2. สร้างไฟล์ ci.yml
cat > .github/workflows/ci.yml << 'EOF'
name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build
EOF

# 3. Push ขึ้น GitHub
git add .github/workflows/ci.yml
git commit -m "Add CI workflow"
git push

# 4. ดูผลลัพธ์
# - ไป https://github.com/username/repo/actions
# - ดู status: ✅ (passed) หรือ ❌ (failed)
# - ถ้า failed → กดเข้าดูรายละเอียด error
```

เสร็จ! ✅ GitHub Actions จะ run ทุกครั้งที่มี push

### 3.3 GitHub Actions CI Example

**.github/workflows/ci.yml**

```yaml
name: Node.js CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix: # Test ใหม่ Node versions พร้อมกัน
        node-version: [16.x, 18.x, 20.x] # สร้าง 3 jobs ขนาน

      # ตัวอย่าง: GitHub จะสร้าง 3 jobs:
      # Job 1: node-version: 16.x
      # Job 2: node-version: 18.x
      # Job 3: node-version: 20.x
      # ทั้ง 3 jobs run พร้อมกัน → Test เร็วกว่า

    steps:
      # 1. Checkout Code
      - name: Checkout code
        uses: actions/checkout@v3

      # 2. Setup Node.js
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"

      # 3. Install Dependencies
      - name: Install dependencies
        run: npm ci

      # 4. Lint
      - name: Run linter
        run: npm run lint

      # 5. Type Check
      - name: Type check
        run: npm run type-check

      # 6. Run Tests
      - name: Run tests
        run: npm test -- --coverage

      # 7. Upload Coverage
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          file: ./coverage/coverage-final.json
          flags: unittests
          name: codecov-umbrella

      # 8. Build
      - name: Build
        run: npm run build

      # 9. Build Docker Image (Optional)
      - name: Build Docker image
        if: github.ref == 'refs/heads/main'
        run: |
          docker build -t myapp:${{ github.sha }} .
          docker tag myapp:${{ github.sha }} myapp:latest
```

### 3.4 GitLab CI Example

**GitLab CI มีอะไรดี:**

- Built-in ใน GitLab (ไม่ต้อง setup เพิ่ม)
- `.gitlab-ci.yml` เหมือน GitHub Actions แต่ syntax ต่างกัน
- Free tier: 400 minuts/month
- ถ้า GitLab Project → ใช้ GitLab CI

**.gitlab-ci.yml**

```yaml
stages:
  - install
  - test
  - build
  - deploy

variables:
  IMAGE: node:18
  NPM_CACHE_DIR: "$CI_PROJECT_DIR/.npm"

cache:
  paths:
    - .npm/
    - node_modules/

install:
  stage: install
  image: $IMAGE
  script:
    - npm ci --prefer-offline --no-audit
  artifacts:
    paths:
      - node_modules/
    expire_in: 1 day

lint:
  stage: test
  image: $IMAGE
  dependencies:
    - install
  script:
    - npm run lint

test:
  stage: test
  image: $IMAGE
  dependencies:
    - install
  script:
    - npm test -- --coverage
  coverage: '/Lines\s*:\s*(\d+\.\d+)%/'
  artifacts:
    reports:
      junit: junit.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

build:
  stage: build
  image: $IMAGE
  dependencies:
    - install
  script:
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 day

deploy_staging:
  stage: deploy
  image: alpine:latest
  dependencies:
    - build
  script:
    - echo "Deploying to staging..."
    -  # Deploy script here
  environment:
    name: staging
    url: https://staging.example.com
  only:
    - develop

deploy_production:
  stage: deploy
  image: alpine:latest
  dependencies:
    - build
  script:
    - echo "Deploying to production..."
    -  # Deploy script here
  environment:
    name: production
    url: https://example.com
  only:
    - main
  when: manual # Manual approval required
```

### 3.5 Jenkins Pipeline Example

**Jenkins มีอะไรดี:**

- Self-hosted (รัน server ตัวเอง)
- Enterprise grade - ใช้ใน Large organizations
- Plugin ecosystem ใหญ่ที่สุด
- Setup ยุ่งกว่า GitLab/GitHub Actions
- ใช้เมื่อ: GitHub/GitLab ไม่เพียงพอ เช่น ต้อง custom integration

**Jenkinsfile**

```groovy
pipeline {
    agent any

    triggers {
        githubPush()  // Trigger on push
    }

    environment {
        NODE_ENV = 'test'
        NPM_CONFIG_CACHE = '.npm-cache'
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Install') {
            steps {
                sh 'npm ci'
            }
        }

        stage('Lint') {
            steps {
                sh 'npm run lint'
            }
        }

        stage('Type Check') {
            steps {
                sh 'npm run type-check'
            }
        }

        stage('Test') {
            steps {
                sh 'npm test -- --coverage'
            }
            post {
                always {
                    junit 'junit.xml'
                    publishHTML([
                        reportDir: 'coverage',
                        reportFiles: 'index.html',
                        reportName: 'Code Coverage'
                    ])
                }
            }
        }

        stage('Build') {
            steps {
                sh 'npm run build'
            }
        }

        stage('Archive') {
            steps {
                archiveArtifacts artifacts: 'dist/**',
                                 allowEmptyArchive: false
            }
        }
    }

    post {
        always {
            cleanWs()
        }
        success {
            echo 'Build successful!'
        }
        failure {
            echo 'Build failed!'
        }
    }
}
```

---

## 4. Code Quality Tools

### 4.1 ESLint (Linting)

**.eslintrc.json**

```json
{
  "env": {
    "es2021": true,
    "node": true,
    "browser": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": ["@typescript-eslint", "react", "react-hooks", "import"],
  "rules": {
    "no-console": ["warn", { "allow": ["warn", "error"] }],
    "no-var": "error",
    "prefer-const": "error",
    "@typescript-eslint/no-unused-vars": "error",
    "@typescript-eslint/explicit-function-return-types": "warn",
    "react/react-in-jsx-scope": "off",
    "react-hooks/rules-of-hooks": "error"
  }
}
```

**ตัวอย่าง - โค้ดที่ ESLint จะแสดง:**

```javascript
// ❌ Bad - ESLint errors
var name = "John";  // ❌ prefer-const: ต้อง const หรือ let
console.log(name);  // ❌ no-console: warn
function test(a: any) {  // ❌ explicit-function-return-types
  return a * 2;
}

// ✅ Good - ผ่าน ESLint
const name = "John";  // OK ใช้ const
// console.log(name);  // ลบ console ออก หรือเพิ่มเข้า allow list
function test(a: number): number {  // มี return type
  return a * 2;
}
```

### 4.2 Prettier (Code Formatting)

**Prettier = Automatic Code Formatter**

- ทำให้ code format ตรงกัน (whitespace, quotes, brackets)
- ไม่ต้องแต่งเอง - รัน `prettier --write` ได้
- ต่างจาก ESLint: ESLint = style/logic, Prettier = formatting only

**.prettierrc** (คำอธิบาย settings สำคัญ)

```json
{
  "semi": true, // เพิ่ม ; ท้ายบรรทัด
  "singleQuote": true, // ใช้ 'string' แทน "string"
  "printWidth": 80, // บรรทัดสูงสุด 80 ตัวอักษร
  "tabWidth": 2, // indent = 2 spaces
  "useTabs": false, // ใช้ space แทน tab
  "trailingComma": "es5", // เพิ่م trailing comma ใน array/object
  "arrowParens": "always", // (x) => x แทน x => x
  "bracketSpacing": true, // { x: 1 } แทน {x: 1}
  "endOfLine": "lf" // Unix line endings (LF)
}
```

---

## 5. Build Artifacts & Docker

### 5.1 Build Artifacts

**Build Artifacts = เก็บ Build Results ไว้ download/deploy**

- `dist/` → Production files (HTML, JS, CSS)
- `coverage/` → Test coverage report
- ทำไมต้อง? → Reuse build ได้ (ไม่ต้อง rebuild)

**Retention policy:**

- `dist`: 30 วัน (เก็บนาน เผื่อ deploy หลาย versions)
- `coverage`: 7 วัน (ไม่ต้องเก็บนาน ใช้เช็ก trends)

```yaml
artifacts:
  - name: dist # ชื่อ artifact
    path: dist/ # ไฟล์ที่เก็บ
    retention: 30 days # เก็บไว้ 30 วัน

  - name: coverage
    path: coverage/
    retention: 7 days # เก็บไว้ 7 วัน
```

### 5.2 Docker Image Creation

**Dockerfile**

```dockerfile
# Multi-stage build
FROM node:18-alpine AS builder

WORKDIR /app

# Copy package files
COPY package*.json ./
RUN npm ci

# Copy source
COPY . .

# Build
RUN npm run build

# Production stage
FROM node:18-alpine

WORKDIR /app

# Install only production dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy built app from builder
COPY --from=builder /app/dist ./dist

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
  CMD node healthcheck.js

EXPOSE 3000

CMD ["node", "dist/index.js"]
```

**คำอธิบาย Multi-stage Build:**

```
Stage 1: Builder (ไฟล์ใหญ่)
- รวม node_modules + source + build tool (npm, tsc, etc.)
- ขนาด ~1GB (เต็มไปด้วย dev dependencies)

Stage 2: Production (ไฟล์เล็ก)
- เฉพาะ runtime + production code
- ขนาด ~150MB (ลด ~85% จาก builder)

ผลลัพธ์: Image สำหรับ production เล็กกว่า → Deploy เร็ว, ใช้Resource น้อย
```

---

## 6. Best Practices

```markdown
## Build Pipeline Best Practices

1. **Keep Builds Fast**
   - parallelize tasks
   - use caching
   - optimize dependencies
   - Target: < 5 minutes

2. **Fail Fast Principle**
   - Lint first (cheap)
   - Then test (medium)
   - Then build (expensive)
   - Stop pipeline on first failure

3. **Use Caching Strategically**
   - Cache node_modules
   - Cache build artifacts
   - Clear cache selectively

4. **Artifact Management**
   - Keep artifacts for reasonable time
   - Upload to artifact registry
   - Version your artifacts

5. **Reproducible Builds**
   - Use lock files (package-lock.json)
   - Use npm ci instead of npm install
   - Specify exact versions

6. **Monitor & Alert**
   - Track build duration trends
   - Alert on failures
   - Monitor artifact sizes

7. **Security in Pipeline**
   - Scan dependencies
   - Scan for secrets
   - Run SAST analysis
   - Update regularly

8. **Documentation**
   - Document build process
   - Maintain runbook
   - Clear error messages

9. **Environment Consistency**
   - Use Docker for consistency
   - Match development env
   - Use env files properly

10. **Version Control**
    - Version everything
    - Tag releases
    - Document changes in CHANGELOG
```

---

## 7. Troubleshooting Common Build Issues

**Build Failed? ตรวจสอบจุดนี้:**

| ปัญหา                | สาเหตุ               | วิธีแก้                                           |
| -------------------- | -------------------- | ------------------------------------------------- |
| `npm ci` ล้มเหลว     | Dependency conflict  | อัปเดท package.json หรือ delete package-lock.json |
| Lint error           | Code style ผิด       | รัน `npm run lint:fix` เพื่อ auto-fix             |
| Test ล้มเหลว         | Logic error          | ดู error message → แก้โค้ด + รัน test ใหม่        |
| Build ล้มเหลว        | Missing files/config | ตรวจสอบ tsconfig.json หรือ build config           |
| Docker build ล้มเหลว | Base image issue     | ลองใช้ tag ที่ชัดเจน (e.g., node:18-alpine)       |

**Debug Tips:**

```bash
# ดู full error message
npm run build 2>&1 | tail -20

# Test เฉพาะ file หนึ่ง
npm test -- path/to/file.test.ts

# เซต debug log
DEBUG=* npm run ci
```

---

## 8. Complete CI/CD Configuration

**Real-world Example: Node.js API Project**

**.github/workflows/main.yml**

```yaml
name: Build and Test

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:14
        env:
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
          POSTGRES_DB: testdb
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Set up Node
        uses: actions/setup-node@v3
        with:
          node-version: "18"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Type check
        run: npm run type-check

      - name: Run tests
        env:
          DATABASE_URL: postgresql://test:test@localhost:5432/testdb
        run: npm test -- --coverage

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          files: ./coverage/lcov.info

      - name: Build
        run: npm run build

      - name: Build and push Docker image
        if: github.ref == 'refs/heads/main'
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          registry: ${{ env.REGISTRY }}
          tags: |
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}

  deploy:
    needs: build
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest

    steps:
      - name: Trigger deployment
        run: |
          curl -X POST https://api.vercel.com/v13/deployments \
            -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d '{"deploymentId": "${{ github.sha }}"}'
```

---

## สรุป

Build Automation Pipeline คือ Foundation ของ CI/CD:

1. **Automation ทุกอย่าง** - Compile, Test, Build, Deploy
2. **Fast Feedback** - ทำให้ Developer รู้เร็ว ถ้า Build ล้มเหลว
3. **Quality Gates** - ตรวจสอบ Code Quality ก่อน Merge
4. **Scalability** - สามารถ Build ขนาดใหญ่ได้
5. **Consistency** - Build ต่าง environment เสมอตรงกัน

Pipeline ที่ดี = Faster Development + Better Quality + Lower Risk
