diff --git a/docs/deployment/methods/git.md b/docs/deployment/methods/git.md index 1bfd498a44d..eb46b32610d 100644 --- a/docs/deployment/methods/git.md +++ b/docs/deployment/methods/git.md @@ -10,7 +10,7 @@ git:from-archive [--archive-type ARCHIVE_TYPE] [ [ ] # Updates an app's git repository with a given docker image git:generate-deploy-key # Generates a deploy ssh key git:load-image [--build-dir DIRECTORY] [ ] # Updates an app's git repository with a docker image loaded from stdin -git:sync [--build] [] # Clone or fetch an app from remote git repo +git:sync [--build|build-if-changes] [] # Clone or fetch an app from remote git repo git:initialize # Initialize a git repository for an app git:public-key # Outputs the dokku public deploy key git:report [] [] # Displays a git report for one or more apps @@ -157,6 +157,12 @@ By default, this command does not trigger an application build. To do so during dokku git:sync --build node-js-app https://github.com/heroku/node-js-getting-started.git ``` +When running `git:sync` without a reference, it may be useful to only build when there are changes. To do so, specify the `--build-if-changes` flag. + +```shell +dokku git:sync --build-if-changes node-js-app https://github.com/heroku/node-js-getting-started.git +``` + ### Initializing from private repositories > [!IMPORTANT] diff --git a/plugins/git/internal-functions b/plugins/git/internal-functions index 8ce59e82fbf..9675cb1e699 100755 --- a/plugins/git/internal-functions +++ b/plugins/git/internal-functions @@ -179,6 +179,7 @@ cmd-git-sync() { 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 @@ -187,6 +188,11 @@ cmd-git-sync() { continue fi + if [[ "$arg" == "--build-if-changes" ]]; then + FLAG="--build-if-changes" + continue + fi + ARGS+=("$arg") done @@ -202,6 +208,10 @@ cmd-git-sync() { 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" count-objects)" == "0 objects, 0 kilobytes" ]]; then dokku_log_info1_quiet "Cloning $APP from $GIT_REMOTE#$GIT_REF" fn-git-clone "$APP" "$GIT_REMOTE" "$GIT_REF" @@ -209,7 +219,20 @@ cmd-git-sync() { 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" diff --git a/tests/unit/git_3.bats b/tests/unit/git_3.bats index 1cec5559657..042431ff6f7 100644 --- a/tests/unit/git_3.bats +++ b/tests/unit/git_3.bats @@ -2,6 +2,12 @@ load test_helper +SMOKE_TEST_APP_1_0_0_SHA=9cf71bba639c4f1671dfd42685338b762d3354f2 +SMOKE_TEST_APP_2_0_0_SHA=5c8a5e42bbd7fae98bd657fb17f41c6019b303f9 +SMOKE_TEST_APP_ANOTHER_BRANCH_SHA=5c8a5e42bbd7fae98bd657fb17f41c6019b303f9 +SMOKE_TEST_APP_MASTER_SHA=af1b02052199b8ca8115f80ff8676a7c7744a45f +SMOKE_TEST_APP_COMMIT_SHA=5c8a5e42bbd7fae98bd657fb17f41c6019b303f9 + setup() { global_setup create_app @@ -121,6 +127,12 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_MASTER_SHA" } @test "(git) git:sync new [--no-build branch]" { @@ -128,6 +140,12 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/another-branch" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_ANOTHER_BRANCH_SHA" } @test "(git) git:sync new [--no-build tag]" { @@ -135,13 +153,25 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" } @test "(git) git:sync new [--no-build commit]" { - run /bin/bash -c "dokku git:sync $TEST_APP https://github.com/dokku/smoke-test-app.git 5c8a5e42bbd7fae98bd657fb17f41c6019b303f9" + run /bin/bash -c "dokku git:sync $TEST_APP https://github.com/dokku/smoke-test-app.git $SMOKE_TEST_APP_COMMIT_SHA" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" echo "output: $output" echo "status: $status" assert_success + assert_output_contains "$SMOKE_TEST_APP_COMMIT_SHA" } @test "(git) git:sync new [--build noarg]" { @@ -150,6 +180,24 @@ teardown() { echo "status: $status" assert_success assert_output_contains "Application deployed" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_MASTER_SHA" + + run /bin/bash -c "dokku git:sync --build-if-changes $TEST_APP https://github.com/dokku/smoke-test-app.git" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Skipping build as no changes were detected" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_MASTER_SHA" } @test "(git) git:sync new [--build branch]" { @@ -158,6 +206,24 @@ teardown() { echo "status: $status" assert_success assert_output_contains "Application deployed" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/another-branch" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_ANOTHER_BRANCH_SHA" + + run /bin/bash -c "dokku git:sync --build-if-changes $TEST_APP https://github.com/dokku/smoke-test-app.git another-branch" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Skipping build as no changes were detected" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/another-branch" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_ANOTHER_BRANCH_SHA" } @test "(git) git:sync new [--build tag]" { @@ -166,14 +232,50 @@ teardown() { echo "status: $status" assert_success assert_output_contains "Application deployed" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" + + run /bin/bash -c "dokku git:sync --build-if-changes $TEST_APP https://github.com/dokku/smoke-test-app.git 1.0.0" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Skipping build as no changes were detected" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" } @test "(git) git:sync new [--build commit]" { - run /bin/bash -c "dokku git:sync --build $TEST_APP https://github.com/dokku/smoke-test-app.git 5c8a5e42bbd7fae98bd657fb17f41c6019b303f9" + run /bin/bash -c "dokku git:sync --build $TEST_APP https://github.com/dokku/smoke-test-app.git $SMOKE_TEST_APP_COMMIT_SHA" echo "output: $output" echo "status: $status" assert_success assert_output_contains "Application deployed" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_COMMIT_SHA" + + run /bin/bash -c "dokku git:sync --build-if-changes $TEST_APP https://github.com/dokku/smoke-test-app.git $SMOKE_TEST_APP_COMMIT_SHA" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Skipping build as no changes were detected" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_COMMIT_SHA" } @test "(git) git:sync existing [errors]" { @@ -209,10 +311,22 @@ teardown() { echo "status: $status" assert_success + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" + run /bin/bash -c "dokku --trace git:sync $TEST_APP https://github.com/dokku/smoke-test-app.git" echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_MASTER_SHA" } @test "(git) git:sync existing [--no-build branch]" { @@ -221,10 +335,22 @@ teardown() { echo "status: $status" assert_success + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" + run /bin/bash -c "dokku git:sync $TEST_APP https://github.com/dokku/smoke-test-app.git another-branch" echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/another-branch" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_ANOTHER_BRANCH_SHA" } @test "(git) git:sync existing [--no-build tag]" { @@ -233,10 +359,22 @@ teardown() { echo "status: $status" assert_success + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" + run /bin/bash -c "dokku git:sync $TEST_APP https://github.com/dokku/smoke-test-app.git 2.0.0" echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_2_0_0_SHA" } @test "(git) git:sync existing [--no-build commit]" { @@ -245,10 +383,22 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku git:sync $TEST_APP https://github.com/dokku/smoke-test-app.git 5c8a5e42bbd7fae98bd657fb17f41c6019b303f9" + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" echo "output: $output" echo "status: $status" assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" + + run /bin/bash -c "dokku git:sync $TEST_APP https://github.com/dokku/smoke-test-app.git $SMOKE_TEST_APP_COMMIT_SHA" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_COMMIT_SHA" } @test "(git) git:sync existing [--build noarg]" { @@ -257,11 +407,35 @@ teardown() { echo "status: $status" assert_success + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" + run /bin/bash -c "dokku git:sync --build $TEST_APP https://github.com/dokku/smoke-test-app.git" echo "output: $output" echo "status: $status" assert_success assert_output_contains "Application deployed" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_MASTER_SHA" + + run /bin/bash -c "dokku git:sync --build-if-changes $TEST_APP https://github.com/dokku/smoke-test-app.git" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Skipping build as no changes were detected" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_MASTER_SHA" } @test "(git) git:sync existing [--build branch]" { @@ -270,11 +444,35 @@ teardown() { echo "status: $status" assert_success + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_2_0_0_SHA" + run /bin/bash -c "dokku git:sync --build $TEST_APP https://github.com/dokku/smoke-test-app.git another-branch" echo "output: $output" echo "status: $status" assert_success assert_output_contains "Application deployed" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_ANOTHER_BRANCH_SHA" + + run /bin/bash -c "dokku git:sync --build-if-changes $TEST_APP https://github.com/dokku/smoke-test-app.git another-branch" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Skipping build as no changes were detected" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_ANOTHER_BRANCH_SHA" } @test "(git) git:sync existing [--build tag]" { @@ -283,11 +481,35 @@ teardown() { echo "status: $status" assert_success + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" + run /bin/bash -c "dokku git:sync --build $TEST_APP https://github.com/dokku/smoke-test-app.git 2.0.0" echo "output: $output" echo "status: $status" assert_success assert_output_contains "Application deployed" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_2_0_0_SHA" + + run /bin/bash -c "dokku git:sync --build-if-changes $TEST_APP https://github.com/dokku/smoke-test-app.git 2.0.0" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Skipping build as no changes were detected" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_2_0_0_SHA" } @test "(git) git:sync existing [--build commit]" { @@ -296,11 +518,35 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku git:sync --build $TEST_APP https://github.com/dokku/smoke-test-app.git 5c8a5e42bbd7fae98bd657fb17f41c6019b303f9" + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_1_0_0_SHA" + + run /bin/bash -c "dokku git:sync --build $TEST_APP https://github.com/dokku/smoke-test-app.git $SMOKE_TEST_APP_COMMIT_SHA" echo "output: $output" echo "status: $status" assert_success assert_output_contains "Application deployed" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_COMMIT_SHA" + + run /bin/bash -c "dokku git:sync --build-if-changes $TEST_APP https://github.com/dokku/smoke-test-app.git $SMOKE_TEST_APP_COMMIT_SHA" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Skipping build as no changes were detected" + + run /bin/bash -c "cat /home/dokku/$TEST_APP/refs/heads/master" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "$SMOKE_TEST_APP_COMMIT_SHA" } @test "(git) git:sync private" { @@ -328,6 +574,12 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "dokku git:sync --build-if-changes $TEST_APP https://github.com/dokku/smoke-test-app-private.git" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Skipping build as no changes were detected" } @test "(git) git:public-key" {