2008년 11월 15일 토요일

Release Branch, Function Branch and Customer Branch

서영아빠님의 "브랜치를 이용하여 운영환경에 선별적으로 배포하기"란 글을 보고 소프트웨어 프로젝트에서 브랜치란 어떤 의미를 가지는지 "소프트웨어 개발의 모든것"이라는 책에서 이에 대하여 소개한 내용이 있는데 이를 인용하여 설명을 하려고 합니다.

여기서 소개하는 브랜치에 대한 얘기의 핵심은 브랜치의 위험성에 대한 "경고"입니다.
브랜치는 위험하지만 소프트웨어 개발에서는 흔히 꼭 필요하게 되어서 철저히 통제가 되어야 한다는 것입니다.

 브랜치(Branch)

브랜치란 필요에 의해서 소스코드를 분기하는 것이다. 
브랜치를 얼마나 잘 통제하는가가 훌륭한 소프트웨어 회사와 평범한 소프트웨어 회사를 구별하는 핵심 요소 중 하나이다. 
브랜치를 해야 하는 경우를 예로 들면 다음과 같다.

  • 제품을 출시 후 유지보수를 하면서 동시에 업그레이드 프로젝트를 진행할 경우
  • 이미 출시 된 제품에 복잡한 기능을 추가하려고 할 경우
  • 고객이 제품에 특정 기능을 넣어 달라고 요구를 하는데, 그 기능이 제품의 표준 기능에서 벗어날 경우
  • 고객이 제품에 특정 기능을 넣어 달라고 요구를 하는데, 표준 기능으로 넣을 시간이 부족한 경우

제품 출시 후 유지보수와 업그레이드 프로젝트를 진행하면서 하나의 소스코드를 같이 사용한다면 완전히 뒤죽박죽이 될 것이다. 아직 완성되지 않은 기능들이 고객에게 전달 될 수도 있다. 이 경우 소스코드를 브랜치하여 브랜치 된 소스코드를 유지보수를 위해 사용할 수도 있고, 업그레이드 용으로 사용할 수도 있다. 상황에 따라서 적절하게 선택하면 된다. 가능하면 적게 바뀔 것을 브랜치로 사용하는 것이 좋을 것이다. 왜냐하면 브랜치는 나중에 트렁크(Trunk)와 머지를 할 것이기 때문이다. 이렇게 서로 다른 소스코드를 가지고 개발하다가 업그레이드 프로젝트가 끝날 때쯤 그 동안 유지보수를 하면서 버그를 수정하거나 일부 기능을 추가한 것들을 서로 머지하게 된다. 이러한 브랜치를 릴리즈 브랜치(Release Branch)라고 부른다.
이미 제품이 출시되어서 유지보수를 하고 있을 경우, 시간이 많이 걸리거나 리스크가 큰 기능을 추가할 때도 브랜치를 사용할 수 있다. 예를 들어 어떤 제품이 2주일에 한번씩 업데이트를 한다고 할 때, 어떤 기능은 구현하는데 4주가 걸린다면 2주 만에 업데이트를 할 때, 완성되지 않은 기능이 포함될 수 있다. 또는 구현의 가능성이 확실하지 않은 기능을 원래 소스코드에서 개발하느라고 소스코드를 마구 건드릴 경우 나중에 기능을 빼려고 해도 깔끔하게 원래대로 되돌려 놓기가 쉽지 않다. 이럴 때 브랜치를 해서 해당 기능이 완성된 후 메인 소스코드와 머지를 하면 된다. 이러한 브랜치를 기능브랜치(Function Branch, Feature Branch)라고 부른다.

브랜치 중에 가장 문제가 되는 경우는 고객의 특수한 요구를 만족시키기 위해서 제품이 분기되는 경우(Customer Branch)이다. 제품이 분기된 뒤, 나중에 머지되지 않고 영원히 브랜치가 유지되는 경우가 많다. 브랜치를 만들고 어느 시점이 지나면 원래 소스코드와 브랜치가 너무 차이가 많이 나서 머지가 거의 불가능해지기 때문이다. 
브랜치를 쉽게 생각하고 일단 소스코드를 분기해서 별도의 제품을 만들기 시작하는 것은 되돌아 올 수 없는 강을 건넌 것이나 다름없다. 경험이 부족한 개발자는 브랜치의 부담을 우습게 생각하기 쉽다. 실제로 초기에는 브랜치가 있어도 견딜만하고 관리할 만 하다. 특히 브랜치를 해야만 매출을 일으키는 경우라면 브랜치의 유혹을 뿌리치기가 쉽지 않다.

그러나 이렇게 브랜치를 계속 만들다 보면 더 이상 감당이 안 되는 때가 오게 된다. 회사가 어느 정도 매출이 일어나고 잘되기 시작하면 과거에 많이 만들어 놓은 브랜치가 더욱 발목을 잡는다. 어차피 제품이 많이 팔리지도 않았다면 문제가 될 것도 없다. 오히려 회사가 잘될 때 문제가 된다. 이쯤 되면 제품의 업그레이드나 신제품 개발보다는 브랜치 관리에 더 많은 노력을 기울일 수밖에 없게 된다. 버그를 하나 고쳐도 여기저기 브랜치를 다 손대야 한다. 어느 브랜치를 어느 고객이 쓰고 있는지 헷갈려서 배포 사고도 가끔 발생한다. 무슨 툴을 하나 만들어도 각 브랜치마다 다르게 개발해야 하는 어려움이 발생한다. 

브랜치가 많아지면 웬만큼 관리를 잘하지 않고는 어느 브랜치에 무슨 기능이 포함되어 있는지 정확하게 파악하기 힘들어 진다. 초기에 브랜치를 만들었던 개발자들도 얼마 간은 브랜치 내용을 정확하게 기억하고 있을지 모르지만, 시간이 지나면 브랜치를 만든 개발자마저도 브랜치 내용을 정확하게 기억하기 어려워진다. 게다가 문서는 없고, 사람마저 바뀌어버리면 정말 알 수 없는 상황이 된다. 이로 인한 문제를 말하자면 끝이 없지만, 한마디로 아수라장이 되어버린다고 할 수 있다.

브랜치가 필요하다고 해서 개발자가 원할 때마다 브랜치를 해서는 안 된다. 브랜치를 하려면 개발 조직의 최고 책임자나 위원회의 허락을 받도록 하는 것이 좋다. 이 때는 브랜치를 해야 하는 이유를 타당하게 설명해야 하고 가능하면 빨리 머지를 할 수 있는 계획도 세워야 할 것이다.

특히 영업 지향의 회사에서는 브랜치의 위험성에 대해서 이해하지 못하는 경우가 많다. 단기적인 매출의 유혹이 회사의 미래를 망치는 경우를 종종 보게 된다. 고객마다 소스코드가 다르고 매번 각 사이트를 지원하기 위해 개발자들이 고객 전용 소스코드를 수정하고 있어도 이를 당연한 것으로 생각하기 쉽다. 이렇게 되풀이 되는 일들이 개발자들의 사기를 떨어뜨리는 것은 물론이다.

2008년 11월 14일 금요일

빌드와 컴파일의 차이

kenu님의 블로그에 빌드와 컴파일에 대한 차이를 묻는 글이 올라와서 간단히 설명해보려고 합니다.

컴파일 : 소스코드 파일 등의 원시파일을 실행파일, 라이브러리 등의 Object 파일로 바꾸는 작업

빌드 : 소스코드 파일들을 컴퓨터에서 실행할 수 있는 소프트웨어로 변환하는 일련의 과정

컴파일은 빌드의 부분 집합입니다.
빌드 과정은 제품마다 서로 다르지만 간단한 예를 하나 들어보면 다음과 같습니다.
보통 아래 과정은 Build Script에 의해서 한번에 자동으로 실행됩니다.
실제 예는 아래 나열한 것보다 수십배는 더 복잡합니다. ^^
  1. 소스코드관리시스템에 태그(베이스라인) 작성
  2. 작성된 태그(베이스라인) 체크아웃을 통해 빌드 전용시스템으로 소소코드 가져오기
  3. 새로운 빌드번호 획득 및 반영
  4. 컴파일(빌드) 시작
  5. 컴파일(빌드)시 발생한 에러 처리
  6. Doxygen 또는 JavaDoc 생성
  7. 팩키징 절차를 통해서 마스터 파일 생성
  8. 스모크 테스트 등 자동화 테스트 실시
  9. 테스트 결과 처리
  10. 빌드 결과를 관련자에 이메일로 전송
  11. 마스터 서버로 마스터 파일 복사
  12. 릴리즈 결과 전사 공지
또 빌드와 릴리즈는 항상 짝을 이뤄 따라 다니며, 수많은 B/R(Build/Release) 엔지니어들이 이에 대한 자동화와 효율성/생산성 증대를 위해서 연구를 하고 있지요. 
소프트웨어 프로젝트에서 빌드의 중요성에 대해서는 제가 이미 포스팅을 한 글이 있으니 참고하세요.

내부 세미나

영회님의 공감이 가는 글(http://younghoe.info/994#footnote_link_994_1)을 보고 의견을 남겨보려고 합니다.

소프트웨어를 개발하는 회사라면 당연히 갖추고 있어야 할 개발 문화는 여러가지가 있지요.
Peer Review, Sharing, 규칙 준수 ...

이 중에서 좋은 문화 중의 하나가 일상화된 내부세미나입니다.

유수의 소프트웨어 회사들을 보면 회사에 늘상 세미나 공지가 있습니다.
누구나 세미나를 진행할 수 있고, 
대부분 직원들이 관심을 가질 만한 주제들이고,
누구나 부담없이 참여를 합니다.
오다가다 들려서 보기도 하고, 
관심이 많으면 준비를 해와서 발표자와 토론도 하기도 하기도 합니다.
누가 시켜서 의무적으로 하는 세미나는 아니지요.

그러한 과정에서 발표자에게도 지식을 더욱 깊고 굳건히 할 수 있는 기회가 되고,
참가자는 새로운 지식을 쉽게 익힐 수 있는 기회가 되고,
회사는 항상 연구하고 새로운 기술을 추구하는 자연스런 분위기가 됩니다.

항상 프로젝트에 치여서 이럴 시간이 전혀 없다면 곤란하지요.
강제로 해야 하고 강제로 참여해야 한다면, 문화로 자리잡을 수가 없지요.
회사에서는 이에 대한 시간적인 공간적인 배려와 약간의 금전적인 지원도 좋죠.

이를 포함한 여러 개발문화들이 뿌리깊게 자리잡지 않고는 Global 경쟁력을 갖춘 소프트웨어 개발 회사가 된다는 것은 불가능하다는 것을 인식해야 하지 않을까요?

Expect Unexpected



제가 구독하는 블로그에 좋은 글이 있어서 번역해서 소개를 합니다.

 예상치 않은 것을 예상하라.

프로젝트관리의 오래된 규칙: 항상 예상치 못한 일이 일어난다. 프로젝트관리자라면 예상치 못한 것을 예상하고 가능한 많은 준비를 해야 한다.

실제로, 잘 준비된 프로젝트 관리자는 예상치못한 일이 일어 났을 때에 대비하여 단지 B플랜(백업플랜)을 가지고만 있는 것이 아니라 B플랜을 실행할 능력을 가지고 있다. 리스크관리는 예측할 수 있는 이슈를 다루는 것이고 바라건데 모든 프로젝트관리자의 기본이다. 하지만 몇가지는 절대로 예상할 수 없다.

이것이 좋은 프로젝트관리자와 위대한 프로젝트관리자를 구분하는 것이다. 예상치 못한 일을 예상하는 능력과 이를 처리할 수 있는 능력이다.

그리고 당신은 예상할 수 없는 상황을 어떻게 처리하는가?

http://blog.brodzinski.com/2008/11/expect-unexpected.html

Expect Unexpected

The old rule of project management: there’s always an unexpected thing to happen. Being a project manager you should expect the unexpected and try to prepare yourself as much as possible.

Actually, well-prepared project manager has not only a plan B for possible failures, she also has an ability to craft a plan B on the fly when something uncommon or unexpected happens. Risk management is all about dealing with issues you can predict and that’s bread and butter of every project manager out there I hope. However some things you can never predict.

That’s the thing which usually differentiates good project managers from great project managers. Ability to expect the unexpected and ability to deal with the situation.

And how you deal with situations you can’t predict?

2008년 11월 13일 목요일

신입 개발자가 들어오면?

신입 개발자가 들어오면 어떻게 하시나요?

회사에서 소프트웨어를 개발하기 위해서는 많은 것을 알아야 함에도 불구하고 딱히 가르칠게 별로 없는 경우를 많이 보았습니다. 체계적인 교육 방법로 마땅치 않고요.
어떻게 신인 개발자를 가르치고 있는지 제가 아는대로 한번 나열을 해보죠.
  • 멘토(사수)를 지정해서 맨투맨으로 이거 저거 생각나는 대로 알려준다.
  • 회사에 문서는 정말로 많다. 책꽂이로 한 벽 가득이다. 그 중에서 뭘 보라고해야 할지 잘 모르겠다.
  • 제품에 관한 변변한 문서가 하나도 없다. 있다 하더라도 부실하거나 옛날 버전이다. 그래서 말로 아는대로 설명해준다.
  • 개발하는 제품의 메뉴얼을 보여주고 제품의 기능을 익히게 한다.
  • 일단 일을 시키고 본다. 물어보는 것이 있으면 그때 그때 알려준다.
  • 소스코드를 보게 한다. 소스코드를 분석해서 스스로 제품의 구조를 알아내는 것도 큰 공부다.
위와 같은 현상이 소설은 아닙니다. 실제로 주변에서 흔히 있는 일을 적어본 겁니다.
우리는 전혀 다르다라고 하시는 분도 있나요?
아니면 이게 무슨 문제지? 라고 생각하는 분도 있나요? 음... 그럼 그렇게 생각하는 것이 또 문제네요. ^^

사실 신입개발자가 들어왔을 때 효율적으로 교육을 시킬 수 있는 역량을 갖추는 일은 쉬운 것이 아닙니다.
그 정도 되면 회사가 소프트웨어 개발 회사로서 왠만한 모든 것은 다 갖추고 있는 것이니까요.

이는 "닭이 먼저냐 달걀이 먼저냐"와 비슷합니다.
그렇게 잘 교육된 신입 개발자는 나중에 고참이 되어서 새로운 신입사원에게 자신이 겪은 대로 할 것입니다.

모든 것을 다 갖추어야 한다고 하면 막막하니까 핵심적인 것만 몇 가지 얘기를 해보죠.

내가 어느 소프트웨어 회사에 신입 개발자로 입사를 했습니다.
당연히 그 소프트웨어 회사는 다음과 같은 기본적인 시스템은 갖추고 있어야 합니다.
  • 소스코드관리시스템
  • 버그관리시스템
  • 개발 프로세스
  • 코딩컨벤션(프로그래밍 가이드)
그리고 입사를 하면 가장 먼저 위의 시스템과 프로세스, 규칙을 익히고 제품에 대한 기본적인 개발문서를 보게 됩니다. 이때 문서가 너무 많거나 아예 없거나 부실해서 있으나마나 하면 소용이 없죠.
그래서 제품의 스펙문서(SRS, Software Requirements Specification)을 먼저 보고 제품을 이해하게 되면 설계서를 보게 되죠. SRS라는 용어가 낯선 분이 있을텐데, SRS는 앞으로 제가 올리는 수많은 글들의 주요 주제가 될 예정이니 지금은 그냥 소프트웨어의 스펙을 정리한 문서라고만 생각해도 됩니다.

이제 저는 소프트웨어 개발에 투입될 기본적인 준비는 된 겁니다. 

그리고 나면 버그를 고치는 일부터 할당이 됩니다. 아주 쉬운 버그부터 시작합니다.
고참은 고치는데 10분이면 될 일은 나는 반나절은 걸려서 해야 할 겁니다. 그래도 그만한 가치가 있는 일이지요.
  • 먼저 버그관리시스템에서 버그를 할당 받습니다.
  • 선배가 어느 파일을 어떻게 고쳐야 하는지도 가이드를 해줍니다.
  • 소스코드관리시스템에서 코드를 내려 받아서 소스코드를 수정합니다.
  • 선배들이 코드리뷰를 해줍니다.
  • 빌드스크립트를 이용해서 빌드도 해봅니다.
  • 개발자 Unit Test도 수행하고요.
  • 버그관리시스템도 갱신합니다.
이런 일을 몇 번 하면서 점점 더 어려운 일을 하지만 항상 선배들이 코드리뷰를 해줍니다.
그러고 나면 설계에도 참여를 하고 새로운 모듈이나 제품도 맡게 됩니다.

엄청나게 많은 일을 몇 줄로 작성을 하다 보니 너무 간단해지기는 했지만 기본은 아래 3가지 입니다.
  • 제대로된 시스템(Infrastructure system)과 개발 프로세스
  • 최신 버전으로 업데이트된 제대로 적힌 핵심 개발문서(SRS)
  • Code Review, Peer Review
사실 이 기본을 갖추는 일은 매우 어려운 일입니다.
어떻게 이러한 기본을 갖춰나가야 할지에 대한 의문이 있다면 저와 계속 의논을 해나가면 어떨까요?

2008년 11월 12일 수요일

빌드가 먼저일까? 베이스라인 설정이 먼저일까?

빌드와 베이스라인 순서에 대해서 이슈가 있다는 글을 보고 아래 글을 작성합니다.

몇몇 빌드관련 솔루션들이 빌드를 해서 성공을 하면 베이스라인(Tag, Label)을 설정하는 것이 있더군요.
이는 원칙에 어긋나는 겁니다.

원칙은 베이스라인을 설정한 후에 해당 베이스라인을 가지고 빌드를 하는 것입니다. 작은 소프트웨어는 사실 이러한 것이 거의 문제가 되지 않습니다. 하지만 대규모 프로젝트는 빌드에 24시간이 넘게 걸리는 것도 있습니다.
Windows NT 개발팀은 Daily Build가 48시간이 걸려서 몇대의 장비가 교대로 Daily Build를 수행했다고 할 정도 입니다.
이 경우 빌드가 끝나고 나서 베이스라인을 설정하려고 하면 이미 소스코드는 엄청나게 바뀌어 있게 됩니다.

베이스라인 설정, 태깅 한 후에 태그를 가져와서 빌드를 하도록 빌드 스크립트를 만들면 됩니다.

Subversion(SVN)과 CVS의 비교

Subversion(SVN)과 CVS에 대한 비교라기 보다는 SVN이 CVS와 비교하여 상대적으로 어떤 점이 더 좋은지에 대한 설명입니다.
SVN은 CVS를 개발하던 핵심 개발자들이 그동안 CVS가 가지고 있던 문제를 해결하고자 완전히 새로운 아키텍쳐로 새로 만든 제품입니다.
따라서 기존에 CVS를 사용하고 있던 개발자들은 SVN으로 넘어오는 것을 적극 검토해보시기 바랍니다.


Subversion(SVN)의 장점
  • CVS에 비해 엄청나게 빠른 업데이트/브랜칭/태깅 시간. -> 최고로 강력한 장점입니다. 
    기존에 대형 프로젝트 같은 경우는 CVS를 이용하면 태깅에 수십분이 걸리기도 했습니다. 하지만 SVN은 아무리 규모가 커도 몇초면 끝납니다.
  • 커밋 단위가 파일이 아니라 체인지셋이라는 점입니다. CVS에서라면 여러 개의 파일을 한꺼번에 커밋하더라도 각각의 파일마다. 리비전이 따로 붙습니다. 반면 Subversion에서는 파일별 리비전이 없고 한번 커밋할 때마다 변경 사항별로 리비전이 하나씩 증가합니다. 
  • CVS와 거의 동일한 사용법. CVS 사용자라면 누구나 어려움 없이 금방 배울 수 있습니다. 
    또한 CVS를 SVN으로 쉽게 Migration을 할 수 있어 원하는 사람은 쉽게 SVN으로 옮겨 올 수 있습니다.
  • 원자적(atomic) 커밋. CVS에서는 여러 파일을 커밋하다가 어느 한 파일에서 커밋이 실패했을 경우 앞의 파일만 커밋이 적용되고 뒤의 파일들은 그대로 남아있게 됩니다. Subversion은 여러개의 파일을 커밋하더라도 커밋이 실패하면 모두 이전 상태로 되돌아 갑니다. 
  • 양방향 데이터 전송으로 네트워크 소통량(트래픽) 최소화. 
    네트워크 상황이 열악한 외부에서도 SVN을 사용하면 협업에 문제가 없습니다.
  • 트리별, 파일별 접근 제어 리스트. 저장소 쓰기 접근을 가진 개발자라도 아무 소스나 수정하지 못하게 조절할 수 있습니다. 




SVN의 설치 방법은 그리 어렵지 않고 인터넷에서 쉽게 구할 수 있으므로 굳이 여기서 설명할 필요는 없겠죠?