코드스테이츠 78-83일차
학습 목표
- 개발 프로젝트 Github 리포지토리에 꼭 필요한 요소를 이해한다.
- 칸반이 무엇인지 이해한다.
- 칸반 원칙과 실천 방안에 대해서 이해한다.
- Github Project, 이슈, 마일스톤 기능을 이용하여 칸반 보드를 제작할 수 있다.
- 칸반 보드로 업무 시각화를 할 수 있다.
README.md
Github는 개발자의 SNS라고 불릴 정도로 다양한 종류의 오픈소스 프로젝트가 공유되어 있다. 오픈소스 프로젝트에 들어가면, 가장 먼저 확인할 수 있는 정보가 바로 이 README.md 파일이다. 기본적인 마크다운 사용법을 잘 숙지하고 있으면 간단한 소개 페이지처럼 제작할 수 있다. README.md 파일을 적는 양식은 따로 존재하지 않지만, 대체로 어떻게 하면 해당 오픈소스를 활용할 수 있는지에 대한 상세한 정보가 작성되어 있다.
.gitignore
gitignore dotfile은 git으로 관리하지 않는 파일 모음이다. 여기에는 개인이 따로 관리해야 하는 중요한 secret token이나, 다른 동료와 공유할 필요가 없는 설정 파일, 그 외 공유할 필요 없는 파일을 기록하면 git이 이를 파악하지 않고, push 할 때도 github 리포지토리에 push되지 않는다.
LICENSE
해당 코드의 라이센스를 표기한다. 깃허브에 public하게 공개된 리포지토리도 라이센스에 따라서 사용을 할 수도 있고, 하지 못 할 수도 있으니 사용할 때 라이센스를 잘 보고 사용해야 한다. 회사에서 사용하는 코드는 private으로 관리하고, 외부에 공개하지 않아 라이센스 정보를 따로 표기하지 않기도한다. 하지만 모종의 이유로 회사에서 작성하는 코드가 public으로 공개된다면, LICENSE를 명확하게 표기해야한다.
프로젝트 관리에 활용할 수 있는 Github 기능
Issue
Issue는 말 그대로 프로젝트에 새로운 기능을 제안하거나, 버그를 찾아 제보하는 등 프로젝트의 이슈를 의미한다.
Milestone
Milestone은 이정표 역할을 하며, 태스크 카드(Issue)를 그룹화하는 데 사용한다. Milestone에 연결된 태스크 카드(Issue)가 종료되면 Milestone마다 진행 상황이 업데이트되는 것을 볼 수 있다. 이 Milestone 기능을 통해 연관된 이슈의 추적과 진행 상황을 한눈에 파악할 수 있는 장점이 있다.
Pull Request
Pull Request는 내가 작업한 내용을 중요 git branch에 합칠 수 있는지 확인하는 요청이다. Github에서는 Pull Request에서 커밋한 코드를 따로 선택하여 해당 부분에 코멘트를 달 수 있다. 현장에서도 Pull Request를 보면서 코멘트를 남기면서 코드 리뷰를 진행하기 때문에 Pull Request 과정에 익숙해지는 것이 중요하다.
Project
Project는 Github 내에서 업무 관리를 해줄 수 있게 돕는 새로운 기능이다.
칸반이란?
칸반은 팀과 조직이 작업을 시각화하고, 업무의 병목 현상과 리소스 낭비를 해결하는 업무 관리 방법이다.
칸반 보드를 통한 시각화
칸반의 대표적인 특징은 칸반 보드를 통한 업무 시각화이다. . 칸반 보드는 아래 사진처럼 업무를 하나의 티켓으로 표현하고, 업무 단계를 하나의 열로 표현한다. 새로운 업무가 생기면 가장 왼쪽 열에 업무가 쌓이고, 업무가 잘 진행되면 가장 오른쪽으로 전달되어 쌓이는 방식이다. 어떤 업무가 현재 어느 업무 단계에 있는지 한눈에 파악할 수 있다.
이렇게 한눈에 업무를 파악할 수 있게 되면 각 팀원이 다른 팀원이 어떤 일을 하고 있는지 투명하게 확인할 수 있고, 문서 파일에 쌓여있는 업무 현황보다 훨씬 더 종합적이고 빠르게 업무 흐름을 파악할 수 있다.
Work In Progress(WIP)로 진행중인 업무 제한 및 흐름 관리
WIP는 현재 진행하고 있는 작업을 의미한다. 칸반에서는 각 업무 단계에 WIP 제한(WIP limit)을 둘 수 있다. WIP 제한이 2이면, 두 개 이상의 카드가 해당 열에 위치할 수 없게 된다. 아래 예시의 경우 하나의 업무를 추가할 수 있다.
업무 흐름 관리
WIP를 두는 이유는 무엇일까?
업무가 과도하게 쌓이지 않는 원활한 업무 흐름을 위해서이다. 모든 팀원이 100%의 리소스를 사용하고 있는 상태에서 계속 새로운 업무가 쌓이게 되면, 업무가 과부하되어서 업무 효율이 나지 않게 된다. 막히는 고속도로에 계속해서 차가 진입하여 속도가 더 느려지는 현상에 비유할 수 있다. 즉, WIP 제한은 고속도로 진입로에서 종종 볼 수 있는 신호등과 같은 역할을 한다.
즉, WIP 제한은 한 번에 처리하는 업무의 양을 최소화하여 팀원이 한 번에 여러 업무를 동시에 진행해서 생기는 맥락 전환의 문제를 방지할 수 있고, 업무 흐름을 적당하게 유지시켜 업무가 차근차근 처리될 수 있도록한다.
프로젝트가 본격적으로 시작하기 전에 정하면 좋을 정책은 아래와 같다.
- 회의 시간 및 해당 회의에서 논의할 내용
- 팀원 간 소통 원칙
- 칸반 티켓을 언제, 어떻게, 누가 추가할지
- WIP 제한
보통 칸반을 사용하는 경우, 데일리 칸반 회의와 주간 보충 회의를 진행한다.
데일리 칸반 회의는 업무의 상태 및 흐름을 관찰하고 추적합니다. 어떻게 하면 구현하고자 하는 기능을 좀 더 빠르게 구현할 수 있을지, 업무가 끝난 인원이 다른 업무를 당겨올 수 있는지 등을 정할 수 있다. 예를 들면, 프론트엔드 개발자 A가 게시판 CRUD 사용자 인터페이스를 모두 다 구현해서 시간이 충분한 경우, 백로그에 있는 다른 프론트엔드 작업을 가져와서 하거나, WIP에 있는 다른 프론트엔드 개발자 B의 업무를 도와 집중하여 끝낼 수 있게 돕는다던지의 의사결정을 할 수 있다.
주간 보충 회의에서는, 칸반 보드에 추가할 만한 업무가 있는지 확인하고, 다음 주에는 어떤 업무를 할 것인지 정할 수 있다. 예를 들면, 프로젝트 진행 상황이 매우 원활하여, 추가로 구현하기로 했던 기능을 구현할 수 있게 된 경우에는 주간 보충 회의를 통해 해당 기능 구현 티켓을 칸반 보드에 추가할 수 있다.
추가로 격주, 혹은 월간으로 KPT 회고를 진행할 수도 있는데, 지금까지의 진행 상황에 대해서 솔직하게 회고하고, 어떻게 하면 좀 더 잘할 수 있을지 개선점을 찾을 수도 있다.
칸반 실천법
- 업무 시각화
- 진행 중인 업무 제한
- 흐름 관리
- 명확한 프로세스 정책
- 피드백 루프 구현
- 협력적인 개선, 실험적인 발전
학습 목표
- Git으로 브랜치를 다루는 방법에 대해 이해한다.
- 브랜칭 전략 중 간소화된 Coz’ Git flow에 대해서 이해하고 적용한다.
- Pull Request와 간단한 코드 리뷰 하는 방법에 대해서 이해한다.
- Git을 다루다가 어려움에 처했을 때, 어떻게 대처하는지에 이해한다.
Git branch
브랜칭(branching)은 기존 개발중인 메인 개발 코드를 그대로 복사하여 새로운 기능 개발을 메인 개발 코드를 건드리지 않고 할 수 있는 버전 관리 기법이다. 처음에 Git 리포지토리를 생성하면 나오는 main 브랜치에서만 작업을 하다가 새로운 기능 개발을 위해 feature 브랜치를 새로 생성하는 경우, 기존 main 브랜치에서의 작업은 유지하고 새로운 feature 브랜치에서 자유롭게 코드를 추가 및 삭제할 수 있다.
브랜치 생성하기 / 변경하기 (git switch)
이 때, 새로운 브랜치로 Git이 바라보는 곳, HEAD를 변경하는 작업을 switch라고 부른다. 브랜치를 생성할 때는 생성(create)의 의미로 -c 를 붙여줘야 하고, 기존에 있는 브랜치로 옮길 때는 붙이지 않아도된다.
# feature라는 브랜치를 새로 생성하는 경우, -c를 붙인다.
git switch -c feature
# checkout이라는 명령어도 사용할 수 있다.
git checkout -b feature
# 기존에 있던 main 브랜치로 HEAD를 변경하려면, -c를 붙이지 않는다.
git switch main
git checkout main
브랜치 합치기 (git merge)
기능 개발이 끝나면 브랜치를 main 브랜치와 합칠 수 있다.
브랜치 합치기 (git merge)
기능 개발이 끝나면 브랜치를 main 브랜치와 합칠 수 있다.
# 기능 개발이 진행되었습니다.
git commit -m "기능1의 세부 기능1"
git commit -m "기능1의 세부 기능2"
git commit -m "기능1 개발 완료"
# 머지를 위해 main 브랜치로 전환
git switch main
# main 브랜치로 feat/todo 브랜치를 병함
git merge feat/todo
브랜치 삭제하기 (git branch -d)
머지된 feature 브랜치는 이미 dev 브랜치에 기록이 완벽하게 남아있기 때문에 굳이 남겨둘 이유가 없어 삭제를 권장한다. 원격 리포지토리에서 pull request가 성공적으로 마무리되면, 아래 스크린샷처럼 브랜치를 삭제하는 버튼을 눌러 쉽게 삭제할 수 있다.
로컬 리포지토리에서 브랜치 삭제는 git branch -d <브랜치명> 으로 할 수 있다.
git branch -d feat/todo
Git은 원활한 버전 관리를 위해서, 브랜치가 합쳐지지 않으면 삭제하지 못하도록 설정이 되어있다. 하지만 종종 다 만들지 못한 기능의 기록을 삭제하고 싶을 수 있다. 이 때 -D 옵션을 쓰면 삭제할 수 있다.
git branch -D feat/todo
다만, 머지되지 않은 브랜치 삭제는 버전 기록 시스템의 사용 목적과는 잘 맞지는 않는다. 잘 못 만들었던 기능이지만, 해당 기능으로 돌아가고 싶을 수도 있기 때문에 돌아갈 여지를 만들어두는게 좋을 수도 있다. 이런 경우는 팀 및 회사 정책에 따르는 것을 권장한다.
Git 설정
로컬 레포지토리와 연결할 유저 정보를 설정한다.
# 버전 히스토리를 식별할 때 사용할 이름을 설정한다.
$ git config --global user.name "[firstname lastname]"
# 각 기록과 연결할 이메일 주소를 설정한다.
$ git config --global user.email “[valid-email]”
도움말 보기
help 명령어를 이용하여 각 명령어 및 옵셥의 기능에 대해 살펴볼 수 있다.
# git에서 제공하는 모든 명령어를 볼 수 있다.
$ git help -all
# 특정 command에서 사용할 수 있는 모든 옵션을 볼 수 있다.
$ git [command] -help
세팅 및 초기화
레포지토리를 초가화하거나 존재하는 레포지토리를 클론할 수 있다.
# 현재 디렉토리를 기준으로 Git 저장소가 생성된다.
$ git init
# URL을 통해 리모트 레포지토리를 로컬 레포지토리에 복제한다.
$ git clone [url]
Stage & Commit
스테이지 영역을 이용하여 커밋할 수 있다.
# 다음 커밋을 위해 현재 디렉토리에서 수정된 파일을 확인할 수 있다.
$ git status
# 다음 커밋을 위해 파일을 추가(스테이지)한다. (stage)
$ git add [file]
# 추가한 파일을 언스테이징합니다. 변경 사항은 유지된다.
$ git reset [file]
# 스테이지되지 않은 변경 사항을 보여준다.
$ git diff
# 스테이지했지만 커밋하지 않은 변경 사항을 보여준다.
$ git diff --staged
# 스테이지된 컨텐츠를 메시지와 함께 커밋한다. (스냅샷 생성)
$ git commit -m “[descriptive message]”
Branch & Merge
작업 내역을 브랜치로 분리해 컨텍스트를 변경, 통합할 수 있다.
# 브랜치 목록을 보여준다. * 표시로 현재 작업중인 브랜치를 확인할 수 있다.
$ git branch
# 현재 커밋에서 새로운 브랜치를 생성한다.
$ git branch [branch-name]
# 다른 브랜치로 전환한다.
$ git switch [branch-name]
$ git checkout [branch-name]
# 새로은 브랜치를 생성하고 해당 브랜치로 전환한다.
$ git switch -c [branch-name]
$ git checkout -b [branch-name]
# 현재 브랜치에 특정 브랜치의 히스토리를 병합한다.
$ git merge [branch-name]
# 현재 브랜치의 모든 커밋 히스토리를 보여준다.
$ git log
비교 및 검사
로그 및 변경 사항을 검사할 수 있다.
# 브랜치B에 없는 브랜치A의 모든 커밋 히스토리를 보여준다.
$ git log branchB..branchA
# 해당 파일의 변경 사항이 담긴 모든 커밋을 표시한다. (파일 이름 변경도 표시)
$ git log --follow [file]
# 브랜치A에 있지만 브랜치B에 없는 것의 변경 내용(diff)을 표시한다. (branch간 상태 비교)
$ git diff branchB...branchA
공유 및 업데이트
특정 레포지토리의 업데이트 사항을 검색하여 로컬 레포지토리를 업데이트할 수 있다.
# url을 통해 특정 리모트 레포지토리를 별칭으로 추가한다.
$ git remote add [alias] [url]
# 별칭으로 추가한 리모트 레포지토리에 있는 모든 브랜치 및 데이터를 로컬로 가져온다.
$ git fetch [alias]
# 리모트 브랜치를 현재 작업중인 브랜치와 병합하여 최신 상태로 만들 수 있다.
$ git merge [alias]/[branch]
# 로컬 브랜치의 커밋을 리모트 브랜치로 전송한다.
$ git push [alias] [branch]
# 리모트 레포지토리의 정보를 가져와 자동으로 로컬 브랜치에 병합한다.
$ git pull
히스토리 수정
브랜치 또는 커밋을 수정하거나 커밋 히스토리를 지울 수 있다.
# 특정 브랜치의 분기 이후 커밋을 현재 작업중인 브랜치에 반영한다.
$ git rebase [branch]
# 득정 커밋 전으로 돌아가며 스테이지된 변경 사항을 모두 지운다.
$ git reset --hard [commitish]
임시 저장
브랜치를 전환하기 위해 변경되었거나 추적중인 파일을 임시로 저장할 수 있다.
# 수정하거나 스테이지된 변경사항을 스택에 임시 저장하고 현재 작업 내역에서 지운다.
$ git stash
# 스택에 임시 저장된 변경사항의 목록을 보여준다.
$ git stash list
# 스택에 임시 저장된 변경사항을 다시 현재 작업 내역에 적용한다.
$ git stash apply
# 스택에 임시 저장된 변경사항을 다시 현재 작업 내역에 적용하고 스택에서 삭제한다.
$ git stash pop
# 스택에 임시 저장된 변경사항을 삭제한다.
$ git stash drop
브랜칭 전략
브랜칭 전략은 보다 효율적인 개발 프로젝트 코드 관리를 위해 브랜치의 종류를 나눠서 관리하는 전략을 말한다. Git이 널리 퍼지게 되면서 몇몇 유명한 브랜칭 전략이 생겨나게 되는데, 그 중 가장 유명한 브랜칭 전략이 Git flow이다.
Git flow
Git flow는 대규모 개발 프로젝트를 제작하여 하나의 소프트웨어의 릴리즈 버전을 명확하게 나누고, 다양한 버전을 배포해야 하는 당시의 개발 환경과는 적합했지만, 빠르게 제작하고 배포하고 고객의 피드백을 받는 애자일한 개발 팀에 적용하기는 다소 복잡했다.
Coz’ Git flow
이에 “원조" Git flow에서 파생된 여러 Git flow가 있는데, 대표적인 Git flow는 Gibhub flow, Gitlab flow가 있다.
Coz’ Git flow는 중요 브랜치 두 개를 가지고 있다. main 브랜치와 dev 브랜치이다.
main 브랜치
사용자에게 언제든 제품으로 출시할 수 있는 브랜치
main 브랜치는 사용자에게 언제든 배포할 수 있는 브랜치이다. 회사에 따라서 master, prod, production등 다양하게 불린다.
“언제든 배포할 수 있다"의 의미는 회사 별로, 팀 별로 다를 수 있으니 최소한의 기준을 세워보자
- 대표적인 기능이 완성되었다.
- 기존 기획했던 레이아웃이나 전체적인 디자인이 얼추 완성되었다.
- 클라이언트, 서버, 데이터베이스가 공개된 웹에서 정상적으로 통신할 수 있다.
- 최소한의 보안이 마련되었다.
- ㄴ브라우저에서 개발 버전에서 사용하던 secret이나 유저의 비밀번호가 노출되는가?
- ㄴ 유저의 기밀 정보 조회를 위해 인증 토큰, 세션이 꼭 필요한가?
이렇게 일정 기준을 충족했고, 핵심 기능이 완성되었으면 main 브랜치로 배포를 할 수 있다.
dev 브랜치
다음 버전 배포를 위한 "개발 중!" 브랜치
dev 브랜치는 다음 버전 배포를 위한 "개발 중!" 브랜치이다. main 브랜치에서부터 브랜칭을 하는게 보통이며, 가능하면 프로젝트 팀원과 프론트엔드와 백엔드의 결과를 합쳐서 확인해볼 수 있을 정도로 준비가 되어야 한다. CI/CD 파이프라인이 잘 구축되어 있다면 dev 브랜치의 코드도 배포를 해두고 수시로 확인할 수도 있다.
main 브랜치와 dev 브랜치는 Github 리포지토리에 늘 업데이트 되어있어야 하며, 팀원의 코드 리뷰를 받고 진행하는 것이 정석이다. 코드 리뷰를 진행할 때에는 “어떤 코드의 어디를 왜 이렇게 바꿨으면 좋겠다.”라는 코멘트를 Github Pull Request에 남기는 것을 권장한다.
보조 브랜치
feature 브랜치
feature 브랜치는 기능 개발, 리펙토링, 문서 작업, 단순 오류 수정 등 다양한 작업을 기록하기 위한 브랜치이다.
feature 브랜치 이름과 커밋 메시지의 예시
hash (브랜치 명) 커밋 메시지
2f85eea (feat/create-todo) feat: Todo 추가 기능
2ad0805 (fix/var-name) fix: 변수 네이밍 컨벤션에 맞게 변수명 변경 (ismale => isMale)
e7ce3ad (refactor) refactor: 불필요한 for 루프 삭제
feature 브랜치는 보통 각 개인의 로컬 리포지토리에서 만들고 작업한다. feature 브랜치는 기능 개발을 위한 브랜치이기 때문에 2명 이상 같이 작업하는 경우가 드물어서, 브랜치 생성이나 삭제에 대해서 너무 두려워하지 말자
회사에 따라서 커밋 기록을 남기는 일반적인 rebase-and-merge, 기능마다 깔끔하게 커밋을 남기기를 원해서 커밋 기록을 정리하는 squash-and-merge등 다양한 merge 전략이 있다.