Skip to content
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
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ services:
script:
- pushd ./examples/maven-centos && ../../build-impl.sh clean install && popd
- pushd ./examples/maven-alpine && ../../build-impl.sh clean install && popd
- pushd ./examples/gradle && ../../build-impl.sh clean build && popd
- pushd ./examples/sbt && ../../build-impl.sh clean package && popd
- pushd ./examples/npm && ../../build-impl.sh build && popd
- pushd ./examples/go && ../../build-impl.sh build -o bin/hello-world && popd
Expand Down
96 changes: 71 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,50 +23,96 @@ Provides build isolation through Docker with automatic detection for common buil
Quick Start
-----------

<>
1) Download `build` script from the [latest release](https://github.com/Koskilabs/builder/releases/latest) script into your project in the directory where you execute your build from (typically the project root directory).

2) Make the `build` script executable (e.g. `chmod +x build`).

3) Create a `.build` file in the same directory as the `build` script.

4) Populate the `.build` with at least the contents from the table below for your build tool.

5) Execute your build by invoking `build` and passing it your usual build tool arguments for your build tool.

Build Tool | `.build` Contents | Build Command
------------ | -------------------------------- | -------------
Maven | BUILD_DOCKER_IMAGE=centos:latest | `./build clean verify`
Gradle | BUILD_DOCKER_IMAGE=centos:latest | `./build clean build`
SBT | BUILD_DOCKER_IMAGE=centos:latest | `./build clean package`
NPM | BUILD_DOCKER_IMAGE=node:latest | `./build build`
Go | BUILD_DOCKER_IMAGE=golang:latest | `./build build`

If your build tool is not listed above then it will not be auto detected. Feel free to file an issue against the
project. However, in the meantime you can specify your build tool manually; specifically, the command to run by
adding the `BUILD_TOOL` property into your `.build` file (e.g. `BUILD_TOOL="make"`).

For Maven, Gradle and SBT projects wishing to use a smaller Alpine based build image check out
[koskilabs/builder-alpine](https://hub.docker.com/r/koskilabs/builder-alpine/) image.

In general, you control your project's build execution environment via `BUILD_DOCKER_IMAGE` to provide the required
dependencies for your project's build. You may also specify the Docker registry via `BUILD_DOCKER_REGISTRY`.

More information on customizing the build can be found in the next section.

Usage
-----

Finally, any combination of these four forms of configuration is permissible. The order of precedence for configuration from highest to lowest is:
The builder may be configured by any combination of these four forms of configuration is permissible. The
order of precedence for configuration from highest to lowest is:

1) Command Line
2) .build (working directory)
3) ~/.build (home directory)
4) Environment

The only required configuration setting is `BUILD_DOCKER_IMAGE` which must be set the Docker image name and
optional tag separated by a colon (e.g. `NAME[:TAG]`).

By default the build script attempts to auto-detect the build tool based on the contents of the project. The
auto detection will set the command to execute (`BUILD_TOOL`), any arguments always passed to it (`BUILD_ARGUMENTS`)
and any values present in the environment (`BUILD_ENVIRONMENT`).

You can then invoke `./build` and pass it any additional arguments you wish to supply to your build tool.

The default auto-detection behavior is disabled if you specify `BUILD_TOOL`.

If you wish to only augment the arguments or environment that are always passed and set, you should not
disable auto detection but instead use `BUILD_ADDITIONAL_ARGUMENTS` and `BUILD_ADDITIONAL_ENVIRONMENT`.

### Configuration

* BUILD_DOCKER_IMAGE :
* BUILD_DOCKER_REGISTRY :
* BUILD_ADDITIONAL_ARGUMENTS :
* BUILD_ADDITIONAL_ENVIRONMENT
* BUILD_TOOL :
* BUILD_ARGUMENTS :
* BUILD_ENVIRONMENT :
* BUILD_EXPOSED_PORTS :
* BUILD_DOCKER_ARGS :
* BUILD_RELEASE : Version of Build (e.g. 0.1.0 or latest). Optional.
* BUILD_DOCKER_IMAGE : The name and tag separated by a colon of the Docker image to build in. Required.
* BUILD_DOCKER_REGISTRY : The address of the registry to use. Optional.
* BUILD_ADDITIONAL_ARGUMENTS : Any arguments to always pass to the build tool in addition to auto-detected ones. Optional.
* BUILD_ADDITIONAL_ENVIRONMENT : Any values to always set in the environment in addition to auto-detected ones. Optional.
* BUILD_TOOL : The command to execute for the build. Auto detected. Optional.
* BUILD_ARGUMENTS : The arguments to always pass to the build tool. Auto detected. Optional.
* BUILD_ENVIRONMENT : The values to always set in the environment. Auto detected. Optional.
* BUILD_EXPOSED_PORTS : Any port mappings for Docker (e.g. `8080:80`). Optional.
* BUILD_DOCKER_ARGS : Any additional arguments for Docker. Optional.
* BUILD_RELEASE : Version of Build (e.g. `0.1.0` or `latest`). Optional.
* BUILD_TARGET : Directory to store build scripts (e.g. '/var/tmp'). Optional.
* BUILD_FORCE_NATIVE : Force the build to run in the current environment. Optional.
* BUILD_FORCE_NATIVE : Force the build to run in the current environment and not wrapped in a Docker invocation. Optional.
* BUILD_CONTAINER_NAME : Name given to the docker container. Optional.
* BUILD_LOCAL_HOST_IP :
* BUILD_LOCAL_DIRECTORY :
* BUILD_CACHE_ROOT :
* BUILD_SOURCE_CACHE_ROOT :
* BUILD_CACHE_PROJECT :
* BUILD_CACHE_MAVEN :
* BUILD_CACHE_IVY :
* BUILD_CACHE_SBT :
* BUILD_CACHE_GRADLE :
* BUILD_DISABLE_GO :
* BUILD_DISABLE_JDK_WRAPPER :
* BUILD_LOCAL_HOST_IP : The IP address of the host running the Docker daemon. Auto detected. Optional.
* BUILD_LOCAL_DIRECTORY : The path of the project on the host running the Docker daemon. Auto detected. Optional.
* BUILD_CACHE_ROOT : The path to the builder cache root. Optional.
* BUILD_CACHE_PROJECT : The path to the project specific cache. Optional.
* BUILD_CACHE_JDK : The [JDK Wrapper](https://github.com/KoskiLabs/jdk-wrapper) cache path. Optional.
* BUILD_CACHE_MAVEN : The path to the project specific Maven cache. Optional.
* BUILD_CACHE_IVY : The path to the project specific Ivy cache. Optional.
* BUILD_CACHE_SBT : The path to the project specific SBT cache. Optional.
* BUILD_CACHE_GRADLE : The path to the project specific Gradle cache. Optional.
* BUILD_DISABLE_GO : Whether to not attempt Go project auto-detection. Optional.
* BUILD_DISABLE_JDK_WRAPPER : Whether to not attempt [JDK Wrapper](https://github.com/KoskiLabs/jdk-wrapper) auto-detection. Optional.
* BUILDER_VERBOSE : Log build actions to standard out. Optional.

By default the Docker registry is [Docker Hub](https://hub.docker.com)<br/>
By default the release is `latest`.<br/>
By default target directory is `~/.builder`.<br/>
By default builds are executed in docker.<br/>
By default builds are executed in Docker.<br/>
By default docker container is named is a sanitized version of the working path.<br/>
By default Go project auto-detection is enabled; for large non-Go projects this may be slow.<br/>
By default [JDK Wrapper](https://github.com/KoskiLabs/jdk-wrapper) auto-detection is enabled.<br/>
By default the build script does not log.

Prerequisites
Expand Down
135 changes: 65 additions & 70 deletions build-impl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -154,87 +154,82 @@ fi
# Build tool auto detection
# NOTE: This happens after loading configuration and defaults to allow those
# values to be used by auto-detection; however, auto-detected values are only
# used if configuration did not specify a value. The auto-detection only sets
# BUILD_TOOL, BUILD_ARGUMENTS and BUILD_ENVIRONMENT.
auto_build_tool=
auto_build_arguments=
auto_build_environment=
if [ -f "pom.xml" ]; then
# Maven Support
log_out "Detected project using Maven build tool"
auto_build_tool="mvn"
auto_build_environment="\"MAVEN_OPTS=-XX:+TieredCompilation -XX:TieredStopAtLevel=1\""
if [ -f "mvnw" ]; then
auto_build_tool="./mvnw"
auto_build_environment="${auto_build_environment} \"MAVEN_USER_HOME=${BUILD_CACHE_MAVEN}\""
fi
common_arguments="-Dmaven.repo.local=${BUILD_CACHE_MAVEN} -DdockerHostIp=${BUILD_LOCAL_HOST_IP} -DdockerHostPath=${BUILD_LOCAL_DIRECTORY}"
if [ -f "settings.xml" ]; then
common_arguments="${common_arguments} --settings settings.xml"
fi
pass_through_arguments="${common_arguments}"
for arg in "$@"; do
if [ -n "${past_build_args}" ]; then
if case "${arg}" in "-D"*) true;; "-P"*) true;; *) false;; esac; then
pass_through_arguments="${pass_through_arguments} ${arg}"
# used if configuration did not specify a value for BUILD_TOOL. In this case
# the auto-detection only sets BUILD_TOOL, BUILD_ARGUMENTS and BUILD_ENVIRONMENT.
if [ -z "${BUILD_TOOL}" ]; then
auto_build_tool=
auto_build_arguments=
auto_build_environment=
if [ -f "pom.xml" ]; then
# Maven Support
log_out "Detected project using Maven build tool"
auto_build_tool="mvn"
auto_build_environment="\"MAVEN_OPTS=-XX:+TieredCompilation -XX:TieredStopAtLevel=1\""
if [ -f "mvnw" ]; then
auto_build_tool="./mvnw"
auto_build_environment="${auto_build_environment} \"MAVEN_USER_HOME=${BUILD_CACHE_MAVEN}\""
fi
common_arguments="-Dmaven.repo.local=${BUILD_CACHE_MAVEN} -DdockerHostIp=${BUILD_LOCAL_HOST_IP} -DdockerHostPath=${BUILD_LOCAL_DIRECTORY}"
if [ -f "settings.xml" ]; then
common_arguments="${common_arguments} --settings settings.xml"
fi
pass_through_arguments="${common_arguments}"
for arg in "$@"; do
if [ -n "${past_build_args}" ]; then
if case "${arg}" in "-D"*) true;; "-P"*) true;; *) false;; esac; then
pass_through_arguments="${pass_through_arguments} ${arg}"
fi
fi
done
auto_build_arguments="-U ${common_arguments} \"-Darguments=${pass_through_arguments}\""
elif [ -f "build.sbt" ]; then
# SBT Support
log_out "Detected project using SBT build tool"
sbt_boot="${BUILD_CACHE_SBT}/boot"
ivy_home="${BUILD_CACHE_IVY}"
auto_build_tool="sbt"
auto_build_arguments="-Dsbt.global.base=${BUILD_CACHE_SBT}/1.0 -Dsbt.boot.directory=${sbt_boot} -Dsbt.ivy.home=${ivy_home}"
if [ -f "repositories" ]; then
auto_build_arguments="${auto_build_arguments} -Dsbt.override.build.repos=true -Dsbt.repository.config=repositories"
fi
if [ -f "sbt" ]; then
auto_build_tool="./sbt"
auto_build_arguments="${auto_build_arguments} -sbt-launch-dir ${BUILD_CACHE_SBT}/launcher -sbt-boot ${sbt_boot} -ivy ${ivy_home}"
fi
elif [ -f "build.gradle" ]; then
# Gradle Support
log_out "Detected project using Gradle build tool"
auto_build_tool="gradle"
auto_build_environment="\"GRADLE_USER_HOME=${BUILD_CACHE_GRADLE}\""
if [ -f "gradlew" ]; then
auto_build_tool="./gradlew"
fi
elif [ -f "package.json" ]; then
# NodeJS Support
log_out "Detected project using NPM build tool"
auto_build_tool="npm"
elif [ -z "${BUILD_DISABLE_GO}" ]; then
if [ "$(find . -type f -name '*.go' | head -n 1 | wc -l)" -gt 0 ]; then
# Go Support
log_out "Detected project using Go build tool"
auto_build_tool="go"
auto_build_environment="\"GOPATH=$(pwd)\" \"GOCACHE=${BUILD_CACHE_GO}\""
fi
done
auto_build_arguments="-U ${common_arguments} \"-Darguments=${pass_through_arguments}\""
elif [ -f "build.sbt" ]; then
# SBT Support
log_out "Detected project using SBT build tool"
sbt_boot="${BUILD_CACHE_SBT}/boot"
ivy_home="${BUILD_CACHE_IVY}"
auto_build_tool="sbt"
auto_build_arguments="-Dsbt.global.base=${BUILD_CACHE_SBT}/1.0 -Dsbt.boot.directory=${sbt_boot} -Dsbt.ivy.home=${ivy_home}"
if [ -f "repositories" ]; then
auto_build_arguments="${auto_build_arguments} -Dsbt.override.build.repos=true -Dsbt.repository.config=repositories"
fi
if [ -f "sbt" ]; then
auto_build_tool="./sbt"
auto_build_arguments="${auto_build_arguments} -sbt-launch-dir ${BUILD_CACHE_SBT}/launcher -sbt-boot ${sbt_boot} -ivy ${ivy_home}"
fi
elif [ -f "build.gradle" ]; then
# Gradle Support
log_out "Detected project using Gradle build tool"
auto_build_tool="gradle"
auto_build_environment="\"GRADLE_USER_HOME=${BUILD_CACHE_GRADLE}\""
if [ -f "gradlew" ]; then
auto_build_tool="./gradlew"
fi
elif [ -f "package.json" ]; then
# NodeJS Support
log_out "Detected project using NPM build tool"
auto_build_tool="npm"
elif [ -z "${BUILD_DISABLE_GO}" ]; then
if [ "$(find . -type f -name '*.go' | head -n 1 | wc -l)" -gt 0 ]; then
# Go Support
log_out "Detected project using Go build tool"
auto_build_tool="go"
auto_build_environment="\"GOPATH=$(pwd)\" \"GOCACHE=${BUILD_CACHE_GO}\""
fi

BUILD_TOOL="${auto_build_tool}"
BUILD_ARGUMENTS="${auto_build_arguments}"
BUILD_ENVIRONMENT="${auto_build_environment}"
fi

# JDK Wrapper Support
if [ -z "${BUILD_DISABLE_JDK_WRAPPER}" ]; then
if [ -f "jdk-wrapper.sh" ]; then
auto_build_tool="./jdk-wrapper.sh ${auto_build_tool}"
auto_build_environment="${auto_build_environment} \"JDKW_TARGET=${BUILD_CACHE_JDK}\""
BUILD_TOOL="./jdk-wrapper.sh ${BUILD_TOOL}"
BUILD_ENVIRONMENT="${BUILD_ENVIRONMENT} \"JDKW_TARGET=${BUILD_CACHE_JDK}\""
fi
fi

# Apply auto detected settings
if [ -z "${BUILD_TOOL}" ]; then
BUILD_TOOL="${auto_build_tool}"
fi
if [ -z "${BUILD_ARGUMENTS}" ]; then
BUILD_ARGUMENTS="${auto_build_arguments}"
fi
if [ -z "${BUILD_ENVIRONMENT}" ]; then
BUILD_ENVIRONMENT="${auto_build_environment}"
fi

# Check required configuration
if [ -z "${BUILD_TOOL}" ]; then
log_err "ERROR: No value specified or discovered for BUILD_TOOL"
Expand Down