-
Notifications
You must be signed in to change notification settings - Fork 186
Umbrella Projects
To be able to build and deploy releases and hot code upgrades for umbrella projects you need to set the RELEASE_DIR
env in the ./.deliver/config
to:
# .deliver/config
RELEASE_DIR="$BUILD_AT/apps/$APP/rel/$APP"
This is necessary because the release dir can't be auto-detected by edeliver. When using exrm, the old release must be copied and extracted to the correct (release) directory already before building, and detecting the release dir automatically is possible only after the build process. In addition exrm generates a release for each umbrella project and it is not possible for edeliver to detect the correct release containing the main application automatically.
In addition auto-versioning does not work for umbrella projects. You need to implement auto-versioning yourself by modifying the application version for each umbrella project, e.g. like this:
# apps/master_app/mix.exs
def project do
[app: :master_app,
version: append_revision("0.0.1"),
deps_path: "../../deps",
lockfile: "../../mix.lock",
elixir: "~> 1.0",
deps: [{:app_one, in_umbrella: true}, {:app_two, in_umbrella: true}]
end
def append_revision(version) do
"#{version}+#{revision()}"
end
defp revision() do
System.cmd("git", ["rev-parse", "--short", "HEAD"])
|> elem(0)
|> String.trim_trailing
end
This should be done for all umbrella projects to be able to generate upgrade instructions for them:
# apps/app_one/mix.exs
def project do
[app: :app_one,
version: append_revision("0.0.1"),
deps_path: "../../deps",
lockfile: "../../mix.lock",
elixir: "~> 1.0",
deps: deps]
end
def append_revision(version) do
"#{version}+#{revision}"
end
defp revision() do
System.cmd("git", ["rev-parse", "--short", "HEAD"])
|> elem(0)
|> String.trim_trailing
end
You can find more examples how to automatically add metadata to the version in the Mix.Tasks.Release.Version
task.
Depending on the exrm version or the release tool your are using, it might be necessary to manually fetch the dependencies of the umbrella projects and also to compile them. This can be done by using a post hook like this:
# .deliver/config
post_erlang_clean_compile() {
[[ "$APP" = "my-main-app" ]] && prepare_projects_in_umbrella
}
prepare_projects_in_umbrella() {
status "Preparing projects in umbrella"
__sync_remote "
[ -f ~/.profile ] && source ~/.profile
set -e
cd '${BUILD_AT}'
for UMBRELLA_APP in \$(ls -1 apps | grep -v '$APP'); do
echo \"Preparing \${UMBRELLA_APP} in umbrella...\" $SILENCE
cd \"${BUILD_AT}/apps/\${UMBRELLA_APP}\" $SILENCE
APP=\"\$UMBRELLA_APP\" MIX_ENV='$TARGET_MIX_ENV' mix do deps.get, compile
done
"
}
If you want to build a release for an umbrella application in addition to the main release (containing the umbrella application) you can build it like a project in a subdirectory:
# .deliver/config
BUILD_AT="..."
# set the build directory to the umbrella project dir
if [[ "$APP" = "my-umbrella-app" ]]; then
BUILD_AT="${BUILD_AT}/apps/${APP}"
fi
# set the build directory to the actual git directory
pre_init_app_remotely() {
[[ "$APP" = "my-umbrella-app" ]] && set_git_project_directory
}
# reset the build directory
pre_erlang_get_and_update_deps() {
[[ "$APP" = "my-umbrella-app" ]] && restore_build_directory
}
set_git_project_directory() {
ACTUAL_PROJECT_DIR="$DELIVER_TO"
DELIVER_TO="$(dirname $DELIVER_TO)"
DELIVER_TO="$(dirname $DELIVER_TO)"
}
restore_build_directory() {
DELIVER_TO="$ACTUAL_PROJECT_DIR"
}
Examples are taken from the exrm umbrella test project.