Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
7c6a41b
Check for existence of ROOT_URL in the same way as MONGO_URL
Sep 30, 2015
d6fa1f3
Added logic to extract COUCHDB_URL from VCAP_SERVICES
thehogg13 Oct 1, 2015
7b9948e
Forgot to put the variable in the latest git push! n00b.
thehogg13 Oct 1, 2015
52c8d0b
Try using profile.d
Oct 4, 2015
c44641b
Wrong directory
Oct 4, 2015
519c1ab
chmod not on the app
Oct 5, 2015
c5a55da
Try different path to jq
Oct 5, 2015
7c5783f
/20
Oct 5, 2015
3bc95f4
jq 2 jq
Oct 5, 2015
f593192
Trying with sudo perms to see if it works, added some echo to try and…
thehogg13 Oct 5, 2015
1c09d36
Echoing out whats in the directories
thehogg13 Oct 5, 2015
e9cd380
trying to get this path thing sorted
thehogg13 Oct 5, 2015
090b1d4
following the bouncing ball
thehogg13 Oct 5, 2015
d39724b
bouncing bouncing ...
thehogg13 Oct 5, 2015
bb798ae
Cleaned up changes
thehogg13 Oct 5, 2015
d2fc312
Try with version detect
Mar 29, 2016
9de3b57
output release
Mar 29, 2016
bd93bd3
output tarball_url
Mar 29, 2016
8c7e011
Do subs from original
Mar 29, 2016
6f2ebcf
Separate install-meteor-verbose.sh
Mar 29, 2016
7d9377c
Use BP_DIR
Mar 29, 2016
acd40bf
Change status
Mar 29, 2016
376e00d
chmod script
Mar 29, 2016
857171f
Build_dir in install
Mar 29, 2016
7ebaa7e
Pass build dir
Mar 29, 2016
c441372
Use source
Mar 29, 2016
f88aeac
Try and get status
Mar 29, 2016
006d8a3
?
Mar 29, 2016
91c990c
Try hard code
Mar 29, 2016
914dfe2
Try dynamic again
Mar 29, 2016
c4033a4
Try without g
Mar 29, 2016
d9f1f91
trim with xargs
Mar 29, 2016
c84d308
Trim \r
Mar 29, 2016
b6cad64
Remove release number status
Mar 29, 2016
afec000
Do npm install for meteor 1.3
Apr 28, 2016
5fa91e4
Update script to use cache etc like meteor-buildpack-horse
Aug 8, 2016
c5fc6d4
Path fixes
Aug 8, 2016
10fd946
wrong variable
Aug 8, 2016
efc81b2
jq failing
Aug 8, 2016
1104be5
Still need to create .vendor directory
Aug 8, 2016
34a6d12
wrong path for path.sh
Aug 8, 2016
a33d4ba
Echo found version
Aug 8, 2016
421a6ce
Need home path for meteor to work
Aug 8, 2016
7414d34
Code being copiled to different directory
Aug 11, 2016
33868af
Still wrong path for node
Aug 11, 2016
829f831
Remove -e
cmcrothers Sep 13, 2016
429d7df
Meteor debug build
cmcrothers Sep 13, 2016
4a94599
Grab code from horse and try --production for npm
Sep 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
285 changes: 204 additions & 81 deletions bin/compile
Original file line number Diff line number Diff line change
@@ -1,94 +1,217 @@
#!/bin/bash
#!/bin/sh

#
# Heroku buildpack for Bluemix
#

# fail fast.
set -e
# debug verbosely.
#set -x

# Load config vars into environment (from https://devcenter.heroku.com/articles/buildpack-api)
export_env_dir() {
env_dir=$1
whitelist_regex=${2:-''}
blacklist_regex=${3:-'^(PATH|GIT_DIR|CPATH|CPPATH|LD_PRELOAD|LIBRARY_PATH)$'}
if [ -d "$env_dir" ]; then
for e in $(ls $env_dir); do
echo "$e" | grep -E "$whitelist_regex" | grep -qvE "$blacklist_regex" &&
export "$e=$(cat $env_dir/$e)"
:
done
fi
}

export_env_dir $3

# Enable verbose debugging if configured to -- though this has to come after
# we've loaded environment configs.
if [ -n "${BUILDPACK_VERBOSE+1}" ]; then
set -x
fi

BUILD_DIR=$1

# Get the path to dir one above this file.
BUILDPACK_DIR=$(cd -P -- "$(dirname -- "$0")" && cd .. && pwd -P)
# Get the directory our app is checked out in (the "BUILD_DIR"), passed by Heroku
APP_CHECKOUT_DIR=$1
CACHE_DIR=$2
METEOR_HOME=$BUILD_DIR/.meteor/local
PATH=$METEOR_HOME/usr/bin:$METEOR_HOME/usr/lib/meteor/bin:$PATH

indent() {
c='s/^/ /'
case $(uname) in
Darwin) sed -l "$c";; # mac/bsd sed: -l buffers on line boundaries
*) sed -u "$c";; # unix/gnu sed: -u unbuffered (arbitrary) chunks of data
esac
}
if [ -n "${BUILDPACK_CLEAR_CACHE+1}" ]; then
echo "----> Clearing cache dir."
rm -rf "$CACHE_DIR"
fi

status() {
echo "-----> $*"
}
#
# Find the meteor app ($APP_SOURCE_DIR).
#

node_version=$(curl --silent --get https://semver.io/node/resolve/0.10.x)
# Set meteor app dir's location to the root of the git repo, plus the value of
# METEOR_APP_DIR (which defaults empty). If you put the meteor app in src/ or
# some other subdirectory, define METEOR_APP_DIR.
APP_SOURCE_DIR="${APP_CHECKOUT_DIR}"
if [ -n "$METEOR_APP_DIR" ]; then
APP_SOURCE_DIR="${APP_SOURCE_DIR}/${METEOR_APP_DIR}"
fi

install_node() {
if [ -f "$BUILD_DIR/.vendor/node/bin/node" ] ; then
status "Skipping Node installation. Already installed."
return
fi
# Try "$APP_SOURCE_DIR/app/" if meteor app isn't there (the "Iron scaffolding
# tool" default).
if [ ! -d "$APP_SOURCE_DIR/.meteor" ] && [ -d "$APP_SOURCE_DIR/app/.meteor" ]; then
APP_SOURCE_DIR="$APP_SOURCE_DIR/app/"
fi
if [ ! -d "$APP_SOURCE_DIR/.meteor" ]; then
echo "FATAL: Can't find meteor app. Set METEOR_APP_DIR to the relative location of the meteor app within your repository if it's not in the root or 'app/' subdirectory. (Tried ${APP_SOURCE_DIR})"
exit 1
fi

# Download node from Heroku's S3 mirror of nodejs.org/dist
status "Downloading and installing node $node_version"
NODE_INSTALLER=node-installer.tar.gz
NODE_URL="http://s3pository.heroku.com/node/v$node_version/node-v$node_version-linux-x64.tar.gz"
curl $NODE_URL > $NODE_INSTALLER
tar xzf $NODE_INSTALLER -C $BUILD_DIR

# Move node (and npm) into ./.vendor and make them executable
mkdir -p $BUILD_DIR/.vendor
mv $BUILD_DIR/node-v$node_version-linux-x64 $BUILD_DIR/.vendor/node
chmod +x $BUILD_DIR/.vendor/node/bin/*
PATH=$BUILD_DIR/.vendor/node/bin:$PATH
}
APP_RELEASE=`cat "$APP_SOURCE_DIR/.meteor/release" | sed -e 's/METEOR@//'`

install_meteor() {
if [ -f "$METEOR_HOME/usr/bin/meteor" ] ; then
status "Skipping Meteor installation. Already installed."
return
fi
# Where we will install meteor. Has to be outside the APP_CHECKOUT_DIR.
METEOR_DIR="$CACHE_DIR/$APP_RELEASE"
# Where we'll put things we compile.
COMPILE_DIR_SUFFIX=".meteor/heroku_build"
COMPILE_DIR="$APP_CHECKOUT_DIR"/"$COMPILE_DIR_SUFFIX"
# Try to minimize meteor's printing, unless we're running verbosely.
if [ -z "$BUILDPACK_VERBOSE" ]; then
METEOR_PRETTY_OUTPUT=0
fi

# status "Install Meteor"
# export PATH=/usr/bin:$PATH # necessary for install script to run from URL
# curl https://install.meteor.com | sh
status "Downloading Meteor install script"
METEOR_INSTALL_SCRIPT=install_meteor.sh
curl https://install.meteor.com/ > $METEOR_INSTALL_SCRIPT

status "Installing Meteor connected to $MONGO_URL"
sed -e '/^#!\/bin\/sh/ s/$/ -x/' \
-e 's/set -/#set -/' \
-e 's/curl --progress-bar --fail.*/curl "$TARBALL_URL" > meteor-bundle.tgz; tar -xzf meteor-bundle.tgz -C "$INSTALL_TMPDIR" -o/' \
$METEOR_INSTALL_SCRIPT > install-meteor-verbose.sh
chmod +x install-meteor-verbose.sh

status "Execute ./install-meteor-verbose.sh"
./install-meteor-verbose.sh
status "Done"

status "Updating PATH with Meteor"
PATH=$HOME/.meteor:$PATH
}
# Create directories as needed.
mkdir -p "$APP_CHECKOUT_DIR" "$METEOR_DIR"
mkdir -p "$COMPILE_DIR" "$COMPILE_DIR/bin" "$COMPILE_DIR/lib"

# Set a default ROOT_URL if one is not defined. Currently, HEROKU_APP_NAME is
# only available if you enable the labs addon "Heroku Dyno Metadata":
# https://devcenter.heroku.com/articles/dyno-metadata
# This logic is duplicated in extra/root_url.sh so that it repeats on dyno
# restart.
if [ -z "$ROOT_URL" ] && [ -n "$HEROKU_APP_NAME" ] ; then
export ROOT_URL="https://${HEROKU_APP_NAME}.herokuapp.com"
fi
if [ -z "$ROOT_URL" ] ; then
echo "FATAL: ROOT_URL is not defined."
exit 1
fi

build() {
(
cd $BUILD_DIR
status "Building meteor bundle"
meteor build --directory deploy --server http://localhost:3000
cd deploy/bundle/programs/server
status "Installing npm dependencies"
npm install 2>&1 | indent
mv $BUILD_DIR/.vendor $BUILD_DIR/vendor
)
}
#
# Install meteor
#

if [ ! -e "$METEOR_DIR/.meteor/meteor" ]; then
echo "-----> Installing meteor"
curl -sS "https://install.meteor.com/?release=$APP_RELEASE" | HOME="$METEOR_DIR" /bin/sh
fi
METEOR="$METEOR_DIR/.meteor/meteor" # The meteor binary.

echo "-----> Meteor version: `HOME=$METEOR_DIR $METEOR --version`"

#
# Build the meteor app!
#
cd "$APP_SOURCE_DIR"

# Determine if we have --server-only flag capability. Allow non-zero return from grep.
echo "-----> Checking if this meteor version supports --server-only"
set +e
HAS_SERVER_ONLY=`HOME=$METEOR_DIR $METEOR help build | grep -e '--server-only'`
set -e
if [ -n "$HAS_SERVER_ONLY" ] ; then
SERVER_ONLY_FLAG='--server-only'
else
SERVER_ONLY_FLAG=""
fi
# Remove the Android platform if we don't support the --server-only flag. iOS
# platform gets ignored properly.
if [ -z "$SERVER_ONLY_FLAG" ]; then
echo "-----> Attempting to remove android platform."
HOME=$METEOR_DIR $METEOR remove-platform android || true
echo "-----> Moving on."
fi

# Identify the npm/node to use. While we could use `meteor node` and `meteor
# npm` to execute these directly, to use them in prod, we'd need to copy the
# meteor world into the built slug, and that's too large (Issue #125).
# Instead, search for the binaries within meteor, and copy them into our built
# slug.

METEOR_NPM=`find $METEOR_DIR -wholename "*/dev_bundle/bin/npm"`
METEOR_NODE=`find $METEOR_DIR -wholename "*/dev_bundle/bin/node"`
# Trim whitespace
METEOR_NPM=`echo "$METEOR_NPM" | sed -e 's/[[:space:]]*$//'`
METEOR_NODE=`echo "$METEOR_NODE" | sed -e 's/[[:space:]]*$//'`
if [ -z "$METEOR_NPM" ] || [ -z "$METEOR_NODE" ] ; then
echo "FATAL: Can't find npm/node within meteor bundle. This is a bug. Please open an issue at https://github.com/AdmitHub/meteor-buildpack-horse.";
exit 1
fi

# Copy node into place for production.
NODE="$COMPILE_DIR"/bin/node
cp "$METEOR_NODE" "$NODE"
chmod a+x "$NODE"

[ ! -d $BUILD_DIR ] && mkdir $BUILD_DIR
[ ! -d $CACHE_DIR ] && mkdir $CACHE_DIR
# Add npm and node path so that 1.4's npm-rebuild.js will function.
PATH="$METEOR_DIR/.meteor:`dirname $METEOR_NPM`:$COMPILE_DIR/bin:$PATH"

install_node
install_meteor
build
echo "-----> Using node: `$NODE --version`"
echo "-----> and npm: `$METEOR_NPM --version`"

status "Checking for post_compile script"
if [ -f $BUILD_DIR/bin/post_compile ] ; then
status "Running post_compile hook"
chmod +x $BUILD_DIR/bin/post_compile
$BUILD_DIR/bin/post_compile
# If we use npm on root, run npm install.
if [ -e "$APP_SOURCE_DIR"/package.json ]; then
$METEOR_NPM install --production
fi

# Related to https://github.com/meteor/meteor/issues/2796 and
# https://github.com/meteor/meteor/issues/2606. Some packages only build their
# assets at runtime, and thus they are not available for bundling unless meteor
# has been launched. To opt-in to this, set BUILDPACK_PRELAUNCH_METEOR=1.
if [ -n "${BUILDPACK_PRELAUNCH_METEOR+1}" ]; then
echo "-----> BUILDPACK_PRELAUNCH_METEOR: Pre-launching meteor to build packages assets"
# Remove the Android platform because it fails due to the Android tools not
# being installed, but leave the iOS platform because it's ignored.
HOME=$METEOR_DIR $METEOR remove-platform android || true
HOME=$METEOR_DIR timeout -s9 60 $METEOR --settings settings.json || true
fi

# Now on to bundling. Don't put the bundle in $APP_CHECKOUT_DIR during
# bundling, or it will recurse, trying to bundle up its own bundling.

echo "-----> Building Meteor app with ROOT_URL: $ROOT_URL"
BUNDLE_DEST=`mktemp -d "$BUILDPACK_DIR/build-XXXX"`

# The actual invocation of `meteor build`!
HOME=$METEOR_DIR $METEOR build $BUILD_OPTIONS --server $ROOT_URL $SERVER_ONLY_FLAG --directory $BUNDLE_DEST

echo "-----> Moving built slug to $COMPILE_DIR/app"
mv $BUNDLE_DEST/bundle "$COMPILE_DIR/app"
rmdir $BUNDLE_DEST

# Run npm install on the built slug; only for `--production` dependencies.
echo "-----> Installing npm production dependencies on built slug"
if [ -e "$COMPILE_DIR"/app/programs/server/package.json ]; then
cd "$COMPILE_DIR"/app/programs/server
$METEOR_NPM install --production
cd "$APP_SOURCE_DIR"
fi

#
# Environment
#
# Add an export of PATH which includes our compile dir, etc.
echo "-----> Adding PATH environment"
mkdir -p "$APP_CHECKOUT_DIR"/.profile.d
cat > "$APP_CHECKOUT_DIR"/.profile.d/path.sh <<EOF
#!/bin/sh
export PATH=\$HOME/$COMPILE_DIR_SUFFIX/bin:\$PATH
export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:\$HOME/$COMPILE_DIR_SUFFIX/lib
EOF

#
# Extras
#

# source scripts in 'extra' dir, if any. Create them for custom stuff like
# binary dependencies, additional environment settings, etc.
echo "-----> Running extras"
for file in `ls "$BUILDPACK_DIR"/extra | sort`; do
. "$BUILDPACK_DIR"/extra/$file
done
24 changes: 1 addition & 23 deletions bin/release
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,10 @@

BUILD_DIR=$1

DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
jq=$DIR/jq
chmod +x $jq

extract_mongo_url() {
# Set if not already present.
if [ -z "${MONGO_URL}" ]; then
#echo "Pulling MONGO_URL from VCAP_SERVICES"
# Find the first service key that contains "mongo", then grab the 'url' (or 'uri') key beneath it.
export MONGO_URL=`echo $VCAP_SERVICES | $jq 'to_entries|map(select(.key|contains("mongo")))[0]|.value[0].credentials|if .url then .url else .uri end|. // empty'`
fi
#echo "MONGO_URL: $MONGO_URL"
}

extract_root_url() {
#echo "Pulling ROOT_URL from VCAP_APPLICATION"
DOMAIN=`echo $VCAP_APPLICATION | $jq '.uris[0]' | sed -e 's/^"//' -e 's/"$//'`
export ROOT_URL="http://$DOMAIN"
#echo "ROOT_URL: $ROOT_URL"
}

extract_mongo_url
extract_root_url

cat <<-YAML
---
default_process_types:
web: MONGO_URL=$MONGO_URL ROOT_URL=$ROOT_URL vendor/node/bin/node deploy/bundle/main.js
web: .meteor/cf_build/bin/node .meteor/cf_build/app/main.js
YAML
32 changes: 32 additions & 0 deletions profile/env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
jq=$HOME/.vendor/jq

extract_mongo_url() {
# Set if not already present.
if [ -z "${MONGO_URL}" ]; then
#echo "Pulling MONGO_URL from VCAP_SERVICES"
# Find the first service key that contains "mongo", then grab the 'url' (or 'uri') key beneath it.
export MONGO_URL=`echo $VCAP_SERVICES | $jq 'to_entries|map(select(.key|contains("mongo")))[0]|.value[0].credentials|if .url then .url else .uri end|. // empty' | sed -e 's/^"//' -e 's/"$//'`
fi
#echo "MONGO_URL: $MONGO_URL"
}

extract_root_url() {
if [ -z "${ROOT_URL}" ]; then
#echo "Pulling ROOT_URL from VCAP_APPLICATION"
DOMAIN=`echo $VCAP_APPLICATION | $jq '.uris[0]' | sed -e 's/^"//' -e 's/"$//'`
export ROOT_URL="http://$DOMAIN"
#echo "ROOT_URL: $ROOT_URL"
fi
}

extract_couchdb_url() {
if [ -z "${COUCHDB_URL}" ]; then
#echo "Pulling COUCHDB_URL from VCAP_SERVICES"
# Find the first service key that contains "cloudant", then grab the 'url' (or 'uri') key beneath it.
export COUCHDB_URL=`echo $VCAP_SERVICES | $jq 'to_entries|map(select(.key|contains("cloudant")))[0]|.value[0].credentials|if .url then .url else .uri end|. // empty' | sed -e 's/^"//' -e 's/"$//'`
fi
}

extract_mongo_url
extract_root_url
extract_couchdb_url