태그 보관물: github

Smoke test를 위한 GitHub Self-hosted Runner 설정

Unittest가 개발 과정에서 논리를 점검하는데 유용하기는 하지만 이세상에는 integration test가 담당해야 하는 부분도 엄연히 존재한다. 각각의 컴포넌트들이 잘 작성되었다 할지라도 이것을 통합했을 때의 동작을 보장하는 것은 또 다른 이야기 이기 때문이다.

이 부분을 커버하기 위한 목적으로 가상의 데이터를 생성하고 프로그램의 처음 시작 부분부터 마지막 출력 부분까지(E2E) 점검하는 스크립트를 만들어 두었다. 문제는 unittest 만큼이나 이 스크립트를 자주 돌리지 않을 뿐 아니라 종종 커밋할 때 까먹는 다는 것이다.

가만, 이런 귀찮을 걸 안까먹으려고 CI를 설정해 두지 않았던가!

몇몇 리소스들을 찾아보니 GitHub workflow에서 제공하는 VM에서 docker를 돌리는 것에는 문제가 없다고 한다. 그래서 기존에 Lint와 Unitest를 수행하던 CI script에 추가로 E2E를 위한 smoke test script를 수행하는 부분을 추가하고 돌려봤더니 안타깝게도 docker instance 생성 후에 pip로 패키지들을 설치하다고 공간이 모자라서 오류가 나고 있었다.

VM에서 띄우는 docker 자체는 동작하지만 디스크 공간 같은 리소스는 충분히 주어지지 않는 것이다. 보다 높은 데이터 공간을 위해 비싼 요금제를 사용하는 것도 고려해 볼 수 있겠지만, 매번 CI를 수행할 때마다 docker instacne들을 모두 재생성 한다면 시간도 오래 걸릴 것이어서 별로 합리적인 해결 방안은 아닐 것 같다.

그래서 생각한 결론은 Self-hosted runner를 살리는 것이다. 이것 용도로 컴퓨터를 설정해야 하고 항상 네트워크에 물려 있도록 해야 하는 귀찮음은 있지만 비싼 GitHub 요금제나 instance 생성에 걸리는 시간은 아낄 수 있을것 이라 생각해서 이다.

Self-hosted runner를 설정하는 과정은 어렵지 않다. GitHub의 Actions 항목에서 Runners -> Self-hosted runner를 선택하고 “New runner” 버튼을 누르면 자세한 설정 명령어가 나오는데, 그대로 복사 붙여넣기만 하면 된다.

기존의 Lint / Unittest를 수행하는 CI는 그대로 GitHub에서 수행하고, 새로 추가된 smoke test만 self-hosted runner에서 돌리도록 해서 총 6분정도가 소요된다. 이 정도면 쓸만하다.

결론

GitHub 요금제를 올리는 방법도 있지만, 스스로 유지보수가 가능하다면 self-hosted runner를 사용해서 docker instance의 재생성을 막고 부가적인 환경 설정을 자유롭게 하는 방법도 고려해 볼만 하다.

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

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을 넣어 주면 알아서 동기화가 이루어 진다.