Skip to content

feat(dora): per-project DORA isolation for Jira boards shared by several projects - #9216

Open
kesamba wants to merge 6 commits into
apache:mainfrom
kesamba:feature/per-project-dora-isolation
Open

kesamba wants to merge 6 commits into
apache:mainfrom
kesamba:feature/per-project-dora-isolation

Conversation

@kesamba

@kesamba kesamba commented Oct 13, 2026

Copy link
Copy Markdown

Summary

When several DevLake projects point at the same Jira board and each narrows it with its own ExtraJQL, the DORA metrics that depend on incidents (Change Failure Rate, MTTR / failed deployment recovery time) counted the whole board for every project, so one project's incidents leaked into the others' numbers.

This PR records which project collected each board issue and filters on it end to end. It is split into commits that each build and pass tests on their own, so it can be reviewed commit by commit:

  1. feat(core): add project_name to board_issues: new project_name column, part of the primary key so an issue in two projects' slices can be linked once per project, with default ''. Migration 20260820. Existing e2e snapshots that verify board_issues gain the (empty) column.
  2. feat(jira): record the collecting project on board issues: project_name on _tool_jira_board_issues (migration 20260710) and ProjectName on JiraApiParams. The issue collector and extractor stamp the pipeline's project. ProjectName is omitempty in the serialized raw-data params, so pipelines without a project keep exactly the same params (no re-collection and no orphaned raw data on upgrade).
  3. feat(jira): convert only the current project's slice of a shared board: the issue convertor reads only the current project's tool rows and stamps the project on domain board_issues.
  4. fix(jira): resync the board when its ExtraJQL changes: the rendered ExtraJQL is folded into the board filter's change-detection key, so changing ExtraJQL triggers a full resync and issues that no longer match get unlinked from the board.
  5. feat(dora): scope incidents and deployment links to the project's slice: ConvertIssuesToIncidents and ConnectIncidentToDeployment filter on board_issues.project_name.
  6. feat(grafana): filter DORA incident panels by project: the same filter in the incident queries of the DORA dashboards (mysql: DORA, dora-by-team, dora-debug, dora-details-change-failure-rate, dora-details-failed-deployment-recovery-time, dora-details-timeto-restore-service; postgresql: DORA, dora-by-team).

Backward compatibility: if a board has no per-project stamps at all (single-project setups, or data collected before this change), every query keeps the previous whole-board behavior. If a board does have stamps, unstamped or NULL rows are treated as an ambiguous leftover pool and excluded, instead of being attributed to every project.

Does this close any open issues?

N/A

Screenshots

N/A

Other Information

  • New unit tests run the real production queries against an in-memory SQLite DB. This adds gorm.io/driver/sqlite as a direct dependency; it was already in go.sum.
    • plugins/jira/tasks/issue_convertor_project_filter_test.go
    • plugins/jira/tasks/issue_extractor_test.go (TestExtractIssuesStampsProjectName)
    • plugins/dora/tasks/incident_from_issue_generator_test.go
    • plugins/dora/tasks/incident_deploy_connector_test.go
  • The dora queries quote the reserved table column per dialect (backticks on MySQL, double quotes otherwise), so they run on MySQL, Postgres and SQLite.
  • The full upstream CI passed on the fork, including test-e2e on both MySQL and Postgres (all plugin e2e suites plus test/e2e/remote and test/e2e/services), golangci-lint, migration-script-lint and check-grafana-dashboards: [fork CI] feat(dora): per-project DORA isolation for shared Jira boards kesamba/devlake#1

🤖 Generated with Claude Code

kesamba and others added 6 commits October 13, 2026 11:24
Several DevLake projects can share one board and each collect their own
slice of it (e.g. via Jira ExtraJQL). Record which project a board/issue
link belongs to by adding project_name to board_issues. It is part of the
primary key so an issue that falls into two projects' slices can be
linked once per project.

Existing rows and plugins that do not set it get an empty project_name,
which keeps the previous single-project behaviour. The e2e snapshots that
verify board_issues gain the (empty) project_name column.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add project_name to _tool_jira_board_issues (part of the primary key) and
ProjectName to JiraApiParams. The issue collector and extractor stamp the
DevLake project the pipeline runs for, so a board shared by several
projects keeps each project's ExtraJQL slice apart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The issue convertor used to read every _tool_jira_board_issues row of the
board, so on a shared board one project's run converted (and stamped) the
other projects' issues too. Filter its input by project_name and stamp
the project on the domain board_issues row.

Boards without any per-project stamps (single-project or pre-feature
data) keep converting all of their issues. On a board that has stamps,
unstamped leftover rows are excluded rather than attributed to every
project.

Adds gorm.io/driver/sqlite (already in go.sum) for the in-memory tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The board filter collectors only compared the saved filter JQL to decide
whether a full resync is needed. Fold the rendered ExtraJQL into that key
so changing ExtraJQL also triggers a full resync, and issues that no
longer match are unlinked from the board instead of lingering in
board_issues.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ConvertIssuesToIncidents and ConnectIncidentToDeployment selected
incidents by board-level project_mapping only, so every project sharing a
board got every incident on it. Also filter on board_issues.project_name,
falling back to the whole board when it has no per-project stamps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Apply the same board_issues.project_name filter to the incident queries
of the DORA dashboards (mysql: DORA, dora-by-team, dora-debug and the
change-failure-rate / failed-deployment-recovery-time /
time-to-restore-service details; postgresql: DORA, dora-by-team), with
the same whole-board fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant