zio
/
webhookd-scripts
Archived
2
0
Fork 0
This repository has been archived on 2023-08-22. You can view files and clone it, but cannot push or open issues/pull-requests.
webhookd-scripts/v1.sh

211 lines
5.1 KiB
Bash
Executable File

#!/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)] $@"
}
function write_separator() {
char=$1
echo "$(printf "%0.s$char" {1..80})"
}
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
script_path="$script_path/default.sh"
else
script_path=""
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..."
write_separator "="
$script_path
write_separator "="
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
if [[ $event == "ping" ]]; then
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'."
else
die "No handler for $event on $service:$repo"
fi
fi