본문 바로가기
나의 공부

깃허브 릴리즈 노트 자동화 하기 - 1 : 버전 업데이트하기

by 이숴 2023. 9. 30.
반응형

보이십니까? 대충 관리되어지고 있는 릴리즈 노트와 버전을...

 

물론 릴리즈 노트는 수동으로 생성할 수도, 수정할 수도 있지만, 매번 CI/CD로 배포가 될 때마다 작성을 해야한다면 여간 귀찮은 작업이 되게 됩니다.

 

이번 주제로는 프로젝트의 버전을 자동으로 관리하고, 버전에 따른 릴리즈 노트 연동을 하는 작업을 함께 알아보겠습니다.

그 전에 먼저 프로젝트의 버전을 수동이 아닌 라벨로 업데이트 하는 방식을 한번 공유하려 합니다.

 

현재 제가 참여하고 있는 프로젝트에서의 릴리즈 노트 이름들을 한번 살펴보면

이상한 이름들

다음과 같이 0.0.1로 고정이 되어 작성이 되고 있습니다.

이는 프로젝트의 버전이 계속 0.0.1로 고정이 되고 있어 버전을 그대로 가져오고 있기 때문입니다.

 

따라서 저희는 먼저 프로젝트의 버전을 자동화해야합니다.

 

버전의 표기법은 일반적으로 유의적 버전을 따릅니다.

유의적 버전은 다음과 같은 형식을 가집니다.

 

Major : 기존 버전과 호환되지 않는 새로운 버전

Minor : 기존 버전과 호환되는 새로운 기능이 추가된 버전

Patch : 기존 버전과 호환되는 버그 및 오타 등이 수정된 버전

 

따라서 위 0.0.1 버전은 프로젝트의 초기 상태를 나타내기 때문에 프로젝트가 발전될 수록 버전을 증가시키면서 관리를 해야합니다.

그래야 체계적이고 코드의 무결성을 유지하면서 충돌할 이슈를 발생 시키지 않고 작업을 할 수 있게 되는 것입니다.

 

저는 해당 작업을 계속 수동으로 해주기 보다는 main으로 PR이 될 때, 자동적으로 버전이 업데이트되길 원하여 아래와 같이 build.gradle에 작업 했습니다.

tasks.register('updateVersion') {
    doFirst {
        def currentVersion = ''
        def ymlFile = file('src/main/resources/application.yml')
        ymlFile.text.split('\n').each {
            if (it.startsWith('version: ')) {
                currentVersion = it.split(' ')[1]
            }
        }

        def increment = project.properties['increment']
        def newVersion = ''
        switch (increment) {
            case 'major':
                newVersion = "${(currentVersion.split("\\.")[0].toInteger() + 1)}.0.0"
                break
            case 'minor':
                newVersion = "${currentVersion.split("\\.")[0]}.${(currentVersion.split("\\.")[1].toInteger() + 1)}.0"
                break
            case 'patch':
                newVersion = "${currentVersion.split("\\.")[0]}.${currentVersion.split("\\.")[1]}.${(currentVersion.split("\\.")[2].toInteger() + 1)}"
                break
            default:
                println "No increment specified"
                return
        }

        ymlFile.text = ymlFile.text.replace("version: $currentVersion", "version: $newVersion")
        def gradleFile = file('build.gradle')
        gradleFile.text = gradleFile.text.replace("version = '${project.version}'", "version = '$newVersion-SNAPSHOT'")
    }
}

이 작업은 Github Actions에서 수행됩니다.

update:
    name: 프로젝트 버전 업데이트
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true && github.base_ref == 'main'
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up JDK 17
        uses: actions/setup-java@v2
        with:
          java-version: '17'
          distribution: 'adopt'

      - name: Save PR labels to file
        run: echo '${{ toJson(github.event.pull_request.labels) }}' > pr_labels.json
      
      - name: Determine Version Increment
        id: vars
        run: |
          LABELS=$(jq -r '.[].name' pr_labels.json | tr '\n' ' ')
          echo "Detected Labels: $LABELS"
          if echo $LABELS | grep -q "major"; then
            echo "Detected major label"
            echo "::set-output name=INCREMENT::major"
          elif echo $LABELS | grep -q "minor"; then
            echo "Detected minor label"
            echo "::set-output name=INCREMENT::minor"
          elif echo $LABELS | grep -q "patch"; then
            echo "Detected patch label"
            echo "::set-output name=INCREMENT::patch"
          else
            echo "No version label detected"
            echo "::set-output name=INCREMENT::"
          fi

      - name: Grant execute permissions for gradlew
        run: chmod +x ./gradlew
      
      - name: Update Project Version with Gradle
        env:
            GITHUB_TOKEN: ${{ secrets.MY_GITHUB_TOKEN }}
        if: steps.vars.outputs.INCREMENT
        run: |
          ./gradlew updateVersion -Pincrement=${{ steps.vars.outputs.INCREMENT }}
          git config --global user.name 'github-actions[bot]'
          git config --global user.email 'github-actions[bot]@users.noreply.github.com'
          git add .
          git commit -m "chore: update project version based on PR label"
          git push

 

버전의 업데이트는 다음 3개의 라벨이 추가됨에 따라 정해지게 됩니다.

PR에 major가 추가되면 1.0.0

PR에 minor가 추가되면 0.1.0

PR에 patch가 추가되면 0.0.1

 

main에 PR 게시물에 추가되는 라벨에 따라 자동화되도록 하였습니다.

 

버전 업데이트는 이런식으로 진행됩니다.

 

이제 이 버전을 토대로 릴리즈 노트를 생성해보겠습니다.

 

반응형

댓글