개요

형상관리 시스템은 IT 프로젝트 진행시 가장 중요한 인프라 시스템중에 하나고 commit log 는 변경 내역을 확인하기 좋은 방법이지만 커밋시에 무엇을 바꿨는지 제대로 기술하기는 쉽지 않은 일이다.

보통 하나의 커밋이 하나의 기능 구현이 끝이 아니고(자주 커밋 안 하고 완료시에 커밋하는 경우도 있지만 이력관리 측면에서 좋은 방법은 아니라고 본다)  열심히 코드를 작성하느라 진이 빠져 실제 로그는 "수정중"," ...", "버그있음" 등으로 기술하기 마련이다.

 

개인적으로 좋은 방법은 코딩전에 개발할 내용을 이슈관리 시스템에 등록해 놓고 커밋시는 해당 이슈번호 정도만 넣고 소스의 변경 내역은 이슈관리 시스템의 issue 와 매칭해서 보는 걸 선호한다.

이를 위해 형상관리 시스템의 hook 기능을 이용하여 커밋시 이슈관리와 연결되는 이슈 번호가 있는지, 이슈 번호는 실제 존재하는 이슈인지등을 확인할 수 있다.

 

subversion의 경우 repository의 hooks 폴더에 event 별로 hook script를 생성할 수 있다. (repository 생성시 hook 폴더하에 template인 event.tmpl 파일이 생성된다)

적합한 hook은 commit 전에 실행되는 pre-commit hook 이므로 comment의 길이를 확인하고 JIRA 의 이슈키가 들어 있는지 확인하는 php 스크립트를 만들어 보았다.

사전 요구 사항

  1. php 와 curl-php이 모듈 설치되어야 한다. Windows 는 php.net  에서 다운받으면 된다.
  2. RHE/CentOS 는 RHEL/CentOS 와 Windows 및 Unix 에 php 5.4 설치 을 참고하여 최신 버전을 설치하거나 yum 으로 기본 버전을 설치한다.

    yum install php-cli -y
    CODE

 

Unix & Linux

  1. cd svn_reposistory
  2. vi hook/pre-comimt

    #!/usr/bin/env php
    <?php
     
    # comment 가 6자 미만이면 커밋 거부
    $minchars = 6;
    $svnlook = 'svnlook';
     
     
    #--------------------------------------------
    $repos = $argv[1];
    $txn = $argv[2];
    $comment = `$svnlook log -t "$txn" "$repos"`;
     
    $comment = chop($comment);
     
    if ( strlen($comment) == 0 ) {
      fwrite(STDERR, "---------------------------------------------------------------------------\n");
      fwrite(STDERR, "Your commit has been blocked because it didn't include a log message.!\n");
      fwrite(STDERR, "Do the commit again, this time with a log message that describes your changes.!\n");
      fwrite(STDERR, "---------------------------------------------------------------------------\n");
      exit(1);
    }
    else if ( strlen($comment) < $minchars ) {
      fwrite(STDERR, "---------------------------------------------------------------------------\n");
      fwrite(STDERR, "Comment must be at least $minchars characters.\n");
      fwrite(STDERR, "---------------------------------------------------------------------------\n");
      exit(1);
    }
     
    ## 커밋 메시지에  Jira issue keys 가 들어 있는지 확인
    $pattern = '/[^A-Za-z]?(?P<prj>[A-Za-z]{1,10})-{1,10}(?P<inum>[0-9]+)./';
    $matches = 0;
    if (!preg_match($pattern, $comment, $matches)) {
      fwrite(STDERR, "---------------------------------------------------------------------------\n");
      fwrite(STDERR, "Comment must match JIRA-ISSUE-KEY!!! \"$comment\"\n");
      fwrite(STDERR, "---------------------------------------------------------------------------\n");
      exit(1);
    }
    
    $issue_key = $matches["prj"] . "-" . $matches["inum"];
    ## jira issue key 가 존재하는지 JIRA REST API 로 확인
    $ch = curl_init("https://jira.example.com/rest/api/2/search");
    $data = array("jql" => "issuekey=$issue_key","maxResults" => 5);
    $json_string = json_encode($data);
    curl_setopt($ch, CURLOPT_HEADER, false);
    #curl_setopt($ch, CURLOPT_VERBOSE, TRUE);  
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_USERPWD, "release-bot:qwert123");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                    "Content-type: application/json",
                    'Content-Length: ' . strlen($json_string)
                ));
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json_string);
    $result     = curl_exec($ch);
    $response   = json_decode($result);
    curl_close($ch);
    if ($response == NULL or property_exists ($response,"errorMessages")) {
        fwrite(STDERR, "Error! " . ($response == NULL ? "Request failed" : $response->errorMessages[0]) . "\n");
    	exit(1);
    }
    else {
        #var_dump($response);
    }
    exit(0);
    ?>
    PHP
  3. chmod +x hooks/pre-commit

Windows

  1. 다음 파일을 pre-commit.cmd 이름으로 hooks 폴더밑에 저장한다. ((warning)perl 이 PATH 에 걸려있지 않다면 절대 경로로 써준다.)

    pre-cimmit.cmd

     

    @echo off 
    php "%1\hooks\pre-commit.php" "%1" "%2"
  2. 위의 pre-commit.php 을 hooks 폴더밑에 저장한다. ((warning) svnlook  이 PATH 에 걸려있지 않다면 절대 경로로 써준다.)

     

Test

  1. 다음과 같이 commit message 를 작게 입력해서 정상 동작하는지 확인해 본다.

    svn commit -m "1234"
    CODE