티스토리 뷰

프로젝트에 Git Flow를 도입해 브랜치 전략을 체계적으로 운영하고 있었지만, prod 배포 시마다 수동으로 태그를 만들고 릴리즈 노트를 작성하는 작업은 여전히 개발자의 몫이었음. 이런 반복적인 업무는 개발에만 집중할 수 없는 환경을 만들게 되었고, 이를 해결하기 위해 배포 시점에 자동으로 버전 태그를 생성하고, 커밋 로그 기반으로 릴리즈 노트를 자동 생성하는 GitHub Actions 워크플로우를 구축.

시나리오

우선 도입한 깃플로우 전략에 따라서 release/, feature/, hofix/ 이렇게 별도 브랜치를 구분해서 완료시켜 dev, prod 로 브랜치 병합 작업을 진행했음.

예를 들어, release/v1.0.0 브랜치를 prod로 머지한다고 가정하면, 이 브랜치명에서 v1.0.0이라는 버전 정보를 추출하여 자동으로 Git 태깅을 진행한다. 그리고 릴리즈 노트에는 이전 태그 이후부터 현재까지의 커밋 메시지 목록을 자동으로 정리해 넣는 시나리오를 구상했음.

tag-release.yml 만들기

우선 깃허브 워크플로우 폴더에 tag-release.yml 을 하나 만들자. (파일명은 원하는대로, tag, release 를 둘 다 자동화할거라서 명시적으로 만들었음.)

다음 순서대로 움직임.

1. prod push

2. 커밋 메시지에서 버전 추출 (Extract version from branch)

3. 이전 태그 가져오기 (Get previous tag)

4. 커밋 목록 추출 (Get commits between tags)

5. 태그 생성 (Create tag)

6. 릴리즈 생성 (Create GitHub Release)

name: Auto Version and Release

on:
  push:
    branches:
      - prod

jobs:
  version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Extract version from branch
        id: extract_version
        run: |
          commit_msg=$(git log -1 --pretty=%B)
          if [[ $commit_msg == *"Merge branch 'release/"* ]]; then
            version=$(echo "$commit_msg" | grep -o "release/[^']*" | sed "s/release\///")
            echo "version=$version" >> $GITHUB_OUTPUT
          elif [[ $commit_msg == *"Merge branch 'feature/"* ]]; then
            version=$(echo "$commit_msg" | grep -o "feature/[^']*" | sed "s/feature\///")
            echo "version=$version" >> $GITHUB_OUTPUT
          elif [[ $commit_msg == *"Merge branch 'hotfix/"* ]]; then
            version=$(echo "$commit_msg" | grep -o "hotfix/[^']*" | sed "s/hotfix\///")
            echo "version=$version" >> $GITHUB_OUTPUT
          else
            echo "version=dev-$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
          fi

      - name: Get previous tag
        id: get_previous_tag
        run: |
          previous_tag=$(git tag --sort=-creatordate | head -n 1 || echo "")
          if [ -z "$previous_tag" ]; then
            echo "previous_tag=HEAD~50" >> $GITHUB_OUTPUT
          else
            echo "previous_tag=$previous_tag" >> $GITHUB_OUTPUT
          fi

      - name: Get commits between tags
        id: get_commits_between
        run: |
          if [ "${{ steps.get_previous_tag.outputs.previous_tag }}" != "HEAD~50" ]; then
            # 이전 태그와 현재 헤드 사이의 커밋 가져오기
            commit_list=$(git log --pretty=format:"- %s (%h)" ${{ steps.get_previous_tag.outputs.previous_tag }}..HEAD)
          else
            commit_list=$(git log --pretty=format:"- %s (%h)" -n 50)
          fi

          echo "commits<<EOF" >> $GITHUB_OUTPUT
          echo "$commit_list" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Create tag
        run: |
          git tag ${{ steps.extract_version.outputs.version }}
          git push origin ${{ steps.extract_version.outputs.version }}

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: ${{ steps.extract_version.outputs.version }}
          name: '${{ steps.extract_version.outputs.version }}'
          body: |
            ## 변경 사항

            ${{ steps.get_commits_between.outputs.commits }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

 

결과

자동 태그 생성
자동 릴리즈 노트 생성

 

이러면, 이제 자동 태그와 릴리즈 노트가 생성되어서 직접 개발자가 작성하는 일이 없어지며, 명확하게 어떤 작업을 커밋했는지에 대한 내용이 들어가게 됩니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함