Setting up the datalake
Entirely optional. dun works with no database at all โ the hooks, the
journal, dun status and dun report are local and need nothing. This is
for the shared view: several repositories and several people looked at
together, and AI attribution correlated with delivery data from GitHub and
your issue tracker.
The stack is Apache DevLake. whodunit
publishes into six whodunit_-prefixed tables and never writes to
DevLake's own domain tables, so its plugins and this tool coexist without
either corrupting the other.
Two steps, deliberately separateโ
Step 1 builds the stack and is run once. Step 2 puts the dashboards on it and is re-run whenever whodunit ships new ones โ which is why it is not folded into step 1.
Neither needs dun or a clone of the repository. This is infrastructure;
the developers who publish into it install the CLI separately.
Step 1 โ the stackโ
Once, on whichever machine holds the database:
curl -fsSL https://raw.githubusercontent.com/navjyotnishant/whodunit/main/deploy/devlake/setup-datalake.sh | sh
Fetches DevLake's own compose file from upstream, generates an encryption
secret, starts four containers, and creates the Grafana datasource. From a
checkout, ./up.sh does the same.
Step 2 โ the dashboardsโ
Again after each whodunit release:
curl -fsSL https://raw.githubusercontent.com/navjyotnishant/whodunit/main/deploy/devlake/import-dashboards.sh | sh
Step 1 offers to run this at the end, so a first install is one sitting.
Against a Grafana you already run, start here and pass --grafana URL.
Re-running replaces the dashboards in place โ same uids, same URLs, no
duplicates. They land in a Whodunit folder rather than General, so they
do not mix with DevLake's own; --folder NAME puts them elsewhere.
Step 3 โ model prices, and teamsโ
Two tables the dashboards read are not filled by dun sync.
Model prices. The Investment Case and the per-model cost view price
each session at its model's list price, from whodunit_model_prices. The
schema creates the table empty, so those panels run on a fresh datalake
and report every session as unpriced until it is filled:
python3 deploy/devlake/fetch-model-prices.py --database lake
It reads the providers' pricing pages and fails closed to a dated snapshot
when a page no longer parses; the dashboard shows fetched or baked <date> beside each price. Rerun it when a new model appears in your
sessions or now and then for price changes. See
The investment case.
Teams. Every team filter and every per-team panel joins DevLake's own
teams and team_users tables, and matches team_users.user_id against
the committer email. dun does not write those tables. They are filled
through DevLake's org plugin, which takes two CSVs:
| file | columns |
|---|---|
teams.csv | Id, Name, Alias, ParentId, SortingIndex |
users.csv | Id, Name, Email, TeamIds |
GET http://localhost:8080/plugins/org/teams.csv (and users.csv) returns
the current contents as a template; upload the edited files back with a
PUT to the same paths, or through the Teams page of the config UI. Use
the committer email as each user's Id โ the dashboards join on that
column, so a user whose Id is anything else lands in (unassigned).
Aliases still resolve first: a second address maps onto its canonical one
before the team lookup, so one Id per person is enough.
The teams map in ~/.whodunit/config.json is not published to the
datalake yet; see Teams and identities.
Point dun at itโ
On each developer machine:
dun config datalake
This asks for the database URL and stores the password encrypted at
rest, bound to that machine โ not in a shell profile, and never in
plaintext in config.json.
Then publish:
dun sync --dry-run # see exactly what would be sent
dun sync # send it
Once configured, git push syncs automatically through the pre-push
hook. There is nothing to schedule.
What gets publishedโ
Six tables, listed in full on the Privacy page. The two identifying fields are the contributor email and the file paths, and both are named there rather than buried.
Portsโ
| DevLake config UI | http://localhost:4000 |
| Grafana | http://localhost:3002 |
The DevLake stack ships with published default credentials for its local
database (merico/merico). They are upstream defaults for a local
compose stack, not secrets โ but a deployment that leaves them reachable
from anywhere but localhost has a problem. Change them before exposing the
stack.
Keeping it runningโ
deploy/devlake/verify.sh
Checks the containers, the schema and the datasource, and says which is wrong rather than that something is.