#!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_AVAILABLE_PATH/apps/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" git_build_app_repo() { declare desc="builds local git app repo for app" verify_app_name "$1" local APP="$1"; local REV="$2" # clean up after ourselves local GIT_BUILD_APP_REPO_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_git.XXXX") trap 'rm -rf "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" > /dev/null' RETURN INT TERM EXIT # git clone - this method creates a new git repository and adds the primary # repo as a remote, then does a fetch depth=1 to avoid cloning # the entire repo local TMP_TAG="dokku/$REV" chmod 755 "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" unset GIT_DIR GIT_WORK_TREE pushd "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" > /dev/null [[ ! -d "$DOKKU_ROOT/$APP" ]] && apps_create "$APP" GIT_DIR="$DOKKU_ROOT/$APP" git tag -d "$TMP_TAG" &> /dev/null || true GIT_DIR="$DOKKU_ROOT/$APP" git tag "$TMP_TAG" "$REV" &> /dev/null git init &> /dev/null git config advice.detachedHead false git remote add origin "$DOKKU_ROOT/$APP" &> /dev/null git fetch --depth=1 origin "refs/tags/$TMP_TAG" &> /dev/null git reset --hard FETCH_HEAD &> /dev/null suppress_output git submodule update --init --recursive GIT_DIR="$DOKKU_ROOT/$APP" git tag -d "$TMP_TAG" &> /dev/null || true find -name .git -prune -exec rm -rf {} \; > /dev/null if [[ -f Dockerfile ]] && [[ "$([[ -f .env ]] && grep -q BUILDPACK_URL .env; echo $?)" != "0" ]] && [[ ! -f ".buildpacks" ]] && [[ -z $(config_get "$APP" BUILDPACK_URL || true) ]]; then plugn trigger pre-receive-app "$APP" "dockerfile" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV" dokku_receive "$APP" "dockerfile" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" else plugn trigger pre-receive-app "$APP" "herokuish" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV" dokku_receive "$APP" "herokuish" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" fi } suppress_output() { declare desc="suppress all output from a given command unless there is an error" local TMP_COMMAND_OUTPUT TMP_COMMAND_OUTPUT=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") trap 'rm -rf "$TMP_COMMAND_OUTPUT" > /dev/null' RETURN INT TERM EXIT "$@" > "$TMP_COMMAND_OUTPUT" 2>&1 || { local exit_code="$?" cat "$TMP_COMMAND_OUTPUT" return "$exit_code" } return 0 } git_deploy_branch() { declare desc="retrieve the deploy branch for a given application" local cmd="git-hook" local APP="$1" local DOKKU_DEPLOY_BRANCH="$(config_get "$APP" DOKKU_DEPLOY_BRANCH || true)" local DOKKU_GLOBAL_DEPLOY_BRANCH="$(config_get --global DOKKU_DEPLOY_BRANCH || true)" if [[ -n "$DOKKU_DEPLOY_BRANCH" ]]; then echo "$DOKKU_DEPLOY_BRANCH" elif [[ -n "$DOKKU_GLOBAL_DEPLOY_BRANCH" ]]; then echo "$DOKKU_GLOBAL_DEPLOY_BRANCH" else echo "master" fi } git_hook_cmd() { declare desc="kick off receive-app trigger from git prereceive hook" local cmd="git-hook" local APP="$2" local DOKKU_DEPLOY_BRANCH="$(git_deploy_branch "$APP")" if ! git check-ref-format --branch "$DOKKU_DEPLOY_BRANCH" 2> /dev/null; then echo $'\e[1G\e[K'"-----> WARNING: Invalid branch name '$DOKKU_DEPLOY_BRANCH' specified via DOKKU_DEPLOY_BRANCH." 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 # shellcheck disable=SC2086 plugn trigger receive-app $APP $newrev else if [[ $(find "$PLUGIN_PATH"/enabled/*/receive-branch 2>/dev/null | wc -l) != 0 ]]; then # shellcheck disable=SC2086 plugn trigger receive-branch $APP $newrev $refname else echo $'\e[1G\e[K'"-----> WARNING: deploy did not complete, you must push to master." echo $'\e[1G\e[K'"-----> for example, try 'git push ${refname/refs\/heads\/}:master'" fi fi done } git_build() { declare desc="setup and call git_build_app_repo" local APP="$1" if [[ $# -ge 2 ]]; then local REF="$2" else local REF=$(< "$DOKKU_ROOT/$APP/refs/heads/master") fi # shellcheck disable=SC2086 git_build_app_repo $APP $REF } git_upload_pack_cmd() { declare desc="executes git-upload-pack" local cmd="git-upload-pack" local APP="$(echo "$2" | perl -pe 's/(? /dev/null local PRERECEIVE_HOOK="$APP_PATH/hooks/pre-receive" cat > "$PRERECEIVE_HOOK" <