Release Please – Change log 생성 자동화

팀에서 Conventional commit을 따르고 있다면, 이것을 활용해서 change log를 만드는 것과 같은 귀찮은 일들을 자동으로 수행해 주는 도구들이 많이 있다. 이 포스팅에서는 그 중에서도 GitHub에서 사용하기에 편하다는 release-please를 Rust project에 적용해 본 내용을 다룬다.

사전 준비

  • GitHub PAT(Personal Access Token)

GitHub -> Settings -> Developer settings -> Personal access tokens -> Fine grained tokens에서 생성, contents, issues, pull-requests 권한을 부여한다. 이렇게 생성한 PAT를 Project -> Settings -> Environments에서 secret key로 등록해 둔다. 여기서는 PLEASE_REPLEASE_TOKEN 이라는 이름으로 설정했다.

  • Version Tag

Cargo.toml에 보면 version field가 있는데 현재 설정된 이 값에 맞춰서 GitHub에 Tag를 생성한다.

GitHub workflow 만들기

release-please는 workflow로 대기하면서 병합 브랜치(주로 main)에 코드가 들어 올 때 마다 이것을 감지해서 changelog를 작성하는 PR을 업데이트 한다. 이를 위해 다음과 같이 GitHub workflow를 하나 만들어 주고 서버로 commit한다. 아래의 예제에서 ci_keys는 앞서 생성한 PAT인 RELEASE_PELASE_TOKEN이 secret key로 들어 있는 environment이다.

동작확인

GitHub workflow가 main branch에 병합되면, 잠시 후에 release-package bot이 만든 PR이 만들어 지고, 여기에는 이전 버전 부터 현재까지의 변경 내역이 기록된다. 또한 이후에 main branch로 들어오는 모든 수정사항들도 기록된다.

사소한(?) 문제들

현재까지 발견한 두개의 문제점은:

  • 첫째. 리스트에 같은 커밋의 내용들이 두개씩 중복해서 나타난다.
  • 둘째. feat / fix 외의 다른 conventional commit들이 track되지 않는다.

첫번째 문제점의 원인은 PR을 merge할 때 default 값인 “Create a merge commit” 버튼으로 병합을 실행했기 때문에 작업 커밋 외에도 merge commit이 change log에 남았기 때문이다. release-please의 문서에서도 제안하듯, “Squash and merge”로 병합을 수행하면 커밋의 내용이 두번씩 중복되어 리스팅되는 문제를 막을 수 있다.

두번째 문제는 feat과 fix commit만 changelog에 올리는 것이 Release Please의 기본동작이기 때문인데 이것을 수정하고 싶다면 다음과 같은, release-please-config.json을 작성해서 어떤 항목들을 지원할 것인지 설정할 수 있다.

다음은 feat / fix외에도 perf / refactor / ci /chore 모두를 change log에 올리도록 하는 설정이다.

{
  "packages": {
    ".": {
      "release-type": "rust",
      "extra-types": ["feat", "fix", "perf", "refactor", "ci", "chore"],
      "bump-patch-for-types": ["refactor", "perf", "ci"],
      "bump-minor-pre-major": true,
      "changelog-sections": [
        { "type": "feat", "section": "Features", "hidden": false },
        { "type": "fix", "section": "Bug Fixes", "hidden": false },
        { "type": "perf", "section": "Performance Improvements", "hidden": false },
        { "type": "refactor", "section": "Code Refactorings", "hidden": false },
        { "type": "ci", "section": "CI Updates", "hidden": false },
        { "type": "chore", "section": "Miscellaneous", "hidden": false }
      ]
    }
  }
}

이 파일을 만들 때는 pair로 .release-please-manifet.json도 만들어 주는 것이 좋다고 해서 함께 만들어 주었다. 그 내용은 다음과 같다.

{
  ".": "1.0.1"
}

주의: release-please-config.json으로 제어할 때 주의해야 점이 있는데, 이 파일에서 release-type을 명시하고 있으므로, CI file에서는 release-type: rust반드시 삭제해 주어야 한다. 만약 이 부분이 있다면 충돌 때문에 설정한 config대로 동작하지 않고 default 동작으로만 동작 하게 될 수도 있다. 만약 잘 동작하지 않는다면 이부분을 확인해 보자.