chenwei791129 opened a new pull request, #9229:
URL: https://github.com/apache/devlake/pull/9229

   ### Summary
   
   Add a DORA project setting, **Source branch pattern** (`prHeadRefPattern`). 
When it is set, only merged pull requests whose source branch 
(`pull_requests.head_ref`) matches the regex count toward Lead Time for 
Changes. This lets teams leave out "carrier" PRs such as release or UAT merges, 
which would otherwise count the same changes twice.
   
   | Item | Behavior |
   | --- | --- |
   | Where to set it | Project → Settings → DORA. Stored in 
`ProjectMetricSetting.PluginOption`, like linker's `prToIssueRegexp` |
   | Matching | Go `regexp.MatchString`. No implicit anchors (write 
`^(feat\|fix)/`); use `(?i)` to ignore case; a leading `refs/heads/` is 
stripped before matching |
   | Empty or whitespace-only | No filtering, same as today |
   | Invalid regex | Plan generation returns `BadInput` (HTTP 400) `invalid 
prHeadRefPattern` |
   | Scope | Only `project_pr_metrics` is affected. `pull_requests` is 
unchanged, so code review dashboards keep all PRs |
   | Data sources | Filtering happens on the domain layer, so it works for 
GitLab, GitHub, Bitbucket and Azure DevOps alike |
   
   | Commit | Change |
   | --- | --- |
   | `feat(dora)` | `task_data.go`: new option plus compile/match helpers. 
`impl.go`: compile in `PrepareTaskData`; `MakeMetricPluginPipelinePlanV200` 
validates early and adds the pattern to the `calculateChangeLeadTime` stage 
only when it is not empty. `change_lead_time_calculator.go`: skip PRs that do 
not match and log how many were excluded |
   | `feat(config-ui)` ×2 | `settings-panel.tsx`: input, description and help 
tooltip in the DORA block |
   
   ### Does this close any open issues?
   
   Closes #9222
   
   ### Screenshots
   
   Project → Settings, with DORA enabled and the new Source branch pattern 
field:
   
   <img width="900" alt="DORA source branch pattern in project settings" 
src="https://raw.githubusercontent.com/chenwei791129/devlake/6ac7107b78a38a03a133ab640193dc11ab5d0f8a/pr-9222/dora-source-branch-pattern.png";
 />
   
   ### Other Information
   
   **Compatibility**
   
   - With no pattern set, the plan and the results are exactly the same as 
before (the existing expected plan in `impl_test` is unchanged).
   - No schema change, no scope config change, no migration.
   - An invalid regex is reported when the plan is generated, so the whole 
blueprint fails to trigger (not only DORA). This matches the monorepo 
`deployJobPattern` option. Validating options on save is handled separately by 
#9228 (closes #9227); the two PRs do not depend on each other.
   - After changing the pattern, a Re-transform is enough. 
`calculateChangeLeadTime` deletes the project's old rows first, so no stale 
rows are left behind.
   
   **Related issues and PRs**
   
   | Link | Relation |
   | --- | --- |
   | #9225 / #9226 | The Engineering Throughput PR time panels average PRs 
without a `project_pr_metrics` row as 0 hours, so those panels read low once a 
pattern is set. DORA dashboards are not affected |
   | #9227 / #9228 | Validate metric plugin options (including this regex) when 
a project is saved |
   | #9223 / #9224 | The dora e2e tests need an `accounts` table on a fresh 
database (pre-existing) |
   
   **Docs**: the user docs live in `apache/devlake-website`. I will open a 
follow-up PR there for `docs/DORA.md` and `docs/Metrics/LeadTimeForChanges.md`.
   
   ### Tests
   
   **Automated**
   
   | Check | Result |
   | --- | --- |
   | `go build`, `go vet`, `gofmt -l`, `golangci-lint run ./plugins/dora/...` | 
Pass |
   | `go test ./plugins/dora/...` incl. e2e (MySQL 8.4) | Pass. New e2e case 
logs `excluded 4 of 7 merged pull requests` |
   | Unit: `task_data_test.go` | Empty/whitespace, invalid regex, case 
sensitivity and `(?i)`, `refs/heads/` prefix, empty `head_ref` |
   | Unit: `impl_test.go` | Option added to the plan only when not empty, 
whitespace treated as unset, invalid regex returns `BadInput`, 
`PrepareTaskData` decoding |
   | config-ui | `tsc` clean; eslint shows only 2 existing prettier warnings on 
untouched lines |
   
   **Manual, against a self-hosted GitLab**
   
   The same commits, backported to v1.0.3-beta15 (only import paths differ), 
were deployed and tested with real data. Two test repos each got 10 MRs: 9 
merged, 1 left open. Every merge to `main` ran a dummy production deploy job.
   
   - **A**: DevLake project with the pattern set
   - **B**: control project, no pattern
   
   After each pattern change I ran a Re-transform (no recollection) and checked 
`project_pr_metrics`, the pipeline log and Grafana.
   
   | Source branch | `^(feat\|fix)/` | `^(feat\|fix\|hotfix)/` | 
`(?i)^(feat\|fix)/` |
   | --- | --- | --- | --- |
   | `feat/alpha`, `fix/beta` | ✔ | ✔ | ✔ |
   | `hotfix/epsilon` | | ✔ | |
   | `FEAT/delta` | | | ✔ |
   | `chore/gamma`, `release-uat`, `my-feat/zeta` | | | |
   | `feat/open` (not merged) | | | |
   
   | Scenario | Rows written for A | Log `excluded M of N` | B (control) | 
Result |
   | --- | --- | --- | --- | --- |
   | No pattern | All 7 | Not logged | 7 | ✔ |
   | `^(feat\|fix)/` | `feat/alpha`, `fix/beta` | 5 of 7 | 7 | ✔ |
   | Change to `^(feat\|fix\|hotfix)/` | Adds `hotfix/epsilon` | 4 of 7 | 7 | ✔ 
|
   | `(?i)^(feat\|fix)/` | Adds `FEAT/delta`, drops `hotfix` | 4 of 7 | 7 | ✔ |
   | Invalid `^(feat\|fix` | Unchanged | — | — | ✔ Save succeeds; triggering 
returns HTTP 400 `invalid prHeadRefPattern` and no pipeline is created |
   | Cleared / whitespace only | All rows again | Not logged | — | ✔ |
   | Matches nothing (`^nothing-matches/`) | 0 rows | 7 of 7 | — | ✔ |
   | Incremental collection after merging `feat/eta` and `chore/theta` | Only 
`feat/eta` added | 6 of 9 | 9 | ✔ Scheduled runs apply it too |
   
   Also confirmed:
   
   - Rows that no longer match are removed when the pattern changes.
   - The pipeline plan carries `prHeadRefPattern` only in the 
`calculateChangeLeadTime` stage, and leaves the key out when it is not set.
   - Deployments are unaffected: every MR in both projects links to its 
production deployment and has a `pr_deploy_time`.
   
   Grafana, with A set to `^(feat|fix)/`:
   
   | Dashboard / panel | A | B | Note |
   | --- | --- | --- | --- |
   | DORA → Deployment Frequency | Same | Same | Not affected ✔ |
   | DORA → Median Lead Time for Changes | 2.1 h | 2.1 h | Test MRs have 
similar durations, so equal medians are expected |
   | DORA Details – Lead Time for Changes → PR list | **3 PRs** | **9 PRs** | 
Only matching MRs are listed ✔ |
   | Engineering Throughput → PRs Opened / Merged | 10 / 9 | 10 / 9 | Not 
affected ✔ |
   | Engineering Throughput → PR Cycle Time | 0.69 h | 2.12 h | Excluded PRs 
are averaged in as 0 h; fixed by #9226 |
   
   Pre-existing issues seen during testing (not caused by this PR):
   
   | Item | What happens | Status |
   | --- | --- | --- |
   | Engineering Throughput PR time panels | PRs without a metrics row are 
averaged in as 0 h (0.69 h vs 2.12 h above) | #9225, fixed by #9226 |
   | GitLab `Convert MR Commits` runs before `Extract MR Commits` | On the 
first collection of a new MR, `pr_coding_time` is NULL; the next pipeline fills 
it in. Happens with or without a pattern, including in the control project | 
Not addressed here |
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to