Files
dokku/plugins/git/functions
2022-04-16 02:25:48 -04:00

199 lines
7.0 KiB
Bash
Executable File

#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
source "$PLUGIN_AVAILABLE_PATH/apps/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/git/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
use_git_worktree() {
declare desc="detects whether to use git worktree"
declare deprecated=true
dokku_log_warn "Deprecated: fn-git-use-worktree"
fn-git-use-worktree
}
git_build_app_repo() {
declare desc="builds local git app repo for app"
declare APP="$1" REV="$2"
local DOKKU_GLOBAL_DISABLE_AUTOCREATE
verify_app_name "$APP"
# clean up after ourselves
local GIT_BUILD_APP_REPO_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$GIT_BUILD_APP_REPO_TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT
chmod 755 "$GIT_BUILD_APP_REPO_TMP_WORK_DIR"
unset GIT_DIR GIT_QUARANTINE_PATH GIT_WORK_TREE
! plugn trigger app-exists "$APP" >/dev/null 2>&1 && plugn trigger app-maybe-create "$APP"
fn-git-setup-build-dir "$APP" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV"
pushd "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" >/dev/null
local DOKKU_APP_DISABLE_ANSI_PREFIX_REMOVAL DOKKU_GLOBAL_DISABLE_ANSI_PREFIX_REMOVAL DOKKU_DISABLE_ANSI_PREFIX_REMOVAL
DOKKU_APP_DISABLE_ANSI_PREFIX_REMOVAL=$(config_get "$APP" DOKKU_DISABLE_ANSI_PREFIX_REMOVAL || true)
DOKKU_GLOBAL_DISABLE_ANSI_PREFIX_REMOVAL=$(config_get --global DOKKU_DISABLE_ANSI_PREFIX_REMOVAL || true)
DOKKU_DISABLE_ANSI_PREFIX_REMOVAL=${DOKKU_APP_DISABLE_ANSI_PREFIX_REMOVAL:="$DOKKU_GLOBAL_DISABLE_ANSI_PREFIX_REMOVAL"}
if [[ "$DOKKU_DISABLE_ANSI_PREFIX_REMOVAL" == "true" ]]; then
git_trigger_build "$APP" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV"
else
git_trigger_build "$APP" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV" | sed -u "s/^/"$'\e[1G'"/"
fi
return $?
}
git_trigger_build() {
declare desc="triggers the actual build process for a given app within a directory at a particular revision"
declare APP="$1" TMP_WORK_DIR="$2" REV="$3"
local BUILDER
if ! plugn trigger core-post-extract "$APP" "$TMP_WORK_DIR" "$REV"; then
return 1
fi
plugn trigger post-extract "$APP" "$TMP_WORK_DIR" "$REV"
BUILDER="$(plugn trigger builder-detect "$APP" "$TMP_WORK_DIR" | head -n1 || true)"
[[ -z "$BUILDER" ]] && BUILDER="herokuish"
plugn trigger pre-receive-app "$APP" "$BUILDER" "$TMP_WORK_DIR" "$REV"
dokku_receive "$APP" "$BUILDER" "$TMP_WORK_DIR"
}
git_deploy_branch() {
declare desc="retrieve the deploy branch for a given application"
declare APP="$1"
declare deprecated=true
dokku_log_warn "Deprecated: plugn#git-deploy-branch"
fn-git-deploy-branch "$APP"
}
cmd-git-hook() {
declare desc="kick off receive-app trigger from git prereceive hook"
declare cmd="git-hook"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1"
local DOKKU_DEPLOY_BRANCH
plugn trigger app-exists "$APP" 2>/dev/null || is_valid_app_name "$APP"
DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
if ! git check-ref-format --branch "$DOKKU_DEPLOY_BRANCH" >/dev/null 2>&1; then
echo $'\e[1G\e[K'"-----> WARNING: Invalid branch name '$DOKKU_DEPLOY_BRANCH' specified via deploy-branch setting."
echo $'\e[1G\e[K'"-----> For more details, please see the man page for 'git-check-ref-format.'"
return
fi
local oldrev newrev refname
while read -r oldrev newrev refname; do
# Only run this script for the master branch. You can remove this
# if block if you wish to run it for others as well.
if [[ $refname == "refs/heads/${DOKKU_DEPLOY_BRANCH}" ]]; then
# broken out into plugin so we might support other methods to receive an app
git_receive_app "$APP" "$newrev"
plugn trigger deploy-source-set "$APP" "git-push" "$newrev"
else
if [[ $(find "$PLUGIN_PATH"/enabled/*/receive-branch 2>/dev/null | wc -l) != 1 ]]; then
plugn trigger receive-branch "$APP" "$newrev" "$refname"
plugn trigger deploy-source-set "$APP" "git-push" "$newrev"
elif [[ -z "$(fn-git-deploy-branch "$APP" "")" ]]; then
echo $'\e[1G\e[K'"-----> Set ${refname/refs\/heads\//} to DOKKU_DEPLOY_BRANCH."
fn-plugin-property-write "git" "$APP" "deploy-branch" "${refname/refs\/heads\//}"
git_receive_app "$APP" "$newrev"
plugn trigger deploy-source-set "$APP" "git-push" "$newrev"
else
echo $'\e[1G\e[K'"-----> WARNING: deploy did not complete, you must push to ${DOKKU_DEPLOY_BRANCH}."
echo $'\e[1G\e[K'"-----> for example, try 'git push <dokku> ${refname/refs\/heads\//}:${DOKKU_DEPLOY_BRANCH}'"
fi
fi
done
}
git_build() {
declare desc="setup and call git_build_app_repo"
local APP="$1" REV="$2"
local DOKKU_DEPLOY_BRANCH ENV_VAR_NAME REF
if [[ -n "$REV" ]]; then
ENV_VAR_NAME="$(fn-plugin-property-get "git" "$APP" "rev-env-var")"
if [[ -z "$ENV_VAR_NAME" ]] && ! fn-plugin-property-exists "git" "$APP" "rev-env-var"; then
ENV_VAR_NAME="GIT_REV"
fi
if [[ -n "$ENV_VAR_NAME" ]]; then
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" "${ENV_VAR_NAME}=${REV}"
fi
local REF="$REV"
else
DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
if [[ -f "$DOKKU_ROOT/$APP/refs/heads/$DOKKU_DEPLOY_BRANCH" ]]; then
REF=$(<"$DOKKU_ROOT/$APP/refs/heads/$DOKKU_DEPLOY_BRANCH")
else
echo $'\e[1G\e[K'"-----> WARNING: Cannot build from '$DOKKU_DEPLOY_BRANCH' as there are no commits stored at that branch."
fi
fi
if [[ -z "$REF" ]]; then
return 1
fi
git_build_app_repo "$APP" "$REF"
return $?
}
git_receive_app() {
declare desc="git receive-app plugin trigger"
declare APP="$1" REV="$2"
# Don't trigger git build if there is no git repository.
if [[ ! -d "$DOKKU_ROOT/$APP/refs" ]]; then
true
else
local exit_code=0
acquire_app_deploy_lock "$APP" "exclusive"
git_build "$APP" "$REV" || exit_code="$?"
release_app_deploy_lock "$APP"
return "$exit_code"
fi
}
cmd-git-upload-pack() {
declare desc="executes git-upload-pack"
declare cmd="git-upload-pack"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1"
APP="$(echo "$APP" | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g' | sed 's/^\///g')"
is_valid_app_name "$APP"
! plugn trigger app-exists "$APP" >/dev/null 2>&1 && plugn trigger app-maybe-create "$APP"
plugn trigger git-pre-pull "$APP"
cat | git-upload-pack "$DOKKU_ROOT/$APP"
plugn trigger git-post-pull "$APP"
}
cmd-git-glob() {
declare desc="catch-all for any other git-* commands"
declare cmd="git-*"
local APP="$(echo "$2" | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g' | sed 's/^\///g')"
local APP_PATH=$DOKKU_ROOT/$APP
plugn trigger app-exists "$APP" 2>/dev/null || is_valid_app_name "$APP"
if [[ $1 == "git-receive-pack" && ! -d "$APP_PATH/refs" ]]; then
! plugn trigger app-exists "$APP" >/dev/null 2>&1 && plugn trigger app-maybe-create "$APP"
fn-git-create-hook "$APP"
fi
if [[ $1 == "git-receive-pack" ]]; then
local args="$1 '$APP_PATH'"
else
local args=$*
fi
git-shell -c "$args"
}