Quad CI
Quad CI is a simple, tiny and beginner friendly Continuous Integration system written in Haskell.
Features
- sandboxed builds in docker containers
- multi-node architecture with agents picking up jobs to work on
- http api to interact with the frontend and other nodes
- support for triggering builds with github webhooks
All in 1K lines of code!
📼 Watch the Intro video (~2 minutes).
Simple Haskell Handbook where we start from zero lines of code and build Quad CI from scratch!
Check out theGetting Started
# Needed for RecordDotSyntax
$ stack install record-dot-preprocessor
# Run server
$ stack run -- start-server
# Run agent
$ stack run -- start-agent
Try running a simple build:
$ curl -X POST -H "Content-Type: application/json" -d \
@test/github-payload.sample.json "http://localhost:9000/webhook/github"
Quad CI comes with a web UI, which can be accessed at http://localhost:3000
. To install it, run the following:
cd frontend/
yarn
yarn next
Why?
This project tries to answer the question: How do I build an application with Haskell?
Intermediate level practical resources on Haskell are notoriously hard to find. My goal is to provide a real world example of an Haskell application, while keeping the scope small (Quad CI is only 1000 lines of code, including tests).
Another goal is to showcase Simple Haskell (or at least my own interpretation of it).
Finally, I think RecordDotSytax
is one of the coolest things that happened in Haskell land recently and I wanted to show how to use it in practice.
Architecture
Single server - multiple agents.
Builds share workspace.
STM queue
1 build/agent concurrency limit
Codebase overview
src/Core.hs
Domain types (Build
, Pipeline
etc.) along with main state machine (progress
)
src/Docker.hs
Talks to Docker api
src/Runner.hs
Runs a single build, collecting logs (Core.collectLogs
) and processing state updates (Core.progress
)
src/JobHandler.hs
Introduces Job
type, which is just a Build
that can be queued and scheduled
src/JobHandler/Memory.hs
An in-memory implementation of JobHandler
, built on top of STM
src/Github.hs
Talks to Github api
src/Agent.hs
Agents ask the server for work to do, run builds (Runner
) and send updates back to the server
src/Server.hs
The server collects jobs to be run (when receiving webhook events). It keeps an internal job queue (JobHandler
) exposed as an http api (used by web ui)
src/Cli.hs
Main entrypoint. Calls either Server.run
or Agent.run
src/Socket.hs
Low-level code to send http requests to a socket. Not interesting, can be ignored.
For a full overview of the codebase, check out the Simple Haskell Handbook where we start from zero lines of code and build Quad CI from scratch!