어서와, 개발은 처음이지?

배포 프로세스 구성하기2 - master 브랜치 push 방지와 pull request approve 설정 본문

EC2_Ubuntu_Devops

배포 프로세스 구성하기2 - master 브랜치 push 방지와 pull request approve 설정

오지고지리고알파고포켓몬고 2020. 6. 23. 18:10
반응형

지난 글에 이어서, 이번에는 master 브랜치에 직접 push를 방지하고, pull request에서 리뷰어들의 동의(approve)를 얻었을 때 merge 할 수 있도록 설정하는 과정을 알아보겠습니다.


1. 개요


협업 문화가 활발해지면서 유지보수성(maintainable)의 중요성 또한 높아졌습니다.


이에 따라서 코드 스타일을 통일하고, 리뷰 문화를 통해서 개발에 대한 생각과 철학을 일치시켜, 마치 '팀'이 하나의 지성체가 되어 개발하는 듯한 환경을 만들기 위해 개발자들은 여러가지 협업 프로세스를 만들어나가고 있습니다.


이전 글에서는 git을 통한 형상관리 프로세스에서 코드 스타일(컨벤션)을 일치시키고, 테스트 코드 작성을 장려하는 프로세스를 구축하는 방법에 대해 알아봤는데, 이번 글에서는 push를 제한하여 pull request를 통한 review 문화를 장려할 수 있도록 세팅해보겠습니다.



2. git hooks


지난 글에서 언급한 바 있지만 글을 두번 읽어야하는 피로도를 줄이기 위해 간단하게 설명하겠습니다.


git을 사용하는 프로젝트는 commit, push 등의 이벤트가 발생할 때, 이를 후킹(hooking)할 수 있는 git hooks 기능을 제공합니다.

예를들어 git push 이벤트가 발생하면 pre-push라는 hook이 먼저 실행되는 것 입니다.


hook은 쉘 스크립트로 작성되어 있으며, ${project_root}/.git/hooks/ 에서 확인할 수 있습니다.

git hooks에 대한 자세한 내용은 이곳을 보시기 바립니다.


이 글에서는 pre-push를 통해 master 브랜치에 push할 수 없도록 스크립트를 수정할 것 입니다.



3. husky


하지만 .git/ 하위 파일은 형상관리 범위에 포함되지 않기 때문에, 협업자들과 pre-push 규칙을 공유하기 위해서는 프로젝트 내에서 별도의 스크립트로 관리하는 것이 좋습니다.


husky 라이브러리를 사용하면 위 문제와 상관없이 프로젝트 레벨에서 git hooks를 편하게 사용할 수 있습니다.


우선 husky를 설치합니다.

$ npm i -D husky


다음은 설정파일인 '.huskyrc.js'를 생성합니다.

module.exports = {
  hooks: {
    "pre-push": "./huskyhooks/pre-push.sh",
  },
};


다음으로 huskyhooks 디렉토리를 생성하고, pre-push.sh를 생성합니다.

$ mkdir huskyhooks
$ vi ./huskyhooks/pre-push.sh


생성한 pre-push.sh 스크립트를 아래 내용을 넣어해줍니다.

#!/bin/sh

FORBIDDEN_HTTPS_URL="https://github.com/Yuddomack/ci-cd-process.git" # insert your remote url (https)
FORBIDDEN_SSH_URL="git@github.com:Yuddomack/ci-cd-process.git" # insert your remote url (ssh)
FORBIDDEN_REF="refs/heads/master" # insert branch ref

ARR_GIT_PARAMS=($(echo $HUSKY_GIT_PARAMS))
ARR_GIT_STDIN=($(echo $HUSKY_GIT_STDIN))

remote=${ARR_GIT_PARAMS[0]}
url=${ARR_GIT_PARAMS[1]}

local_ref=${ARR_GIT_STDIN[0]}
local_sha=${ARR_GIT_STDIN[1]}
remote_ref=${ARR_GIT_STDIN[2]}
remote_sha=${ARR_GIT_STDIN[3]}

if [ "$url" != "$FORBIDDEN_HTTPS_URL" -a "$url" != "$FORBIDDEN_SSH_URL" ]
then
    exit 0 # Forked Project 에서는 제한하지 않음
fi

if [ "$remote_ref" == "$FORBIDDEN_REF" ]
then
    echo "DO NOT PUSH it master"
    exit 1 # 금지된 ref 로 push 를 실행하면 에러
fi

exit 0

[위 스크립트는 가비아 기술블로그를 참조했습니다.]


그리고 FORBIDDEN_HTTPS_URL, FORBIDDEN_SSH_URL을 자신의 remote 주소에 해당하는 것으로 바꿔줍니다.


위 주소는 자신의 github 레포지토리에서 쉽게 확인할 수 있습니다.


(만약 nodejs 환경이 아니라면 husky를 사용하지 않고, 프로젝트 내 pre-push 스크립트를 작성해 놓고 .git/hooks/ 와 동기화하도록 코드를 작성하거나 개발환경에서 제공하는 다른 방법을 사용하셔도 됩니다.)


[https]


[ssh]


4. push를 해보자


세팅이 끝났으면 commit후 push를 실행해보겠습니다.

$ git push origin master


에러가 정상적으로 출력되나요?


이전에는 remote 저장소의 master 브랜치에 push가 가능했지만 pre-push에서 이를 제약하여 아래 이미지처럼 push가 되지 않습니다.



혹시 permission denied가 나온다면 pre-push.sh 파일의 권한을 chmod 명령을 사용하여 755로 바꿔주세요

$ chmod 755 pre_push.sh


자, 이제 master 브랜치에 직접 push할 수 없게 됐습니다.


하지만 착각하지 말아야 할 것은

이런 환경을 구축했던 이유가 '팀'의 개발문화나 형상관리 전략을 헤치는 행위에 경각심을 주한 것이지, push를 '금지'하는것 자체는 아니라는 것입니다.


이런 프로세스가 늘어날수록 병목 구간을 발생시킬 수 있기 때문에, '남들 다 하니까 우리도 하자'가 아니라 상황과 조직에 맞게 적용하는 것이 중요하겠습니다.




5. approve 설정


이제 pull request 전 마지막 과정으로 github에서 approve 조건을 설정해보도록 하겠습니다.


github 레포지토리의 setting에서 branches 메뉴를 선택합니다.



다음으로 오른쪽에 Add rule 버튼을 클릭한 뒤, branch name pattern를 작성하고 Require pull request reviews before merging를 선택하여 원하는 approve 조건 수를 설정합니다.



각 브랜치 별로 다른 규칙을 적용할 수 있으니 팀의 형상관리 전략에 따라 적절히 사용하시면 됩니다.


이제 하단에 create 버튼을 클릭하면 설정이 적용됩니다.



6. pull request


여기까지 세팅이 정상적으로 됐다면, 우리는 pre-push에 의해 이 변경된 코드를 master 브랜치에 반영할 수 없습니다.

이를 반영하기위해 branch를 생성하여 pull request를 등록하는 협업의 형태를 따라가겠습니다.


우선 branch를 생성하고 remote에 push합니다.

$ git branch develop
$ git checkout develop
$ git push origin develop


이제 github으로 이동하여 develop 브랜치에서 pull request를 생성합니다.



pull request가 생성되면 approve를 얻지 않으면 merge할 수 없다는 메세지를 확인할 수 있습니다.



이제 마지막으로 approve를 획득하면, merge가 가능하게 바뀌는 모습을 볼 수 있습니다.




7. 마무리


이번에는 master 브랜치에 직접 push를 방지하고, pull request에 approve를 설정하여 merge할 수 있도록 프로세스를 구축하는 방법에 대해 알아봤습니다.

본 글에서 사용한, 앞으로 적용할 프로세스의 코드는 이곳에서 확인할 수 있습니다.


이러한 프로세스를 적용하면 branch를 적극적으로 활용할 수 밖에 없고, 코드 리뷰 문화도 자연스럽게 따라오게 됩니다.


하지만 전략없는 branch 사용은 형상관리 복잡도가 올라가고, 커밋이 쌓여 코드 리뷰를 하기 어려워지고 배포가 지연되는 등의 문제가 발생할 수 있습니다.


이 글에서 소개한 방법은 정답이 아니니 각 팀의 상황과 환경을 고려하여 하는것이 중요하겠습니다.


다음으로는 jenkins를 사용하여 push 이후 배포 방법에 대하여 다뤄보겠습니다.





Comments