Skip to content

Buildpack incompatible with building in /app #13

@edmorley

Description

@edmorley

Hi

I'm on the team that maintains Heroku's build system and official buildpacks, and wanted to let you know about a future incompatibility with this buildpack.

The directory in which the Heroku build system performs builds is currently a path like/tmp/build_<hash>.

In the near future this path will be changing to /app so that the build-time and run-time app locations are the same path - in order to resolve a number of long standing bugs, and reduce the number of hacks buildpacks have to use to work around non-relocatable languages/toolchains.

This change will mean builds using this buildpack will show warnings like:

remote: -----> Python + OpenCV + Numpy + Scipy app detected
remote: cp: '/app/requirements.txt' and '/app/requirements.txt' are the same file
remote: cp: '/app/test' and '/app/test' are the same file
remote: -----> Generating environment
remote:        Fetching...
remote:        Unpacking...
...
remote: -----> Creating environment variables.
remote: cp: '/app/.heroku' and '/app/.heroku' are the same file
remote: cp: '/app/.profile.d' and '/app/.profile.d' are the same file
remote: -----> Buildpack installed.

...and worse, the build will appear to succeed (exit non-zero) due to this buildpack not using Bash "exit on error", however the contents of the app source will not be copied correctly into the build, meaning the app will fail to boot.

To reproduce, the new behaviour can be enabled manually (ahead of it being the new default), using:

heroku labs:enable build-in-app-dir -a my_app_name

To fix, some reworking of these parts will be needed (eg skipping the move if BUILD_DIR is already /app):

# Does some serious copying.
deep-cp() {
declare source="$1" target="$2"
mkdir -p "$target"
# cp doesn't like being called without source params,
# so make sure they expand to something first.
# subshell to avoid surprising caller with shopts.
(
shopt -s nullglob dotglob
set -- "$source"/!(tmp|.|..)
[[ $# == 0 ]] || cp -a "$@" "$target"
)
}
# Does some serious moving.
deep-mv() {
deep-cp "$1" "$2"
deep-rm "$1"
}
# Does some serious deleting.
deep-rm() {
# subshell to avoid surprising caller with shopts.
(
shopt -s dotglob
rm -rf "$1"/!(tmp|.|..)
)
}
###################################
BUILD_DIR=$1
CACHE_DIR=$2
APP_DIR="/app"
deep-mv $BUILD_DIR $APP_DIR
ORIG_BUILD_DIR=$BUILD_DIR
BUILD_DIR=$APP_DIR
cd $BUILD_DIR

deep-mv $BUILD_DIR $ORIG_BUILD_DIR

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions