ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Ogitflow - gitflow 기반 개발 프로세스 구축기
    기술과 개발 2021. 4. 1. 17:46
    다양한 협업 프로세스, 어느 것이 가장 효율적일까?

     

    유저들의 피드백을 반영해서 업데이트를 진행해야 하거나 심각한 버그 등이 생겼을 , 정립된 개발 프로세스는 이를 빠른 시일 내에 있도록 만들어 줍니다. 개발 프로세스를 어떻게 구축하냐에 따라 업무의 효율 개발자들의 퍼포먼스가 달라지는 만큼, 조직에 적합한 개발 프로세스를 선택하는 것은 중요한 문제입니다.

    멋진 협업 vs. 그렇지 않은 협업

    1. 프로세스를 구축한 계기

    안녕하세요! OKIT 개발자 Messi 그리고 duckduckhero 입니다. 저희가 회사에 들어오고 나서 맡은 업무는 바로 유저들이 OKIT 앱을 사용함에 따라 생기게 되는 통계들을 보여주고 유저들의 활동을 관리하는 Admin 툴을 만드는 것이었습니다. OKIT 개발팀은 전까지는 서비스에 필요한 개인 단위 연구를 주로 했기 때문에, 비교적 프로젝트였던 Admin 개발을 시작하면서 어떤 협업 툴을 사용해서 코드를 개발하고 관리할 지에 대한 고민을 하기 시작했습니다.

    2. 플랫폼 선택

    결론부터 말하자면 저희는 Bitbucket 사용합니다. Github, Source Tree 많은 버전 관리 툴이 존재하지만, OKIT 개발팀에선 이미 Bitbucket 사용하고 있었기 때문에 효율성의 측면에서도 유리하고, 사용하고 있던 Atlassian 여러 협업 (Jira, Confluence, Trello) 과도 호환성이 뛰어나기 때문에 여러 측면에서 최선의 선택이었습니다.

    3. 좌충우돌 Gitflow 도입기

    *아래부터의 내용은 브랜치, 커밋 (Git) 대한 기초적인 이해가 있을 경우 이해하실 있습니다. 만약 그렇지 않은 상태라면 관련 글을 읽어보고 오시는 것을 추천합니다. 

     

    소스코드를 관리하는 브랜치 관련 전략 저희가 택한 것은 gitflow입니다. main, develop, hotfix, release, feature 단계로 브랜치를 나누는 것이 gitflow 골자이고, 브랜치의 역할은 다음과 같습니다.

     

    • Main: 서비스 되고 있는 코드를 저장하는 브랜치
    • develop: 업데이트를 준비하는 브랜치
    • feature: 업데이트의 기능을 개발하는 브랜치
    • hotfix: 출시하고 나서 급하게 버그를 수정해야 사용하는 브랜치
    • release: QA 테스트를 진행하는 브랜치

    물론 gitflow 실무에 성공적으로 적용하기까지의 과정은 결코 순탄하지 않았습니다. 인터넷에는 많은 리소스가 있었지만, 추상적인 방법론을 다룬 것이 대부분이라서 '이건 이렇게 하고 다음에는 이런 하는 거야~’ 식의 step-by-step 가이드라인을 찾기는 쉽지 않았기 때문입니다. 그래서 저희는 직접 다양한 방식을 시도해서 gitflow 배워보기로 결심했습니다. 

    방법 1: 1 1 브랜치 

    제일 먼저 도입한 방법으로, 이름에서 드러나듯이 각각의 개발자가 자신이 하루동안 작업을 하나의 브랜치로 만들어서 develop 브랜치에 매일 merge 하는 방식입니다. 세세한 과정을 적어보자면 다음과 같습니다. 

     

    1. 출근하자마자 원격 레포의 develop 브랜치를 개발자의 로컬 환경으로 pull한다.
    2. 해야 작업을 수행한다. (기능 추가, 버그 수정 ) 
    3. 작업을 끝내고 퇴근하기 ‘{mmDD-name}’ 형식 (: 0316-kim) 브랜치를 만든 다음 그날의 작업을 커밋한다. 
    4. 해당 브랜치를 원격 레포의 develop 브랜치에 merge 하는 PR 작성한다. 
    5. 다음날 아침 전날 발생한 PR들을 팀원들끼리 살펴보며 간략한 코드 리뷰 merge 한다. 그리고 처음부터의 과정을 반복한다. 

    이러한 방법은 장단점이 명확했습니다. 작업 프로세스가 무척 간단명료하면서도 효과적으로 협업을 있었습니다. 그러나 팀원의 수가 많아지고, 개발하는 기능들이 늘어날수록 헷갈리는 점들이 많아질 것이 예상되기도 했습니다. OKIT팀은 해당 방법을 1주일 가량 사용해보았는데, 협업에 익숙하지 않고 규모가 작은 초기 팀이 경험삼아 도입해보기에는 좋은 방법이나 장기적으로는 비효율적이라는 결론에 도달했습니다. 

    방법 2: 1 Feature 1 브랜치 

    사실 위에서 사용했던 단위로 브랜치를 만드는 방법은 전형적인 gitflow로부터는 많이 벗어난 스타일이었습니다. Gitflow 정석은 제품의 세부적인 기능(feature) 별로 브랜치를 만들어서 코드를 관리하는 것이더군요. 저희는 그런 방법이 너무 복잡해보여서 처음에는 쉽사리 채택하지 못했는데, 막상 사용해보니 엄청 편하다는 깨달았습니다. 

     

    이번 방법은 태스크를 분류하는 것에서부터 시작됩니다. 모든 태스크는 크게 가지 단위로 나눠질 있습니다. 커밋(Commit) 레벨 태스크, 그리고 브랜치(Branch) 레벨 태스크이죠. OKIT에서는 제품의 확실하게 분류 가능하고 독립적으로 존재할 있는 기능을 브랜치 레벨 태스크로, 그러한 기능을 구현하기 위해 필요한 세부적인 소기능과 단계들을 커밋 레벨 태스크로 분류했습니다 (이렇게 보니 OKR과도 일맥상통하는 같습니다). 

     

    예를 들어보자면, 다음과 같겠죠. 

     

    • 브랜치 레벨 태스크 : 관리자용 사용자 게시물 관리 페이지 
    • 커밋 레벨 태스크 : 게시물 검색 기능, 게시물 삭제 기능, 게시물 조회 기능  

    기능마다 하나의 브랜치가 존재하게 되므로, 원격 레포에 존재하게 되는 브랜치들은 다음과 같습니다. 

     

    • develop
    • master 
    • staging 
    • feature/(기능1) 
    • feature/(기능2) 
    • feature/(기능3)
    •  

     

    그럼 다음에는 어떻게 작업을 진행하면 될까요? 결국 개발자가 당장 개발을 해야 하는 것은 브랜치 레벨 급의 기능이 아니라 커밋 레벨 급의 작은 소기능일 것입니다. , 하나의 소기능을 작업한 다음에 기능을 언급한 커밋메시지를 작성하여 소기능이 속한 브랜치에 커밋하면 됩니다. 브랜치를 다시 원격 레포의 develop 브랜치에 merge하는 PR 날리는 것이죠. 세부적인 과정은 다음과 같습니다. 

     

    1. 개발할 소기능 (sub-task) 정한다.
    2. sub-task 속해있는 feature 브랜치와 같은 이름으로 로컬 브랜치를 생성한다.
    3. git pull origin develop 통해 최신 코드를 받아온다.
    4. Sub-task 개발이 완료되면 생성한 로컬 브랜치에다가 commit하고, 커밋 메세지는 “feature/(기능2) (소기능이름) 완료등으로 한다. 
    5. feature 브랜치에 push 하기 전에 git pull origin develop merge conflict 방지한다.
    6. feature 브랜치에다가 push 하고 develop에다 pull request 날린다.

    방법 2-2 : Jira 도입하기 

    기능별 브랜치를 생성해서 작업하던 도중, Atlassian Jira 이용하면 gitflow 훨씬 효율적으로 관리할 있다는 것을 배워서, 도입해보기로 했습니다. Jira 태스크를 Epic, Story, Sub-task 단위로 나눌 있게 해주는데, 회사마다 작업을 분류하는 기준이 조금씩 다르다고 합니다. OKIT에서 회의를 통해 정한 기준은 다음과 같습니다. 

     

    Epic, Story, sub-task 기준

     

    • story 길어야 일주일 안에 해결할 있는 정도의 일로 설정한다 (위에서 언급한 브랜치 레밸 태스크).
    • sub-task 하루에 1-2 정도 처리할 있는 정도의 양으로 정한다 (위에서 언급한 커밋 레벨 태스크). 하나의 sub-task지라 티켓이라고 한다. 
    • story 만들 팀원과 상의해서 기능 단위로 생성하고, 추가할 때마다 브랜치를 생성한다.

    Jira 사용함으로서 이전 방식과 제일 크게 달라진 점은 이제는 feature 브랜치가 기능별로 생성된다는 점입니다. 저희는 Story 마다 각각 feature 브랜치를 생성해 Bitbucket 원격 저장소와 Jira 연동해 주었는데, 개발자들은 자신의 로컬 저장소에다 feature 브랜치와 같은 이름의 브랜치를 만들고, commit 때마다 Sub-task 번호를 커밋 메시지 앞에다가 붙입니다. Push Jira 연결된 브랜치로 주면 됩니다.

    제가 만든 거 아닙니다...

    업무 예시)

    Jira Task 구조

    : Story OKM-15 / Sub-task OKM-28-graph1

     

    Git 명령어

    git checkout -b feature/OKM-15-stat

    git add .

    git commit -m “OKM-28 통계 화면 개발 완료!”

    git push {origin} feature/OKM-15-stat

     

    저렇게 push 생성한 PR 머지할 , Jira Sub-task 완료했다고 Bitbucket에서 업무 상황 업데이트를 있게 됩니다.

    4. 회고

    feature 브랜치를 기능 단위로 분리하는 전략을 택하고 나서는 업무가 유연해졌다고 느꼈습니다. 특히 작은 단위로 업무를 완료하고 진행 상황을 업데이트하는데는 Jira Bitbucket 호환성이 몫을 했습니다. 새로운 업무 방식을 도입하는 것이 처음에는 귀찮았고 거리낌이 느껴졌지만, 며칠동안 적응하고 나니 업무 효율도 훨씬 좋아진 것이 체감되었습니다.

     

    지금의 프로세스를 정립할 도움을 주신 ()크라우드웍스의 CTO 장정식 님에게 감사의 말씀을 드리며, 이번 포스팅을 마치고자 합니다.

    5. 레퍼런스 

    https://blog.gangnamunni.com/post/understanding_git_flow/

    https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow

    https://uxgjs.tistory.com/183

     

    by Messi & duckduckhero

    댓글

Copyright 2021 OKIT INC. All Rights Reserved