notes
CICD - semantic-release
CI/CD 파이프라인에 semantic-release를 붙이는 설정·릴리스 흐름 메모.
커밋 메시지 컨벤션(feat/fix/…)만 맞춰 두면 버전·CHANGELOG·깃 태그를 자동으로 올려 주는 게 semantic-release다. Jenkinsfile 쪽은 MD - semantic-release 글에 따로 있다.
- 커밋 메시지만 컨벤션대로 쓰면 버전, CHANGELOG, 태그를 CI가 알아서 올린다.
- fix·docs 같은 건 patch, feat는 minor, BREAKING CHANGE는 major다.
- 컨벤션에 안 맞는 커밋만 있으면 릴리스가 안 나간다. 태그가 안 생기면 커밋 로그부터 본다.
흐름
브랜치에 푸시될 때만 돌리게 해서, 로컬에서 버전을 수동으로 올리지 않는다. package.json version은 0.0.0-development처럼 두고 도구가 채우게 하는 편.
내가 쓰는 .releaserc.json
{
"branches": ["main", "dev/test", "dev/style", "dev/kms"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
[
"@semantic-release/git",
{
"message": "chore(release): v${nextRelease.version} [skip ci]"
}
]
],
"releaseRules": [
{ "type": "docs", "release": "patch" },
{ "type": "refactor", "release": "patch" },
{ "type": "style", "release": "patch" },
{ "type": "test", "release": "patch" },
{ "type": "chore", "release": "patch" },
{ "type": "feat", "release": "minor" },
{ "type": "fix", "release": "patch" }
]
}
포인트:
- branches — main만이 아니라 팀에서 쓰는 dev/* 도 릴리스 대상으로 열어 둔 상태. 환경마다 태그 전략이 다르면 여기만 고친다.
- @semantic-release/git message — 기본 메시지가 길면 커밋 메시지 길이 제한에 걸린다. 짧게
chore(release): v… [skip ci]로 고정. - releaseRules — docs/refactor/style/test/chore도 patch로 올려서 “문서만 고쳤는데 버전이 안 움직임”을 줄임. feat만 minor.
나중에 알게 된 건데, release 브랜치는 최대 3개까지다. 지금처럼 main에 dev/* 세 개를 다 넣으면 개수가 넘어서, dev 쪽은 { "name": "dev/test", "prerelease": "test" }처럼 prerelease로 돌리는 게 맞다. 그러면 1.4.0-test.1 같은 버전이 붙는다.
플러그인 순서
npm 배포·GitHub Release가 필요하면 @semantic-release/npm, @semantic-release/github를 추가한다. npm은 git보다 앞에 둬야 바뀐 package.json 버전이 같이 커밋된다. Jenkins에서 돌릴 때는 GH_TOKEN을 credentials로 넣고 npx semantic-release를 부른다.
처음 세팅할 때는 로컬에서 npx semantic-release --dry-run --no-ci로 다음 버전이 뭐로 나오는지만 확인했다. 실제 태그는 안 만든다.
fetch-depth: 0을 빼먹으면 이전 태그를 못 찾아서 매번 1.0.0부터 다시 계산하려고 한다.
name: release
on:
push:
branches: [main]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}커밋 컨벤션이랑 세트
Husky + commitlint 쓸 때와 맞춘다.
feat: 기능
fix: 버그
docs / style / refactor / test / chore: 위 룰상 patch
BREAKING CHANGE: major (푸터나 ! 문법)
메시지가 컨벤션을 벗어나면 analyzer가 release를 안 올려서 “왜 태그가 안 되지?”가 된다. 그때는 커밋 로그부터 본다.