지라 버전을 자동으로 릴리스해볼까요?

지라에서 릴리스/버전을 관리하다보니 발생한 번거로운 수작업을 깃헙 액션으로 자동화해보았습니다. 이를 통해 프로젝트 가시성과 메타 정보 공유라는 가치를 더 쉽게 얻을 수 있었답니다.

지라 버전을 자동으로 릴리스해볼까요?

지난 번 지라의 배포 기능을 사용해볼까요? 글에서는 지라의 배포 기능을 사용하여 프로젝트 가시성을 확보했는데요. (자세한 내용은 아래 링크를 참고하세요.)

지라의 배포(deployments) 기능을 사용해볼까요?
깃헙 액션과 지라 배포를 연동해보았습니다. 언제, 어떤 기능이, 어느 서버에 배포됐는지 한 눈에 볼 수 있어서 좋아요.

이슈별 배포 시기를 확인할 수 있어서 편한 만큼, 이슈의 묶음 즉 버전별 배포 시기를 확인하고 싶어졌습니다. (혹은 반대로 어떤 날 배포했던 이슈 목록을 확인하고 싶기도 했고요.)

짧게 훑어보는 지라의 릴리스/버전

지라의 릴리스 기능을 사용하면 버전(=이슈 묶음)을 언제 배포했는지 관리할 수 있습니다. (지라 내에서는 '릴리스'와 '릴리즈'가 혼용되고 있으며, 이 글에서는 '릴리스'로 통일하여 사용했습니다.)

지라에서 특정 릴리스의 정보를 관리할 수 있습니다

다음 화면은 지라의 릴리스 목록인데요. 가장 왼쪽 열의 제목이 '버전'이고, 오른쪽 상단에는 '버전 만들기' 버튼도 보입니다. 어떤 버전들의 오른쪽 끝에는 '릴리스' 버튼이 붙어 있기도 하고요.

릴리스 목록 화면

이렇게 버전과 릴리스가 서로 많이 엮여 있어서 조금 헷갈렸는데요. 제가 이해한 방식으로 정리해보면, 지라의 버전에는 여러 속성이 존재합니다. 다음 화면에서 보듯 이름, 시작 날짜, 릴리스 날짜, 설명 등이 있는데요. 화면에 보이는 속성 외에 '릴리스 여부' 속성이 숨어 있습니다. 기본 값은 '릴리스되지 않음'입니다.

버전 만들기 모달 화면에서는 이름, 시작 날짜, 릴리스 날짜, 설명 필드를 입력할 수 있습니다

만든 버전은 이슈의 '수정 버전' 부분에서 할당할 수 있습니다. (태그처럼 한 이슈에 여러 버전을 할당할 수도 있습니다.)

이슈의 '수정 버전'에 버전을 할당한 모습

이제 릴리스 목록에서 버전에 붙은 '릴리스' 버튼을 누르면 다음 화면처럼 릴리스 날짜를 지정할 수 있고 어떤 이슈들이 버전에 포함됐는지도 확인할 수 있습니다. (예를 들어 다음 화면의 '4 이슈'를 클릭하면 버전에 포함된 이슈 목록을 확인할 수 있습니다.)

릴리스 모달에서는 릴리스 날짜를 지정할 수 있고, 버전에 포함된 이슈도 확인할 수 있습니다

릴리스를 끝내면 다음 화면처럼 버전의 상태가 RELEASED로 바뀌고, 버전에 포함된 각 이슈의 상태, 빌드 현황, 배포 현황도 확인할 수 있습니다.

릴리스된 버전의 상태와 포함된 이슈 목록

보통은 모든 이슈를 해결한 상태겠지만 그렇지 않은 경우 다음처럼 해결되지 않은 이슈를 어떻게 처리할지 물어보기도 합니다.

해결하지 않은 이슈가 남아 있을 때 해결책을 물어보는 모달 창

귀찮은 일들

지라의 배포 기능을 사용해볼까요? 글에서 설명했듯, 인덴트에서는 깃헙에서 배포용 PR을 만들고 이를 머지하여 자동으로 배포하는 방식을 사용합니다.

그런데 지라에서도 릴리스를 관리하기로 한 시점부터, 서버 배포 전후로 다음과 같은 관리 작업(이라고 쓰고 인형 눈 붙이기 비슷한 반복 작업)이 필요해졌습니다.

  • 지라에서 버전을 생성합니다.
  • 이번 스프린트에서 작업할 이슈에 버전을 붙여 줍니다.
  • 배포용 PR을 생성합니다.
    • PR에 포함된 지라 이슈들을 살펴보며 PR 본문을 정리합니다.
  • (배포용 PR 머지 == 서버 배포)
  • 배포용 PR에 포함된 지라 이슈들을 하나씩 열어, 수정 버전이 잘 할당됐는지 확인합니다.
    • 수정 버전이 할당되지 않은 이슈에는 버전을 할당합니다.
  • 지라의 버전을 릴리스합니다.

버전별 배포 현황을 한 눈에 파악할 수 있다는 장점에도 불구하고 단순 작업이 너무 귀찮더라고요. 그리고 귀찮음은 항상 개선책으로 이어지죠.

(부록: PR 제목 규칙)

작업 전, 배포용 PR의 제목을 인식하여 지라의 버전 제목으로 사용하고자 다음과 같이 특별한 제목 규칙을 만들었습니다.

[배포단위-V앱버전.스프린트번호.배포번호] 배포용 PR

예를 들어 [Back-V2.14.4] 배포용 PR이라고 적으면, 백엔드 작업이고 앱 버전은 2, 스프린트는 열네 번째에서 네 번째로 배포한다는 뜻이 됩니다.

개선책

귀찮은 작업 중 자동화할 수 있는 작업들은 다음과 같았고,

  • (버전이 없으면) 버전을 생성합니다.
  • PR에 포함된 지라 이슈들을 살펴보며 PR 본문을 정리합니다.
  • 배포용 PR에 포함된 지라 이슈에 수정 버전을 할당합니다.
  • 지라에서 해당 버전을 릴리스합니다.‌

자동화를 구현하기 위해 다음과 같은 깃헙 액션을 활용했습니다.

actions-ecosystem/action-regex-match를 사용하여 PR 제목 규칙을 파싱하고 버전 이름을 찾아냅니다.

connorsmallman/github-jira-changelog-action는 다음과 같은 일을 수행합니다.

  1. PR에 포함된 커밋 목록에서 지라 이슈 번호를 가져옵니다.
  2. 버전 이름으로 버전을 생성합니다.
  3. PR에 포함된 지라 이슈들에, 2에서 생성한 버전을 할당합니다.

blablacar/action-sticky-description는 PR에 포함된 이슈 목록을 다음과 같이 정리합니다.

anothrNick/github-tag-action는 깃 태그를 붙입니다. (이왕 버전을 관리하기로 했으니, 이 버전 이름으로 깃 태그도 생성하기로 했습니다.)

깃헙 액션 소스코드와 최종 흐름도

jobs: 
  jira-release: 
    name: Jira release 
    if: github.event_name == 'pull_request' && contains(github.event.pull_request.title, '배포') 
    runs-on: ubuntu-latest 
    steps: 
      - uses: actions/checkout@v2 

      - name: Get regex-matching PR title 
        uses: actions-ecosystem/action-regex-match@v2 
        id: regex-match 
        with: 
          text: ${{ github.event.pull_request.title }} 
          regex: '\[(.*?)\]' 

      - name: Export regex matching version 
        run: echo "VERSION=${{ steps.regex-match.outputs.group1 }}" >> $GITHUB_ENV 

      - name: Process changelog 
        id: changelog 
        uses: connorsmallman/github-jira-changelog-action@1.2.0 
        with: 
          jira_host: 'indentcorp.atlassian.net' 
          jira_email: 'admin@indentcorp.com' 
          jira_token: 'token_token_token' 
          jira_base_url: 'https://indentcorp.atlassian.net' 
          jira_ticket_id_pattern: /([A-Z0-9]+\-[0-9]+)/i 
          source_control_range_from: 'origin/develop' 
          source_control_range_to: 'origin/main' 

      - name: Publish message to description 
        uses: blablacar/action-sticky-description@master 
        with: 
          issue_number: ${{ github.event_name == 'pull_request' && github.event.number || github.event.issue.number }} 
          message: "${{ steps.changelog.outputs.changelog_message }}" 
      
      - name: Bump version and push tag 
        uses: anothrNick/github-tag-action@1.36.0 
        env: 
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 
          WITH_V: true 
          CUSTOM_TAG: ${{ env.VERSION }} 

이를 통해 자동화된 워크플로는 다음과 같습니다. 파란색을 사용자가 실행하면 노란색은 모두 자동으로 처리됩니다.

완성된 자동화 흐름도(파란색은 사용자 실행 작업, 노란색은 자동화 작업)

릴리스/버전 관리가 주는 또다른 장점

이렇게 해서 원했던 자동화를 마쳤고, 릴리스/버전을 손쉽게 관리하게 됐습니다. 그러자 또다른 장점들을 느낄 수 있었는데요.

첫째는 스프린트와 별개로 기능별로 버전을 만들어 두었을 때, 각 버전이 언제쯤 배포될지 예측할 수 있었다는 점입니다. 다음 화면과 같이 보고서의 버전 보고서를 열고 버전을 선택하면, 버전에 포함된 이슈 중 완료한 이슈와 남은 이슈 그리고 지금까지 팀이 보여준 작업 속도에 기반한 배포 가능 시점을 예측해서 보여줍니다.

배포 가능 시점을 예측해 볼 수 있는 버전 보고서

(스크럼 기능을 사용한다면) 릴리스 번다운 보고서를 열어서 특정 버전을 몇 번의 스프린트 내에 릴리스할 수 있는지도 예측할 수 있고요.

버전을 배포하기까지 스프린트를 몇 번 진행해야 할지 알려주는 릴리스 번다운 보고서

둘째는 개발 진행 중 발생하는 프로젝트의 메타 정보를 저장할 공간이 생겼다는 점입니다. 인덴트에서는 제품과 관련된 내용을 지라 이슈에 정리하고, 회의록은 노션 등의 공간에 저장하고 있는데요. 제품과 관련된 정보를 최대한 기록한다고 해도 여전히 어디에 적어야 할지 애매한 정보들이 존재합니다. 예를 들어 이 버전이 프로덕트에 어떤 가치를 더하는지, 저 버전은 어떤 의도로 계획했는지 등인데요. 개인적으론 메타 정보가 많이 공유될수록 구성원들이 프로덕트 목적과 업무 방향을 잃지 않을 수 있다고 생각하기에, 이 점이 가장 마음에 듭니다.

결론

모든 팀이 지라를 사용할 필요도 없고, 지라를 쓴다고 해도 모든 기능을 사용할 필요는 없을 겁니다. 필요한 기능을 필요에 따라 사용하면 좋은 도구일 테죠. 다만 이 글에서 언급한 프로젝트 가시성과 메타 정보 공유라는 가치를 팀원들과 공유하고 싶은 분들이라면, 꼭 지라가 아니어도 좋으니 버전 관리와 자동화를 한 번 시도해보시길 추천합니다.