2022-01-05 11:40:19 +01:00
#!/usr/bin/env bash
# TODO: Check installed: git, jq
function detech( ) {
command = ${ @ : 2 }
log = $1
" $command " & >$log & disown
}
function die( ) {
write_log " Oops: $@ " 1>& 2 ; exit 1;
}
function get_log_timestamps( ) {
$event = $1
$log_file = $2
grep -oP " ^(\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\] $event at \K([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})) $" $log_file
}
function get_os( ) {
function get_os_line( ) {
file = ""
property = $1
if [ [ -f "/etc/os-release" ] ] ; then
file = "/etc/os-release"
elif [ [ -f "/usr/etc/os-release" ] ] ; then
file = "/usr/etc/os-release"
fi
if [ [ ! -z $file ] ] ; then
echo $( grep -oP " (?<=^ $property =).+ " $file | tr -d '"' )
fi
}
os_name = $( get_os_line "NAME" )
os_version = $( get_os_line "VERSION" )
os_pretty = $( get_os_line "PRETTY_NAME" )
if [ [ ! -z $os_pretty ] ] ; then
echo " $os_pretty "
elif [ [ ! -z $os_name ] ] ; then
echo " $os_name $os_version "
else
echo "Unknown OS"
fi
}
function now( ) {
echo $( date +"%Y-%m-%d %H:%M:%S" )
}
function query_json( ) {
echo " $1 " | jq $2 -r
}
function split_string( ) {
echo $1 | cut -d" $2 " -f$3
}
function write_log( ) {
echo " [ $( now) ] $@ "
}
2022-01-05 12:22:49 +01:00
function write_separator( ) {
char = $1
echo " $( printf " %0.s $char " { 1..80} ) "
}
2022-01-05 11:40:19 +01:00
payload = $1
service = $2
event = $3
id = $4
started_time = $( now)
base_dir = " $( dirname " $( realpath -s " $0 " ) " ) "
build_base_dir = " $base_dir /wd "
log_base_dir = " $base_dir /logs "
script_base_dir = " $base_dir /repos "
mkdir -p $build_base_dir
mkdir -p $log_base_dir
if [ [ -z $event ] ] ; then
if [ [ ! -z $x_github_event ] ] ; then
event = $x_github_event
else
die "Missing event"
fi
fi
if [ [ -z $service ] ] ; then
service = "github"
fi
if [ [ -z $id ] ] ; then
if [ [ ! -z $x_github_delivery ] ] ; then
id = $x_github_delivery
else
id = $( cat /proc/sys/kernel/random/uuid)
fi
fi
if [ [ ! -z " $payload " ] ] ; then
payload_type = $( echo $payload | jq type -r)
if [ [ $? != 0 ] ] ; then
die "Bad body format (expecting JSON)"
else
if [ [ ! $payload_type = "object" ] ] ; then
die " Bad body format (expecting JSON object but got $payload_type ) "
fi
fi
else
die "Missing payload"
fi
# TODO: Test Gitea
if ! { [ [ $service = = "github" ] ] || [ [ $service = = "gitea" ] ] ; } ; then
die " Service ' $service ' not supported "
fi
repo = $( query_json " $payload " ".repository.full_name" )
repo_author = $( split_string $repo "/" 1)
repo_name = $( split_string $repo "/" 2)
instance = " $( date +"%y%m%d%H%M%S" ) _ ${ repo_name } _ $id "
script_path = " $script_base_dir / $service / $repo_author / $repo_name "
build_path = " $build_base_dir / $instance "
log_path = " $log_base_dir / $instance .txt "
if [ [ -f " $script_path / $event .sh " ] ] ; then
script_path = " $script_path / $event .sh "
elif [ [ -f " $script_path /default.sh " ] ] ; then
2022-01-05 11:58:50 +01:00
script_path = " $script_path /default.sh "
else
script_path = ""
2022-01-05 11:40:19 +01:00
fi
if [ [ ! -z $script_path ] ] ; then
function invoke_script( ) {
write_log " Started at $( now) "
export _hook_event = $event
export _hook_id = $id
export _hook_payload = $payload
export _repo_clone_url = $( query_json " $payload " ".repository.clone_url" )
export _wd = $build_path
export -f query_json
export -f now
export -f split_string
export -f write_log
write_log "Creating working directory..."
mkdir -p $build_path
write_log " Setting path to ' $build_path '... "
cd $build_path
chmod +x $script_path
if { [ [ $event = = "push" ] ] ; } ; then
export _branch = $( split_string $( query_json " $payload " ".ref" ) "/" 3)
export _commit_hash = $( query_json " $payload " ".head_commit.id" )
export _commit_message = $( query_json " $payload " ".head_commit.message" )
export _commit_timestamp = $( query_json " $payload " ".head_commit.timestamp" )
write_log " Cloning repository from ' $_repo_clone_url '... "
git clone --recurse-submodules -q $_repo_clone_url $build_path
write_log " Resetting repository to ' $_commit_hash '... "
git reset --hard -q $_commit_hash
fi
write_log "Executing script..."
2022-01-05 12:22:49 +01:00
write_separator "="
2022-01-05 11:40:19 +01:00
$script_path
2022-01-05 12:22:49 +01:00
write_separator "="
2022-01-05 11:40:19 +01:00
write_log "Removing working directory..."
rm -rf $build_path
write_log " Finished at $( now) "
}
detech " $log_path " invoke_script
echo " Repo: $service : $repo "
echo " Event: $event ( $id ) "
echo " Instance: $instance "
echo " Script: $script_path "
echo " Working: $build_path "
echo " Log: $log_path "
echo " Host: $( hostname) ( $( get_os) ) "
echo " Started: $started_time "
else
2022-01-05 12:10:49 +01:00
if [ [ $event = = "ping" ] ] ; then
2022-01-05 12:22:49 +01:00
echo "Pong!"
echo ""
echo " If you're seeing this, that means you've done something right. To trigger scripts on events place them in ' $script_base_dir / $service / $repo_author / $repo_name /<event>.sh'. "
2022-01-05 12:07:25 +01:00
else
die " No handler for $event on $service : $repo "
fi
2022-01-05 11:40:19 +01:00
fi