Skip to content
This repository was archived by the owner on Feb 13, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 0 additions & 4 deletions .profile.d/buildpack-boot.sh

This file was deleted.

10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
**Please note:** This buildpack is an experimental project and is not officially supported.

# ASP.NET 5 Buildpack
# .NET Core Buildpack

This is a [Heroku buildpack](http://devcenter.heroku.com/articles/buildpack) for building [ASP.NET 5](http://www.asp.net/vnext/overview/aspnet-vnext/aspnet-5-overview) apps using [`project.json` files](https://github.com/aspnet/Home/wiki/Project.json-file) and the [kpm package manager](https://github.com/aspnet/Home/wiki/Package-Manager).

[Mono](http://www.mono-project.com/) is bundled for runtime execution.
This is a [Heroku buildpack](http://devcenter.heroku.com/articles/buildpack) for building [.NET Core](https://www.microsoft.com/net/core) apps using [`project.json` files](https://docs.microsoft.com/en-us/dotnet/articles/core/tools/project-json).

## Usage

Example usage:

$ heroku create --buildpack http://github.com/heroku/dotnet-buildpack.git
$ heroku create --buildpack http://github.com/friism/dotnet-buildpack.git
$ git push heroku master

The buildpack will detect your app as ASP.NET 5 if it has `project.json`. If the source code you want to build contains multiple `project.json` files, you can use a [`.deployment`](https://github.com/projectkudu/kudu/wiki/Customizing-deployments) or set a `$PROJECT` config var to control which one is built.
The buildpack will detect your app as .NET Core if it has `project.json`. If the source code you want to build contains multiple `project.json` files, you can use a [`.deployment`](https://github.com/projectkudu/kudu/wiki/Customizing-deployments) or set a `$PROJECT` config var to control which one is built.
167 changes: 83 additions & 84 deletions bin/compile
Original file line number Diff line number Diff line change
Expand Up @@ -18,83 +18,82 @@ source $BUILDPACK_DIR/bin/util

export_env_dir ${ENV_DIR}

: ${MONO_VERSION:="4.0.1.44"}
: ${MONO_DOWNLOAD_LOCATION:="https://github.com/friism/mono-builder/releases/download/v${MONO_VERSION}/mono-${MONO_VERSION}.tar.gz"}
: ${LIBUV_VERSION:="1.6.0"}
: ${NODE_VERSION:="0.12.2"}
: ${DNVM_BRANCH:="dev"}
: ${DNX_VERSION:="latest"}

# REMARK: https://github.com/aspnet/dnx/pull/2620 and https://github.com/aspnet/aspnet-docker/issues/80
[ -z "$MONO_THREADS_PER_CPU" ] && export MONO_THREADS_PER_CPU=50

if [ -n "$BUILD_DEBUG" ]; then
DNU_FLAGS=""
echo "DNX_VERSION: ${DNX_VERSION}"
echo "DNVM_BRANCH: ${DNVM_BRANCH}"
else
DNU_FLAGS="--quiet"
fi

if [ -n "$UNSTABLE_TOOLCHAIN" ]; then
DNVM_FLAGS="-u"
else
DNVM_FLAGS=""
fi

SRC_DIR=`mktemp -d`
: ${LIBUV_VERSION:="1.10.1"}
: ${NODEJS_VERSION:="6.9.1"}
: ${DOTNET_SDK_VERSION:="1.0.0-preview2-1-003177"}
: ${DOTNET_RUNTIME_VERSION:="1.1.0"}
: ${LIBUNWIND_VERSION:="1.1-4.1"}

export NUGET_XMLDOC_MODE=skip
export DOTNET_CLI_TELEMETRY_OPTOUT=1
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1

SRC_DIR=`mktemp -d`/app
mkdir -p ${SRC_DIR}
# Move the app source code into temporary src dir using subshell to not leak shopt
(
shopt -s dotglob
mv ${BUILD_DIR}/* ${SRC_DIR}
)

mkdir -p ${BUILD_DIR}/.profile.d
mkdir -p ${CACHE_DIR}

echo "installing ${MONO_DOWNLOAD_LOCATION}"
# TODO: use s4cmd
curl ${MONO_DOWNLOAD_LOCATION} -Ls | tar xz -C ${BUILD_DIR}
# Mono expects to be running out of /app
ln -s ${BUILD_DIR}/mono /app

export PATH="/app/mono/bin:${PATH}"
export LD_LIBRARY_PATH="/app/mono/lib:${LD_LIBRARY_PATH}"

mozroots --import --sync --quiet
cp -r ~/.config ${BUILD_DIR}/.

# TODO: This test doesn't seen to actually work
# TODO: Maybe just run `npm install -g` and if anything is missing, install it after
if [[ -n $(find . -type f -iname package.json -o -iname bower.json -o -iname gruntfile.js) ]]
then
# Install Node and grunt-cli
NODE_PATH=`mktemp -d`
curl https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz -Ls \
| tar xz -C ${NODE_PATH}
export PATH="${NODE_PATH}/node-v${NODE_VERSION}-linux-x64/bin:${PATH}"
# Get libunwind
# TODO: factor this out into method
LIBUNWIND_DEB_DIR=${CACHE_DIR}/deb/libunwind/${LIBUNWIND_VERSION}
if [ ! -f ${LIBUNWIND_DEB_DIR}/libunwind.deb ]; then
rm -rf ${CACHE_DIR}/deb/libunwind/* || true
mkdir -p ${LIBUNWIND_DEB_DIR}

echo "Downloading libunwind version ${LIBUNWIND_VERSION}"
curl -o ${LIBUNWIND_DEB_DIR}/libunwind.deb -sSL https://mirrors.kernel.org/ubuntu/pool/main/libu/libunwind/libunwind8_${LIBUNWIND_VERSION}_amd64.deb
fi
mkdir -p ${BUILD_DIR}/.apt
dpkg -x ${LIBUNWIND_DEB_DIR}/libunwind.deb $BUILD_DIR/.apt/
export LD_LIBRARY_PATH="$BUILD_DIR/.apt/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
cat <<EOF >$BUILD_DIR/.profile.d/000_apt.sh
export LD_LIBRARY_PATH="\$HOME/.apt/usr/lib/x86_64-linux-gnu:\$LD_LIBRARY_PATH"
EOF

# Get Dotnet Core
DOTNET_CACHE_LOCATION=${CACHE_DIR}/dotnet/${DOTNET_SDK_VERSION}
if [ ! -d ${DOTNET_CACHE_LOCATION} ]; then
rm -rf ${CACHE_DIR}/dotnet/* || true
mkdir -p ${DOTNET_CACHE_LOCATION}/{sdk,runtime}

echo "Downloading .NET SDK version ${DOTNET_SDK_VERSION} and runtime version ${DOTNET_RUNTIME_VERSION}"

DOTNET_SDK_DOWNLOAD_URL=https://dotnetcli.blob.core.windows.net/dotnet/preview/Binaries/$DOTNET_SDK_VERSION/dotnet-dev-ubuntu-x64.$DOTNET_SDK_VERSION.tar.gz
curl -sSL ${DOTNET_SDK_DOWNLOAD_URL} | tar xz -C ${DOTNET_CACHE_LOCATION}/sdk
find ${DOTNET_CACHE_LOCATION}/sdk/sdk/${DOTNET_SDK_VERSION}/runtimes/* -maxdepth 0 ! -name unix -exec rm -r {} +
rm -f ${DOTNET_CACHE_LOCATION}/sdk/sdk/${DOTNET_SDK_VERSION}/nuGetPackagesArchive.lzma

DOTNET_RUNTIME_DOWNLOAD_URL=http://download.microsoft.com/download/A/F/6/AF610E6A-1D2D-47D8-80B8-F178951A0C72/Binaries/dotnet-ubuntu-x64.${DOTNET_RUNTIME_VERSION}.tar.gz
curl -sSL ${DOTNET_RUNTIME_DOWNLOAD_URL} | tar xz -C ${DOTNET_CACHE_LOCATION}/runtime
fi
export PATH="${DOTNET_CACHE_LOCATION}/sdk:$PATH"
cp -r ${DOTNET_CACHE_LOCATION}/runtime ${BUILD_DIR}/dotnet
cat <<EOF >$BUILD_DIR/.profile.d/000_dotnet.sh
export PATH="\$HOME/dotnet:\$PATH"
EOF

# Get Node.js
NODEJS_CACHE_LOCATION=${CACHE_DIR}/nodejs/${NODEJS_VERSION}
export PATH="${NODEJS_CACHE_LOCATION}/node-v${NODEJS_VERSION}-linux-x64/bin:$PATH"
if [ ! -d ${NODEJS_CACHE_LOCATION} ]; then
rm -rf ${CACHE_DIR}/nodejs/* || true
NODEJS_DOWNLOAD_URL=https://nodejs.org/dist/v${NODEJS_VERSION}/node-v${NODEJS_VERSION}-linux-x64.tar.xz

mkdir -p ${NODEJS_CACHE_LOCATION}

echo "Downloading Node.js version ${NODEJS_VERSION}"
curl -sSL ${NODEJS_DOWNLOAD_URL} | tar xJ -C ${NODEJS_CACHE_LOCATION}
npm install -g grunt-cli bower gulp
fi
npm config set cache ${NODEJS_CACHE_LOCATION}/npm/cache -g

# Install DNX
# TODO: consider making this not dependent on GitHub being up
touch ~/.profile
curl -sSL https://raw.githubusercontent.com/aspnet/Home/${DNVM_BRANCH}/dnvminstall.sh \
| sh && source ~/.dnx/dnvm/dnvm.sh

export DNVM_RUNTIME_LOCAL_CACHE="/app/.dnx"
export DNVM_RUNTIME_CACHE_LOCATION="${CACHE_DIR}/dnx/runtimes"
mkdir -p ${DNVM_RUNTIME_LOCAL_CACHE}
mkdir -p ${DNVM_RUNTIME_CACHE_LOCATION}
ln -s ${DNVM_RUNTIME_CACHE_LOCATION} ${DNVM_RUNTIME_LOCAL_CACHE}/runtimes

# TODO: extract DNX version from global.json
dnvm install $DNX_VERSION $DNVM_FLAGS -a default

# Add DNX to the build output
DNX_BUILD_LOCATION=${BUILD_DIR}/.dnx/runtimes/
mkdir -p ${DNX_BUILD_LOCATION}
cp -r ~/.dnx/runtimes/`dnvm alias default` ${DNX_BUILD_LOCATION}

# Build the project
DEPLOYMENT_FILE_LOCATION=${SRC_DIR}/.deployment
if [ -n "$PROJECT" ]; then
PROJECT_JSON_FILE=${SRC_DIR}/${PROJECT}
Expand All @@ -109,32 +108,32 @@ else
fi
echo "Building ${PROJECT_JSON_FILE}"

export DNU_LOCAL_CACHE="/app/.local/share/dnu"
export DNU_CACHE_LOCATION="${CACHE_DIR}/dnu/cache"
mkdir -p ${DNU_LOCAL_CACHE}
mkdir -p ${DNU_CACHE_LOCATION}
ln -s ${DNU_CACHE_LOCATION} ${DNU_LOCAL_CACHE}/cache
export NUGET_PACKAGES="${CACHE_DIR}/nuget/cache"
dotnet restore ${PROJECT_JSON_FILE}

dnu restore $DNU_FLAGS ${PROJECT_JSON_FILE}
dotnet publish ${PROJECT_JSON_FILE} --output ${BUILD_DIR} --runtime ubuntu.14.04-x64 --configuration Release

dnu publish --out ${BUILD_DIR} $DNU_FLAGS --no-source --configuration Release ${PROJECT_JSON_FILE}

# Clean out core-stuff that we don't need in the slug
find ${BUILD_DIR} -iname dnxcore50 -print0 | xargs -r -0 rm --
# Get libuv
LIBUV_CACHE_LOCATION=${CACHE_DIR}/libuv/${LIBUV_VERSION}
if [ ! -d ${LIBUV_CACHE_LOCATION} ]; then
rm -rf ${CACHE_DIR}/libuv/* || true
mkdir -p ${LIBUV_CACHE_LOCATION}

mkdir -p ${BUILD_DIR}/.profile.d
cp -n ${BUILDPACK_DIR}/.profile.d/* ${BUILD_DIR}/.profile.d/
echo "Downloading libuv version ${LIBUV_VERSION}"
curl https://github.com/friism/libuv-builder/releases/download/v${LIBUV_VERSION}/libuv-${LIBUV_VERSION}.tar.gz -sSL \
| tar xz -C ${LIBUV_CACHE_LOCATION}
fi
cp -r ${LIBUV_CACHE_LOCATION}/libuv ${BUILD_DIR}
cat <<EOF >$BUILD_DIR/.profile.d/000_libuv.sh
export LD_LIBRARY_PATH="\$HOME/libuv/lib:\$LD_LIBRARY_PATH"
EOF

curl https://github.com/friism/libuv-builder/releases/download/v${LIBUV_VERSION}/libuv-${LIBUV_VERSION}.tar.gz -sL \
| tar xz -C ${BUILD_DIR}
# TODO: read Procfile from `commands` in project.json
if [ -e ${SRC_DIR}/Procfile ]; then
cp ${SRC_DIR}/Procfile ${BUILD_DIR}
else
ROOTS=`cd ${BUILD_DIR}; find approot/packages/ -name root`
if [ $( echo "${ROOTS}" | wc -l ) -gt 0 ]; then
APP_ROOT=$(echo "$ROOTS" | head -1)
cat << EOT >> ${BUILD_DIR}/Procfile
web: ./kestrel --server.urls http://+:\$PORT
web: ASPNETCORE_URLS='http://+:\$PORT' dotnet ./app.dll --urls http://+:\$PORT
EOT
fi
fi
2 changes: 1 addition & 1 deletion bin/detect
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# bin/detect <build-dir>

if [ -n "$( find $1 -maxdepth 3 -iname project.json )" ]; then
echo "ASP.NET 5" && exit 0
echo ".NET Core" && exit 0
else
echo "no" && exit 1
fi
2 changes: 1 addition & 1 deletion bin/util
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function conditional_download() {

function export_env_dir() {
local env_dir=$1
local whitelist_regex=${2:-'(DEPENDENCY_S3_BUCKET_PATH|MONO_VERSION|LIBUV_VERSION|NODE_VERSION|PROJECT|BUILD_DEBUG|DNVM_BRANCH|DNX_VERSION)$'}
local whitelist_regex=${2:-'(LIBUV_VERSION|NODEJS_VERSION|DOTNET_SDK_VERSION|DOTNET_RUNTIME_VERSION|PROJECT|LIBUNWIND_VERSION)$'}
local blacklist_regex=${3:-'^(PATH|GIT_DIR|CPATH|CPPATH|LD_PRELOAD|LIBRARY_PATH)$'}
if [ -d "$env_dir" ]; then
for e in $(ls $env_dir); do
Expand Down