티스토리 뷰

반응형

이게 왜 궁금해?

tag 생성으로부터 trigger 되는 CI/CD pipeline을 구성하던 중 한 가지 문제가 생겼다.

Gitops 방식을 사용하고 있는 프로젝트였고, tag 가 생성되면 production 까지 배포될 수 있도록 Container image를 생성하고 Cluster git repo의 container tag를 앞에서 빌드한 tag로 수정하는 작업을 수행하도록 구성했다.

문제는 tag 가 어느 Branch에서 만들어지던간에 Pipeline이 Trigger되어 production 까지 배포될 수 있는 것이었다. 예를 들어 temp branch에서 tag를 생성해 push하면 production 으로 배포될 수 있었다. 특정 branch에서 tag 가 생성하였는가를 판단하는 Webhook이 있었다면 좋았겠지만 슬프게도 현재 사용하는 VCS(Version Control System)에서는 지원하지 않았다.

위 문제를 해결하기 위해 git tag 가 master branch에서 만들어졌는가를 판단할 필요가 있었다. 그렇기에 이를 찾아보기 시작했다.


Revision를 사용하자

당연히 먼저 생각한 것은 Revision을 사용하는 것이었다.

Revision이라고 하면 어떤 것인지 잘 모를 수 있는데, Git은 Commit을 할 때마다 SHA-1 값을 사용해 해당 Commit에 대한 인식표를 심어놓는다. 이걸 Revision이라고 한다.

  • 보통 git log 를 통해 Commit revision을 확인해볼 수 있다.
$ git log
 
commit 9680dc2053c2933508b49ac4d8be99e20273d7e8 (HEAD -> master, origin/master)
Author: KimDoubleB <tree9295@gmail.com>
Date:   Fri Feb 11 18:01:06 2022 +0900

    added canary test yaml

commit 9e12e05d1385c45b48d365f3cd7605447bf8d971
Author: KimDoubleB <tree9295@gmail.com>
Date:   Fri May 14 16:11:06 2021 +0900

    docs: update ingress docs (add images)

commit 22d0813fb998a75e14bab506dc4f48e80ff325a9
Author: KimDoubleB <tree9295@gmail.com>
Date:   Fri May 14 16:10:10 2021 +0900

    feat: kubernetes metric monitoring set 구축(prometheus, grafana, spring boot/actuator/micrometer)

commit 0acff6ad0462c12bacd99e111d795bf01b94bfbf
Author: KimDoubleB <tree9295@gmail.com>
Date:   Thu May 13 17:02:05 2021 +0900

    feat: prometheus example images

...
  • Revision에 대한 자세한 내용은 여길 참조하자.

 

Git tag도 어떻게보면 하나의 Branch로 생각할 수 있다. 그렇기에 master branch의 최신 commit의 reivision과 tag의 최신 commit revision을 비교하면 되겠다고 생각했다.

 

그럼 최신 commit revision을 확인할 수 있는 방법은 무엇일까?

다양한 방법이 있는데, 나는 git rev-parse 를 사용했다. 이름 그대로 revision을 parsing 하는 명령어라고 보면 되는데, 특정 branch의 revision을 출력한다.

  • 자세한 설명은 공식문서보다 stackoverflow가 더 자세히 되어있으니 참조하자.
$ git rev-parse master                                                                                                                                                  ✔
9680dc2053c2933508b49ac4d8be99e20273d7e8

 

그럼 이를 이용해 tag와 비교하면 되겠구나 싶었다.

$ git checkout master

$ git tag 1.0.0

$ git rev-parse master
9680dc2053c2933508b49ac4d8be99e20273d7e8

$ git rev-parse 1.0.0
9680dc2053c2933508b49ac4d8be99e20273d7e8

이렇게 해결이 됬으면 참 좋았겠지만, 그렇지 않았다.

 


git tag 생성 방법

Git의 tag 생성에는 두 가지 방법(Lightweight tag, Annotated Tag)이 있다.

 

Lightweight tag 는 브랜치와 거의 유사하게 동작한다. tag 생성 시 새로운 커밋을 만들어 가르키는 것이 아니라 기존 Branch의 commit을 가리키게 된다. 포인터의 역할을 하는 것이라고 보면 된다.

 

반면에 Annotated tag 는 새로운 커밋을 생성하는 것처럼 tag를 생성한다고 보면 된다 (실제로 새로운 커밋을 생성하는 것은 아니다) . Git에 tag를 생성한 이에 대한 정보, 날짜, 태그 메세지 등의 정보를 담는다.

 

일반적으로 Annotated tag 를 사용해 위 정보들을 활용할 수 있도록 한다. Source tree 툴에서는 Lightweight tag 를 비추천(not recommend)이라 명시한다. 즉, Annotated tag 를 사용하는 것을 추천하고 있다.

  • Tag에 대한 자세한 내용은 공식문서를 참조하자.

 

git log 를 해도 Annotated tag 에 대한 정보가 보이지 않는다. 하지만 Annotated tag 를 생성하면서 해당 tag에 대한 최신 revision은 바뀌게 된다.

$ git tag -a 1.0.1 -m "version 1.0.1" # annotated tag

$ git log # 따로 새로운 reivision/tag message가 보이지 않는다

commit 9680dc2053c2933508b49ac4d8be99e20273d7e8 (HEAD -> master, tag: 1.0.1, tag: 1.0.0, origin/master)
Author: KimDoubleB <tree9295@gmail.com>
Date:   Fri Feb 11 18:01:06 2022 +0900

    added canary test yaml

commit 9e12e05d1385c45b48d365f3cd7605447bf8d971
Author: KimDoubleB <tree9295@gmail.com>
Date:   Fri May 14 16:11:06 2021 +0900

    docs: update ingress docs (add images)

commit 22d0813fb998a75e14bab506dc4f48e80ff325a9
Author: KimDoubleB <tree9295@gmail.com>
Date:   Fri May 14 16:10:10 2021 +0900

    feat: kubernetes metric monitoring set 구축(prometheus, grafana, spring boot/actuator/micrometer)

commit 0acff6ad0462c12bacd99e111d795bf01b94bfbf
Author: KimDoubleB <tree9295@gmail.com>
Date:   Thu May 13 17:02:05 2021 +0900

    feat: prometheus example images

...

$ git rev-parse master
9680dc2053c2933508b49ac4d8be99e20273d7e8

$ git rev-parse 1.0.1
c2810c8bc6e39db86b16c322ba4afb43fc4ae387 # master revision과 차이가 있다

위에서 보는 것처럼 master branch에서 생성한 tag임에도 revision 차이가 있는 것을 볼 수 있다.

그렇기에 Annotated tag 를 사용하는 경우, git rev-parse 를 통해 tag가 master로 부터 만들어진 것인가를 판단하지 못한다.

 


rev-list를 사용하자

git rev-list는 rev-parse와 다르게 revision을 list로 출력한다. 즉, 한 개의 commit이 아닌 전체 commit들의 revision을 출력한다.

$ git log master

commit 9680dc2053c2933508b49ac4d8be99e20273d7e8 (HEAD -> master, tag: 1.0.1, tag: 1.0.0, origin/master)
Author: KimDoubleB <tree9295@gmail.com>
Date:   Fri Feb 11 18:01:06 2022 +0900

    added canary test yaml

commit 9e12e05d1385c45b48d365f3cd7605447bf8d971
Author: KimDoubleB <tree9295@gmail.com>
Date:   Fri May 14 16:11:06 2021 +0900

    docs: update ingress docs (add images)

commit 22d0813fb998a75e14bab506dc4f48e80ff325a9
Author: KimDoubleB <tree9295@gmail.com>
Date:   Fri May 14 16:10:10 2021 +0900

    feat: kubernetes metric monitoring set 구축(prometheus, grafana, spring boot/actuator/micrometer)

commit 0acff6ad0462c12bacd99e111d795bf01b94bfbf
Author: KimDoubleB <tree9295@gmail.com>
Date:   Thu May 13 17:02:05 2021 +0900

    feat: prometheus example images

...

$ git rev-list master

9680dc2053c2933508b49ac4d8be99e20273d7e8
9e12e05d1385c45b48d365f3cd7605447bf8d971
22d0813fb998a75e14bab506dc4f48e80ff325a9
0acff6ad0462c12bacd99e111d795bf01b94bfbf
...

 

git rev-list 는 Annotated tag 를 사용해 tag가 생성되었어도 tag의 revision이 생략된다.

  • 아마 revision을 어떻게 읽어오느냐의 차이가 있는 것 같은데, parent의 commit 부터 훑어서 읽어오며 tag revision은 생략하는 듯 하다.
$ git rev-list 1.0.1 # master와 결과가 같은 것을 볼 수 있다

9680dc2053c2933508b49ac4d8be99e20273d7e8
9e12e05d1385c45b48d365f3cd7605447bf8d971
22d0813fb998a75e14bab506dc4f48e80ff325a9
0acff6ad0462c12bacd99e111d795bf01b94bfbf
...

 

결국 rev-list를 통해 master branch와 tag 의 최신 revision을 비교하면 tag 가 master branch로부터 만들어졌는지 확인할 수 있다.

$ git rev-list master -n 1
9680dc2053c2933508b49ac4d8be99e20273d7e8

$ git tag -a 1.0.2 -m "version 1.0.2"

$ git rev-list 1.0.2 -n 1
9680dc2053c2933508b49ac4d8be99e20273d7e8

 


이렇게 해서 원하던 Pipeline 구성을 마칠 수 있었다. 구성하면서 rev-parse, rev-list에 대한 정보가 많이 없어서 고생했다. 한국 공식문서에서는 "저수준 명령이기 때문에 평소에는 전혀 필요하지 않다"라고 이야기하고 있을정도로 사용 후기가 없었다. 공식문서의 설명도 어렵게되어있어 stackoverflow를 많이 참조한 것 같다.

결론적으로 git revision을 활용해 무언가 비교하고 수행해야하는 로직이 있다면 rev-parse, rev-list를 사용해보면 좋을 것 같다.

320x100
반응형

'Development > Overall' 카테고리의 다른 글

ACID  (0) 2022.03.12
여러가지 프로그래밍 언어의 Type casting  (0) 2021.01.22
컴파일과 빌드  (0) 2021.01.21
댓글
반응형
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함