diff --git a/.travis.yml b/.travis.yml index 2564626..c0e4cf8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/README.md b/README.md index 7046de4..0807da2 100644 --- a/README.md +++ b/README.md @@ -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)
By default the release is `latest`.
By default target directory is `~/.builder`.
-By default builds are executed in docker.
+By default builds are executed in Docker.
By default docker container is named is a sanitized version of the working path.
+By default Go project auto-detection is enabled; for large non-Go projects this may be slow.
+By default [JDK Wrapper](https://github.com/KoskiLabs/jdk-wrapper) auto-detection is enabled.
By default the build script does not log. Prerequisites diff --git a/build-impl.sh b/build-impl.sh index d040633..f92c8dd 100755 --- a/build-impl.sh +++ b/build-impl.sh @@ -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"