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 동작으로만 동작 하게 될 수도 있다. 만약 잘 동작하지 않는다면 이부분을 확인해 보자.

[Tip] Emacs: rust-analyzer-tramp가 계속 죽는 문제

Remote server에 tramp mode로 rust file을 읽어서 rust-mode에 진입한 후에 미니버퍼에 아래와 같은 경고가 뜨는데, ‘y’를 입력해서 rust-analyzer-tramp를 재실행 시켜도 계속해서 죽어서 같은 오류가 보이는 문제가 생겼다.

rust-analyzer 설치 확인

Remote server측에 rust-analyzer가 설치되어 있지 않으면 이와 같은 문제가 생길 수 있으니 다음의 명령어로 rust-analyzer를 update해본다. 만약 설치 되어 있지 않다면 이 과정에서 설치될 것이다.

rustup component add rust-analyzer

Remote path 사용

rust-analyzer가 이미 설치 되어 있음에도 문제가 발생 한다면 서버측의 path가 제대로 설정되고 있는지 확인해 보자. Trump mode는 서버측의 PATH 환경변수 값 을 읽지 않으므로 경로정보를 서버의 것으로 유지 하도록 설정해 주어야 한다.

 (require 'tramp)
 (setq tramp-default-method "ssh")
 ;; Respect remote path.
 (with-eval-after-load 'tramp
   (add-to-list 'tramp-remote-path 'tramp-own-remote-path))

OpenProject와 GitHub 연동하는 보다 간단한 방법

OpenProject와 GitHub의 연동을 위해 이전의 포스팅에서 다룬 방법은 OpenProject의 task ticket에있는 Git snippets의 내용을 복사해서 터미널에 붙여넣는 것이었는데, 이 때 만들어지는 branch의 이름은 OpenProject ticket의 제목에 기반한 것이어서 자칫하면 branch의 이름이 지나치게 길어지는 데다가, 사전에 정해둔 팀내의 branch naming rule과 충돌하기 쉽다.

다행히도 OpenProject의 GitHub 자동 연동기능은 branch naming명이 아닌 커밋 메세지내에 있는 issue ticket link에 의해 연결는 것이어서 branch의 이름은 Git snippets에서 제안하는 것과 달라도 문제가 없다.

수정 사항을 만들고 나서 commit message를 작성할 때 OpenProject의 issue ticket link을 걸어 주면 Git snippets의 내용을 복사하지 않더라도 GitHub와 연동이 잘 되는 것을 볼 수 있다. 혹시 있을 오류를 대비해서 Commit의 내용에도 [OP#56] 처럼 OpenProject내의 task ticket 번호를 언급해 주기는 했으나 이것은 없어도 아무런 문제가 없다.

GitHub에서 PR을 생성한 후 OpenProject의 해당 ticket을 보면 PR의 상태를 잘 받아서 상태를 보여주고 있는 것이 보인다.

결론

OpenProject의 Git snippet은 유용한 template이기는 하나 팀내의 다른 branch naming이나 commit message 작성에 관한 규칙이 있다면 굳이 따를 필요는 없다. Commit message내에 OpenProject의 ticket과 link시키기 위한 URL을 넣어 주면 알아서 동기화가 이루어 진다.