---
id: devops-renovate-dependabot
title: Dependency 자동 update — Renovate / Dependabot
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [devops, dependencies, security, vibe-coding]
tech_stack: { language: "JSON / YAML", applicable_to: ["DevOps"] }
applied_in: []
aliases: [Renovate, Dependabot, npm audit, dependency update, auto merge, lockfile]
---

# Dependency 자동 Update

> Dep 가 stale = security risk + breaking change 한꺼번. **Renovate / Dependabot 가 자동 PR**. 자동 merge (안전한 거).

## 📖 핵심 개념
- 매 dep 가 매주 새 release.
- 안 update = 1년 후 100+ 변경 한꺼번.
- Auto-update + auto-merge (test pass 시).
- Major / minor / patch 별 strategy.

## 💻 코드 패턴

### Dependabot (GitHub 내장)
```yaml
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: 'npm'
    directory: '/'
    schedule:
      interval: 'weekly'
    open-pull-requests-limit: 10
    versioning-strategy: 'increase'
    
  - package-ecosystem: 'docker'
    directory: '/'
    schedule:
      interval: 'monthly'
```

→ 매 주 PR. GitHub native.

### Renovate (강력)
```json
// renovate.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:recommended",
    ":automergePatch"
  ],
  "schedule": ["after 8am every weekday"],
  "packageRules": [
    {
      "matchUpdateTypes": ["minor", "patch"],
      "automerge": true
    },
    {
      "matchPackagePatterns": ["^@types/"],
      "automerge": true,
      "matchUpdateTypes": ["major", "minor", "patch"]
    },
    {
      "matchPackagePatterns": ["react"],
      "automerge": false
    }
  ],
  "rangeStrategy": "bump"
}
```

→ Renovate 가 auto-merge + custom rule 가 강력.

### Auto-merge (안전)
```
조건:
- Test pass (CI green)
- No conflicts
- Patch / minor 만 (semver)
- 작은 lib (devDependencies)

→ Manual review 안 함.
```

### Major version (manual)
```
React 18 → 19:
- API breaking
- Manual review 필수
- Migration guide 읽기
- 별 PR 가 grouping
```

→ Renovate `groupName` 으로 묶음.

```json
{
  "packageRules": [
    {
      "matchPackagePatterns": ["react", "react-dom"],
      "groupName": "react"
    }
  ]
}
```

### Lockfile maintenance
```json
{
  "lockFileMaintenance": {
    "enabled": true,
    "schedule": ["after 2am on Sunday"]
  }
}
```

→ `package-lock.json` 의 transitive dep 도 update.

### Schedule
```json
{
  "schedule": [
    "after 9am on monday",
    "after 9am on wednesday"
  ]
}
```

→ 평일 morning. 주말 / 새벽 X.

### Concurrent PR limit
```json
{
  "prConcurrentLimit": 5,
  "prHourlyLimit": 2
}
```

→ 100+ PR 한꺼번 X.

### Vulnerability alert
```yaml
# Dependabot security alert
security-updates:
  open-pull-requests-limit: 10
  schedule:
    interval: 'daily'
```

→ CVE 공개 = 자동 PR 다음날.

### npm audit
```bash
npm audit
# critical: 2, high: 5, moderate: 12

npm audit fix
# 자동 fix patch 만.

npm audit fix --force
# major 도 — breaking 가능.
```

### Snyk / Socket / GitHub
```
- Snyk: SaaS, deep scan
- Socket: malicious / typosquatting
- GitHub Advanced Security

→ Renovate + Snyk = belt + suspenders.
```

### Lockfile
```bash
# npm
npm install            # → package-lock.json
npm ci                  # CI: lock 그대로

# yarn
yarn install            # → yarn.lock
yarn install --frozen-lockfile  # CI

# pnpm
pnpm install            # → pnpm-lock.yaml

# Bun
bun install             # → bun.lockb
```

→ Lock = reproducible build.

### Ranges
```json
// package.json
"react": "^19.0.0"      // 19.x.x (caret)
"react": "~19.0.0"      // 19.0.x (tilde)
"react": "19.0.0"       // 정확
"react": "*"            // ❌ 위험
```

→ Caret default. 정확 = library / public package.

### Library author
```json
// 라이브러리 publish
{
  "peerDependencies": {
    "react": ">=18"
  }
}
```

→ `peer` = host project 가 install.

### Renovate 가 자동 fail PR 닫음
```json
{
  "rebaseWhen": "never",
  "stabilityDays": 3,
  "internalChecksFilter": "strict"
}
```

→ 새 release 가 3일 후 (bug 가능성).

### CI 가 매 PR 통과 가정
```yaml
# .github/workflows/test.yml
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test
      - run: npm run build
```

→ 매 dep PR 가 test 자동 실행.

### Auto-merge GitHub action
```yaml
# .github/workflows/auto-merge.yml
name: auto-merge
on: pull_request
jobs:
  auto-merge:
    if: github.actor == 'renovate[bot]'
    runs-on: ubuntu-latest
    steps:
      - uses: pascalgn/automerge-action@v0.16.4
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          MERGE_METHOD: squash
          MERGE_LABELS: 'automerge'
```

### License check
```bash
# License compatibility
npx license-checker --production --onlyAllow="MIT;Apache-2.0;BSD-3-Clause;ISC"
```

→ GPL / unknown 가 들어옴 = 차단.

### Provenance / SLSA
```json
// npm 9+
{
  "publishConfig": {
    "provenance": true
  }
}
```

→ Build 의 source / commit 가 검증.

### Supply chain attack
```
2018 event-stream: 작은 dep 이 큰 framework 종속.
2021 ua-parser-js: maintainer hijack.
2024 xz: open source backdoor.

방어:
- Renovate stabilityDays
- Socket scan (typosquatting, malicious)
- Pin specific version (lock)
- Audit transitive deps (npm audit signatures)
```

### Monorepo (workspace)
```json
{
  "extends": [
    "config:recommended",
    "monorepo:turborepo"
  ]
}
```

→ Workspace 별 version lock.

### Postinstall 함정
```json
// postinstall script 가 임의 코드 실행.
"scripts": {
  "postinstall": "rm -rf /"  // ❌ 악성
}
```

→ `--ignore-scripts` flag (CI). pnpm 가 default 약간 안전.

### Dead dep 제거
```bash
npx depcheck
# Unused dependencies:
# - lodash
# - moment
```

→ `package.json` 에 있지만 안 쓰임 — 삭제.

### Audit signatures (npm 9+)
```bash
npm audit signatures
# → 모든 dep 가 서명 검증.
```

→ Provenance 가 published 매 package 가 signed origin.

### CI duration
```
Test 가 30 min = renovate 가 매 PR 30 min.
하루 5 PR = 2.5 hour CI 시간.

→ Cache + parallel 가 cost.
```

### "Wait, why is this PR breaking?"
```
CHANGELOG 읽기.
GitHub release notes.
Major = 의도적 breaking.
Patch = 의도적 fix — but bug 가능.

→ Auto-merge 가 한 번 잘못 = test 가 미커버.
```

### Self-host Renovate
```yaml
# .github/workflows/renovate.yml
on:
  schedule: [{ cron: '0 8 * * 1-5' }]
  workflow_dispatch:
jobs:
  renovate:
    runs-on: ubuntu-latest
    steps:
      - uses: renovatebot/github-action@v40
        with:
          token: ${{ secrets.RENOVATE_TOKEN }}
```

→ App 설치 안 하고 self-host.

## 🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| GitHub native | Dependabot |
| Power user | Renovate |
| Auto-merge patch | Renovate `:automergePatch` |
| 큰 library (React) | Manual review |
| Vulnerability | Daily security PR |
| Supply chain | Snyk + Socket |
| Self-host | Renovate workflow |
| 작은 / 단순 | Dependabot 충분 |

## ❌ 안티패턴
- **No update**: 1년 후 100+ stale.
- **모두 auto-merge**: major breaking 가 production 갈 수.
- **Test 약함 + auto-merge**: 실수 통과.
- **Renovate 비활성**: stale.
- **`*` version**: Russian roulette.
- **Postinstall scripts 신뢰**: 위험.
- **Lock 없음**: drift.

## 🤖 LLM 활용 힌트
- Renovate 가 Dependabot 보다 강력.
- Auto-merge patch / minor + manual major.
- Stability days 가 supply chain 보호.
- License + audit 도.

## 🔗 관련 문서
- [[DevSec_Supply_Chain]]
- [[DevOps_CI_CD_Pipeline_Patterns]]
- [[Security_Secrets_Management]]
