보통 gerrit 은 jenkins 와 같은 CI 시스템과 연동하여 patch 가 gerrit 리뷰 시스템으로 올라갈 때, 자동 또는 수동으로 빌드를 하도록 연동해놓는다.
Gerrit Topic
문제는 프로젝트가 커져서 여러개의 git project 로 나뉘어 관리를 할 경우에 발생한다.
(참고로 내 환경에서는 git submodule 을 사용하지 않고 모두 별도의 git 으로 구분되어있는 상태에서 repo 로 관리하고 있다. git submodule 의 경우에는 gerrit 과 연동해보지 않아서 이 내용이 가능한지는 확인하지 못하였다)
특히 여러개의 git project 에 걸쳐서 하나의 기능이 구현되거나, git project 간에 dependency 가 발생하는 경우가 그러하다.
패치는 기본적으로 특정 git project 를 기반으로 하기 때문에, git project 간 의존성에 대해서 확인할 수가 없다.
gerrit 에서는 이렇게 여러개의 git project 간에 의존성에 대한 리뷰를 편하게 하기 위해서 topic 이라는 기능을 제공한다.
기본 사용법은 아래와 같다.
# git push origin <refspec...>%topic=<topic name>
or
# git push origin <refspec...> -o topic=<topic name>
example)
# git push origin HEAD:refs/for/master%topic=topic_test
또는 직접 gerrit UI 의 topic 부분을 수정하여 topic 을 지정할 수 있다.
topic 을 지정하게 되면 gerrit 상에서는 관련 topic 을 묶어서 함께 리뷰하기가 편리하다.
https://gerrit-review.googlesource.com/Documentation/user-review-ui.html#same-topic
그림
https://gerrit-review.googlesource.com/Documentation/user-review-ui.html#project-branch-topic
Gerrit Topic 과 Jenkins 빌드 연동
gerrit 에서 이렇게 여러 프로젝트간 의존성을 연결이 가능하다면, jenkins 에서 빌드할 때도 활용을 할 수 있지 않을까 하는게 생각의 출발이었다.
우선 gerrit 과 jenkins 가 연동되었을때, test 나 build 요청으로 인하여 jenkins 가 해당 동작에 대한 trigger 를 하게 되면 다음과 같은 변수가 설정되어 빌드가 수행되는 서버에 전달된다.
Jenkins 에서 전달해주는 Gerrit 변수
아래 예제는 내가 사용하는 jenkins 시스템에서 특정 빌드의 parameter 메뉴에서 확인한 항목이다.
GERRIT_EVENT_TYPE
GERRIT_EVENT_HASH
GERRIT_BRANCH
GERRIT_TOPIC
GERRIT_CHANGE_NUMBER
GERRIT_CHANGE_ID
GERRIT_PATCHSET_NUMBER
GERRIT_PATCHSET_REVISION
GERRIT_REFSPEC
GERRIT_PROJECT
GERRIT_CHANGE_SUBJECT
GERRIT_CHANGE_COMMIT_MESSAGE
GERRIT_CHANGE_URL
GERRIT_CHANGE_OWNER
GERRIT_CHANGE_OWNER_NAME
GERRIT_CHANGE_OWNER_EMAIL
GERRIT_PATCHSET_UPLOADER
GERRIT_PATCHSET_UPLOADER_NAME
GERRIT_PATCHSET_UPLOADER_EMAIL
GERRIT_EVENT_COMMENT_TEXT
GERRIT_EVENT_ACCOUNT
GERRIT_EVENT_ACCOUNT_NAME
GERRIT_EVENT_ACCOUNT_EMAIL
GERRIT_NAME
GERRIT_HOST
GERRIT_PORT
GERRIT_SCHEME GERRIT_VERSION
Gerrit Query 활용
그리고 구글링으로 stackoverflow 에서 gerrit 에서 query 를 사용하는 명령을 담은 내용을 찾았다. (https://goo.gl/XtSV5v)
git 이 topic 기능을 제공하는 것이 아니기 때문에, git / repo 명령을 통해서 여러 프로젝트간 정보를 엮어낼 방법이 없는 것으로 알고 있다. (혹시 더 좋은 방법을 알고 계신분은 공유해주시면 감사하겠습니다)
따라서 gerrit query 명령을 사용해서 필요한 정보를 얻어와야 한다. gerrit query 관련 문서 : https://goo.gl/Y1MNAK
기본적인 gerrit query 사용법(SYNOPSIS)은 다음과 같다. (자세한 내용은 위 링크 참고)
SYNOPSIS
ssh -p <port> <host> gerrit query [--format ] [--current-patch-set] [--patch-sets | --all-approvals] [--files] [--comments] [--commit-message] [--dependencies] [--submit-records] [--all-reviewers] [--start <n> | -S <n>] [--] <query> [limit:<n>]
동일한 Topic Name 의 Patch set 가져오기
위 내용을 토대로 아래 명령을 해보자. 내 경우 빌드 테스트를 하기 위함이기 때문에, 최신 patch set 만 필요하여 --current-patch-set 을 사용하였다.
ssh -p <gerrit port> <gerrit host> gerrit query --current-patch-set topic:<topic name>
그러면 결과로 gerrit topic name 이 같은 패치에 대한 최신 current patch set 에 대한 정보를 출력해준다.
그 정보중에서 필요한 내용만 확인해보았다.
... (생략)
currentPatchSet:
number: 3
revision: xxxxxxxxxxxxxxxxxxxxxxxxxx
parents:
[7bd2eb1788df1834cda8df43f4e0b2db45edde74]
ref: refs/changes/xx/xxxxx/x
... (생략)
각각 revision hash 값과 refspec 을 보여준다. 위 내용을 사용하여 repo 명령과 조합해주면 동일한 topic 에 대한 패치를 가져와서 빌드가 되도록 구현할 수 있다.
필요한 정보 추출하기
gerrit query 명령을 사용해서 필요한 정보를 뽑아온다. 우선 fetch 를 하기 위해 필요한 것은 refspec 정보이다. 이때, jenkins 로부터 받아온 환경 변수를 사용하여 명령을 구성한다.
ssh -p $ [user_name]@$ gerrit query --current-patch-set topic:$ | grep ref: | sed s%\ \ \ \ ref:\ %% | xargs -r -n 1 repo forall -c git fetch origin
위 명령은 현재 최신 source 를 받은 상태라면, 그 코드에 topic name 이 같은 패치를 fetch 해온다.
물론 repo forall 로 수행했기 때문에 해당 refspec 이 존재하지 않는 프로젝트는 에러 메시지가 발생하지만, 무시한다.
다음 이 패치를 적용하는 것은 위 명령과 유사한 구조로 revision 정보를 뽑아와서, fetch 대신 cherry-pick 이나 checkout 을 수행하도록 한다.
ssh -p $ [user_name]@$ gerrit query --current-patch-set topic:$ | grep revision: | sed s%\ \ \ \ revision:\ %% | xargs -r -n 1 repo forall -c git cherry-pick
내가 가진 환경에서는 잘 동작한다.
'IT 기술 > 개발환경_유틸 관련 팁' 카테고리의 다른 글
[vim] tab 을 space 로 변환, [no]expandtab 관련 팁 (0) | 2018.08.29 |
---|---|
[GIT] commit message 유지하면서 commit 에 포함된 파일 제거하기 (0) | 2018.05.29 |
[RFC 2119] MAY, MAY NOT, SHALL, SHOULD 의 사용 (0) | 2017.03.03 |
[ubuntu] minicom 스크립트 실행하기 (0) | 2013.09.25 |
[apt-get] update 에러 "E: Encountered a section with no Package: header" (0) | 2013.09.12 |