ci-cd · git:20260826.34a9b20 · 2026-08-26 · sha256 21014c889cdb4532

ci-cd git:20260826.34a9b20A

Immutable. This exact content is served forever at /api/v1/blob/21014c889cdb4532.

---
name: ci-cd
description: GitHub Actions CI/CD 파이프라인 설계 및 자동화
compatibility: omp
---

# CI/CD Skill

GitHub Actions 기반 CI/CD 파이프라인을 설계하는 스킬입니다.

## CI 파이프라인 (Pull Request)

```yaml
name: CI
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

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

      - uses: actions/setup-go@v5
        with:
          go-version-file: go.mod

      - name: 의존성 캐시
        uses: actions/cache@v4
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }}

      - name: 테스트
        run: go test -race -coverprofile=coverage.out ./...

      - name: 커버리지 확인
        run: |
          COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
          echo "Coverage: ${COVERAGE}%"
          if (( $(echo "$COVERAGE < 85" | bc -l) )); then
            echo "커버리지 85% 미달"
            exit 1
          fi

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: golangci/golangci-lint-action@v6
        with:
          version: latest

  build:
    runs-on: ubuntu-latest
    needs: [test, lint]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version-file: go.mod
      - run: go build ./...
```

## CD 파이프라인 (릴리스)

```yaml
name: Release
on:
  push:
    tags: ['v*']

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

      - uses: actions/setup-go@v5
        with:
          go-version-file: go.mod

      - uses: goreleaser/goreleaser-action@v6
        with:
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

## GoReleaser 설정

```yaml
# .goreleaser.yml
version: 2
builds:
  - main: ./cmd/app
    binary: app
    env:
      - CGO_ENABLED=0
    goos: [linux, darwin, windows]
    goarch: [amd64, arm64]
    ldflags:
      - -s -w
      - -X main.version={{.Version}}

archives:
  - format: tar.gz
    format_overrides:
      - goos: windows
        format: zip

changelog:
  sort: asc
  filters:
    exclude:
      - '^docs:'
      - '^test:'
```

## 파이프라인 설계 원칙

### 빠른 피드백
```
lint (1분) → 단위 테스트 (2분) → 통합 테스트 (5분) → 빌드 (1분)
     ↓              ↓                    ↓
   빠른 실패     빠른 실패           빠른 실패
```

### 캐싱 전략
- Go 모듈 캐시: `~/go/pkg/mod`
- 빌드 캐시: `~/.cache/go-build`
- Docker 레이어 캐시: `docker/build-push-action` cache

### 시크릿 관리
- GitHub Secrets 사용
- `.env` 파일 커밋 금지
- OIDC 토큰 활용 (클라우드 배포)

## 체크리스트

- [ ] PR에 테스트 + 린트 자동 실행
- [ ] 커버리지 85% 게이트
- [ ] 의존성 캐싱 설정
- [ ] 태그 기반 릴리스 자동화
- [ ] 시크릿 하드코딩 없음
- [ ] 병렬 실행으로 피드백 시간 최소화