commit 28ee6af633c4c3f735de9a3a66ff18e416eb910f Author: Ducky Date: Wed Jan 5 10:40:19 2022 +0000 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4cf7ced --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Runtime +logs/* +wd/* + +# Temporary +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* diff --git a/repos/.gitkeep b/repos/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/v1.sh b/v1.sh new file mode 100755 index 0000000..9e96b9b --- /dev/null +++ b/v1.sh @@ -0,0 +1,197 @@ +#!/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)] $@" +} + +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" +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..." + + echo "================================================================================" + $script_path + echo "================================================================================" + + 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 + die "No handler for $event on $service:$repo" +fi