# packcheck: Universal build and CI testing for Haskell packages

[ bsd3, ci, library, testing ] [ Propose Tags ]

This package contains a universal CI/build script packcheck.sh and config files designed such that you can just copy over .travis.yml, appveyor.yml or .circleci/config.yml to your package repo and your package is CI ready in a jiffy. You can build and test packages on local machine as well. For local testing, copy packcheck.sh to your local machine, put it in your PATH, and run it from your package directory:

$packcheck.sh cabal-v2$ packcheck.sh stack

You can try the script on this package itself. It builds and comprehensively sanity tests a Haskell package across build tools (stack/cabal), uniformly, consistently and across all platforms (Linux/MacOS/Windows). You do not need to be familiar with any of the build tools to use it.

This is also a minimal yet complete model package (with tests, benchmarks, CI already working) that can be used as a starting point to develop a new package. Beginners can use it to learn about haskell package metadata structure, benchmarks, tests, CI configs etc.

See the README for comprehensive documentation.

## Modules

[Index] [Quick Jump]

## Flags

### Manual Flags

NameDescriptionDefault
dev

Development build

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

#### Maintainer's Corner

For package maintainers and hackage trustees

Candidates

• No Candidates
Versions [RSS] 0.1.0, 0.1.1, 0.2.0, 0.3.0, 0.3.1, 0.4.0, 0.4.1, 0.4.2, 0.5.0, 0.5.1, 0.6.0 Changelog.md base (>=4.8 && <5) [details] BSD-3-Clause 2017 Harendra Kumar Harendra Kumar harendra.kumar@gmail.com Testing, CI https://github.com/composewell/packcheck https://github.com/composewell/packcheck/issues head: git clone https://github.com/composewell/packcheck by harendra at 2021-07-20T09:35:30Z LTSHaskell:0.6.0, NixOS:0.6.0, Stackage:0.6.0 4579 total (61 in the last 30 days) (no votes yet) [estimated by Bayesian average] λ λ λ Docs available Last success reported on 2021-07-20

[back to package description]

# packcheck

## Quick Start

Please use cabal version 2.4 or later.

### Build on CI

To use packcheck for CI testing of your repo:

#### Github Actions

CI should work out of the box for most packages. Uncomment the relevant lines in the CI config files or change the values of the environment variables for fine grained control or custom configuration.

### Build on Local Machine

You can use packcheck to build or CI test a package on your local machine as well. For local use, copy packcheck.sh to your local machine (Linux/OSX/Windows), put it in your PATH, and run it from your package directory. You can pass the same evironment variables that are used in CI files to run the exact same tests locally. Usage is as simple as:

$packcheck.sh cabal$ packcheck.sh cabal GHCVER=8.6.5
$packcheck.sh cabal ENABLE_GHCJS=y$ packcheck.sh stack GHCVER=8.6

packcheck can automatically pick the requested version of GHC from:

• multiple GHC path components in your PATH environment variable
• hvr ghc PPA install directory
• stack installed ghc binaries

### Out of the box support

GHC GHCJS
cabal stack
Linux OSX Windows
Github Appveyor CircleCI Travis Local Machine

The script can be easily adapted to any CI with a single line build command.

## Key Features

• Error messages: A lot of emphasis has been put on providing precise and detailed error messages when something fails so that the user can easily fix things.
• Informational: The output provides all the information that you may want to know, tool paths being used, their versions, how they are invoked, build options, time taken by each build step etc. You can even copy the commands from the output and paste them on your local host to reproduce the build or failure and debug quickly. See here for a sample output.
• Same tests everywhere: You can run exact same tests with same options or flags, in the same way, on all CI platforms.
• Choose options: Conveniently control all aspects of build through command line or environment variables, including tool options or whether to enable benchmarks, haddock, coverage, test etc.
• Picking GHC: Right GHC is picked up automatically from PATH or TOOLS_DIR (hvr ghc PPA installation dir) based on GHCVER. Stack installed GHC binaries can be picked automatically when available.
• Test source distribution: packcheck creates the source distribution and builds the package from the generated tarball to make sure that you build what you release and don't miss adding a file to the distribution. Also, checks if any file in the git repo is missing in the source distribution.
• Upload coverage: To send coverage info to coveralls.io just uncomment a line in your respective ci config file.
• Non-destructive: By default the script does not change any config or upgrade any tools on the host machine.
• Auto tool install: For stack builds, stack and ghc can be installed automatically

## Introduction

The package packcheck includes a script called packcheck.sh, it is a high level universal super build script to uniformly, consistently build and comprehensively sanity test a Haskell package across build tools (stack/cabal) and across all platforms (Linux/MacOS/Windows). You do not need to be familiar with any of the build tools to use it.

To make sure that it works everywhere without installing anything it is deliberately written using the bash shell scripting language. Any of the parameters to control the builds can either be passed on the script command line or as environment variables for convenient use on CI systems.

packcheck is also a minimal yet complete "hello world" Haskell package with model config files that can be used unmodified in any Haskell package. The CI configs can be modified declaratively, using environment variables, to adapt to any kind of build scenario you can imagine.

This model package has everything that a Haskell package usually has; including tests, benchmarks and Linux/MacOS/Windows CI already working. It can be used as a starting point to develop a new package. Beginners can use it to learn about haskell package metadata structure.

## What all does it do?

An invocation of packcheck.sh performs a whole battery of tests, all aspects can be controlled via environment variables, command line. The flow goes roughly as follows:

• Pick up the correct version of GHC/cabal/stack
• create source distribution and unpack it to test from it
• run hlint
• build source, benchmarks and docs
• run tests
• generate and upload coverage report (to coveralls.io)
• perform distribution checks

## Usage Examples

You can run these commands on your local machine as well as inside a CI script. You can try these commands in the packcheck package itself:

$cd packcheck$ ./packcheck.sh cabal GHCVER=8.6.5
$./packcheck.sh stack RESOLVER=lts-13$ ./packcheck.sh stack GHCVER=8.6.5
$./packcheck.sh stack RESOLVER=lts-7.24 STACK_YAML=stack-8.0.yaml STACK_BUILD_OPTIONS="--flag streamly:examples-sdl" CABALVER=1.24 # You can also do a cabal build using stack installed ghc:$ stack exec ./packcheck.sh cabal RESOLVER=lts-11

Run hlint commands on the directories src and test:

$./packcheck.sh hlint HLINT_OPTIONS="lint" HLINT_TARGETS="src test" Send coverage info of the testsuites named test1 and test2 to coveralls.io using hpc-coveralls.$ ./packcheck.sh cabal GHCVER=8.8.3 COVERALLS_OPTIONS="test1 test2"

## Picking GHC versions

When GHCVER parameter is not specified, packcheck looks for a binary named ghc in your PATH environment variable. It uses first such binary found in PATH.

When GHCVER parameter is specified, it looks for ghc in the PATH and if GHCVER is a PREFIX of the actual version of ghc binary found then that ghc binary is used. Otherwise, packcheck tries to look for another ghc binary in the next PATH components until it finds a matching ghc version.

When both GHCVER and TOOLS_DIR are specified then in addition to searching in PATH environment variable, packcheck also looks for ghc in ${TOOLS_DIR}/ghc/${GHCVER}*/bin. This is to facilitate selecting any GHC version from an hvr/ghc ubuntu PPA installation without putting all the myriad GHC version directories explicitly in your PATH.

If all of the above fails packcheck looks for ghc in the stack install locations.

## packcheck-safe

packcheck-safe.sh is a more robust wrapper over packcheck.sh, it does not trust or use any environment variables, all environment needs to be specified explicitly on the command line. Therefore, it ensures better reproducibility.

It also catches any misspelled command line parameter names. For example, packcheck.sh won't catch it if you typed GHCVWR=8.4 instead of GHCVER=8.4, it just assumes that GHCVER is not specified. packcheck-safe.sh would generate an error saying that GHCVWR is not recognized. Since it uses a clean environment you will have to specify PATH as well on the command line. For example,

$./packcheck-safe.sh cabal PATH=/bin:/usr/bin:/opt/ghc/bin ## packcheck-remote packcheck-remote.sh is a wrapper over packcheck.sh. It allows you to run packcheck on a remote repository by cloning it locally and optionally merging a branch into another branch (e.g. merging a PR branch into master).$ ./packcheck-remote.sh --force \
--remote=https://github.com/user/repo \
--checkout=origin/master \
--merge=origin/branch \
--directory=./repo.packcheck \
-- cabal GHCVER=8.8.3