diff --git a/docs/deployment/methods/git.md b/docs/deployment/methods/git.md index fdcfecb970c..b34897d590f 100644 --- a/docs/deployment/methods/git.md +++ b/docs/deployment/methods/git.md @@ -12,6 +12,7 @@ git:initialize # Initialize a git repository git:public-key # Outputs the dokku public deploy key git:report [] [] # Displays a git report for one or more apps git:set () # Set or clear a git property for an app +git:unlock [--force] # Removes previous git clone folder for new deployment ``` Git-based deployment has been the traditional method of deploying applications in Dokku. As of v0.12.0, Dokku introduces a few ways to customize the experience of deploying via `git push`. A Git-based deployment currently supports building applications via: diff --git a/plugins/git/help-functions b/plugins/git/help-functions index 42f64c2555b..5772397930f 100755 --- a/plugins/git/help-functions +++ b/plugins/git/help-functions @@ -36,5 +36,6 @@ fn-help-content() { git:public-key, Outputs the dokku public deploy key git:report [] [], Displays a git report for one or more apps git:set (), Set or clear a git property for an app + git:unlock [--force], Removes previous git clone folder for new deployment help_content } diff --git a/plugins/git/internal-functions b/plugins/git/internal-functions index c3b05c7ae0b..a803d7f5ed9 100755 --- a/plugins/git/internal-functions +++ b/plugins/git/internal-functions @@ -193,6 +193,18 @@ cmd-git-sync() { verify_app_name "$APP" + if [[ -d "$DOKKU_LIB_ROOT/data/git/$APP" ]]; then + if has_tty eq 0; then + cmd-git-unlock "$APP" + if [[ -d "$DOKKU_LIB_ROOT/data/git/$APP" ]]; then + dokku_log_fail "Failed to delete existing clone folder" + exit 15 + fi + else + dokku_log_fail "Run 'git:unlock' to remove the existing temporary clone" + fi + fi + if [[ -z "$GIT_REMOTE" ]]; then dokku_log_fail "Missing GIT_REMOTE parameter" return @@ -215,6 +227,40 @@ cmd-git-sync() { fi } +cmd-git-unlock() { + declare desc="removes the clone folder for an app" + local cmd="git:unlock" + [[ "$1" == "$cmd" ]] && shift 1 + declare APP="$1" FLAG + + for arg in "$@"; do + if [[ "$arg" == "--force" ]]; then + FLAG="--force" + continue + fi + + ARGS+=("$arg") + done + + local APP_CLONE_ROOT="$DOKKU_LIB_ROOT/data/git/$APP" + + if [[ -d "$APP_CLONE_ROOT" ]]; then + if [[ "$FLAG" == "--force" ]]; then + fn-git-remove-clone-folder "$APP_CLONE_ROOT" + else + read -rp "Are you sure that want to delete clone folder (y/n)?" choice + case "$choice" in + y | Y) + fn-git-remove-clone-folder "$APP_CLONE_ROOT" + ;; + n | N) echo "no" ;; + *) echo "please answer with yes or no" ;; + esac + fi + else + dokku_log_info1 "No clone folder exists app already unlocked" + fi +} cmd-git-public-key() { declare desc="outputs the dokku public deploy key" local cmd="git:public-key" @@ -301,6 +347,13 @@ fn-git-auth-error() { 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" @@ -331,10 +384,6 @@ fn-git-clone() { dokku_log_fail "The clone subcommand can only be executed for new applications" fi - if [[ -d "$APP_CLONE_ROOT" ]]; then - dokku_log_fail "Clone in progress" - fi - if [[ -z "$GIT_REF" ]]; then GIT_REF="$(fn-git-deploy-branch "$APP")" fi diff --git a/plugins/git/subcommands/unlock b/plugins/git/subcommands/unlock new file mode 100755 index 00000000000..ca256e1cce2 --- /dev/null +++ b/plugins/git/subcommands/unlock @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +source "$PLUGIN_AVAILABLE_PATH/git/internal-functions" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x + +cmd-git-unlock "$@" diff --git a/tests/unit/git_6.bats b/tests/unit/git_6.bats new file mode 100644 index 00000000000..ab706a5753d --- /dev/null +++ b/tests/unit/git_6.bats @@ -0,0 +1,30 @@ +#!/usr/bin/env bats + +load test_helper + +setup() { + global_setup + touch /home/dokku/.ssh/known_hosts + chown dokku:dokku /home/dokku/.ssh/known_hosts + mkdir -p "$DOKKU_LIB_ROOT/data/git/$TEST_APP" + chown dokku:dokku "$DOKKU_LIB_ROOT/data/git/$TEST_APP" +} + +teardown() { + rm -f /home/dokku/.ssh/id_rsa.pub || true + global_teardown +} + +@test "(git) git:unlock [success]" { + run /bin/bash -c "dokku git:unlock $TEST_APP --force" + echo "output: $output" + echo "status: $status" + assert_success +} + +@test "(git) git:unlock [missing arg]" { + run /bin/bash -c "dokku git:unlock" + echo "output: $output" + echo "status: $status" + assert_failure +}