A forge for Fossil repositories. Quarry hosts many repositories at once and gives each one a timeline, wiki, tickets, forum, chat, landings and CI. It stores and syncs them through zit, a reimplementation of Fossil, so both clients work against it unchanged:
fossil clone https://zeitforge.app/r/quarry quarry.fossil
zit clone https://zeitforge.app/r/quarry quarry.zit
The two clients share Fossil's sync protocol, so clone, pull, push and
unversioned files (fossil uv sync, clone -u) behave the same from
either. zeitforge.app runs it.
What a repository gets
- Fossil's own content, browsable: timeline, check-ins, diffs, files,
embedded docs, wiki, tickets, forum, technotes. Links in imported
content that point at Fossil's URLs (
/info/<hash>,/tktview,/wiki?name=, …) resolve to quarry's pages (docs/fossil-paths.md). - Fossil's users, unchanged: a hosted Fossil repository brings its users and their capability letters with it, and the letters are quarry's permission model (RFC 0004). Fossil clients authenticate the way they always have.
- Landings: propose a branch onto another, review it, accept it (docs/landings.md). Protected branches are enforced at the sync front, so a refused push never reaches the store (RFC 0007).
- CI: workflows written as YAML under
ci/, run on dagnats runners, reported on landings and check-ins, with environments whose secrets only reviewed code can reach (RFC 0009, 0019). - Chat, mentions and an inbox: live chat per repository and team, mentions from chat and the forum, notifications in-app, by email and by browser push (RFC 0011). A Fossil server's own chat can be bridged in.
- Teams: user-owned places that hold repositories, grant roles and gather their chat and tickets (RFC 0018).
- Attachments and releases: files on tickets, wiki, technotes and forum posts, and unversioned files and release downloads, with the bytes in the repository's own bucket (RFC 0016, 0020).
- A git mirror out: a public repository's trunk pushed to GitHub or any Git host after each move (RFC 0022).
- An API for everything the pages do: every page is built on the same
ops as
/api/v1(docs/api.md), and agent accounts hold scoped tokens of their own (RFC 0021).
Bringing a repository
A repository starts empty, is imported from Fossil and owned here, or mirrors an upstream Fossil server on an interval (read-only by default) (docs/hosting.md). Anyone with an account may create one.
Quarry holds no hostage bytes. Everything durable lives in the repositories' own artifacts or their buckets; every quarry index is derived and rebuilt from them. A repository taken elsewhere takes everything with it.
Running it
quarry serve --addr 127.0.0.1:8950 --data ./data --repo quarry=$HOME/quarry
The full stack is quarry, zit, notify and dagnats. Quarry runs zit for
every read and write, so the zit version is part of quarry's behaviour:
pin it (ZIT_VERSION in scripts/build-linux.sh). Running by hand, with
compose, and the fleet admin's work: docs/running.md.
Working on it
- Spec: docs/rfcs/0001-quarry-forge.md; every RFC, grouped and with its status: docs/rfcs/README.md
- This repository is a zit repository, landed on zeitforge.app like any other: quarry has been built on quarry from the first commit.
make checkruns the local gates CI runs: gofmt, vet, test, the race detector on the concurrency-bound packages, and build. The tests include the structural assertion that onlyinternal/opstouches the data planes.