一种方法确实是使用 webhook:
有很多不同的可能解决方案可以做到这一点。我会使用由钩子调用的 sh 脚本。
如何拦截你的 webhook 取决于你的服务器的配置,如果你安装了 php-fpm 你可以使用 PHP 脚本。
当您在 Gitlab 项目(设置->Webhooks)中创建 Webhook 时,您可以指定您想要挂钩的事件类型(在我们的例子中是新构建),以及一个秘密令牌,以便您可以验证脚本已被 Gitlab 调用。
PHP 脚本可以是这样的:
<?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");
我在webroot外面创建了一个token.ini文件,只有一行:
token = supersecrettoken
这样端点只能由Gitlab自己调用。然后该脚本会检查构建的一些参数,如果一切正常,它就会运行部署脚本。
部署脚本也非常基础,但有一些有趣的地方:
#!/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;
首先,脚本必须是可执行的 (chown +x deploy.sh) 并且它必须属于网络服务器的用户(通常是 www-data)。
脚本需要有一个访问令牌(您可以在此处创建)才能访问数据。我将它作为环境变量插入:
sudo vi /etc/environment
在文件中你必须添加类似:
PERSONAL_TOKEN="supersecrettoken"
然后记得重新加载文件:
source /etc/environment
您可以通过sudo -u www-data echo PERSONAL_TOKEN 检查一切是否正常,并验证令牌是否打印在终端中。
现在,脚本的另一个有趣部分是工件在哪里。分支的最后一个可用构建只能通过 API 访问;他们正在努力在 Web 界面中实现 API,以便您始终可以从 Web 下载最新版本。
API的url是
https://gitlab.example.com/api/v3/projects/projectid/builds/artifacts/branchname/download?job=jobname
虽然您可以想象 branchname 和 jobname 是什么,但要找到 projectid 有点困难。
它作为projectid包含在webhook的主体中,但是如果你不想拦截hook,你可以去你项目的设置,触发器部分,有例子API 调用次数:您可以从那里确定项目 ID。