diff --git a/plugins/git/git-from-directory b/plugins/git/git-from-directory index b204c3526..3958f4566 100755 --- a/plugins/git/git-from-directory +++ b/plugins/git/git-from-directory @@ -18,9 +18,14 @@ trigger-git-git-from-directory() { # shellcheck disable=SC2086 trap "rm -rf '$TMP_WORK_DIR' '$TMP_WORK_DIR_2' >/dev/null" RETURN INT TERM EXIT - dokku_log_info1 "Updating git repository with specified build context" + local has_code=true local git_objects="$(fn-git-cmd "$APP_ROOT" count-objects 2>/dev/null || true)" if [[ -z "$git_objects" ]] || [[ "$git_objects" == "0 objects, 0 kilobytes" ]]; then + local has_code=false + fi + + dokku_log_info1 "Updating git repository with specified build context" + if [[ "$has_code" == "false" ]]; then # setup new repo cp -rT "$SOURCECODE_WORK_DIR" "$TMP_WORK_DIR" suppress_output fn-git-cmd "$TMP_WORK_DIR" init @@ -44,7 +49,7 @@ trigger-git-git-from-directory() { if suppress_output fn-git-cmd "$TMP_WORK_DIR" diff-index --quiet HEAD --; then dokku_log_warn "No changes detected, skipping git commit" dokku_log_warn "Call 'ps:rebuild' on app to rebuild the app from existing source" - return + return 1 fi suppress_output fn-git-cmd "$TMP_WORK_DIR" commit -m "Automated commit @ $(date +%s)" @@ -54,7 +59,18 @@ trigger-git-git-from-directory() { fi rm -rf "$TMP_WORK_DIR" "$TMP_WORK_DIR_2" >/dev/null - git_receive_app "$APP" "$REV" + if git_receive_app "$APP" "$REV"; then + return + else + local exit_code=$? + local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + if [[ "$has_code" == "false" ]]; then + fn-git-cmd "$APP_ROOT" update-ref -d HEAD + else + fn-git-cmd "$APP_ROOT" update-ref "refs/heads/$DOKKU_DEPLOY_BRANCH" "$DOKKU_DEPLOY_BRANCH^" + fi + return "$exit_code" + fi } trigger-git-git-from-directory "$@" diff --git a/tests/apps/python/alt.Dockerfile b/tests/apps/python/alt.Dockerfile index 289b02f6a..0c600e36b 100644 --- a/tests/apps/python/alt.Dockerfile +++ b/tests/apps/python/alt.Dockerfile @@ -1,5 +1,9 @@ FROM python:3.11.0-buster +ARG BUILD_ARG=key + WORKDIR /app COPY . /app + +RUN echo $BUILD_ARG > BUILD_ARG.contents diff --git a/tests/apps/python/web.py b/tests/apps/python/web.py index c7c3d36a3..e14bb903c 100644 --- a/tests/apps/python/web.py +++ b/tests/apps/python/web.py @@ -1,6 +1,7 @@ import http.server import json import os +import sys class GetHandler(http.server.BaseHTTPRequestHandler): @@ -17,6 +18,10 @@ class GetHandler(http.server.BaseHTTPRequestHandler): if __name__ == "__main__": + if os.getenv("FAIL_ON_STARTUP") == "true": + print("Failing on startup due to FAIL_ON_STARTUP=true") + sys.exit(1) + port = int(os.getenv("PORT", 5000)) server = http.server.HTTPServer(("0.0.0.0", port), GetHandler) print("Listening on port {0}".format(port)) diff --git a/tests/unit/git_4.bats b/tests/unit/git_4.bats index 6d26de148..8f78a701f 100644 --- a/tests/unit/git_4.bats +++ b/tests/unit/git_4.bats @@ -58,6 +58,80 @@ teardown() { assert_success } +@test "(git) git:from-image [failing deploy]" { + local CUSTOM_TMP=$(mktemp -d "/tmp/dokku.me.XXXXX") + trap 'popd &>/dev/null || true; rm -rf "$CUSTOM_TMP"' INT TERM + rmdir "$CUSTOM_TMP" && cp -r "${BATS_TEST_DIRNAME}/../../tests/apps/python" "$CUSTOM_TMP" + + run /bin/bash -c "docker image build -t dokku-test/$TEST_APP:latest -f $CUSTOM_TMP/alt.Dockerfile $CUSTOM_TMP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "docker image build -t dokku-test/$TEST_APP:v2 --build-arg BUILD_ARG=value -f $CUSTOM_TMP/alt.Dockerfile $CUSTOM_TMP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku config:set --no-restart $TEST_APP FAIL_ON_STARTUP=true" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku git:from-image $TEST_APP dokku-test/$TEST_APP:latest" + echo "output: $output" + echo "status: $status" + assert_failure + + run /bin/bash -c "dokku config:get $TEST_APP FAIL_ON_STARTUP" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "true" + + run /bin/bash -c "dokku git:status $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_failure + assert_output "fatal: this operation must be run in a work tree" + + run /bin/bash -c "dokku config:set --no-restart $TEST_APP FAIL_ON_STARTUP=false" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku git:from-image $TEST_APP dokku-test/$TEST_APP:latest" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku config:set --no-restart $TEST_APP FAIL_ON_STARTUP=true" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku git:from-image $TEST_APP dokku-test/$TEST_APP:v2" + echo "output: $output" + echo "status: $status" + assert_failure + + run /bin/bash -c "dokku config:set --no-restart $TEST_APP FAIL_ON_STARTUP=false" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku git:from-image $TEST_APP dokku-test/$TEST_APP:v2" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "No changes detected, skipping git commit" 0 + + run /bin/bash -c "docker image rm dokku-test/$TEST_APP:latest dokku-test/$TEST_APP:v2" + echo "output: $output" + echo "status: $status" + assert_success +} + @test "(git) git:from-image [onbuild]" { local TMP=$(mktemp -d "/tmp/dokku.me.XXXXX") trap 'popd &>/dev/null || true; rm -rf "$TMP"' INT TERM