GitLab – system hooks (czyli jak automatycznie dodać web-hooka)

Pisałem ostatnio o tym jak automatycznie serwować statycznie ostatnią wersję repozytorium. Wszystko super, działa i tak dalej. Tylko… wymagać od ludzi by ręcznie za każdym razem dodawali webhooka do tego? Bezsensu ;) Niech robi się to samo! Szukając tego w google trafić można na sugestię by była taka możliwość… Kto by się przejmował tym, że tego nie ma? Na pewno nie ja. Grzebiąc w dokumentacji gitlaba – natrafiłem pierw na informacje o API – za pomocą którego można dodać webhooka do projektu. Tylko.. skoro umiem już dodawać to jak zrobić by dodało się to przy tworzeniu repo? Przy pomocy system hooks ;)

Czym jest systemhooks? Kolejnym miejscem, w którym się podaje adres to pliku, który dostaje na twarz JSONa. Kiedy? Gdy tworzymy/kasujemy: użytkownika, grupę lub repozytorium. Teraz zostało już tylko stworzenie odpowiedniego skryptu i gotowe.

<?php
ignore_user_abort(true);            //don't want users screwing up the processing of the script by stopping it mid-process

$push_webhook_url = "http://static.example.com/push-hook.php"; // url to our push webhook
$gitlab_url       = "https://git.example.com/";  // url to gitlab
$api_version      = "v3";

$user             = "admin";
$token            = "admin-token";

$api_url          = $gitlab_url . "api/" . $api_version;
$auth             = "private_token=" . $token . "&user=" . $user;

function make_post( $data ){
    $post = '';

    foreach( $data as $key => $value ){
        $post .= $key . '=' . $value . '&';
    }
    rtrim( $post, '&' );

    return $post;
}

function add_hook( $id ){
    global $api_url, $auth, $push_webhook_url;

    $data = array( 'url' => $push_webhook_url, 'push_events' => 'true' );
    $url = $api_url . "/projects/" . $id . "/hooks" . "?" . $auth;

    $options = array(
        'http' => array(
            'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
            'method'  => 'POST',
            'content' => make_post( $data ),
        ),
    );
    $context  = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
}

if( $HTTP_RAW_POST_DATA ){
    // decode json from gitlab
    if( $data = json_decode( $HTTP_RAW_POST_DATA ) ){
        if( $data->event_name == "project_create" ){
            add_hook( $data->project_id );
        }
    }

}
?>

Teraz podczas tworzenia nowego repozytorium zostanie wywołany ten skrypt, który za pomocą API GitLaba doda webhooka. Szkoda, że takich opcji nie ma domyślnie w ustawieniach, ale jak widać – nic nie jest niemożliwe ;) W przyszłości prawdopodobnie skrypt przepiszę dodając kolejne funkcjonalności – jak np. kasowanie plików statycznych przy usuwaniu repozytorium.