안녕하세요~! 설 연휴 앞두고 뭘 포스팅하지 하다가 요즘 너무 쿠버네티스나 Azure만 올린 것 같아서
간만에 Bitbucket 웹훅 만들기로 돌아왔습니다~
웹훅(webhook)이 뭐예요?
저는 남이 내려주는 정의를 참 좋아하는데요, 아래 페이지를 참조하시죠!
https://en.wikipedia.org/wiki/Webhook
예.. 미리 용도에 맞게 정의해 둔 HTTP 콜백입니다.
애초에 이 글을 검색해서 들어오시게 된 분들은 웹훅을 모르실 수가 없어서, 굳이 긴 설명은 필요 없을 것 같습니다.
이벤트 발생했을때 웹훅 걸어서 알림을 보내거나 어떤 동작을 트리거하는 용도로 정말 정말 정말 많이 사용합니다.
저는 웹훅을 생각하면 어릴 때 봤던 나홀로집에라는 영화가 생각이 나는데요,
문에 훅을 달아두고 거기에 줄을 길게 연결해서 도둑들이 문을 열고 침입하면
줄이 당겨지면서 고정해 두었던 양동이에서 물이 쏟아져서 도둑들이 물을 맞았던 (!) 장면이 떠오르더라구요ㅎㅎ
물리적이냐 논리적이냐의 차이지 비슷한 역할이라고 생각하며 사용하고 있습니다^^
Bitbucket에 웹훅을 왜 걸어요?
GitHub이든 Bitbucket이든 Gitlab이든 용도는 비슷할 것이라고 생각이 되는데요,
공수를 줄이기 위해 웹훅을 겁니다.
PR이 올라왔을 때 슬랙이나 팀즈로 알림을 보낸다든지,
PR이 머지되었을 때 배포를 시작한다든지 하는 식으로 이벤트가 발생했을 때 다른 동작을 트리거할 수 있습니다.
웹훅 그냥 리파지토리 들어가서 걸면 되지 않나요?
웹훅을 한 250개정도의 리포지토리에 동시에 걸어야 한다면...?
삶이 다소 아찔해집니다.
저 같은 경우에는 빌드 및 배포를 수행하는 Jenkins 잡을 구성하는 것을 포함하는
자동화 개발에 사용했는데요, 그래서 예제도 Jenkins를 사용해서 공유드릴 예정입니다.
curl 한 번이면 행복해질 건데 손으로 하나하나 클릭하지 맙시다!
그래서 어떻게 건다고요?
간단합니다. curl 이든 아니면 다른 방식으로든 HTTP POST request를 아래와 같은 방식으로 날려 주시면 됩니다.
curl -X POST -u ${username}:${password} -H 'Content-Type: application/json' \
https://${bitbucket주소}/rest/api/1.0/projects/${bitbucket 프로젝트}/repos/${repo명}/webhooks \
-d '{"name": "${사용하실 webhook의 이름}",
"url": "${webhook을 걸어 줄 url}",
"active": true, # 이 부분을 false로 하면 생성은 되지만 inactive 상태로 생성됩니다.
"events": ["pr:merged"]}' # 이벤트의 종류입니다. 어떤 이벤트가 발생했을 때 웹훅이 생겨나는지! 고르시면 됩니다.
"""
${} 이 부분은 따로 말씀드리지 않아도 본인의 환경에 맞게 하시겠죠..?
위의 예제같은 경우에는 pull request가 merge 되었을 때 웹훅을 쏘게 되는데요,
쏠 때 어떤 내용을 보내는지! payload는 아래의 공식문서를 참고해 주세요~
https://support.atlassian.com/bitbucket-cloud/docs/event-payloads/
요걸 Jenkins pipeline에 적용해서 PR이 merge되면 Jenkins 잡에 build trigger를 주고 싶다! 라고 한다면~?
아래와 같은 방식으로 응용이 가능합니다.
(선략)
withCredentials([usernamePassword(
credentialsId: '${credential 이름}' ,
usernameVariable: 'username',
passwordVariable: 'password')]) {
sh """
curl -X POST -u ${username}:${password} -H 'Content-Type: application/json' \
https://${bitbucket 도메인}/rest/api/1.0/projects/${bitbucket 프로젝트}/repos/${bitbucket repo}/webhooks \
-d '{"name": "${웹훅 이름}",
"url": "https://${jenkins domain}/generic-webhook-trigger/invoke?token=${webhook을 받아서 빌드할 잡의 토큰}",
"active": true,
"events": ["pr:merged"]}'
"""
}
}
(후략)
요렇게 되어있다면 PR이 머지될 때 해당 Jenkins Job에서 자동적으로 빌드가 발생하게 됩니다~^^
물론 쏘는 쪽만 백날천날 쏜다고 되는 건 당연히 아니고요, 받아주는 Jenkins 쪽에서
Generic webhook trigger가 enabled 상태여야 하고, 토큰도 지정해 주어야 합니다.
또 예제의 파이프라인 코드에서는 withCredentials를 사용해서 인증값을 넣어주었는데요,
저렇게 똑같이 사용하시려면 파이프라인을 실행하는 Jenkins에서 credential이 미리 저장되어 있어야 하겠죠~!
아무튼 요렇게만 해서 돌려 주시면 bitbucket repository에 성공적으로 webhook이 생성된 것을 보실 수 있습니다^^
리포지토리는 막 찍을 수가 없어서 아쉽게도 캡쳐는 없는 것으로 . . . . ^^;;;;
주의사항
pr:merged 이런 식으로 웹훅이 생성되는 것을 보시면 아시겠지만, Bitbucket 웹훅 발생 조건은
브랜치 단위가 아니라 리포지토리 단위입니다. 그래서 Jenkins 빌드를 자동화하는 경우라면
저렇게만! 사용하시면 dev 브랜치로 풀리퀘를 머지했는데 전체 환경에서 배포가 일어날 수도 있겠습니다.
따라서 받아주는 Jenkins 쪽에서도 pullRequest.toRef.displayId 와 같은 브랜치 정보를 받아와서
브랜치 값에 따라서 트리거가 발동하거나, 발동하지 않도록 필터 처리를 해 주셔야 합니다~^^
그 외에도, 리포지토리 단위이므로 멀티모듈 구성인 경우라면 더더욱 토큰과 필터에 신경 써 주어야 합니다.
필터 설정은 혹시 적용에 어려움을 겪으신다면 댓글이든 뭐든 문의 주시면 도움 드리겠습니다~
이상입니다~
즐거운 명절 보내세요~ 헉 벌써 3시가 다 되어가네요;;;