최근에 이런 저런 여유 시간이 생겨서 회사에서 개발자 생산성 향상을 위해 몇 가지 툴링 작업을 해봤다.
자랑은 아니고 그냥 배운 점들이 많아서 내용 정리겸 적어본다. 특히 Gitlab API에 이렇게 많은 기능이 제공되는지 몰랐다. 그리고 R&D 해보면서 나중에 개인 사이드로도 도입해볼 법한 재밌는 것들을 많이 발견했다. 아래 간략하게 내용을 정리해본다.
이런 류의 툴링은 항상 개발자에게 있어서 "맛난 간식"같은 느낌이다. 뭐 내가 툴링을 좀 좋아하는 성격인 것 같기도 하다.
1) 장기간 방치된 릴리즈 브랜치 알림 기능
회사에서 릴리즈 완료 이후 해당 릴리즈 머지 요청이 필요한데 종종 방치되어 한달이 넘어가는 릴리즈 브랜치가 생기는 경우가 있곤 했다.
그래서 이를 방지하고자 Gitlab 프로젝트의 브랜치 중 장기간 방치된 릴리즈 브랜치를 탐색하고 이에 대한 알림을 보낼 수 있도록 만들어봤다.
아래와 같이 작업했다.
- .gitlab-ci.yml에 새 Pipeline Job을 정의
- 특정 repo의 브랜치 목록을 가져올 수 있도록 Gitlab API를 활용
- Gitlab API를 호출하기 위해 Gitlab Personal Access Token이 필요했었음 (Gitlab PAT)
- 이걸 Gitlab PAT를 gitlab cicd variable에 설정해서 씀
- Branches READ 권한 1개만 설정하여 권한을 최소화하고, 유효기간은 6개월로 러프하게 생성함
- 참고로 PAT로 Gitlab API로 호출하는거라서 아무리 "자유가 어느정도 허용된?" 개발자 툴링이더라도 고심해서 권한을 빡빡하게 좁혀서 잡아두는 게 좋다. 그럴 일 없겠지만 혹시나 이런 개인 토큰 사고가 흔하기 때문에 좁힐 수 있는 최대한으로 권한 좁혀서 사용하고, 정말 어지간하면 반드시 READ만 사용하는게 좋다고 생각한다.
- Gitlab API를 호출하기 위해 Gitlab Personal Access Token이 필요했었음 (Gitlab PAT)
- 자동화 업무 적용 프로젝트(Repository)에 gitlab pipeline schedule을 생성한다.
- cronjob 정의로 일주일에 한번 스케쥴 돌고 매주 월요일 오전 10시 반에 정의한 파이프라인을 실행하도록 구성한다.
- cronjob: * * * * * --> (분 시 일 월 요일)
- cronjob 정의로 일주일에 한번 스케쥴 돌고 매주 월요일 오전 10시 반에 정의한 파이프라인을 실행하도록 구성한다.
- 생성된 Slack 채널로 Webhook을 통해 알림을 전송할 수 있도록 구성
프론트, 백엔드 Repo를 모두 스캔할 수 있도록 했고 다른 개발자들도 초대해서 릴리즈 머지 요청이 필요한 오래된(릴리즈 하고 난 지 일주일이 넘은) 릴리즈 브랜치가 있는지를 알 수 있게 했다.
2) 가장 활발한 MR 데일리 요약 기능
나는 보통 습관적으로 퇴근 직전에 5~10분 정도 아주 빠르게 오늘 내가 뭘했었는지 훑어보고 퇴근하곤 한다. 그 생각이 나기도 해서 Gitlab에서 하루 동안 가장 활발하게 작업된 MR에 대해 매일 해당 작업에 대한 요약을 Slack 알림으로 전달하도록 하여 금일 진행했던 업무 파악을 용이하게 하기 위해 개발해봤다.
사용 기술
- python3:12
- Gitlab Pipelines schedule (Gitlab 메뉴 잘 살펴보다가 발견한 기능이다. 꽤나 유용하다. )
- 데일리 cronjob (매일 오후 6시 30에 실행되도록 해두었다.) --> 주말을 별도로 제외하진 않았는데, 어차피 주말에는 MR이나 커밋, 리뷰가 들어오지 않아서 항상 스캔 대상에 아무것도 없게됨
- Gitlab API를 적극 활용했다.
- MR 목록 조회
- MR에서 생성된 Discussion을 조회 (Discussion을 통해서 note(코멘트)를 조회 가능함) (Discussion을 얻으면 내부 notes키를 가진 Array 내에 note가 들어가있습니다. 이게 실제 코멘트라고 보면 됨)
- 특정 branch의 커밋 내역을 조회 (ref_name이라는 인자로 branch 네임을 넘겨야 해당 브랜치의 커밋 내역을 가져올 수 있어요.)
- Bedrock API (이건 회사에서 허용해줬기 때문에 API key 발급받아서 작업했다.)
동작 흐름은 아래와 같다.
- 대상 프로젝트(repo)에 대해 열려있는 MR 목록을 조회
- (MR이 열려있고, 오늘 내 업데이트된 MR + "Draft: "가 아닌 "리뷰 가능한 상태의" MR)
- MR 내에서 생성된 Discussion을 조회
- Discussion 내에서 Note(코멘트)를 추출합니다.
- 이때 시스템이 생성한 Note은 제거하고 사람이 생성한 Note(코멘트)만 남깁니다. ("system"필드가 True인지?)
- 그리고 오늘 생성된 Note만 남깁니다.
- 이때 시스템이 생성한 Note은 제거하고 사람이 생성한 Note(코멘트)만 남깁니다. ("system"필드가 True인지?)
- Discussion 내에서 Note(코멘트)를 추출합니다.
- MR 내에서 생성된 커밋 내역을 조회
- 오늘 추가된 커밋만 모읍니다.
- Note + commit 수 기반으로 가중치(가장 활발한 가중치)를 계산하고 가장 활발한 MR 1건을 선정
- 해당 MR의 Note와 commit을 Bedrock API에게 input으로 제공
- Bedrock API의 요약 응답을 Slack Alert로 전송
- 10줄 이내로 요약 + 한글로 요약 + 본인이 시니어 엔지니어라고 가정하고 명확하게 내용을 요약하세요 !! 등으로 system role을 주었음
이때 가장 활발한 MR을 찾는 가중치 계산은 아래 공식을 따랐음 (이건 따로 Refer가 있는게 아니라 그냥 개인적으로 도출한 방식입니다.)
MR note의 가중치는 3
MR 커밋의 가중치는 2
코멘트를 커밋보다 중요한 선정 기준으로 보고 아래 계산을 통해 가중치를 계산했습니다.
weight = (note 수 * 3) + (commit 수 * 2)
3) 프로젝트 의존성 취약점 스캔 기능 도입 (OSV-Scanner)
사내에서 개발/운영 중인 프로젝트 내 의존성 파일에 대한 사전 취약점 분석이 미비하여 이를 보완하기 위해 R&D 및 도입해봤다.
최근 npm axios 의존성 관련 보안 이슈 등이 있어 이에 대해 사전에 의존성 스캔을 통해 현재 프로젝트의 보안 상태를 확인하고 예방할 수 있다.
참고로 npm axios 관련 이슈는 최근에 꽤나 크게 이슈가 됬었다. (관련해서 아래 내용이 좋으니까 참고하면 좋다)
기존에 개발된 의존성 스캔 도구를 활용해서 프로젝트 내 의존성 파일을 점검하는 방식으로 진행할려고 했고 의존성 스캔 도구로 OSV-Scanner를 선정했다. 이걸 처음에는 직접 만들어볼까 싶었는데 실장님께서 이건 기존에 매우 좋은 툴링이 이미 개발된 게 있고 그걸 R&D 해보는 것에 대해 조언을 주셔서 이쪽 방향으로 틀어봤다.
OSV-Scanner란
Google이 만든 오픈소스 의존성 취약점 스캐너. OSV 데이터베이스를 백엔드로 사용한다.
OSV DB는 GitHub, Python, npm, Go, Rust, Maven 등 20개 이상의 에코시스템을 커버하는 오픈소스 취약점 DB라고 보면 된다.
아래 두 단계로 취약점 스캔이 진행된다.
1. Package Extraction → lockfile, SBOM, 디렉토리에서 패키지 목록 추출
2. Vulnerability Matching → 추출한 패키지를 OSV DB와 대조하여 CVE 탐지
주요 기능은 아래와 같다.
소스 및 의존성 lockfile에 대한 스캔 기능을 제공한다.
2번 방식이 lockfile만 지정하면 되서 간편하게 확인 가능하다.
lockfile 지정아니더라도 특정 디렉토리 이하 전체 스캔으로도 체크 가능하다.
개인적으로 2번 방식이 젤 편하다.
# 1) 디렉토리 재귀 스캔 (lockfile 자동 탐지)
osv-scanner scan source -r ./
# 2) 특정 lockfile 지정 (lockfile만 지정하면 돼서 간편)
osv-scanner scan source --lockfile requirements.txt:requirements.txt
# 3) 여러 lockfile 동시 지정
osv-scanner scan source --lockfile package-lock.json --lockfile Cargo.lock
지원하는 의존성 lockfile 형식는 아래과 같다.
requiremens.txt, package-lock.json, gradle.lockfile, yarn.lock, go.mod, Cargo.lock, pom.xml, build.gradle, Gemfile.lock
그리고 나는 이 OSV-Scanner라는걸, Gitlab CI/CD pipeline job에서 돌아갈 수 있도록 구성했다.
.gitlab-ci.yml에 job을 정의했고 OSV-Scanner 이미지를 기반으로 삼고 거기서 내가 지정한 lockfile을 타깃으로 scan을 진행하도록 했다. 참고로 이때 OSV-Scanner는 흥미로운 동작을 하는데 scan 결과가 터미널에 예쁘게 formatting되어서 출력되는데 여기서 known vulnerabilities가 하나라도 있다면 exit code 1로 종료한다. 즉 Gitlab CI/CD pipeline Job 자체를 실패시키는 거다.
그래서 나는 의존성 취약점 스캔은 어느 정도 참고 사항으로 삼고 이걸 확인하고 나서 나중에 별개 작업으로 일괄 버전 업데이트를 진행할 수 있도록 이 job의 실패 여부는 True로 가능하도록 해두었다. 실패해도 그 다음 메인 어플리케이션 build -> deploy가 실패하면 급한 상황에서 꽤 짜증나는 상황이 연출될 것 같아서 그렇다.
참고로 OSV-Scanner가 지원하는 JVM 계열의 gralde.lockfile파일 관련해서는 재밌는 내용이 있다. 이 내용은 한 번 읽어볼 만 하다.
JVM (java/kotlin)관련 프로젝트에는 보통 build.gradle.kts 같은 파일로 의존성을 관리하는 경우가 있음
그런데 이건 사실상 lockfile을 의미하는 것은 아님.
근데 OSV-Scanner는 정확한 버전을 freezing한 lockfile을 요구함
따라서 아래 명령어를 통해 JVM 프로젝트에서 gradle.lockfile이라는 Lockfile을 만들어낼 수 있음
./gradlew dependencies --write-locks
이때 이 lockfile을 소스 관리에 포함시키면서 관리를 해야만 이걸 앞으로 꾸준히 활용할 수 가 있음
물론 이걸 gitlab CI/CD piipeline내에서 lockfile을 만들고 그때만 활용하는 방식도 나쁘지는 않음
근데 왜 springboot 많이 만지는 개발자들은 이 gradle.lockfile을 자주 만나지는 않을까? 그건 springboot쪽 의존성에는 BOM이라고 해서 기본적으로 문제 없는 버전에 대한 지원이 이미 있어서 여기서 보안을 어느정도 보장해주기 때문에 lockfile을 많이들 쓰지는 않는다고 함.
다만 이건 BOM이 지원되는 라이브러리 한정 이고 만약 프로젝트 내 지원이 안되는 여러 라이브러리를 쓴다면 BOM으로 당연히 커버가 안되고 gradle.lockfile을 도입해서 항상 소스코드에 포함시키거나 pipeline job에서 필요할때 생성해서 체크하는 방식을 쓰는 방향이 좋아보인다는 생각을 했음
물론 gradle.lockfile을 관리하기로 약속한 뒤부터는 dependency 수정할때마다 MR전에 개발자가 로컬에서 lockfile을 다시 갱신하고 changes에 추가시켜야한다는 약간의 운영 불편함이 존재하게 됨
따라서 JVM 계열에서 gradle.lockfile 도입은 장단점이 명확하기 때문에 다른 팀원들과 이야기를 맞춰놓고 결정하는 것이 좋아보임
내 개인적인 생각은 의존성이 다양한 여러가지를 쓴다면 불편하더라도 프로젝트에 gradle.lockfile을 유지하는게 좋다는 생각을 함
보인이라는게 원래 귀찮은 게 맞음
다만 그 위치를 프로젝트 소스 내에 항상 포함시킬지 별도 pipeilne job에서 할 지에 대해서는 고민을 해보면 좋음 (후자가 나을 듯?)
'Dev' 카테고리의 다른 글
| [Dev] 로직 내 AI 도입에 대한 체감 (0) | 2026.04.04 |
|---|---|
| [개발] Software Engineer와 AI 그리고 미래 (0) | 2026.02.01 |
| [개발] UTM 사용 시 System Clock과 실제 물리 시간이 맞지 않는 경우 (0) | 2026.01.25 |
| [개발] 좋은 글 첨부 (0) | 2026.01.25 |
| [개발] Parallel Programming에 대한 괜찮은 아티클 (0) | 2026.01.18 |