본문 바로가기
IT 기술/개발환경_유틸 관련 팁

[git/gerrit] gerrit 을 사용한 여러 project 함께 빌드

by 땅뚱 2018. 4. 26.

보통 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

내가 가진 환경에서는 잘 동작한다.