From 86e034605a00c80837e23d38ca10f12685b75be4 Mon Sep 17 00:00:00 2001 From: Piyush Mishra Date: Sun, 21 Feb 2021 11:20:54 +0530 Subject: [PATCH] heroku --- .travis.yml | 8 +++ bin/compile | 152 ++++++++++++++++++++++++++++++++++++++++ bin/detect | 8 +++ docker-compose-test.yml | 12 ++++ test_buildpack | 17 +++++ 5 files changed, 197 insertions(+) create mode 100644 .travis.yml create mode 100755 bin/compile create mode 100755 bin/detect create mode 100644 docker-compose-test.yml create mode 100755 test_buildpack diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7cdb7e8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +os: "linux" +sudo: "required" +services: +- "docker" +script: +# Test both pristine and cached deploys. +- "./test_buildpack" +- "./test_buildpack" diff --git a/bin/compile b/bin/compile new file mode 100755 index 0000000..5fc3983 --- /dev/null +++ b/bin/compile @@ -0,0 +1,152 @@ +#!/bin/bash + +# Find all the directories we might need (based on +# heroku-buildpack-nodejs code). +BUILD_DIR=${1:-} +CACHE_DIR=${2:-} +ENV_DIR=${3:-} +BP_DIR=$(cd $(dirname ${0:-}); cd ..; pwd) + +# Export DATABASE_URL at build time, mostly because Diesel is the best way to +# do SQL in Rust right now, and Diesel will use it to generate code for the +# database schema. +if [ -e "$ENV_DIR/DATABASE_URL" ]; then + export DATABASE_URL="$(cat $ENV_DIR/DATABASE_URL)"; +fi + +# Set defaults for our configuration variables. Stable Rust is sufficiently +# stable at this point that I think we can just default it. +VERSION=stable + +# Set this to "1" in `RustConfig` to just install a Rust toolchain and not +# build `Cargo.toml`. This is useful if you have a project written in Ruby +# or Node (for example) that needs to build extension modules using Rust. +RUST_SKIP_BUILD=0 +# If your Rust code is not at the root directory of the repository, specify a +# `BUILD_PATH` to the correct directory in the `RustConfig` +BUILD_PATH="" +# Set this to "1" in `RustConfig` to install diesel at build time and copy it +# into the target directory, next to your app binary. This makes it easy to +# run migrations by adding a release step to your Procfile: +# `release: ./target/release/diesel migration run` +RUST_INSTALL_DIESEL=0 +# These flags are passed to `cargo install diesel`, e.g. '--no-default-features --features postgres' +DIESEL_FLAGS="" +# Default build flags to pass to `cargo build`. +RUST_CARGO_BUILD_FLAGS="--release" + +# Load our toolchain configuration, if any was specified. +if [ -f "$BUILD_DIR/rust-toolchain" ]; then + VERSION="$(cat "$BUILD_DIR/rust-toolchain")" +fi + +# Load our configuration variables, if any were specified. +if [ -f "$BUILD_DIR/RustConfig" ]; then + . "$BUILD_DIR/RustConfig" +fi + +# Standard paranoia. +set -eu + +# Check our configuration options. +if [ -z ${VERSION+x} ]; then + >&2 echo "failed: must set VERSION with rust-toolchain or RustConfig to indicate the Rust version." + exit 1 +fi + +# Notify users running old, unstable versions of Rust about how to deploy +# successfully. +if [ $RUST_SKIP_BUILD -ne 1 ] && ( [ ! -z ${CARGO_URL+x} ] || [ ! -f "$BUILD_DIR/$BUILD_PATH/Cargo.toml" ] ); then + >&2 cat <&2 cat < $BP_DIR/export +# Our rustup installation. +export RUSTUP_HOME="$CACHE_DIR/multirust" + +# Our cargo installation. We implicitly trust Rustup and Cargo +# to do the right thing when new versions are released. +export CARGO_HOME="$CACHE_DIR/cargo" + +# Include binaries installed by cargo and rustup in our path. +PATH="\$CARGO_HOME/bin:\$PATH" +EOF + +# Read our build environment back in and evaluate it so that we can use it. +. $BP_DIR/export + +# Switch to our cache directory. +mkdir -p "$CACHE_DIR" +cd "$CACHE_DIR" + +# Make sure we have an appropriate Rust toolchain installed. +if [ -d "$CARGO_HOME" ]; then + echo "-----> Checking for new releases of Rust $VERSION channel" + # It's possible that $VERSION has changed, or the `stable` channel has updated. + rustup self update + rustup update "$VERSION" + rustup default "$VERSION" +else + echo "-----> Downloading rustup" + curl https://sh.rustup.rs -sSf > rustup.sh + chmod u+x rustup.sh + echo "-----> Using rustup to install Rust channel $VERSION" + ./rustup.sh -y --default-toolchain "$VERSION" + rm rustup.sh +fi +if [ ! -x "$CARGO_HOME/bin/rustc" ]; then + echo "failed: Cannot find Rust binaries at $CARGO_HOME" + exit 1 +fi + +# This is where we will cache our Rust output. Note the suggestions at +# https://github.com/alexcrichton/cargo/commit/014765f788ca1c2476936835ca32cc2746f99b42 +# which describe how this needs to be named. +export CARGO_TARGET_DIR="$CACHE_DIR/target" + +if [ $RUST_SKIP_BUILD -ne 1 ]; then + # Build our project (into CARGO_TARGET_DIR so we have caching) and copy it + # back to the source tree. In theory, we could probably just copy the + # binary or do something clever with `cargo install`, but we haven't + # figured that out yet. + # + # To debug git issues: + #export RUST_LOG="cargo::sources::git=debug" + # To debug compiler and linking issues, add `--verbose`. + echo "-----> Building application using Cargo" + cd "$BUILD_DIR/$BUILD_PATH" + rm -rf target/ + cargo build $RUST_CARGO_BUILD_FLAGS + mkdir -p target/release + find "$CARGO_TARGET_DIR/release" -maxdepth 1 -type f -executable -exec cp -a -t target/release {} \; +else + echo "-----> Skipping Cargo build" +fi + +# Install diesel so we can use it for migrations +if [ $RUST_INSTALL_DIESEL -eq 1 ]; then + echo "-----> Installing diesel" + cargo install diesel_cli $DIESEL_FLAGS || echo "already installed" + cp $(which diesel) target/release/ +fi diff --git a/bin/detect b/bin/detect new file mode 100755 index 0000000..fba4b47 --- /dev/null +++ b/bin/detect @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ -f "$1/RustConfig" ] || [ -f "$1/rust-toolchain" ] || [ -f "$1/Cargo.toml" ]; then + echo "Rust" + exit 0 +else + exit 1 +fi diff --git a/docker-compose-test.yml b/docker-compose-test.yml new file mode 100644 index 0000000..cfe37f8 --- /dev/null +++ b/docker-compose-test.yml @@ -0,0 +1,12 @@ +# This is called from ./test_buildpack. +version: "2" +services: + testbuild: + image: "heroku/cedar" + volumes: + - ".:/src" + working_dir: "/src" + environment: + HOME: "/src" + user: "$UID:$GROUPS" + command: ["bin/compile", "/src/rust-buildpack-example-actix", "/src/cache"] diff --git a/test_buildpack b/test_buildpack new file mode 100755 index 0000000..535293b --- /dev/null +++ b/test_buildpack @@ -0,0 +1,17 @@ +#!/bin/bash + +# Standard paranoia. The `-e` is critical if we want failed tests to be +# reported on Travis. +set -euo pipefail + +# Get an example program for testing if we don't have one yet. +if [ ! -d ./rust-buildpack-example-actix ]; then + git clone https://github.com/emk/rust-buildpack-example-actix.git +fi + +# Export the current UID so that our child processes can see it. This will +# be used as a parameter in our `docker-compose-test.yml` file. +export UID GROUPS + +# Run the build in a Heroku-like environment using `docker-compose`. +docker-compose -f docker-compose-test.yml up