├── .gitmodules ├── LICENSE ├── README.md └── bin ├── compile ├── detect ├── release ├── steps ├── clang ├── hooks │ ├── post_compile │ └── pre_compile ├── libatomic-install ├── slug-cleanup ├── swift ├── swift-build ├── swift-install └── swiftenv └── utils /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "swiftenv"] 2 | path = swiftenv 3 | url = http://github.com/kylef/swiftenv 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Kyle Fuller 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of heroku-buildpack-swift nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Heroku buildpack: swift 2 | 3 | This buildpack is not recommended for use. Instead consider using [Heroku's container runtime](https://devcenter.heroku.com/articles/container-registry-and-runtime) along with the [Swift container images](https://swift.org/download/). 4 | 5 | For example a Dockerfile: 6 | 7 | ```dockerfile 8 | FROM docker.io/swift:5.5 as build 9 | 10 | WORKDIR /usr/src/app 11 | 12 | COPY Package.swift Package.resolved ./ 13 | COPY Sources Sources 14 | COPY Tests Tests 15 | RUN swift build --configuration release 16 | RUN swift test --configuration release 17 | 18 | 19 | FROM docker.io/swift:5.5-slim 20 | 21 | # Copy the build executable target (named in Package.swift) 22 | COPY --from=build /usr/src/app/.build/release/server . 23 | CMD ./server $PORT 24 | ``` 25 | 26 | Build and push the image to Heroku's registry: 27 | 28 | ```shell 29 | $ heroku container:push web 30 | ``` 31 | 32 | Then release the image: 33 | 34 | ```shell 35 | $ heroku container:release web 36 | ``` 37 | 38 | ## Buildpack Usage 39 | 40 | For historical purposes, below are the usage for the buildpack. Although its use is discouraged. 41 | 42 | Example usage: 43 | 44 | ```shell 45 | $ ls 46 | Procfile Package.swift Sources 47 | 48 | $ heroku create --buildpack kyle/swift 49 | 50 | $ git push heroku master 51 | remote: -----> Swift app detected 52 | remote: -----> Installing Swift 4.1 53 | remote: -----> Installing clang-3.7.0 54 | remote: -----> Building Package 55 | remote: -----> Copying binaries to 'bin' 56 | ``` 57 | 58 | You can also add it to upcoming builds of an existing application: 59 | 60 | ```shell 61 | $ heroku buildpacks:set kyle/swift 62 | ``` 63 | 64 | The buildpack will detect your app as Swift if it has a `Package.swift` file in 65 | the root. 66 | 67 | ### Procfile 68 | 69 | Using the Procfile, you can set the process to run for your web server. Any 70 | binaries built from your Swift source using swift package manager will 71 | be placed in your $PATH. 72 | 73 | ```swift 74 | web: HelloWorld --workers 3 --bind 0.0.0.0:$PORT 75 | ``` 76 | 77 | ### Specify a Swift version 78 | 79 | You can also customise the version of Swift used with a `.swift-version` file 80 | in your repository: 81 | 82 | ```shell 83 | $ cat .swift-version 84 | 4.1 85 | ``` 86 | 87 | The `.swift-version` file is completely compatible with 88 | [swiftenv](http://github.com/kylef/swiftenv). 89 | 90 | **NOTE**: *Since there are frequent Swift language changes, it's advised that 91 | you pin to your Swift version.* 92 | 93 | ### Hooks 94 | 95 | You can place custom scripts to be ran before and after compiling your Swift 96 | source code inside the following files in your repository: 97 | 98 | - `bin/pre_compile` 99 | - `bin/post_compile` 100 | 101 | This is useful if you would need to install any other dependencies. 102 | 103 | ### Using the latest buildpack code 104 | 105 | The `kyle/swift` buildpack from the [Heroku Registry](https://devcenter.heroku.com/articles/buildpack-registry) represents the latest stable version of the buildpack. If you'd like to use the latest buildpack code from this Github repository, you can set your buildpack to the GitHub URL: 106 | 107 | ```shell 108 | $ heroku buildpacks:set https://github.com/kylef/heroku-buildpack-swift 109 | ``` 110 | -------------------------------------------------------------------------------- /bin/compile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # bin/compile 3 | 4 | set -e 5 | set -o pipefail 6 | 7 | BIN_DIR=$(cd $(dirname $0); pwd) 8 | ROOT_DIR=$(dirname $BIN_DIR) 9 | 10 | BUILD_DIR=$1 11 | CACHE_DIR=$2 12 | ENV_DIR=$3 13 | 14 | DEFAULT_SWIFT_VERSION="4.1" 15 | CLANG_VERSION=3.7.0 16 | SWIFT_BUILD_CONFIGURATION="release" 17 | SWIFT_BUILD_FLAGS="" 18 | SWIFT_BUILD_PATH="$CACHE_DIR/.build" 19 | 20 | if [ -f "$ENV_DIR/SWIFT_BUILD_CONFIGURATION" ]; then 21 | SWIFT_BUILD_CONFIGURATION=`cat "$ENV_DIR/SWIFT_BUILD_CONFIGURATION"` 22 | fi 23 | if [ -f "$ENV_DIR/SWIFT_BUILD_FLAGS" ]; then 24 | SWIFT_BUILD_FLAGS=`cat "$ENV_DIR/SWIFT_BUILD_FLAGS"` 25 | fi 26 | 27 | mkdir -p "$CACHE_DIR" 28 | 29 | source "$BIN_DIR/utils" 30 | source "$BIN_DIR/steps/swiftenv" 31 | source "$BIN_DIR/steps/swift" 32 | source "$BIN_DIR/steps/clang" 33 | source "$BIN_DIR/steps/hooks/pre_compile" 34 | source "$BIN_DIR/steps/swift-build" 35 | source "$BIN_DIR/steps/swift-install" 36 | source "$BIN_DIR/steps/libatomic-install" 37 | source "$BIN_DIR/steps/slug-cleanup" 38 | 39 | # Setup application environment 40 | mkdir -p $BUILD_DIR/.profile.d 41 | 42 | set-env PATH '$HOME/.swift-bin:$PATH' 43 | set-env LD_LIBRARY_PATH '$LD_LIBRARY_PATH:$HOME/.swift-lib' 44 | 45 | source "$BIN_DIR/steps/hooks/post_compile" 46 | -------------------------------------------------------------------------------- /bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # bin/detect 3 | 4 | if [[ -f $1/Package.swift ]]; then 5 | echo "Swift" && exit 0 6 | else 7 | echo "no" && exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /bin/release: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # bin/release 3 | 4 | echo "--- {}" 5 | -------------------------------------------------------------------------------- /bin/steps/clang: -------------------------------------------------------------------------------- 1 | if [[ ! -d "$CACHE_DIR/clang-$CLANG_VERSION" ]]; then 2 | cd $CACHE_DIR 3 | puts-step "Installing clang-$CLANG_VERSION" 4 | mkdir -p "clang-$CLANG_VERSION" 5 | curl http://llvm.org/releases/$CLANG_VERSION/clang+llvm-$CLANG_VERSION-x86_64-linux-gnu-ubuntu-14.04.tar.xz -s -L | xz -d -c | tar x -C clang-$CLANG_VERSION &> /dev/null 6 | cd $BUILD_DIR 7 | fi 8 | 9 | export PATH="$CACHE_DIR/clang-$CLANG_VERSION/clang+llvm-$CLANG_VERSION-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH" 10 | -------------------------------------------------------------------------------- /bin/steps/hooks/post_compile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -f bin/post_compile ]; then 4 | echo "-----> Running post-compile hook" 5 | chmod +x bin/post_compile 6 | ./bin/post_compile 7 | fi 8 | -------------------------------------------------------------------------------- /bin/steps/hooks/pre_compile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -f bin/pre_compile ]; then 4 | echo "-----> Running pre-compile hook" 5 | chmod +x bin/pre_compile 6 | ./bin/pre_compile 7 | fi 8 | -------------------------------------------------------------------------------- /bin/steps/libatomic-install: -------------------------------------------------------------------------------- 1 | # Heroku 16 stack is missing `libatomic` from runtime lets copy over 2 | 3 | if [ "$STACK" = "heroku-16" ]; then 4 | cp "/usr/lib/x86_64-linux-gnu/libatomic.so.1" "$BUILD_DIR/.swift-lib" 5 | fi 6 | -------------------------------------------------------------------------------- /bin/steps/slug-cleanup: -------------------------------------------------------------------------------- 1 | # Remove unnnessecary files from being included in the slug 2 | 3 | remove() { 4 | if [ -r "$1" ]; then 5 | rm -fr "$1" 6 | fi 7 | } 8 | 9 | remove "$BUILD_DIR/Package.swift" 10 | remove "$BUILD_DIR/Package.resolved" 11 | remove "$BUILD_DIR/Sources" 12 | remove "$BUILD_DIR/Tests" 13 | -------------------------------------------------------------------------------- /bin/steps/swift: -------------------------------------------------------------------------------- 1 | # Install Swift 2 | cd "$BUILD_DIR" 3 | SWIFT_PREFIX="$(swiftenv prefix || true)" 4 | if ! [ -d "$SWIFT_PREFIX" ]; then 5 | VERSION="$(env DONT_CHECK=true swiftenv version-name)" 6 | puts-step "Installing $VERSION" 7 | swiftenv install 8 | fi 9 | -------------------------------------------------------------------------------- /bin/steps/swift-build: -------------------------------------------------------------------------------- 1 | cd $BUILD_DIR 2 | puts-step "Building Package" 3 | swift build $SWIFT_BUILD_FLAGS --configuration "$SWIFT_BUILD_CONFIGURATION" --build-path "$SWIFT_BUILD_PATH" 4 | -------------------------------------------------------------------------------- /bin/steps/swift-install: -------------------------------------------------------------------------------- 1 | puts-step "Installing dynamic libraries" 2 | mkdir -p $BUILD_DIR/.swift-lib 3 | SWIFT_PREFIX="$(swiftenv prefix)" 4 | cp $SWIFT_PREFIX/usr/lib/swift/linux/*.so $BUILD_DIR/.swift-lib 5 | find "$SWIFT_BUILD_PATH/$SWIFT_BUILD_CONFIGURATION/" -name '*.so' -type f -exec cp {} $BUILD_DIR/.swift-lib \; 6 | 7 | puts-step "Installing binaries" 8 | mkdir -p "$BUILD_DIR/.swift-bin" 9 | find "$SWIFT_BUILD_PATH/$SWIFT_BUILD_CONFIGURATION/" ! -name '*.so' -type f -perm /a+x -exec cp {} $BUILD_DIR/.swift-bin \; 10 | -------------------------------------------------------------------------------- /bin/steps/swiftenv: -------------------------------------------------------------------------------- 1 | # Fetch swiftenv 2 | unset GIT_DIR 3 | git submodule update --init --recursive >/dev/null 4 | 5 | # Activate swiftenv 6 | export SWIFTENV_ROOT="$CACHE_DIR/swiftenv" 7 | export PATH="$ROOT_DIR/swiftenv/bin:$PATH" 8 | eval "$(swiftenv init -)" 9 | 10 | if ! [ -f "$BUILD_DIR/.swift-version" ] && [ -z "$SWIFT_VERSION" ]; then 11 | export SWIFT_VERSION="$DEFAULT_SWIFT_VERSION" 12 | fi 13 | -------------------------------------------------------------------------------- /bin/utils: -------------------------------------------------------------------------------- 1 | puts-step() { 2 | echo "-----> $@" 3 | } 4 | 5 | set-env() { 6 | PROFILE_PATH="$BUILD_DIR/.profile.d/swift.sh" 7 | echo "export $1=$2" >> $PROFILE_PATH 8 | } 9 | --------------------------------------------------------------------------------