레이블이 svn인 게시물을 표시합니다. 모든 게시물 표시
레이블이 svn인 게시물을 표시합니다. 모든 게시물 표시

2020년 10월 16일 금요일

SVN commit hook connect JIRA - Add Comment(Only My Brain-fficial)

 

have following software installed

1. jira 다운 및 설치

링크 - https://www.atlassian.com/ko/software/jira/download

 - start jira server[8080] 으로 서벼 켜놓고 localhost:8080 으로 접속

 - 설치 후 jira 계정 생성 및 프로젝트 생성에서 대충 이슈 만들어서 세팅


2. VisualSVN server 다운 및 설치.

Visual SVN Server Download

https://www.visualsvn.com/server/download/


2 - 1. repository 생성

- 생성 하면 백업 폴더에 hooks 폴더 생성 되어있음.

참고 - https://www.visualsvn.com/server/getting-started/

create ex) 빨간 박스는 밑에 과정에서 생긴 파일들.



3. php 다운 및 설치 (perl 방식도 있으나 안해봄) - OS종류 잘 보고 따라할것.

 - https://www.lesstif.com/software-architect/svn-hook-commit-jira-17105782.html

 - 위 링크와 같도록 셋팅. (cmd 창 이미지는 기존 svn으로 사용하듯이 commit 해도 됨)

 - 정규식 관련 자료 - https://regexr.com/
    (나도 잘 모르므로 검색하시길..)


4. JIRA REST API v2 Document

 - https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-comments/#api-rest-api-2-issue-issueidorkey-comment-post

 - 위 링크에서 필요한 정보들 찾아서 추가 및 수정. (본인은 add comment 만 추가한 상태)


-------------- only my example codes ---------------


pre-commit.cmd

- .bat file

Copy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 echo start 1>&2 echo message 1>&2 echo : %MESSAGE% 1>&2 for /f "tokens=* USEBACKQ" %%i in (`svnlook log %1 -t %2`) do ( set "RESULT=%%i" ) echo "%RESULT%" 1>&2 :: ex ) "C:/Program Files/PHP/v7.2/php.exe" -n C:/Repositories/HookTest/hooks/pre-commit.php %1 %2 "%RESULT%" php "%1\hooks\pre-commit.php" "%1" "%2" "%RESULT%"

 - comment 부분 utf-8로 넘기는 작업



pre-commit.php

 - commit hook php file

Copy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #!/usr/bin/env php <?php require_once 'jira_comment.php'; ////// ini 에서 가져온 값들 ////////// $configVars = parse_ini_file('myconfig.ini', TRUE); $username = $configVars['Account']['username']; $password = $configVars['Account']['password']; $jiraURL = $configVars['Address']['url']; $jiraURL_Issue = $configVars['Address']['url_issue']; //////////////////////////////////// # comment 가 4자 미만이면 커밋 거부 $minchars = 4; $svnlook = 'svnlook'; #-------------------------------------------- $repos = $argv[1]; $txn = $argv[2]; $comment = $argv[3]; #$comment = `$svnlook log -t "$txn" "$repos"`; $comment_temp = $comment; $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. : $comment\n"); fwrite(STDERR, "---------------------------------------------------------------------------\n"); exit(1); } ## 커밋 메시지에 Jira issue keys 가 들어 있는지 확인 #$pattern = '/(?P<prj>[0-9a-zA-Z]{1,10})-{1,10}(?P<inum>[0-9]+):(?P<comm>[\x{1100}-\x{11FF}\x{3130}-\x{318F}\x{AC00}-\x{D7AF}]{0,1000})+/u'; $pattern = '/(?P<prj>[0-9a-zA-Z]{1,10})-{1,10}(?P<inum>[0-9]+)/'; #$pattern = '/[^0-9a-zA-Z]?(?P<prj>[0-9A-Za-z]{1,10})-{1,10}(?P<inum>[0-9]+)./'; #$pattern = '/\w?(?P<prj>\w{1,10})-\d(?P<inum>\d{1,10})./'; $matches = 0; if (!preg_match($pattern, $comment, $matches)) { fwrite(STDERR, "---------------------------------------------------------------------------\n"); fwrite(STDERR, "Comment must match JIRA-ISSUE-KEY!!! \"$comment\"\n"); fwrite(STDERR, print_r($matches,TRUE)); fwrite(STDERR, "---------------------------------------------------------------------------\n"); exit(1); } $issue_key = $matches["prj"] . "-" . $matches["inum"]; #$comment_key = $matches["comm"]; $strLength = mb_strlen($issue_key) + 1; $comment_key = mb_substr($comment_temp,$strLength); ## jira issue key 가 존재하는지 JIRA REST API 로 확인. // ini 로 변경. #$ch = curl_init("http://localhost:8080/rest/api/2/issue/"); #$url = "http://localhost:8080/rest/api/2/search/"; /////////////// curl 날리는 방식 ///////////////////// /* ( $ch = curl_init(); $data = array("jql" => "issuekey=$issue_key","maxResults" => 5); $json_string = json_encode($data); curl_setopt($ch, CURLOPT_URL, $jiraURL); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_VERBOSE, TRUE); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_setopt($ch, CURLOPT_USERPWD, "$username:$password"); 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); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $response = json_decode($result); 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); } ) */ ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////// jira issue 관련 //////////////////////////////////////////////////////// $url_issue = $jiraURL_Issue.$issue_key; $url_comment = $url_issue.'/comment'; JiraComment::BaseAuth($username, $password); JiraComment::GetIssueFromIssuekey($url_comment, $issue_key); JiraComment::AddIssueComment($url_comment, $comment_key); ######################## 로 그 찍 어 보 는 공 간 ( 에러 났을때 )######################## fwrite(STDERR , "------------------------------------------------------------------------\n"); fwrite(STDERR , "Comment - \"$comment\"\n"); fwrite(STDERR , "------------------------------------------------------------------------\n"); fwrite(STDERR , "Issue Key - \"$issue_key\"\n"); fwrite(STDERR , "------------------------------------------------------------------------\n"); fwrite(STDERR , "Comment key - \"$comment_key\"\n"); fwrite(STDERR , "------------------------------------------------------------------------\n"); fwrite(STDERR, print_r($matches,TRUE)); fwrite(STDERR , "------------------------------------------------------------------------\n"); fwrite(STDERR , print_r($data,TRUE)); fwrite(STDERR , "------------------------------------------------------------------------\n"); fwrite(STDERR , "json string - \" $json_string\"\n"); fwrite(STDERR , "------------------------------------------------------------------------\n"); fwrite(STDERR , "code - \" $code\"\n"); fwrite(STDERR , "------------------------------------------------------------------------\n"); fwrite(STDERR , "result - \" $result\"\n"); fwrite(STDERR , "------------------------------------------------------------------------\n"); ##################################################################################### exit(0); ?>



jira_comment.php

 - pre-commit jira support php file (feat.unirest)

Copy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <?php require_once 'C:\Users\ldy\Documents\unirest-php-master\src\Unirest.php'; class JiraComment { ////////jira 기본 인증. public static function BaseAuth($username, $password) { Unirest\Request::auth($username, $password); } ////////이슈 정보 get. public static function GetIssueInfo($issueURL, $issueKey) { $headers = array( 'Accept' => 'application/json', ); $response = Unirest\Request::get( $issueURL.$issueKey, $headers ); if ($response == NULL or property_exists ($response,"errorMessages")) { fwrite(STDERR, "===============================================\n"); fwrite(STDERR, "Error! GetIssueInfo - " . ($response == NULL ? "Request failed" : $response->errorMessages[0]) . "\n"); fwrite(STDERR, "===============================================\n"); exit(1); } else { var_dump($response); } } ////////이슈에 댓글 정보 get. public static function GetIssueCommentsInfo($issueCommnetURL) { $headers = array( 'Accept' => 'application/json', ); return Unirest\Request::get( $issueCommnetURL, $headers ); } ////////이슈키에 맞는 댓글 정보 get. public static function GetIssueFromIssuekey($issueCommnetURL, $issuekey) { $headers = array( 'Accept' => 'application/json', ); $response_getcomment = Unirest\Request::get( $issueCommnetURL, $headers ); //입력한 이슈 키에 대한 이슈를 못가져 왔다면 error. if($response_getcomment->code != 200) { fwrite(STDERR, "===============================================\n"); fwrite(STDERR, "== Comment must match JIRA-ISSUE-KEY!!!!!!!!!!!!!! \"$issuekey\"\n"); fwrite(STDERR, "===============================================\n"); exit(1); } else { var_dump($response_getcomment); } } ////////이슈키에 맞는 이슈에 댓글 add. public static function AddIssueComment($issueCommnetURL, $comment) { $headers = array( 'Accept' => 'application/json', 'Content-Type' => 'application/json; charset=utf-8', ); /*$body = <<<REQUESTBODY { /////// 관리자전용 댓글 달수있게하는 옵션 ////////// "visibility": { "type": "role", "value": "Administrators" }, ////////////////////////////////////////////////// "body": "{$comment_key}" } REQUESTBODY; */ $body = <<<REQUESTBODY { "body": "{$comment}" } REQUESTBODY; $response = Unirest\Request::post( $issueCommnetURL, $headers, $body ); if ($response == NULL or property_exists ($response,"errorMessages")) { fwrite(STDERR, "===============================================\n"); fwrite(STDERR, "Error! AddIssueComment - " . ($response == NULL ? "Request failed" : $response->errorMessages[0]) . "\n"); fwrite(STDERR, "===============================================\n"); exit(1); } else { var_dump($response); } } } ?>


위 코드 사용시 Unirest관련 not found error 발생.

https://github.com/Kong/unirest-php

- 위 링크에서 받아서 압축 해제 후 php 코드 맨 위에 삽입.

require_once '/path/to/unirest-php/src/Unirest.php';

( jira_comment.php 상단에 있음 )


myconfig.ini

- ini file

Copy
1 2 3 4 5 6 7 8 9 ; My Account Setting [Account] username="jira-id" password="jira-password" ; Jira Address Setting [Address] url="http://'jira url'/rest/api/2/search/" url_issue = "http://'jira url'/rest/api/2/issue/"



- 번 외 -

jira-subversion-plugin

 - https://github.com/kashak88/jira-subversion-plugin/blob/master/atlassian-jira-subversion-plugin-3.0.2-jira8.jar

(jira8 에서 사용가능한 plugin - 설치는 되나 작동하는지 확인은 안됨)


2020년 10월 7일 수요일

svnlook: Can't open file ~ The filename, directory name, or volume label syntax is incorrect.

 


A basic reason 1

Perhaps you haven't installed tortorisSVN Comman Line Client Tools.

So svnlook was not installed.

2019년 12월 20일 금요일

GIT 과 SVN의 차이점

GIT 과 SVN 을 이해하려면 먼저 형상관리(버전관리)에 대해 이해해야 한다.
프로젝트를 진행할 때 각자 업무를 나눠서 맡은 부분을 개발을 하게 되는데,
각자가 개발한 코드 혹은 문서들을 하나의 관리 도구에서 통합적으로, 버전별로 관리하게 되는 것을
형상관리(Configuration Management) 혹은 버전관리(Version Management)라고 부른다.
형상관리, 버전관리, 변경관리 등 용어는 다양하지만
실무에서 사용하는 의미는 거의 비슷하기 때문에 구분하지 않고 사용하는 경우가 많다.

형상관리 방식에는 크게 중앙집중식분산관리식 으로 나뉘는데
대표적으로 사용되는 도구가
중앙집중관리식의 SVN 그리고 분산관리식의 GIT 이다.
SVN 은 내 로컬PC 에서 Commit을 하면 바로 중앙저장소에 반영이 되는 반면
GIT 은 내 로컬PC에서 Commit을 하면 로컬 저장소에 반영이 되고 로컬저장소에서 Push를 하면
원격저장소에 반영이 된다.

SVN최대의 장점은 직관적이다.
모든 사람이 중앙서버에 있는 같은 자료를 받아오고
내가 Commit을 하는 순간 모든 사람에게 공유가 된다.
이러한 방식의 단점은 만약 두 사람이 하나의 파일을 동시에 수정하고 커밋하였을 때
충돌이 일어날 확률이 높다는 얘기이다.

반면 GIT은 직관적이지 못하고 적응하는데에 시간이 필요하다.
내가 한 작업물을 원격저장소에 올리려면
우선 로컬PC 에서 작업내용을 Commit 하여 로컬 저장소에 반영한 후,
원격저장소에서 fetch로 로컬저장소로 마스터 파일을 받아와서
충돌이 나지 않게 merge를 이용하여 합친 다음,
로컬 저장소의 내용을 Push 하여 원격저장소에 올리면 그때 다른 사람들에게 나의 작업 내용이 공유가 된다.

그러나 GIT 의 장점은
모든 작업이 로컬에서 이루어지고 네트워크 사용은 원격 저장소로 저장할 때 한 번 이루어지므로
개발 시 처리속도가 빠르고,
웹 상에 저장소를 둘 수 있기 때문에
언제 어디서나 협업을 할 수 있고(이건 단점일수도…),
여러 사람이 가지가 뻗어나가듯 자신의 작업을 하기 때문에 이를 브랜치 라고 하는데,
브랜치와 머지의 상호작용을 잘 할 수 있도록 편의성을 잘 제공해주기 때문에 협업이 더욱 더 용이해진다.
그리고 원격저장소의 내용이 모든 협업자들의 로컬 저장소에 저장이 되어 있으므로
중앙저장소에 에러가 생기면 모든 작업이 마비되는 SVN 과 다르게
원격저장소에 에러가 생겨도 로컬에서 복구하기 용이하고,
히스토리 관리가 잘 제공되어 있어 히스토리 관리가 용이하다.


2019년 11월 20일 수요일

Git이란?

▶ 1. Git이란? (참고 : https://git-scm.com/book/ko/v2 (공식 Site 한글 매뉴얼))



 - SVN과 마찬가지로 소스코드의 효율적인 관리를 위한 형상 관리 도구(Configuration Management Tool) 중 하나.
즉, 소프트웨어를 개발하는 기업의 핵심 자산인 소스코드를 효과적으로 관리할 수 있게 해주는 무료이자 공개소프트웨어이다.
최근 오픈소스 커뮤니티의 발전과 함께 널리 사용되고 있으며, SVN을 사용하던 개발 조직들도 하나둘씩 Git으로 갈아타고 있는 추세.

 - Git이 SVN과 다른 점은 분산형 관리 시스템이라는 것이다.
중앙 서버에 소스코드와 히스토리를 저장하는 SVN과 달리 Git은 소스코드를 여러 개발 PC와 저장소에 분산해서 저장하기 때문에 중앙 서버에 장애가 발생해도 로컬 저장소에 커밋을 할 수 있으며, 로컬 저장소들을 이용하여 중앙 저장소의 복원도 가능하다.
또한, 분산형으로 코드를 관리하기 때문에 다양한 Workflow를 가능하게 한다는 점이 SVN과 비교하여 Git이 갖는 장점이라 할 수 있다.

 - 초창기 Git은 리눅스를 만든 리눅스 토발즈가 리눅스 커널 개발에 이용하려고 만들었다. 
기존 리눅스 커널 관리를 위해 BitKeeper라는 툴을 쓰다가 유료로 전환되는 바람에 만든 분산형 버전 관리 시스템이다.
이후 GitHub 등에서 오픈소스 개발을 위해 사용하면서 소프트웨어 업계에 널리 사용되게 되었다.

 - 참고 URL
SourceTree (클릭으로 Git을 관리할 수 있는 툴) : https://www.sourcetreeapp.com/



▶ 2. Git의 장점

- 소스코드를 주고 받을 필요 없이, 같은 파일을 여러 명이 동시에 작업하는 병렬 개발이 가능하다.

- 즉 브랜치를 통해 개발한 뒤, 본 프로그램에 합치는 방식(Merge)으로 개발을 진행할 수 있다. 

- 분산 버전관리이기 때문에 인터넷이 연결되지 않은 곳에서도 개발을 진행할 수 있으며, 중앙 저장소가 날라가버려도 다시 원상복구할 수 있습니다.

- 팀 프로젝트가 아닌, 개인 프로젝트일지라도 GIT을 통해 버전 관리를 하면 체계적인 개발이 가능해지고, 프로그램이나 패치를 배포하는 과정도 간단해집니다. (pull을 통한 업데이트, patch 파일 배포) 


  (그림 출처: http://pismute.github.io/whygitisbetter/images/local-remote.png)



▶ 3. 공식 사이트에 나온 Git의 특징

 - 3.1 Distributed development
전체 개발 이력을 각 개발자의 로컬로 복사본을 제공하고 변경된 이력을 다시 하나의 저장소로 복사한다.
이러한 변경은 추가개발지점을 가져와, 로컬개발 지점과 동일하게 병합(merge)할 수 있다.저장소는 Git protocol 및 HTTP로 쉽고 효율적(특별한 웹서버 구성없이)으로 접근할 수 있다.

 - 3.2 Strong support for non-linear development
신속하고 편리항 branch 및 merge 지원, 비선형(여러갈래) 개발 이력을 시각화하고 탐색 할 수 있는 강력한 도구를 제공한다.

 - 3.3 Efficient handling of large projects
Git은 매우 빠르고, 대형프로젝트나 이력이 많은 작업에 매우 합리적이다. Git은 대부분의 다른 버전관리시스템보다 빠르게 요청한다. 그리고 일부 작업에서는 더 빠르게 진행한다.
또한, 최근의 정상급 오픈소스 버전관리 시스템보다 장기간의 수정내역을 매우 효율적인 압축방법을 사용한다.

 - 3.4 Cryptographic authentication of history
GIt의 이력은  성공한 개발이력의 commit에 의해 개정명으로 저장된다. 일단 그것이 배포되면, 그것을 모르고 예전버전으로 변경하는것은 불가능하다. 또한, 그것들을 암호화 할수 있다.

 - 3.5 Toolkit design
UNIX의 전통에 따라, GIT은 C로 작성된 많은 소규모 도구모음이다, 그리고 많은 스크립트들이 기능 보강을 제공한다. Git은 새로운 기발한 작업을 위한 손쉬운 사용과 쉬운 스크립팅을 위한 도구를 제공한다.



▶ 4. Github. Gitlab?

- Git 이랑 Github은 무슨 차이일까????

Git의 기능 데이터를 원격 저장소에 저장하는 기능이 있다. 이때 원격 저장소 역할을 하는 것이 Github이다.
하지만 비공개(Private) 프로젝트의 경우 월 비용을 지불해야 하기 때문에 비공개 프로젝트도 무료로 지원하는 gitlab도 많이 사용되고 있다.



▶ 5. 관련 용어들
 - Repository : 저장소를 의미하며, 저장소는 히스토리, 태그, 소스의 가지치기 혹은 branch에 따라 버전을 저장한다. 저장소를 통해 작업자가 변경한 모든 히스토리를 확인 할 수 있다.

 - Working Tree : 저장소를 어느 한 시점을 바라보는 작업자의 현재 시점.

 - Staging Area : 저장소에 커밋하기 전에 커밋을 준비하는 위치.

 - Commit : 현재 변경된 작업 상태를 점검을 마치면 확정하고 저장소에 저장하는 작업.

 - Head : 현재 작업중인 Branch를 가리킨다.

 - Branch : 가지 또는 분기점을 의미하며, 작업을 할때에 현재 상태를 복사하여 Branch에서 작업을 한 후에 완전하다 싶을때 Merge를 하여 작업을 한다.

 - Merge : 다른 Branch의 내용을 현재 Branch로 가져와 합치는 작업을 의미한다.



▶ 6. Git 사용하기 기초 용어

git init : 버전관리 하고싶은 폴더에서 초기화를 하는 준비

git branch
- 독립적인 공간을 만든다. 
- 새로 만든 branch lab1은 master와 완전히 동일한 상태를 가진 공간.
- 브랜치에서 수정을 한 후 커밋하면 lab1에만 기록되며 master 브랜치에는 어떤 영향도 주지 않는다.
- 원하는 만큼 빠르게 branch를 만들 수 있다.

- 실험 중 다른 브랜치로 돌아가야 할 때 : checkout master 로 head를 옮겨야 한다.
(cf > 작업 중인 위치를 가르키는 가상의 커서가 존재하는데 이를 git에서는 HEAD라 한다.)

- 실험 성공 : lab1 브랜치의 내용을 마스터 브랜치와 병합(Merge) 한다.
- 실험 실패 : lab1 브랜치를 삭제한다.

checkout
- 독립된 작업 공간인 브랜치를 자유롭게 이동할 수 있다.

git commit 
 - 의미있는 수정 작업이 끝났을 때 마침을 알리는 작업

pull
- 리모트 저장소의 변경된 내용을 로컬(내 컴퓨터) 저장소에 적용하는 작업을 pull이라 한다.


master
- git init을 했을 때, default로 만들어지는 가지가 'master'이다.


동료와 함께 작업하려면? -> github! or bitbucket
- git은 'remote 저장소'를 지원한다.
- github이 바로 remote저장소이다.
- bitbucket은 5명까지 공동작업 가능하다. (그 이상은 유료)
- github은 private가 유료이다.


( add, commit, push, pull, fetch, checkout 용어에 따른 프로세스)
( 그림 출처: http://osteele.com)


출처: https://goddaehee.tistory.com/91 [갓대희의 작은공간]