blob: 158d15eb8ce58382ead019ba1f3bf5aa3967a835 [file] [log] [blame] [view]
---
title: "Project"
sidebar_position: 5
description: >
`Project` is **a set of [Scope](../Overview/KeyConcepts.md#data-scope) from different domains**, a way to group different resources, and it is crucial for some metric calculations like `Dora`.
---
# Summary
For some metric calculations such as the `DORA` metric, we often encounter situations requiring comprehensive calculations based on data from multiple data sources.
For example, we may use `GitLab` for code hosting, `Jenkins` for CI/CD, to calculate PR deployment cycle time, we need to know which `GitLab Projects` and `Jenkins Jobs` are related for correctness and performance reasons.
However, in most cases, we have multiple `GitLab Projects` / `Jenkins Jobs` that belong to different teams in our Apache DevLake database.
To distinguish them into different groups. The `Project` is introduced in v0.15. Essentially, a `project` consists of a set of [Scopes](../Overview/KeyConcepts.md#data-scope), i.e., a couple of `GitLab Projects`, `Jira Boards` or `Jenkins Jobs`, etc.
`Project` is **a set of [Scope](../Overview/KeyConcepts.md#data-scope) from different domains**, a way to group different resources, and it is crucial for some metric calculation like `Dora`.
Next, let us introduce `Project` in the following order:
- `Project` related models
- Related APIs that can be used to manipulate `Project` models
- The interface that needs to be implemented when developing various plugins to support the `Project`.
- The interface that needs to be implemented to develop the `Data Source Plugin`
- The interface that needs to be implemented to develop the `Metric Plugins`
# Models
To support project we contains the following three models:
- `projects` describes a project object, including its name, creation and update time and other basic information
- `project_metric_settings` describes what metric plugins a project had enabled.
- `project_mapping` describes the mapping relationship of project and scope, including the name of the projectthe table name of [Scope](../Overview/KeyConcepts.md#data-scope) and the row_id in the [Scope](../Overview/KeyConcepts.md#data-scope) table.
## projects
| **field** | **type** | **length** | **description** | **key** |
| ------------- | -------- | ---------- | ----------------------------- | ------- |
| `name` | varchar | 255 | name for project | PK |
| `description` | longtext | | description of the project | |
| `created_at` | datetime | 3 | created time of project | |
| `updated_at` | datetime | 3 | last updated time of project | |
### example
| **name** | **describe** | **created_at** | **updated_at** |
| --------- | ------------------------------------ | ----------------------- | ------------------------|
| project_1 | this is one of the test projects | 2022-11-01 01:22:13.000 | 2022-11-01 02:24:15.000 |
| project_2 | this is another project test project | 2022-11-01 01:23:29.000 | 2022-11-01 02:27:24.000 |
## project_metric_settings
| **field** | **type** | **length** | **description** | **key** |
| --------------- | -------- | ---------- | ---------------------------------------------------------- | ------- |
| `project_name` | varchar | 255 | name for project | PK |
| `plugin_name` | varchar | 255 | name for plugin | PK |
| `plugin_option` | longtext | | check if metric plugins have been enabled by the project | |
| `enable` | tinyint | 1 | if the metric plugins is enabled | |
### example
| **project_name** | **plugin_name** | **plugin_option** | **enable** |
| ---------------- | --------------- | ----------------- | ---------- |
| project_1 | dora | {} | true |
| project_2 | dora | {} | false |
## project_mapping
| **field** | **type** | **length** | **description** | **key** |
| -------------- | -------- | ---------- | ------------------------------------------------------------- | ------- |
| `project_name` | varchar | 255 | name for project | PK |
| `table` | varchar | 255 | the table name of [Scope](../Overview/KeyConcepts.md#data-scope) | PK |
| `row_id` | varchar | 255 | the row_id in the [Scope](../Overview/KeyConcepts.md#data-scope) table | PK |
### example
| **project_name** | **table** | **row_id** |
| ---------------- | --------- | ------------------------ |
| project_1 | Repo | gitlab:GithubRepo:1:lake |
| project_1 | Board | jira:JiraBoard:1:lake |
| project_2 | Repo | github:GithubRepo:1:lake |
# How to manage project via API
For API specification, please check the swagger doc(by visiting `[Your Config-UI Host]/api/swagger/index.html`).
Related endpoints:
1. /projects
2. /projects/:projectName/metrics
3. /plugins
# The interface that needs to be implemented
We divide plugins into two categories
- The first category is `Data Source Plugin`, such as `GitLab` `GitHub` `Jira` `Jenkins`, etc. These plugins collect data from various data sources
- The second category is `Metric Plugin`, such as `Dora`, etc. These plugins do not directly contact the data source but do secondary calculations based on the collected data after the `Data Source Plugin` works
## Data Source Plugin
For example `GitLab` `GitHub` `Jira` `Jenkins` etc.
These plugins, from various data sources, extract data into the database and store them, they deal directly with the data source, so we classify them as `Data Source Plugin`.
## the DataSourcePluginBlueprintV200 interface
`Data Source Plugin` needs to implement `DataSourcePluginBlueprintV200` interface to support `project`
The interface definition for this interface is as follows
```go
// DataSourcePluginBlueprintV200 extends the V100 to provide support for
// Project, so that complex metrics like DORA can be implemented based on a set
// of Data Scopes
type DataSourcePluginBlueprintV200 interface {
MakeDataSourcePipelinePlanV200(
connectionId uint64,
scopes []*BlueprintScopeV200,
syncPolicy BlueprintSyncPolicy,
) (PipelinePlan, []Scope, errors.Error)
}
```
`scopes` in input parameters is a set of arrays containing IDs, Names, and Entities.
The input data format is as follows:
```go
[]*core.BlueprintScopeV200{
{
Entities: []string{"CODE", "TICKET", "CICD"},
Id: "37",
Name: "test",
},
}
```
`syncPolicy` in input parameters contains some option settings, whose structure is defined as follows:
```go
type BlueprintSyncPolicy struct {
Version string `json:"version" validate:"required,semver,oneof=1.0.0"`
SkipOnFail bool `json:"skipOnFail"`
CreatedDateAfter *time.Time `json:"createdDateAfter"`
}
```
`PipelinePlan` in output is a part of blueprint JSON:
The input data format is as follows:(Take GitLab plugin as an example)
```go
core.PipelinePlan{
{
{
Plugin: "gitlab",
Subtasks: []string{
tasks.ConvertProjectMeta.Name,
tasks.CollectApiIssuesMeta.Name,
tasks.ExtractApiIssuesMeta.Name,
tasks.ConvertIssuesMeta.Name,
tasks.ConvertIssueLabelsMeta.Name,
tasks.CollectApiJobsMeta.Name,
tasks.ExtractApiJobsMeta.Name,
tasks.CollectApiPipelinesMeta.Name,
tasks.ExtractApiPipelinesMeta.Name,
},
Options: map[string]interface{}{
"connectionId": uint64(1),
"projectId": testID,
},
},
{
Plugin: "gitextractor",
Options: map[string]interface{}{
"proxy": "",
"repoId": repoId,
"url": "https://git:nddtf@this_is_cloneUrl",
},
},
},
{
{
Plugin: "refdiff",
Options: map[string]interface{}{
"tagsLimit": 10,
"tagsOrder": "reverse semver",
"tagsPattern": "pattern",
},
},
},
}
```
`project` needs to provide a specific set of [Scopes](../Overview/KeyConcepts.md#data-scope) for a specific `connection` to the plugin through this interface, and then obtain the plugin involved in the `PipelineTask` All `plugins` and corresponding parameter information. At the same time, the plugin needs to convert entities like `repo` and `board` in the data source into a `scope interface` that `project` can understand
The corresponding `scope interface` has been implemented at following files of in the framework layer:
- `models/domainlayer/devops/cicd_scope.go`
- `models/domainlayer/ticket/board.go`
- `models/domainlayer/code/repo.go`
In the `plugins/gitlab/impl/impl.go` file, there is a `GitLab` plugin implementation of the above interface, which can be used as a reference.
And the `plugins/gitlab/api/blueprint_v200.go` contains implementation details.
The following files contain the models that the relevant implementations depend on for reference:
- `plugins/gitlab/models/project.go`
- `plugins/gitlab/models/scope_config.go`
## Metric Plugins
For example `Dora`, and `Refdff` plugins belong to the `Metric Plugins`
These plugins are mainly for calculating various metrics, they do not directly contact the data source, so we classify them as `Metric Plugins`.
## The PluginMetric Interface
`Metric Plugins` needs to implement the `PluginMetric` interface to support `project`
The interface definition for this interface looks like this:
```go
type PluginMetric interface {
// returns a list of required data entities and expected features.
// [{ "model": "cicd_tasks", "requiredFields": {"column": "type", "execptedValue": "Deployment"}}, ...]
RequiredDataEntities() (data []map[string]interface{}, err errors.Error)
// returns if the metric depends on Project for calculation.
// Currently, only dora would return true.
IsProjectMetric() bool
// indicates which plugins must be executed before executing this one.
// declare a set of dependencies with this
RunAfter() ([]string, errors.Error)
// returns an empty pointer of the plugin setting struct.
// (no concrete usage at this point)
Settings() (p interface{})
}
```
`Project` needs `PluginMetric` to know whether a `Metric Plugin` is dependent on `project`, and the tables and fields required in its calculation process.
In the `plugins/dora/impl/impl.go` file, there is a `Dora` plugin implementation of the above interface, which can be used as a sample reference.You can find it by searching the following fields:
- `func (plugin Dora) RequiredDataEntities() (data []map[string]interface{}, err errors.Error)`
- `func (plugin Dora) IsProjectMetric() bool`
- `func (plugin Dora) RunAfter() ([]string, errors.Error)`
- `func (plugin Dora) Settings() interface{}`
## References
To dig deeper into developing and utilizing our built-in functions and have a better developer experience, feel free to dive into our [godoc](https://pkg.go.dev/github.com/apache/incubator-devlake) reference.