Renovate를 이용한 의존성 자동 업데이트

1) 의존성 자동 업데이트가 왜 필요한가
요즘은 소프트웨어 개발할 때 라이브러리를 편리하게 많이 사용한다.
예를 들어 내가 만든 크롬 확장(sh-cho/open-via-menlo)의 의존성을 보면 아래와 같은데, 작은 앱도 이렇게 많은 패키지 의존성을 가지고 있다.
{
"devDependencies": {
"@ant-design/icons": "^5.2.6",
"@babel/cli": "^7.23.0",
"@babel/core": "^7.23.2",
"@babel/plugin-transform-modules-commonjs": "^7.23.0",
"@babel/plugin-transform-runtime": "^7.23.2",
"@babel/preset-env": "^7.23.2",
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.23.2",
"@types/chrome": "^0.0.268",
"@types/eslint": "^8.44.4",
"@types/jest": "^29.5.5",
"@types/lodash": "^4.14.199",
"@types/minimatch": "^5.1.2",
"@types/node": "^20.8.6",
"@types/react": "^18.2.28",
"@types/react-dom": "^18.2.13",
"@typescript-eslint/eslint-plugin": "^6.8.0",
"@typescript-eslint/parser": "^6.8.0",
"antd": "^5.10.1",
"babel-jest": "^29.7.0",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^12.0.0",
"css-loader": "^6.8.1",
"dotenv-webpack": "^8.0.1",
"eslint": "^8.51.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"html-webpack-plugin": "^5.5.3",
"jest": "^29.7.0",
"lodash": "^4.17.21",
"minimatch": "^9.0.3",
"prettier": "^3.0.3",
"process": "^0.11.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"recoil": "^0.7.7",
"style-loader": "^3.3.3",
"terser-webpack-plugin": "^5.3.9",
"ts-jest": "^29.1.1",
"ts-loader": "^9.5.0",
"typescript": "^5.2.2",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-merge": "^5.10.0"
},
}
package.json 일부
이렇게 많은 의존성들을 손수 업데이트 한다는건 매우 고된 일이다. 또한 위와 같이 앱에서 사용되는 npm 패키지 뿐 아니라, 도커(docker) 이미지, 헬름(helm) 차트, github-actions 등 여러 서드파티의 버전관리를 손수 한다는 것은 불가능에 가깝다.
버전 관리가 어렵다고 해서 업그레이드를 하지 않고 초기 세팅했을 때의 버전으로 계속 사용한다면 각종 취약점이나 버그에 노출될 수 있다.
따라서 요즘은 자동으로 의존성을 업데이트하는 봇을 많이 사용하는 추세고, 대표적인 봇을 꼽자면 아래와 같다
- Dependabot (by GitHub)
- Renovate (by Mend.io (formerly WhiteSource))

이번 글에서는 Renovate에 대해 간단히 소개해보겠다
2) Renovate
- renovate 소개(by Mend): https://www.mend.io/renovate/
- renovate docs: https://docs.renovatebot.com/
Renovate(레노베이트)는 Mend에서 유지보수하는 의존성 관리 툴이다.
의존성 업데이트는 Pull Request로 올라오며, 자동으로 머지하도록 설정할 수 있다. 또한 일, 주 단위 등으로 의존성 검사할 스케줄을 정할 수 있다.
major 버전 업데이트는 수동, minor/patch 버전 업데이트는 자동으로 머지 되도록 하는 등 세부적인 설정도 가능해 입맛에 맞게 사용할 수 있다.
2-1) Renovate vs Dependabot
- Bot comparison: https://docs.renovatebot.com/bot-comparison/
깃허브 Dependabot과 비교했을 때 여러 이점이 있는데, GitLab 등 다른 플랫폼에서도 사용 가능하며, 모노레포 패키지 업데이트시 뭉쳐주기도 하고, 셀프 호스팅도 가능하다.
더 자세한 비교 항목들은 위 링크를 참고한다
2-2) Renovate 사용법
- Renovate Reading List: https://docs.renovatebot.com/reading-list/
GitHub에서 Renovate를 한번 사용해보자. 기타 자세한 사용법은 문서를 참고하자.
먼저 아래 링크에서 Renovate app 설치가 필요하다.
- Renovate GitHub App: https://github.com/apps/renovate
설치할 때, 모든 리파지토리에 적용하거나 적용할 리파지토리를 수동으로 선택할 수 있다.

그 다음, renovate 봇이 올린 PR을 확인한다. renovate/configure
브랜치를 보면 renovate.json
파일이 추가되어 있을 것이다.
내 설정에 맞게 수정한 뒤 renovate 봇의 PR을 머지하면 된다. 또는, 직접 파일을 만들어서 main 브랜치에 푸시해도 된다. 이 경우 PR은 자동으로 close 된다

머지가 되었다면 이제 renovate가 수시로 업데이트를 PR로 올리게 된다.
PR이 꽤나 많이 올라오기 때문에 자동 머지되도록 설정하는게 편한데, CI가 통과될 때만 머지가 되기 때문에 테스트 환경을 잘 만들어둬야 한다.
2-3) Renovate 설정 예시
일주일에 한 번만 버전 체크하고, 마이너 버전 업데이트까지는 자동 머지하도록 하고, lockfile 업데이트 등을 설정한 예시는 아래와 같다.
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch", "pin", "digest"],
"automerge": true,
"automergeType": "branch"
},
{
"matchDepTypes": ["devDependencies"],
"automerge": true,
"automergeType": "branch"
}
],
"lockFileMaintenance": {
"enabled": true
},
"automerge": true,
"platformAutomerge": true,
"schedule": ["before 4am on monday"]
}
renovate.json example