gitlab의 web hook 을 사용하여 push 시 특정 저장소에 pull 하기

gitlab 저장소에 push 가 발생할 경우 자동적으로 pull 을 해야 할 경우가 있다.

 

gitlab 의 웹 훅을 사용하면 이런 기능을 구현할 수 있다.

 

구성도

gitlab ---> Web Server(php) --> standalone server(ruby)

 

web server 의 php 에서 바로 git pull 을 하지 않는 이유는 SELinux 때문에 웹 서버에서 구동되는 PHP 권한이 낮기 때문에 별도의 standalone 서버를 만들고 여기에 다시 포워딩을 하기 때문이다.

 

Web server용 notify php 작성

gitlab 의 hook 을 받을 스크립트를 작성한 후에 web content 폴더에 git-hook.php 로 저장한다.

git-hook.php
<?php
    $inputJSON = file_get_contents('php://input');
    $input= json_decode( $inputJSON, TRUE ); //convert JSON into array
    // var_dump result as string
    ob_start();
    var_dump($input);
    $result = ob_get_clean();
    error_log("Git Hook Received" );
## 보안 문제때문에 바로 실행 불가
## $res = exec(" git pull origin develop ");
    // create a new cURL resource
    $ch = curl_init();
    // set URL and other appropriate options
    curl_setopt($ch, CURLOPT_URL, "http://localhost:3899/?repos=master");
    curl_setopt($ch, CURLOPT_HEADER, 0);
    // grab URL and pass it to the browser
    $ret = curl_exec($ch);
    if ($ret != TRUE) {
        error_log("curl exec failed: " .  curl_error($ch));
    }
    // close cURL resource, and free up system resources
    curl_close($ch);
?>

 

php 에서 정보를 전달받을 Stand alone server

#!/usr/bin/env ruby
require "webrick"
class GitHookServlet < WEBrick::HTTPServlet::AbstractServlet
    def do_GET (request, response)
            response.status = 200
            response.content_type = "text/plain"
            result = nil
            branch = `git rev-parse --abbrev-ref HEAD`.chomp;
            case branch
                when "develop"
                        result = `git pull origin develop`
                when "master"
                        result = `git pull origin master`
                else
                        result = "No support repository " + branch
                        response.status = 404
            end
            response.body = branch + " is " + result.to_s + "\n"
    end
end
log_file = File.open 'web-rick.log', 'a+'
log = WEBrick::Log.new log_file
access_log = [
  [log_file, WEBrick::AccessLog::COMBINED_LOG_FORMAT],
]
 
## clone 한 저장소 루트
root = '/var/www/wordpress/wordpress-3.9'
Dir.chdir(root)
#server = WEBrick::HTTPServer.new(:Port => 1234)
server = WEBrick::HTTPServer.new :Port => 3899, :DocumentRoot => root, :Logger => log, :AccessLog => access_log
server.mount "/", GitHookServlet
trap("INT") {
    server.shutdown
}
#WEBrick::Daemon.start 
server.start 
  1. git remote -v 로 볼때 origin 이라는 remote 가 추가되어 있어야 한다.
  2. git 서버에 ssh 키가 등록되어 암호를 입력하지 않아도 되도록 설정되어야 한다.

 

저장한 후 다음 명령어로 구동

ruby ./web-server.rb

 

gitlab 의 web hook 설정

gitlab 의 프로젝트에 들어가서 "settings" -> "Web Hooks" 메뉴에서 URL 을 입력하고 "Add Web Hook" 을 클릭한다.

 

이제 push 할 경우