This is an automated email from the ASF dual-hosted git repository.
klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/devlake-website.git
The following commit(s) were added to refs/heads/main by this push:
new 4162feefe9b docs: add monorepo plugin documentation (#835)
4162feefe9b is described below
commit 4162feefe9bc75ae952100cb668e7265816bdec4
Author: Itai Spiegel <[email protected]>
AuthorDate: Wed Oct 14 09:57:56 2026 +0300
docs: add monorepo plugin documentation (#835)
Companion to apache/devlake#9037 (Plugin for per-sub-project DORA metrics
in a monorepo).
Adds a Plugins/monorepo page covering how deployments are attributed by CI
job name and pull requests by label, the per-project configuration on the
project settings page and its equivalent metric plugin option, the
unattributed/All reserved names, what the plugin writes, and the built-in
Monorepo Sub-Projects dashboard. It also states that only Deployment
Frequency and Lead Time for Changes are computed per sub-project, since
incidents are not attributed.
Documents the new sub_project columns on pull_requests,
pull_request_commits and project_pr_metrics plus the new
cicd_deployment_subprojects table in the domain layer schema, and links to
the plugin from the DORA page.
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
---
docs/DORA.md | 11 +++
docs/DataModels/DevLakeDomainLayerSchema.md | 17 ++++
docs/Plugins/monorepo.md | 147 ++++++++++++++++++++++++++++
3 files changed, 175 insertions(+)
diff --git a/docs/DORA.md b/docs/DORA.md
index d828d3388c5..49308324bb8 100644
--- a/docs/DORA.md
+++ b/docs/DORA.md
@@ -206,6 +206,17 @@ If you are not familiar with Grafana, please refer to our
[Grafana doc](Configur
<br/><br/>
+## DORA for a monorepo
+
+DevLake measures DORA at the project level, and a project's scope is a
repository. If a
+single repository hosts several logically separate projects — each with its
own deploy job
+and its own PR label — all of them collapse into one set of DORA numbers.
+
+The [monorepo plugin](Plugins/monorepo.md) splits such a repository into
sub-projects and
+computes per-sub-project Deployment Frequency and Lead Time for Changes.
+
+<br/>
+
## Try it Out
To create the DORA dashboard with your own toolchain, please look at the
[configuration tutorial](Configuration/Tutorial.md) and [project organization
documentation](Configuration/HowToOrganizeDevlakeProjects.md) for more details.
diff --git a/docs/DataModels/DevLakeDomainLayerSchema.md
b/docs/DataModels/DevLakeDomainLayerSchema.md
index 4676005c75f..7f6cda28cb9 100644
--- a/docs/DataModels/DevLakeDomainLayerSchema.md
+++ b/docs/DataModels/DevLakeDomainLayerSchema.md
@@ -465,6 +465,7 @@ Pull requests are the abstraction of GitHub pull requests,
GitLab merge requests
| `head_ref` | varchar | 255 | The branch name in the head
repo that contains the changes that will be added to the base
| |
| `base_commit_sha` | char | 40 | The base commit of this PR.
| |
| `head_commit_sha` | char | 40 | The head commit of this PR.
| |
+| `sub_project` | varchar | 100 | The monorepo sub-project this
PR belongs to, matched by label. Written by the [monorepo
plugin](../Plugins/monorepo.md); NULL when the project has no monorepo
configuration.
|
|
#### pull_request_labels
@@ -489,6 +490,7 @@ The list is additive. This means if a rebase with commit
squashing takes place a
| `commit_author_name` | varchar | 255 | The name of the person who
authored the commit | |
| `commit_author_email` | varchar | 255 | The email address of the
person who authored the commit. | |
| `commit_authored_date` | varchar | 255 | The date and time when the
commit was authored. | |
+| `sub_project` | varchar | 100 | Mirrors the owning pull
request's `sub_project`. | |
#### pull_request_comments
@@ -656,6 +658,20 @@ Normally, one deployment only deploy to one repo. But in
some cases, one deploym
| `repo_url` | varchar | 191 | The url of the
repo
| |
| `prev_success_deployment_commit_id` | varchar | 255 | The last
successful deployment_commit_id before this one in the same `cicd_scope`,
`repo` and `environment`, which is used to calculate the new commits deployed
by this deployment, thereby measuring [DORA - change lead
time](../Metrics/LeadTimeForChanges.md).
| |
+#### cicd_deployment_subprojects
+
+Maps a deployment to the monorepo sub-project(s) it deployed. Rows are written
by the [monorepo plugin](../Plugins/monorepo.md), which matches the name of the
deploying CI job against each sub-project's configured pattern.
+
+The relationship is many-to-many: a pipeline that runs the deploy jobs of
several sub-projects produces one row per sub-project, so dashboards can `GROUP
BY sub_project` without double counting.
+
+Projects without monorepo configuration have no rows in this table at all;
dashboards treat a missing mapping as the single, implicit `All` group.
+
+| **field** | **type** | **length** | **description**
| **key** |
+|:---------------------|:---------|:-----------|:------------------------------------------------------------------------------------------|:--------|
+| `project_name` | varchar | 100 | The project this mapping
belongs to | PK |
+| `cicd_deployment_id` | varchar | 255 | The deployment, matching
[table.cicd_deployment_commits](#cicd_deployment_commits).`cicd_deployment_id`
| PK |
+| `sub_project` | varchar | 100 | The sub-project this
deployment deployed | PK
|
+
### Domain 5 - Code Quality
The names of tables in the 'Code Quality' domain will start with a prefix cq\_
@@ -929,6 +945,7 @@ metrics, such as _'No. of Issue closed by contributor',
'No. of commits by contr
| `deployment_id` | longtext | | The id of cicd_task which
deploy the commits of this PR | |
| `pr_deploy_time` | bigint | | The time it takes from when a
PR is merged to when it is deployed | |
| `pr_cycle_time` | bigint | | The total time from the first
commit to when the PR is deployed | |
+| `sub_project` | varchar | 100 | The monorepo sub-project of
this PR, copied from [table.pull_requests](#pull_requests) | |
#### project_issue_metrics
diff --git a/docs/Plugins/monorepo.md b/docs/Plugins/monorepo.md
new file mode 100644
index 00000000000..82b02748999
--- /dev/null
+++ b/docs/Plugins/monorepo.md
@@ -0,0 +1,147 @@
+---
+title: "Monorepo"
+description: >
+ Monorepo Plugin
+---
+
+## Summary
+
+DevLake's scope model is one scope per repository, so a repository that hosts
several
+logically separate projects collapses into a single set of DORA numbers. The
`monorepo`
+plugin splits such a repository into **sub-projects** and computes
per-sub-project
+delivery metrics.
+
+Like [DORA](../DORA.md) and [Linker](./linker.md), it is a metric plugin: it
works on the
+domain layer after data collection, and runs after `dora`.
+
+It attributes:
+
+- **Deployments** to a sub-project by matching the name of the CI job that
performed the
+ deployment against a regular expression.
+- **Pull requests** to a sub-project by matching the PR's labels.
+
+From those two attributions it produces per-sub-project
+[Deployment Frequency](../Metrics/DeploymentFrequency.md) and
+[Lead Time for Changes](../Metrics/LeadTimeForChanges.md).
+
+[Change Failure Rate](../Metrics/CFR.md) and
+[Median Time to Restore Service](../Metrics/MTTR.md) are **not** computed per
sub-project,
+because they require incident data and incidents are not attributed to
sub-projects.
+
+## Supported Versions
+
+The monorepo plugin was added after the `v1.0.3-beta18` release and is
available in all
+later releases.
+
+## Configuration
+
+The plugin is configured per project, on the project's settings page.
+
+1. Open **Projects** → your project → **Settings**.
+2. Tick **Enable Monorepo Sub-Projects**.
+3. Add one row per sub-project and fill in the three fields below.
+4. Click **Save**, then re-run the project's blueprint.
+
+| Field | Description
| Example |
+|:--------------------------|:----------------------------------------------------------------------------------------------------------------------------------------|:---------------------|
+| **Sub-project name** | Identifies the sub-project in the output tables
and dashboards. Must be unique within the project.
| `serviceA` |
+| **Labels** | Comma-separated pull request labels that mark a
PR as belonging to this sub-project. Matching is **exact and case-sensitive**.
| `serviceA,svc-a` |
+| **Deploy job pattern** | A [Go regular
expression](https://pkg.go.dev/regexp/syntax) matched against `cicd_tasks.name`
to recognise this sub-project's deploy jobs. | `^deploy-serviceA$` |
+
+`unattributed` and `All` are reserved and cannot be used as sub-project names.
+
+The same options can be set through the API or the Config UI's
+[advanced mode](../Configuration/AdvancedMode.md) as the project's `monorepo`
metric
+plugin option:
+
+```json
+{
+ "pluginName": "monorepo",
+ "enable": true,
+ "pluginOption": {
+ "subProjects": [
+ {
+ "name": "serviceA",
+ "prLabels": ["serviceA", "svc-a"],
+ "deployJobPattern": "^deploy-serviceA$"
+ },
+ {
+ "name": "serviceB",
+ "prLabels": ["serviceB"],
+ "deployJobPattern": "^deploy-serviceB$"
+ }
+ ],
+ "includeUnattributed": true
+ }
+}
+```
+
+`includeUnattributed` (default `true`) controls what happens to pull requests
and
+deployments that belong to the project but match none of the configured
sub-projects:
+with `true` they are recorded under the sentinel sub-project `unattributed`,
so you can
+see how much of the repository is not yet classified; with `false` they are
left
+unclassified.
+
+## How attribution works
+
+### Deployments
+
+Every deployment of the project is joined to the CI/CD tasks of the pipeline
that produced
+it, and each task of type `Deployment` has its name matched against each
sub-project's
+`deployJobPattern`.
+
+- A pipeline that runs the deploy jobs of several sub-projects produces **one
row per
+ sub-project**, so dashboards can `GROUP BY sub_project` without double
counting.
+- Deployments imported directly from a provider's deployment API (rather than
generated
+ from a pipeline) carry no job name and cannot be attributed.
+
+### Pull requests
+
+All pull requests of the project are attributed — open, closed and merged — by
label.
+A pull request belongs to exactly one sub-project: when it carries the labels
of more than
+one, the **first matching sub-project in the configured order wins**, so order
the list
+from most to least specific.
+
+PR coding, pickup, review, deploy and cycle time are not recomputed by this
plugin; they
+are taken from DORA's own `project_pr_metrics` rows and tagged with the
sub-project.
+
+### Mismatch warnings
+
+After tagging, the plugin cross-checks each PR's label-derived sub-project
against the
+sub-project of the deployment that DORA says actually shipped it.
Disagreements are logged
+as warnings and never fail the pipeline — labels always win. They usually
point at a
+`prLabels` or `deployJobPattern` entry that needs fixing, though a pipeline
deploying
+several sub-projects at once will produce such warnings legitimately.
+
+## Output
+
+| Table
| Description
|
+|:------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------|
+|
[`cicd_deployment_subprojects`](../DataModels/DevLakeDomainLayerSchema.md#cicd_deployment_subprojects)
| Maps each deployment to the sub-project(s) it deployed.
|
+|
[`pull_requests.sub_project`](../DataModels/DevLakeDomainLayerSchema.md#pull_requests)
| The sub-project a pull request belongs to.
|
+|
[`pull_request_commits.sub_project`](../DataModels/DevLakeDomainLayerSchema.md#pull_request_commits)
| Mirrors the owning pull request's sub-project.
|
+|
[`project_pr_metrics.sub_project`](../DataModels/DevLakeDomainLayerSchema.md#project_pr_metrics)
| Tags DORA's per-PR metrics with the sub-project.
|
+
+A `NULL` `sub_project` means the row was never classified — single-repo
projects, or rows
+the plugin has not processed. Dashboards render these as the single implicit
group `All`
+via `COALESCE(sub_project, 'All')`.
+
+Attribution is rebuilt from scratch on every run, so changing the
configuration and
+re-running the blueprint reclassifies existing data.
+
+:::note
+The plugin also populates `monorepo_subproject_deployments` and
+`monorepo_subproject_pr_metrics`. Both are deprecated and will be removed in a
future
+release — query the tables above instead.
+:::
+
+## Dashboard
+
+A built-in Grafana dashboard, **Monorepo Sub-Projects**, visualises the output:
+
+- Deployment Count by Sub-Project
+- Deployment Frequency over Time
+- Change Lead Time Breakdown by Sub-Project
+- Unattributed PRs
+- Awaiting Deployment
+- Attributed Deployments