Current section
Files
Jump to
Current section
Files
strategies/erlang-build-upgrade
#!/usr/bin/env bashREQUIRED_CONFIGS+=("APP")REQUIRED_CONFIGS+=("BUILD_HOST")REQUIRED_CONFIGS+=("BUILD_USER")REQUIRED_CONFIGS+=("BUILD_AT")OPTIONAL_CONFIGS+=("FROM")OPTIONAL_CONFIGS+=("WITH")OPTIONAL_CONFIGS+=("TO")OPTIONAL_CONFIGS+=("REBAR_CONFIG")TO="${TO:=$(get_latest_commit)}"help() { echo -e "${bldwht}Usage:${txtrst} edeliver build upgrade [Options]${txtbld}Options:${txtrst} --with=<release-version-from-store> ${txtylw}The release version to build the upgrade from${txtrst}. This release must have been built somewhen by the ${bldwht}build release${txtrst} command and must exist in the release store. --from=<git-revision> The revision to build the upgrade from ${txtylw}if that release is not avaiable any more${txtrst} (in the release store). ${txtylw}Must be in the branch${txtrst} passed as ${bldwht}--branch=${txtrst} argument or in the master (default). --to=<git-tag> The revision to build the upgrade for. Default is the HEAD of the master branch or the branch passed as ${bldwht}--branch=${txtrst} argument. --branch=<git-branch> The branch to build. ${txtylw}Default is the master branch${txtrst}. ${txtgrn}The branch doesn't need to be pushed to remote${txtrst} before building. The revision passed as ${bldwht}--from=${txtrst} or ${bldwht}--to=${txtrst} argument must be in that branch. --mix-env=<env> Build the upgrade with a custom mix environment. Default is ${bldwht}prod${txtrst}. --skip-relup-mod Skip modification of the grenerated relup instructions. No custom relup instructions are added. --relup-mod=<module-name> The name of the module to modify the relup if there are several modules. The module must implement the Behaviour ${bldwht}Edeliver.Relup.Modification${txtrst}. --auto-version=[git-]revision|[git-]commit-count[-all[-branches]|-branch] |[git-]branch[-unless-master]|[build-]date|mix-env ${txtgrn}Appends${txtrst} the git sha1 revision, the current commit count either across all branches (default) or for the current branch, the current branch name (optionally only unless it is the master branch) and/or the build date as ${txtgrn}metadata to the current upgrade version${txtrst}. To append that metadata ${txtgrn}automatically for each build${txtrst} set the ${bldwht}AUTO_VERSION${txtrst} env in the config. Values can also be combined using the ${bldwht}+${txtrst} char, e.g. ${bldwht}git-revison+git-branch${txtrst} creates version 1.2.3-82a5834-master. --increment-version=major|minor|patch Increments the major, minor or patch version ${txtylw}for the current build${txtrst}. --set-version=<release-version> Sets the release version for ${txtylw}the current build${txtrst}.${txtbld}Faster Builds:${txtrst} ${txtblu}(Faster builds might fail during build or during runtime)${txtrst} --skip-git-clean Don't build from a clean state for faster builds. Can be adjusted by the ${bldwht}GIT_CLEAN_PATHS${txtrst} environment variable. Should be at least ${bldwht}rel${txtrst} for elixir releases. --skip-mix-clean Skip the 'mix clean step' for faster builds. Can be used in addition to ${bldwht}--skip-git-clean${txtrst} Option for incremental builds.${bldylw}Info:${txtrst} Builds an upgrade on the build host and copies it to the release store. It can be used by the edeliver ${bldwht}deploy upgrade${txtrst} command to deploy it on staging or production hosts. ${txtgrn}The built upgrade can be used for hot code upgrades without a restart${txtrst} of the node. It is ${txtylw}required${txtrst} that the ${txtylw}release${txtrst} of the running node ${txtylw}is available${txtrst} (${bldwht}--with=${txtrst} Option) ${txtylw}or can be built${txtrst} (${bldwht}--from=${txtrst} Option) to be able to create the hot code upgrade strategy (relup). It ${txtylw}might be necessary to adjust the upgrade instructions${txtrst} (relup) by using the ${bldwht}edit relup${txtrst} command. "}set_build_hostsrun() { authorize_hosts authorize_release_store_on_build_host if [[ -n "$WITH" ]]; then [[ "$RELEASE_CMD" = "mix" ]] && local _release_type="*" || local _release_type="release" validate_release_is_in_store "$_release_type" $WITH # we can skip init_app_remotely and pushing to remote if release does not exist if [[ $? -ne 0 ]]; then hint_message "You can build appups also with the --from=<git-tag-or-revision> option\nif the release is not in your release store"; exit 2 fi # push current state init_app_remotely git_push git_reset_remote git_clean_remote elif [[ -n "$FROM" ]]; then # push current state init_app_remotely git_push git_reset_remote git_clean_remote # checkout old version git_checkout_remote $FROM # build old release erlang_get_and_update_deps # ... but don't change version of old release local _increment_release_version_option="$INCREMENT_RELEASE_VERSION" local _set_release_version_option="$SET_RELEASE_VERSION" INCREMENT_RELEASE_VERSION="" SET_RELEASE_VERSION="" erlang_clean_compile erlang_generate_release [[ "$RELEASE_CMD" = "rebar" ]] && rename_release_add_version [[ "$RELEASE_CMD" = "mix" ]] && __detect_remote_release_dir && __detect_remote_release_version # reset the option to auto-increment or setting the version for building the curent release for the upgrade INCREMENT_RELEASE_VERSION="$_increment_release_version_option" SET_RELEASE_VERSION="$_set_release_version_option" OLD_RELEASE_VERSION=${RELEASE_VERSION} else error_message "no old version specified"; exit 2 fi # checkout new version git_checkout_remote $TO # build new release erlang_get_and_update_deps erlang_clean_compile # check already now whether the built release will # have a different release version as the original release if [[ "$RELEASE_CMD" = "mix" ]]; then status "Checking version of new release" if [[ "$AUTO_RELEASE_VERSION" =~ ^(patch|minor|major)$ ]]; then local _version_command="release.version increase $AUTO_RELEASE_VERSION --verbose | grep -oe ' to .*' | cut -b 5-" elif [[ "$AUTO_RELEASE_VERSION" == "git" ]]; then local _version_command="release.version append-git-revision --verbose | grep -oe ' to .*' | cut -b 5-" elif [[ -n "$AUTO_RELEASE_VERSION" ]]; then local _version_command="release.version set \"$AUTO_RELEASE_VERSION\" --verbose | grep -oe ' to .*' | cut -b 5-" else local _version_command="release.version show" fi local _version_that_will_be_built=$(__remote " [ -f ~/.profile ] && source ~/.profile cd $BUILD_AT $SILENCE MIX_ENV=\"$TARGET_MIX_ENV\" $MIX_CMD $_version_command ") [[ -n "$WITH" ]] && local _old_version="$WITH" || local _old_version="$OLD_RELEASE_VERSION" [[ "$_version_that_will_be_built" = "$_old_version" ]] \ && __show_upgrade_version_does_not_differ_error_message \ && exit 1 fi if [[ -n "$WITH" ]] && [[ "$RELEASE_CMD" != "rebar" ]]; then # when generating upgrades with `mix release` (exrm) the old # release must be uploaded before generating the release. # `erlang_generate_release` generates the upgrade then automatically RELEASE_DIR="${RELEASE_DIR:-"${DELIVER_TO}/rel/${APP}"}" local _release_destination_path="$(dirname $RELEASE_DIR)" [[ "$RELEASE_FILE" =~ upgrade\.tar\.gz$ ]] && _release_destination_path="${_release_destination_path%%/}/${APP}" upload_release_archive "$_release_destination_path" "$RELEASE_FILE" "$WITH" remote_extract_release_archive "$WITH" "$(dirname $RELEASE_DIR)" if [[ "$RELEASE_FILE" =~ upgrade\.tar\.gz$ ]]; then status "Removing old releases which were included in upgrade package" __remote " [ -f ~/.profile ] && source ~/.profile set -e cd \"$(dirname $RELEASE_DIR)/${APP}/releases\" $SILENCE for release_dir in \$(ls -1); do [[ \"\$release_dir\" != \"$WITH\" ]] && [[ -n \"\$release_dir\" ]] && [[ -d \"\$release_dir\" ]] && echo \"removing \$release_dir\" $SILENCE && rm -rf \"\$release_dir\" || : done " fi __detect_remote_release_dir __detect_remote_release_version OLD_RELEASE_VERSION=${RELEASE_VERSION} fi if [[ "$RELEASE_CMD" = "relx" ]]; then relx_generate_relup else erlang_generate_release fi if [[ -n "$WITH" ]] && [[ "$RELEASE_CMD" = "rebar" ]]; then __detect_remote_release_dir # backup new release rename_release_add_version "new" NEW_RELEASE_VERSION=$RELEASE_VERSION; OLD_RELEASE_VERSION="$WITH" # upload and extract old release upload_release_archive "$(dirname $RELEASE_DIR)" "${APP}_${WITH}.release.tar.gz" "$WITH" remote_extract_release_archive "$WITH" "$(dirname $RELEASE_DIR)" # rename old release rename_release_add_version "old" "$WITH" # restore new release rename_release_remove_version $NEW_RELEASE_VERSION fi # generate default appups [[ "$RELEASE_CMD" = "rebar" ]] && rebar_generate_appup $OLD_RELEASE_VERSION # overwrite default appups with custom appups [[ "$RELEASE_CMD" = "rebar" ]] && copy_appups_from_release_store_to_build_host $OLD_RELEASE_VERSION # generate upgrade package and copy it to release store if [[ "$RELEASE_CMD" = "relx" ]]; then erlang_archive_release elif [[ "$RELEASE_CMD" = "mix" ]]; then remove_built_release_archive "$OLD_RELEASE_VERSION" RELEASE_VERSION="" # redetect new version __detect_remote_release_version else rebar_generate_upgrade $OLD_RELEASE_VERSION fi copy_release_to_release_store "upgrade"}