mirror of
https://github.com/dokku/dokku.git
synced 2025-12-29 00:25:08 +01:00
The previous method sometimes truncated the sha, depending on how the app was deployed. Using the long sha will ensure that the value is stable, regardless of the deployment method. Closes #6770
579 lines
18 KiB
Bash
Executable File
579 lines
18 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
|
set -eo pipefail
|
|
[[ $DOKKU_TRACE ]] && set -x
|
|
|
|
cmd-git-allow-host() {
|
|
declare desc="adds a host to known_hosts"
|
|
local cmd="git:allow-host"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
declare HOST="$1"
|
|
[[ -z "$HOST" ]] && dokku_log_fail "Please supply a git host"
|
|
|
|
ssh-keyscan -t rsa "$HOST" >>"$DOKKU_ROOT/.ssh/known_hosts"
|
|
dokku_log_info1 "$HOST added to known hosts"
|
|
}
|
|
|
|
cmd-git-from-archive() {
|
|
declare desc="updates an app's git repository with a given archive file"
|
|
local cmd="git:from-archive"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
declare APP ARCHIVE_URL USER_NAME USER_EMAIL
|
|
local ARCHIVE_TYPE="tar"
|
|
|
|
ARGS=()
|
|
skip=false
|
|
for arg in "$@"; do
|
|
if [[ "$arg" == "--archive-type" ]]; then
|
|
skip=true
|
|
continue
|
|
fi
|
|
|
|
if [[ "$skip" == "true" ]]; then
|
|
ARCHIVE_TYPE="$arg"
|
|
skip=false
|
|
continue
|
|
fi
|
|
|
|
ARGS+=("$arg")
|
|
done
|
|
|
|
APP="${ARGS[0]}"
|
|
ARCHIVE_URL="${ARGS[1]}"
|
|
USER_NAME="${ARGS[2]}"
|
|
USER_EMAIL="${ARGS[3]}"
|
|
|
|
verify_app_name "$APP"
|
|
[[ -z "$ARCHIVE_URL" ]] && dokku_log_fail "Please specify an archive url or -- to fetch the archive from stdin"
|
|
|
|
local VALID_ARCHIVE_TYPES=("tar" "tar.gz" "zip")
|
|
if ! fn-in-array "$ARCHIVE_TYPE" "${ARCHIVE_TYPE[@]}"; then
|
|
dokku_log_fail "Invalid archive type specified, valid archive types include: tar, tar.gz, zip"
|
|
fi
|
|
|
|
plugn trigger git-from-archive "$APP" "$ARCHIVE_URL" "$ARCHIVE_TYPE" "$USER_NAME" "$USER_EMAIL"
|
|
plugn trigger deploy-source-set "$APP" "$ARCHIVE_TYPE" "$ARCHIVE_URL"
|
|
}
|
|
|
|
cmd-git-generate-deploy-key() {
|
|
declare desc="generates a deploy ssh key"
|
|
local cmd="git:generate-deploy-key"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
|
|
if [[ -f "$DOKKU_ROOT/.ssh/id_ed25519.pub" ]] || [[ -f "$DOKKU_ROOT/.ssh/id_rsa.pub" ]]; then
|
|
dokku_log_exclaim_quiet "A deploy key already exists for this host"
|
|
return
|
|
fi
|
|
|
|
ssh-keygen -t ed25519 -C "dokku@$(hostname)" -N "" -f "$DOKKU_ROOT/.ssh/id_ed25519"
|
|
}
|
|
|
|
cmd-git-auth() {
|
|
declare desc="configures netrc authentication for a given git server"
|
|
local cmd="git:auth"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
declare HOST="$1" USERNAME="$2" PASSWORD="$3"
|
|
[[ -z "$HOST" ]] && dokku_log_fail "Please supply a git host"
|
|
|
|
if [[ -n "$USERNAME" ]] && [[ -z "$PASSWORD" ]]; then
|
|
dokku_log_fail "Missing password for netrc auth entry"
|
|
fi
|
|
|
|
if [[ -z "$USERNAME" ]]; then
|
|
dokku_log_info1 "Removing netrc auth entry for host $HOST"
|
|
netrc unset "$HOST"
|
|
return $?
|
|
fi
|
|
|
|
dokku_log_info1 "Setting netrc auth entry for host $HOST"
|
|
touch "${DOKKU_ROOT}/.netrc"
|
|
netrc set "$HOST" "$USERNAME" "$PASSWORD"
|
|
}
|
|
|
|
cmd-git-load-image() {
|
|
declare desc="updates an app's git repository with a docker image loaded from stdin"
|
|
local cmd="git:load-image"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
declare APP DOCKER_IMAGE USER_NAME USER_EMAIL
|
|
local BUILD_DIR
|
|
|
|
ARGS=()
|
|
skip=false
|
|
for arg in "$@"; do
|
|
if [[ "$arg" == "--build-dir" ]]; then
|
|
skip=true
|
|
continue
|
|
fi
|
|
|
|
if [[ "$skip" == "true" ]]; then
|
|
BUILD_DIR="$arg"
|
|
skip=false
|
|
continue
|
|
fi
|
|
|
|
ARGS+=("$arg")
|
|
done
|
|
|
|
APP="${ARGS[0]}"
|
|
DOCKER_IMAGE="${ARGS[1]}"
|
|
USER_NAME="${ARGS[2]}"
|
|
USER_EMAIL="${ARGS[3]}"
|
|
|
|
verify_app_name "$APP"
|
|
[[ -z "$DOCKER_IMAGE" ]] && dokku_log_fail "Please specify a docker image"
|
|
[[ ! -t 0 ]] || dokku_log_fail "Expecting tar archive containing docker image on STDIN"
|
|
|
|
cat | docker load
|
|
|
|
if ! verify_image "$DOCKER_IMAGE"; then
|
|
dokku_log_fail "Loaded image tarball but the specified docker image was not found: $DOCKER_IMAGE"
|
|
fi
|
|
|
|
if ! plugn trigger git-from-image "$APP" "$DOCKER_IMAGE" "$BUILD_DIR" "$USER_NAME" "$USER_EMAIL"; then
|
|
return 1
|
|
fi
|
|
plugn trigger deploy-source-set "$APP" "docker-image" "$DOCKER_IMAGE"
|
|
}
|
|
|
|
cmd-git-from-image() {
|
|
declare desc="updates an app's git repository with a given docker image"
|
|
local cmd="git:from-image"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
declare APP DOCKER_IMAGE USER_NAME USER_EMAIL
|
|
local BUILD_DIR
|
|
|
|
ARGS=()
|
|
skip=false
|
|
for arg in "$@"; do
|
|
if [[ "$arg" == "--build-dir" ]]; then
|
|
skip=true
|
|
continue
|
|
fi
|
|
|
|
if [[ "$skip" == "true" ]]; then
|
|
BUILD_DIR="$arg"
|
|
skip=false
|
|
continue
|
|
fi
|
|
|
|
ARGS+=("$arg")
|
|
done
|
|
|
|
APP="${ARGS[0]}"
|
|
DOCKER_IMAGE="${ARGS[1]}"
|
|
USER_NAME="${ARGS[2]}"
|
|
USER_EMAIL="${ARGS[3]}"
|
|
|
|
verify_app_name "$APP"
|
|
[[ -z "$DOCKER_IMAGE" ]] && dokku_log_fail "Please specify a docker image"
|
|
|
|
if ! plugn trigger git-from-image "$APP" "$DOCKER_IMAGE" "$BUILD_DIR" "$USER_NAME" "$USER_EMAIL"; then
|
|
return 1
|
|
fi
|
|
plugn trigger deploy-source-set "$APP" "docker-image" "$DOCKER_IMAGE"
|
|
}
|
|
|
|
cmd-git-sync() {
|
|
declare desc="clone or fetch an app from remote git repo"
|
|
local cmd="git:sync"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
declare APP GIT_REMOTE GIT_REF FLAG
|
|
local CURRENT_REF DOKKU_DEPLOY_BRANCH SHOULD_BUILD UPDATED_REF
|
|
|
|
ARGS=()
|
|
for arg in "$@"; do
|
|
if [[ "$arg" == "--build" ]]; then
|
|
FLAG="--build"
|
|
continue
|
|
fi
|
|
|
|
if [[ "$arg" == "--build-if-changes" ]]; then
|
|
FLAG="--build-if-changes"
|
|
continue
|
|
fi
|
|
|
|
ARGS+=("$arg")
|
|
done
|
|
|
|
APP="${ARGS[0]}"
|
|
GIT_REMOTE="${ARGS[1]}"
|
|
GIT_REF="${ARGS[2]}"
|
|
|
|
verify_app_name "$APP"
|
|
|
|
if [[ -z "$GIT_REMOTE" ]]; then
|
|
dokku_log_fail "Missing GIT_REMOTE parameter"
|
|
return
|
|
fi
|
|
|
|
local APP_ROOT="$DOKKU_ROOT/$APP"
|
|
DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
|
|
CURRENT_REF="$(fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" 2>/dev/null || true)"
|
|
|
|
if ! fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" >/dev/null 2>&1; then
|
|
dokku_log_info1_quiet "Cloning $APP from $GIT_REMOTE#$GIT_REF"
|
|
fn-git-clone "$APP" "$GIT_REMOTE" "$GIT_REF"
|
|
else
|
|
dokku_log_verbose "Fetching remote code for $APP from $GIT_REMOTE#$GIT_REF"
|
|
fn-git-fetch "$APP" "$GIT_REMOTE" "$GIT_REF"
|
|
fi
|
|
|
|
UPDATED_REF="$(fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" 2>/dev/null || true)"
|
|
local SHOULD_BUILD=false
|
|
if [[ "$FLAG" == "--build" ]]; then
|
|
SHOULD_BUILD=true
|
|
elif [[ "$FLAG" == "--build-if-changes" ]]; then
|
|
if [[ "$CURRENT_REF" == "$UPDATED_REF" ]]; then
|
|
dokku_log_verbose "Skipping build as no changes were detected"
|
|
return
|
|
fi
|
|
|
|
SHOULD_BUILD=true
|
|
fi
|
|
|
|
if [[ "$SHOULD_BUILD" == "true" ]]; then
|
|
if [[ -n "$GIT_REF" ]]; then
|
|
GIT_REF="$(fn-git-cmd "$APP_ROOT" rev-parse "$GIT_REF")"
|
|
plugn trigger receive-app "$APP" "$GIT_REF"
|
|
else
|
|
plugn trigger receive-app "$APP"
|
|
fi
|
|
plugn trigger deploy-source-set "$APP" "git-sync" "${GIT_REMOTE}#${GIT_REF}"
|
|
fi
|
|
}
|
|
|
|
cmd-git-public-key() {
|
|
declare desc="outputs the dokku public deploy key"
|
|
local cmd="git:public-key"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
|
|
if [[ -f "$DOKKU_ROOT/.ssh/id_ed25519.pub" ]]; then
|
|
cat "$DOKKU_ROOT/.ssh/id_ed25519.pub"
|
|
return
|
|
elif [[ -f "$DOKKU_ROOT/.ssh/id_rsa.pub" ]]; then
|
|
cat "$DOKKU_ROOT/.ssh/id_rsa.pub"
|
|
return
|
|
fi
|
|
|
|
fn-git-auth-error
|
|
}
|
|
|
|
cmd-git-report() {
|
|
declare desc="displays a git report for one or more apps"
|
|
declare cmd="git:report"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
declare APP="$1" INFO_FLAG="$2"
|
|
|
|
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
|
|
INFO_FLAG="$APP"
|
|
APP=""
|
|
fi
|
|
|
|
if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then
|
|
INFO_FLAG="true"
|
|
fi
|
|
|
|
if [[ -z "$APP" ]]; then
|
|
for app in $(dokku_apps); do
|
|
cmd-git-report-single "$app" "$INFO_FLAG" | tee || true
|
|
done
|
|
else
|
|
cmd-git-report-single "$APP" "$INFO_FLAG"
|
|
fi
|
|
}
|
|
|
|
cmd-git-report-single() {
|
|
declare APP="$1" INFO_FLAG="$2"
|
|
local APP_ROOT="$DOKKU_ROOT/$APP"
|
|
if [[ "$INFO_FLAG" == "true" ]]; then
|
|
INFO_FLAG=""
|
|
fi
|
|
verify_app_name "$APP"
|
|
local flag_map=(
|
|
"--git-deploy-branch: $(fn-plugin-property-get "git" "$APP" "deploy-branch" "master")"
|
|
"--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "master")"
|
|
"--git-keep-git-dir: $(fn-plugin-property-get "git" "$APP" "keep-git-dir" "false")"
|
|
"--git-rev-env-var: $(fn-plugin-property-get "git" "$APP" "rev-env-var" "GIT_REV")"
|
|
"--git-sha: $(fn-git-cmd "$APP_ROOT" rev-parse HEAD 2>/dev/null || false)"
|
|
"--git-source-image: $(fn-git-source-image "$APP")"
|
|
"--git-last-updated-at: $(fn-git-last-updated-at "$APP")"
|
|
)
|
|
|
|
if [[ -z "$INFO_FLAG" ]]; then
|
|
dokku_log_info2_quiet "${APP} git information"
|
|
for flag in "${flag_map[@]}"; do
|
|
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
|
|
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"
|
|
done
|
|
else
|
|
local match=false
|
|
local value_exists=false
|
|
for flag in "${flag_map[@]}"; do
|
|
valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)"
|
|
if [[ "$flag" == "${INFO_FLAG}:"* ]]; then
|
|
value=${flag#*: }
|
|
size="${#value}"
|
|
if [[ "$size" -ne 0 ]]; then
|
|
echo "$value" && match=true && value_exists=true
|
|
else
|
|
match=true
|
|
fi
|
|
fi
|
|
done
|
|
[[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}"
|
|
[[ "$value_exists" == "true" ]] || dokku_log_fail "not deployed"
|
|
fi
|
|
}
|
|
|
|
cmd-git-status() {
|
|
declare desc="check the git status output for an app"
|
|
local cmd="git:status"
|
|
[[ "$1" == "$cmd" ]] && shift 1
|
|
declare APP="$1"
|
|
local APP_ROOT="$DOKKU_ROOT/$APP"
|
|
|
|
verify_app_name "$APP"
|
|
fn-git-cmd "$APP_ROOT" status
|
|
}
|
|
|
|
fn-git-auth-error() {
|
|
dokku_log_warn "There is no deploy key associated with the $DOKKU_SYSTEM_USER user."
|
|
dokku_log_warn "Generate an ssh key with the following command:"
|
|
dokku_log_warn " dokku git:generate-deploy-key"
|
|
dokku_log_fail "As an alternative, configure the netrc authentication via the git:auth command"
|
|
}
|
|
|
|
fn-git-remove-clone-folder() {
|
|
declare APP_CLONE_ROOT="$1"
|
|
dokku_log_info1 "About to delete $APP_CLONE_ROOT"
|
|
rm -rf "$APP_CLONE_ROOT"
|
|
dokku_log_info1 "Successfully deleted $APP_CLONE_ROOT"
|
|
}
|
|
|
|
fn-git-create-hook() {
|
|
declare APP="$1"
|
|
local APP_PATH="$DOKKU_ROOT/$APP"
|
|
local PRERECEIVE_HOOK="$APP_PATH/hooks/pre-receive"
|
|
|
|
if [[ ! -d "$APP_PATH/refs" ]]; then
|
|
suppress_output git init -q --bare "$APP_PATH"
|
|
fi
|
|
|
|
cat >"$PRERECEIVE_HOOK" <<EOF
|
|
#!/usr/bin/env bash
|
|
set -e
|
|
set -o pipefail
|
|
|
|
cat | DOKKU_ROOT="$DOKKU_ROOT" dokku git-hook $APP
|
|
EOF
|
|
chmod +x "$PRERECEIVE_HOOK"
|
|
}
|
|
|
|
fn-git-clone() {
|
|
declare desc="creates an app from remote git repo"
|
|
declare APP="$1" GIT_REMOTE="$2" GIT_REF="$3"
|
|
local APP_ROOT="$DOKKU_ROOT/$APP"
|
|
[[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on"
|
|
|
|
local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
|
|
if fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" >/dev/null 2>&1; then
|
|
dokku_log_fail "The clone subcommand can only be executed for new applications"
|
|
fi
|
|
|
|
if [[ -z "$GIT_REF" ]]; then
|
|
GIT_REF="$(fn-git-deploy-branch "$APP")"
|
|
fi
|
|
|
|
local TMP_IS_REF_DIR=$(mktemp -d "/tmp/dokku-ref-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
|
|
trap "rm -rf '$TMP_IS_REF_DIR' >/dev/null" RETURN INT TERM EXIT
|
|
|
|
is_ref=true
|
|
if GIT_TERMINAL_PROMPT=0 git clone --depth 1 -n --branch "$GIT_REF" "$GIT_REMOTE" "$TMP_IS_REF_DIR" 2>/dev/null; then
|
|
is_ref=false
|
|
fi
|
|
rm -rf "$TMP_IS_REF_DIR"
|
|
|
|
local TMP_CLONE_DIR=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
|
|
trap "rm -rf '$TMP_CLONE_DIR' >/dev/null" RETURN INT TERM EXIT
|
|
|
|
if [[ "$is_ref" == "true" ]]; then
|
|
GIT_TERMINAL_PROMPT=0 suppress_output git clone -n "$GIT_REMOTE" "$TMP_CLONE_DIR"
|
|
fn-git-cmd "$TMP_CLONE_DIR" checkout -qq "$GIT_REF"
|
|
else
|
|
GIT_TERMINAL_PROMPT=0 suppress_output git clone -n --branch "$GIT_REF" "$GIT_REMOTE" "$TMP_CLONE_DIR"
|
|
if fn-git-cmd "$TMP_CLONE_DIR" show-ref --verify "refs/heads/$GIT_REF" &>/dev/null; then
|
|
dokku_log_verbose "Detected branch, setting deploy-branch to $GIT_REF"
|
|
fn-plugin-property-write "git" "$APP" "deploy-branch" "$GIT_REF"
|
|
fi
|
|
fi
|
|
|
|
DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
|
|
if [[ "$GIT_REF" != "$DOKKU_DEPLOY_BRANCH" ]]; then
|
|
if [[ "$is_ref" == "true" ]]; then
|
|
fn-git-cmd "$TMP_CLONE_DIR" branch -qq -D "$DOKKU_DEPLOY_BRANCH" 2>/dev/null || true
|
|
fi
|
|
|
|
fn-git-cmd "$TMP_CLONE_DIR" checkout -qq -b "$DOKKU_DEPLOY_BRANCH"
|
|
fi
|
|
|
|
rsync -a "$TMP_CLONE_DIR/.git/" "$APP_ROOT"
|
|
fn-git-create-hook "$APP"
|
|
fn-git-cmd "$APP_ROOT" config --add core.bare true
|
|
}
|
|
|
|
fn-git-cmd() {
|
|
declare GIT_DIR="$1"
|
|
local exit_code="1"
|
|
shift 1
|
|
|
|
pushd "$GIT_DIR" >/dev/null
|
|
git "$@"
|
|
exit_code="$?"
|
|
popd &>/dev/null || pushd "/tmp" >/dev/null
|
|
return $exit_code
|
|
}
|
|
|
|
fn-git-fetch() {
|
|
declare APP="$1" GIT_REMOTE="$2" GIT_REF="$3"
|
|
local DOKKU_DEPLOY_BRANCH
|
|
local APP_ROOT="$DOKKU_ROOT/$APP"
|
|
|
|
local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
|
|
if ! fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" >/dev/null 2>&1; then
|
|
dokku_log_fail "The fetch subcommand can only be executed for existing applications"
|
|
fi
|
|
|
|
DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
|
|
if ! fn-git-cmd "$APP_ROOT" check-ref-format --branch "$DOKKU_DEPLOY_BRANCH" &>/dev/null; then
|
|
dokku_log_warn "Invalid branch name '$DOKKU_DEPLOY_BRANCH' specified via deploy-branch setting."
|
|
dokku_log_warn "For more details, please see the man page for 'git-check-ref-format.'"
|
|
return
|
|
fi
|
|
|
|
fn-git-cmd "$APP_ROOT" remote rm remote &>/dev/null || true
|
|
fn-git-cmd "$APP_ROOT" remote add --mirror=fetch --no-tags remote "$GIT_REMOTE"
|
|
if [[ -z "$GIT_REF" ]]; then
|
|
GIT_TERMINAL_PROMPT=0 fn-git-cmd "$APP_ROOT" fetch --update-head-ok remote "$DOKKU_DEPLOY_BRANCH"
|
|
else
|
|
GIT_TERMINAL_PROMPT=0 fn-git-cmd "$APP_ROOT" fetch --update-head-ok remote
|
|
fn-git-cmd "$APP_ROOT" update-ref "refs/heads/$DOKKU_DEPLOY_BRANCH" "$GIT_REF^{commit}"
|
|
fi
|
|
|
|
fn-git-cmd "$APP_ROOT" config --add core.bare true
|
|
}
|
|
|
|
fn-git-has-code() {
|
|
declare desc="checks if there is code at a specific branch"
|
|
declare APP="$1" DOKKU_DEPLOY_BRANCH="$2"
|
|
|
|
if [[ -z "$DOKKU_DEPLOY_BRANCH" ]]; then
|
|
DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
|
|
fi
|
|
|
|
local HEAD_FILE="$DOKKU_ROOT/$APP/refs/heads/$DOKKU_DEPLOY_BRANCH"
|
|
if [[ -f "$HEAD_FILE" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
fn-git-last-updated-at() {
|
|
declare desc="retrieve the deploy branch for a given application"
|
|
declare APP="$1"
|
|
local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
|
|
local HEAD_FILE="$DOKKU_ROOT/$APP/refs/heads/$DOKKU_DEPLOY_BRANCH"
|
|
|
|
if [[ -f "$HEAD_FILE" ]]; then
|
|
stat -c %Y "$HEAD_FILE"
|
|
fi
|
|
}
|
|
|
|
fn-git-deploy-branch() {
|
|
declare desc="retrieve the deploy branch for a given application"
|
|
local APP="$1"
|
|
local DEFAULT_BRANCH="${2-master}"
|
|
|
|
local DOKKU_DEPLOY_BRANCH="$(fn-plugin-property-get "git" "$APP" "deploy-branch" "")"
|
|
local DOKKU_GLOBAL_DEPLOY_BRANCH="$(fn-plugin-property-get "git" "--global" "deploy-branch" "")"
|
|
if [[ -n "$DOKKU_DEPLOY_BRANCH" ]]; then
|
|
echo "$DOKKU_DEPLOY_BRANCH"
|
|
elif [[ -n "$DOKKU_GLOBAL_DEPLOY_BRANCH" ]]; then
|
|
echo "$DOKKU_GLOBAL_DEPLOY_BRANCH"
|
|
else
|
|
echo "$DEFAULT_BRANCH"
|
|
fi
|
|
}
|
|
|
|
fn-git-setup-build-dir() {
|
|
declare APP="$1" GIT_WORKDIR="$2" REV="$3"
|
|
local DOKKU_KEEP_GIT_DIR="$(fn-plugin-property-get "git" "$APP" "keep-git-dir" "")"
|
|
|
|
if [[ "$DOKKU_KEEP_GIT_DIR" == "true" ]]; then
|
|
fn-git-setup-build-dir-new "$APP" "$GIT_WORKDIR" "$REV"
|
|
else
|
|
fn-git-setup-build-dir-worktree "$APP" "$GIT_WORKDIR" "$REV"
|
|
fi
|
|
}
|
|
|
|
fn-git-setup-build-dir-new() {
|
|
declare APP="$1" GIT_WORKDIR="$2" REV="$3"
|
|
local APP_ROOT="$DOKKU_ROOT/$APP"
|
|
local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
|
|
|
|
# unset the git quarantine path to allow us to use 2.13.0+
|
|
# See this issue for more information: https://github.com/dokku/dokku/issues/2796
|
|
unset GIT_QUARANTINE_PATH
|
|
|
|
# repo workaround from https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52249
|
|
# and https://docs.gitlab.com/ee/user/project/repository/repository_mirroring.html#preventing-conflicts-using-a-pre-receive-hook
|
|
fn-git-cmd "$APP_ROOT" archive "$REV" | tar x --warning=none -C "${GIT_WORKDIR}"
|
|
suppress_output fn-git-cmd "$GIT_WORKDIR" clone --bare "$DOKKU_ROOT/$APP" .git
|
|
suppress_output fn-git-cmd "$GIT_WORKDIR" config --local gc.auto 0
|
|
suppress_output fn-git-cmd "$GIT_WORKDIR" config --local --bool core.bare false
|
|
suppress_output fn-git-cmd "$GIT_WORKDIR" config --local receive.denyCurrentBranch ignore
|
|
suppress_output fn-git-cmd "$GIT_WORKDIR" symbolic-ref HEAD "refs/heads/$DOKKU_DEPLOY_BRANCH"
|
|
suppress_output fn-git-cmd "$GIT_WORKDIR" reset "$REV" -- .
|
|
suppress_output fn-git-cmd "$GIT_WORKDIR" push $GIT_WORKDIR $REV:refs/heads/$DOKKU_DEPLOY_BRANCH
|
|
|
|
fn-git-setup-build-dir-submodules "$APP" "$GIT_WORKDIR"
|
|
}
|
|
|
|
fn-git-setup-build-dir-worktree() {
|
|
declare APP="$1" GIT_WORKDIR="$2" REV="$3"
|
|
local APP_ROOT="$DOKKU_ROOT/$APP"
|
|
|
|
# unset the git quarantine path to allow us to use 2.13.0+
|
|
# See this issue for more information: https://github.com/dokku/dokku/issues/2796
|
|
unset GIT_QUARANTINE_PATH
|
|
|
|
suppress_output fn-git-cmd "$APP_ROOT" worktree add "$GIT_WORKDIR" "$REV"
|
|
fn-git-setup-build-dir-submodules "$APP" "$GIT_WORKDIR"
|
|
suppress_output fn-git-cmd "$APP_ROOT" worktree prune
|
|
}
|
|
|
|
fn-git-setup-build-dir-submodules() {
|
|
declare APP="$1" GIT_WORKDIR="$2"
|
|
local DOKKU_KEEP_GIT_DIR="$(fn-plugin-property-get "git" "$APP" "keep-git-dir" "")"
|
|
|
|
# unset the git quarantine path to allow us to use 2.13.0+
|
|
# See this issue for more information: https://github.com/dokku/dokku/issues/2796
|
|
unset GIT_QUARANTINE_PATH
|
|
suppress_output fn-git-cmd "$GIT_WORKDIR" submodule sync --recursive
|
|
suppress_output fn-git-cmd "$GIT_WORKDIR" submodule update --init --recursive
|
|
|
|
if [[ "$DOKKU_KEEP_GIT_DIR" != "true" ]]; then
|
|
pushd "$GIT_WORKDIR" >/dev/null
|
|
find "$GIT_WORKDIR" -name .git -prune -exec rm -rf {} \; >/dev/null
|
|
popd &>/dev/null || pushd "/tmp" >/dev/null
|
|
fi
|
|
}
|
|
|
|
fn-git-source-image() {
|
|
declare desc="retrieve the source-image for a given application"
|
|
declare APP="$1"
|
|
|
|
fn-plugin-property-get "git" "$APP" "source-image" ""
|
|
}
|