├── .gitignore ├── .travis.yml ├── .travis ├── attach-binary.sh ├── install-ghr.sh └── install-stack.sh ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-* 3 | cabal-dev 4 | *.o 5 | *.hi 6 | *.chi 7 | *.chs.h 8 | *.dyn_o 9 | *.dyn_hi 10 | .hpc 11 | .hsenv 12 | .cabal-sandbox/ 13 | cabal.sandbox.config 14 | *.prof 15 | *.aux 16 | *.hp 17 | *.eventlog 18 | .stack-work/ 19 | cabal.project.local 20 | .HTF/ 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/commercialhaskell/stack 2 | language: nix 3 | sudo: false 4 | 5 | cache: 6 | directories: 7 | - $HOME/.ghc 8 | - $HOME/.cabal 9 | - $HOME/.stack 10 | - .stack-work 11 | 12 | matrix: 13 | fast_finish: true 14 | include: 15 | # Add build targets here 16 | - env: GHCVER=8.0.2 CACHE_NAME=8.0.2 17 | compiler: ": #stack 8.0.2" 18 | addons: {apt: {packages: [ghc-8.0.2], sources: [hvr-ghc]}} 19 | 20 | - env: GHCVER=8.2.1 CACHE_NAME=8.2.1 BUILD_BINARY=1 21 | compiler: ": #stack 8.2.1" 22 | addons: {apt: {packages: [ghc-8.2.1], sources: [hvr-ghc]}} 23 | 24 | - env: GHCVER=8.2.1 CACHE_NAME=8.2.1-osx BUILD_BINARY=1 25 | os: osx 26 | compiler: ": #stack 8.2.1" 27 | addons: {apt: {packages: [ghc-8.2.1], sources: [hvr-ghc]}} 28 | 29 | install: 30 | - unset CC 31 | - export PATH=$HOME/.local/bin:/opt/ghc/$GHCVER/bin:$PATH 32 | - ./.travis/install-ghr.sh 33 | - ./.travis/install-stack.sh 34 | 35 | script: 36 | - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]" 37 | - GHC_OPTIONS="-Werror" 38 | - | 39 | set -ex 40 | # Run tests 41 | stack --no-terminal test --ghc-options="$GHC_OPTIONS" 42 | set +ex 43 | 44 | after_success: 45 | - | 46 | # Build and ship binary 47 | ./.travis/attach-binary.sh 48 | -------------------------------------------------------------------------------- /.travis/attach-binary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -o errexit -o verbose 3 | 4 | if test ! "$BUILD_BINARY" || test ! "$TRAVIS_TAG" 5 | then 6 | echo 'This is not a release build.' 7 | elif test ! "$GITHUB_TOKEN" 8 | then 9 | echo 'The GITHUB_TOKEN environment variable is not set!' 10 | exit 1 11 | else 12 | echo "Building binary for $TRAVIS_OS_NAME to $TRAVIS_TAG..." 13 | stack build --ghc-options -O2 --pedantic 14 | echo "Attaching binary for $TRAVIS_OS_NAME to $TRAVIS_TAG..." 15 | OWNER="$(echo "$TRAVIS_REPO_SLUG" | cut -f1 -d/)" 16 | REPO="$(echo "$TRAVIS_REPO_SLUG" | cut -f2 -d/)" 17 | BIN="$(stack path --local-install-root)/bin/$REPO" 18 | BUNDLE_NAME="$REPO-$TRAVIS_TAG-$TRAVIS_OS_NAME.tar.gz" 19 | cp "$BIN" "./$REPO" 20 | chmod +x "./$REPO" 21 | tar -czf "$BUNDLE_NAME" "$REPO" 22 | echo "SHA256:" 23 | shasum -a 256 "$BUNDLE_NAME" 24 | ghr -t "$GITHUB_TOKEN" -u "$OWNER" -r "$REPO" --replace "$(git describe --tags)" "$BUNDLE_NAME" 25 | fi 26 | -------------------------------------------------------------------------------- /.travis/install-ghr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -o errexit -o verbose 3 | 4 | if test ! "$BUILD_BINARY" || test ! "$TRAVIS_TAG" 5 | then 6 | echo 'This is not a release build.' 7 | else 8 | if [ "$TRAVIS_OS_NAME" = "linux" ] 9 | then 10 | ARCH="linux" 11 | else 12 | ARCH="darwin" 13 | fi 14 | echo "Installing ghr" 15 | URL="https://github.com/tcnksm/ghr/releases/download/v0.5.4/ghr_v0.5.4_${ARCH}_386.zip" 16 | curl -L ${URL} > ghr.zip 17 | mkdir -p "$HOME/bin" 18 | export PATH="$HOME/bin:$PATH" 19 | unzip ghr.zip -d "$HOME/bin" 20 | rm ghr.zip 21 | fi 22 | -------------------------------------------------------------------------------- /.travis/install-stack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Adapted from https://github.com/commercialhaskell/stack 4 | 5 | set -eux 6 | 7 | travis_retry() { 8 | cmd=$* 9 | $cmd || (sleep 2 && $cmd) || (sleep 10 && $cmd) 10 | } 11 | 12 | fetch_stack_osx() { 13 | curl -skL https://www.stackage.org/stack/osx-x86_64 | tar xz --strip-components=1 --include '*/stack' -C ~/.local/bin; 14 | } 15 | 16 | fetch_stack_linux() { 17 | curl -sL https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'; 18 | } 19 | 20 | # We need stack to generate cabal files with precise bounds, even for cabal 21 | # builds. 22 | mkdir -p ~/.local/bin; 23 | if [ "$(uname)" = "Darwin" ]; then 24 | travis_retry fetch_stack_osx 25 | else 26 | travis_retry fetch_stack_linux 27 | fi 28 | 29 | travis_retry stack --no-terminal setup; 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, Chris Penner 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # haskell-stack-travis-ci 2 | Dead simple setup tools for running a Haskell build matrix using stack for several versions. 3 | 4 | Scripts are adapted from those used for [haskell stack's build process](https://github.com/commercialhaskell/stack); as well as stealing a bit of [@tfausak's](https://github.com/tfausak) workflow. 5 | 6 | To test builds for a Haskell project using [stack](https://github.com/commercialhaskell/stack): 7 | 8 | - `cp haskell-stack-travis-ci/.travis* my-project/` 9 | - Optionally add/remove GHC version build matrix targets inside `.travis.yml`. 10 | - For Libraries without binaries remove `BUILD_BINARY=1` from `.travis.yml` in the build matrix. 11 | - ...? 12 | - Profit 13 | 14 | # Building and shipping binaries: 15 | - Set the `BUILD_BINARY=1` environment variable for each variation in the build matrix you want to ship. 16 | - Set a `GITHUB_TOKEN` environment variable for your project's builds in TravisCI; you can [create a token here](https://github.com/settings/tokens). 17 | - For a public repo select the `public_repo` scope 18 | - For a private repo select the `repo` scope 19 | --------------------------------------------------------------------------------