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

Reply via email to