2

Im currently trying to figure out how to deploy an gitlab project automatically using ci. I managed to run the building stage successfully, but im unsure how to retrieve and push those builds to the releases.

As far as I know it is possibile to use rsync or webhooks (for example Git-Auto-Deploy) to get the build. However I failed to apply these options successfully.

For publishing releases I did read https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/api/tags.md#create-a-new-release, but im not sure if I understand the required pathing schema correctly.

Is there any simple complete example to try out this process?

1 Answer 1

1

A way is indeed to use webhooks:

There are tons of different possible solutions to do that. I'd go with a sh script which is invoked by the hook.

How to intercept your webhook is up to the configuration of your server, if you have php-fpm installed you can use a PHP script.

When you create a webhook in your Gitlab project (Settings->Webhooks) you can specify for which kind of events you want the hook (in our case, a new build), and a secret token so you can verify the script has been called by Gitlab.

webhook

The PHP script can be something like that:

<?php
// Check token
$security_file = parse_ini_file("../token.ini");
$gitlab_token = $_SERVER["HTTP_X_GITLAB_TOKEN"];

if ($gitlab_token !== $security_file["token"]) {
    echo "error 403";
    exit(0);
}

// Get data
$json = file_get_contents('php://input');
$data = json_decode($json, true);

// We want only success build on master
if ($data["ref"] !== "master" ||
    $data["build_stage"] !== "deploy" ||
    $data["build_status"] !== "success") {
  exit(0);
}

// Execute the deploy script:
shell_exec("/usr/share/nginx/html/deploy.sh 2>&1");

I created a token.ini file outside the webroot, which is just one line:

token = supersecrettoken

In this way the endpoint can be called only by Gitlab itself. The script then checks some parameters of the build, and if everything is ok it runs the deploy script.

Also the deploy script is very very basic, but there are a couple of interesting things:

#!/bin/bash
# See 'Authentication' section here: http://docs.gitlab.com/ce/api/
SECRET_TOKEN=$PERSONAL_TOKEN

# The path where to put the static files
DEST="/usr/share/nginx/html/"

# The path to use as temporary working directory
TMP="/tmp/"

# Where to save the downloaded file
DOWNLOAD_FILE="site.zip";

cd $TMP;
wget --header="PRIVATE-TOKEN: $SECRET_TOKEN" "https://gitlab.com/api/v3/projects/774560/builds/artifacts/master/download?job=deploy_site" -O $DOWNLOAD_FILE;
ls;
unzip $DOWNLOAD_FILE;

# Whatever, do not do this in a real environment without any other check
rm -rf $DEST;
cp -r _site/ $DEST;
rm -rf _site/;
rm $DOWNLOAD_FILE;

First of all, the script has to be executable (chown +x deploy.sh) and it has to belong to the webserver’s user (usually www-data).

The script needs to have an access token (which you can create here) to access the data. I inserted it as environment variable:

sudo vi /etc/environment

in the file you have to add something like:

PERSONAL_TOKEN="supersecrettoken"

and then remember to reload the file:

source /etc/environment

You can check everything is alright doing sudo -u www-data echo PERSONAL_TOKEN and verify the token is printed in the terminal.

Now, the other interesting part of the script is where is the artifact. The last available build of a branch is reachable only through API; they are working on implementing the API in the web interface so you can always download the last version from the web.

The url of the API is

https://gitlab.example.com/api/v3/projects/projectid/builds/artifacts/branchname/download?job=jobname

While you can imagine what branchname and jobname are, the projectid is a bit more tricky to find.

It is included in the body of the webhook as projectid, but if you do not want to intercept the hook, you can go to the settings of your project, section Triggers, and there are examples of APIs calls: you can determine the project id from there.

Sign up to request clarification or add additional context in comments.

3 Comments

I hosted the php script on my localhost using XAMPP/Apache, but when i test the hook i keep getting "Hook execution failed: execution expired", what could be the cause of this? I guess the gitlab cant access the server, but i have no clue how to debug this.
@aabbcccc does your PC have a public IP? If yes, check if you can reach it from outside your subnet, probably there is some firewall...
@rpadovani,PHP cannot run shell_exec,any other solution?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.