GitLab API로 DORA 메트릭 대시보드 만들기
원문은 Alex O'Callaghan님이 에 게재했습니다. 이 블로그 구독하기
소프트웨어 개발 팀의 생산성을 측정하는 일은 어렵다. 지표를 측정해 성과를 평가하기 시작하면, 행동에 영향을 미쳐 의도치 않은 결과를 낳을 수 있다. Jira 같은 프로젝트 관리 툴처럼 소프트웨어 딜리버리를 간접적으로 나타내는 자료에만 의존하면, 성과는 개선되지 않으면서 지표만 개선하는 행동을 부추길 수 있다. 스토리 포인트를 부풀리거나 티켓을 닫는 시점을 조절하는 식이다.
빅테크 기업들이 생산성을 어떻게 추적하는지에 대한 Pragmatic Engineer 글을 보고, Jira 워크플로에서 나온 지표에만 의존하던 생산성 측정 방식을 실제 프로젝트를 변경하고 배포하는 방식으로 전환할 방법은 없을지 고민하게 됐다. GitLab API를 활용해 Mintel의 팀들을 위한 대시보드를 만들고 배포 빈도와 변경 리드 타임을 추적할 수 있었다.
무엇을 추적할까?
현재 우리가 엔지니어링 생산성 목표로 주로 사용하는 지표는 사이클 타임, 즉 티켓이 Jira 워크플로에서 ‘In Progress’ 상태에서 ‘Done’ 상태로 이동하는 데 걸리는 시간이다. 모든 엔지니어링 팀이 Jira를 사용하고 있어 이 데이터는 이미 확보되어 있으며, Jira의 리포팅 기능을 이용하면 다양한 리포트를 만들어 데이터를 추적하고 시각화할 수 있다.
하지만 이러한 지표는 실제 상황을 보여주는 표상에 불과하며, 실제 코드 변경 및 릴리스와는 수동으로 동기화되거나 혹은 제대로 동기화되지 않은 채 유지된다. 2020년 DevOps Research and Assessment(DORA)는 소프트웨어 개발 팀의 성과를 나타내는 네 가지 핵심 지표를 제시했다.
- 배포 빈도 - 조직이 프로덕션에 성공적으로 릴리스하는 빈도
- 변경 리드 타임 - 커밋이 프로덕션에 반영되기까지 걸리는 시간
- 변경 실패율 - 프로덕션 장애를 일으키는 배포의 비율
- 서비스 복구 시간 - 조직이 프로덕션 장애로부터 복구하는 데 걸리는 시간
배포 빈도와 변경 리드 타임은 코드 기반 워크플로에서 비교적 쉽게 도출할 수 있으면서도 생산성을 가늠할 수 있는 지표라는 점에서 특히 눈에 띄었다.
배포 빈도
배포 빈도를 파악하는 첫 단계는 배포가 트리거된 시점을 알 수 있는 지표를 찾는 것이었다. GitLab에는 사전 구축된 DORA 메트릭 대시보드와 연동되는 deployments 기능이 있다. 문제 해결!
하지만 우리 프로젝트들은 deployments 기능을 사용하고 있지 않았다. 팀에 추가 작업을 지시하기보다는 바로 쓸 수 있는 데이터를 얻고 싶었다.
다행히 대부분의 프로젝트는 메인 브랜치에 태그를 푸시해 배포를 트리거하는 공통 워크플로를 가진 공유 GitLab CI 템플릿을 사용하고 있었다. 이 태그들은 공통된 SemVer 패턴(vX.X.X)을 따랐고, GitLab에는 프로젝트의 모든 태그를 가져오는 API가 있다.
각 팀이 소유한 프로젝트별로 태그를 가져오는 간단한 TypeScript 스크립트를 작성했다.
import { Gitlab } from "@gitbeaker/rest";
const api = new Gitlab({
token: process.env.GITLAB_TOKEN,
});
const { id, name } = project;
const tags = await api.Tags.all(id);
// Filter to just release tags
const releaseTags = tags.filter((tag) => tag.name.match(/^v\d+\.\d+\.\d+$/));GitLab API 요청에는 사용하기 쉬운 GitLab SDK인 gitbeaker를 사용했다. 그리고 csv-stringify를 이용해 릴리스 정보를 CSV 파일로 작성했다.
그다음 CSV 데이터를 Google Sheets로 가져와 시각화를 만들 수 있었다.

이 방식은 배포 파이프라인이 완료되는 데 걸리는 시간이나 배포 성공 여부를 고려하지는 않지만, 배포 빈도를 가늠하는 출발점으로는 충분히 괜찮았다.
변경 리드 타임
변경 리드 타임을 계산하는 일은 조금 더 복잡했다. 변경 리드 타임이란 변경 사항이 main 브랜치에 커밋된 뒤 프로덕션에 배포되기까지 걸리는 시간이다. 우리 프로젝트에서는 모든 변경이 머지 리퀘스트를 통해 main에 머지되며, GitLab에는 프로젝트의 머지 리퀘스트를 가져오는 API가 있다.
각 머지된 변경에 대해 변경 리드 타임을 다음과 같이 계산했다.
Lead time = Time of release - Time of merge
이를 위해서는 각 머지 리퀘스트를 해당 변경이 포함된 릴리스와 연결해야 했다. 각 머지 리퀘스트에 대해 merged_at 시점 이후에 발생한 가장 이른 릴리스를 찾는 방식으로 처리했다.
import moment from "moment";
const { id, name } = project;
// Get all merged merge requests in descending time order
const merges = await api.MergeRequests.all({
projectId: id,
state: "merged",
sort: "desc",
});
// Get all releases in ascending time order
const tags = await api.Tags.all(id, {
orderBy: "updated",
sort: "asc",
});
const releaseTags = tags.filter((tag) => tag.name.match(/^v\d+\.\d+\.\d+$/));
const leadTimes = [];
merges.forEach((merge) => {
if (merge.merged_at) {
// Find the next release
const mergeTime = moment(merge.merged_at);
const release = releaseTags.find((tag) => {
return moment(tag.commit.committed_date).utc().isAfter(mergeTime);
});
if (release && release.commit.committed_date) {
// Get the time (in hours) between merge and release
const leadTime = moment
.duration(moment(release.commit.comitted_date).utc().diff(mergeTime))
.asHours();
leadTimes.push({
project: name,
title: merge.title,
merged_at: merge.merged_at,
released_at: release.commit.committed_date,
lead_time: leadTime,
});
}
}
});그다음 각 변경의 리드 타임을 담은 CSV 파일을 하나 더 만들어 특정 기간 동안의 평균 변경 리드 타임을 계산할 수 있었다.
정기적으로 업데이트되는 대시보드
데이터를 몇몇 엔지니어링 매니저와 공유했더니 과거 데이터에서도 유용한 인사이트가 있었지만, 스프린트 회고에 이 메트릭을 활용하고 시간에 따른 변화를 정기적으로 리뷰하면 더 가치가 있겠다는 의견이 나왔다. 스크립트를 수동으로 실행하고 CSV에서 시각화를 만드는 일을 계속 맡고 싶지 않았고, 그렇다고 완전한 서비스와 데이터베이스를 구축하며 오래 끌고 싶지도 않았다.
React와 Vite, TypeScript, shadcn/ui를 이용해 간단한 React 대시보드를 빠르게 만들기로 했다. 스크립트를 수정해 GitLab JSON 응답을 public 디렉터리의 파일로 저장하도록 했고, 빌드 시점에 데이터를 한 번 가져온 뒤 대시보드에서 클라이언트 쪽에서 메트릭을 계산하도록 했다. 변경 사항과 릴리스를 연결하고 리드 타임을 계산하는 데 시간이 오래 걸리기 때문에 이 부분은 빌드 시점 스크립트에 남겨두었다.
그리고 스케줄된 GitLab 파이프라인을 설정해 매일 최신 데이터를 가져와 사이트를 다시 빌드하고, GitLab Pages로 배포하도록 했다.
금방 팀 리드들이 활용할 수 있는 메트릭을 보여주는 대시보드를 만들 수 있었다.

활용 현황과 향후 개선 방향
현재 이 대시보드는 4개의 엔지니어링 팀에 rollout됐으며, 팀이 스스로를 돌아보는 데 어떻게 유용한 도구가 될 수 있을지 모색하는 중이다. 팀의 업무 방식에 대해 논의하고 변화의 영향을 평가하는 데 더 객관적인 근거를 제공하기 시작했다.
이 대시보드가 팀 외부의 이해관계자와 소통하고, 개발자 경험 개선이 생산성에 미치는 영향을 보여주는 또 하나의 도구가 되기를 기대한다.
더 많은 팀을 온보딩하면서 이 메트릭을 가장 잘 활용하는 방법과 더불어 인사이트를 줄 수 있는 다른 지표가 있는지도 계속 파악하고 있다. 장기적으로는 이 커스텀 솔루션은 확장성이나 유지보수성 측면에서 그다지 효율적이지 않다. 가치가 입증되면 DX나 Atlassian Compass 같은 유사한 대시보드를 제공할 수 있는 플랫폼을 비롯해 GitLab deployments 같은 플랫폼을 검토할 예정이다.
정량적 데이터가 전부는 아니다. 현재 툴과 프로세스에서 엔지니어들이 얼마나 생산적이라고 느끼는지 더 잘 이해하기 위해 부서 전체를 대상으로 개발자 만족도 설문조사를 진행할 계획이다.
글을 무작위로 읽기

댓글
로그인하고 댓글 남기기