안녕하세요, 피처링에서 프론트엔드 개발자로 일하고 있는 라운입니다.
피처링의 프론트엔드 팀은 고객에게 배포되는 최종 제품의 버전을 직접 관리하고 있습니다. 고객과 명확한 소통을 위해서는 각 버전마다 어떤 기능이 추가되었고 어떤 변경사항이 있었는지 정확히 정리된 릴리즈 노트와 체계적인 버전 관리가 필수적입니다.
하지만 개발 주기가 빠르고 요구사항이 자주 변경되는 스타트업 환경에서는 이 과정이 매우 비효율적으로 진행되었습니다. 매번 릴리즈가 있을 때마다 프론트엔드 개발자들은 “이번 버전에는 어떤 기능과 변경사항이 포함되었나요?“라는 질문을 반복적으로 받았습니다. 여기에 더해 데이터팀, 백엔드팀의 변경사항까지도 빠짐없이 확인해야 했고, PM은 수작업으로 이 정보를 종합해 릴리즈 노트를 작성해야 했습니다.
이러한 반복적이고 수동적인 프로세스는 개발자들이 본연의 업무에 집중하지 못하게 만들고, 결과적으로 개발 생산성을 크게 떨어뜨렸습니다. 또한, 스타트업 특성상 릴리즈 노트 작성이나 버전 관리 업무만을 위한 전담 인력을 두는 것도 어려웠습니다.
이러한 문제를 해결하기 위해 우리는 릴리즈 노트 작성과 버전 관리를 자동화하기로 결정했습니다. 이 글에서는 저희가 자동화를 어떻게 구현했고, 그 과정에서 어떤 어려움과 성과가 있었는지 자세히 소개하겠습니다.
목표
릴리즈 관리 업무를 자동화하여 개발자들이 본연의 업무에만 집중할 수 있는 환경을 조성하는 것이 목표였습니다. 이를 위해 다음과 같은 세부 목표를 설정했습니다.
- 개발자가 개발 업무에만 집중할 수 있는 환경 구축
- 개발자는 Git Flow에 따른 코드 작성, PR 리뷰 등 핵심 업무에 집중할 수 있어야합니다.
-
릴리즈 노트 작성, 배포 과정 등 반복적인 작업에 소모되는 시간을 최소화해야 합니다.
- 효율적이고 체계적인 버전 관리 프로세스 확립
- 개발 주기가 빠른 스타트업 환경에서도 일관된 버전 관리 프로세스를 자동화하여 유지되야 합니다.
-
반복적이고 불필요한 커뮤니케이션을 줄여 팀 전체의 생산성을 높여야 합니다.
전체 자동화 플로우
설계한 릴리즈 자동화 플로우는 다음과 같습니다:
저희 팀은 GitHub, Jira, Notion을 주요 협업 도구로 사용하고 있으며, 프론트엔드, 백엔드, 데이터팀이 각기 다른 GitHub 리포지토리를 운영합니다.
따라서 GitHub Releases는 모든 팀의 버전 관리를 위한 중심 도구로 사용하되, 릴리즈 노트는 Jira에서 통합 관리하고, 최종 결과는 Notion에 자동 정리되도록 구조화했습니다.
-
GitHub: 각 팀의 PR과 커밋 정보를 수집하는 출발점
-
Jira: 모든 티켓과 릴리즈 정보를 통합하는 관리 허브
-
Notion: 내부 공유 및 고객 전달용 릴리즈 노트를 위한 최종 도착지
주요 기능 자동화
1. Github -> Github Releases
릴리즈 관리의 첫 번째 단계는 GitHub의 Pull Request(PR)에서 시작됩니다.
PR에서 작성된 태그와 제목을 기반으로 GitHub Release Drafter가 릴리즈 노트를 자동으로 작성합니다.
release-drafter.yml
name-template: '$RESOLVED_VERSION 🌈' tag-template: '$RESOLVED_VERSION' categories: - title: '변경 내역' labels: - 'note:✨' - title: '수정 버그 내역' labels: - 'note:🐛' - 'note:🚑' ... version-resolver: major: labels: - 'version:major' minor: labels: - 'version:minor' patch: labels: - 'version:patch'
실제 사용 예시
위와 같이 PR 제목이 Label에 맞춰 GitHub Release에 자동으로 반영되는 것을 확인할 수 있습니다.
Release Drafter를 적용한 뒤부터는 모든 기능이 PR 단위로 정리되고, 브랜치도 자연스럽게 기능 중심으로 관리되기 시작했습니다. 덕분에 릴리즈 노트 작성에 신경 쓸 필요 없이, 정확하고 일관된 기록이 자동으로 쌓이게 됐습니다.
2. GitHub Releases → Jira Release
릴리즈 노트가 GitHub에 정리된 이후, 이 정보를 Jira의 Release 버전으로 연결하고 릴리즈 처리까지 자동화하는 구조를 만들었습니다.
이전에는 배포가 있을 때마다 다음과 같은 작업을 모두 수작업으로 처리해야 했습니다:
-
이번 릴리즈에 포함된 Jira 티켓을 수동으로 파악
-
Jira에 새 버전 생성
-
각 티켓을 해당 버전에 연결
-
버전 설명 작성
-
최종 릴리즈 처리
이 모든 과정을 GitHub Actions와 Jira REST API로 자동화하면서, 릴리즈 관리의 반복 작업을 크게 줄일 수 있었습니다.
Flow
-
deploy 라벨이 붙은 PR이 main 브랜치에 머지됩니다.
-
Git 태그를 기준으로 다음 patch 버전을 계산합니다.
-
PR 커밋 메시지에서 [FC-1234] 같은 Jira 티켓을 정규식으로 추출합니다.
-
추출된 티켓을 해당 Jira 버전에 자동으로 연결합니다.
-
GitHub Release Drafter가 생성한 릴리즈 본문(body)을 가져와 Jira 버전 설명란에 추가합니다.
-
Jira Release를 released: true 상태로 처리하고, 릴리즈 날짜를 등록합니다.
Script
# 버전 계산 LATEST_TAG_NAME=$(git describe --tags --abbrev=0) IFS='.' read -r major minor patch <<< "${LATEST_TAG_NAME//v/}" NEW_VERSION="${major}.${minor}.$((patch + 1))" # PR 커밋에서 Jira 티켓 추출 commits=$(gh pr view ${{ github.event.pull_request.number }} --json commits --jq '.commits[].messageHeadline') tickets=$(echo "$commits" | grep -oE '\\[FC-[0-9]+\\]' | sed 's/[\\[\\]]//g' | sort -u)
# 티켓들을 Jira 릴리즈 버전에 연결 for ticket in $tickets; do curl -X PUT "https://${JIRA_DOMAIN}.atlassian.net/rest/api/3/issue/${ticket}" \ -H "Content-Type: application/json" \ -H "Authorization: Basic ${JIRA_AUTH_TOKEN}" \ --data '{ "update": { "fixVersions": [{ "add": { "name": "'"${NEW_VERSION}"'" } }] } }' done
# Jira Release 설명 업데이트 및 릴리즈 처리 RELEASE_DESCRIPTION=$(gh release view ${RELEASE_VERSION} --json body --jq '.body') RELEASE_ID=$(gh api -X GET "https://${JIRA_DOMAIN}.atlassian.net/rest/api/3/project/${JIRA_PROJECT}/versions" \ -H "Authorization: Basic ${JIRA_AUTH_TOKEN}" \ -H "Accept: application/json" | jq -r '.[] | select(.name == "'"${NEW_VERSION}"'") | .id') curl -X PUT "https://${JIRA_DOMAIN}.atlassian.net/rest/api/3/version/${RELEASE_ID}" \ -H "Content-Type: application/json" \ -H "Authorization: Basic ${JIRA_AUTH_TOKEN}" \ --data '{ "name": "'"${NEW_VERSION}"'", "description": "'"${RELEASE_DESCRIPTION}"'", "released": true, "releaseDate": "'"$(date -u +"%Y-%m-%d")"'" }'
Jira Release
위와 같이, GitHub Releases에 작성된 배포 내역이 Jira Release의 Description에 자동으로 반영되고,
릴리즈에 포함된 커밋에서 추출된 Jira 티켓들도 해당 Release에 자동으로 연결된 것을 확인할 수 있습니다.
팀 간 협업 방식
백엔드와 데이터팀 역시 동일한 Jira Release 버전에 자신들의 변경사항을 description에 계속 추가해두고 프론트엔드 쪽에서 최종 배포가 진행되면, Release Drafter에서 정리한 내용과 함께 이전까지 각 팀에서 누적해둔 변경사항 설명까지 포함되어 최종 Jira 릴리즈에 반영됩니다.
이를 통해 단일 릴리즈 버전에 여러 팀의 변경 이력이 통합되며, 나중에 회고하거나 고객 대응을 할 때도 어떤 팀이 어떤 변경을 언제 릴리즈했는지를 추적할 수 있게 되었습니다.
자동 버전 생성 (Jira Automation)
버전 릴리즈가 발생하면 자동으로 다음 patch 버전을 생성하는 Jira Automation도 설정해두었습니다.
예를 들어 1.5.16 릴리즈가 완료되면 1.5.17 버전이 자동으로 생성되어 다음 릴리즈 준비가 완료됩니다.
이렇게 자동화를 적용한 이후로는, Jira 릴리즈 등록에 필요한 수작업이 거의 사라졌습니다.
릴리즈 노트는 GitHub 기준으로 작성되고, Jira에는 정확한 티켓 연결과 설명이 자동으로 입력되며, 릴리즈 상태도 함께 정리됩니다.
3. Jira Release → Zapier → Notion
Jira에서 릴리즈가 완료되면, 그 정보를 Notion에 자동으로 정리해 고객에게 제공하는 릴리즈 노트를 생성합니다.
이를 위해 Zapier + Notion API + OpenAI API를 조합하여 다음과 같은 구조를 구성했습니다.
Flow
실제 사용 중인 Zapier 플로우 일부를 발췌했습니다.
- Trigger – Webhook
Jira Automation에서 릴리즈 완료 시 Zapier Webhook을 호출합니다. -
OpenAI API를 통한 요약
Jira Release의 설명 내용을 OpenAI에 프롬프트로 전달해 자연스럽고 일관된 문장으로 정리합니다. -
Path 분기 – KR / JP
릴리즈 대상이 한국(KR)인지 일본(JP)인지 조건에 따라 분기합니다. -
Notion Database에 생성
각 언어별로 사전에 구성해둔 Notion Database에 릴리즈 노트를 생성합니다.
이때 생성된 노트는 Draft 상태로 들어가며, 이후 수동 검토 및 Publish 설정이 가능합니다.
Admin 페이지로 상태 관리
Notion에는 Admin 페이지를 별도로 구성해두었습니다.
각 릴리즈 노트 항목은 status 필드를 가지고 있으며, 이 값이 Draft 또는 Publish 중 하나로 설정됩니다.
-
Draft: 내부 검토 중인 상태이며, 고객용 공개 페이지에서는 보이지 않음
-
Publish: 고객-facing 페이지에 자동으로 반영되어 노출됨
이를 통해 PM 또는 운영 담당자가 별도의 에디터 없이도 릴리즈 노트를 검토하고 손쉽게 공개 상태를 제어할 수 있게 했습니다.
결론
이번 릴리즈 자동화 시스템을 구축하면서, 우리가 반복적으로 겪고 있던 릴리즈 관리의 비효율성과 커뮤니케이션 비용을 실질적으로 해결할 수 있었습니다.
GitHub, Jira, Notion 각각이 고립된 도구가 아니라, 하나의 유기적인 릴리즈 파이프라인으로 연결되면서 기술팀 전체의 생산성은 물론, 릴리즈 품질과 전달 정확도까지 함께 개선됐습니다.
무엇보다 중요한 변화는,
• 릴리즈 노트가 ‘누군가의 책임’이 아닌, 개발 흐름에 자연스럽게 녹아든 구조가 되었고
• PR 단위로 기능이 분리되며 브랜치 관리가 명확해졌고,
• 릴리즈 기록이 단일 출처(GitHub → Jira → Notion)로 일관되게 유지된다는 점입니다.
스타트업처럼 빠르게 움직이는 팀일수록 릴리즈는 빨라지고, 그만큼 관리가 느슨해지기 쉽습니다.
이번 자동화를 통해 우리는 “릴리즈 관리를 따로 하지 않아도 되도록 만드는” 방법을 선택했고, 그 선택이 결과적으로 릴리즈 자체의 신뢰도를 높여주었습니다.
이 글이 릴리즈 자동화를 고민하고 있는 다른 팀에게도 작은 참고가 되길 바랍니다.