• Stars
    star
    130
  • Rank 277,575 (Top 6 %)
  • Language
    Haskell
  • License
    Other
  • Created about 10 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

UNMAINTAINED: Continuous integration server

WARNING: UNMAINTAINED PROJECT

This project is not actively developed - you are likely to be better of using something more complete (if you do want to use it, consider forking it and taking it over). See the blog post giving notes on why it is now unmaintained.

Bake is a continuous integration server, designed for large, productive, semi-trusted teams. In particular it primarily targets:

  • Large teams where there are at least several contributors working full-time on a single code base.
  • Productive teams which are regularly pushing code, many times a day.
  • Semi-trusted teams where code does not go through manual code review, but code does need to pass a test suite and perhaps some static analysis. People are assumed to be fallible.

To give a flavour, the web GUI looks of a running Bake system looks like:

Acknowledgements: The name "Bake" is thanks to Andy Adams-Moran.

The Design

Bake is a Haskell library that can be used to put together a continuous integration server. To run Bake you start a single server for your project, which coordinates tasks, provides an HTTP API for submitting new patches, and a web-based GUI for viewing the progress of your patches. You also run some Bake clients which run the tests on behalf of the server. While Bake is written in Haskell, most of the tests are expected to just call some system command.

There are a few aspects that make Bake different from most alternatives:

  • Patches are submitted to Bake, but are not applied to the main repo until they have passed all their tests. There is no way for someone to "break the build" - at all points the repo will build on all platforms and all tests will pass.
  • Bake scales up so that even if you have 5 hours of testing and 50 commits a day it will not require 250 hours of computation per day. In order for Bake to prove that a set of patches pass a test, it does not have to test each patch individually.
  • Bake allows multiple clients to run tests, even if some tests are only able to be run on some clients, allowing both parallelisation and specialisation (testing both Windows and Linux, for example).
  • Bake can detect that tests are no longer valid, for example because they access a server that is no longer running, and report the issue without blaming the submitted patches.

The Workflow

Bake is highly parametrisable, and can be reconfigured to support several different styles of use, but here I give one plausible workflow. Imagine a number of developers, somewhere between 5 and 50. Each developer has 1 or 2 active branches they are working on. You have a master branch, which developers merge from once a day. When a developer has completed something they push their branch to the Git repo and register the SHA1 with Bake. Bake then tests the patch on all tests (in conjunction with all other patches that got promoted) and if it passes merges it into the master branch. Once a day (say 7pm) you pause the incoming patches, ensure the queue has emptied, then resume.

An Example

The test suite provides both an example configuration and commands to drive it. Here we annotate a slightly simplified version of the example, for lists of imports see the original code.

First we define an enumeration for where we want tests to run. Our server is going to require tests on both Windows and Linux before a patch is accepted.

    data Platform = Linux | Windows deriving (Show,Read)
    platforms = [Linux,Windows]

Next we define the test type. A test is something that must pass before a patch is accepted.

    data Action = Compile | Run Int deriving (Show,Read)

Our type is named Action. We have two distinct types of tests, compiling the code, and running the result with a particular argument. Now we need to supply some information about the tests:

    allTests = [(p,t) | p <- platforms, t <- Compile : map Run [1,10,0]]
    
    execute :: (Platform,Action) -> TestInfo (Platform,Action)
    execute (p,Compile) = matchOS p $ run $ do
        cmd "ghc --make Main.hs"
    execute (p,Run i) = require [(p,Compile)] $ matchOS p $ run $ do
        cmd ("." </> "Main") (show i)

We have to declare allTests, then list of all tests that must pass, and execute, which gives information about a test. Note that the test type is (Platform,Action), so a test is a platform (where to run the test) and an Action (what to run). The run function gives an IO action to run, and require specifies dependencies. We use an auxiliary matchOS to detect whether a test is running on the right platform:

    #if WINDOWS
    myPlatform = Windows
    #else
    myPlatform = Linux
    #endif

    matchOS :: Platform -> TestInfo t -> TestInfo t
    matchOS p = suitable (return . (==) myPlatform)

We use the suitable function to declare whether a test can run on a particular client. Finally, we define the main function:

    main :: IO ()
    main = bake $
        ovenGit "http://example.com/myrepo.git" "master" $
        ovenTest readShowStringy (return allTests) execute
        defaultOven{ovenServer=("127.0.0.1",5000)}

We define main = bake, then fill in some configuration. We first declare we are working with Git, and give a repo name and branch name. Next we declare what the tests are, passing the information about the tests. Finally we give a host/port for the server, which we can visit in a web browser or access via the HTTP API.

Using the Example

Now we have defined the example, we need to start up some servers and clients using the command line for our tool. Assuming we compiled as bake, we can write bake server and bake client (we'll need to launch at least one client per OS). We can view the state by visiting http://127.0.0.1:5000 in a web browser.

To add a patch we can run bake addpatch --name=d088cc3c677a867185f083aca200cb421c27b984, using the SHA1 of the commit, which will try and integrate that patch into the master branch, after all the tests have passed. Alternatively, we can run bake addpatch --name=$(git rev-parse HEAD) to try and integrate our working tree into master.

When viewing the server, there are a few additional URL's that may be of use:

  • ?stats= will show stats about which tests take longest, how long a test run takes, which test fails most often.
  • ?raw= will give internal details of the implementation.
  • /dump will download an SQLite database containing all of the persistent state.
  • ?admin= will give you an admin control panel on any page, letting you retry/delete patches and skip tests. If you want to restrict access to this panel, run bake admin myPassword which says that running bake server --admin=3A18885C will then require ?admin=myPassword.

More Examples

You can find more examples at:

More Repositories

1

hlint

Haskell source code suggestions
Haskell
1,459
star
2

ghcid

Very low feature GHCi based IDE
Haskell
1,130
star
3

shake

Shake build system
Haskell
744
star
4

hoogle

Haskell API search engine
Haskell
689
star
5

tagsoup

Haskell library for parsing and extracting information from (possibly malformed) HTML/XML documents
Haskell
231
star
6

record-dot-preprocessor

A preprocessor for a Haskell record syntax using dot
Haskell
129
star
7

weeder

Detect dead exports or package imports
Haskell
124
star
8

debug

Haskell library for debugging
JavaScript
121
star
9

rattle

Forward build system with speculation and caching
Haskell
102
star
10

spaceleak

Notes on space leaks
Haskell
101
star
11

extra

Extra Haskell functions
Haskell
93
star
12

cmdargs

Haskell library for command line argument processing
Haskell
91
star
13

build-shootout

Comparison of build program expressive power
Haskell
88
star
14

uniplate

Haskell library for simple, concise and fast generic operations.
Haskell
74
star
15

safe

Haskell library for safe (pattern match free) functions
Haskell
45
star
16

ghc-make

An alternative to ghc --make which supports parallel compilation of modules and runs faster when nothing needs compiling.
Haskell
40
star
17

interpret

Rust
38
star
18

neil

General tools for Neil
Haskell
38
star
19

profiterole

GHC prof manipulation script
Haskell
30
star
20

nsis

Haskell DSL for producing Windows Installer using NSIS
Haskell
26
star
21

derive

A Haskell program and library to derive instances for data types
TeX
25
star
22

supero

Haskell optimisation tool based on supercompilation
Haskell
25
star
23

hexml

A bad XML parser
C
19
star
24

offline-stack

Install Stack without internet access
Haskell
18
star
25

catch

Haskell pattern match analsyis checker
Haskell
15
star
26

js-jquery

Haskell library to obtain minified jQuery code
Haskell
9
star
27

rexe

.exe forwarder, to allow replacing binaries on PATH
Haskell
8
star
28

office

Macros for Microsoft Office
VBA
7
star
29

VSHaskell

Visual Studio 2010 addin
C#
7
star
30

record-hasfield

A version of HasField that will be available in future GHC
Haskell
7
star
31

shake-paper

Paper on the new GHC Shake-based build system
HTML
6
star
32

lasagna

Checker for Haskell layering violations
Haskell
5
star
33

guihaskell

A graphical REPL and development environment for Haskell
Haskell
5
star
34

hwwg

Haskell Website Working Group
5
star
35

shake-bazel

Experimenting with Shake and Bazel combined
Haskell
4
star
36

blogs

TeX
4
star
37

haskell-parser

Haskell parser based on that from GHC
Haskell
4
star
38

filepattern

A file path matching library
Haskell
4
star
39

idris-playground

Playing around with Idris
Idris
4
star
40

proplang

A Haskell library for functional GUI development
Haskell
4
star
41

thesis

My PhD thesis - Transformation and Analysis of Functional Programs
Haskell
3
star
42

js-flot

Haskell library to obtain minified Flot code
Haskell
3
star
43

qed

Experiments writing a prover
Haskell
3
star
44

core-playground

Simple Core language for Haskell experiments
Haskell
3
star
45

js-dgtable

Haskell library to obtain minified jquery.dgtable code
JavaScript
3
star
46

neil-check

Run neil and hlint on all my projects
Haskell
3
star
47

shake-examples

3
star
48

proof

Haskell library for writing proofs
Haskell
2
star
49

ci-check

Test the various supported CI's
2
star
50

hogle-dead

This repo has been moved to the master branch of https://github.com/ndmitchell/hoogle.
Haskell
2
star
51

stack-3137

Reproduce https://github.com/commercialhaskell/stack/issues/3137
Haskell
2
star
52

winhaskell

Windows Haskell GUI interpretter
C++
1
star
53

fossilizer

Generate 3D images of fossil bedding surfaces
JavaScript
1
star
54

bug-i386-ghc84

1
star
55

proposition

Haskell library for manipulating propositions.
Haskell
1
star
56

tex2hs

A program to check for type errors in a Latex document
Haskell
1
star
57

ndmitchell

1
star
58

hlint-test

Haskell
1
star
59

ghc-process

Compiling and linking files in a single process using the GHC API
Haskell
1
star
60

shark

A bad replacement for cabal/stack
1
star
61

index-search

Searching compressed text indicies
C
1
star
62

awesomo

Prototype optimiser for Haskell programs
Haskell
1
star
63

ninjasmith

Ninja file generator and tester
Haskell
1
star
64

firstify

A Haskell library to transform Yhc Core programs to first-order
TeX
1
star