#!/usr/bin/php-cgi -dcgi.force_redirect=0
<?php
# encoding: utf-8
# api: cgi
# type: config
# category: admin
# title: Hooks
# description: Configure hooks (e.g. web services)
# version: 0.2
# state: beta
# config: -
# depends: fossil (=2.17)
# access: admin
#
# The `hooks` entry is a JSON list. WARNING: might be subject
# to change. So should not be used without verifying compat.
#
#-- init
include("./fossil_common.php"); # db() etc.
if (!is_admin()) {
die("Admin-only");
}
error_reporting(E_ALL);
#-- fossil HTML output
function page_md($text) {
header("Content-Type: text/html; charset=utf-8");
print <<<EOF
<div class='fossil-doc' data-title='Hooks setup'>
<style>
.config-list label {
display: block;
margin-bottom: 10pt;
border-left: 3pt #ddd solid;
border-radius: 5pt 0 0 5pt;
padding-left: 10pt;
}
.save-button {
padding: 2pt 30pt;
}
</style>
$text
EOF;
}
#-- saving
function save($hooks) {
$hooks = array_values(
array_filter(
(array)$hooks,
function($row) {
return !empty($row["cmd"]);
}
)
);
db(
"REPLACE INTO config (name,mtime,value) VALUES (?,?,?)",
["hooks", time(), json_encode($hooks)]
);
}
if (!empty($_POST["hooks"])) {
save($_POST["hooks"]);
}
#-- print hook row
function hook_row($i, $row, $rows=1, $id="", $h="h") {
print <<<END
<tr>
<td>$i</td>
<td><input list=hooktypes name="hooks[$i][type]" value="{$h($row["type"])}" size=13></td>
<td><textarea name="hooks[$i][cmd]" $id cols=75 rows=$rows>{$h($row["cmd"])}</textarea></td>
<td><input name="hooks[$i][seq]" value="{$h($row["seq"])}" size=3></td>
</tr>
END;
}
#-- get `hooks` from config table
$hooks = json_decode(get_config("hooks", "[]"), TRUE);
#-- build form table
page_md("
<div class=config-list>
<form method=POST enctype='multipart/form-data'>
<datalist id=hooktypes>
<option value=after-receive title='after every commit or push/pull'>
<option value=before-commit>
<option value=commit-msg>
<option value=disabled>
</datalist>
<table>
<tr> <th>#</th> <th>type</th> <th>command</th> <th>seq</th> </tr>
");
# fields
foreach ($hooks as $i=>$row) {
hook_row($i, $row);
}
hook_row(count($hooks), ["type"=>"after-receive", "cmd"=>"", "seq"=>50], 3, "id=hook_cmd");
?>
<tr><td colspan=4 align=center><input type=submit value="Add / Save" class=save-button></td></tr>
</table>
</form>
<h3>Web hooks</h3>
<p>
Add one of the standard webhook services:
</p>
<p>
<select id=web_set onchange="document.getElementById('hook_cmd').innerText=this.value">
<option value=''>
<option value="FOSSIL_REPOSITORY='%R' fossil-webhook https://service.rest/">fossil-webhook
<option value="FOSSIL_REPOSITORY='%R' fossil-webhook --git https://service1.rest/">fossil-webhook --git
<option value="FOSSIL_REPOSITORY='%R' fossil-webhook --if:check-in https://service.rest/ https://service2.rest/ '+extra=parameter2' '+Token:Bearer 123'">fossil-webhook --if:check-in +Header
<option value='curl -X POST -d "branches=trunk" -d "token=1234" https://readthedocs.org/api/v2/webhook/example-project/1/'>ReadTheDocs
<option value='wget https://127.0.0.1/jenkins/github-webook'>Jenkins
<option value='wget https://localhost:8080/ext/fx_meta'>fossil/ext/fx_meta
</select>
</p>
<h3>Docs</h3>
<ul>
<li> See <a href="https://fossil-scm.org/home/doc/trunk/www/hooks.md">hooks.md</a> on how commands are run.
<li> Emulate https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads …
<li> Probably needs a cmdline helper <code>fossil-webhook</code>
</ul>
</div>