diff --git a/docs/GettingStarted/HelmSetup.md b/docs/GettingStarted/HelmSetup.md index 054f6b4d71d..db010dbcf31 100644 --- a/docs/GettingStarted/HelmSetup.md +++ b/docs/GettingStarted/HelmSetup.md @@ -45,7 +45,7 @@ To install the chart with release name `devlake`,follow these steps: ```shell helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart helm repo update - helm install devlake devlake/devlake --version=0.19.0-beta6 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET + helm install devlake devlake/devlake --version=0.20.0-beta8 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET ``` And visit your devlake from the node port (32001 by default). @@ -86,14 +86,14 @@ grafana by url `http://YOUR-NODE-IP:30091` ```shell helm repo update -helm upgrade devlake devlake/devlake --version=0.19.0-beta6 --set lake.encryptionSecret.secret= +helm upgrade devlake devlake/devlake --version=0.20.0-beta8 --set lake.encryptionSecret.secret= ``` **If you're upgrading from DevLake v0.18.x or later versions:** ```shell helm repo update -helm upgrade devlake devlake/devlake --version=0.19.0-beta6 +helm upgrade devlake devlake/devlake --version=0.20.0-beta8 ``` ### Uninstall diff --git a/versioned_docs/version-v0.19/GettingStarted/HelmSetup.md b/versioned_docs/version-v0.19/GettingStarted/HelmSetup.md index ed36c055ed4..c1b0d724294 100644 --- a/versioned_docs/version-v0.19/GettingStarted/HelmSetup.md +++ b/versioned_docs/version-v0.19/GettingStarted/HelmSetup.md @@ -45,7 +45,7 @@ To install the chart with release name `devlake`,follow these steps: ```shell helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart helm repo update - helm install devlake devlake/devlake --version=0.19.0-beta6 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET + helm install devlake devlake/devlake --version=0.19.0 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET ``` And visit your devlake from the node port (32001 by default). @@ -86,14 +86,14 @@ grafana by url `http://YOUR-NODE-IP:30091` ```shell helm repo update -helm upgrade devlake devlake/devlake --version=0.19.0-beta6 --set lake.encryptionSecret.secret= +helm upgrade devlake devlake/devlake --version=0.19.0 --set lake.encryptionSecret.secret= ``` **If you're upgrading from DevLake v0.18.x or later versions:** ```shell helm repo update -helm upgrade devlake devlake/devlake --version=0.19.0-beta6 +helm upgrade devlake devlake/devlake --version=0.19.0 ``` ### Uninstall diff --git a/versioned_docs/version-v0.20/GettingStarted/HelmSetup.md b/versioned_docs/version-v0.20/GettingStarted/HelmSetup.md index ed36c055ed4..63f94f24d90 100644 --- a/versioned_docs/version-v0.20/GettingStarted/HelmSetup.md +++ b/versioned_docs/version-v0.20/GettingStarted/HelmSetup.md @@ -45,7 +45,7 @@ To install the chart with release name `devlake`,follow these steps: ```shell helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart helm repo update - helm install devlake devlake/devlake --version=0.19.0-beta6 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET + helm install devlake devlake/devlake --version=0.20.0-beta8 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET ``` And visit your devlake from the node port (32001 by default). @@ -86,14 +86,14 @@ grafana by url `http://YOUR-NODE-IP:30091` ```shell helm repo update -helm upgrade devlake devlake/devlake --version=0.19.0-beta6 --set lake.encryptionSecret.secret= +helm upgrade devlake devlake/devlake --version=0.20.0-beta8 --set lake.encryptionSecret.secret= ``` **If you're upgrading from DevLake v0.18.x or later versions:** ```shell helm repo update -helm upgrade devlake devlake/devlake --version=0.19.0-beta6 +helm upgrade devlake devlake/devlake --version=0.20.0-beta8 ``` ### Uninstall diff --git a/versioned_docs/version-v0.21/Configuration/APIKeys.md b/versioned_docs/version-v0.21/Configuration/APIKeys.md new file mode 100644 index 00000000000..00077224163 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/APIKeys.md @@ -0,0 +1,34 @@ +--- +title: "API Keys" +sidebar_position: 31 +description: > + API Keys +--- +## What is an 'API Key' +![api-key-list](images/api-key-list.png) + +An API key, also known as an API token, is a string used for authentication when making requests to DevLake's open API or webhook. It serves as a form of identification to ensure authorized access. + +An API key contains three components: +1. Name: This is the descriptive name assigned to the key for easy identification. +2. Expiration: You have the option to set an expiration period for the API key, such as 7 days, 30 days, 90 days, or choose for it to never expire. +3. Allowed Path: The API URL or endpoint that the API key is permitted to access. It defines the specific resources that the key can interact with. + +## How does an API key work? +### Accessing DevLake Open APIs +Check out the [API docs](/docs/Overview/References.md). + +### Utilizing API Key in [Incoming Webhooks](webhook.md) +It is typically not necessary to manually create an API key from the 'API keys' page. Instead, you can follow these steps: + +1. Navigate to the 'Data Connection' page. +2. Create a new webhook, and an API key will be automatically generated for you. +3. You can copy the provided curl commands, which include the API key, and save them in your local environment for future use. +4. If you happen to forget to save the API key, do not worry. You can view the webhook details and regenerate a new API key if needed. It is important to note that the API keys automatically generated for webhooks will not be displayed on the 'API keys' page. + +![api-key-list](images/auto-generated-api-key.png) + + +## Troubleshooting + +If you run into any problems, please check the [Troubleshooting](/Troubleshooting/Installation.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/AdvancedMode.md b/versioned_docs/version-v0.21/Configuration/AdvancedMode.md new file mode 100644 index 00000000000..4d61e4c4f64 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/AdvancedMode.md @@ -0,0 +1,400 @@ +--- +title: "Blueprint Advanced Mode" +sidebar_position: 29 +description: > + Using the advanced mode of Config-UI +--- + +## Why advanced mode? + +Advanced mode allows users to create any pipeline by writing JSON. This is useful for users who want to: + +1. Collect multiple GitHub/GitLab repos or Jira projects within a single pipeline +2. Have fine-grained control over what entities to collect or what subtasks to run for each plugin +3. Orchestrate a complex pipeline that consists of multiple stages of plugins. + +Advanced mode gives utmost flexibility to users by exposing the JSON API. + +## How to use advanced mode to create pipelines? + +1. Click on "+ New Blueprint" on the Blueprint page. + +![image](/img/AdvancedMode/AdvancedMode1.png) + +2. In step 1, click on the "Advanced Mode" link. + +![image](/img/AdvancedMode/AdvancedMode2.png) + +3. The pipeline editor expects a 2D array of plugins. The first dimension represents different stages of the pipeline and the second dimension describes the plugins in each stage. Stages run in sequential order and plugins within the same stage runs in parallel. We provide some templates for users to get started. Please also see the next section for some examples. + +![image](/img/AdvancedMode/AdvancedMode3.png) + +4. You can choose how often you would like to sync your data in this step by selecting a sync frequency option or enter a cron code to specify your preferred schedule. After setting up the Blueprint, you will be prompted to the Blueprint's activity detail page, where you can track the progress of the current run and wait for it to finish before the dashboards become available. You can also view all historical runs of previously created Blueprints from the list on the Blueprint page. + +## Examples + +### 1. GitHub + +Collect multiple GitHub repos sequentially. Below is an example for collecting 2 GitHub repos sequentially. It has 2 stages, each contains a GitHub task. + +``` +[ + [ + { + "Plugin": "github", + "Options": { + "connectionId": 1, + "repo": "incubator-devlake", + "owner": "apache" + } + }, + { + "Plugin": "github", + "Options": { + "connectionId": 1, + "repo": "lake", + "owner": "merico-dev" + } + } + ] +] +``` + +GitHub: + +- `connectionId`: The ID of your GitHub connection at page http://localhost:4000/connections/github. +- `owner`: Just take a look at the URL: https://github.com/apache/incubator-devlake, owner is `apache`. +- `repo`: Just take a look at the URL: https://github.com/apache/incubator-devlake, repo is `incubator-devlake`. + +### 2. GitLab + +Collect multiple GitLab repos sequentially. + +> When there're multiple collection tasks against a single data source, we recommend running these tasks sequentially since the collection speed is mostly limited by the API rate limit of the data source. +> Running multiple tasks against the same data source is unlikely to speed up the process and may overwhelm the data source. + +Below is an example for collecting 2 GitLab repos sequentially. It has 2 stages, each contains a GitLab task. + +``` +[ + [ + { + "Plugin": "gitlab", + "Options": { + "connectionId": 1, + "projectId": 152***74 + } + } + ], + [ + { + "Plugin": "gitlab", + "Options": { + "connectionId": 2, + "projectId": 116***98 + } + } + ] +] +``` + +- `connectionId`: The ID of your GitLab connection at page http://localhost:4000/connections/gitlab. +- `projectId`: GitLab repo's Project ID. + +### 3. Jenkins + +Collect multiple Jenkins jobs sequentially. Below is an example for collecting 2 Jenkins jobs sequentially. It has 2 stages, each contains a Jenkins task. + +``` +[ + [ + { + "plugin": "jenkins", + "options": { + "connectionId": 1, + "scopeId": "auto_deploy" + } + } + ], + [ + { + "plugin": "jenkins", + "options": { + "connectionId": 2, + "scopeId": "Deploy test" + } + } + ] +] +``` + +- `connectionId`: The ID of your Jenkins connection at page http://localhost:4000/connections/jenkins. +- `scopeId`: Jenkins job name. + +### 4. Jira + +Collect multiple Jira boards sequentially. Below is an example for collecting 2 Jira boards sequentially. It has 2 stages, each contains a Jira task. + +``` +[ + [ + { + "plugin": "jira", + "options": { + "boardId": 8, + "connectionId": 1 + } + } + ], + [ + { + "plugin": "jira", + "options": { + "boardId": 26, + "connectionId": 1 + } + } + ] +] +``` + +- `connectionId`: The ID of your Jira connection at page http://localhost:4000/connections/jira. +- `boardId`: Just take a look at the URL - it will be the last number in the address. Should look something like this at the end: `RapidBoard.jspa?rapidView=8` or `/projects/xxx/boards/8`. So `8` would be the board ID in that case. + +### 5. Jira + GitLab + +Below is an example for collecting a GitLab repo and a Jira board in parallel. It has a single stage with a GitLab task and a Jira task. As GitLab and Jira are using their own tokens, they can be executed in parallel. + +``` +[ + [ + { + "plugin":"jira", + "options":{ + "boardId":8, + "connectionId":1 + } + } + ], + [ + { + "Plugin":"gitlab", + "Options":{ + "connectionId":1, + "projectId":116***98 + } + } + ] +] +``` + +### 6. TAPD + +Below is an example for collecting a TAPD workspace. Since users can configure multiple TAPD connection, it's required to pass in a `connectionId` for TAPD task to specify which connection to use. + +``` +[ + [ + { + "plugin": "tapd", + "options": { + "createdDateAfter": "2006-01-02T15:04:05Z", + "workspaceId": 34***66, + "connectionId": 1 + } + } + ] +] +``` + +- `createdDateAfter`: The data range you wish to collect after the given date. +- `connectionId`: The ID of your TAPD connection at page http://localhost:4000/connections/tapd. +- `workspaceId`: TAPD workspace id, you can get it from two ways: + - url: ![tapd-workspace-id](/img/ConfigUI/tapd-find-workspace-id.png) + - db: you can check workspace info from db.\_tool_tapd_workspaces and get all workspaceId you want to collect after execution of the following json in `advanced mode` + ```json + [ + [ + { + "plugin": "tapd", + "options": { + "companyId": 558***09, + "workspaceId": 1, + "connectionId": 1 + }, + "subtasks": ["collectCompanies", "extractCompanies"] + } + ] + ] + ``` + +### 7. TAPD + GitLab + +Below is an example for collecting a TAPD workspace and a GitLab repo in parallel. It has a single stage with a TAPD task and a GitLab task. + +``` +[ + [ + { + "plugin": "tapd", + "options": { + "createdDateAfter": "2006-01-02T15:04:05Z", + "workspaceId": 6***14, + "connectionId": 1 + } + } + ], + [ + { + "Plugin":"gitlab", + "Options":{ + "connectionId":1, + "projectId":116***98 + } + } + ] +] +``` + +### 8. Zentao + +Below is an example for collecting a Zentao workspace. Since users can configure multiple Zentao connection, it's required to pass in a `connectionId` for Zentao task to specify which connection to use. + +``` +[ + [ + { + plugin: 'zentao', + options: { + connectionId: 1, + productId: 1, + projectId: 1, + executionId: 1 + } + } + ] +] +``` + +- `connectionId`: The ID of your Zentao connection at page http://localhost:4000/connections/zentao. +- `productId`: optional, ZENTAO product id, see "Find Product Id" for details. +- `projectId`: optional, ZENTAO product id, see "Find Project Id" for details. +- `executionId`: optional, ZENTAO product id, see "Find Execution Id" for details. + +You must choose at least one of `productId`, `projectId` and `executionId`. + +#### Find Product Id + +1. Navigate to the Zentao Product in the browser + ![](/img/ConfigUI/zentao-product.png) +2. Click the red square annotated in the pic above + ![](/img/ConfigUI/zentao-product-id.png) +3. Then the number in the red circle above is `ProductId` + +#### Find Project Id + +1. Navigate to the Zentao Project in the browser + ![](/img/ConfigUI/zentao-project-id.png) +2. Then the number in the red square above is `ProjectId` + +#### Find Execution Id + +1. Navigate to the Zentao Execution in the browser + ![](/img/ConfigUI/zentao-execution-id.png) +2. Then the number in the red square above is `ExecutionId` + +### 9. BitBucket + +Below is an example for collecting a bitbucket repo. + +```json +[ + [ + { + "plugin": "bitbucket", + "options": { + "connectionId": 1, + "owner": "apache", + "repo": "devlake" + } + } + ] +] +``` + +- `connectionId`: The ID of your bitbucket connection at page http://localhost:4000/connections/bitbucket. +- `owner`: the owner of the repository. +- `repo`: the bitbucket repository name. + +### 10. SonarQube + +Below is an example for collecting a SonarQube project. + +```json +[ + [ + { + "plugin": "sonarqube", + "options": { + "connectionId": 1, + "projectKey": "testDevLake" + } + } + ] +] +``` + +- `connectionId`: The ID of your SonarQube connection at page http://localhost:4000/connections/sonarqube. +- `projectKey`: The project key of the SonarQube. To find the project key in SonarQube, please follow the steps: + - 1. Log in to the SonarQube management page. + - 2. Find the project for which you want to find the project key. + - 3. Click on the project name to enter the project homepage. + - 4. In the top menu bar of the project homepage, select "Project Information". + - 5. On the "Project Information" page, you will see the project key. + + +### 11. Teambition + +Below is an example for collecting a Teambition project. Since users can configure multiple Teambition connection, it's required to pass in a `connectionId` for Teambition task to specify which connection to use. + +```json +[ + [ + { + "plugin": "teambition", + "options": { + "createdDateAfter": "2006-01-02T15:04:05Z", + "projectId": "5e5****376", + "connectionId": 1 + } + } + ] +] +``` + +- `connectionId`: The ID of your Teambition connection at page http://localhost:4000/connections/teambition. +- `projectId`: Teambition project id, you can get it from url: ![image](https://user-images.githubusercontent.com/3294100/229808849-66dac8c0-5ff6-459b-850c-62bc60a3a519.png) + +## Editing a Blueprint (Advanced Mode) + +This section is for editing a Blueprint in the Advanced Mode. To edit in the Normal mode, please refer to [this guide](Tutorial.md#editing-a-blueprint-normal-mode). + +To edit a Blueprint created in the Advanced mode, you can simply go the Configuration page of that Blueprint and edit its configuration. + +![img](/img/ConfigUI/BlueprintEditing/blueprint-edit2.png) + +## How to skip collectors in a Blueprint (Advanced Mode)? +- 1. Create a Blueprint in the Advanced Mode. +- 2. You can skip collectors in a Blueprint by setting `skipCollectors` to `true` in the request body of the trigger API. For example: +``` + curl --request POST \ + --url http://localhost:8080/blueprints/:blueprintId/trigger \ + --header 'content-type: application/json' \ + --data '{ + "skipCollectors": true + }' +``` + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/AzureDevOps.md b/versioned_docs/version-v0.21/Configuration/AzureDevOps.md new file mode 100644 index 00000000000..55374b36eb9 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/AzureDevOps.md @@ -0,0 +1,95 @@ +--- +title: "Azure DevOps" +sidebar_position: 5 +description: Config UI instruction for Azure DevOps +--- + +Visit Config UI at: `http://localhost:4000`. + +## Step 1 - Add Data Connections + +On the Connections page, you can select GitHub and create a new connection or it. + +### Step 1.1 - Authentication + +![azuredevops-create-a-connection](images/azuredevops-create-a-connection.png) + +#### Connection Name + +Give your connection a unique name to help you identify it in the future. + +#### Token + +Paste your Azure DevOps personal access token (PAT) here. Check [Azure's official doc](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#create-a-pat) on how to create a PAT. +Make sure that the Organization field is set to "All accessible organizations" when creating the PAT. + +#### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +### Step 1.2 - Add Data Scopes + +![azuredevops-set-data-scope](images/azuredevops-set-data-scope.png) + +#### Select repositories + +Select the repositories you want to collect data from. + +#### Data Entities + +Azure DevOps supports the following data entities. + +- CI/CD: builds and jobs. +- Source Code Management: repositories and their commits. +- Code Review: pull requests and their commits. + + +### Step 1.3 - Add Scope Config (Optional) + +Scope config contains two parts: +- The entities of which domain you wish to collect: Usually, you don't have to modify this part. However, if you don't want to collect certain Azure DevOps entities, you can unselect some entities to accelerate the collection speed. + - Source Code Management: Azure repos, refs, commits, etc. + - Code Review: Azure PRs, PR comments and reviews, etc. + - CI/CD: Azure pipelines, jobs, etc. + - Cross Domain: Azure accounts, etc. +- The transformations on the Azure DevOps data you are going to collect. + + +The transformations are mainly used for calculating [DORA metrics](../DORA.md), so DevLake needs to know what are `deployments` in your Azure Pipelines. You can configure: + - Regex for `Deployments`: Azure DevOps pipeline or one of its jobs whose names match this regex will be registered as deployments in DevLake + - Regex for `Production` environment: Azure DevOps pipeline or one of its jobs whose names match this regex will be considered as a PRODUCTION deployment. + +![azuredevops-set-transformation](images/azuredevops-set-transformation.png) + +The additional settings for transformations are RefDiff options: +- Tags Limit: the number of tags to compare. +- Tags Pattern: Only tags that match the given regex are taken into account. + +## Step 2 - Collect Data in a Project +### Step 2.1 - Create a Project +Collecting Azure DevOps data requires creating a project first. You can visit the Project page from the side menu and create a new project by following the instructions on the user interface. + +![create-a-project](images/create-a-project.png) + +### Step 2.2 - Add a Azure DevOps Connection +You can add a previously configured GitLab connection to the project and select the boards for which you wish to collect the data for. +Please note: if you don't see the repositories you are looking for, please check if you have added them to the connection first. + +![add-a-connection](images/add-a-connection-project.png) + +### Step 2.3 - Set the Sync Policy +There are three settings for Sync Policy: +- Data Time Range: You can select the time range of the data you wish to collect. The default is set to the past six months. +- Sync Frequency: You can choose how often you would like to sync your data in this step by selecting a sync frequency option or entering a cron code to specify your prefered schedule. +- Skip Failed Tasks: sometime a few tasks may fail in a long pipeline; you can choose to skip them to avoid spending more time in running the pipeline all over again. + +![sync-policy](images/sync-policy.png) + +### Step 2.4 - Start Data Collection +Click on "Collect Data" to start collecting data for the whole project. You can check the status in the Status tab on the same page. +![collect-data](images/collect-data.png) + + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/BitBucket.md b/versioned_docs/version-v0.21/Configuration/BitBucket.md new file mode 100644 index 00000000000..cf69391ddb9 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/BitBucket.md @@ -0,0 +1,148 @@ +--- +title: "BitBucket Cloud" +sidebar_position: 7 +description: Config UI instruction for BitBucket(Cloud) +--- + +Visit Config UI at : `http://localhost:4000` and go to `Connections` page. + +## Step 1 - Add Data Connections + +![image](https://user-images.githubusercontent.com/3294100/220118398-2d08070f-0edb-4de6-8696-9ee58b80719b.png) + +### Connection Name + +Give your connection a unique name to help you identify it in the future. + +### Endpoint URL + +For BitBucket Cloud, you do not need to enter the REST API endpoint URL, which is always `https://api.bitbucket.org/2.0/`. + +DevLake will support BitBucket Server in the future. + +### Username and App Password + +Learn about [how to create a BitBucket app password](https://support.atlassian.com/bitbucket-cloud/docs/create-an-app-password/). + +The following permissions are required to collect data from BitBucket repositories: + +- Account:Read +- Workspace membership:Read +- Projects:Read +- Repositories:Read +- Pull requests:Read +- Issues:Read +- Pipelines:Read +- Runners:Read + +![bitbucket-app-password-permissions](/img/ConfigUI/bitbucket-app-password-permissions.jpeg) + + +### Proxy URL (Optional) + +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + + +### Fixed Rate Limit (Optional) + +DevLake uses a dynamic rate limit to collect BitBucket data. You can adjust the rate limit if you want to increase or lower the speed. + +The maximum rate limit for different entities in BitBucket(Cloud) [varies from 1,000 - 60,000 requests/hour](https://support.atlassian.com/bitbucket-cloud/docs/api-request-limits/). The rate limit to access repository data is 1,000 requests/hour, but we find it can still run when we input a value that exceeds 1,000. You can try using a larger rate limit if you have large repositories. + + + + +### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +## Step 2 - Configure Blueprint + +![image](https://user-images.githubusercontent.com/14050754/224308925-449a4d3e-ed52-45e9-bb72-0d2892df374f.png) + +### Repositories + +Select the BitBucket repositories to collect. + +### Data Entities + +Usually, you don't have to modify this part. However, if you don't want to collect certain BitBucket entities, you can unselect some entities to accelerate the collection speed. + +- Issue Tracking: BitBucket issues, issue comments, etc. +- Source Code Management: BitBucket repos, refs, commits, etc. +- Code Review: BitBucket PRs, PR comments, etc. +- CI/CD: BitBucket Pipelines, BitBucket Deployments, etc. +- Cross Domain: BitBucket accounts, etc. + + +## Step 3 - Adding Transformation Rules (Optional) +You can add a `transformation` to standardize the data. A `transformation` acts on the BitBucket data in the [tool layer](/docs/DataModels/ToolLayerSchema.md), transforming it to the [domain layer](/docs/DataModels/DevLakeDomainLayerSchema.md). + +### Issue Tracking + +**Issue Status Mapping**
+![image](https://user-images.githubusercontent.com/14050754/224309704-b096c256-b2cf-4107-b78c-044d06b5f23c.png) + +The given settings transformed the BitBucket issue statuses to the issue statuses used by DevLake, enabling you to measure metrics like the Issue Delivery Rate on the pre-built dashboards, as DevLake understands your definition of when an issue is considered as completed (status = 'DONE'). + +- TODO: The issues that are planned but have not been worked on yet +- IN-PROGRESS: The issues that are work-in-progress +- DONE: The issues that are completed +- OTHER: Other issues statuses that do not belong to the three statuses above + +The original status will be saved in the column `original_status` of the table 'issues', and the new status will be saved in the column `status` of the same table. + +**Issue Type Mapping**
+DevLake will convert the issue types of 'enhancement', 'proposal', and 'task' from BitBucket into the new issue type 'REQUIREMENT' for DevLake. In contrast, any issues classified as 'bug' in BitBucket will be converted into the new issue type 'BUG' for DevLake. The original type will be saved in the column `original_type` of the table 'issues', and the new type will be saved in the column `type` of the same table. + +### CI/CD +The CI/CD configuration for BitBucket is used for calculating [DORA metrics](../DORA.md). + +By default, DevLake will identify the deployment and environment settings that are defined in the BitBucket CI .yml file. + +![image](https://user-images.githubusercontent.com/14050754/224311429-31304867-8cdd-476b-8675-e4acbc17f552.png) + +However, to ensure this works properly, you must specify the deployment settings in the .yml file. +![img_v2_89602d14-a733-4679-9d4b-d9635c03bc5g](https://user-images.githubusercontent.com/3294100/221528908-4943b1e6-1398-49e9-8ce9-aa264995f9bc.jpg) + +The pipeline steps with the `deployment` key will be recognized as DevLake deployments. The value of the `deployment` key will be recognized as the environment of DevLake deployments. + +All BitBucket pipeline steps will be saved in table 'cicd_tasks', but DevLake deployments will be set as `type` = 'deployment' and `environment` = '{BitBucket-pipeline-step.deployment.value}'. + +If you have not defined these settings in the .yml file, please select 'Detect Deployments from Pipeline steps in BitBucket', and input the RegEx in the following fields: + +![image](https://user-images.githubusercontent.com/14050754/224310350-cc9a4901-476d-4583-ad73-4d3b394bc343.png) + +- Deployment: A pipeline step with a name that matches the given RegEx will be recognized as a DevLake deployment. +- Production: A pipeline step with a name that matches the given RegEx will be recognized as a DevLake cicd_task in the production environment. + +**Introduction to BitBucket CI entities**
+BitBucket has several key CI entities: `pipelines`, `pipeline steps`, and `deployments`. A Bitbucket pipeline contains several pipeline steps. Each pipeline step defined with a deployment key can be mapped to a BitBucket deployment. + +Each Bitbucket pipeline is converted to a cicd_pipeline in DevLake's domain layer schema and each Bitbucket pipeline step is converted to a cicd_task in DevLake's domain layer. +![image](https://user-images.githubusercontent.com/3294100/220288225-71bee07d-c319-45bd-98e5-f4d01359840e.png) + +If a pipeline step defines `deployment` with a value (usually indicating the environment), this pipeline step is also a BitBucket deployment. + +![image](https://user-images.githubusercontent.com/3294100/221887426-4cae1c46-31ce-4fcd-b773-a54c28af0264.png) + +### Additional Settings (Optional) + +- Tags Limit: DevLake compares the last N pairs of tags to get the "commit diff', "issue diff" between tags. N defaults to 10. + + - commit diff: new commits for a tag relative to the previous one + - issue diff: issues solved by the new commits for a tag relative to the previous one + +- Tags Pattern: Only tags that meet the given Regular Expression will be counted. + +- Tags Order: Only "reverse semver" order is supported for now. + +Please click `Save` to save the transformation rules for the repo. In the data scope list, click `Next Step` to continue configuring. + +## Step 4 - Setting Sync Policy + +You can choose how often you would like to sync your data in this step by selecting a sync frequency option or entering a cron code to specify your prefered schedule. + +## Troubleshooting + +If you run into any problems, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues). diff --git a/versioned_docs/version-v0.21/Configuration/CircleCI.md b/versioned_docs/version-v0.21/Configuration/CircleCI.md new file mode 100644 index 00000000000..4cafaefd68f --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/CircleCI.md @@ -0,0 +1,86 @@ +--- +title: "CircleCI" +sidebar_position: 8 +description: Config UI instruction for CircleCI +--- + +Visit Config UI at : `http://localhost:4000` and go to `Connections` page. + +## Step 1 - Add Data Connections + +### Step 1.1 - Authentication + +![image](/img/ConfigUI/circleci-add-data-connections.png) + +#### Connection Name + +Give your connection a unique name to help you identify it in the future. + +#### Endpoint URL + +For CircleCI, you do not need to enter the REST API endpoint URL, which is always `https://circleci.com/api/`. + + +#### Token + +Learn about [Managing API Tokens](https://circleci.com/docs/managing-api-tokens/). + +Tokens you have generated that can be used to access the CircleCI API. Apps using these tokens can act as you and have full read- and write-permissions! +There are two types of API token(Personal and Project) you can create within CircleCI. + + +#### Proxy URL (Optional) + +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + + +#### Fixed Rate Limit (Optional) + +DevLake uses a dynamic rate limit to collect CircleCI data. You can adjust the rate limit if you want to increase or lower the speed. +Learn more about [CircleCI API rate limit](https://circleci.com/docs/api-developers-guide/#rate-limits). + + +#### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +### Step 1.2 - Configure Data Scope + +![image](/img/ConfigUI/circleci-choose-data-scope.png) + +#### Projects + +Select the CircleCI projects to collect. + +### Step 1.3 - Adding Scope Config (Optional) +![image](/img/ConfigUI/circleci-scope-config.png) +You can add a `transformation` to standardize the data. A `transformation` acts on the CircleCI data in the [tool layer](/docs/DataModels/ToolLayerSchema.md), transforming it to the [domain layer](/docs/DataModels/DevLakeDomainLayerSchema.md). + +## Step 2 - Collect Data in a Project +### Step 2.1 - Create a Project +Collecting CircleCI data requires creating a project first. You can visit the Project page from the side menu and create a new project by following the instructions on the user interface. + +![create-a-project](images/create-a-project.png) + +### Step 2.2 - Add a CircleCI Connection +You can add a previously configured CircleCI connection to the project and select the boards for which you wish to collect the data for. +Please note: if you don't see the repositories you are looking for, please check if you have added them to the connection first. + +![add-a-connection](images/add-a-connection-project.png) + +### Step 2.3 - Set the Sync Policy +There are three settings for Sync Policy: +- Data Time Range: You can select the time range of the data you wish to collect. The default is set to the past six months. +- Sync Frequency: You can choose how often you would like to sync your data in this step by selecting a sync frequency option or enter a cron code to specify your preferred schedule. +- Skip Failed Tasks: sometime a few tasks may fail in a long pipeline; you can choose to skip them to avoid spending more time in running the pipeline all over again. + +![sync-policy](images/sync-policy.png) + +### Step 2.4 - Start Data Collection +Click on "Collect Data" to start collecting data for the whole project. You can check the status in the Status tab on the same page. +![collect-data](images/collect-data.png) + + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/Dashboards/AccessControl.md b/versioned_docs/version-v0.21/Configuration/Dashboards/AccessControl.md new file mode 100644 index 00000000000..500fd0d3855 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Dashboards/AccessControl.md @@ -0,0 +1,44 @@ +--- +title: "Dashboard Access Control" +sidebar_position: 2 +description: > + Dashboard Access Control +--- + + +# Dashboard Access Control + +This tutorial shows how to leverage Grafana's role-based access control (RBAC) to manage what dashboards a user has access to. If you're setting up a single DevLake instance to be shared by multiple teams in your organization, this tutorial can help you achieve data segregation between teams. + +## Example solution: one folder for each team + +One of the simplest solutions is to create one Grafana folder for each team and assign permissions to teams at the folder level. Below is a step-by-step walk through. + +1. Sign in as Grafana admin and create a new folder + +![create-new-folder](/img/Grafana/create-new-folder.png) + +2. Click "Permissions" tab and remove the default access of "Editor (Role)" and "Viewer (Role)" + +![folder-permission](/img/Grafana/folder-permission.png) + +After removing default permissions: + +![after-remove-default-permissions](/img/Grafana/after-remove-default-permissions.png) + + +3. Add "View" permission to the target team (you'll need to create this team in Grafana first) + +![add-team-permission](/img/Grafana/add-team-permission.png) + +4. Copy/move dashboards into this folder (you may need to edit the dashboard so that it only shows data belongs to this team) + +## Reference + +1. [Manage dashboard permissions by Grafana](https://grafana.com/docs/grafana/latest/administration/user-management/manage-dashboard-permissions/#grant-dashboard-folder-permissions) + + + + + + diff --git a/versioned_docs/version-v0.21/Configuration/Dashboards/GrafanaUserGuide.md b/versioned_docs/version-v0.21/Configuration/Dashboards/GrafanaUserGuide.md new file mode 100644 index 00000000000..127db67e6a6 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Dashboards/GrafanaUserGuide.md @@ -0,0 +1,135 @@ +--- +title: "Grafana User Guide" +sidebar_position: 2 +description: > + Grafana User Guide +--- + + +# Grafana + + + +When first visiting Grafana, you will be provided with a sample dashboard with some basic charts setup from the database. + +## Contents + +Section | Link +:------------ | :------------- +Logging In | [View Section](#logging-in) +Viewing All Dashboards | [View Section](#viewing-all-dashboards) +Customizing a Dashboard | [View Section](#customizing-a-dashboard) +Dashboard Settings | [View Section](#dashboard-settings) +Provisioning a Dashboard | [View Section](#provisioning-a-dashboard) +Troubleshooting DB Connection | [View Section](#troubleshooting-db-connection) + +## Logging In + +Once the app is up and running, visit `http://localhost:3002` to view the Grafana dashboard. + +Default login credentials are: + +- Username: `admin` +- Password: `admin` + +## Viewing All Dashboards + +To see all dashboards created in Grafana visit `/dashboards` + +Or, use the sidebar and click on **Manage**: + +![Screen Shot 2021-08-06 at 11 27 08 AM](https://user-images.githubusercontent.com/3789273/128534617-1992c080-9385-49d5-b30f-be5c96d5142a.png) + +## Importing a Dashboard +If you want to import a dashboard to Grafana which you have backed up earlier, please follow the steps below: + +1. Click the `Import` icon +2. Click the `Upload JSON file` button +3. If the dashboard conflicts with an existing one, please change the `Name` and `uid` +4. Click `Import` + +![grafana-sections](../images/upload-dashboard.png) + + +## Customizing a Dashboard + +When viewing a dashboard, click the top bar of a panel, and go to **edit** + +![Screen Shot 2021-08-06 at 11 35 36 AM](https://user-images.githubusercontent.com/3789273/128535505-a56162e0-72ad-46ac-8a94-70f1c7a910ed.png) + +**Edit Dashboard Panel Page:** + +![grafana-sections](https://user-images.githubusercontent.com/3789273/128540136-ba36ee2f-a544-4558-8282-84a7cb9df27a.png) + +### 1. Preview Area +- **Top Left** is the variable select area (custom dashboard variables, used for switching projects, or grouping data) +- **Top Right** we have a toolbar with some buttons related to the display of the data: + - View data results in a table + - Time range selector + - Refresh data button +- **The Main Area** will display the chart and should update in real time + +> Note: Data should refresh automatically, but may require a refresh using the button in some cases + +### 2. Query Builder +Here we form the SQL query to pull data into our chart, from our database +- Ensure the **Data Source** is the correct database + + ![Screen Shot 2021-08-06 at 10 14 22 AM](https://user-images.githubusercontent.com/3789273/128545278-be4846e0-852d-4bc8-8994-e99b79831d8c.png) + +- Select **Format as Table**, and **Edit SQL** buttons to write/edit queries as SQL + + ![Screen Shot 2021-08-06 at 10 17 52 AM](https://user-images.githubusercontent.com/3789273/128545197-a9ff9cb3-f12d-4331-bf6a-39035043667a.png) + +- The **Main Area** is where the queries are written, and in the top right is the **Query Inspector** button (to inspect returned data) + + ![Screen Shot 2021-08-06 at 10 18 23 AM](https://user-images.githubusercontent.com/3789273/128545557-ead5312a-e835-4c59-b9ca-dd5c08f2a38b.png) + +### 3. Main Panel Toolbar +In the top right of the window are buttons for: +- Dashboard settings (regarding entire dashboard) +- Save/apply changes (to specific panel) + +### 4. Grafana Parameter Sidebar +- Change chart style (bar/line/pie chart etc) +- Edit legends, chart parameters +- Modify chart styling +- Other Grafana specific settings + +## Dashboard Settings + +When viewing a dashboard click on the settings icon to view dashboard settings. Here are 2 important sections to use: + +![Screen Shot 2021-08-06 at 1 51 14 PM](https://user-images.githubusercontent.com/3789273/128555763-4d0370c2-bd4d-4462-ae7e-4b140c4e8c34.png) + +- Variables + - Create variables to use throughout the dashboard panels, that are also built on SQL queries + + ![Screen Shot 2021-08-06 at 2 02 40 PM](https://user-images.githubusercontent.com/3789273/128553157-a8e33042-faba-4db4-97db-02a29036e27c.png) + +- JSON Model + - Copy `json` code here and save it to a new file in `/grafana/dashboards/` with a unique name in the `lake` repo. This will allow us to persist dashboards when we load the app + + ![Screen Shot 2021-08-06 at 2 02 52 PM](https://user-images.githubusercontent.com/3789273/128553176-65a5ae43-742f-4abf-9c60-04722033339e.png) + +## Provisioning a Dashboard + +To save a dashboard in the `lake` repo and load it: + +1. Create a dashboard in browser (visit `/dashboard/new`, or use sidebar) +2. Save dashboard (in top right of screen) +3. Go to dashboard settings (in top right of screen) +4. Click on _JSON Model_ in sidebar +5. Copy code into a new `.json` file in `/grafana/dashboards` + +## Troubleshooting DB Connection + +To ensure we have properly connected our database to the data source in Grafana, check database settings in `./grafana/datasources/datasource.yml`, specifically: +- `database` +- `user` +- `secureJsonData/password` + + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Dashboard.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/Dashboards/_category_.json b/versioned_docs/version-v0.21/Configuration/Dashboards/_category_.json new file mode 100644 index 00000000000..eef7e419cb4 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Dashboards/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Dashboard Configuration", + "position": 37 +} diff --git a/versioned_docs/version-v0.21/Configuration/GitHub.md b/versioned_docs/version-v0.21/Configuration/GitHub.md new file mode 100644 index 00000000000..0128e2ea2af --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/GitHub.md @@ -0,0 +1,209 @@ +--- +title: "GitHub" +sidebar_position: 9 +description: Config UI instruction for GitHub +--- + +Visit Config UI at: `http://localhost:4000`. + +## Step 1 - Add Data Connections + +On the Connections page, you can select GitHub and create a new connection or it. + +### Step 1.1 - Authentication +![github-add-data-connections](images/github-create-a-connection.png) + +#### Connection Name + +Give your connection a unique name to help you identify it in the future. + +#### Endpoint URL + +This should be a valid REST API endpoint, e.g. `https://api.github.com/`. The URL should end with `/`. + +#### Personal Access Token(s) + +You can use one of the following GitHub tokens: personal access tokens(PATs) or fine-grained personal access tokens. + +##### GitHub Personal Access Tokens(Recommended) + +> Prerequisites: please make sure your organization has enabled Personal Access Token before configuration. See the [detailed doc](https://docs.github.com/en/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization). + +Learn about [how to create a GitHub personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token). The following permissions are required to collect data from repositories: + +- `repo:status` +- `repo_deployment` +- `read:user` +- `read:org` + +However, if you want to collect data from private repositories, the following permissions are required: + +- `repo` +- `read:user` +- `read:org` + +The difference is that you have to give full permission for `repos`, not just `repo:status` and `repo_deployment`. Starting from v0.18.0, DevLake provides the auto-check for the permissions of your token(s). + +The data collection speed is restricted by the **rate limit of [5,000 requests](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting) per hour per token** (15,000 requests/hour if you pay for GitHub enterprise). You can accelerate data collection by configuring _multiple_ personal access tokens. Please note that multiple tokens should be created by different GitHub accounts. Tokens belonging to the same GitHub account share the rate limit. + +##### Fine-grained Personal Access Tokens + +Note: this token doesn't support GraphQL APIs. You have to disable `Use GraphQL APIs` on the connection page if you want to use it. However, this will significantly increase the data collection time. + +If you're concerned with giving classic PATs full unrestricted access to your repositories, you can use fine-grained PATs announced by GitHub recently. With fine-grained PATs, GitHub users can create read-only PATs that only have access to repositories under certain GitHub orgs. But in order to do that, org admin needs to enroll that org with fine-grained PATs beta feature first. Please check [this doc](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-fine-grained-personal-access-token) for more details. +The token should be granted read-only permission for the following entities. + - `Actions` + - `Contents` + - `Discussions` + - `Issues` + - `Metadata` + - `Pull requests` + + +##### GitHub Apps +Learn about [how to create a GitHub Apps](https://docs.github.com/en/apps/maintaining-github-apps/modifying-a-github-app-registration#navigating-to-your-github-app-settings). The following permissions are required to collect data from repositories: +- Repository + - Actions + - Administration + - Checks + - Commit statuses + - Contents + - Deployments + - Issues + - Metadata + - Pull requests +- Organization + - Members + + +#### Use Graphql APIs + +If you are using `github.com` or your on-premise GitHub version supports GraphQL APIs, toggle on this setting to collect data quicker. + +- GraphQL APIs are 10+ times faster than REST APIs, but they may not be supported in GitHub on-premise versions. +- Instead of using multiple tokens to collect data, you can use ONLY ONE token because GraphQL APIs are quick enough. + +#### Proxy URL (Optional) + +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + +#### Fixed Rate Limit (Optional) + +DevLake uses a dynamic rate limit to collect GitHub data. You can adjust the rate limit if you want to increase or lower the speed. + +The maximum rate limit for GitHub is ** [5,000 requests/hour](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting)** (15,000 requests/hour if you pay for GitHub enterprise). Please do not use a rate that exceeds this number. + +#### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +### Step 1.2 - Add Data Scopes + +#### Repositories + +Choose the GitHub repositories you wish to collect either by finding them in the miller column, or searching. You can only add public repositories through the search box. + + +![github-set-data-scope](images/github-add-data-scopes.png) + + +### Step 1.3 - Add Scope Config (Optional) +Scope config contains two parts: +- The entities of which domain you wish to collect: Usually, you don't have to modify this part. However, if you don't want to collect certain GitHub entities, you can unselect some entities to accelerate the collection speed. + - Issue Tracking: GitHub issues, issue comments, issue labels, etc. + - Source Code Management: GitHub repos, refs, commits, etc. + - Code Review: GitHub PRs, PR comments and reviews, etc. + - CI/CD: GitHub Workflow runs, GitHub Workflow jobs, etc. + - Cross Domain: GitHub accounts, etc. +- The transformations on the GitHub data you are going to collect. + - The details of the transformations will be explained below. + - Without adding transformation rules, you can still view the "[GitHub Metrics](/livedemo/DataSources/GitHub)" dashboard. However, if you want to view "[Weekly Bug Retro](/livedemo/QAEngineers/WeeklyBugRetro)", "[Weekly Community Retro](/livedemo/OSSMaintainers/WeeklyCommunityRetro)" or other pre-built dashboards, the following transformation rules, especially "Type/Bug", should be added. + - Each GitHub repo has at most ONE set of transformations. + +![github-add-transformation-rules-list](images/github-scope-config.png) +![github-add-transformation-rules](images/github-set-transformation2.png) + +#### Issue Tracking + +- Severity: Parse the value of `severity` from issue labels. + + - when your issue labels for severity level are like 'severity/p0', 'severity/p1', 'severity/p2', then input 'severity/(.\*)$' + - when your issue labels for severity level are like 'p0', 'p1', 'p2', then input '(p0|p1|p2)$' + +- Component: Same as "Severity". + +- Priority: Same as "Severity". + +- Type/Requirement: The `type` of issues with labels that match given regular expression will be set to "REQUIREMENT". Unlike "PR.type", submatch does nothing, because for issue management analysis, users tend to focus on 3 kinds of types (Requirement/Bug/Incident), however, the concrete naming varies from repo to repo, time to time, so we decided to standardize them to help analysts metrics. + +- Type/Bug: Same as "Type/Requirement", with `type` setting to "BUG". + +- Type/Incident: Same as "Type/Requirement", with `type` setting to "INCIDENT". + +#### CI/CD + +This set of configurations is used to define 'deployments'. Deployments are related to measure [DORA metrics](../DORA.md). + +For GitHub deployments, DevLake recognizes them as deployments by specifying a regular expression (regex) to identify the production environments among all 'GitHub environments'. + +If your deployments are not performed through GitHub deployments but rather specific workflow runs in GitHub, you have the option to convert a workflow run into a DevLake deployment. In this case, you need to configure two regular expressions (regex): + +- Deployment: The given regex should match the name of the GitHub workflow run or one of its jobs to be considered as a deployment. For example, if the workflow run used for deployment is named 'build-and-push-image', you can input (push-image). To make the regex case insensitive, you can include (?i) before the regex. +- Production: The given regex should match either the workflow run's name or its branch's name to be considered a deployment within the production environment. For instance: + - If the workflow run used for deployment is named 'build-to-prod', you can input (prod). To make the regex case insensitive, you can include (?i) before the regex. + - Also, many users in GitHub utilize the same workflow for both staging and prod deployments, executing it on the release branch would indicate a production deployment. + +![github-action-run](/img/ConfigUI/github-action-run.png) +![github-action-job](/img/ConfigUI/github-action-job.png) + +#### Code Review + +- Type: The `type` of pull requests will be parsed from PR labels by given regular expression. For example: + + - when your labels for PR types are like 'type/feature-development', 'type/bug-fixing' and 'type/docs', please input 'type/(.\*)$' + - when your labels for PR types are like 'feature-development', 'bug-fixing' and 'docs', please input '(feature-development|bug-fixing|docs)$' + +- Component: The `component` of pull requests will be parsed from PR labels by given regular expression. + +#### Additional Settings (Optional) + +- Tags Limit: It'll compare the last N pairs of tags to get the "commit diff", "issue diff" between tags. N defaults to 10. + + - commit diff: new commits for a tag relative to the previous one + - issue diff: issues solved by the new commits for a tag relative to the previous one + +- Tags Pattern: Only tags that meet given regular expression will be counted. + +- Tags Order: Only "reverse semver" order is supported for now. + +Please click `Save` to save the transformation rules for the repo. In the data scope list, click `Next Step` to continue configuring. + + +## Step 2 - Collect Data in a Project +### Step 2.1 - Create a Project +Collecting GitHub data requires creating a project first. You can visit the Project page from the side menu and create a new project by following the instructions on the user interface. + +![create-a-project](images/create-a-project.png) + +### Step 2.2 - Add a GitHub Connection +You can add a previously configured GitHub connection to the project and select the boards for which you wish to collect the data for. +Please note: if you don't see the repositories you are looking for, please check if you have added them to the connection first. + +![add-a-connection](images/add-a-connection-project.png) + +### Step 2.3 - Set the Sync Policy +There are three settings for Sync Policy: +- Data Time Range: You can select the time range of the data you wish to collect. The default is set to the past six months. +- Sync Frequency: You can choose how often you would like to sync your data in this step by selecting a sync frequency option or enter a cron code to specify your preferred schedule. +- Skip Failed Tasks: sometime a few tasks may fail in a long pipeline; you can choose to skip them to avoid spending more time in running the pipeline all over again. + +![sync-policy](images/sync-policy.png) + +### Step 2.4 - Start Data Collection +Click on "Collect Data" to start collecting data for the whole project. You can check the status in the Status tab on the same page. +![collect-data](images/collect-data.png) + + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/GitLab.md b/versioned_docs/version-v0.21/Configuration/GitLab.md new file mode 100644 index 00000000000..8f5b38decf1 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/GitLab.md @@ -0,0 +1,130 @@ +--- +title: "GitLab" +sidebar_position: 11 +description: Config UI instruction for GitLab +--- + +Visit Config UI: `http://localhost:4000`. + +## Step 1 - Add Data Connections + +On the Connections page, you can select GitHub and create a new connection or it. + +### Step 1.1 - Authentication + +![gitlab-add-data-connections](images/gitlab-create-a-connection.png) + +#### Connection Name + +Give your connection a unique name to help you identify it in the future. + +#### GitLab Version + +Select if you use GitLab Cloud or GitLab Server (v11+). + +#### Endpoint URL + +This should be a valid REST API endpoint. + +- If you use GitLab cloud, you do not need to enter the endpoint, which is always `https://gitlab.com/api/v4/`. +- If you GitLab Server (v11+), the endpoint will look like `https://gitlab.example.com/api/v4/`. + Please note: the endpoint URL should end with `/`. + +#### Personal Access Token + +Your GitLab personal access token (PAT) is required to add a connection. Learn about [how to create a GitLab personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html). + +##### Personal Access Token Permissions + +At least one of the following permissions is required to collect data from repositories: + +- `api` +- `read_api` + +You also have to double-check your GitLab user permission settings. + +1. Go to the Project information -> Members page of the GitLab projects you wish to collect. +2. Check your role in this project from the Max role column. Make sure you are not the Guest role, otherwise, you will not be able to collect data from this project. + +#### Proxy URL (Optional) + +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + +#### Fixed Rate Limit (Optional) + +DevLake uses a dynamic rate limit at around 12,000 requests/hour to collect GitLab data. You can adjust the rate limit if you want to increase or lower the speed. + +The maximum rate limit for GitLab Cloud is ** [120,000 requests/hour](https://docs.gitlab.com/ee/user/gitlab_com/index.html#gitlabcom-specific-rate-limits)**. Tokens under the same IP address share the rate limit, so the actual rate limit for your token will be lower than this number. + +For self-managed GitLab rate limiting, please contact your GitLab admin to [get or set the maximum rate limit](https://repository.prace-ri.eu/git/help/security/rate_limits.md) of your GitLab instance. Please do not use a rate that exceeds this number. + +#### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +### Step 1.2 - Add Data Scopes + +#### Repositories + +![gitlab-set-data-scope](images/gitlab-set-data-scope.png) + + +Select the GitLab repositories you want to collect from the miller column. **Please note that repositories with guest permissions or those that are archived have already been excluded.** You can also use the search function to find them. Limited by the GitLab API, You need to type more than 2 characters to search. The repositories only with guest permissions are not shown in the list. + + +### Step 1.3 - Add Scope Config (Optional) +Scope config contains two parts: +- The entities of which domain you wish to collect: Usually, you don't have to modify this part. However, if you don't want to collect certain GitLab entities, you can unselect some entities to accelerate the collection speed. + - Issue Tracking: GitLab issues, issue comments, issue labels, etc. + - Source Code Management: GitLab repos, refs, commits, etc. + - Code Review: GitLab MRs, MR comments and reviews, etc. + - CI/CD: GitLab pipelines, jobs, etc. + - Cross Domain: GitLab accounts, etc. +- The transformations on the GitLab data you are going to collect. + - The details of the transformations will be explained below. + - Without adding transformation rules, you can still view some of the dashboards. + - Each GitLab repo has at most ONE set of transformations. + +![gitlab-set-transformation1](images/gitlab-scope-config.png) +![gitlab-set-transformation2](images/gitlab-set-transformation2.png) + +#### CI/CD + +This set of configurations is used to define 'deployments'. Deployments are related to measure [DORA metrics](../DORA.md). + +For GitLab deployments, DevLake recognizes them as deployments by specifying a regular expression (regex) to identify the production environments among all 'GitLab environments'. + +If your deployments are not performed through GitLab deployments but rather specific pipelines in GitLab, you have the option to convert a GitLab pipeline run into a DevLake deployment. In this case, you need to configure two regular expressions (regex): + +- Deployment: The given regex should match the name of the GitLab pipeline's branch name or one of its job names to be considered as a deployment. For example, if the pipeline is executet on the 'build-and-push-image', you can input (push-image). To make the regex case insensitive, you can include (?i) before the regex. +- Production: The given regex should match either the pipeline's branch name or one of its job names to be considered a deployment within the production environment. For instance: + - If the pipeline used for deployment is named 'build-to-prod', you can input (prod). To make the regex case insensitive, you can include (?i) before the regex. + - Also, many users in GitLab utilize the same pipeline for both staging and prod deployments, executing it on the release branch would indicate a production deployment. + +## Step 2 - Collect Data in a Project +### Step 2.1 - Create a Project +Collecting GitLab data requires creating a project first. You can visit the Project page from the side menu and create a new project by following the instructions on the user interface. + +![create-a-project](images/create-a-project.png) + +### Step 2.2 - Add a GitLab Connection +You can add a previously configured GitLab connection to the project and select the boards for which you wish to collect the data for. +Please note: if you don't see the repositories you are looking for, please check if you have added them to the connection first. + +![add-a-connection](images/add-a-connection-project.png) + +### Step 2.3 - Set the Sync Policy +There are three settings for Sync Policy: +- Data Time Range: You can select the time range of the data you wish to collect. The default is set to the past six months. +- Sync Frequency: You can choose how often you would like to sync your data in this step by selecting a sync frequency option or entering a cron code to specify your prefered schedule. +- Skip Failed Tasks: sometime a few tasks may fail in a long pipeline; you can choose to skip them to avoid spending more time in running the pipeline all over again. + +![sync-policy](images/sync-policy.png) + +### Step 2.4 - Start Data Collection +Click on "Collect Data" to start collecting data for the whole project. You can check the status in the Status tab on the same page. +![collect-data](images/collect-data.png) + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/HowToOrganizeDevlakeProjects.md b/versioned_docs/version-v0.21/Configuration/HowToOrganizeDevlakeProjects.md new file mode 100644 index 00000000000..0d0261f6c33 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/HowToOrganizeDevlakeProjects.md @@ -0,0 +1,225 @@ +--- +title: "How to Organize DevLake Projects" +sidebar_position: 3 +description: > + How to Organize DevLake Projects +--- + +This guide provides a step-by-step approach to organizing projects in DevLake, enabling you to measure DORA metrics according to your specific use cases. + +## 1. What is a DevLake project? +On a high level, a DevLake project can be viewed as a real-world project or product line. It represents a specific initiative or endeavor within the software development domain. + +On a lower level, a DevLake project is a way of organizing and grouping data from different domains. DevLake uses various [data scopes](/docs/Overview/KeyConcepts.md#data-scope), such as repos, boards, cicd_scopes, and cq_projects as the 'container' to associate different types of data to a specific project. See more on this [doc](/docs/Overview/KeyConcepts.md#project). + +## 2. Why is it important to organize projects? + +This is crucial due to the fact that DevLake measures DORA metrics at the project level. Each project is associated with specific key entities, such as 'pull requests', 'deployments', and 'incidents', which are used to calculate the corresponding DORA metrics. Therefore, proper project organization ensures accurate and meaningful DORA metric calculations for effective analysis and evaluation. + +![](../Configuration/images/HowToOrganizeDevlakeProjects/project_pipeline.png) + +> How are four [DORA](../DORA.md) metrics calculated from 'pull requests', 'deployments', and 'incidents'? +> +> - [Deployment Frequency](../Metrics/DeploymentFrequency.md): How often does a project `deploys`? +> - [Lead Time for Changes](../Metrics/LeadTimeForChanges.md): How fast are the `pull requests` delivered? +> - [Change Failure Rate](../Metrics/CFR.md): How many `deployments` lead to `incidents`? +> - [Median Time to Restore](../Metrics/MTTR.md): How fast are `incidents` solved? + + +## 3. Challenges in project organization +There are several challenges associated with organizing projects in DevLake due to different development practices within teams. Some of these challenges include: + +- Managing multiple Git repos, issue boards, and CI/CD pipelines within a project. +- Having a Git repo, issue board, or CI/CD pipeline associated with multiple projects, such as in the case of mono-repos or boards used to track incidents from user feedback. +- Managing multiple projects within a team and the need to measure DORA metrics at the team level. +- Projects contributed by multiple teams, with each team requiring the ability to measure their own DORA metrics. + +This document serves as a guide to address these challenges and provide assistance in effectively dealing with these diverse development practices. + +## 4. General advice + +### 4.1. Determining the number of DevLake projects + +It is advisable to create DevLake projects that align with the number of real-life projects you have. + +For example, if you have a team (Team A) responsible for managing multiple projects, it is recommended to create separate DevLake projects for each individual project instead of creating a single project named 'Team A'. This approach allows for better organization and tracking of metrics specific to each project. + + +### 4.2 Principles of organizing projects + +When organizing projects in DevLake, it is important to associate all relevant [data scopes](/docs/Overview/KeyConcepts.md#data-scope), such as repos, issue boards, and CI/CD scopes, with the corresponding DevLake project based on real-life practices. + +In situations where a repo or board is shared by multiple projects in real life, it is recommended to include them in all of these projects within DevLake. This is because DevLake cannot differentiate which commits or issues belong to specific projects. Rather than excluding shared resources from DORA measurements, it is advisable to consider them in all relevant projects. + +### 4.3 Measuring DORA at the team level + +To clarify the concepts, let's define three terms: + +- [`Project`](/docs/Overview/KeyConcepts.md#project): Refers to a real-world project or product line, such as Apache DevLake or Apache Spark. It focuses on the work to be done. +- `Team`: Represents a department, such as the 'product team' or 'engineering team'. It focuses on the people and their roles. Note that people within the same team may not always work on the same projects. +- `Project Team`: Comprises individuals working on a specific project. + +DevLake does support measuring DORA metrics at the project-team level, which is essentially the same as measuring at the project level. However, it is important to note that DevLake does not recommend measuring DORA metrics at the team level. Despite the existence of the 'DORA by team' dashboard contributed by the community. Doing so may introduce inaccuracies and dilute the significance of measuring DORA metrics from the outset. + +## 5. Use Cases +This section demonstrates real-life practices and how they get reflected in DevLake. + +Disclaimer: _To keep this guide shorter, some technical details are only mentioned in +[Use Case 1](HowToOrganizeDevlakeProjects#41-use-case-1-apache-projects), +so if you read this page for the first time, make sure to go through them in order._ + +Note: _If you use webhooks, check the [quick note](HowToOrganizeDevlakeProjects#5-about-webhooks) about them below._ + +### 5.1. Use Case 1: Apache Projects +Apache Software Foundation (ASF) has and is developing many +[projects](https://en.wikipedia.org/wiki/List_of_Apache_Software_Foundation_projects). + +To take an example we will analyze 2 `projects`: DevLake and [Spark](https://spark.apache.org/). +Both are independent of each other. Assume that ASF wants to check the health of the development +and maintenance of these projects with DORA. + +DevLake manages 3 `repos`: [incubator-devlake](https://github.com/apache/incubator-devlake), +[incubator-devlake-website](https://github.com/apache/incubator-devlake-website), +and [incubator-devlake-helm-chart](https://github.com/apache/incubator-devlake-helm-chart). +There are many repos related to _Spark_ in one way or another. To keep it simple, +we will also pick 3 `repos`: [spark](https://github.com/apache/spark), +[spark-website](https://github.com/apache/spark-website), and [incubator-livy](https://github.com/apache/incubator-livy). + +![](../Configuration/images/HowToOrganizeDevlakeProjects/project_use_case_1.png) + +Both projects use GitHub for storing code (including `pull requests`), `deployments` on GitHub Actions, and `incidents`. + +Note: _To avoid confusion between DevLake as a `project` in this use case and DevLake as a platform, +we will use complete names i.e. `project DevLake` and `platform DevLake` respectively._ + +#### 5.1.1. Organizing Projects +First, create two projects on the DevLake platform, one for DevLake and one for Spark. +These will represent real-world projects. + +![](../Configuration/images/HowToOrganizeDevlakeProjects/create_project_1.png) +![](../Configuration/images/HowToOrganizeDevlakeProjects/create_project_2.png) + +Once these are created, the connections created in the following steps will be bound to them. + +#### 5.1.2. Creating Connections + +Since all is on GitHub in this case, we can use just 1 connection with the following properties: +- it includes all the project's `repos` +- its scope includes everything we work with (i.e. `pull requests`, `deployments`, and `incidents`) + +If you store `incidents` on Jira, for example, you will need to create a separate connection just for them. +The same applies to `deployments`, a separate connection is needed in case they are stored in Jenkins (or any other host for `deployments`). + +#### 5.1.3. Configuring Connections +This part is described in [GitHub](../Configuration/GitHub.md) connection configuration. Please check the [configuration guide](../Configuration/Tutorial.md) for configuring other data sources. + +#### 5.1.4. Using Connections + +At this point, we have projects and connections created on the platform DevLake. +It is time to bind those connections to the projects. To do so, follow the steps described in the [Tutorial](../Configuration/Tutorial.md). + +#### 5.1.5. Resulting Metrics + +To know if the data of a project is successfully collected to your DORA Dashboard: + +![](../Configuration/images/HowToOrganizeDevlakeProjects/navigate_to_dora_1.png) +![](../Configuration/images/HowToOrganizeDevlakeProjects/navigate_to_dora_2.png) + +If everything goes well, you should see all the 4 charts. +If something is wrong, and you are puzzled as to why, check out the +[Debugging Dora Issue Metrics](../Troubleshooting/Dashboard.md#debugging-dora-issue-metrics) page. + +#### 5.1.6. How can I observe metrics by project? +In the same DORA dashboard check out this menu point: +![](../Configuration/images/HowToOrganizeDevlakeProjects/observe_metrics_by_project_panel.png) + +The metrics should change when you select or deselect projects, representing the projects you selected. + +### 5.2. Use Case 2: Multiple Teams with Distinct Projects + +Consider a scenario where a company operates with several teams, each managing one or more projects. +For illustration, we will explore two such teams: the Payments team and the Internal Tools team. +Here's a simplified representation of this scenario: + +#### Quick Overview: +- The Payments team works on a single project: “payments”. +- The Internal Tools team manages two projects: “it-legacy” and “it-new”. +- Both teams use different sets of tools and boards. + +![](../Configuration/images/HowToOrganizeDevlakeProjects/project_use_case_2.png) + +#### Step-by-Step Simplification: +1. **Define the Teams and Projects:** + - **Payments Team**: + - One project: "payments". + - **Internal Tools Team**: + - Two projects: "it-legacy" and "it-new". +2. **Understand the Tools**: + - Assume both teams utilize GitHub for `repos` and Jenkins for CI/CD. + - The _Payments_ team uses Jira boards. + - The _Internal Tools_ team uses webhooks for reporting incidents. + +#### 5.2.1. Organizing Projects + +DORA is effective for observing the impacts of methodology changes within a team. +From DORA’s standpoint, the concept of distinct `teams` is not recognized; only `projects` exist. +Adding a `team` concept introduces unnecessary complexity without providing any substantial benefit. + +In DevLake, we create three `projects`: _payments_, _it-legacy_, and _it-new_. + +It is crucial to maintain **atomic** `projects`, representing the smallest, independent units, +to prevent complexity and ensure precise data representation. **Atomic** `projects` allow for a more flexible +and accurate data comparison and combination between `projects`. + +#### 5.2.2. Adding Connections + +Create just one connection and reuse it across projects by adding data scopes. +This method optimizes data collection, minimizing redundancy and ensuring more efficient use of resources. + +It is NOT recommended to create multiple connections, for instance, GitHub repos, as it +will increase the time to collect the data due to the storage of multiple copies of shared repos in the database. + +The only exception is the webhooks: **we must have 1 connection per project**, +as this is the only way DevLake can accurately assign `incidents` to the corresponding `project`. + +So, in total we will have only these connections: +- 1 connection for all GitHub `repos` to collect `pull requests` +- 1 connection to Jenkins to collect all `deployments` +- 1 connection to Jira to collect `incidents` +- 2 webhook connections to collect `incidents`: 1 per each `project` that uses webhooks (_it-legacy_ and _it-new_) + +The step-by-step [Configuration Guide](../Configuration/Tutorial.md) shows how to both add connections and set scopes as described in the next chapter. + +#### 5.2.3. Setting Scopes +Now, add the connections to our projects and set the scope to them: + +For payments `project`: +- add 1 scope to GitHub connection for _p1...p10_ `repos` to collect their `pull requests` +- add 1 scope to Jenkins for `deployments` of _p1...p10_ `repos` +- add 1 scope to Jira to collect `incidents` + +For it-legacy `project`: +- add 1 scope to GitHub for `repos` _it-legacy-1_, _it-legacy-2_, _it-core-1_ and _it-core-2_ to collect their `pull requests` +- add 1 scope to Jenkins for `deployments` of _it-legacy-1_, _it-legacy-2_, _it-core-1_ and _it-core-2_ `repos` +- include the _it-legacy_ webhook for collecting `incidents` + +For it-new `project`: +- add 1 scope to GitHub for `repos` _it-new-1_, _it-new-2_, _it-core-1_ and _it-core-2_ to collect their `pull requests` +- add 1 scope to Jenkins for `deployments` of _it-new-1_, _it-new-2_, _it-core-1_ and _it-core-2_ `repos` +- include the _it-new_ webhook for collecting `incidents` + +#### 5.2.4. Resulting Metrics +See [5.1.5 Resulting Metrics](HowToOrganizeDevlakeProjects#515-resulting-metrics) + +## 6. About Webhooks +**Assigning a UNIQUE webhook to each project is critical.** This ensures that the DevLake platform +correctly associates the incoming data with the corresponding project through the webhook. + +If you use the same webhook across multiple projects, the data sent by it **will be replicated per each +project that uses that webhook**. More information available on the [Webhook](/docs/Plugins/webhook.md) page + +## 7. Troubleshooting + +Please check out the [Debugging DORA Issue Metrics](../Troubleshooting/Dashboard.md#debugging-dora-issue-metrics) to debug DORA dashboard. + +If you still run into any problems, please check the [Troubleshooting](/docs/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Configuration/Jenkins.md b/versioned_docs/version-v0.21/Configuration/Jenkins.md new file mode 100644 index 00000000000..fd417562649 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Jenkins.md @@ -0,0 +1,81 @@ +--- +title: "Jenkins" +sidebar_position: 13 +description: Config UI instruction for Jenkins +--- + +Visit Config UI at: `http://localhost:4000`. + +## Step 1 - Add Data Connections + +![jenkins-create-a-connection](images/jenkins-create-a-connection.png) + +### Connection Name + +Give your connection a unique name to help you identify it in the future. + +### Endpoint URL + +This should be a valid REST API endpoint. Eg. `https://ci.jenkins.io/`. The endpoint url should end with `/`. + +### Username (E-mail) + +Your User ID for the Jenkins Instance. + +### Password + +For help on Username and Password, please see Jenkins docs on [using credentials](https://www.jenkins.io/doc/book/using/using-credentials/). You can also use "API Access Token" for this field, which can be generated at `User` -> `Configure` -> `API Token` section on Jenkins. + +### Fixed Rate Limit (Optional) + +DevLake uses a dynamic rate limit to collect Jenkins data. You can adjust the rate limit if you want to increase or lower the speed. + +There is no doc about Jenkins rate limiting. Please create an issue if you find related information. + +### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +## Step 2 - Setting Data Scope + +![jenkins-set-data-scope](/img/ConfigUI/jenkins-set-data-scope.png) + +### Jobs + +Choose the Jenkins jobs. All `Jenkins builds` under these jobs will be collected. + +### Data Entities + +Jenkins only supports `CI/CD` domain entities, transformed from Jenkins builds and stages. + +- CI/CD: Jenkins builds, stages, etc. + +## Step 3 - Adding Transformation Rules (Optional) + +![jenkins-set-transformation1](images/jenkins-set-transformation1.png) +![jenkins-set-transformation2](images/jenkins-set-transformation2.png) + +This set of configurations is used for calculating [DORA metrics](../DORA.md). + +If you'd like to define `deployments` with Jenkins, please select "Detect Deployment from Jenkins Builds", and provide the following regexes + +- Deployment: Jenkins stages whose names match the regex will be registered as deployments (if a Jenkins build has no stage, its job name will be used to match the regex) +- Production: Jenkins stages whose names match the regex will be assigned environment 'PRODUCTION' (if a Jenkins build has no stage, its job name will be used to match the regex) + +This is how it works behind the scene: + +- If a Jenkins build has stages, it's converted to a cicd_pipeline and its stages are converted to cicd_tasks in DevLake's domain layer schema. +- If a Jenkins build has no stage, it's converted to both a cicd_pipeline and a cicd_task whose names are the build's jobName. + +After the conversion, the two regexes are applied to the records in the cicd_tasks table. +![jenkins-job-build-stage](/img/ConfigUI/jenkins-job-build-stage.png) + +You can also select "Not using Jenkins builds as Deployments" if you're not using Jenkins to conduct deployments. + +## Step 4 - Setting Sync Policy + +You can choose how often you would like to sync your data in this step by selecting a sync frequency option or enter a cron code to specify your prefered schedule. + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/Jira.md b/versioned_docs/version-v0.21/Configuration/Jira.md new file mode 100644 index 00000000000..2cd3c0df3f2 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Jira.md @@ -0,0 +1,157 @@ +--- +title: "Jira" +sidebar_position: 15 +description: Config UI instruction for Jira +--- + +Visit Config UI at: `http://localhost:4000`. + +## Step 1 - Add Data Connections + +On the Connections page, you can select Jira and create a new connection or it. + +### Stept 1.1 - Authentication + +![jira-add-data-connections](images/jira-create-a-connection.png) + +#### Connection Name + +Give your connection a unique name to help you identify it in the future. + +Please note: the following configuration for the endpoint and authentication for your Jira connection depends on your Jira version, Jira Cloud or Server/Data Center. + +#### Jira Cloud +##### Endpoint URL +This should be a valid REST API endpoint: `https://.atlassian.net/rest/` + +Please note: the endpoint url should end with `/`. + +##### E-mail +Please enter the e-mail of your Jira account. + +##### API Token +Learn about [how to create an API token](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/). + +Please note: Jira API token and Personal Access Token are two different tokens. + +#### Jira Server/Data Center +##### Endpoint URL +This should be a valid REST API endpoint: `https://jira..com/rest/` + +Please note: the endpoint url should end with `/`. + +##### Authentication Method +Jira Server supports two ways of authentication: using basic authentication or Personal Access Token. + +##### Username +Please enter the username of your Jira account. + +##### Password +Please enter the password of your Jira account. + +##### Personal Access Token +Learn about [how to create a Personal Access Token](https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html). + +#### Token Permissions +For both Jira Cloud and Jira Server, when accessing Jira API, users may encounter access restrictions if their token does not have sufficient permissions. This is typically caused by insufficient scope or role settings for the Jira token. + +To solve this issue, users can take the following steps: + +- Checking User Permissions + +Users can confirm whether they have sufficient permissions by checking their permissions in Jira. For Cloud users, they can view their global and project permissions through the "Permissions" tab on the "Profile" page. For Server users, they can log in to Jira as an administrator and view user permissions on the "User Management" page. + +- Ensuring Sufficient Permissions + +Before using the Jira API, users need to ensure that their account has at least the necessary project or global permissions. Global permissions include various Jira system settings and management operations, while project permissions control specific operations and configurations for each Jira project. Users can assign roles such as `Project Administrator`, `Project Lead`, `Developer`, etc. for the corresponding projects, or assign global permissions such as `Jira Administrators`, `Jira Software Administrators`, etc. It is recommended to minimize the permissions granted to the API to ensure system security. + +- Solving Access Restrictions + +To solve access restrictions caused by insufficient Jira token permissions, users should check the token's permission settings to ensure the correct scope and role are set. If the permission settings are correct but the required API is still inaccessible, consider using other authentication methods, such as authenticating with a username and password. If the issue persists, contact the Jira administrator for further assistance. + +#### Proxy URL (Optional) + +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + +##### Fixed Rate Limit (Optional) + +DevLake uses a dynamic rate limit to collect Jira data. You can adjust the rate limit if you want to increase or lower the speed. If you encounter a 403 error during data collection, please lower the rate limit. + +Jira(Cloud) uses a dynamic rate limit and has no clear rate limit. For Jira Server's rate limiting, please contact your Jira Server admin to [get or set the maximum rate limit](https://repository.prace-ri.eu/git/help/security/rate_limits.md) of your Jira instance. Please do not use a rate that exceeds this number. + +#### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +### Step 1.2 - Add Data Scopes + +#### Boards + +Choose the Jira boards to collect. + +![jira-set-data-scope](images/jira-add-data-scopes.png) + + +### Step 1.3 - Add Scope Config (Optional) +Scope config contains two parts: +- The entities of which domain you wish to collect: Usually, you don't have to modify this part. However, if you don't want to collect certain Jira entities, you can unselect some entities to accelerate the collection speed. + - Issue Tracking: Jira issues, issue comments, issue labels, etc. + - Cross Domain: Jira accounts, etc. +- The transformations on the Jira data you are going to collect + - Issue Type: Standardize the issue types to DevLake's pre-defined three issue types: REQUIREMENT, BUG, and INCIDENT. + - Story Points: Map the custom field that represents story_point in your Jira to DevLake's issue story point. + - Cross-domain: Get the commit(s) associated with Jira issues from Jira issues' remote links or development panels. + +Although this configuration is optional, some of the above transformations are required to measure metrics such as [Requirement Lead Time](https://devlake.apache.org/docs/Metrics/RequirementLeadTime), [Bug Age](https://devlake.apache.org/docs/Metrics/BugAge) or [DORA - Median Time to Restore Service](https://devlake.apache.org/docs/Metrics/MTTR) in the built-in Grafana dashboards. + +Without adding transformation rules, you can not view all charts in "Jira" or "Engineering Throughput and Cycle Time" dashboards.
+ +Each Jira board has at most ONE set of transformations. + + +![jira-add-transformation-1](images/jira-set-transformation1.png) +![jira-add-transformation-2](images/jira-set-transformation2.png) +![jira-add-transformation-3](images/jira-set-transformation3.png) + + + +#### Issue Tracking + +- Requirement: choose the issue types to be transformed to "REQUIREMENT". +- Bug: choose the issue types to be transformed to "BUG". +- Incident: choose the issue types to be transformed to "INCIDENT". +- Epic Key: choose the custom field that represents Epic key. In most cases, it is "Epic Link". +- Story Point: choose the custom field that represents story points. In most cases, it is "Story Points". + +#### Additional Settings + +- Remotelink Commit SHA: parse the commits from an issue's remote links by the given regular expression so that the relationship between `issues` and `commits` can be created. You can directly use the regular expression `/commit/([0-9a-f]{40})$`. + +## Step 2 - Collect Data in a Project +### Step 2.1 - Create a Project +Collecing Jira data reuiqres creating a project first. You can visit the Project page from the side menu and create a new project by following the instructions on the user interface. + +![create-a-project](images/create-a-project.png) + +### Step 2.2 - Add a Jira Connection +You can add a previously configured Jira connection to the project and select the boards for which you wish to collect the data for. +Please note: if you don't see the boards you are looking for, please check if you have added them to the connection first. + +![add-a-connection](images/add-a-connection-project.png) + +### Step 2.3 - Set the Sync Policy +There are three settings for Sync Policy: +- Data Time Range: You can select the time range of the data you wish to collect. The default is set to the past six months. +- Sync Frequency: You can choose how often you would like to sync your data in this step by selecting a sync frequency option or enter a cron code to specify your prefered schedule. +- Skip Failed Tasks: sometime a few tasks may fail in a long pipeline; you can choose to skip them to avoid spending more time in running the pipeline all over again. + +![sync-policy](images/sync-policy.png) + +### Step 2.4 - Start Data Collection +Click on "Collect Data" to start collecting data for the whole project. You can check the status in the Status tab on the same page. +![collect-data](images/collect-data.png) + + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/Opsgenie.md b/versioned_docs/version-v0.21/Configuration/Opsgenie.md new file mode 100644 index 00000000000..cf9ed0ae143 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Opsgenie.md @@ -0,0 +1,83 @@ +--- +title: "Opsgenie" +sidebar_position: 11 +description: Config UI instruction for Opsgenie +--- + +Visit Config UI at: `http://localhost:4000`. + +## Step 1 - Add Data Connections + +On the Connections page, you can select Opsgenie and create a new connection on it. + +### Step 1.1 - Authentication +![opsgenie-add-data-connections](images/opsgenie-create-a-connection.png) + +#### Connection Name + +Give your connection a unique name to help you identify it in the future. + +#### Endpoint URL + +Opsgenie makes available two types of REST API endpoints, US and EU, eg. `https://api.opsgenie.com/` or `https://api.eu.opsgenie.com/`. You can choose wich instance by selecting the due radio input. + +#### API Access Key + +In the `API key management` section of your Atlassian Opsgenie account settings, you can create a API key to manage your requests. + +Learn about [how to create a Opsgenie API key](https://support.atlassian.com/opsgenie/docs/api-key-management/). The following permissions are required to collect data from repositories: + +- `Read` +- `Create and Update` +- `Configuration Access` + +#### Proxy URL (Optional) + +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + +#### Fixed Rate Limit (Optional) + +DevLake uses a dynamic rate limit to collect Opsgenie data. You can adjust the rate limit if you want to increase or lower the speed. + +Opsgenie doesn't establishes a maximum rate limit for its API request, thus you should check this **[detailed doc](https://docs.opsgenie.com/docs/api-rate-limiting)** on how to calculate your rate limit, based on number of user and account plan that you hired. For now, the default rate limit is in 6,000 request/hour (100 request/minute). + +#### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +### Step 1.2 - Add Data Scopes + +#### Services + +Choose the Opsgenie services you wish to collect either by finding them in the miller column, or searching. + +![opsgenie-set-data-scope](images/opsgenie-add-data-scopes.png) + +## Step 2 - Collect Data in a Project +### Step 2.1 - Create a Project +Collecing Opsgenie data requires creating a project first. You can visit the Project page from the side menu and create a new project by following the instructions on the user interface. + +![create-a-project](images/create-a-project.png) + +### Step 2.2 - Add a Opsgenie Connection +You can add a previously configured Opsgenie connection to the project and select the boards for which you wish to collect the data for. +Please note: if you don't see the services you are looking for, please check if you have added them to the connection first. + +![add-a-connection](images/add-a-connection-project.png) + +### Step 2.3 - Set the Sync Policy +There are three settings for Sync Policy: +- Data Time Range: You can select the time range of the data you wish to collect. The default is set to the past six months. +- Sync Frequency: You can choose how often you would like to sync your data in this step by selecting a sync frequency option or enter a cron code to specify your prefered schedule. +- Skip Failed Tasks: sometime a few tasks may fail in a long pipeline; you can choose to skip them to avoid spending more time in running the pipeline all over again. + +![sync-policy](images/sync-policy.png) + +### Step 2.4 - Start Data Collection +Click on "Collect Data" to start collecting data for the whole project. You can check the status in the Status tab on the same page. +![collect-data](images/collect-data.png) + + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/PagerDuty.md b/versioned_docs/version-v0.21/Configuration/PagerDuty.md new file mode 100644 index 00000000000..0996240d260 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/PagerDuty.md @@ -0,0 +1,57 @@ +--- +title: "PagerDuty" +sidebar_position: 17 +description: Config UI instruction for PagerDuty +--- + +Visit Config UI at: `http://localhost:4000`. + +## Step 1 - Add Data Connections + +![pagerduty-create-a-connection](images/pagerduty-create-a-connection.png) + +### Connection Name + +Give your connection a unique name to help you identify it in the future. + +### Token + +Paste your PagerDuty personal access token (PAT) here. You may make it a Read-Only token for the plugin's purposes. + +### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +## Step 1 - Add Data Connection + +Create a project for PagerDuty by adding the connection created above to it. + +![pagerduty-add-data-connection](images/pagerduty-add-data-connection.png) + +## Step 2 - Setting Data Scope + +### Select services + +Select the services you want to collect data from. + +![pagerduty-set-data-scope](images/pagerduty-set-data-scope.png) + +### Data Entities + +PagerDuty supports the following data entities. + +- Issue Tracking: These map to PagerDuty incidents. + +## Step 3 - Adding Transformation Rules (Optional) + +Currently, this plugin does not support transformation rules, so skip this page by clicking `Next Step`. + +## Step 4 - Set Sync Policy + +Set the sync policy as you see fit. Note that PagerDuty can only collect data from up to 6 months prior to the present time. + +![pagerduty-sync-policy](images/pagerduty-sync-policy.png) + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/SonarQube.md b/versioned_docs/version-v0.21/Configuration/SonarQube.md new file mode 100644 index 00000000000..75c435c9f43 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/SonarQube.md @@ -0,0 +1,65 @@ +--- +title: "SonarQube Server" +sidebar_position: 19 +description: Config UI instruction for SonarQube +--- + +Visit Config UI at: `http://localhost:4000`. + +## Step 1 - Add Data Connections + +![sonarqube-add-data-connections](/img/ConfigUI/sonarqube-add-data-connections.png) + +### Connection Name + +Name your connection. + +### Endpoint URL + +This should be a valid REST API endpoint + +- `http://:/api/` + +The endpoint url should end with `/`. + +### Token + +Please use a system admin account to create the SonarQube token, because some SonarQube APIs require this permission to list all projects. Learn about [how to create a SonarQube token](https://docs.sonarsource.com/sonarqube/8.9/user-guide/user-account/generating-and-using-tokens/#generating-a-token). + +### Proxy URL (Optional) + +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + +### Fixed Rate Limit (Optional) + +DevLake uses a dynamic rate limit at around 18,000 requests/hour to collect SonarQube data. You can adjust the rate limit if you want to increase or lower the speed. + +### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +## Step 2 - Setting Data Scope + +![sonarqube-set-data-scope](/img/ConfigUI/sonarqube-set-data-scope.png) + +### Projects + +Choose the SonarQube projects to collect. + +### Data Entities + +Usually, you don't have to modify this part. However, if you don't want to collect certain SonarQube entities, you can unselect some entities to accerlerate the collection speed. + +- Code Quality Domain: SonarQube issues, issue code blocks, file metrics, hotspots, etc. +- Cross Domain: SonarQube accounts, etc. + +## Step 3 - Adding Transformation Rules (Optional) +SonarQube does not have transformation and this step will be skipped. + +## Step 4 - Setting Sync Policy + +You can choose how often you would like to sync your data in this step by selecting a sync frequency option or enter a cron code to specify your prefered schedule. + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/Tapd.md b/versioned_docs/version-v0.21/Configuration/Tapd.md new file mode 100644 index 00000000000..b575f2f7961 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Tapd.md @@ -0,0 +1,76 @@ +--- +title: "TAPD" +sidebar_position: 21 +description: Config UI instruction for TAPD +--- + +Visit Config UI at: `http://localhost:4000` and go to `Connections` page. + +## Step 1 - Add Data Connections +![tapd-add-data-connections](/img/ConfigUI/tapd-add-data-connections.png) + +### Connection Name +Name your connection. + +### Endpoint URL +This should be a valid REST API endpoint + - `https://api.tapd.cn/` +The endpoint url should end with `/`. + +### Username/Password +Input the username and password of your Tapd account, you can follow the steps as below. +![tapd-account](/img/ConfigUI/tapd-account.png) + +### Proxy URL (Optional) +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + +### Ralte Limit (Optional) +For TAPD, we suggest you setting the rate limit to 3500 + +### Test and Save Connection +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +## Step 2 - Setting Data Scope + +![image-20230410224100853](https://user-images.githubusercontent.com/3294100/230924072-433451e5-97a3-4d99-9ca7-0a43d0bacd01.png) + +You can find the campany id in your Tapd company dashboard. + +![image-20230410223926964](https://user-images.githubusercontent.com/3294100/230923942-4dd5bbd7-a391-4abc-ab99-ff7543d919ac.png) + +### Workspaces + +Choose the Tapd workspaces to collect. + +### Data Entities + +Usually, you don't have to modify this part. However, if you don't want to collect certain Tapd entities, you can unselect some entities to accerlerate the collection speed. + +- Issue Tracking: Tapd issues, issue comments, issue labels, etc. +- Cross Domain: Tapd accounts, etc. + +## Step 3 - Adding Transformation Rules (Optional) + +![image](https://user-images.githubusercontent.com/3294100/230924606-bf6ef00c-73fa-4a60-be8f-1f27fe4ef6ae.png) + +Without adding transformation rules, you can not view all charts in "Engineering Throughput and Cycle Time" dashboards.
+ +Each Tapd workspace can be configured with different transformation rules. + +### Issue Tracking + +- Requirement: choose the issue types to be transformed to "REQUIREMENT". +- Bug: choose the issue types to be transformed to "BUG". +- Incident: choose the issue types to be transformed to "INCIDENT". +- TODO: The issues that are planned but have not been worked on yet +- IN-PROGRESS: The issues that are work-in-progress +- DONE: The issues that are completed + +## Step 4 - Setting Sync Policy + +You can choose how often you would like to sync your data in this step by selecting a sync frequency option or enter a cron code to specify your prefered schedule. + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) + diff --git a/versioned_docs/version-v0.21/Configuration/TeamConfiguration.md b/versioned_docs/version-v0.21/Configuration/TeamConfiguration.md new file mode 100644 index 00000000000..af8197b8467 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/TeamConfiguration.md @@ -0,0 +1,194 @@ +--- +title: "Team Configuration" +sidebar_position: 35 +description: > + Team Configuration +--- +## What is 'Team Configuration' and how it works? + +To organize and display metrics by `team`, Apache DevLake needs to know about the team configuration in an organization, specifically: + +1. What are the teams? +2. Who are the users(unified identities)? +3. Which users belong to a team? +4. Which accounts(identities in specific tools) belong to the same user? + +Each of the questions above corresponds to a table in DevLake's schema, illustrated below: + +![image](/img/Team/teamflow0.png) + +1. `teams` table stores all the teams in the organization. +2. `users` table stores the organization's roster. An entry in the `users` table corresponds to a person in the org. +3. `team_users` table stores which users belong to a team. +4. `user_accounts` table stores which accounts belong to a user. An `account` refers to an identiy in a DevOps tool and is automatically created when importing data from that tool. For example, a `user` may have a GitHub `account` as well as a Jira `account`. + +Apache DevLake uses a simple heuristic algorithm based on emails and names to automatically map accounts to users and populate the `user_accounts` table. +When Apache DevLake cannot confidently map an `account` to a `user` due to insufficient information, it allows DevLake users to manually configure the mapping to ensure accuracy and integrity. + +## A step-by-step guide + +In the following sections, we'll walk through how to configure teams and create the five aforementioned tables (`teams`, `users`, `team_users`, `accounts`, and `user_accounts`). +The overall workflow is: + +1. Create the `teams` table +2. Create the `users` and `team_users` table +3. Populate the `accounts` table via data collection +4. Run a heuristic algorithm to populate `user_accounts` table +5. Manually update `user_accounts` when the algorithm can't catch everything + +Note: + +1. Please replace `/path/to/*.csv` with the absolute path of the CSV file you'd like to upload. +2. Please replace `127.0.0.1:4000` with your actual Apache DevLake ConfigUI service IP and port number. + +## Step 1 - Create the `teams` table + +You can create the `teams` table by sending a PUT request to `/plugins/org/teams.csv` with a `teams.csv` file. To jumpstart the process, you can download a template `teams.csv` from `/plugins/org/teams.csv?fake_data=true`. Below are the detailed instructions: + +a. Download the template `teams.csv` file + + i. GET http://127.0.0.1:4000/api/plugins/org/teams.csv?fake_data=true (pasting the URL into your browser will download the template) + + ii. If you prefer using curl: + curl --location --request GET 'http://127.0.0.1:4000/api/plugins/org/teams.csv?fake_data=true' + + +b. Fill out `teams.csv` file and upload it to DevLake (If you are using Excel to modify the CSV file, please save it with UTF-8 encoding. See [how](https://answers.microsoft.com/en-us/msoffice/forum/all/how-can-i-save-a-csv-with-utf-8-encoding-using/12801501-c1e4-4a64-80d9-96b680b64cfe)) + + i. Fill out `teams.csv` with your org data. Please don't modify the column headers or the file suffix. + + ii. Upload `teams.csv` to DevLake with the following curl command: + curl --location --request PUT 'http://127.0.0.1:4000/api/plugins/org/teams.csv' --form 'file=@"/path/to/teams.csv"' + + iii. The PUT request would populate the `teams` table with data from `teams.csv` file. + You can connect to the database and verify the data in the `teams` table. + See Appendix for how to connect to the database. + +![image](/img/Team/teamflow3.png) + + +## Step 2 - Create the `users` and `team_users` table + +You can create the `users` and `team_users` table by sending a single PUT request to `/plugins/org/users.csv` with a `users.csv` file. To jumpstart the process, you can download a template `users.csv` from `/plugins/org/users.csv?fake_data=true`. Below are the detailed instructions: + +a. Download the template `users.csv` file + + i. GET http://127.0.0.1:4000/api/plugins/org/users.csv?fake_data=true (pasting the URL into your browser will download the template) + + ii. If you prefer using curl: + curl --location --request GET 'http://127.0.0.1:4000/api/plugins/org/users.csv?fake_data=true' + + +b. Fill out `users.csv` and upload to DevLake (If you are using Excel to modify the CSV file, please save it with UTF-8 encoding. See [how](https://answers.microsoft.com/en-us/msoffice/forum/all/how-can-i-save-a-csv-with-utf-8-encoding-using/12801501-c1e4-4a64-80d9-96b680b64cfe)) + + i. Fill out `users.csv` with your org data. Please don't modify the column headers or the file suffix + + ii. Upload `users.csv` to DevLake with the following curl command: + curl --location --request PUT 'http://127.0.0.1:4000/api/plugins/org/users.csv' --form 'file=@"/path/to/users.csv"' + + iii. The PUT request would populate the `users` table along with the `team_users` table with data from `users.csv` file. + You can connect to the database and verify these two tables. + +![image](/img/Team/teamflow1.png) + +![image](/img/Team/teamflow2.png) + +c. If you ever want to update `team_users` or `users` table, simply upload the updated `users.csv` to DevLake again following step b. + +## Step 3 - Populate the `accounts` table via data collection + +The `accounts` table is automatically populated when you collect data from data sources like GitHub and Jira through DevLake. + +For example, the GitHub plugin would create one entry in the `accounts` table for each GitHub user involved in your repository. +For demo purposes, we'll insert some mock data into the `accounts` table using SQL: + +``` +INSERT INTO `accounts` (`id`, `created_at`, `updated_at`, `_raw_data_params`, `_raw_data_table`, `_raw_data_id`, `_raw_data_remark`, `email`, `full_name`, `user_name`, `avatar_url`, `organization`, `created_date`, `status`) +VALUES + ('github:GithubAccount:1:1234', '2022-07-12 10:54:09.632', '2022-07-12 10:54:09.632', '{\"ConnectionId\":1,\"Owner\":\"apache\",\"Repo\":\"incubator-devlake\"}', '_raw_github_api_pull_request_reviews', 28, '', 'TyroneKCummings@teleworm.us', '', 'Tyrone K. Cummings', 'https://avatars.githubusercontent.com/u/101256042?u=a6e460fbaffce7514cbd65ac739a985f5158dabc&v=4', '', NULL, 0), + ('jira:JiraAccount:1:629cdf', '2022-07-12 10:54:09.632', '2022-07-12 10:54:09.632', '{\"ConnectionId\":1,\"BoardId\":\"76\"}', '_raw_jira_api_users', 5, '', 'DorothyRUpdegraff@dayrep.com', '', 'Dorothy R. Updegraff', 'https://avatars.jiraxxxx158dabc&v=4', '', NULL, 0); + +``` + +![image](/img/Team/teamflow4.png) + +## Step 4 - Run a heuristic algorithm to populate `user_accounts` table + +Now that we have data in both the `users` and `accounts` table, we can tell DevLake to infer the mappings between `users` and `accounts` with a simple heuristic algorithm based on names and emails. + +a. Send an API request to DevLake to run the mapping algorithm + +``` +curl --location --request POST '127.0.0.1:4000/api/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "name": "test", + "plan":[ + [ + { + "plugin": "org", + "subtasks":["connectUserAccountsExact"], + "options":{ + "connectionId":1 + } + } + ] + ] +}' +``` + +b. After successful execution, you can verify the data in `user_accounts` in the database. + +![image](/img/Team/teamflow5.png) + +## Step 5 - Manually update `user_accounts` when the algorithm can't catch everything + +It is recommended to examine the generated `user_accounts` table after running the algorithm. +We'll demonstrate how to manually update `user_accounts` when the mapping is inaccurate/incomplete in this section. +To make manual verification easier, DevLake provides an API for users to download `user_accounts` as a CSV file. +Alternatively, you can verify and modify `user_accounts` all by SQL, see Appendix for more info. + +a. GET http://127.0.0.1:4000/api/plugins/org/user_account_mapping.csv(pasting the URL into your browser will download the file). If you prefer using curl: +``` +curl --location --request GET 'http://127.0.0.1:4000/api/plugins/org/user_account_mapping.csv' +``` + +![image](/img/Team/teamflow6.png) + +b. If you find the mapping inaccurate or incomplete, you can modify the `user_account_mapping.csv` file and then upload it to DevLake. +For example, here we change the `UserId` of row 'Id=github:GithubAccount:1:1234' in the `user_account_mapping.csv` file to 2. + +c. Save and upload the updated `user_account_mapping.csv` file with the following curl command (If you are using Excel to modify the CSV file, please save it with UTF-8 encoding. See [how](https://answers.microsoft.com/en-us/msoffice/forum/all/how-can-i-save-a-csv-with-utf-8-encoding-using/12801501-c1e4-4a64-80d9-96b680b64cfe)): + +``` +curl --location --request PUT 'http://127.0.0.1:4000/api/plugins/org/user_account_mapping.csv' --form 'file=@"/path/to/user_account_mapping.csv"' +``` + +d. You can verify the data in the `user_accounts` table has been updated. + +![image](/img/Team/teamflow7.png) + +## Appendix A: how to connect to the database + +Here we use MySQL as an example. You can install database management tools like Sequel Ace, DataGrip, MySQLWorkbench, etc. + + +Or through the command line: + +``` +mysql -h -u -p -P +``` + +## Appendix B: how to examine `user_accounts` via SQL + +``` +SELECT a.id as account_id, a.email, a.user_name as account_user_name, u.id as user_id, u.name as real_name +FROM accounts a + join user_accounts ua on a.id = ua.account_id + join users u on ua.user_id = u.id +``` + + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Installation.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/Teambition.md b/versioned_docs/version-v0.21/Configuration/Teambition.md new file mode 100644 index 00000000000..2623edb1535 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Teambition.md @@ -0,0 +1,56 @@ +--- +title: "Teambition(WIP)" +sidebar_position: 23 +description: Config UI instruction for Teambition +--- + +Visit Config UI: `http://localhost:4000` and go to `Connections` page. + +## Step 1 - Add Data Connections +![teambition-add-data-connections](https://user-images.githubusercontent.com/3294100/229744282-1959dc82-9038-49a8-924d-11821fafa73a.png) + +### Connection Name +Give your connection a unique name to help you identify it in the future. + +#### Endpoint URL +This should be a valid REST API endpoint + - `https://open.teambition.com/api/` +The endpoint url should end with `/`. + +### App Id/Secret Key +Input the app id and secret key of your Teambition account, you can follow the steps as below. +![image-20230404213648139](https://user-images.githubusercontent.com/3294100/229810617-fe75cf7d-5a84-4741-9016-47140b276e18.png)![image](https://user-images.githubusercontent.com/3294100/229810458-cf47806b-6307-419c-8147-a176ebafca74.png) + +You should ensure that you have added all the necessary "get" and "list" authentication methods. + +![image](https://user-images.githubusercontent.com/3294100/229813323-0c490e65-1ecb-4e1c-8df2-ef68cb55a4a4.png) + +#### Tenant Type/Tenant Id + +It is important to add your app before finding the Tenant Id. + +![image](https://user-images.githubusercontent.com/3294100/229812333-188e497f-db5c-426c-ad1e-6fdb5e1e3b17.png) + +![image](https://user-images.githubusercontent.com/3294100/229812594-e3c619cb-363d-491f-aeae-3e8e6912c70a.png) + +![image](https://user-images.githubusercontent.com/3294100/229814145-9bdf006e-450e-4c14-98c6-a5b3fba690ea.png) + +### Proxy URL (Optional) + +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + +### Ralte Limit (Optional) +For Teambition, we suggest you setting the rate limit to 5000 + +### Test and Save Connection +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +## Step 2 - Configure Blueprint + +Similar to other beta plugins, Teambition does not support `project`, which means, you can only collect Teambition data via blueprint's advanced mode. + +Please go to the `Blueprints` page and switch to advanced mode. See how to use advanced mode and JSON [examples](AdvancedMode.md#11-teambition). + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Configuration/Tutorial.md b/versioned_docs/version-v0.21/Configuration/Tutorial.md new file mode 100644 index 00000000000..42ac5a5f336 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Tutorial.md @@ -0,0 +1,63 @@ +--- +title: "Tutorial" +sidebar_position: 1 +description: Config UI instruction +--- + +The Apache DevLake Config UI provides a user-friendly interface for configuring the data collection process. To access the Config UI, please visit http://localhost:4000. + +## Basic Configuration +To ensure the proper functioning of DevLake, follow these two key steps: + +### Step 1 - Add Data Connections +![img](images/data-connections.png) + +- Step 1.1 - Add a connection. Configure the endpoint and authentication details to connect to the source data. + +- Step 1.2 - Add data scope, such as Git repositories, issue boards, or CI/CD pipelines, to determine what data should be collected. + +- Step 1.3 - Add scope config (optional). Define the specific data entities within the data scope for collection or apply transformation rules to the raw API responses. + +### Step 2 - Collect Data in a Project +- Step 2.1 - Create a project. DevLake assesses DORA metrics at the project level. For more information on organizing DevLake projects, please refer to [how to organize DevLake projects](/docs/Configuration/HowToOrganizeDevlakeProjects.md) for more details. + +- Step 2.2 - Associate connection(s) with the project. When associating a connection with a project, you can select specific data scopes. All connections linked to the same project will be considered part of the same project for calculating DORA metrics. + +- Step 2.3 - Set the synchronization policy. Specify the sync frequency, time range and the skip-on-fail option for your data. + +- Step 2.4 - Start data collection. Choose the desired [mode](#step-2---collect-data-in-a-project) for collecting data. + +### Step 3 - Check the Data in Grafana Dashboards +To view the collected data, click on the "Dashboards" button located in the top-right corner of Config UI. For detailed instructions, please refer to the [Grafana manuals](Dashboards/GrafanaUserGuide.md). + +## Examples +For detailed examples, please refer to the respective documentation files available in this folder, such as [GitHub configuration](GitHub.md), [GitLab configuration](GitLab.md), [Jira configuration](Jira.md) and more. They provide step-by-step instructions and guidance for configuring DevLake with different platforms. + +## Q&A + +#### Q1. What are the specific sync policies to configure? +- Time Filter: This allows you to select the desired time range for syncing data, optimizing the collection process. + +- Frequency: You can determine the frequency of data synchronization by choosing a sync frequency option or specifying a cron code for a custom schedule. + +- Running Policy: By default, the "Skip failed tasks" option is enabled. This helps prevent data loss in scenarios where you are collecting a large volume of data (e.g., 10+ GitHub repositories, Jira boards, etc.). When a task fails, this policy allows the pipeline to continue running, preserving the data collected by successful tasks. You can rerun the failed tasks later from the blueprint's detail page. + + +#### Q2. What data collection modes do DevLake support? +Three modes. +- _Collect Data (Default)_: This mode retrieves data within the specified time range. Tools and entities that support incremental refresh will utilize this method, while those that only support full refresh will perform a full refresh. This mode is the default choice for recurring pipelines. +- _Collect Data in Full Refresh Mode_: In this mode, all existing data within the designated time range will be deleted and re-collected. It is useful for removing outdated or irrelevant data from DevLake that no longer exists in the original tools. +- _Re-transform Data_: This mode does not collect new data. Instead, it applies the latest transformation rules from the Scope Config to the existing data. + +## Troubleshooting + +#### 1. What can be done when a data collection failed or partially succeeded? +- First, re-run the failed task once all other tasks have completed. If the task still fails, proceed to the next steps. +- Capture a screenshot of the error message associated with the failed task. +- Download the logs from the pipeline for further analysis. +- Visit the [GitHub repository](https://github.com/apache/incubator-devlake/issues) and create a bug report. Include the captured screenshot and the downloaded logs in the bug report. + + ![img](/img/ConfigUI/BlueprintEditing/blueprint-edit3.png) + + +For other problems, please check the [troubleshooting](/Troubleshooting/Configuration.md) doc, [create an issue](https://github.com/apache/incubator-devlake/issues), or contact us on [Slack](https://join.slack.com/t/devlake-io/shared_invite/zt-17b6vuvps-x98pqseoUagM7EAmKC82xQ). diff --git a/versioned_docs/version-v0.21/Configuration/Zentao.md b/versioned_docs/version-v0.21/Configuration/Zentao.md new file mode 100644 index 00000000000..51a96af3d0f --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/Zentao.md @@ -0,0 +1,59 @@ +--- +title: "Zentao" +sidebar_position: 27 +description: Config UI instruction for Zentao(禅道) +--- + +Visit Config UI at: `http://localhost:4000` and go to `Connections` page. + +## Step 1 - Add Data Connections + +![zentao-add-data-connections](images/zentao-create-a-connection.png) + +### Connection Name + +Give your connection a unique name to help you identify it in the future. + +### Endpoint URL + +Please ensure that the REST API endpoint URL is valid. It should be in the format of either `http://:/api.php/v1/` or `http://:/zentao/api.php/v1/`. + +If the initial test fails, please try another endpoint URL as the URL depends on where Zentao is deployed. Additionally, please ensure that the endpoint URL ends with a forward slash `/`. + +### Username/Password + +Input the username and password of your Zentao account. + +### Proxy URL (Optional) + +If you are behind a corporate firewall or VPN you may need to utilize a proxy server. Enter a valid proxy server address on your network, e.g. `http://your-proxy-server.com:1080` + +### Test and Save Connection + +Click `Test Connection`, if the connection is successful, click `Save Connection` to add the connection. + +## Step 2 - Setting Data Scope + +![image](https://user-images.githubusercontent.com/3294100/230921313-d43821c2-0c41-4bb4-b1ef-d87e4afb1fa4.png) + +### Projects and Products + +Please select the Zentao products for collecting stories/bugs and the Zentao projects for collecting executions. Both will also collect information on accounts/departments. + +### Data Entities + +Usually, you don't have to modify this part. However, if you don't want to collect certain Lento entities, you can unselect some entities to accerlerate the collection speed. + +- Issue Tracking: Lento issues, issue comments, issue labels, etc. + +## Step 3 - Adding Transformation Rules (Optional) +Zentao does not have transformation and this step will be skipped. + +## Step 4 - Setting Sync Policy + +You can choose how often you would like to sync your data in this step by selecting a sync frequency option or enter a cron code to specify your prefered schedule. + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) + diff --git a/versioned_docs/version-v0.21/Configuration/_category_.json b/versioned_docs/version-v0.21/Configuration/_category_.json new file mode 100644 index 00000000000..48013204918 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Config UI", + "position": 3, + "link":{ + "type": "generated-index", + "slug": "Config UI" + } +} diff --git a/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/create_project_1.png b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/create_project_1.png new file mode 100644 index 00000000000..08acd956909 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/create_project_1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/create_project_2.png b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/create_project_2.png new file mode 100644 index 00000000000..f054e5364b1 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/create_project_2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/navigate_to_dora_1.png b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/navigate_to_dora_1.png new file mode 100644 index 00000000000..0f89aeb18a8 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/navigate_to_dora_1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/navigate_to_dora_2.png b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/navigate_to_dora_2.png new file mode 100644 index 00000000000..4eb27c16f57 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/navigate_to_dora_2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/observe_metrics_by_project_panel.png b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/observe_metrics_by_project_panel.png new file mode 100644 index 00000000000..0b47235994a Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/observe_metrics_by_project_panel.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/project_pipeline.png b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/project_pipeline.png new file mode 100644 index 00000000000..845ef6563d9 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/project_pipeline.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/project_use_case_1.png b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/project_use_case_1.png new file mode 100644 index 00000000000..a06e763964c Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/project_use_case_1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/project_use_case_2.png b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/project_use_case_2.png new file mode 100644 index 00000000000..4cc071558c6 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/HowToOrganizeDevlakeProjects/project_use_case_2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/add-a-connection-project.png b/versioned_docs/version-v0.21/Configuration/images/add-a-connection-project.png new file mode 100644 index 00000000000..2e619b6bf7e Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/add-a-connection-project.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/api-key-list.png b/versioned_docs/version-v0.21/Configuration/images/api-key-list.png new file mode 100644 index 00000000000..ac4a34dbfbe Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/api-key-list.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/arch-dataflow-domain.svg b/versioned_docs/version-v0.21/Configuration/images/arch-dataflow-domain.svg new file mode 100644 index 00000000000..2c35d672b83 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/images/arch-dataflow-domain.svg @@ -0,0 +1,4 @@ + + + +
Tool layer
Tool layer
Extract raw data into a relational schema
Extract raw data into a relatio...
_tool_jira_issues
_tool_jira_issues
_tool_github_issues
_tool_github_iss...
e.g. _raw_jira_issues
e.g. _raw_jira_issues
Raw layer
Raw layer
Caches API responses 
Caches API responses 
Domain layer
Domain layer
Provides domain abstraction across different tools
Provides domain abstractio...
e.g. _raw_jira_issues
e.g. _raw_jira_is...
_raw_github_issues
_raw_github_issu...
issues
issues
Text is not SVG - cannot display
\ No newline at end of file diff --git a/versioned_docs/version-v0.21/Configuration/images/arch-dataflow-raw.svg b/versioned_docs/version-v0.21/Configuration/images/arch-dataflow-raw.svg new file mode 100644 index 00000000000..a413ef537c9 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/images/arch-dataflow-raw.svg @@ -0,0 +1,4 @@ + + + +
Tool layer
Tool layer
Extract raw data into a relational schema
Extract raw data into a relational...
_tool_jira_issues
_tool_jira_issues
_tool_github_issues
_tool_github_iss...
e.g. _raw_jira_issues
e.g. _raw_jira_issues
Raw layer
Raw layer
Caches API responses 
Caches API responses 
Domain layer
Domain layer
Provides domain abstraction across different tools
Provides domain abstractio...
e.g. _raw_jira_issues
e.g. _raw_jira_is...
_raw_github_issues
_raw_github_issu...
issues
issues
Text is not SVG - cannot display
\ No newline at end of file diff --git a/versioned_docs/version-v0.21/Configuration/images/arch-dataflow-tool.svg b/versioned_docs/version-v0.21/Configuration/images/arch-dataflow-tool.svg new file mode 100644 index 00000000000..a35793c42f9 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/images/arch-dataflow-tool.svg @@ -0,0 +1,4 @@ + + + +
Tool layer
Tool layer
Extract raw data into a relational schema
Extract raw data into a relatio...
_tool_jira_issues
_tool_jira_issues
_tool_github_issues
_tool_github_iss...
e.g. _raw_jira_issues
e.g. _raw_jira_issues
Raw layer
Raw layer
Caches API responses 
Caches API responses 
Domain layer
Domain layer
Provides domain abstraction across different tools
Provides domain abstractio...
e.g. _raw_jira_issues
e.g. _raw_jira_is...
_raw_github_issues
_raw_github_issu...
issues
issues
Text is not SVG - cannot display
\ No newline at end of file diff --git a/versioned_docs/version-v0.21/Configuration/images/arch-dataflow.svg b/versioned_docs/version-v0.21/Configuration/images/arch-dataflow.svg new file mode 100644 index 00000000000..46ecaa94099 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/images/arch-dataflow.svg @@ -0,0 +1,4 @@ + + + +
Tool layer
Tool layer
Extract raw data into a relational schema
Extract raw data into a relatio...
_tool_jira_issues
_tool_jira_issues
_tool_github_issues
_tool_github_iss...
e.g. _raw_jira_issues
e.g. _raw_jira_issues
Raw layer
Raw layer
Caches API responses 
Caches API responses 
e.g. _raw_jira_issues
e.g. _raw_jira_is...
_raw_github_issues
_raw_github_issu...
Domain layer
Domain layer
Provides domain abstraction across different tools
Provides domain abstractio...
issues
issues
Text is not SVG - cannot display
\ No newline at end of file diff --git a/versioned_docs/version-v0.21/Configuration/images/auto-generated-api-key.png b/versioned_docs/version-v0.21/Configuration/images/auto-generated-api-key.png new file mode 100644 index 00000000000..0eefa7658cd Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/auto-generated-api-key.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/azuredevops-create-a-connection.png b/versioned_docs/version-v0.21/Configuration/images/azuredevops-create-a-connection.png new file mode 100644 index 00000000000..042c1f4f789 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/azuredevops-create-a-connection.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/azuredevops-set-data-scope.png b/versioned_docs/version-v0.21/Configuration/images/azuredevops-set-data-scope.png new file mode 100644 index 00000000000..37b4f8cdfed Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/azuredevops-set-data-scope.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/azuredevops-set-transformation.png b/versioned_docs/version-v0.21/Configuration/images/azuredevops-set-transformation.png new file mode 100644 index 00000000000..cd28de7533d Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/azuredevops-set-transformation.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/blueprint-erd.svg b/versioned_docs/version-v0.21/Configuration/images/blueprint-erd.svg new file mode 100644 index 00000000000..fdf9543b814 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/images/blueprint-erd.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/versioned_docs/version-v0.21/Configuration/images/cfr.png b/versioned_docs/version-v0.21/Configuration/images/cfr.png new file mode 100644 index 00000000000..73af317d74b Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/cfr.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/collect-data.png b/versioned_docs/version-v0.21/Configuration/images/collect-data.png new file mode 100644 index 00000000000..962cb164ad2 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/collect-data.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/create-a-project.png b/versioned_docs/version-v0.21/Configuration/images/create-a-project.png new file mode 100644 index 00000000000..7d95a9b8227 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/create-a-project.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/data-connections.png b/versioned_docs/version-v0.21/Configuration/images/data-connections.png new file mode 100644 index 00000000000..6fd8d7adbe7 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/data-connections.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/deployment_definition.png b/versioned_docs/version-v0.21/Configuration/images/deployment_definition.png new file mode 100644 index 00000000000..7c54fd4c5fc Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/deployment_definition.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/deployments.png b/versioned_docs/version-v0.21/Configuration/images/deployments.png new file mode 100644 index 00000000000..1e05b234207 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/deployments.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/domain-layer-schema-diagram.svg b/versioned_docs/version-v0.21/Configuration/images/domain-layer-schema-diagram.svg new file mode 100644 index 00000000000..4e5bd21c159 --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/images/domain-layer-schema-diagram.svg @@ -0,0 +1,19874 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/versioned_docs/version-v0.21/Configuration/images/domain_layer_model.ndm2 b/versioned_docs/version-v0.21/Configuration/images/domain_layer_model.ndm2 new file mode 100644 index 00000000000..da4eaee29dd --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/images/domain_layer_model.ndm2 @@ -0,0 +1,20126 @@ +{ + "paper": { + "name": "A4", + "leftMargin": 0.5, + "rightMargin": 0.5, + "topMargin": 0.5, + "bottomMargin": 0.5, + "isPortriat": true + }, + "modelVersion": 2.01, + "defaultSchema": "Default", + "server": { + "objectType": "Server_MYSQL", + "name": "Default", + "uuid": "", + "serverVersion": 80099, + "edition": "Default", + "lowerCaseTableNames": 0, + "schemas": [ + { + "objectType": "Schema_MYSQL", + "name": "Default", + "tables": [ + { + "objectType": "Table_MYSQL", + "name": "issue_labels", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_labels_issues_1", + "fields": [ + "issue_id" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "board_sprints", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "board_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "Jira: origin_board_key, Github and Gitlab: origin_repo_key", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "board_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "sprint_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "sprint_id" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_board_sprints_boards_1", + "fields": [ + "board_id" + ], + "referenceSchema": "Default", + "referenceTable": "boards", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_board_sprints_sprints_1", + "fields": [ + "sprint_id" + ], + "referenceSchema": "Default", + "referenceTable": "sprints", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "board_issues", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "board_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "Jira: origin_board_key, Github and Gitlab: origin_repo_key", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "board_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_board_issues_boards_1", + "fields": [ + "board_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "boards", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_board_issues_issues_1", + "fields": [ + "issue_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "sprint_trends", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "sprint_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "sprint_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "started_date", + "type": "datetime", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "started_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "ended_date", + "type": "datetime", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "ended_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "ended_hour", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "ended_hour" + }, + { + "objectType": "TableField_MYSQL", + "name": "added", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "added" + }, + { + "objectType": "TableField_MYSQL", + "name": "removed", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "removed" + }, + { + "objectType": "TableField_MYSQL", + "name": "remaining", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "remaining" + }, + { + "objectType": "TableField_MYSQL", + "name": "resolved", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "resolved" + }, + { + "objectType": "TableField_MYSQL", + "name": "added_requirements", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "added_requirements" + }, + { + "objectType": "TableField_MYSQL", + "name": "removed_requirements", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "removed_requirements" + }, + { + "objectType": "TableField_MYSQL", + "name": "remaining_requirements", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "remaining_requirements" + }, + { + "objectType": "TableField_MYSQL", + "name": "resolved_requirements", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "resolved_requirements" + }, + { + "objectType": "TableField_MYSQL", + "name": "added_bugs", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "added_bugs" + }, + { + "objectType": "TableField_MYSQL", + "name": "removed_bugs", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "removed_bugs" + }, + { + "objectType": "TableField_MYSQL", + "name": "remaining_bugs", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "remaining_bugs" + }, + { + "objectType": "TableField_MYSQL", + "name": "resolved_bugs", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "resolved_bugs" + }, + { + "objectType": "TableField_MYSQL", + "name": "added_incidents", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "added_incidents" + }, + { + "objectType": "TableField_MYSQL", + "name": "removed_incidents", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "removed_incidents" + }, + { + "objectType": "TableField_MYSQL", + "name": "remaining_incidents", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "remaining_incidents" + }, + { + "objectType": "TableField_MYSQL", + "name": "resolved_incidents", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "resolved_incidents" + }, + { + "objectType": "TableField_MYSQL", + "name": "added_other_issues", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "added_other_issues" + }, + { + "objectType": "TableField_MYSQL", + "name": "removed_other_issues", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "removed_other_issues" + }, + { + "objectType": "TableField_MYSQL", + "name": "remaining_other_issues", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "remaining_other_issues" + }, + { + "objectType": "TableField_MYSQL", + "name": "resolved_other_issues", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "resolved_other_issues" + }, + { + "objectType": "TableField_MYSQL", + "name": "added_story_points", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "added_story_points" + }, + { + "objectType": "TableField_MYSQL", + "name": "removed_story_points", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "removed_story_points" + }, + { + "objectType": "TableField_MYSQL", + "name": "remaining_story_points", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "remaining_story_points" + }, + { + "objectType": "TableField_MYSQL", + "name": "resolved_story_points", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "resolved_story_points" + }, + { + "objectType": "TableField_MYSQL", + "name": "added_worklog_minutes", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "added_worklog_minutes" + } + ], + "indexes": [], + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_assignee_history", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "assignee", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "assignee" + }, + { + "objectType": "TableField_MYSQL", + "name": "start_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "start_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "end_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "end_date" + } + ], + "indexes": [], + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_sprints_history", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "sprint_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "sprint_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "start_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "start_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "end_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "end_date" + } + ], + "indexes": [], + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_status_history", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_status", + "type": "enum", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_status" + }, + { + "objectType": "TableField_MYSQL", + "name": "start_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "start_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "end_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "end_date" + } + ], + "indexes": [], + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "board_repos(WIP)", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "board_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "board_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "repo_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_id" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issue_board_repo_boards_1", + "fields": [ + "board_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "boards", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issue_board_repo_repos_1", + "fields": [ + "repo_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "repos", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "pull_request_issues", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "pull_request_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "pull_request_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "pull_request_number", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "pull_request_number" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_number", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_number" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_request_issues_pull_requests_1", + "fields": [ + "pull_request_id" + ], + "referenceSchema": "Default", + "referenceTable": "pull_requests", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_request_issues_issues_1", + "fields": [ + "issue_id" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "repo_languages(WIP)", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "repo_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "language", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "language" + }, + { + "objectType": "TableField_MYSQL", + "name": "bytes", + "type": "int", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "bytes" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_repos_languages_repos_1", + "fields": [ + "repo_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "repos", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "repo_commits", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "repo_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_repo_commits_repos_1", + "fields": [ + "repo_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "repos", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_repo_commits_commits_1", + "fields": [ + "commit_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "commit_parents", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "parent", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "parent" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commit_parents_commits_1", + "fields": [ + "parent" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commit_parents_commits_2", + "fields": [ + "commit_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "commit_comments(WIP)", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "user_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "user_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "body", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "body" + }, + { + "objectType": "TableField_MYSQL", + "name": "line", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "line" + }, + { + "objectType": "TableField_MYSQL", + "name": "position", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "position" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commit_comments_commits_1", + "fields": [ + "commit_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "pull_request_events(WIP)", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "pull_request_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "pull_request_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "action", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "action" + }, + { + "objectType": "TableField_MYSQL", + "name": "actor_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "actor_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_requests_history_pull_requests_1", + "fields": [ + "pull_request_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "pull_requests", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_requests_history_users_1", + "fields": [ + "actor_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "refs_issues_diffs", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "new_ref_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "new_ref_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "old_ref_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "old_ref_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "new_ref_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "new_ref_commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "old_ref_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "old_ref_commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_number", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_number" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + } + ], + "indexes": [], + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_worklogs", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "author_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "author_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "comment", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "comment" + }, + { + "objectType": "TableField_MYSQL", + "name": "time_spent_minutes", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "time_spent_minutes" + }, + { + "objectType": "TableField_MYSQL", + "name": "logged_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "the time user logged the record", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "logged_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "started_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "work started date", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "started_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_worklogs_issues_1", + "fields": [ + "issue_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_worklogs_accounts_1", + "fields": [ + "author_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "users", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "int", + "length": 0, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "email", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "email" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "user_accounts", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "user_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "user_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "account_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "account_id" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_user_accounts_users_1", + "fields": [ + "user_id" + ], + "referenceSchema": "Default", + "referenceTable": "users", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_user_accounts_accounts_1", + "fields": [ + "account_id" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "team_users", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "team_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "team_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "user_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "user_id" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_team_users_teams_1", + "fields": [ + "team_id" + ], + "referenceSchema": "Default", + "referenceTable": "teams", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_team_users_users_1", + "fields": [ + "user_id" + ], + "referenceSchema": "Default", + "referenceTable": "users", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "teams", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "alias", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "alias" + }, + { + "objectType": "TableField_MYSQL", + "name": "parent_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "parent_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "sorting_index", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "sorting_index" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_teams_teams_1", + "fields": [ + "parent_id" + ], + "referenceSchema": "Default", + "referenceTable": "teams", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "components", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "repo_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "path_regex", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "path_regex" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_components_repos_1", + "fields": [ + "repo_id" + ], + "referenceSchema": "Default", + "referenceTable": "repos", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "commit_file_components", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "commit_file_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_file_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "component_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "component_name" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commit_file_components_commit_files_1", + "fields": [ + "commit_file_id" + ], + "referenceSchema": "Default", + "referenceTable": "commit_files", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "jobs(WIP)", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + } + ], + "indexes": [], + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "builds(WIP)", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "job_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "job_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "duration_sec", + "type": "bigint", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "duration_sec" + }, + { + "objectType": "TableField_MYSQL", + "name": "started_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "started_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "build result", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "nullable", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_builds_jobs_1", + "fields": [ + "job_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "jobs(WIP)", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "accounts", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "email", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "email" + }, + { + "objectType": "TableField_MYSQL", + "name": "full_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "full_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "user_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "user_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "avartar_url", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "avartar_url" + }, + { + "objectType": "TableField_MYSQL", + "name": "organization", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "organization" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "0", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "sprints", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "url", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "url" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + }, + { + "objectType": "TableField_MYSQL", + "name": "started_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "started_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "ended_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "ended_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "completed_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "completed_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_board_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_board_id" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_sprints_projects_1", + "fields": [ + "project_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "issue_projects", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "table_1", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [], + "indexes": [], + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "finished_commits_diffs", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "new_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "new_commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "old_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "old_commit_sha" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "new_commit_sha", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "old_commit_sha", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commits_diffs_status_commits_diffs_status_1", + "fields": [ + "new_commit_sha" + ], + "referenceSchema": "Default", + "referenceTable": "commits_diffs", + "referenceFields": [ + "new_commit_sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commits_diffs_status_commits_diffs_status_2", + "fields": [ + "old_commit_sha" + ], + "referenceSchema": "Default", + "referenceTable": "commits_diffs", + "referenceFields": [ + "old_commit_sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commits_diffs_status_commits_diffs_status_3", + "fields": [ + "old_commit_sha" + ], + "referenceSchema": "lake", + "referenceTable": "cicd_pipeline_commits", + "referenceFields": [ + "commit_sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "project", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "name for project ", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "description", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "description of the project", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "description" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_at", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "created time of project", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_at" + }, + { + "objectType": "TableField_MYSQL", + "name": "updated_at", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "last updated time of project", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "updated_at" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "name", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "project_metric_settings", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "project_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "name for project", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "project_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "plugin_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "name for plugin ", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "plugin_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "plugin_option", + "type": "longtext", + "length": 0, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "check if metric plugins have been enabled by the project", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "plugin_option" + }, + { + "objectType": "TableField_MYSQL", + "name": "enable", + "type": "tinyint", + "length": 1, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "if the metric plugins is enabled", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "enable" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "project_name", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "plugin_name", + "keyLength": -2147483648, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_project_metric_settings_project_1", + "fields": [ + "project_name" + ], + "referenceSchema": "Default", + "referenceTable": "project", + "referenceFields": [ + "name" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "project_mapping", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "project_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "name for project", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "project_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "table", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "the table name of Scope", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "table" + }, + { + "objectType": "TableField_MYSQL", + "name": "row_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "the row_id in the Scope", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "row_id" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "project_name", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "table", + "keyLength": -2147483648, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "row_id", + "keyLength": -2147483648, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_project_mapping_project_1", + "fields": [ + "project_name" + ], + "referenceSchema": "Default", + "referenceTable": "project", + "referenceFields": [ + "name" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cq_file_metrics", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "project_key", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "project_key" + }, + { + "objectType": "TableField_MYSQL", + "name": "file_name", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "file_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "file_path", + "type": "longtext", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "file_path" + }, + { + "objectType": "TableField_MYSQL", + "name": "file_language", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "file_language" + }, + { + "objectType": "TableField_MYSQL", + "name": "code_smells", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "code_smells" + }, + { + "objectType": "TableField_MYSQL", + "name": "sqale_index", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "sqale_index" + }, + { + "objectType": "TableField_MYSQL", + "name": "sqale_rating", + "type": "double", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "sqale_rating" + }, + { + "objectType": "TableField_MYSQL", + "name": "bugs", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "bugs" + }, + { + "objectType": "TableField_MYSQL", + "name": "reliability_rating", + "type": "varchar", + "length": 20, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "reliability_rating" + }, + { + "objectType": "TableField_MYSQL", + "name": "vulnerabilities", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "vulnerabilities" + }, + { + "objectType": "TableField_MYSQL", + "name": "security_rating", + "type": "varchar", + "length": 20, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "security_rating" + }, + { + "objectType": "TableField_MYSQL", + "name": "security_hotspots", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "security_hotspots" + }, + { + "objectType": "TableField_MYSQL", + "name": "security_hotspots_reviewed", + "type": "double", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "security_hotspots_reviewed" + }, + { + "objectType": "TableField_MYSQL", + "name": "security_review_rating", + "type": "varchar", + "length": 20, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "security_review_rating" + }, + { + "objectType": "TableField_MYSQL", + "name": "ncloc", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "ncloc" + }, + { + "objectType": "TableField_MYSQL", + "name": "coverage", + "type": "double", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "coverage" + }, + { + "objectType": "TableField_MYSQL", + "name": "uncovered_lines", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "uncovered_lines" + }, + { + "objectType": "TableField_MYSQL", + "name": "lines_to_cover", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "lines_to_cover" + }, + { + "objectType": "TableField_MYSQL", + "name": "duplicated_lines_density", + "type": "double", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "duplicated_lines_density" + }, + { + "objectType": "TableField_MYSQL", + "name": "duplicated_blocks", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "duplicated_blocks" + }, + { + "objectType": "TableField_MYSQL", + "name": "duplicated_files", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "duplicated_files" + }, + { + "objectType": "TableField_MYSQL", + "name": "duplicated_lines", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "duplicated_lines" + }, + { + "objectType": "TableField_MYSQL", + "name": "effort_to_reach_maintainability_rating_a", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "effort_to_reach_maintainability_rating_a" + }, + { + "objectType": "TableField_MYSQL", + "name": "complexity", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "complexity" + }, + { + "objectType": "TableField_MYSQL", + "name": "cognitive_complexity", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "cognitive_complexity" + }, + { + "objectType": "TableField_MYSQL", + "name": "num_of_lines", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "num_of_lines" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "", + "fields": [], + "referenceSchema": "Default", + "referenceTable": "cq_projects", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cq_issues", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "rule", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "rule" + }, + { + "objectType": "TableField_MYSQL", + "name": "severity", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "severity" + }, + { + "objectType": "TableField_MYSQL", + "name": "component", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "component" + }, + { + "objectType": "TableField_MYSQL", + "name": "project_key", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "project_key" + }, + { + "objectType": "TableField_MYSQL", + "name": "line", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "line" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 20, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + }, + { + "objectType": "TableField_MYSQL", + "name": "message", + "type": "longtext", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "message" + }, + { + "objectType": "TableField_MYSQL", + "name": "debt", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "debt" + }, + { + "objectType": "TableField_MYSQL", + "name": "effort", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "effort" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_author_email", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_author_email" + }, + { + "objectType": "TableField_MYSQL", + "name": "assignee", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "assignee" + }, + { + "objectType": "TableField_MYSQL", + "name": "hash", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "hash" + }, + { + "objectType": "TableField_MYSQL", + "name": "tags", + "type": "longtext", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "tags" + }, + { + "objectType": "TableField_MYSQL", + "name": "type", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "type" + }, + { + "objectType": "TableField_MYSQL", + "name": "scope", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "scope" + }, + { + "objectType": "TableField_MYSQL", + "name": "start_line", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "start_line" + }, + { + "objectType": "TableField_MYSQL", + "name": "end_line", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "end_line" + }, + { + "objectType": "TableField_MYSQL", + "name": "vulnerability_probablility", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "vulnerability_probablility" + }, + { + "objectType": "TableField_MYSQL", + "name": "security_category", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "security_category" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "updated_date", + "type": "datetime", + "length": 3, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "updated_date" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "_copy_2", + "fields": [], + "referenceSchema": "Default", + "referenceTable": "cq_projects", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cq_issue_code_blocks", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_key", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_key" + }, + { + "objectType": "TableField_MYSQL", + "name": "component", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "component" + }, + { + "objectType": "TableField_MYSQL", + "name": "start_line", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "start_line" + }, + { + "objectType": "TableField_MYSQL", + "name": "end_line", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "end_line" + }, + { + "objectType": "TableField_MYSQL", + "name": "start_offset", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "start_offset" + }, + { + "objectType": "TableField_MYSQL", + "name": "end_offset", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "end_offset" + }, + { + "objectType": "TableField_MYSQL", + "name": "msg", + "type": "longtext", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "msg" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "_copy_1", + "fields": [], + "referenceSchema": "Default", + "referenceTable": "cq_issues", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cq_projects", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "qualifier", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "qualifier" + }, + { + "objectType": "TableField_MYSQL", + "name": "visibility", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "visibility" + }, + { + "objectType": "TableField_MYSQL", + "name": "last_analysis_date", + "type": "datetime", + "length": 3, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "last_analysis_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "varchar", + "length": 128, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_comments", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "account_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "account_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "body", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "body" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issue_comments_issues_1", + "fields": [ + "issue_id" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "boards", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "description", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "description" + }, + { + "objectType": "TableField_MYSQL", + "name": "url", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "url" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "type", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "type" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "sprint_issues", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "sprint_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "sprint_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "sprint_id", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "issue_id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issue_board_repo_boards_1_copy_1", + "fields": [ + "sprint_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "sprints", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issue_board_repo_repos_1_copy_1", + "fields": [ + "issue_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_changelogs", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "author_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "author_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "author_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "author_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "field_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "field_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "field_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "field_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_from_value", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_from_value" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_to_value", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_to_value" + }, + { + "objectType": "TableField_MYSQL", + "name": "from_value", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "from_value" + }, + { + "objectType": "TableField_MYSQL", + "name": "to_value", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "to_value" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issue_changelogs_issues_1", + "fields": [ + "issue_id" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "repos", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "description", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "description" + }, + { + "objectType": "TableField_MYSQL", + "name": "url", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "url" + }, + { + "objectType": "TableField_MYSQL", + "name": "owner_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "owner_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "language", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "language" + }, + { + "objectType": "TableField_MYSQL", + "name": "forked_from", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "forked_from" + }, + { + "objectType": "TableField_MYSQL", + "name": "deleted", + "type": "tinyint", + "length": 1, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "deleted" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "updated_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "updated_date" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_repos_repos_1", + "fields": [ + "forked_from" + ], + "referenceSchema": "Default", + "referenceTable": "repos", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_repos_users_1", + "fields": [ + "owner_id" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "refs", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "The reference name", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "repo_id", + "type": "int", + "length": 0, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "The commit id that this reference included\n", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "is_default", + "type": "tinyint", + "length": 1, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "0:default branch;1:not default\n", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "is_default" + }, + { + "objectType": "TableField_MYSQL", + "name": "ref_type", + "type": "varchar", + "length": 64, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "BRANCH,TAG", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "ref_type" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_refs_repos_1", + "fields": [ + "ref" + ], + "referenceSchema": "Default", + "referenceTable": "repos", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_refs_commits_1", + "fields": [ + "commit_sha" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "commits_diffs", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "new_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "new_commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "old_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "old_commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "The commit id that the 'ref' contains\n", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "sorting_index", + "type": "bigint", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "sorting_index" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "commit_sha", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "new_commit_sha", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "old_commit_sha", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_ref_diffs_commits_1", + "fields": [ + "commit_sha" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_refs_diffs_commits_refs_1", + "fields": [ + "new_ref_name" + ], + "referenceSchema": "Default", + "referenceTable": "refs", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "ref_commits", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "new_ref_id", + "type": "char", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "new_ref_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "old_ref_id", + "type": "char", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "old_ref_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "new_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "new_commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "old_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "old_commit_sha" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "new_ref_id", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "old_ref_id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_ref_commits_ref_commits_1", + "fields": [ + "new_commit_sha" + ], + "referenceSchema": "Default", + "referenceTable": "finished_commits_diffs", + "referenceFields": [ + "new_commit_sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_ref_commits_ref_commits_2", + "fields": [ + "old_commit_sha" + ], + "referenceSchema": "Default", + "referenceTable": "finished_commits_diffs", + "referenceFields": [ + "old_commit_sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "commits", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "message", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "message" + }, + { + "objectType": "TableField_MYSQL", + "name": "author_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "author_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "author_email", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "author_email" + }, + { + "objectType": "TableField_MYSQL", + "name": "authored_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "authored_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "author_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "author_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "committer_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "committer_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "committer_email", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "committer_email" + }, + { + "objectType": "TableField_MYSQL", + "name": "committed_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "committed_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "committer_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "committer_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "additions", + "type": "bigint", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "additions" + }, + { + "objectType": "TableField_MYSQL", + "name": "deletions", + "type": "bigint", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "deletions" + }, + { + "objectType": "TableField_MYSQL", + "name": "dev_eq", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "dev_eq" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "sha", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commits_repo_users_1", + "fields": [ + "author_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commits_repo_users_2", + "fields": [ + "committer_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "commit_files", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "file_path", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "file_path" + }, + { + "objectType": "TableField_MYSQL", + "name": "additions", + "type": "bigint", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "additions" + }, + { + "objectType": "TableField_MYSQL", + "name": "deletions", + "type": "bigint", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "deletions" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_commit_files_commits_1", + "fields": [ + "commit_sha" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "pull_request_labels", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "label_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "label_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "pull_request_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "pull_request_id" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_request_labels_pull_requests_1", + "fields": [ + "pull_request_id" + ], + "referenceSchema": "Default", + "referenceTable": "pull_requests", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "pull_request_comments", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "pull_request_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "pull_request_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "body", + "type": "longtext", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "body" + }, + { + "objectType": "TableField_MYSQL", + "name": "account_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "account_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "position", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "deprecated", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "position" + }, + { + "objectType": "TableField_MYSQL", + "name": "type", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "type" + }, + { + "objectType": "TableField_MYSQL", + "name": "review_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "review_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_requests_history_pull_requests_1_copy_1", + "fields": [ + "pull_request_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "pull_requests", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_requests_history_users_1_copy_1", + "fields": [ + "actor_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cicd_scopes", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "description", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "description" + }, + { + "objectType": "TableField_MYSQL", + "name": "url", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "url" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "updated_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "updated_date" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "pull_request_commits", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "pull_request_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "pull_request_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_author_name", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_author_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_author_email", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_author_email" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_authored_date", + "type": "datetime", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_authored_date" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_request_commits_pull_requests_1", + "fields": [ + "pull_request_key" + ], + "referenceSchema": "Default", + "referenceTable": "pull_requests", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_request_commits_commits_1", + "fields": [ + "commit_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "table_2", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [], + "indexes": [], + "foreignKeys": [], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_repo_commits", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "repo_url", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_url" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "host", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "host" + }, + { + "objectType": "TableField_MYSQL", + "name": "namespace", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "namespace" + }, + { + "objectType": "TableField_MYSQL", + "name": "repo_name", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_name" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "issue_id", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "repo_url", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "commit_sha", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "_copy_3", + "fields": [ + "commit_sha" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_assignees", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "assignee_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "assignee_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "assignee_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "assignee_name" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_labels_issues_1_copy_1", + "fields": [ + "issue_id" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "pull_requests", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "title", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "title" + }, + { + "objectType": "TableField_MYSQL", + "name": "description", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "description" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "merged, etc", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_status", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_status" + }, + { + "objectType": "TableField_MYSQL", + "name": "parent_pr_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "parent_pr_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "pull_request_key", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "pull_request_key" + }, + { + "objectType": "TableField_MYSQL", + "name": "base_repo_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "base_repo_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "head_repo_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "head_repo_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "author_name", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "author_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "author_id", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "author_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "url", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "url" + }, + { + "objectType": "TableField_MYSQL", + "name": "type", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "feature or bugfix, parsed from labels", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "type" + }, + { + "objectType": "TableField_MYSQL", + "name": "component", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "parsed from labels", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "component" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "merged_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "merged_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "closed_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "closed_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "merge_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "merge_commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "base_ref", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "base_ref" + }, + { + "objectType": "TableField_MYSQL", + "name": "head_ref", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "head_ref" + }, + { + "objectType": "TableField_MYSQL", + "name": "base_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "base_commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "head_commit_sha", + "type": "char", + "length": 40, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "head_commit_sha" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "FK1_copy_2", + "fields": [ + "repo_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "repos", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_prs_repo_users_1", + "fields": [ + "author_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pull_requests_commits_1", + "fields": [ + "merge_commit_sha" + ], + "referenceSchema": "Default", + "referenceTable": "commits", + "referenceFields": [ + "sha" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_relationships", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "source_issue_id", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "source_issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "target_issue_id", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "target_issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_type", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_type" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_labels_issues_1_copy_1_copy_1", + "fields": [ + "issue_id" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issue_custom_array_fields", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "field_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "field_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "field_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "field_name" + } + ], + "indexes": [], + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_labels_issues_1_copy_1_copy_2", + "fields": [ + "issue_id" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "issues", + "comment": "", + "engine": "", + "characterSet": "", + "collation": "", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "", + "encryption": false, + "createOptions": "", + "createTime": "", + "checkTime": "", + "dataFree": 0, + "dataLength": 0, + "indexLength": 0, + "maxDataLength": 0, + "rows": 0, + "updateTime": "", + "DDL": "", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "issue_key", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "issue_key" + }, + { + "objectType": "TableField_MYSQL", + "name": "url", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "url" + }, + { + "objectType": "TableField_MYSQL", + "name": "title", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "title" + }, + { + "objectType": "TableField_MYSQL", + "name": "description", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "description" + }, + { + "objectType": "TableField_MYSQL", + "name": "type", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "type" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_type", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_type" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_status", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_status" + }, + { + "objectType": "TableField_MYSQL", + "name": "story_point", + "type": "double", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "story_point" + }, + { + "objectType": "TableField_MYSQL", + "name": "priority", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "priority" + }, + { + "objectType": "TableField_MYSQL", + "name": "severity", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "severity" + }, + { + "objectType": "TableField_MYSQL", + "name": "urgency", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "urgency" + }, + { + "objectType": "TableField_MYSQL", + "name": "component", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "component" + }, + { + "objectType": "TableField_MYSQL", + "name": "parent_issue_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "parent_issue_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "epic_key", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "epic_key" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_estimate_minutes", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_estimate_minutes" + }, + { + "objectType": "TableField_MYSQL", + "name": "time_spent_minutes", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "time_spent_minutes" + }, + { + "objectType": "TableField_MYSQL", + "name": "time_remaining_minutes", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "time_remaining_minutes" + }, + { + "objectType": "TableField_MYSQL", + "name": "creator_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "creator_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "creator_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "creator_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "assignee_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "current_assignee", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "assignee_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "assignee_name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "assignee_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "updated_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "updated_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "resolution_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "resolution_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "lead_time_minutes", + "type": "int", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "lead_time_minutes" + }, + { + "objectType": "TableField_MYSQL", + "name": "original_project", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_0900_ai_ci", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "original_project" + }, + { + "objectType": "TableField_MYSQL", + "name": "icon_url", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "icon_url" + }, + { + "objectType": "TableField_MYSQL", + "name": "x_custom_field_1", + "type": "", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "x_custom_field_1" + } + ], + "indexes": [], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "" + }, + { + "objectType": "IndexField_MYSQL", + "name": "", + "keyLength": 0, + "order": "", + "oldName": "" + } + ], + "oldName": "", + "indexMethod": "", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "FK1_copy_4", + "fields": [ + "project_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "issue_projects", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issues_issue_user_1", + "fields": [ + "creator_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "issue_users", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issues_issue_user_2", + "fields": [ + "assignee_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "issue_users", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issues_users_1", + "fields": [ + "creator_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issues_users_2", + "fields": [ + "assignee_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issues_users_3", + "fields": [ + "developer_assignee_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "accounts", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_issues_issues_1", + "fields": [ + "parent_origin_key" + ], + "referenceSchema": "Default", + "referenceTable": "issues", + "referenceFields": [ + "origin_key" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + } + ], + "views": [] + }, + { + "objectType": "Schema_MYSQL", + "name": "lake", + "tables": [ + { + "objectType": "Table_MYSQL", + "name": "cicd_pipeline_relationships", + "comment": "", + "engine": "InnoDB", + "characterSet": "utf8mb4", + "collation": "utf8mb4_bin", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "Dynamic", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "cicd_pipeline_relationships", + "encryption": false, + "createOptions": "", + "createTime": "2022-09-19 11:30:48", + "checkTime": "", + "dataFree": 0, + "dataLength": 16384, + "indexLength": 16384, + "maxDataLength": 0, + "rows": 47, + "updateTime": "2022-09-23 02:22:56", + "DDL": "CREATE TABLE `cicd_pipeline_relationships` (\n `parent_pipeline_id` varchar(255) COLLATE utf8mb4_bin NOT NULL,\n `child_pipeline_id` varchar(255) COLLATE utf8mb4_bin NOT NULL,\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `_raw_data_params` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_table` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_id` bigint unsigned DEFAULT NULL,\n `_raw_data_remark` longtext COLLATE utf8mb4_bin,\n PRIMARY KEY (`parent_pipeline_id`,`child_pipeline_id`),\n KEY `idx_cicd_pipeline_relationships_raw_data_params` (`_raw_data_params`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "parent_pipeline_id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "parent_pipeline_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "child_pipeline_id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "child_pipeline_id" + } + ], + "indexes": [ + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_pipeline_relationships_raw_data_params", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_pipeline_relationships_raw_data_params", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "1", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "_raw_data_params", + "keyLength": 0, + "order": "ASC", + "oldName": "_raw_data_params" + } + ] + } + ], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "parent_pipeline_id", + "keyLength": 0, + "order": "", + "oldName": "parent_pipeline_id" + }, + { + "objectType": "IndexField_MYSQL", + "name": "child_pipeline_id", + "keyLength": 0, + "order": "", + "oldName": "child_pipeline_id" + } + ], + "oldName": "", + "indexMethod": "BTREE", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_parent_pipeline", + "fields": [ + "parent_pipeline_id" + ], + "referenceSchema": "lake", + "referenceTable": "cicd_pipelines", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_child_pipeline", + "fields": [ + "child_pipeline_id" + ], + "referenceSchema": "lake", + "referenceTable": "cicd_pipelines", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cicd_tasks", + "comment": "", + "engine": "InnoDB", + "characterSet": "utf8mb4", + "collation": "utf8mb4_bin", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "Dynamic", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "cicd_tasks", + "encryption": false, + "createOptions": "", + "createTime": "2022-09-19 11:30:49", + "checkTime": "", + "dataFree": 5242880, + "dataLength": 5259264, + "indexLength": 4227072, + "maxDataLength": 0, + "rows": 10967, + "updateTime": "2022-09-25 13:34:30", + "DDL": "CREATE TABLE `cicd_tasks` (\n `id` varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT 'This key is generated based on details from the original plugin',\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `_raw_data_params` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_table` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_id` bigint unsigned DEFAULT NULL,\n `_raw_data_remark` longtext COLLATE utf8mb4_bin,\n `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `pipeline_id` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `result` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,\n `status` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,\n `type` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL COMMENT ' to indicate this is CI or CD',\n `duration_sec` bigint unsigned DEFAULT NULL,\n `started_date` datetime(3) DEFAULT NULL,\n `finished_date` datetime(3) DEFAULT NULL,\n `environment` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n PRIMARY KEY (`id`),\n KEY `idx_cicd_tasks_raw_data_params` (`_raw_data_params`),\n KEY `idx_cicd_tasks_pipeline_id` (`pipeline_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "This key is generated based on details from the original plugin", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "pipeline_id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "pipeline_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "result", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "result" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + }, + { + "objectType": "TableField_MYSQL", + "name": "type", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": " to indicate this is CI or CD", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "type" + }, + { + "objectType": "TableField_MYSQL", + "name": "duration_sec", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": true, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "duration_sec" + }, + { + "objectType": "TableField_MYSQL", + "name": "started_date", + "type": "datetime", + "length": 3, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "started_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "finished_date", + "type": "datetime", + "length": 3, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "finished_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "environment", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "environment" + }, + { + "objectType": "TableField_MYSQL", + "name": "cicd_scope_id", + "type": "longtext", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "cicd_scope_id" + } + ], + "indexes": [ + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_tasks_raw_data_params", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_tasks_raw_data_params", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "1", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "_raw_data_params", + "keyLength": 0, + "order": "ASC", + "oldName": "_raw_data_params" + } + ] + }, + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_tasks_pipeline_id", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_tasks_pipeline_id", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "7170", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "pipeline_id", + "keyLength": 0, + "order": "ASC", + "oldName": "pipeline_id" + } + ] + } + ], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "id" + } + ], + "oldName": "", + "indexMethod": "BTREE", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pipeline_id_1", + "fields": [ + "pipeline_id" + ], + "referenceSchema": "lake", + "referenceTable": "cicd_pipelines", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_cicd_tasks_cicd_scopes_1", + "fields": [ + "cicd_scope_id" + ], + "referenceSchema": "Default", + "referenceTable": "cicd_scopes", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cicd_deployments", + "comment": "", + "engine": "InnoDB", + "characterSet": "utf8mb4", + "collation": "utf8mb4_bin", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "Dynamic", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "cicd_pipeline_commits", + "encryption": false, + "createOptions": "", + "createTime": "2022-09-19 11:30:50", + "checkTime": "", + "dataFree": 4194304, + "dataLength": 3162112, + "indexLength": 2129920, + "maxDataLength": 0, + "rows": 8031, + "updateTime": "2022-09-25 13:33:39", + "DDL": "CREATE TABLE `cicd_pipeline_commits` (\n `pipeline_id` varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT 'This key is generated based on details from the original plugin',\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `_raw_data_params` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_table` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_id` bigint unsigned DEFAULT NULL,\n `_raw_data_remark` longtext COLLATE utf8mb4_bin,\n `commit_sha` varchar(255) COLLATE utf8mb4_bin NOT NULL,\n `branch` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `repo` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `repo_id` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `repo_url` longtext COLLATE utf8mb4_bin,\n PRIMARY KEY (`pipeline_id`,`commit_sha`),\n KEY `idx_cicd_pipeline_commits_raw_data_params` (`_raw_data_params`),\n KEY `idx_cicd_pipeline_commits_repo_id` (`repo_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "This key is generated based on details from the original plugin", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "cicd_scope_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "cicd_scope_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "result", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "result" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + }, + { + "objectType": "TableField_MYSQL", + "name": "environment", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "environment" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "started_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "started_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "finished_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "finished_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "duration_sec", + "type": "bigint", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "duration_sec" + } + ], + "indexes": [ + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_pipeline_commits_raw_data_params", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_pipeline_commits_raw_data_params", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "1", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "_raw_data_params", + "keyLength": 0, + "order": "ASC", + "oldName": "_raw_data_params" + } + ] + }, + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_pipeline_commits_repo_id", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_pipeline_commits_repo_id", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "1", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "repo_id", + "keyLength": 0, + "order": "ASC", + "oldName": "repo_id" + } + ] + } + ], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "pipeline_id" + } + ], + "oldName": "", + "indexMethod": "BTREE", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_cicd_deployment_commits_cicd_scopes_1_copy_1", + "fields": [ + "cicd_scope_id" + ], + "referenceSchema": "Default", + "referenceTable": "cicd_scopes", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cicd_pipelines", + "comment": "", + "engine": "InnoDB", + "characterSet": "utf8mb4", + "collation": "utf8mb4_bin", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "Dynamic", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "cicd_pipelines", + "encryption": false, + "createOptions": "", + "createTime": "2022-09-19 11:30:48", + "checkTime": "", + "dataFree": 4194304, + "dataLength": 1589248, + "indexLength": 1589248, + "maxDataLength": 0, + "rows": 8074, + "updateTime": "2022-09-25 13:33:39", + "DDL": "CREATE TABLE `cicd_pipelines` (\n `id` varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT 'This key is generated based on details from the original plugin',\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `_raw_data_params` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_table` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_id` bigint unsigned DEFAULT NULL,\n `_raw_data_remark` longtext COLLATE utf8mb4_bin,\n `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `result` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,\n `status` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,\n `type` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL COMMENT ' to indicate this is CI or CD',\n `duration_sec` bigint unsigned DEFAULT NULL,\n `created_date` datetime(3) DEFAULT NULL,\n `finished_date` datetime(3) DEFAULT NULL,\n `environment` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n PRIMARY KEY (`id`),\n KEY `idx_cicd_pipelines_raw_data_params` (`_raw_data_params`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "This key is generated based on details from the original plugin", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "result", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "result" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + }, + { + "objectType": "TableField_MYSQL", + "name": "type", + "type": "varchar", + "length": 100, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": " to indicate this is CI or CD", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "type" + }, + { + "objectType": "TableField_MYSQL", + "name": "duration_sec", + "type": "bigint", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": true, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "duration_sec" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "finished_date", + "type": "datetime", + "length": 3, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "finished_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "environment", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "environment" + }, + { + "objectType": "TableField_MYSQL", + "name": "cicd_scope_id", + "type": "longtext", + "length": -2147483648, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "cicd_scope_id" + } + ], + "indexes": [ + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_pipelines_raw_data_params", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_pipelines_raw_data_params", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "1", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "_raw_data_params", + "keyLength": 0, + "order": "ASC", + "oldName": "_raw_data_params" + } + ] + } + ], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "id" + } + ], + "oldName": "", + "indexMethod": "BTREE", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_cicd_pipelines_cicd_scopes_1", + "fields": [ + "cicd_scope_id" + ], + "referenceSchema": "Default", + "referenceTable": "cicd_scopes", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cicd_pipeline_commits", + "comment": "", + "engine": "InnoDB", + "characterSet": "utf8mb4", + "collation": "utf8mb4_bin", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "Dynamic", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "cicd_pipeline_commits", + "encryption": false, + "createOptions": "", + "createTime": "2022-09-19 11:30:50", + "checkTime": "", + "dataFree": 4194304, + "dataLength": 3162112, + "indexLength": 2129920, + "maxDataLength": 0, + "rows": 8031, + "updateTime": "2022-09-25 13:33:39", + "DDL": "CREATE TABLE `cicd_pipeline_commits` (\n `pipeline_id` varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT 'This key is generated based on details from the original plugin',\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `_raw_data_params` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_table` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_id` bigint unsigned DEFAULT NULL,\n `_raw_data_remark` longtext COLLATE utf8mb4_bin,\n `commit_sha` varchar(255) COLLATE utf8mb4_bin NOT NULL,\n `branch` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `repo` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `repo_id` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `repo_url` longtext COLLATE utf8mb4_bin,\n PRIMARY KEY (`pipeline_id`,`commit_sha`),\n KEY `idx_cicd_pipeline_commits_raw_data_params` (`_raw_data_params`),\n KEY `idx_cicd_pipeline_commits_repo_id` (`repo_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "pipeline_id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "This key is generated based on details from the original plugin", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "pipeline_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "branch", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "branch" + }, + { + "objectType": "TableField_MYSQL", + "name": "repo", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo" + }, + { + "objectType": "TableField_MYSQL", + "name": "repo_id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_id" + } + ], + "indexes": [ + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_pipeline_commits_raw_data_params", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_pipeline_commits_raw_data_params", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "1", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "_raw_data_params", + "keyLength": 0, + "order": "ASC", + "oldName": "_raw_data_params" + } + ] + }, + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_pipeline_commits_repo_id", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_pipeline_commits_repo_id", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "1", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "repo_id", + "keyLength": 0, + "order": "ASC", + "oldName": "repo_id" + } + ] + } + ], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "pipeline_id", + "keyLength": 0, + "order": "", + "oldName": "pipeline_id" + }, + { + "objectType": "IndexField_MYSQL", + "name": "commit_sha", + "keyLength": 0, + "order": "", + "oldName": "commit_sha" + } + ], + "oldName": "", + "indexMethod": "BTREE", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_pipeline_id", + "fields": [ + "pipeline_id" + ], + "referenceSchema": "lake", + "referenceTable": "cicd_pipelines", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + }, + { + "objectType": "Table_MYSQL", + "name": "cicd_deployment_commits", + "comment": "", + "engine": "InnoDB", + "characterSet": "utf8mb4", + "collation": "utf8mb4_bin", + "autoIncrement": 0, + "tablespace": "", + "storage": "", + "insertMethod": "", + "connection": "", + "checksum": false, + "rowFormat": "Dynamic", + "avgRowLength": 0, + "maxRows": 0, + "minRows": 0, + "keyBlockSize": 0, + "packKeys": "", + "delayKeyWrite": false, + "dataDirectory": "", + "indexDirectory": "", + "statsAutoRecalc": "", + "statsPersistent": "", + "statsSamplePages": 0, + "union": "", + "pageCheckSum": false, + "transactional": false, + "compression": "", + "oldName": "cicd_pipeline_commits", + "encryption": false, + "createOptions": "", + "createTime": "2022-09-19 11:30:50", + "checkTime": "", + "dataFree": 4194304, + "dataLength": 3162112, + "indexLength": 2129920, + "maxDataLength": 0, + "rows": 8031, + "updateTime": "2022-09-25 13:33:39", + "DDL": "CREATE TABLE `cicd_pipeline_commits` (\n `pipeline_id` varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT 'This key is generated based on details from the original plugin',\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `_raw_data_params` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_table` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `_raw_data_id` bigint unsigned DEFAULT NULL,\n `_raw_data_remark` longtext COLLATE utf8mb4_bin,\n `commit_sha` varchar(255) COLLATE utf8mb4_bin NOT NULL,\n `branch` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `repo` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `repo_id` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,\n `repo_url` longtext COLLATE utf8mb4_bin,\n PRIMARY KEY (`pipeline_id`,`commit_sha`),\n KEY `idx_cicd_pipeline_commits_raw_data_params` (`_raw_data_params`),\n KEY `idx_cicd_pipeline_commits_repo_id` (`repo_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + "partitionBy": "", + "partitionByExpr": "", + "partitions": 0, + "partitionKeyAlgorithm": "", + "subPartitionBy": "", + "subPartitionByExpr": "", + "subPartitions": 0, + "subPartitionKeyAlgorithm": "", + "fields": [ + { + "objectType": "TableField_MYSQL", + "name": "id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "This key is generated based on details from the original plugin", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "id" + }, + { + "objectType": "TableField_MYSQL", + "name": "cicd_scope_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "cicd_scope_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "cicd_deployment_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "cicd_deployment_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "name", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "name" + }, + { + "objectType": "TableField_MYSQL", + "name": "result", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "result" + }, + { + "objectType": "TableField_MYSQL", + "name": "status", + "type": "varchar", + "length": 100, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "status" + }, + { + "objectType": "TableField_MYSQL", + "name": "environment", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "environment" + }, + { + "objectType": "TableField_MYSQL", + "name": "created_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "created_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "started_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "started_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "finished_date", + "type": "datetime", + "length": 3, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "finished_date" + }, + { + "objectType": "TableField_MYSQL", + "name": "duration_sec", + "type": "bigint", + "length": -2147483648, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "duration_sec" + }, + { + "objectType": "TableField_MYSQL", + "name": "commit_sha", + "type": "char", + "length": 40, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": false, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "commit_sha" + }, + { + "objectType": "TableField_MYSQL", + "name": "ref_name", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "ref_name" + }, + { + "objectType": "TableField_MYSQL", + "name": "repo_id", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_id" + }, + { + "objectType": "TableField_MYSQL", + "name": "repo_url", + "type": "varchar", + "length": 255, + "decimals": -2147483648, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "utf8mb4", + "collation": "utf8mb4_bin", + "isNullable": true, + "defaultType": "Null", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "repo_url" + }, + { + "objectType": "TableField_MYSQL", + "name": "prev_success_deployment_commit_id", + "type": "varchar", + "length": 255, + "decimals": 0, + "isUnsigned": false, + "isZeroFill": false, + "setEnumValues": "", + "isBinary": false, + "charset": "", + "collation": "", + "isNullable": true, + "defaultType": "Others", + "defaultValue": "", + "isOnUpdateCurrentTimestamp": false, + "isAutoInc": false, + "comment": "", + "columnFormat": "", + "storage": "", + "isVirtual": false, + "isGeneratedAlways": false, + "virtualExpr": "", + "virtualType": "", + "oldName": "prev_success_deployment_commit_id" + } + ], + "indexes": [ + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_pipeline_commits_raw_data_params", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_pipeline_commits_raw_data_params", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "1", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "_raw_data_params", + "keyLength": 0, + "order": "ASC", + "oldName": "_raw_data_params" + } + ] + }, + { + "objectType": "Index_MYSQL", + "name": "idx_cicd_pipeline_commits_repo_id", + "type": "NORMAL", + "method": "BTREE", + "comment": "", + "oldName": "idx_cicd_pipeline_commits_repo_id", + "online": false, + "keyBlockSize": 0, + "parser": "", + "algorithm": "", + "lock": "", + "collation": "A", + "cardinality": "1", + "packed": "", + "IsVisibleIndex": false, + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "repo_id", + "keyLength": 0, + "order": "ASC", + "oldName": "repo_id" + } + ] + } + ], + "primaryKey": { + "objectType": "PrimaryKey_MYSQL", + "name": "", + "fields": [ + { + "objectType": "IndexField_MYSQL", + "name": "id", + "keyLength": 0, + "order": "", + "oldName": "pipeline_id" + } + ], + "oldName": "", + "indexMethod": "BTREE", + "comment": "" + }, + "foreignKeys": [ + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_cicd_deployment_commits_cicd_scopes_1", + "fields": [ + "cicd_scope_id" + ], + "referenceSchema": "Default", + "referenceTable": "cicd_scopes", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + }, + { + "objectType": "ForeignKey_MYSQL", + "name": "fk_cicd_deployment_commits_cicd_deployments_1", + "fields": [ + "cicd_deployment_id" + ], + "referenceSchema": "lake", + "referenceTable": "cicd_deployments", + "referenceFields": [ + "id" + ], + "onDelete": "", + "onUpdate": "", + "sourceCardinality": "NoneRelationship", + "targetCardinality": "NoneRelationship", + "oldName": "" + } + ], + "checks": [], + "triggers": [], + "tablePartitions": [] + } + ], + "views": [] + } + ] + }, + "diagrams": [ + { + "name": "Diagram 1", + "paperWidth": 3, + "paperHeight": 1, + "tableFont": "Arial Unicode MS", + "tableFontSize": 14, + "isBalckWhite": false, + "showDBSchemaName": false, + "showViewRelations": true, + "notation": "default", + "showFieldComment": true, + "showTableComment": false, + "shapes": [ + { + "type": "table", + "schemaName": "Default", + "tableName": "issues", + "x": 106, + "y": 714, + "width": 200, + "height": 654, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "board_issues", + "x": 349, + "y": 313, + "width": 200, + "height": 89, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "repos", + "x": 1250, + "y": 463, + "width": 200, + "height": 259, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "boards", + "x": 599, + "y": 311, + "width": 200, + "height": 172, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "commits", + "x": 1250, + "y": 864, + "width": 200, + "height": 316, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "pull_requests", + "x": 1600, + "y": 280, + "width": 200, + "height": 512, + "isBold": false, + "titleColor": { + "r": 54, + "g": 182, + "b": 254, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "sprints", + "x": 600, + "y": 622, + "width": 200, + "height": 215, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "accounts", + "x": 673, + "y": 1256, + "width": 204, + "height": 218, + "isBold": false, + "titleColor": { + "r": 92, + "g": 240, + "b": 158, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "sprint_issues", + "x": 351, + "y": 629, + "width": 200, + "height": 91, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "issue_worklogs", + "x": 350, + "y": 778, + "width": 200, + "height": 191, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "label", + "name": "Label 1", + "x": 54, + "y": 10, + "width": 307, + "height": 77, + "text": "Domain Layer", + "fontName": "Arial Unicode MS", + "fontSize": 48, + "isFontBold": false, + "isFontItalic": false + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "repo_commits", + "x": 1250, + "y": 738, + "width": 200, + "height": 88, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "pull_request_commits", + "x": 1600, + "y": 835, + "width": 200, + "height": 151, + "isBold": false, + "titleColor": { + "r": 54, + "g": 182, + "b": 254, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "commit_parents", + "x": 1250, + "y": 1211, + "width": 200, + "height": 88, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "rectangle", + "name": "issue tracking", + "x": 592, + "y": 16, + "width": 274, + "height": 56, + "opacity": 1.0, + "isBold": false, + "color": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + }, + "borderColor": { + "r": 254, + "g": 254, + "b": 254, + "a": 1 + }, + "shapeStyle": "version1", + "label": { + "x": 600, + "y": 72, + "width": 94, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "type": "label", + "name": "Label 3", + "x": 658, + "y": 26, + "width": 160, + "height": 40, + "text": "Issue Tracking", + "fontName": "Arial Unicode MS", + "fontSize": 20, + "fontColor": { + "r": 254, + "g": 254, + "b": 254, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false + }, + { + "type": "rectangle", + "name": "source code management", + "x": 882, + "y": 16, + "width": 274, + "height": 56, + "opacity": 1.0, + "isBold": false, + "color": { + "r": 44, + "g": 110, + "b": 177, + "a": 1 + }, + "borderColor": { + "r": 254, + "g": 254, + "b": 254, + "a": 1 + }, + "shapeStyle": "version1", + "label": { + "x": 900, + "y": 72, + "width": 170, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "type": "label", + "name": "Label 3 Copy 1", + "x": 897, + "y": 26, + "width": 250, + "height": 40, + "text": "Source Code Management", + "fontName": "Arial Unicode MS", + "fontSize": 20, + "fontColor": { + "r": 254, + "g": 254, + "b": 254, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false + }, + { + "type": "rectangle", + "name": "CI/CD", + "x": 1495, + "y": 16, + "width": 274, + "height": 56, + "opacity": 1.0, + "isBold": false, + "color": { + "r": 247, + "g": 29, + "b": 51, + "a": 1 + }, + "borderColor": { + "r": 254, + "g": 254, + "b": 254, + "a": 1 + }, + "shapeStyle": "version1", + "label": { + "x": 1503, + "y": 73, + "width": 50, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "type": "label", + "name": "Label 3 Copy 1 Copy 1", + "x": 1600, + "y": 28, + "width": 59, + "height": 40, + "text": "CI/CD", + "fontName": "Arial Unicode MS", + "fontSize": 18, + "fontColor": { + "r": 254, + "g": 254, + "b": 254, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false + }, + { + "type": "rectangle", + "name": "Cross-domain", + "x": 2101, + "y": 16, + "width": 274, + "height": 56, + "opacity": 1.0, + "isBold": false, + "color": { + "r": 80, + "g": 242, + "b": 140, + "a": 1 + }, + "borderColor": { + "r": 254, + "g": 254, + "b": 254, + "a": 1 + }, + "shapeStyle": "version1", + "label": { + "x": 2109, + "y": 71, + "width": 96, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "type": "label", + "name": "Label 3 Copy 1 Copy 1 Copy 1", + "x": 2169, + "y": 24, + "width": 132, + "height": 39, + "text": "Cross-domain", + "fontName": "Arial Unicode MS", + "fontSize": 20, + "fontColor": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "pull_request_comments", + "x": 1850, + "y": 524, + "width": 200, + "height": 230, + "isBold": false, + "titleColor": { + "r": 54, + "g": 182, + "b": 254, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "refs", + "x": 977, + "y": 606, + "width": 200, + "height": 171, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "commit_files", + "x": 1600, + "y": 1125, + "width": 200, + "height": 150, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "issue_labels", + "x": 108, + "y": 312, + "width": 200, + "height": 89, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "board_sprints", + "x": 600, + "y": 503, + "width": 200, + "height": 89, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "pull_request_labels", + "x": 1850, + "y": 340, + "width": 200, + "height": 91, + "isBold": false, + "titleColor": { + "r": 54, + "g": 182, + "b": 254, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "commits_diffs", + "x": 979, + "y": 823, + "width": 200, + "height": 133, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "rectangle", + "name": "code review", + "x": 1191, + "y": 16, + "width": 274, + "height": 56, + "opacity": 1.0, + "isBold": false, + "color": { + "r": 47, + "g": 165, + "b": 254, + "a": 1 + }, + "borderColor": { + "r": 54, + "g": 182, + "b": 254, + "a": 1 + }, + "shapeStyle": "version1", + "label": { + "x": 1199, + "y": 71, + "width": 83, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "type": "label", + "name": "Label 3 Copy 1 Copy 2", + "x": 1262, + "y": 25, + "width": 129, + "height": 40, + "text": "Code Review", + "fontName": "Arial Unicode MS", + "fontSize": 20, + "fontColor": { + "r": 254, + "g": 254, + "b": 254, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false + }, + { + "type": "label", + "name": "Label 3 Copy 1 Copy 1 Copy 1 Copy 1", + "x": 59, + "y": 113, + "width": 389, + "height": 40, + "text": "Note: WIP tables are still under development", + "fontName": "Arial Unicode MS", + "fontSize": 18, + "fontColor": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "pull_request_issues", + "x": 1600, + "y": 108, + "width": 200, + "height": 133, + "isBold": false, + "titleColor": { + "r": 92, + "g": 240, + "b": 158, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "users", + "x": 1267, + "y": 1339, + "width": 200, + "height": 113, + "isBold": false, + "titleColor": { + "r": 92, + "g": 240, + "b": 158, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "user_accounts", + "x": 968, + "y": 1342, + "width": 200, + "height": 94, + "isBold": false, + "titleColor": { + "r": 92, + "g": 240, + "b": 158, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "teams", + "x": 968, + "y": 1525, + "width": 200, + "height": 151, + "isBold": false, + "titleColor": { + "r": 92, + "g": 240, + "b": 158, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "team_users", + "x": 1269, + "y": 1523, + "width": 200, + "height": 95, + "isBold": false, + "titleColor": { + "r": 92, + "g": 240, + "b": 158, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "commit_file_components", + "x": 1600, + "y": 1001, + "width": 200, + "height": 87, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "components", + "x": 1250, + "y": 304, + "width": 200, + "height": 112, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "lake", + "tableName": "cicd_pipeline_commits", + "x": 2849, + "y": 903, + "width": 240, + "height": 154, + "isBold": false, + "titleColor": { + "r": 251, + "g": 56, + "b": 65, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "lake", + "tableName": "cicd_pipelines", + "x": 2849, + "y": 1095, + "width": 240, + "height": 254, + "isBold": false, + "titleColor": { + "r": 251, + "g": 56, + "b": 65, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "lake", + "tableName": "cicd_tasks", + "x": 2848, + "y": 1384, + "width": 242, + "height": 282, + "isBold": false, + "titleColor": { + "r": 251, + "g": 56, + "b": 65, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "ref_commits", + "x": 978, + "y": 1026, + "width": 197, + "height": 138, + "isBold": false, + "titleColor": { + "r": 55, + "g": 131, + "b": 192, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "project", + "x": 1600, + "y": 1340, + "width": 200, + "height": 151, + "isBold": false, + "titleColor": { + "r": 92, + "g": 240, + "b": 158, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "project_metric_settings", + "x": 1920, + "y": 1340, + "width": 200, + "height": 151, + "isBold": false, + "titleColor": { + "r": 92, + "g": 240, + "b": 158, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "project_mapping", + "x": 1600, + "y": 1550, + "width": 200, + "height": 120, + "isBold": false, + "titleColor": { + "r": 92, + "g": 240, + "b": 158, + "a": 1 + } + }, + { + "type": "rectangle", + "name": "Cross-domain Copy 2", + "x": 1798, + "y": 16, + "width": 274, + "height": 56, + "opacity": 1.0, + "isBold": false, + "color": { + "r": 162, + "g": 108, + "b": 254, + "a": 1 + }, + "borderColor": { + "r": 254, + "g": 254, + "b": 254, + "a": 1 + }, + "shapeStyle": "version1", + "label": { + "x": 1806, + "y": 73, + "width": 146, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "type": "label", + "name": "Label 3 Copy 1 Copy 1 Copy 1 Copy 2", + "x": 1875, + "y": 25, + "width": 123, + "height": 39, + "text": "Code Quality", + "fontName": "Arial Unicode MS", + "fontSize": 20, + "fontColor": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "cq_projects", + "x": 2523, + "y": 163, + "width": 200, + "height": 200, + "isBold": false, + "titleColor": { + "r": 162, + "g": 108, + "b": 254, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "cq_issues", + "x": 2523, + "y": 387, + "width": 200, + "height": 514, + "isBold": false, + "titleColor": { + "r": 162, + "g": 108, + "b": 254, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "cq_issue_code_blocks", + "x": 2246, + "y": 392, + "width": 200, + "height": 231, + "isBold": false, + "titleColor": { + "r": 162, + "g": 108, + "b": 254, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "cq_file_metrics", + "x": 2764, + "y": 139, + "width": 200, + "height": 625, + "isBold": false, + "titleColor": { + "r": 162, + "g": 108, + "b": 254, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "issue_comments", + "x": 346, + "y": 424, + "width": 200, + "height": 150, + "isBold": false, + "titleColor": { + "r": 250, + "g": 166, + "b": 14, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "issue_changelogs", + "x": 103, + "y": 1390, + "width": 200, + "height": 278, + "isBold": false, + "titleColor": { + "r": 250, + "g": 166, + "b": 14, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "cicd_scopes", + "x": 2553, + "y": 1173, + "width": 240, + "height": 177, + "isBold": false, + "titleColor": { + "r": 247, + "g": 29, + "b": 51, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "lake", + "tableName": "cicd_deployment_commits", + "x": 2239, + "y": 1245, + "width": 240, + "height": 382, + "isBold": false, + "titleColor": { + "r": 251, + "g": 56, + "b": 65, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "issue_repo_commits", + "x": 679, + "y": 872, + "width": 200, + "height": 191, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "issue_assignees", + "x": 106, + "y": 574, + "width": 200, + "height": 111, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "issue_relationships", + "x": 106, + "y": 426, + "width": 200, + "height": 141, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "lake", + "tableName": "cicd_deployments", + "x": 2238, + "y": 955, + "width": 240, + "height": 257, + "isBold": false, + "titleColor": { + "r": 251, + "g": 56, + "b": 65, + "a": 1 + } + }, + { + "type": "table", + "schemaName": "Default", + "tableName": "issue_custom_array_fields", + "x": 351, + "y": 1001, + "width": 200, + "height": 111, + "isBold": false, + "titleColor": { + "r": 253, + "g": 181, + "b": 12, + "a": 1 + } + } + ], + "layers": [], + "relations": [ + { + "name": "FK1_copy_2", + "sourceTableName": "pull_requests", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1585, + "y": 453 + }, + { + "x": 1585, + "y": 500 + }, + { + "x": 1465, + "y": 500 + } + ], + "label": { + "x": 1545, + "y": 414, + "width": 50, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_board_issues_boards_1", + "sourceTableName": "board_issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 564, + "y": 360 + }, + { + "x": 584, + "y": 360 + } + ], + "label": { + "x": 560, + "y": 362, + "width": 173, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_board_issues_issues_1", + "sourceTableName": "board_issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 334, + "y": 380 + }, + { + "x": 321, + "y": 380 + }, + { + "x": 321, + "y": 755 + } + ], + "label": { + "x": 174, + "y": 341, + "width": 170, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_prs_repo_users_1", + "sourceTableName": "pull_requests", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1815, + "y": 514 + }, + { + "x": 2101, + "y": 514 + }, + { + "x": 2101, + "y": 1313 + }, + { + "x": 892, + "y": 1313 + } + ], + "label": { + "x": 1811, + "y": 516, + "width": 137, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_commits_repo_users_1", + "sourceTableName": "commits", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1235, + "y": 1020 + }, + { + "x": 1220, + "y": 1020 + }, + { + "x": 1220, + "y": 1300 + }, + { + "x": 892, + "y": 1300 + } + ], + "label": { + "x": 1251, + "y": 1022, + "width": 170, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_commits_repo_users_2", + "sourceTableName": "commits", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1235, + "y": 1100 + }, + { + "x": 1235, + "y": 1108 + }, + { + "x": 1235, + "y": 1304 + }, + { + "x": 892, + "y": 1304 + } + ], + "label": { + "x": 1251, + "y": 1102, + "width": 170, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_issues_users_1", + "sourceTableName": "issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 321, + "y": 1120 + }, + { + "x": 650, + "y": 1120 + }, + { + "x": 650, + "y": 1300 + }, + { + "x": 658, + "y": 1300 + } + ], + "label": { + "x": 311, + "y": 1081, + "width": 122, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_issues_users_2", + "sourceTableName": "issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 321, + "y": 1140 + }, + { + "x": 630, + "y": 1140 + }, + { + "x": 630, + "y": 1310 + }, + { + "x": 658, + "y": 1310 + } + ], + "label": { + "x": 311, + "y": 1101, + "width": 122, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_issue_board_repo_boards_1_copy_1", + "sourceTableName": "sprint_issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 566, + "y": 670 + }, + { + "x": 585, + "y": 670 + }, + { + "x": 585, + "y": 670 + } + ], + "label": { + "x": 556, + "y": 631, + "width": 253, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_issue_board_repo_repos_1_copy_1", + "sourceTableName": "sprint_issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 336, + "y": 697 + }, + { + "x": 336, + "y": 765 + }, + { + "x": 321, + "y": 765 + } + ], + "label": { + "x": 119, + "y": 658, + "width": 245, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_worklogs_issues_1", + "sourceTableName": "issue_worklogs", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 335, + "y": 951 + }, + { + "x": 335, + "y": 770 + }, + { + "x": 320, + "y": 770 + }, + { + "x": 321, + "y": 770 + } + ], + "label": { + "x": 202, + "y": 912, + "width": 143, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_issues_users_3", + "sourceTableName": "issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 321, + "y": 1160 + }, + { + "x": 320, + "y": 1310 + }, + { + "x": 658, + "y": 1310 + } + ], + "label": { + "x": 311, + "y": 1121, + "width": 122, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_repo_commits_repos_1", + "sourceTableName": "repo_commits", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1465, + "y": 790 + }, + { + "x": 1490, + "y": 790 + }, + { + "x": 1490, + "y": 510 + }, + { + "x": 1465, + "y": 510 + } + ], + "label": { + "x": 1461, + "y": 761, + "width": 170, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_repo_commits_commits_1", + "sourceTableName": "repo_commits", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1235, + "y": 806 + }, + { + "x": 1235, + "y": 906 + } + ], + "label": { + "x": 1251, + "y": 808, + "width": 187, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pull_request_commits_pull_requests_1", + "sourceTableName": "pull_request_commits", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1815, + "y": 884 + }, + { + "x": 1815, + "y": 430 + } + ], + "label": { + "x": 1811, + "y": 855, + "width": 265, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pull_request_commits_commits_1", + "sourceTableName": "pull_request_commits", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1585, + "y": 904 + }, + { + "x": 1575, + "y": 904 + }, + { + "x": 1465, + "y": 904 + } + ], + "label": { + "x": 1360, + "y": 865, + "width": 235, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_repos_repos_1", + "sourceTableName": "repos", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1465, + "y": 520 + }, + { + "x": 1465, + "y": 660 + } + ], + "label": { + "x": 1455, + "y": 481, + "width": 118, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_commit_parents_commits_1", + "sourceTableName": "commit_parents", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1465, + "y": 1277 + }, + { + "x": 1482, + "y": 1277 + }, + { + "x": 1482, + "y": 912 + }, + { + "x": 1465, + "y": 912 + } + ], + "label": { + "x": 1256, + "y": 1238, + "width": 199, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_commit_parents_commits_2", + "sourceTableName": "commit_parents", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1465, + "y": 1256 + }, + { + "x": 1465, + "y": 917 + } + ], + "label": { + "x": 1256, + "y": 1217, + "width": 199, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_repos_users_1", + "sourceTableName": "repos", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1235, + "y": 593 + }, + { + "x": 892, + "y": 593 + }, + { + "x": 892, + "y": 1290 + } + ], + "label": { + "x": 1128, + "y": 554, + "width": 117, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pull_requests_history_pull_requests_1_copy_1", + "sourceTableName": "pull_request_comments", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1835, + "y": 590 + }, + { + "x": 1835, + "y": 420 + }, + { + "x": 1815, + "y": 420 + } + ], + "label": { + "x": 1532, + "y": 551, + "width": 313, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pull_requests_history_users_1_copy_1", + "sourceTableName": "pull_request_comments", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 2065, + "y": 630 + }, + { + "x": 2080, + "y": 630 + }, + { + "x": 2080, + "y": 1310 + }, + { + "x": 892, + "y": 1310 + } + ], + "label": { + "x": 1791, + "y": 591, + "width": 264, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_issues_issues_1", + "sourceTableName": "issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 91, + "y": 770 + }, + { + "x": 91, + "y": 1060 + } + ], + "label": { + "x": 101, + "y": 731, + "width": 128, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_commit_files_commits_1", + "sourceTableName": "commit_files", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1585, + "y": 1189 + }, + { + "x": 1560, + "y": 1189 + }, + { + "x": 1560, + "y": 908 + }, + { + "x": 1465, + "y": 908 + } + ], + "label": { + "x": 1595, + "y": 1150, + "width": 177, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_refs_repos_1", + "sourceTableName": "refs", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1192, + "y": 692 + }, + { + "x": 1235, + "y": 692 + }, + { + "x": 1235, + "y": 514 + }, + { + "x": 1235, + "y": 510 + } + ], + "label": { + "x": 1182, + "y": 653, + "width": 107, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_refs_commits_1", + "sourceTableName": "refs", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1192, + "y": 717 + }, + { + "x": 1192, + "y": 911 + }, + { + "x": 1235, + "y": 911 + } + ], + "label": { + "x": 1182, + "y": 678, + "width": 124, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_labels_issues_1", + "sourceTableName": "issue_labels", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 93, + "y": 380 + }, + { + "x": 83, + "y": 380 + }, + { + "x": 83, + "y": 757 + }, + { + "x": 91, + "y": 757 + } + ], + "label": { + "x": 109, + "y": 351, + "width": 124, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_board_sprints_boards_1", + "sourceTableName": "board_sprints", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 585, + "y": 550 + }, + { + "x": 584, + "y": 364 + } + ], + "label": { + "x": 601, + "y": 521, + "width": 175, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_board_sprints_sprints_1", + "sourceTableName": "board_sprints", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 815, + "y": 570 + }, + { + "x": 815, + "y": 670 + } + ], + "label": { + "x": 811, + "y": 572, + "width": 173, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pull_request_labels_pull_requests_1", + "sourceTableName": "pull_request_labels", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1835, + "y": 410 + }, + { + "x": 1815, + "y": 330 + } + ], + "label": { + "x": 1851, + "y": 412, + "width": 250, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_ref_diffs_commits_1", + "sourceTableName": "commits_diffs", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1194, + "y": 916 + }, + { + "x": 1235, + "y": 916 + } + ], + "label": { + "x": 1184, + "y": 877, + "width": 149, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_refs_diffs_commits_refs_1", + "sourceTableName": "commits_diffs", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 964, + "y": 864 + }, + { + "x": 962, + "y": 720 + } + ], + "label": { + "x": 980, + "y": 835, + "width": 187, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pull_request_issues_pull_requests_1", + "sourceTableName": "pull_request_issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1815, + "y": 157 + }, + { + "x": 1815, + "y": 324 + } + ], + "label": { + "x": 1811, + "y": 159, + "width": 253, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pull_request_issues_issues_1", + "sourceTableName": "pull_request_issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1585, + "y": 177 + }, + { + "x": 70, + "y": 180 + }, + { + "x": 70, + "y": 763 + }, + { + "x": 91, + "y": 763 + } + ], + "label": { + "x": 1385, + "y": 138, + "width": 210, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_worklogs_accounts_1", + "sourceTableName": "issue_worklogs", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 565, + "y": 846 + }, + { + "x": 658, + "y": 930 + }, + { + "x": 658, + "y": 1295 + } + ], + "label": { + "x": 555, + "y": 807, + "width": 159, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pull_requests_commits_1", + "sourceTableName": "pull_requests", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1585, + "y": 664 + }, + { + "x": 1560, + "y": 664 + }, + { + "x": 1560, + "y": 900 + }, + { + "x": 1465, + "y": 900 + } + ], + "label": { + "x": 1412, + "y": 625, + "width": 183, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_user_accounts_users_1", + "sourceTableName": "user_accounts", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1183, + "y": 1390 + }, + { + "x": 1252, + "y": 1390 + } + ], + "label": { + "x": 1173, + "y": 1351, + "width": 173, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_team_users_teams_1", + "sourceTableName": "team_users", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1254, + "y": 1570 + }, + { + "x": 1183, + "y": 1570 + } + ], + "label": { + "x": 1105, + "y": 1531, + "width": 159, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_team_users_users_1", + "sourceTableName": "team_users", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1484, + "y": 1590 + }, + { + "x": 1482, + "y": 1380 + } + ], + "label": { + "x": 1480, + "y": 1561, + "width": 155, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_teams_teams_1", + "sourceTableName": "teams", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1183, + "y": 1580 + }, + { + "x": 1183, + "y": 1630 + } + ], + "label": { + "x": 1173, + "y": 1541, + "width": 124, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_user_accounts_accounts_1", + "sourceTableName": "user_accounts", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 953, + "y": 1408 + }, + { + "x": 892, + "y": 1320 + } + ], + "label": { + "x": 769, + "y": 1369, + "width": 194, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_commit_file_components_commit_files_1", + "sourceTableName": "commit_file_components", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1585, + "y": 1047 + }, + { + "x": 1585, + "y": 1171 + } + ], + "label": { + "x": 1317, + "y": 1008, + "width": 278, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pipeline_id", + "sourceTableName": "cicd_pipeline_commits", + "sourceSchemaName": "lake", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 3104, + "y": 949 + }, + { + "x": 3104, + "y": 1137 + } + ], + "label": { + "x": 3001, + "y": 910, + "width": 93, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_pipeline_id_1", + "sourceTableName": "cicd_tasks", + "sourceSchemaName": "lake", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 3105, + "y": 1471 + }, + { + "x": 3104, + "y": 1144 + } + ], + "label": { + "x": 3101, + "y": 1442, + "width": 108, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_project_metric_settings_project_1", + "sourceTableName": "project_metric_settings", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1905, + "y": 1420 + }, + { + "x": 1910, + "y": 1420 + }, + { + "x": 1910, + "y": 1420 + }, + { + "x": 1815, + "y": 1420 + } + ], + "label": { + "x": 1669, + "y": 1382, + "width": 246, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_project_mapping_project_1", + "sourceTableName": "project_mapping", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1700, + "y": 1535 + }, + { + "x": 1700, + "y": 1560 + }, + { + "x": 1700, + "y": 1560 + }, + { + "x": 1700, + "y": 1506 + } + ], + "label": { + "x": 1708, + "y": 1515, + "width": 207, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "", + "sourceTableName": "cq_file_metrics", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 2749, + "y": 207 + }, + { + "x": 2738, + "y": 207 + } + ], + "label": { + "x": 2709, + "y": 168, + "width": 50, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "_copy_2", + "sourceTableName": "cq_issues", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 2738, + "y": 519 + }, + { + "x": 2738, + "y": 214 + } + ], + "label": { + "x": 2678, + "y": 480, + "width": 50, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "_copy_1", + "sourceTableName": "cq_issue_code_blocks", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 2461, + "y": 464 + }, + { + "x": 2508, + "y": 437 + } + ], + "label": { + "x": 2451, + "y": 425, + "width": 50, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_issue_comments_issues_1", + "sourceTableName": "issue_comments", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 331, + "y": 499 + }, + { + "x": 331, + "y": 760 + }, + { + "x": 321, + "y": 760 + } + ], + "label": { + "x": 149, + "y": 460, + "width": 192, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_issue_changelogs_issues_1", + "sourceTableName": "issue_changelogs", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 88, + "y": 1456 + }, + { + "x": 77, + "y": 1456 + }, + { + "x": 77, + "y": 766 + }, + { + "x": 91, + "y": 766 + } + ], + "label": { + "x": 104, + "y": 1427, + "width": 199, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_cicd_pipelines_cicd_scopes_1", + "sourceTableName": "cicd_pipelines", + "sourceSchemaName": "lake", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 2834, + "y": 1333 + }, + { + "x": 2833, + "y": 1218 + }, + { + "x": 2808, + "y": 1218 + } + ], + "label": { + "x": 2632, + "y": 1294, + "width": 212, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_cicd_tasks_cicd_scopes_1", + "sourceTableName": "cicd_tasks", + "sourceSchemaName": "lake", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 2833, + "y": 1639 + }, + { + "x": 2808, + "y": 1639 + }, + { + "x": 2808, + "y": 1225 + } + ], + "label": { + "x": 2654, + "y": 1600, + "width": 189, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_components_repos_1", + "sourceTableName": "components", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 1235, + "y": 349 + }, + { + "x": 1235, + "y": 504 + } + ], + "label": { + "x": 1251, + "y": 351, + "width": 159, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_cicd_deployment_commits_cicd_scopes_1", + "sourceTableName": "cicd_deployment_commits", + "sourceSchemaName": "lake", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 2494, + "y": 1311 + }, + { + "x": 2494, + "y": 1219 + }, + { + "x": 2538, + "y": 1219 + } + ], + "label": { + "x": 2490, + "y": 1282, + "width": 288, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "_copy_3", + "sourceTableName": "issue_repo_commits", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 894, + "y": 977 + }, + { + "x": 1210, + "y": 977 + }, + { + "x": 1235, + "y": 926 + } + ], + "label": { + "x": 884, + "y": 938, + "width": 50, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_labels_issues_1_copy_1", + "sourceTableName": "issue_assignees", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 91, + "y": 621 + }, + { + "x": 91, + "y": 754 + } + ], + "label": { + "x": 107, + "y": 623, + "width": 176, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_labels_issues_1_copy_1_copy_1", + "sourceTableName": "issue_relationships", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 91, + "y": 473 + }, + { + "x": 91, + "y": 757 + } + ], + "label": { + "x": 107, + "y": 475, + "width": 229, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_cicd_deployment_commits_cicd_scopes_1_copy_1", + "sourceTableName": "cicd_deployments", + "sourceSchemaName": "lake", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 2493, + "y": 1023 + }, + { + "x": 2493, + "y": 1213 + }, + { + "x": 2538, + "y": 1213 + } + ], + "label": { + "x": 2144, + "y": 984, + "width": 339, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_cicd_deployment_commits_cicd_deployments_1", + "sourceTableName": "cicd_deployment_commits", + "sourceSchemaName": "lake", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 2224, + "y": 1331 + }, + { + "x": 2223, + "y": 1001 + } + ], + "label": { + "x": 2240, + "y": 1302, + "width": 323, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + }, + { + "name": "fk_labels_issues_1_copy_1_copy_2", + "sourceTableName": "issue_custom_array_fields", + "sourceSchemaName": "Default", + "lineWidth": 1, + "visible": true, + "vertices": [ + { + "x": 336, + "y": 1047 + }, + { + "x": 321, + "y": 1047 + }, + { + "x": 321, + "y": 775 + } + ], + "label": { + "x": 352, + "y": 1049, + "width": 227, + "height": 31, + "fontName": "Arial Unicode MS", + "fontSize": 14, + "fontColor": { + "r": 51, + "g": 51, + "b": 51, + "a": 1 + }, + "isFontBold": false, + "isFontItalic": false, + "isVisible": false + } + } + ], + "viewRelations": [] + } + ] +} \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-circleci-screenshot-1.png b/versioned_docs/version-v0.21/Configuration/images/dora-circleci-screenshot-1.png new file mode 100644 index 00000000000..6bb14214939 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-circleci-screenshot-1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-circleci-screenshot-2.png b/versioned_docs/version-v0.21/Configuration/images/dora-circleci-screenshot-2.png new file mode 100644 index 00000000000..c647b8eb0a3 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-circleci-screenshot-2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-config-label.png b/versioned_docs/version-v0.21/Configuration/images/dora-config-label.png new file mode 100644 index 00000000000..97a32df1174 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-config-label.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-dashboard.png b/versioned_docs/version-v0.21/Configuration/images/dora-dashboard.png new file mode 100644 index 00000000000..a6ece92c116 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-dashboard.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-github-connection-1.png b/versioned_docs/version-v0.21/Configuration/images/dora-github-connection-1.png new file mode 100644 index 00000000000..f9986f1e6ae Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-github-connection-1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-intro.png b/versioned_docs/version-v0.21/Configuration/images/dora-intro.png new file mode 100644 index 00000000000..0f48c8f947a Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-intro.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-jira-connection-1.png b/versioned_docs/version-v0.21/Configuration/images/dora-jira-connection-1.png new file mode 100644 index 00000000000..113a9fcfcca Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-jira-connection-1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-jira-connection-2.png b/versioned_docs/version-v0.21/Configuration/images/dora-jira-connection-2.png new file mode 100644 index 00000000000..f3619ce7beb Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-jira-connection-2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-project-1.png b/versioned_docs/version-v0.21/Configuration/images/dora-project-1.png new file mode 100644 index 00000000000..94e13807233 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-project-1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-project-2.png b/versioned_docs/version-v0.21/Configuration/images/dora-project-2.png new file mode 100644 index 00000000000..249b0ab00c6 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-project-2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-project-3.png b/versioned_docs/version-v0.21/Configuration/images/dora-project-3.png new file mode 100644 index 00000000000..dd08396cff3 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-project-3.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-webhook-1.png b/versioned_docs/version-v0.21/Configuration/images/dora-webhook-1.png new file mode 100644 index 00000000000..679a420a939 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-webhook-1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-webhook-2.png b/versioned_docs/version-v0.21/Configuration/images/dora-webhook-2.png new file mode 100644 index 00000000000..863d0a9a467 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-webhook-2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/dora-webhook-3.png b/versioned_docs/version-v0.21/Configuration/images/dora-webhook-3.png new file mode 100644 index 00000000000..23e351785fa Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/dora-webhook-3.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/github-add-data-scopes.png b/versioned_docs/version-v0.21/Configuration/images/github-add-data-scopes.png new file mode 100644 index 00000000000..9d2e03a0688 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/github-add-data-scopes.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/github-create-a-connection.png b/versioned_docs/version-v0.21/Configuration/images/github-create-a-connection.png new file mode 100644 index 00000000000..4b1bc15fbe2 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/github-create-a-connection.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/github-scope-config.png b/versioned_docs/version-v0.21/Configuration/images/github-scope-config.png new file mode 100644 index 00000000000..d48f5c25cec Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/github-scope-config.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/github-set-transformation1.png b/versioned_docs/version-v0.21/Configuration/images/github-set-transformation1.png new file mode 100644 index 00000000000..a665a8677d2 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/github-set-transformation1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/github-set-transformation2.png b/versioned_docs/version-v0.21/Configuration/images/github-set-transformation2.png new file mode 100644 index 00000000000..c079a5f3a63 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/github-set-transformation2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/gitlab-create-a-connection.png b/versioned_docs/version-v0.21/Configuration/images/gitlab-create-a-connection.png new file mode 100644 index 00000000000..31ee473888b Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/gitlab-create-a-connection.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/gitlab-scope-config.png b/versioned_docs/version-v0.21/Configuration/images/gitlab-scope-config.png new file mode 100644 index 00000000000..f0743bc6486 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/gitlab-scope-config.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/gitlab-set-data-scope.png b/versioned_docs/version-v0.21/Configuration/images/gitlab-set-data-scope.png new file mode 100644 index 00000000000..c493d135962 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/gitlab-set-data-scope.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/gitlab-set-transformation1.png b/versioned_docs/version-v0.21/Configuration/images/gitlab-set-transformation1.png new file mode 100644 index 00000000000..37cafd14b70 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/gitlab-set-transformation1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/gitlab-set-transformation2.png b/versioned_docs/version-v0.21/Configuration/images/gitlab-set-transformation2.png new file mode 100644 index 00000000000..833b3c2f649 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/gitlab-set-transformation2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/introduction-userflow1.png b/versioned_docs/version-v0.21/Configuration/images/introduction-userflow1.png new file mode 100644 index 00000000000..729ab76c863 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/introduction-userflow1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/introduction-userflow2.png b/versioned_docs/version-v0.21/Configuration/images/introduction-userflow2.png new file mode 100644 index 00000000000..ddb655535c2 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/introduction-userflow2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/introduction-userflow3.png b/versioned_docs/version-v0.21/Configuration/images/introduction-userflow3.png new file mode 100644 index 00000000000..83c8eadbd6e Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/introduction-userflow3.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/introduction-userflow5.png b/versioned_docs/version-v0.21/Configuration/images/introduction-userflow5.png new file mode 100644 index 00000000000..b38cbf60c7d Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/introduction-userflow5.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/jenkins-create-a-connection.png b/versioned_docs/version-v0.21/Configuration/images/jenkins-create-a-connection.png new file mode 100644 index 00000000000..74173a41e19 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/jenkins-create-a-connection.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/jenkins-set-transformation1.png b/versioned_docs/version-v0.21/Configuration/images/jenkins-set-transformation1.png new file mode 100644 index 00000000000..d6567e4a670 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/jenkins-set-transformation1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/jenkins-set-transformation2.png b/versioned_docs/version-v0.21/Configuration/images/jenkins-set-transformation2.png new file mode 100644 index 00000000000..2f2b5980425 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/jenkins-set-transformation2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/jira-add-data-scopes.png b/versioned_docs/version-v0.21/Configuration/images/jira-add-data-scopes.png new file mode 100644 index 00000000000..a85fd7045aa Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/jira-add-data-scopes.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/jira-create-a-connection.png b/versioned_docs/version-v0.21/Configuration/images/jira-create-a-connection.png new file mode 100644 index 00000000000..68fb73bc6b1 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/jira-create-a-connection.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/jira-set-data-scope.png b/versioned_docs/version-v0.21/Configuration/images/jira-set-data-scope.png new file mode 100644 index 00000000000..27dd8b1edbf Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/jira-set-data-scope.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/jira-set-transformation1.png b/versioned_docs/version-v0.21/Configuration/images/jira-set-transformation1.png new file mode 100644 index 00000000000..a480caf2184 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/jira-set-transformation1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/jira-set-transformation2.png b/versioned_docs/version-v0.21/Configuration/images/jira-set-transformation2.png new file mode 100644 index 00000000000..66bbce57068 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/jira-set-transformation2.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/jira-set-transformation3.png b/versioned_docs/version-v0.21/Configuration/images/jira-set-transformation3.png new file mode 100644 index 00000000000..d4f164e47c4 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/jira-set-transformation3.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/lead_time.png b/versioned_docs/version-v0.21/Configuration/images/lead_time.png new file mode 100644 index 00000000000..a9a3206fe1d Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/lead_time.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/lead_time_for_changes_definition.png b/versioned_docs/version-v0.21/Configuration/images/lead_time_for_changes_definition.png new file mode 100644 index 00000000000..fa10c990f24 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/lead_time_for_changes_definition.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/mttr.png b/versioned_docs/version-v0.21/Configuration/images/mttr.png new file mode 100644 index 00000000000..8c77736a4b7 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/mttr.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/opsgenie-add-data-scopes.png b/versioned_docs/version-v0.21/Configuration/images/opsgenie-add-data-scopes.png new file mode 100644 index 00000000000..fdcaefe894d Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/opsgenie-add-data-scopes.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/opsgenie-create-a-connection.png b/versioned_docs/version-v0.21/Configuration/images/opsgenie-create-a-connection.png new file mode 100644 index 00000000000..8fafc45962a Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/opsgenie-create-a-connection.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/pagerduty-add-data-connection.png b/versioned_docs/version-v0.21/Configuration/images/pagerduty-add-data-connection.png new file mode 100644 index 00000000000..92af389dfa2 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/pagerduty-add-data-connection.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/pagerduty-create-a-connection.png b/versioned_docs/version-v0.21/Configuration/images/pagerduty-create-a-connection.png new file mode 100644 index 00000000000..bb861b6e860 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/pagerduty-create-a-connection.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/pagerduty-set-data-scope.png b/versioned_docs/version-v0.21/Configuration/images/pagerduty-set-data-scope.png new file mode 100644 index 00000000000..4dcc3c76aa6 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/pagerduty-set-data-scope.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/pagerduty-sync-policy.png b/versioned_docs/version-v0.21/Configuration/images/pagerduty-sync-policy.png new file mode 100644 index 00000000000..6155fb4c408 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/pagerduty-sync-policy.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/sync-policy.png b/versioned_docs/version-v0.21/Configuration/images/sync-policy.png new file mode 100644 index 00000000000..1147e41377f Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/sync-policy.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/upload-dashboard.png b/versioned_docs/version-v0.21/Configuration/images/upload-dashboard.png new file mode 100644 index 00000000000..e2805913b93 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/upload-dashboard.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/webhook-add.png b/versioned_docs/version-v0.21/Configuration/images/webhook-add.png new file mode 100644 index 00000000000..2cd53766493 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/webhook-add.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/webhook-connection1.png b/versioned_docs/version-v0.21/Configuration/images/webhook-connection1.png new file mode 100644 index 00000000000..9b7377f0f21 Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/webhook-connection1.png differ diff --git a/versioned_docs/version-v0.21/Configuration/images/zentao-create-a-connection.png b/versioned_docs/version-v0.21/Configuration/images/zentao-create-a-connection.png new file mode 100644 index 00000000000..4ce325ce4ce Binary files /dev/null and b/versioned_docs/version-v0.21/Configuration/images/zentao-create-a-connection.png differ diff --git a/versioned_docs/version-v0.21/Configuration/webhook.md b/versioned_docs/version-v0.21/Configuration/webhook.md new file mode 100644 index 00000000000..207cb96b96a --- /dev/null +++ b/versioned_docs/version-v0.21/Configuration/webhook.md @@ -0,0 +1,49 @@ +--- +title: "Webhooks" +sidebar_position: 25 +description: Config UI instructions for Webhook +--- + +Visit config-ui: `http://{localhost}:4000`. + +### Step 1 - Add a new incoming webhook + +Go to the 'Connections' page. Create a webhook with a unique name. + +![webhook-add-data-connections](images/webhook-add.png) + + +### Step 2 - Create webhooks connection + +Click on Generate POST URL, and you will find three webhook URLs. + +![webhook-connection1](images/webhook-connection1.png) + +Copy the ones that suit your usage into your CI/CD or issue-tracking systems. You can always come back to the webhook page to copy the URLs later on. + +A non-expired API key is auto-generated for the authentication of the webhook. This API key only shows in the payload when you create the webhook. However, you can always revoke and generate a new token when you view the webhook details. + +See the [full payload schema](../Plugins/webhook.md) of webhooks. + +### Step 3 - Use webhook in a project + +If you want to use webhook data to measure [DORA metrics](../DORA.md), you have to associate it with a DevLake project. + +- Go to the 'Incoming Webhooks' tab on a project's page. +- Add webhook by selecting the existing webhook. +- Go to the project's blueprint page and click 'Collect Data'. This will trigger the DORA plugin to measure DORA metrics with the data collected by the [data connections and webhooks associated with this project](HowToOrganizeDevlakeProjects.md#2-why-is-it-important-to-organize-projects). + +![project-webhook-use](/img/ConfigUI/project-webhook-use.png) + +#### Put webhook on the internet + +For the new webhook to work, it needs to be accessible from the DevOps tools from which you would like to push data to DevLake. If DevLake is deployed in your private network and your DevOps tool (e.g. CircleCI) is a cloud service that lives outside of your private network, then you need to make DevLake's webhook accessible to the outside cloud service. + +There are many tools for this: + +- For testing and quick setup, [ngrok](https://ngrok.com/) is a useful utility that provides a publicly accessible web URL to any locally hosted application. You can put DevLake's webhook on the internet within 5 mins by following ngrok's [Getting Started](https://ngrok.com/docs/getting-started) guide. Note that, when posting to webhook, you may need to replace the `localhost` part in the webhook URL with the forwarding URL that ngrok provides. +- If you prefer DIY, please check out open-source reverse proxies like [fatedier/frp](https://github.com/fatedier/frp) or go for the classic [nginx](https://www.nginx.com/). + +## Troubleshooting + +If you run into any problems, please check the [Troubleshooting](/Troubleshooting/Configuration.md) or [create an issue](https://github.com/apache/incubator-devlake/issues). diff --git a/versioned_docs/version-v0.21/DORA.md b/versioned_docs/version-v0.21/DORA.md new file mode 100644 index 00000000000..93d28450e0e --- /dev/null +++ b/versioned_docs/version-v0.21/DORA.md @@ -0,0 +1,215 @@ +--- +title: "DORA" +sidebar_position: 4 +description: > + DORA Metrics +--- + +This document describes everything you need to know about DORA, and implementing this powerful and practical framework in DevLake. + +## What are DORA metrics? + +Created six years ago by a team of researchers, DORA stands for "DevOps Research & Assessment" and is the answer to years of research, having examined thousands of teams, seeking a reliable and actionable approach to understanding the performance of software development teams. + +DORA has since become a standardized framework focused on the stability and velocity of development processes, one that avoids the more controversial aspects of productivity and individual performance measures. + +There are two key clusters of data inside DORA: Velocity and Stability. The DORA framework is focused on keeping them in context with each other, as a whole, rather than as independent variables, making the data more challenging to misinterpret or abuse. + +Within velocity are two core metrics: + +- [Deployment Frequency](./Metrics/DeploymentFrequency.md): Number of successful deployments to production, how rapidly is your team releasing to users? +- [Lead Time for Changes](./Metrics/LeadTimeForChanges.md): How long does it take from commit to the code running in production? This is important, as it reflects how quickly your team can respond to user requirements. + +Stability is composed of two core metrics: + +- [Median Time to Restore Service](./Metrics/MTTR.md): How long does it take the team to properly recover from a failure once it is identified? +- [Change Failure Rate](./Metrics/CFR.md): How often are your deployments causing a failure? + +![](Configuration/images/dora-intro.png) + +To make DORA even more actionable, there are well-established benchmarks to determine if you are performing at "Elite", "High", "Medium", or "Low" levels. Inside DevLake, you will find the benchmarking table available to assess and compare your own projects. + +## Why is DORA important? + +DORA metrics help teams and projects measure and improve software development practices to consistently deliver reliable products, and thus happy users! + +## How to implement DORA metrics with Apache DevLake? + +DevLake measures DORA metrics at the [project level](Configuration/HowToOrganizeDevlakeProjects.md#2-why-is-it-important-to-organize-projects). You can set up DORA metrics in a few steps: + +- **Install**: via [Docker Compose](GettingStarted/DockerComposeSetup.md) or [Helm](GettingStarted/HelmSetup.md). +- **Configure and collect data**: + - Create [data connections](Overview/KeyConcepts.md#data-connection) to retrieve the data from various tools such as Jira, GitHub, Jenkins, etc. + - Configure the DORA-related [scope config](Overview/KeyConcepts.md#scope-config) to define `deployments` and `incidents`. + - Create a DevLake project, and associate the data connections with the project. Collect data to see DORA metrics +- **Report**: DevLake provides a built-in DORA dashboard and another dashboard to help you debug DORA. See an example screenshot below or check out our [live demo](https://grafana-lake.demo.devlake.io/grafana/d/qNo8_0M4z/dora?orgId=1). + + ![DORA Dashboard](Configuration/images/dora-dashboard.png) + +DevLake now supports Jenkins, GitHub Action, GitLab CI, BitBucket and Azure Pipelines as the data sources for `deployments`; Jira boards, GitHub issues, TAPD workspaces and Zentao issues as the sources for `incidents` data; Github/BitBucket/Azure/GitLab repos as the sources for `Pull Requests` and `Commits`. + +If your CI/CD or incident management tools are not listed on the [Supported Data Sources](./Overview/SupportedDataSources.md) page, have no fear! DevLake provides incoming webhooks to push your `deployments` or `incidents` to DevLake. The webhook configuration doc can be found [here](./Configuration/webhook.md). + +## A real-world example + +Let us walk through the DORA implementation process for a [project team](Configuration/HowToOrganizeDevlakeProjects.md#43-measuring-dora-at-the-team-level) with the following toolchain + +- Source Code Management and Code Review: GitHub +- Continous Deployments: GitHub Actions & CircleCI +- Incident management: Jira + +Calculating DORA metrics requires three key entities: **Pull requests**, **deployments**, and **incidents**. Their exact definitions of course depend on a project's DevOps practice and vary project by project. For the project in this example, let us assume the following definition: + +- Code Changes: All commits and pull requests in GitHub. +- Deployments: GitHub workflow run whose jobs contain "deploy" and "push-image" in their names and CircleCI deployments. +- Incidents: Jira issues whose type is "DORA Incident" + +In the next section, we will demonstrate how to configure DevLake to implement DORA metrics for the aforementioned example project team. + +### Step 1 - Configure GitHub & Jira connections + +1.1 Visit the config-ui at `http://localhost:4000`. + +1.2 Go to the __Connections__ page. Create a Jira connection. + +1.3 Add your project's Jira boards. Click the `Associate Scope Config` icon to configure for DORA metrics. + + ![](Configuration/images/dora-jira-connection-1.png) + + To make it simple, fields with the ![](Configuration/images/dora-config-label.png) label are DORA-related configurations for every data source. Via these fields, you can define what "incidents" and "deployments" are for each data source. + + This project uses Jira issue type `DORA Incident` as "incident". Please select the `DORA Incident` for the `Incident` field. Jira issues belonging to this type will be converted to 'INCIDENT' in DevLake. + + ![](Configuration/images/dora-jira-connection-2.png) + + +1.4 Create a GitHub connection. Add the GitHub repositories. Once added, associate the scope configuration with the repositories. + + In this project, the GitHub CI jobs 'deploy' and 'push-image' are recognized as deployments. To identify these deployments, please use the pattern '(?i)(deploy|push-image)'. GitHub Workflow runs that match this pattern will be transformed into 'deployments' and recorded in the table 'cicd_deployments' in DevLake. + + ![](Configuration/images/dora-github-connection-1.png) + + Please note that starting from v0.20, DevLake automatically collects GitHub deployments and converts them into DevLake deployments by default. + +### Step 2 - Collect CircleCI deployments via webhook + +Using CircleCI as an example, we demonstrate how to actively push data to DevLake using the Webhook approach, in cases where DevLake does not have a plugin specific to that tool to pull data from your data source. Please note that CircleCI will be supported from v0.21. + +2.1 Go to the __Connections__ page. Add a webhook called 'CircleCI'. + +2.2 Copy the curl command to register deployments to Devlake. This curl command includes a non-expired [API key](Configuration/APIKeys.md) generated automatically. + + ![](Configuration/images/dora-webhook-1.png) + +2.3 Head to your CircleCI's pipelines page in a new tab. Find your deployment pipeline and click `Configuration File`. + + ![](Configuration/images/dora-circleci-screenshot-1.png) + +2.4 Paste the curl command to the `config.yml`. Change the key-values in the payload. See the full payload schema [here](./Plugins/webhook.md/#deployment). + +``` +version: 2.1 + +jobs: + build: + docker: + - image: cimg/base:stable + steps: + - checkout + - run: + name: "build" + command: | + echo Hello, World! + + deploy: + docker: + - image: cimg/base:stable + steps: + - checkout + - run: + name: "deploy" + command: | + # The time a deploy started + start_time=`date '+%Y-%m-%dT%H:%M:%S%z'` + + # Some deployment tasks here ... + echo Hello, World! + + # Send the request to DevLake after deploy + # The values start with a '$CIRCLE_' are CircleCI's built-in variables + curl http://127.0.0.1:4000/api/plugins/webhook/2/deployments -X 'POST' -d "{ + \"commit_sha\":\"$CIRCLE_SHA1\", + \"repo_url\":\"$CIRCLE_REPOSITORY_URL\", + \"start_time\":\"$start_time\" + }" + +workflows: + build_and_deploy_workflow: + jobs: + - build + - deploy +``` + + +2.5 Run the CircleCI pipeline. Visit DevLake's DB to check if the deployments have been successfully pushed to DevLake. The deployments will appear in table [cicd_deployments](DataModels/DevLakeDomainLayerSchema.md#cicd_deployments) and [cicd_deployment_commits](DataModels/DevLakeDomainLayerSchema.md#cicd_deployment_commits) in DevLake's database. + + ![](Configuration/images/dora-circleci-screenshot-2.png) + + ![webhook-query](/img/ConfigUI/webhook-query-deployments.png) + + +### Step 3 - Create a project and collect data +Once all the data connections and webhooks have been configured, it is essential to associate them with a DevLake project. This association is necessary to accurately measure DORA metrics. + +3.1 Go to the __Projects__ page. Create 'project1' and enable DORA metrics. + + ![project1](/img/ConfigUI/project1.png) + +3.2 Add Jira and a GitHub connections to this project. + + ![](Configuration/images/dora-project-2.png) + + Choose the Jira boards and GitHub repos that belong to 'project1'. + + ![](Configuration/images/dora-project-3.png) + +3.3 Go to the __webhooks__ tab. Add the existing webhook 'CircleCI' to this project. + + ![](Configuration/images/dora-webhook-2.png) + + ![](Configuration/images/dora-webhook-3.png) + +3.4 Go to the __blueprint status__ tab, click `Collect All` to start data collection. + +### Step 4 - View and customize DevLake's DORA dashboard + +With all the data collected, DevLake's DORA dashboard is ready to deliver your DORA metrics and benchmarks. + +Click the `Dashboards` on the top right corner. You can find the DORA dashboard within the Grafana instance shipped with DevLake, ready for you to put into action. + +You can customize the DORA dashboard by editing the underlying SQL query of each panel. + +For a breakdown of each metric's SQL query, please refer to the corresponding metric docs: + +- [Deployment Frequency](./Metrics/DeploymentFrequency.md) +- [Lead Time for Changes](./Metrics/LeadTimeForChanges.md) +- [Median Time to Restore Service](./Metrics/MTTR.md) +- [Change Failure Rate](./Metrics/CFR.md) + +If you are not familiar with Grafana, please refer to our [Grafana doc](Configuration/Dashboards/GrafanaUserGuide.md), or jump into Slack for help. + +
+ +:tada::tada::tada: Congratulations! You are now a DevOps Hero, with your own DORA dashboard! + +

+ +## 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. + +
+ +## Troubleshooting + +If you run into any problem, please check the DORA debug dashboard, [DORA troubleshooting documentation](/Troubleshooting/Dashboard.md#debugging-dora-issue-metrics) or [create an issue](https://github.com/apache/incubator-devlake/issues) on GitHub. diff --git a/versioned_docs/version-v0.21/DataModels/DevLakeDomainLayerSchema.md b/versioned_docs/version-v0.21/DataModels/DevLakeDomainLayerSchema.md new file mode 100644 index 00000000000..258d9f84442 --- /dev/null +++ b/versioned_docs/version-v0.21/DataModels/DevLakeDomainLayerSchema.md @@ -0,0 +1,874 @@ +--- +title: "Domain Layer Schema" +description: > + The data tables to query engineering metrics +sidebar_position: 1 +--- + +## Summary + + + + + + + +This document describes Apache DevLake's domain layer schema. + +Referring to DevLake's [architecture](../Overview/Architecture.md), the data in the domain layer is transformed from the data in the tool layer. The tool layer schema is based on the data from specific tools such as Jira, GitHub, GitLab, Jenkins, etc. The domain layer schema can be regarded as an abstraction of tool-layer schemas. + +

+ +![](../Configuration/images/arch-dataflow-domain.svg) + +

+

DevLake Dataflow

+ +## Use Cases + +1. [All metrics](../Metrics) from pre-built dashboards are based on this data schema. +2. As a user, you can create your own customized dashboards based on this data schema. +3. As a contributor, you can refer to this data schema while working on the ETL logic when adding/updating data source plugins. + +## Data Models + +This is the up-to-date domain layer schema for DevLake. Tables (entities) are categorized into 5 domains. + +1. Issue tracking: Jira issues, GitHub issues, GitLab issues, etc. +2. Source code management: Git/GitHub/GitLab commits and refs(tags and branches), etc. +3. Code review: GitHub PRs, GitLab MRs, etc. +4. CI/CD: Jenkins jobs & builds, etc. +5. Code Quality: SonarQube issues, hotspots, file metrics, etc. +6. Cross-domain: entities that map entities from different domains to break data isolation. + +### Schema Diagram + +![Domain Layer Schema](../Configuration/images/domain-layer-schema-diagram.svg) + +When reading the schema, you'll notice that many tables' primary key is called `id`. Unlike auto-increment id or UUID, `id` is a string composed of several parts to uniquely identify similar entities (e.g. repo) from different platforms (e.g. GitHub/GitLab) and allow them to co-exist in a single table. + +Tables that end with WIP are still under development. + +### Naming Conventions + +1. The name of a table is in plural form. E.g. boards, issues, etc. +2. The name of a table which describe the relation between 2 entities is in the form of [BigEntity in singular form]\_[SmallEntity in plural form]. E.g. board_issues, sprint_issues, pull_request_comments, etc. +3. Value of the field in enum type are in capital letters. E.g. [table.issues.type](#issues) has 3 values, REQUIREMENT, BUG, INCIDENT. Values that are phrases, such as 'IN_PROGRESS' of [table.issues.status](#issues), are separated with underscore '\_'. + +## How to Customize Data Models + +Apache DevLake provides 2 plugins: + +- [customize](https://devlake.apache.org/docs/Plugins/customize): to create/delete columns in the domain layer schema with the data extracted from [raw layer tables](https://devlake.apache.org/docs/Overview/Architecture/#dataflow) +- [dbt](https://devlake.apache.org/docs/Plugins/customize): to transform data based on the domain layer schema and generate new tables + +
+ +## DWD Entities - (Data Warehouse Detail) + +### Domain 1 - Issue Tracking + +#### issues + +An `issue` is the abstraction of GitHub/GitLab/BitBucket/Jira/TAPD/Zentao... issues. + +| **field** | **type** | **length** | **description** | **key** | +|:----------------------------|:----------------------------------------------|:-----------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------| +| `id` | varchar | 255 | An issue's `id` is composed of < plugin >:< Entity >:< PK0 >[:PK1]..."
  • For Github issues, a Github issue's id is like "github:GithubIssues:< GithubIssueId >". E.g. 'github:GithubIssues:1049355647'
  • For Jira issues, a Github repo's id is like "jira:JiraIssues:< JiraSourceId >:< JiraIssueId >". E.g. 'jira:JiraIssues:1:10063'. < JiraSourceId > is used to identify which jira source the issue came from, since DevLake users can import data from several different Jira instances at the same time.
| PK | +| `issue_key` | varchar | 255 | The key of this issue. For example, the key of this Github [issue](https://github.com/apache/incubator-devlake/issues/1145) is 1145. | | +| `url` | varchar | 255 | The url of the issue. It's a web address in most cases. | | +| `title` | varchar | 255 | The title of an issue | | +| `description` | longtext | | The detailed description/summary of an issue | | +| `type` | varchar | 100 | The standard type of this issue. There are 3 standard types:
  • REQUIREMENT: this issue is a feature
  • BUG: this issue is a bug found during test
  • INCIDENT: this issue is a bug found after release
The 3 standard types are transformed from the original types of an issue. The transformation rule is set in the '.env' file or 'config-ui' before data collection. For issues with an original type that has not mapped to a standard type, the value of `type` will be the issue's original type. | | +| `original_type` | varchar | 100 | The original type of an issue. | | +| `status` | varchar | 100 | The standard statuses of this issue. There are 3 standard statuses:
  • TODO: this issue is in backlog or to-do list
  • IN_PROGRESS: this issue is in progress
  • DONE: this issue is resolved or closed
The 3 standard statuses are transformed from the original statuses of an issue. The transformation rule:
  • For Jira issue status: transformed from the Jira issue's `statusCategory`. Jira issue has 3 default status categories: 'To Do', 'In Progress', 'Done'.
  • For Github issue status:
    • open -> TODO
    • closed -> DONE
| | +| `original_status` | varchar | 100 | The original status of an issue. | | +| `story_point` | double | | The story point of this issue. Only certain types(e.g. story) of Jira or TAPD issues has story points | | +| `priority` | varchar | 255 | The priority of the issue | | +| `urgency` | varchar | 255 | The urgency of the issue | | +| `component` | varchar | 255 | The component a bug-issue affects. This field only supports Github plugin for now. The value is transformed from Github issue labels by the rules set according to the user's configuration of .env by end users during DevLake installation. | | +| `severity` | varchar | 255 | The severity level of a bug-issue. This field only supports Github plugin for now. The value is transformed from Github issue labels by the rules set according to the user's configuration of .env by end users during DevLake installation. | | +| `parent_issue_id` | varchar | 255 | The id of its parent issue | | +| `epic_key` | varchar | 255 | The key of the epic this issue belongs to. For tools with no epic-type issues such as Github and GitLab, this field is default to an empty string | | +| `original_estimate_minutes` | int | | The original estimation of the time allocated for this issue | | +| `time_spent_minutes` | int | | The original estimation of the time allocated for this issue | | +| `time_remaining_minutes` | int | | The remaining time to resolve the issue | | +| `creator_id` | varchar | 255 | The id of issue creator | | +| `creator_name` | varchar | 255 | The name of the creator | | +| `assignee_id` | varchar | 255 | The id of issue assignee.
  • For Github issues: this is the last assignee of an issue if the issue has multiple assignees
  • For Jira issues: this is the assignee of the issue at the time of collection
| | +| `assignee_name` | varchar | 255 | The name of the assignee | | +| `created_date` | datetime | 3 | The time issue created | | +| `updated_date` | datetime | 3 | The last time issue gets updated | | +| `resolution_date` | datetime | 3 | The time the issue changes to 'DONE'. | | +| `lead_time_minutes` | int | | Describes the cycle time from issue creation to issue resolution.
  • For issues whose type = 'REQUIREMENT' and status = 'DONE', lead_time_minutes = resolution_date - created_date. The unit is minute.
  • For issues whose type != 'REQUIREMENT' or status != 'DONE', lead_time_minutes is null
| | +| `original_project` | varchar | 255 | The name of the original project this issue belongs to. Transformed from a Jira project's name, a TAPD workspace's name, etc. | | +| `icon_url` | varchar | 255 | The url of the issue icon. | | +| `x_custom_field_1` | It depends on the type of the converted field | - | The value of the custom field. This field is available when utilizing the [customize](/docs/Plugins/customize.md) plugin to convert Jira's raw layer fields to the domain layer fields. | | + +#### issue_assignees + +This table shows the assignee(s) of issues. Multiple entries can exist per issue, as a GitHub/TAPD issue may have multiple assignees at the same time. This table can be used to get the detailed information of all issue assignees. + +| **field** | **type** | **length** | **description** | **key** | +|:----------------|:---------|:-----------|:----------------|:---------------| +| `issue_id` | varchar | 255 | Issue ID | FK_issues.id | +| `assignee_id` | varchar | 255 | Assignee ID | FK_accounts.id | +| `assignee_name` | varchar | 255 | Assignee Name | | + +#### issue_labels + +This table shows the labels of issues. Multiple entries can exist per issue. This table can be used to filter issues by label name. + +| **field** | **type** | **length** | **description** | **key** | +|:-------------|:---------|:-----------|:------------------------------------------------------------------|:-------------| +| `label_name` | varchar | 255 | Label name. Collect from GitHub issue labels or Jira issue labels | | +| `issue_id` | varchar | 255 | Issue ID | FK_issues.id | + +#### issue_comments + +This table shows the comments of issues. Only GitHub and TAPD issue comments are collected. Issues with multiple comments are shown as multiple records. This table can be used to calculate _metric - issue response time_. + +| **field** | **type** | **length** | **description** | **key** | +|:---------------|:---------|:-----------|:-------------------------------------------|:---------------| +| `id` | varchar | 255 | The unique id of a comment | PK | +| `issue_id` | varchar | 255 | Issue ID | FK_issues.id | +| `account_id` | varchar | 255 | The id of the account who made the comment | FK_accounts.id | +| `body` | longtext | | The body/detail of the comment | | +| `created_date` | datetime | 3 | The creation date of the comment | | +| `updated_date` | datetime | 3 | The update date of the comment | | + +#### issue_changelogs + +This table shows the changelogs of issues. Only Jira issue changelogs are collected for now. Issues with multiple changelogs are shown as multiple records. This is transformed from Jira or TAPD changelogs. + +| **field** | **type** | **length** | **description** | **key** | +|:----------------------|:---------|:-----------|:-----------------------------------------------------------------|:---------------| +| `id` | varchar | 255 | The unique id of an issue changelog | PK | +| `issue_id` | varchar | 255 | Issue ID | FK_issues.id | +| `author_id` | varchar | 255 | The id of the user who made the change | FK_accounts.id | +| `author_name` | varchar | 255 | The id of the user who made the change | | +| `field_id` | varchar | 255 | The id of changed field | | +| `field_name` | varchar | 255 | The id of changed field | | +| `original_from_value` | longtext | | The original value of the changed field | | +| `original_to_value` | longtext | | The new value of the changed field | | +| `from_value` | longtext | | The transformed/standardized original value of the changed field | | +| `to_value` | longtext | | The transformed/standardized new value of the changed field | | +| `created_date` | datetime | 3 | The creation date of the changelog | | + +#### issue_worklogs + +This table shows the work logged under issues. Only Jira issue worklogs are collected for now. Usually, an issue has multiple worklogs logged by different developers. + +| **field** | **type** | **length** | **description** | **key** | +|:---------------------|:---------|:-----------|:-----------------------------------------------------------------------------------------|:---------------| +| `id` | varchar | 255 | The id of the worklog. | PK | +| `author_id` | varchar | 255 | The id of the author who logged the work | FK_accounts.id | +| `comment` | longtext | 255 | The comment made while logging the work. | | +| `time_spent_minutes` | int | | The time logged. The unit of value is normalized to minute. E.g. 1d =) 480, 4h30m =) 270 | | +| `logged_date` | datetime | 3 | The time of this logging action | | +| `started_date` | datetime | 3 | Start time of the worklog | | +| `issue_id` | varchar | 255 | Issue ID | FK_issues.id | + +#### issue_relationships + +This table shows the metadata of information about relationships between issues. + +| **field** | **type** | **length** | **description** | **key** | +|:------------------|:---------|:-----------|:----------------------------------------------------------|:--------| +| `id` | varchar | 255 | Issue ID | PK | +| `source_issue_id` | int | | ID of the source issue in the relationship | | +| `target_issue_id` | int | | ID of the target issue in the relationship | | +| `original_type` | varchar | 255 | Type of relationship between the source and target issues | | + +#### issue_repo_commits + +This table shows the metadata of commits made to a code repository associated with specific issues. + +| **field** | **type** | **length** | **description** | **key** | +|:-------------|:---------|:-----------|:-------------------------------------|:--------| +| `issue_id` | varchar | 255 | Issue ID | PK | +| `repo_url` | varchar | 255 | The URL of the code repository | PK | +| `commit_sha` | varchar | 255 | The SHA of the commit. | PK | +| `host` | varchar | 255 | The hostname | | +| `namespace` | varchar | 255 | The namespace of the code repository | | +| `repo_name` | varchar | 255 | The name of the code repository. | | + +#### issue_custom_array_fields + +The table below presents the custom fields of issues in an 'array' type. This table is available when utilizing the [customize](/docs/Plugins/customize.md) plugin to convert Jira's raw layer fields to the domain layer fields. It is important to note that custom fields of other types will be displayed as 'x_custom_field_1' in the [issues](#issues) table. + +| **field** | **type** | **length** | **description** | **key** | +|:--------------|:---------|:-----------|:-----------------------------------------------------------------------------------|:--------| +| `issue_id` | varchar | 255 | Issue ID | PK | +| `field_id` | varchar | 255 | The ID of the array field of the issue. It starts with 'x_', e.g. x_product_lines. | | +| `field_value` | varchar | 255 | The value of the array field. E.g. DevLake, DevSea, DevPond. | | + +You can refer to the following SQL to use this table. + +``` +-- query issue count by product lines +select + count(*) as issue_count, field_value +from issues + join issue_custom_array_fields on issues.id = issue_custom_array_fields.issue_id +where field_id = 'x_product_lines' +group by field_value; +``` + +#### boards + +A `board` is an issue list or a collection of issues. It's the abstraction of a Jira board, a Jira or TAPD project, a [GitHub repo's issue list](https://github.com/apache/incubator-devlake/issues) or a GitLab repo's issue list. This table can be used to filter issues by the boards they belong to. + +| **field** | **type** | **length** | **description** | **key** | +|:---------------|:---------|:-----------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------| +| `id` | varchar | 255 | A board's `id` is composed of "< plugin >:< Entity >:< PK0 >[:PK1]..."
  • For a Github repo's issue list, the board id is like "< github >:< GithubRepos >:< ConnectionId >:< GithubRepoId >".
    E.g. "github:GithubRepo:384111310"
  • For a Jira Board, the id is like "< jira >:< JiraSourceId >< JiraBoards >:< ConnectionId >:< JiraBoardsId >".
    E.g. "jira:1:JiraBoards:1:12"
| PK | +| `name` | varchar | 255 | The name of the board. Note: the board name of a Github repo 'apache/incubator-devlake' is 'apache/incubator-devlake', representing the [default issue list](https://github.com/apache/incubator-devlake/issues). | | +| `description` | varchar | 255 | The description of the board. | | +| `url` | varchar | 255 | The url of the board. E.g. https://github.com/apache/incubator-devlake/issues | | +| `created_date` | datetime | 3 | Board creation time | | +| `type` | varchar | 255 | Identify scrum and non-scrum board | | + +#### board_issues + +This table shows the relation between boards and issues. This table can be used to filter issues by board. + +| **field** | **type** | **length** | **description** | **key** | +|:-----------|:---------|:-----------|:----------------|:-------------| +| `board_id` | varchar | 255 | Board id | FK_boards.id | +| `issue_id` | varchar | 255 | Issue id | FK_issues.id | + +#### sprints + +A `sprint` is the abstraction of Jira sprints, TAPD iterations and GitHub milestones. A sprint contains a list of +issues. + +| **field** | **type** | **length** | **description** | **key** | +|:--------------------|:---------|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------| +| `id` | varchar | 255 | A sprint's `id` is composed of "< plugin >:< Entity >:< PK0 >[:PK1]..."
  • A sprint in a Github repo is a milestone, the sprint id is like "< github >:< GithubRepos >:< GithubRepoId >:< milestoneNumber >".
    Eg. The id for this [sprint](https://github.com/apache/incubator-devlake/milestone/5) is "github:GithubRepo:384111310:5"
  • For a Jira Board, the id is like "< jira >:< JiraSourceId >< JiraBoards >:< JiraBoardsId >".
    Eg. "jira:1:JiraBoards:12"
| PK | +| `name` | varchar | 255 | The name of sprint.
For Github projects, the sprint name is the milestone name. For instance, 'v0.10.0 - Introduce Temporal to DevLake' is the name of this [sprint](https://github.com/apache/incubator-devlake/milestone/5). | | +| `url` | varchar | 255 | The url of sprint. | | +| `status` | varchar | 255 | There are 3 statuses of a sprint:
  • CLOSED: a completed sprint
  • ACTIVE: a sprint started but not completed
  • FUTURE: a sprint that has not started
  • SUSPENDED: a sprint that has been suspended
| | +| `started_date` | datetime | 3 | The start time of a sprint | | +| `ended_date` | datetime | 3 | The planned/estimated end time of a sprint. It's usually set when planning a sprint. | | +| `completed_date` | datetime | 3 | The actual time to complete a sprint. | | +| `original_board_id` | datetime | 3 | The id of board where the sprint first created. This field is not null only when this entity is transformed from Jira sprints.
In Jira, sprint and board entities have 2 types of relation:
  • A sprint is created based on a specific board. In this case, board(1):(n)sprint. This field `original_board_id` is used to show the relation.
  • A sprint can be mapped to multiple boards, a board can also show multiple sprints. In this case, board(n):(n)sprint. This relation is shown in [table.board_sprints](#board_sprints)
| FK_boards.id | + +#### sprint_issues + +This table shows the relation between sprints and issues that have been added to sprints. This table can be used to show +metrics such as _'ratio of unplanned issues'_, _'completion rate of sprint issues'_, etc + +| **field** | **type** | **length** | **description** | **key** | +|:------------|:---------|:-----------|:----------------|:--------------| +| `sprint_id` | varchar | 255 | Sprint id | FK_sprints.id | +| `issue_id` | varchar | 255 | Issue id | FK_issues.id | + +#### board_sprints + +| **field** | **type** | **length** | **description** | **key** | +|:------------|:---------|:-----------|:----------------|:--------------| +| `board_id` | varchar | 255 | Board id | FK_boards.id | +| `sprint_id` | varchar | 255 | Sprint id | FK_sprints.id | + +
+ +### Domain 2 - Source Code Management + +#### repos + +GitHub, GitLab or BitBucket repositories. + +| **field** | **type** | **length** | **description** | **key** | +|:---------------|:---------|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------| +| `id` | varchar | 255 | A repo's `id` is composed of "< plugin >:< Entity >:< PK0 >[:PK1]..."
For example, a Github repo's id is like "< github >:< GithubRepos >:< ConnectionId >:< GithubRepoId >". E.g. 'github:GithubRepos:1:384111310' | PK | +| `name` | longtext | | The name of repo. For DevLake, it's 'apache/incubator-devlake' | | +| `description` | longtext | | The description of repo. | | +| `url` | longtext | | The url of repo. E.g. https://github.com/apache/incubator-devlake | | +| `owner_id` | varchar | 255 | The id of the owner of repo | FK_accounts.id | +| `language` | varchar | 255 | The major language of repo. E.g. The language for apache/incubator-devlake is 'Go' | | +| `forked_from` | longtext | | Empty unless the repo is a fork in which case it contains the `id` of the repo the repo is forked from. | | +| `deleted` | tinyint | 1 | 0: repo is active 1: repo has been deleted | | +| `created_date` | datetime | 3 | Repo creation date | | +| `updated_date` | datetime | 3 | Last full update was done for this repo | | + +#### repo_commits + +The commits belong to the history of a repository. More than one repo can share the same commits if one is a fork of the +other. + +| **field** | **type** | **length** | **description** | **key** | +|:-------------|:---------|:-----------|:----------------|:---------------| +| `repo_id` | varchar | 255 | Repo id | FK_repos.id | +| `commit_sha` | char | 40 | Commit sha | FK_commits.sha | + +#### refs + +A ref is the abstraction of a branch or tag. + +| **field** | **type** | **length** | **description** | **key** | +|:-------------|:---------|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------| +| `id` | varchar | 255 | A ref's `id` is composed of "< plugin >:< Entity >:< PK0 >[:PK1]..."
For example, a Github ref is composed of "github:GithubRepos:< GithubRepoId >:< RefUrl >". E.g. The id of release v5.3.0 of PingCAP/TiDB project is 'github:GithubRepos:384111310:refs/tags/v5.3.0' A repo's `id` is composed of "< plugin >:< Entity >:< PK0 >[:PK1]..." | PK | +| `name` | varchar | 255 | The name of the ref. E.g. '[refs/tags/v0.9.3](https://github.com/apache/incubator-devlake/tree/v0.9.3)' or 'origin/main' | | +| `repo_id` | varchar | 255 | The id of repo this ref belongs to | FK_repos.id | +| `commit_sha` | char | 40 | The commit this ref points to at the time of collection | | +| `is_default` | tinyint | 1 |
  • 0: not the default branch
  • 1: the ref is the default branch. By the definition of [Github](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-branches-in-your-repository/changing-the-default-branch), the default branch is the base branch for pull requests and code commits.
| | +| `ref_type` | varchar | 64 | There are 2 typical types:
  • BRANCH
  • TAG
| | + +#### commits_diffs + +This table shows the commits added in a new commit compared to an old commit. This table can be used to support tag-based and deploy-based metrics. + +The records of this table are computed by [RefDiff](https://github.com/apache/incubator-devlake/tree/main/backend/plugins/refdiff) plugin. The computation should be manually triggered after using [GitRepoExtractor](https://github.com/apache/incubator-devlake/tree/main/backend/plugins/gitextractor) to collect commits and refs. The algorithm behind is similar to [this](https://github.com/apache/incubator-devlake/compare/v0.8.0%E2%80%A6v0.9.0). + +| **field** | **type** | **length** | **description** | **key** | +|:-----------------|:---------|:-----------|:---------------------------------------------------------------------------|:--------| +| `new_commit_sha` | char | 40 | The commit new ref/deployment points to at the time of collection | PK | +| `old_commit_sha` | char | 40 | The commit old ref/deployment points to at the time of collection | PK | +| `commit_sha` | char | 40 | One of the added commits in the new ref compared to the old ref/deployment | PK | +| `sorting_index` | bigint | | An index for debugging, please skip it | | + +#### ref_commits + +| **field** | **type** | **length** | **description** | **key** | +|:-----------------|:---------|:-----------|:-------------------------------------------------------|:--------| +| `new_ref_id` | varchar | 255 | The new ref's id for comparison | PK | +| `old_ref_id` | varchar | 255 | The old ref's id for comparison | PK | +| `new_commit_sha` | char | 40 | The commit new ref points to at the time of collection | | +| `old_commit_sha` | char | 40 | The commit old ref points to at the time of collection | | + +#### commits + +| **field** | **type** | **length** | **description** | **key** | +|:------------------|:---------|:-----------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------| +| `sha` | char | 40 | One of the added commits in the new ref compared to the old ref | FK_commits.sha | +| `message` | varchar | 255 | Commit message | | +| `author_name` | varchar | 255 | The value is set with command `git config user.name xxxxx` commit | | +| `author_email` | varchar | 255 | The value is set with command `git config user.email xxxxx` author | | +| `authored_date` | datetime | 3 | The date when this commit was originally made | | +| `author_id` | varchar | 255 | The id of commit author | FK_accounts.id | +| `committer_name` | varchar | 255 | The name of committer | | +| `committer_email` | varchar | 255 | The email of committer | | +| `committed_date` | datetime | 3 | The last time the commit gets modified.
For example, when rebasing the branch where the commit is in on another branch, the committed_date changes. | | +| `committer_id` | varchar | 255 | The id of committer | FK_accounts.id | +| `additions` | bigint | | Added lines of code | | +| `deletions` | bigint | | Deleted lines of code | | +| `dev_eq` | int | | A metric that quantifies the amount of code contribution. The data can be retrieved from [AE plugin](https://github.com/apache/incubator-devlake/tree/main/backend/plugins/ae). | | + +#### commit_files + +The files that have been changed by commits. + +| **field** | **type** | **length** | **description** | **key** | +|:-------------|:---------|:-----------|:-------------------------------------------------------|:---------------| +| `id` | varchar | 255 | The `id` is composed of "< Commit_sha >:< file_path >" | FK_commits.sha | +| `commit_sha` | char | 40 | Commit sha | FK_commits.sha | +| `file_path` | varchar | 255 | Path of a changed file in a commit | | +| `additions` | bigint | | The added lines of code in this file by the commit | | +| `deletions` | bigint | | The deleted lines of code in this file by the commit | | + +#### components + +The components of files extracted from the file paths. This can be used to analyze Git metrics by component. + +| **field** | **type** | **length** | **description** | **key** | +|:-------------|:---------|:-----------|:-------------------------------------------------------|:------------| +| `repo_id` | varchar | 255 | The repo id | FK_repos.id | +| `name` | varchar | 255 | The name of component | | +| `path_regex` | varchar | 255 | The regex to extract components from this repo's paths | | + +#### commit_file_components + +The relationship between commit_file and component_name. + +| **field** | **type** | **length** | **description** | **key** | +|:-----------------|:---------|:-----------|:-----------------------------|:-------------------| +| `commit_file_id` | varchar | 255 | The id of commit file | FK_commit_files.id | +| `component_name` | varchar | 255 | The component name of a file | | + +#### commit_parents + +The parent commit(s) for each commit, as specified by Git. + +| **field** | **type** | **length** | **description** | **key** | +|:--------------------|:---------|:-----------|:------------------|:---------------| +| `commit_sha` | char | 40 | commit sha | FK_commits.sha | +| `parent_commit_sha` | char | 40 | Parent commit sha | FK_commits.sha | + +
+ +### Domain 3 - Code Review + +#### pull_requests + +Pull requests are the abstraction of GitHub pull requests, GitLab merge requests, BitBucket pull requests, etc. + +| **field** | **type** | **length** | **description** | **key** | +|:-------------------|:---------|:-----------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------| +| `id` | varchar | 255 | A pull request's `id` is composed of "< plugin >:< Entity >:< PK0 >[:PK1]..." E.g. For 'github:GithubPullRequests:1347' | | +| `title` | longtext | | The title of pull request | | +| `description` | longtext | | The body/description of pull request | | +| `status` | varchar | 100 | The PR/MR statuses are standardized to 'OPEN', 'MERGED' and 'CLOSED'. [Learn how each plugin's PR statuses are standardized](https://github.com/apache/incubator-devlake/issues/4745). | | +| `original_status` | varchar | 100 | The original status of pull requests. | | +| `parent_pr_id` | varchar | 255 | The id of the parent PR | | +| `pull_request_key` | varchar | 255 | The key of PR. E.g. 1536 is the key of this [PR](https://github.com/apache/incubator-devlake/pull/1563) | | +| `base_repo_id` | varchar | 255 | The repo that will be updated. | | +| `head_repo_id` | varchar | 255 | The repo containing the changes that will be added to the base. If the head repository is NULL, this means that the corresponding project had been deleted when DevLake processed the pull request. | | +| `author_name` | varchar | 100 | The author's name of the pull request | | +| `author_id` | varchar | 100 | The author's id of the pull request | | +| `url` | varchar | 255 | the web link of the pull request | | +| `type` | varchar | 255 | The work-type of a pull request.For example: feature-development, bug-fix, docs,etc. | | +| `component` | varchar | 255 | The component this PR affects.
The value is transformed from Github/GitLab pull request labels by configuring `GITHUB_PR_COMPONENT` in `.env` file during installation. | | +| `created_date` | datetime | 3 | The time PR created. | | +| `merged_date` | datetime | 3 | The time PR gets merged. Null when the PR is not merged. | | +| `closed_date` | datetime | 3 | The time PR closed. Null when the PR is not closed. | | +| `merge_commit_sha` | char | 40 | the merge commit of this PR. By the definition of [Github](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-branches-in-your-repository/changing-the-default-branch), when you click the default Merge pull request option on a pull request on Github, all commits from the feature branch are added to the base branch in a merge commit. | FK_commits.sha | +| `base_ref` | varchar | 255 | The branch name in the base repo that will be updated | | +| `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. | | + +#### pull_request_labels + +This table shows the labels of pull request. Multiple entries can exist per pull request. This table can be used to +filter pull requests by label name. + +| **field** | **type** | **length** | **description** | **key** | +|:------------------|:---------|:-----------|:----------------|:--------------------| +| `label_name` | varchar | 255 | Label name | | +| `pull_request_id` | varchar | 255 | Pull request ID | FK_pull_requests.id | + +#### pull_request_commits + +A commit associated with a pull request. + +The list is additive. This means if a rebase with commit squashing takes place after the commits of a pull request have been processed, the old commits will not be deleted. + +| **field** | **type** | **length** | **description** | **key** | +|:-----------------------|:---------|:-----------|:---------------------------------------------------------|:--------------------| +| `pull_request_id` | varchar | 255 | Pull request id | FK_pull_requests.id | +| `commit_sha` | char | 40 | Commit sha | FK_commits.sha | +| `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. | | + +#### pull_request_comments + +Normal comments, review bodies, reviews' inline comments of GitHub's pull requests or GitLab's merge requests. + +| **field** | **type** | **length** | **description** | **key** | +|:------------------|:---------|:-----------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------| +| `id` | varchar | 255 | Comment id | PK | +| `pull_request_id` | varchar | 255 | Pull request id | FK_pull_requests.id | +| `body` | longtext | | The body of the comments | | +| `account_id` | varchar | 255 | The account who made the comment | FK_accounts.id | +| `created_date` | datetime | 3 | Comment creation time | | +| `position` | int | | Deprecated | | +| `type` | varchar | 255 | - For normal comments: NORMAL
- For review comments, ie. diff/inline comments: DIFF
- For reviews' body (exist in GitHub but not GitLab): REVIEW | | +| `review_id` | varchar | 255 | Review_id of the comment if the type is `REVIEW` or `DIFF` | | +| `status` | varchar | 255 | Status of the comment | | + +
+ +### Domain 4 - CI/CD + +#### cicd_scopes + +The entity to filter or group 'cicd_pipelines'. + +- For GitHub: a GitHub repo is converted to a cicd_scope +- For GitLab: a GitLab project is converted to a cicd_scope +- For Jenkins: a Jenkins job is converted to a cicd_scope +- For Bamboo CI: a Bamboo plan is converted to a cicd_scope + +| **field** | **type** | **length** | **description** | **key** | +|:---------------|:---------|:-----------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------| +| `id` | varchar | 255 | A cicd_scope's `id` is composed of "< plugin >:< Entity >:< PluginConnectionId >[:PK1]..."
For example, a GitHub cicd_scope's id is "github:GithubRepos:< GithubConnectionId >:< GithubRepoId >", a Bamboo cicd_scope's id is 'bamboo:BambooPlan:< BambooConnectionId >:< BambooPlanKey >' | PK | +| `name` | varchar | 255 | The name of cicd_scope. | | +| `description` | longtext | | The description of cicd_scope. | | +| `url` | varchar | 255 | The url of cicd_scope. E.g. https://github.com/apache/incubator-devlake or https://jenkins.xxx.cn/view/PROD/job/OPS_releasev2/ | | +| `created_date` | datetime | 3 | Creation date of the cicd_scope, nullable | | +| `updated_date` | datetime | 3 | Updation date of the cicd_scope, nullable | | + +#### cicd_pipelines + +A cicd_pipeline is the abstraction of a top-level CI/CD execution, e.g. a GitHub workflow run, a GitLab pipeline, a BitBucket pipeline, a Jenkins build, a Bamboo plan build, etc. A cicd_pipeline contains one or more of cicd_tasks. + +| **field** | **type** | **length** | **description** | **key** | +|:----------------------|:---------|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------|:------------------| +| `id` | varchar | 255 | This key is generated based on details from the original plugin | PK | +| `name` | varchar | 255 | For gitlab, as there is no name for pipeline, so we use projectId, others have their own name | | +| `result` | varchar | 100 | The result of the pipeline. It will be standardized to 'SUCCESS', 'FAILURE', '' in DevLake based on each plugin's possible results. | | +| `original_result` | varchar | 100 | The original_result of the pipeline. Its value depends on the state of the corresponding entity in the different plugins. | | +| `status` | varchar | 100 | The status of the pipeline. It will be standardized to 'DONE', 'IN_PROGRESS', 'OTHER' in DevLake based on each plugin's possible statues. | | +| `original_status` | varchar | 100 | The original_status of the pipeline. Its value depends on the state of the corresponding entity in the different plugins. | | +| `type` | varchar | 100 | The value will be set to 'DEPLOYMENT' if it matched the regex configured in the Scope Config, otherwise it is an empty string. | | +| `environment` | varchar | 255 | The value will be set to 'PRODUCTION' if it matched the regex configured in the Scope Config, otherwise it is an empty string. | | +| `duration_sec` | double | | how long does this pipeline take | | +| `queued_duration_sec` | double | | how long does this pipeline take queuing | | +| `created_date` | datetime | 3 | When this pipeline created. | | +| `queued_date` | datetime | 3 | The queued time of the pipeline. | | +| `started_date` | datetime | 3 | The started time of the pipeline. | | +| `finished_date` | datetime | 3 | When this pipeline finished. | | +| `cicd_scope_id` | longtext | | The id of cicd_scope this pipeline belongs to | FK_cicd_scopes.id | + +#### cicd_pipeline_commits + +| **field** | **type** | **length** | **description** | **key** | +|:--------------|:---------|:-----------|:----------------------------------------------------------------|:--------| +| `pipeline_id` | varchar | 255 | This key is generated based on details from the original plugin | PK | +| `commit_sha` | varchar | 255 | The commit that triggers this pipeline | PK | +| `branch` | varchar | 255 | The branch that triggers this pipeline | | +| `repo_url` | varchar | 255 | | | +| `repo_id` | varchar | 255 | The repo that this pipeline belongs to | | + +#### cicd_tasks + +A cicd_task is the abstraction of the bottom-level CI/CD execution. + +- For GitHub: a cicd_task is a GitHub job run in a GitHub workflow run. +- For GitLab: a cicd_task is a GitLab job run of a GitLab pipeline run. +- For Jenkins: a cicd_task is a subtask of a Jenkins build. If a build does not have subtask(s), then the build will also be saved as a cicd_task in this table. +- For Bamboo CI: a cicd_task is a Bamboo job build in a Bamboo plan build. + +| **field** | **type** | **length** | **description** | **key** | +|:----------------------|:---------|:-----------|:-------------------------------------------------------------------------------------------------------------------------------------|:------------------| +| `id` | varchar | 255 | This key is generated based on details from the original plugin | PK | +| `name` | varchar | 255 | | | +| `pipeline_id` | varchar | 255 | The id of the cicd_pipeline it belongs to | | +| `result` | varchar | 100 | The result of the task. It will be standardized to 'SUCCESS', 'FAILURE', '' in DevLake based on each plugin's possible. | | +| `original_result` | varchar | 100 | The original_result of the task. Its value depends on the state of the corresponding entity in the different plugins. | | +| `status` | varchar | 100 | The status of the task. It will be standardized to 'DONE', 'IN_PROGRESS', 'OTHER' in DevLake based on each plugin's possible states. | | +| `original_status` | varchar | 100 | The original_status of the task. Its value depends on the state of the corresponding entity in the different plugins. | | +| `type` | varchar | 100 | The value will be set to 'DEPLOYMENT' if it matched the regex configured in the Scope Config, otherwise it is an empty string. | | +| `environment` | varchar | 255 | The value will be set to 'PRODUCTION' if it matched the regex configured in the Scope Config, otherwise it is an empty string. | +| `duration_sec` | double | | How long does this task take | | +| `ququed_duration_sec` | double | | How long does this task take queuing | | +| `created_date` | datetime | 3 | The created time of the task. | | +| `queued_date` | datetime | 3 | The queued time of the task. | | +| `started_date` | datetime | 3 | When this task started | | +| `finished_date` | datetime | 3 | When this task finished | | | +| `cicd_scope_id` | longtext | | The id of cicd_scope this task belongs to | FK_cicd_scopes.id | + +#### cicd_deployments + +A cicd_deployment refers to a deployment at the project level. In the case where a pipeline run or build deploys across three distinct repositories, it will be categorized as ONE cicd_deployment while being recorded as THREE separate cicd_deployment_commits. +It may come from several sources: + +- Domain layer [cicd_pipelines](#cicd_pipelines), such as GitHub workflow runs, GitLab pipelines, Jenkins builds and BitBucket pipelines, etc. Deployments from cicd_pipelines will be transformed according to the regex configuration set in the Blueprint transformation before adding to this table. +- Tool layer deployments: in v0.20, only the BitBucket\Bamboo\GitLab and GitHub(Use GraphQL APIs) plugins collect the independent deployment entity which you can find in table.\_tool_bitbucket_deployments and \_tool_bamboo_deploy_builds, there will be more in the future. +- Deployments pushed directly from webhooks + +Additional Notes + +- CICD deployments are recorded at the project level, not the repository level. +- CICD deployment commits are individual commits that represent a single deployment across multiple repositories. + +| **field** | **type** | **length** | **description** | **key** | +|:----------------------|:---------|:-----------|:----------------------------------------------------------------------------------------------------------------------------|:------------------| +| `id` | varchar | 255 | The deployment_id of this deployment. The value will be set with `id` when it comes from webhooks. | PK | +| `cicd_scope_id` | varchar | 255 | The id of cicd_scope this deployment belongs to | FK_cicd_scopes.id | +| `name` | varchar | 255 | The name of the deployment | | +| `result` | varchar | 100 | The result of the deployment, enum. 'SUCCESS', 'FAILUR'E, '' | | +| `original_result` | varchar | 100 | The original_result of the deployment. Its value depends on the state of the corresponding entity in the different plugins. | | +| `status` | varchar | 100 | The status of this deployment, enum: 'IN_PROGRESS', 'DONE', 'OTHER' | | +| `original_status` | varchar | 100 | The original_status of the deployment. Its value depends on the state of the corresponding entity in the different plugins. | | +| `environment` | varchar | 255 | The environment to deploy, only 'PRODUCTION' deployment will appear in v0.17 | | +| `created_date` | datetime | 3 | The created time of the deployment. | | +| `queued_date` | datetime | 3 | The queued time of the deployment. | | +| `started_date` | datetime | 3 | The started time of the deployment. | | +| `finished_date` | datetime | 3 | The finished time of the deployment | | +| `duration_sec` | double | | The time this deployment takes | | +| `ququed_duration_sec` | double | | The time this deployment takes queuing | | + +#### cicd_deployment_commits + +A cicd_deployment_commit is a deployment in a specific repo. A deployment may come from several sources: + +- Domain layer [cicd_pipelines](#cicd_pipelines), such as GitHub workflow runs, GitLab pipelines, Jenkins builds and BitBucket pipelines, etc. Deployments from cicd_pipelines will be transformed according to the regex configuration set in the Blueprint transformation before adding to this table. +- Tool layer deployments: in v0.18, only the BitBucket and Bamboo plugins collect the independent deployment entity which you can find in table.\_tool_bitbucket_deployments and \_tool_bamboo_deploy_builds, but there will be more in the future. +- Deployments pushed directly from webhooks + +You can query deployments from this table by `SELECT DISTINCT cicd_deployment_id FROM cicd_deployments_commits`. + +Normally, one deployment only deploy to one repo. But in some cases, one deployment may deploy in multiple repos with different commits. In these cases, there will be multiple pairs of deployment-commit-repo, appeared in multiple entries in this table. + +| **field** | **type** | **length** | **description** | **key** | +|:------------------------------------|:---------|:-----------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------| +| `id` | varchar | 255 | This key is the combination of the deployment's id and repo_url, e.g.
- from a GitHub workflow run: github:GithubRun:1:384111310:3521097091:https://github.com/apache/incubator-devlake
- from a Jenkins build, jenkins:JenkinsBuild:1:deploy#7:https://github.com/apache/incubator-devlake
- from a webhook, webhook:1:90489d3951711d72:e6bde456807818c5c78d7b265964d6d48b653af6 | PK | +| `cicd_scope_id` | varchar | 255 | The id of cicd_scope this deployment_commit belongs to | FK_cicd_scopes.id | +| `cicd_deployment_id` | varchar | 255 | The deployment_id of this deployment_commit. The value will be set with `id` when it comes from webhooks. | | +| `name` | varchar | 255 | The name of the deployment | | +| `result` | varchar | 100 | The result of the deployment, enum: 'SUCCESS', 'FAILURE', '' | | +| `original_result` | varchar | 100 | The original_result of the deployment. Its value depends on the state of the corresponding entity in the different plugins. | | +| `status` | varchar | 100 | The status of this deployment, enum: 'IN_PROGRESS', 'DONE', 'OTHER' | | +| `original_status` | varchar | 100 | The original_status of the deployment. Its value depends on the state of the corresponding entity in the different plugins. | | +| `environment` | varchar | 255 | The environment to deploy | | +| `created_date` | datetime | 3 | The created time of the deployment. | | +| `queued_date` | datetime | 3 | The queued time of the deployment. | | +| `started_date` | datetime | 3 | The started time of the deployment. | | +| `finished_date` | datetime | 3 | The finished time of the deployment | | +| `duration_sec` | double | | The time this deployment takes | | +| `queued_duration_sec` | double | | The time this deployment takes queueing | | +| `commit_sha` | char | 40 | The commit sha that triggers the deployment | | +| `ref_name` | varchar | 255 | The ref (branch/tag) name of the commit | | +| `repo_id` | varchar | 255 | - | | +| `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). | | + +### Domain 5 - Code Quality + +The names of tables in the 'Code Quality' domain will start with a prefix cq\_ + +#### cq_projects + +| **field** | **type** | **length** | **description** | **key** | +|:---------------------|:---------|:-----------|:------------------------------------------------------------------------------------|:--------| +| `id` | varchar | 255 | This key is generated based on details from the original plugin | PK | +| `name` | varchar | 255 | The name of the project in SonarQube | | +| `qualifier` | varchar | 255 | The type of project. Examples include "TRK" for regular projects and "VW" for views | | +| `visibility` | varchar | 64 | The visibility of the project. Examples include "public" and "private" | | +| `last_analysis_date` | datatime | 3 | The date and time of the most recent analysis of the project | | +| `commit_sha` | varchar | 128 | It represents the version number or code version identifier of a project | | + +#### cq_issues + +| **field** | **type** | **length** | **description** | **key** | +|:----------------------------|:---------|:-----------|:------------------------------------------------------------------------|:--------| +| `id` | varchar | 255 | This key is generated based on details from the original plugin | PK | +| `rule` | varchar | 255 | The key of the rule that the issue is violating | | +| `severity` | varchar | 255 | The severity level of the issue | | +| `component` | varchar | 255 | The name of the component where the issue was found | | +| `project_key` | varchar | 255 | The key of the project that the issue belongs to | | +| `line` | bigint | | The line number where the issue was found | | +| `status` | varchar | 255 | The status of the issue | | +| `message` | longtext | | The message associated with the issue | | +| `debt` | bigint | | The estimated time required to fix the issue | | +| `effort` | bigint | | The effort required to fix the issue | | +| `commit_author_email` | varchar | 255 | The email address of the author of the commit that introduced the issue | | +| `assignee` | varchar | 255 | The person assigned to fix the issue | | +| `hash` | varchar | 255 | A hash code for the issue | | +| `tags` | varchar | 255 | Any tags associated with the issue | | +| `type` | varchar | 255 | The type of the issue | | +| `scope` | varchar | 128 | The scope of the issue | | +| `start_line` | bigint | 255 | The starting line of the issue | | +| `end_line` | bigint | 255 | The ending line of the issue | | +| `start_offset` | bigint | 255 | The starting offset of the issue | | +| `end_offset` | bigint | 255 | The ending offset of the issue | | +| `vulnerability_probability` | varchar | 100 | The probability of the issue being a vulnerability | | +| `security_category` | varchar | 100 | The security category of the issue | | +| `created_date` | datetime | 3 | The time when the issue was created | | +| `updated_date` | datetime | 3 | The time when the issue was last updated | | + +#### cq_issue_code_blocks + +| **field** | **type** | **length** | **description** | **key** | +|:---------------|:---------|:-----------|:--------------------------------------------------------------------------------------|:--------| +| `id` | varchar | 255 | This key is generated based on details from the original plugin | PK | +| `issue_key` | varchar | 255 | A string that stores the key of the issue that the code block is associated with | | +| `component` | varchar | 255 | A string that stores the name of the component that the code block is associated with | | +| `start_line` | bigint | 255 | An integer that stores the line number where the code block starts | | +| `end_line` | bigint | 255 | An integer that stores the line number where the code block ends | | +| `start_offset` | bigint | 255 | An integer that stores the offset where the code block starts | | +| `end_offset` | bigint | 255 | An integer that stores the offset where the code block ends | | +| `msg` | longtext | | A long text field that stores the message associated with the code block | | + +#### cq_file_metrics + +| **field** | **type** | **length** | **description** | **key** | +|:-------------------------------------------|:---------|:-----------|:----------------------------------------------------------------|:--------| +| `id` | varchar | 255 | This key is generated based on details from the original plugin | PK | +| `project_key` | varchar | 255 | The key of the project that the issue belongs to | PK | +| `file_name` | longtext | | longtext fields that store the name of the file | | +| `file_path` | longtext | | longtext fields that store the path of the file | | +| `file_language` | longtext | | longtext fields that store the language of the file | | +| `code_smells` | bigint | | Code smells of this file | | +| `sqale_index` | bigint | | Sqale index of the file | | +| `sqale_rating` | double | | Sqale rating of the file | | +| `bugs` | bigint | | Bugs rating of the file | | +| `reliability_rating` | longtext | | Reliability rating of the file | | +| `vulnerabilities` | bigint | | Vulnerabilities of the file | | +| `security_rating` | longtext | | Security rating of the file | | +| `security_hotspots` | bigint | | Security hotspots of the file | | +| `security_hotspots_reviewed` | double | | Security hotspots reviewed of the file | | +| `security_review_rating` | longtext | | Security review rating of the file | | +| `ncloc` | bigint | | Ncloc of the file | | +| `coverage` | double | | Ncoverage of the file | | +| `lines_to_cover` | bigint | | Lines to cover of the file | | +| `duplicated_lines_density` | double | | Duplicated lines density of the file | | +| `duplicated_blocks` | bigint | | Duplicated blocks of the file | | +| `duplicated_files` | bigint | | Duplicated files of the file | | +| `duplicated_lines` | bigint | | Duplicated lines of the file | | +| `effort_to_reach_maintainability_rating_a` | bigint | | Effort to reach maintainability rating a of the file | | +| `complexity` | bigint | | Complexity of the file | | +| `cognitive_complexity` | bigint | | Cognitive complexity of the file | | +| `num_of_lines` | bigint | | Num of lines of the file | | + +### Domain 6 - Cross-Domain Entities + +These entities are used to map entities between different domains. They are the key players to break data isolation. + +There are low-level entities such as issue_commits, users, and higher-level cross domain entities such as board_repos + +#### issue_commits + +A low-level mapping between "issue tracking" and "source code management" domain by mapping `issues` and `commits`. Issue(n): Commit(n). + +The original connection between these two entities lies in either issue tracking tools like Jira or source code management tools like GitLab. You have to use tools to accomplish this. + +For example, a common method to connect Jira issue and GitLab commit is a GitLab plugin [Jira Integration](https://docs.gitlab.com/ee/integration/jira/). With this plugin, the Jira issue key in the commit message written by the committers will be parsed. Then, the plugin will add the commit urls under this jira issue. Hence, DevLake's [Jira plugin](https://github.com/apache/incubator-devlake/tree/main/backend/plugins/jira) can get the related commits (including repo, commit_id, url) of an issue. + +| **field** | **type** | **length** | **description** | **key** | +|:-------------|:---------|:-----------|:----------------|:---------------| +| `issue_id` | varchar | 255 | Issue id | FK_issues.id | +| `commit_sha` | char | 40 | Commit sha | FK_commits.sha | + +#### pull_request_issues + +This table shows the issues closed by pull requests. It's a medium-level mapping between "issue tracking" and "source code management" domain by mapping issues and commits. Issue(n): Commit(n). + +The data is extracted from the body of pull requests conforming to certain regular expression. The regular expression can be defined in GITHUB_PR_BODY_CLOSE_PATTERN in the .env file + +| **field** | **type** | **length** | **description** | **key** | +|:----------------------|:---------|:-----------|:-----------------|:--------------------| +| `pull_request_id` | varchar | 255 | Pull request id | FK_pull_requests.id | +| `issue_id` | varchar | 255 | Issue id | FK_issues.id | +| `pull_request_number` | varchar | 255 | Pull request key | | +| `issue_number` | varchar | 255 | Issue key | | + +#### board_repos (Deprecated) + +A way to link "issue tracking" and "source code management" domain by mapping `boards` and `repos`. Board(n): Repo(n). + +| **field** | **type** | **length** | **description** | **key** | +|:-----------|:---------|:-----------|:----------------|:-------------| +| `board_id` | varchar | 255 | Board id | FK_boards.id | +| `repo_id` | varchar | 255 | Repo id | FK_repos.id | + +#### accounts + +This table stores of user accounts across different tools such as GitHub, Jira, GitLab, etc. This table can be joined to get the metadata of all accounts. +metrics, such as _'No. of Issue closed by contributor', 'No. of commits by contributor',_ + +| **field** | **type** | **length** | **description** | **key** | +|:---------------|:---------|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------| +| `id` | varchar | 255 | An account's `id` is the identifier of the account of a specific tool. It is composed of "< Plugin >:< Entity >:< PK0 >[:PK1]..."
For example, a Github account's id is composed of "< github >:< GithubAccounts >:< GithubUserId >)". E.g. 'github:GithubUsers:14050754' | PK | +| `email` | varchar | 255 | Email of the account | | +| `full_name` | varchar | 255 | Full name | | +| `user_name` | varchar | 255 | Username, nickname or Github login of an account | | +| `avatar_url` | varchar | 255 | | | +| `organization` | varchar | 255 | User's organization(s) | | +| `created_date` | datetime | 3 | User creation time | | +| `status` | int | | 0: default, the user is active. 1: the user is not active | | + +#### users + +| **field** | **type** | **length** | **description** | **key** | +|-----------|----------|------------|-------------------------------|---------| +| `id` | varchar | 255 | id of a person | PK | +| `email` | varchar | 255 | the primary email of a person | | +| `name` | varchar | 255 | name of a person | | + +#### user_accounts + +| **field** | **type** | **length** | **description** | **key** | +|--------------|----------|------------|-----------------|------------------| +| `user_id` | varchar | 255 | users.id | Composite PK, FK | +| `account_id` | varchar | 255 | accounts.id | Composite PK, FK | + +#### teams + +| **field** | **type** | **length** | **description** | **key** | +|-----------------|----------|------------|----------------------------------------------------|---------| +| `id` | varchar | 255 | id from the data sources, decided by DevLake users | PK | +| `name` | varchar | 255 | name of the team. E.g. team A, team B, etc. | | +| `alias` | varchar | 255 | alias or abbreviation of a team | | +| `parent_id` | varchar | 255 | teams.id, default to null | FK | +| `sorting_index` | int | 255 | the field to sort team | | + +#### team_users + +| **field** | **type** | **length** | **description** | **key** | +|-----------|----------|------------|--------------------------------------------------|------------------| +| `team_id` | varchar | 255 | Full name of the team. E.g. team A, team B, etc. | Composite PK, FK | +| `user_id` | varchar | 255 | users.id | Composite PK, FK | + +#### project + +| **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 | | + +#### 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 | | + +#### 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 | + +#### project_pr_metrics + +| **field** | **type** | **length** | **description** | **key** | +|:-------------------|:---------|:-----------|:---------------------------------------------------------------------------------------|:--------| +| `id` | varchar | 255 | Id of PR | PK | +| `project_name` | varchar | 100 | The project that this PR belongs to | PK | +| `first_review_id` | longtext | | The id of the first review on this pr | | +| `first_commit_sha` | longtext | | The sha of the first commit | | +| `pr_coding_time` | bigint | | The time it takes from the first commit until a PR is issued | | +| `pr_pickup_time` | bigint | | The time it takes from when a PR is issued until the first comment is added to that PR | | +| `pr_review_time` | bigint | | The time it takes to complete a code review of a PR before it gets merged | | +| `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 | | + +#### project_issue_metrics + +| **field** | **type** | **length** | **description** | **key** | +|:----------------|:---------|:-----------|:--------------------------------------------|:--------| +| `id` | varchar | 255 | Id of Issue | PK | +| `project_name` | varchar | 100 | The project that this Issue belongs to | PK | +| `deployment_id` | longtext | | The id of cicd_task which cause an incident | | + +#### refs_issues_diffs + +This table shows the issues fixed by commits added in a new ref compared to an old one. The data is computed from [table.commits_diffs](#commits_diffs), [table.pull_requests](#pull_requests), [table.pull_request_commits](#pull_request_commits), and [table.pull_request_issues](#pull_request_issues). + +This table can support tag-based analysis, for instance, '_No. of bugs closed in a tag_'. + +| **field** | **type** | **length** | **description** | **key** | +|:---------------------|:---------|:-----------|:-------------------------------------------------------|:-------------| +| `new_ref_id` | varchar | 255 | The new ref's id for comparison | FK_refs.id | +| `old_ref_id` | varchar | 255 | The old ref's id for comparison | FK_refs.id | +| `new_ref_commit_sha` | char | 40 | The commit new ref points to at the time of collection | | +| `old_ref_commit_sha` | char | 40 | The commit old ref points to at the time of collection | | +| `issue_number` | varchar | 255 | Issue number | | +| `issue_id` | varchar | 255 | Issue id | FK_issues.id | + +
+ +## Get Domain Layer Models in Developer Mode + +When developing a new plugin, you need to refer to domain layer models, as all raw data should be transformed to domain layer data to provide standardized metrics across tools. Please use the following method to access the domain data models. + +```golang +import "github.com/apache/incubator-devlake/models/domainlayer/domaininfo" + +domaininfo := domaininfo.GetDomainTablesInfo() +for _, table := range domaininfo { +// do something +} +``` + +If you want to learn more about plugin models, please visit [PluginImplementation](https://devlake.apache.org/docs/DeveloperManuals/PluginImplementation) diff --git a/versioned_docs/version-v0.21/DataModels/RawLayerSchema.md b/versioned_docs/version-v0.21/DataModels/RawLayerSchema.md new file mode 100644 index 00000000000..e2336e5ca20 --- /dev/null +++ b/versioned_docs/version-v0.21/DataModels/RawLayerSchema.md @@ -0,0 +1,29 @@ +--- +title: "Raw Layer Schema" +description: > + Caches raw API responses from data source plugins +sidebar_position: 3 +--- + +## Summary + +This document describes Apache DevLake's raw layer schema. + +Referring to DevLake's [architecture](../Overview/Architecture.md), the raw layer stores the API responses from data sources (DevOps tools) in JSON. This saves developers' time if the raw data is to be transformed differently later on. Please note that communicating with data sources' APIs is usually the most time-consuming step. + + +## Use Cases + +1. As a user, you can check raw data tables to verify data quality if you have concerns about the [domain layer data](DevLakeDomainLayerSchema.md). +2. As a developer, you can customize domain layer schema based on raw data tables via [customize](Plugins/customize.md). + + +## Data Models + +Raw layer tables start with a prefix `_raw_`. Each plugin contains multiple raw data tables, the naming convension of these tables is `_raw_{plugin}_{entity}`. For instance, +- _raw_jira_issues +- _raw_jira_boards +- _raw_jira_board_issues +- ... + +Normally, you do not need to use these tables, unless you have one of the above use cases. diff --git a/versioned_docs/version-v0.21/DataModels/SystemTables.md b/versioned_docs/version-v0.21/DataModels/SystemTables.md new file mode 100644 index 00000000000..6fea769add1 --- /dev/null +++ b/versioned_docs/version-v0.21/DataModels/SystemTables.md @@ -0,0 +1,28 @@ +--- +title: "System Tables" +description: > + Stores DevLake's own entities +sidebar_position: 4 +--- + +## Summary + +This document describes Apache DevLake's data models of its own entities. These tables are used and managed by the Devlake framework. + + +## Use Cases + +1. As a user, you can check `_devlake_blueprints` and `_devlake_pipelines` when failing to collect data via DevLake's blueprint. +2. As a contributor, you can check these tables to debug task concurrency or data migration features. + + +## Data Models + +These tables start with a prefix `_devlake`. Unlike raw or tool data tables, DevLake only contains one set of system tables. The naming convension of these tables is `_raw_{plugin}_{entity}`, such as +- _devlake_blueprints +- _devlake_pipelines +- _devlake_tasks +- _devlake_subtasks +- ... + +Normally, you do not need to use these tables, unless you have one of the above use cases. diff --git a/versioned_docs/version-v0.21/DataModels/ToolLayerSchema.md b/versioned_docs/version-v0.21/DataModels/ToolLayerSchema.md new file mode 100644 index 00000000000..9d846e5d3b5 --- /dev/null +++ b/versioned_docs/version-v0.21/DataModels/ToolLayerSchema.md @@ -0,0 +1,28 @@ +--- +title: "Tool Layer Schema" +description: > + Extract raw data into a relational schema for each specific tool +sidebar_position: 2 +--- + +## Summary + +This document describes Apache DevLake's tool layer schema. + +Referring to DevLake's [architecture](../Overview/Architecture.md), the Tool layer extracts raw data from JSONs into a relational schema that's easier to consume by analytical tasks. Each DevOps tool would have a schema that's tailored to its data structure, hence the name, the Tool layer. + + +## Use Cases + +As a user, you can check tool data tables to verify data quality if you have concerns about the [domain layer data](DevLakeDomainLayerSchema.md). + + +## Data Models + +Tool layer tables start with a prefix `_tool_`. Each plugin contains multiple tool data tables, the naming convension of these tables is `_tool_{plugin}_{entity}`. For instance, +- _tool_jira_issues +- _tool_jira_boards +- _tool_jira_board_issues` +- ... + +Normally, you do not need to use tool layer tables, unless you have one of the above use cases. diff --git a/versioned_docs/version-v0.21/DataModels/_category_.json b/versioned_docs/version-v0.21/DataModels/_category_.json new file mode 100644 index 00000000000..ae28c626ea0 --- /dev/null +++ b/versioned_docs/version-v0.21/DataModels/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Data Models", + "position": 6, + "link":{ + "type": "generated-index", + "slug": "DataModels" + } +} diff --git a/versioned_docs/version-v0.21/DeveloperManuals/DBMigration.md b/versioned_docs/version-v0.21/DeveloperManuals/DBMigration.md new file mode 100644 index 00000000000..9072902edb8 --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/DBMigration.md @@ -0,0 +1,90 @@ +--- +title: "DB Migration" +description: > + DB Migration +sidebar_position: 3 +--- + +## Summary +Starting in v0.10.0, DevLake provides a lightweight migration tool for executing migration scripts. +Both the framework and the plugins can define their migration scripts in their own migration folder. +The migration scripts are written with gorm in Golang to support different SQL dialects. + + +## Migration Scripts +The migration scripts describe how to do database migration and implement the `MigrationScript` interface. +When DevLake starts, the scripts register themselves to the framework by invoking the `Register` function. +The method `Up` contains the steps of migration. + +```go +type MigrationScript interface { + // this function will contain the business logic of the migration (e.g. DDL logic) + Up(basicRes BasicRes) errors.Error + // the version number of the migration. typically in date format (YYYYMMDDHHMMSS), e.g. 20220728000001. Migrations are executed sequentially based on this number. + Version() uint64 + // The name of this migration + Name() string +} +``` + +## The Migration Model + +For each migration, we define a "snapshot" datamodel of the model that we wish to perform the migration on. +The fields on this model shall be identical to the actual model; but unlike the actual one, this one will +never change in the future. The naming convention of these models is `YYYYMMDD` and they must implement +the `func TableName() string` method, and consumed by the `Script::Up` method. + +## Table `migration_history` + +The table tracks migration scripts execution and schemas changes, and from which, DevLake can figure out the current state of database schemas. + +## Execution + +Each plugin has a `migrationscripts` subpackage that lists all the migrations to be executed for that plugin. You +will need to add your migration to that list for the framework to pick it up. Similarly, there is a package +for the framework-only migrations defined under the `models` package. + + +## How It Works +1. Check `migration_history` table, calculate all the migration scripts need to be executed. +2. Sort scripts by `Version` and `Name` in ascending order. Please do NOT change these two values for the script after release for any reasons; otherwise, users may fail to upgrade due to the duplicated execution. +3. Execute the scripts. +4. Save the results in the `migration_history` table. + + +## Best Practices + +When you write a new migration script, please pay attention to the fault tolerance and the side effect. It would be better if the failed script could be safely retried, in case if something goes wrong during the migration. For this purpose, the migration scripts should be well-designed. For example, if you have created a temporary table in the Up method, it should be dropped before exiting, regardless of success or failure. + +Suppose we want to change the type of the Primary Key `name` of table `users` from `int` to `varchar(255)` + +1. Rename `users` to `users_20221018` (stop if error, otherwise define a `defer` to rename back on error) +2. Create new `users` (stop if error, otherwise define a `defer` to drop the table on error) +3. Convert data from `users_20221018` to `users` (stop if error) +4. Drop table `users_20221018` + +With these steps, the `defer` functions would be executed in reverse order if any error occurred during the migration process so the database would roll back to the original state in most cases. + +However, you don't neccessary deal with all the mess. We had summarized some of the most useful code examples for you to follow: + +- [Create new tables]https://github.com/apache/incubator-devlake/blob/main/backend/core/models/migrationscripts/20220406_add_frame_tables.go) +[Rename column](https://github.com/apache/incubator-devlake/blob/main/backend/core/models/migrationscripts/20220505_rename_pipeline_step_to_stage.go) +- [Add columns with default value](https://github.com/apache/incubator-devlake/blob/main/backend/core/models/migrationscripts/20220616_add_blueprint_mode.go) +- [Change the values(or type) of Primary Key](https://github.com/apache/incubator-devlake/blob/main/backend/core/models/migrationscripts/20220913_fix_commitfile_id_toolong.go) +- [Change the values(or type) of Column](https://github.com/apache/incubator-devlake/blob/main/backend/core/models/migrationscripts/20220903_encrypt_blueprint.go) + +The above examples should cover most of the scenarios you may encounter. If you come across other scenarios, feel free to create issues in our GitHub Issue Tracker for discussions. + + +In order to help others understand the script you have written, there are a couple of rules we suggest to follow: + +- Name your script in a meaningful way. For instance, `renamePipelineStepToStage` is more descriptive than `modifyPipelines`. +- The script should keep only the targeted `fields` you are attempting to operate except when using `migrationhelper.Transform`, which is a full table tranformation that requires full table definition. If this is the case, add comment to the end of the fields to indicate which ones are the targets. +- Add comments to the script when the operation is too complicated to be expressed in plain code. + +Other rules to follow when writing a migration script: + +- The migration script should only use the interfaces and packages offered by the framework like `core`, `errors` and `migrationhelper`. Do NOT import `gorm` or package from `plugin` directly. +- The name of `model struct` defined in your script should be suffixed with the `Version` of the script to distinguish from other scripts in the same package to keep it self-contained, i.e. `tasks20221018`. Do NOT refer `struct` defined in other scripts. +- All scripts and models names should be `camelCase` to avoid accidental reference from other packages. + diff --git a/versioned_docs/version-v0.21/DeveloperManuals/Dal.md b/versioned_docs/version-v0.21/DeveloperManuals/Dal.md new file mode 100644 index 00000000000..3e1d397e5ef --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/Dal.md @@ -0,0 +1,173 @@ +--- +title: "Dal" +sidebar_position: 5 +description: > + The Dal (Data Access Layer) is designed to decouple the hard dependency on `gorm` in v0.12 +--- + +## Summary + +The Dal (Data Access Layer) is designed to decouple the hard dependency on `gorm` in v0.12. The advantages of introducing this isolation are: + + - Unit Test: Mocking an Interface is easier and more reliable than Patching a Pointer. + - Clean Code: DBS operations are more consistence than using `gorm ` directly. + - Replaceable: It would be easier to replace `gorm` in the future if needed. + +## The Dal Interface + +```go +type Dal interface { + AutoMigrate(entity interface{}, clauses ...Clause) error + Exec(query string, params ...interface{}) error + RawCursor(query string, params ...interface{}) (*sql.Rows, error) + Cursor(clauses ...Clause) (*sql.Rows, error) + Fetch(cursor *sql.Rows, dst interface{}) error + All(dst interface{}, clauses ...Clause) error + First(dst interface{}, clauses ...Clause) error + Count(clauses ...Clause) (int64, error) + Pluck(column string, dest interface{}, clauses ...Clause) error + Create(entity interface{}, clauses ...Clause) error + Update(entity interface{}, clauses ...Clause) error + CreateOrUpdate(entity interface{}, clauses ...Clause) error + CreateIfNotExist(entity interface{}, clauses ...Clause) error + Delete(entity interface{}, clauses ...Clause) error + AllTables() ([]string, error) +} +``` + + +## How to use + +### Query +```go +// Get a database cursor +user := &models.User{} +cursor, err := db.Cursor( + dal.From(user), + dal.Where("department = ?", "R&D"), + dal.Orderby("id DESC"), +) +if err != nil { + return err +} +for cursor.Next() { + err = dal.Fetch(cursor, user) // fetch one record at a time + ... +} + +// Get a database cursor by raw sql query +cursor, err := db.Raw("SELECT * FROM users") + +// USE WITH CAUTIOUS: loading a big table at once is slow and dangerous +// Load all records from database at once. +users := make([]models.Users, 0) +err := db.All(&users, dal.Where("department = ?", "R&D")) + +// Load a column as Scalar or Slice +var email string +err := db.Pluck("email", &username, dal.Where("id = ?", 1)) +var emails []string +err := db.Pluck("email", &emails) + +// Execute query +err := db.Exec("UPDATE users SET department = ? WHERE department = ?", "Research & Development", "R&D") +``` + +### Insert +```go +err := db.Create(&models.User{ + Email: "hello@example.com", // assuming this the Primarykey + Name: "hello", + Department: "R&D", +}) +``` + +### Update +```go +err := db.Create(&models.User{ + Email: "hello@example.com", // assuming this the Primarykey + Name: "hello", + Department: "R&D", +}) +``` +### Insert or Update +```go +err := db.CreateOrUpdate(&models.User{ + Email: "hello@example.com", // assuming this is the Primarykey + Name: "hello", + Department: "R&D", +}) +``` + +### Insert if record(by PrimaryKey) didn't exist +```go +err := db.CreateIfNotExist(&models.User{ + Email: "hello@example.com", // assuming this is the Primarykey + Name: "hello", + Department: "R&D", +}) +``` + +### Delete +```go +err := db.CreateIfNotExist(&models.User{ + Email: "hello@example.com", // assuming this is the Primary key +}) +``` + +### DDL and others +```go +// Returns all table names +allTables, err := db.AllTables() + +// Automigrate: create/add missing table/columns +// Note: it won't delete any existing columns, nor does it update the column definition +err := db.AutoMigrate(&models.User{}) +``` + +## How to do Unit Test +First, run the command `make mock` to generate the Mocking Stubs, the generated source files should appear in `mocks` folder. +``` +mocks +├── ApiResourceHandler.go +├── AsyncResponseHandler.go +├── BasicRes.go +├── CloseablePluginTask.go +├── ConfigGetter.go +├── Dal.go +├── DataConvertHandler.go +├── ExecContext.go +├── InjectConfigGetter.go +├── InjectLogger.go +├── Iterator.go +├── Logger.go +├── Migratable.go +├── PluginApi.go +├── PluginBlueprintV100.go +├── PluginInit.go +├── PluginMeta.go +├── PluginTask.go +├── RateLimitedApiClient.go +├── SubTaskContext.go +├── SubTaskEntryPoint.go +├── SubTask.go +└── TaskContext.go +``` +With these Mocking stubs, you may start writing your TestCases using the `mocks.Dal`. +```go +import "github.com/apache/incubator-devlake/mocks" + +func TestCreateUser(t *testing.T) { + mockDal := new(mocks.Dal) + mockDal.On("Create", mock.Anything, mock.Anything).Return(nil).Once() + userService := &services.UserService{ + Dal: mockDal, + } + userService.Post(map[string]interface{}{ + "email": "helle@example.com", + "name": "hello", + "department": "R&D", + }) + mockDal.AssertExpectations(t) +``` + diff --git a/versioned_docs/version-v0.21/DeveloperManuals/DeveloperSetup.md b/versioned_docs/version-v0.21/DeveloperManuals/DeveloperSetup.md new file mode 100644 index 00000000000..18b864288e9 --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/DeveloperSetup.md @@ -0,0 +1,130 @@ +--- +title: "Developer Setup" +description: > + The steps to install DevLake in developer mode. +sidebar_position: 1 +--- + + +## Requirements + +- Docker v19.03.10+ +- Golang v1.19+ +- GNU Make + - Mac (Preinstalled) + - Windows: [Download](http://gnuwin32.sourceforge.net/packages/make.htm) + - Ubuntu: `sudo apt-get install build-essential libssl-dev` + +## How to setup dev environment + +The following guide will walk through how to run DevLake's frontend (`config-ui`) and backend in dev mode. + + +1. Navigate to where you would like to install this project and clone the repository: + + ```sh + git clone https://github.com/apache/incubator-devlake.git + cd incubator-devlake + ``` + +2. Install dependencies for plugins: + + - [RefDiff](../Plugins/refdiff.md#development) + +3. Install Go packages + + ```sh + cd backend + go get + cd .. + ``` + +4. Copy the sample config file to new local file: + + ```sh + cp env.example .env + ``` + +5. Update the following variables in the file `.env`: + + * `DB_URL`: Replace `mysql:3306` with `127.0.0.1:3306` + +6. Start the MySQL and Grafana containers: + + > Make sure the Docker daemon is running before this step. + + ```sh + docker-compose -f docker-compose-dev.yml up -d mysql grafana + ``` + +7. Run `devlake` and `config-ui` in dev mode in two separate terminals: + + ```sh + # specify the plugins that you need for both backend and frontend + export DEVLAKE_PLUGINS=bamboo,bitbucket,circleci,customize,dora,gitextractor,github,github_graphql,gitlab,jenkins,jira,org,pagerduty,refdiff,slack,sonarqube,trello,webhook + # run devlake + make dev + # run config-ui + make configure-dev + ``` + + For common errors, please see [Troubleshooting](#troubleshotting). + +8. Config UI is running at `localhost:4000` + - For how to use Config UI, please refer to our [tutorial](Configuration/Tutorial.md) + +## Running Tests + +```sh +# install mockery +go install github.com/vektra/mockery/v2@latest +# generate mocking stubs +make mock +# run tests +make test +``` + +## DB migrations + +Please refer to the [Migration Doc](../DeveloperManuals/DBMigration.md). + +## Using DevLake API + +All DevLake APIs (core service + plugin API) are documented with swagger. To see API doc live with swagger: + + - Install [swag](https://github.com/swaggo/swag). + - Run `make swag` to generate the swagger documentation. + - Visit `http://localhost:8080/swagger/index.html` while `devlake` is running. + + +## Developing dashboards + +To access Grafana, click *View Dashboards* button in the top left corner of Config UI, or visit `localhost:3002` (username: `admin`, password: `admin`). + +For provisioning, customizing, and creating dashboards, please refer to our [Grafana Doc](../Configuration/Dashboards/GrafanaUserGuide.md). + + +## Troubleshooting + + + Q: Running `make dev` yields error: `libgit2.so.1.3: cannot open share object file: No such file or directory` + + A: `libgit2.so.1.3` is required by the gitextractor plugin and should be . Make sure your program can find `libgit2.so.1.3`. `LD_LIBRARY_PATH` can be assigned like this if your `libgit2.so.1.3` is located at `/usr/local/lib`: + + ```sh + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib + ``` + + Note that the version has to be pinned to 1.3.0. If you don't have it, you may need to build it manually with CMake from [source](https://github.com/libgit2/libgit2/releases/tag/v1.3.0). + + +## Compiling + + - Compile all plugins: `make build-plugin` + - Compile specific plugins: `PLUGIN= make build-plugin` + - Compile server: `make build` + - Compile worker: `make build-worker` + +## 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. diff --git a/versioned_docs/version-v0.21/DeveloperManuals/E2E-Test-Guide.md b/versioned_docs/version-v0.21/DeveloperManuals/E2E-Test-Guide.md new file mode 100644 index 00000000000..e844d5fbb13 --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/E2E-Test-Guide.md @@ -0,0 +1,211 @@ +--- +title: "E2E Test Guide" +description: > + The steps to write E2E tests for plugins. +--- + +# How to write E2E tests for plugins + +## Why write E2E tests + +E2E testing, as a part of automated testing, generally refers to black-box testing at the file and module level or unit testing that allows the use of some external services such as databases. The purpose of writing E2E tests is to shield some internal implementation logic and see whether the same external input can output the same result in terms of data aspects. In addition, compared to the black-box integration tests, it can avoid some chance problems caused by network and other factors. More information about the plugin can be found here: Why write E2E tests (incomplete). +In DevLake, E2E testing consists of interface testing and input/output result validation for the plugin Extract/Convert subtask. This article only describes the process of writing the latter. As the Collectors invoke external +services we typically do not write E2E tests for them. + +## Preparing data + +Let's take a simple plugin - Feishu Meeting Hours Collection as an example here. Its directory structure looks like this. +![image](https://user-images.githubusercontent.com/3294100/175061114-53404aac-16ca-45d1-a0ab-3f61d84922ca.png) +Next, we will write the E2E tests of the sub-tasks. + +The first step in writing the E2E test is to run the Collect task of the corresponding plugin to complete the data collection; that is, to have the corresponding data saved in the table starting with `_raw_feishu_` in the database. +This data will be presumed to be the "source of truth" for our tests. Here are the logs and database tables using the DirectRun (cmd) run method. +``` +$ go run plugins/feishu/main.go --numOfDaysToCollect 2 --connectionId 1 (Note: command may change with version upgrade) +[2022-06-22 23:03:29] INFO failed to create dir logs: mkdir logs: file exists +press `c` to send cancel signal +[2022-06-22 23:03:29] INFO [feishu] start plugin +[2022-06-22 23:03:33] INFO [feishu] scheduler for api https://open.feishu.cn/open-apis/vc/v1 worker: 13, request: 10000, duration: 1h0m0s +[2022-06-22 23:03:33] INFO [feishu] total step: 2 +[2022-06-22 23:03:33] INFO [feishu] executing subtask collectMeetingTopUserItem +[2022-06-22 23:03:33] INFO [feishu] [collectMeetingTopUserItem] start api collection +[2022-06-22 23:03:34] INFO [feishu] [collectMeetingTopUserItem] finished records: 1 +[2022-06-22 23:03:34] INFO [feishu] [collectMeetingTopUserItem] end api collection error: %!w() +[2022-06-22 23:03:34] INFO [feishu] finished step: 1 / 2 +[2022-06-22 23:03:34] INFO [feishu] executing subtask extractMeetingTopUserItem +[2022-06-22 23:03:34] INFO [feishu] [extractMeetingTopUserItem] get data from _raw_feishu_meeting_top_user_item where params={"connectionId":1} and got 148 +[2022-06-22 23:03:34] INFO [feishu] [extractMeetingTopUserItem] finished records: 1 +[2022-06-22 23:03:34] INFO [feishu] finished step: 2 / 2 +``` + +image +Ok, the data has now been saved to the `_raw_feishu_*` table, and the `data` column is the return information from the plugin. Here we only collected data for the last 2 days. The data information is not much, but it also covers a variety of situations. That is, the same person has data on different days. + +It is also worth mentioning that the plugin runs two tasks, `collectMeetingTopUserItem` and `extractMeetingTopUserItem`. The former is the task of collecting, which is needed to run this time, and the latter is the task of extracting data. It doesn't matter whether the extractor runs in the prepared data session. + +Next, we need to export the data to .csv format. This step can be done in a variety of different ways - you can show your skills. I will only introduce a few common methods here. + +### DevLake Code Generator Export + +Run `go run generator/main.go create-e2e-raw` directly and follow the guidelines to complete the export. This solution is the simplest, but has some limitations, such as the exported fields being fixed. You can refer to the next solutions if you need more customisation options. + +![usage](https://user-images.githubusercontent.com/3294100/175849225-12af5251-6181-4cd9-ba72-26087b05ee73.gif) + +### GoLand Database export + +![image](https://user-images.githubusercontent.com/3294100/175067303-7e5e1c4d-2430-4eb5-ad00-e38d86bbd108.png) + +This solution is very easy to use and will not cause problems using Postgres or MySQL. +![image](https://user-images.githubusercontent.com/3294100/175068178-f1c1c290-e043-4672-b43e-54c4b954c685.png) +The success criteria for csv export is that the go program can read it without errors, so several points are worth noticing. + +1. the values in the csv file should be wrapped in double quotes to avoid special symbols such as commas in the values that break the csv format +2. double quotes in csv files are escaped. generally `""` represents a double quote +3. pay attention to whether the column `data` is the actual value, not the value after base64 or hex + +After exporting, move the .csv file to `plugins/feishu/e2e/raw_tables/_raw_feishu_meeting_top_user_item.csv`. + +### MySQL Select Into Outfile + +This is MySQL's solution for exporting query results to a file. The MySQL currently started in docker-compose-dev.yml comes with the --security parameter, so it does not allow `select ... into outfile`. The first step is to turn off the security parameter, which is done roughly as follows. +![origin_img_v2_c809c901-01bc-4ec9-b52a-ab4df24c376g](https://user-images.githubusercontent.com/3294100/175070770-9b7d5b75-574b-49ed-9bca-e9f611f60795.jpg) +After closing it, use `select ... into outfile` to export the csv file. The export result is rough as follows. +![origin_img_v2_ccfdb260-668f-42b4-b249-6c2dd45816ag](https://user-images.githubusercontent.com/3294100/175070866-2204ae13-c058-4a16-bc20-93ab7c95f832.jpg) +Notice that the data field has extra hexsha fields, which need to be manually converted to literal quantities. + +### Vscode Database + +This is Vscode's solution for exporting query results to a file, but it is not easy to use. Here is the export result without any configuration changes +![origin_img_v2_c9eaadaa-afbc-4c06-85bc-e78235f7eb3g](https://user-images.githubusercontent.com/3294100/175071987-760c2537-240c-4314-bbd6-1a0cd85ddc0f.jpg) +However, it is obvious that the escape symbol does not conform to the csv specification, and the data is not successfully exported. After adjusting the configuration and manually replacing `\"` with `""`, we get the following result. +![image](https://user-images.githubusercontent.com/3294100/175072314-954c6794-3ebd-45bb-98e7-60ddbb5a7da9.png) +The data field of this file is encoded in base64, so it needs to be decoded manually to a literal amount before using it. + +### MySQL workbench + +This tool must write the SQL yourself to complete the data export, which can be rewritten by imitating the following SQL. +```sql +SELECT id, params, CAST(`data` as char) as data, url, input,created_at FROM _raw_feishu_meeting_top_user_item; +``` +![image](https://user-images.githubusercontent.com/3294100/175080866-1631a601-cbe6-40c0-9d3a-d23ca3322a50.png) +Select csv as the save format and export it for use. + +### Postgres Copy with csv header + +`Copy(SQL statement) to '/var/lib/postgresql/data/raw.csv' with csv header;` is a common export method for PG to export csv, which can also be used here. +```sql +COPY ( +SELECT id, params, convert_from(data, 'utf-8') as data, url, input,created_at FROM _raw_feishu_meeting_top_user_item +) to '/var/lib/postgresql/data/raw.csv' with csv header; +``` +Use the above statement to complete the export of the file. If pg runs in docker, just use the command `docker cp` to export the file to the host. + +## Writing E2E tests + +First, create a test environment. For example, let's create `meeting_test.go`. +![image](https://user-images.githubusercontent.com/3294100/175091380-424974b9-15f3-457b-af5c-03d3b5d17e73.png) +Then enter the test preparation code in it as follows. The code is to create an instance of the `feishu` plugin and then call `ImportCsvIntoRawTable` to import the data from the csv file into the `_raw_feishu_meeting_top_user_item` table. + +```go +func TestMeetingDataFlow(t *testing.T) { + var plugin impl.Feishu + dataflowTester := e2ehelper.NewDataFlowTester(t, "feishu", plugin) + + // import raw data table + dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_feishu_meeting_top_user_item.csv", "_raw_feishu_meeting_top_user_item") +} +``` +The signature of the import function is as follows. +```func (t *DataFlowTester) ImportCsvIntoRawTable(csvRelPath string, rawTableName string)``` +It has a twin, with only slight differences in parameters. +```func (t *DataFlowTester) ImportCsvIntoTabler(csvRelPath string, dst schema.Tabler)``` +The former is used to import tables in the raw layer. The latter is used to import arbitrary tables. +**Note:** These two functions will delete the db table and use `gorm.AutoMigrate` to re-create a new table to clear data in it. +After importing the data is complete, run this tester and it must be PASS without any test logic at this moment. Then write the logic for calling the call to the extractor task in `TestMeetingDataFlow`. + +```go +func TestMeetingDataFlow(t *testing.T) { + var plugin impl.Feishu + dataflowTester := e2ehelper.NewDataFlowTester(t, "feishu", plugin) + + taskData := &tasks.FeishuTaskData{ + Options: &tasks.FeishuOptions{ + ConnectionId: 1, + }, + } + + // import raw data table + dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_feishu_meeting_top_user_item.csv", "_raw_feishu_meeting_top_user_item") + + // verify extraction + dataflowTester.FlushTabler(&models.FeishuMeetingTopUserItem{}) + dataflowTester.Subtask(tasks.ExtractMeetingTopUserItemMeta, taskData) + +} +``` +The added code includes a call to `dataflowTester.FlushTabler` to clear the table `_tool_feishu_meeting_top_user_items` and a call to `dataflowTester.Subtask` to simulate the running of the subtask `ExtractMeetingTopUserItemMeta`. + +Now run it and see if the subtask `ExtractMeetingTopUserItemMeta` completes without errors. The data results of the `extract` run generally come from the raw table, so the plugin subtask will run correctly if written without errors. We can observe if the data is successfully parsed in the db table in the tool layer. In this case the `_tool_feishu_meeting_top_user_items` table has the correct data. + +If the run is incorrect, maybe you can troubleshoot the problem with the plugin itself before moving on to the next step. + +## Verify that the results of the task are correct + +Let's continue writing the test and add the following code at the end of the test function +```go +func TestMeetingDataFlow(t *testing.T) { + ...... + + dataflowTester.VerifyTable( + models.FeishuMeetingTopUserItem{}, + "./snapshot_tables/_tool_feishu_meeting_top_user_items.csv", + []string{ + "meeting_count", + "meeting_duration", + "user_type", + "_raw_data_params", + "_raw_data_table", + "_raw_data_id", + "_raw_data_remark", + }, + ) +} +``` +Its purpose is to call `dataflowTester.VerifyTable` to complete the validation of the data results. The third parameter is all the fields of the table that need to be verified. +The data used for validation exists in `. /snapshot_tables/_tool_feishu_meeting_top_user_items.csv`, but of course, this file does not exist yet. + +There is a twin, more generalized function, that could be used instead: +```go +dataflowTester.VerifyTableWithOptions(models.FeishuMeetingTopUserItem{}, + dataflowTester.TableOptions{ + CSVRelPath: "./snapshot_tables/_tool_feishu_meeting_top_user_items.csv" + }, + ) + +``` +The above usage will be default to validating against all fields of the `models.FeishuMeetingTopUserItem` model. There are additional fields on `TableOptions` that can be specified to limit which fields on that model to perform validation on. + +To facilitate the generation of the file mentioned above, DevLake has adopted a testing technique called `Snapshot`, which will automatically generate the file based on the run results when the `VerifyTable` or `VerifyTableWithOptions` functions are called without the csv existing. + +But note! Please do two things after the snapshot is created: 1. check if the file is generated correctly 2. re-run it to make sure there are no errors between the generated results and the re-run results. +These two operations are critical and directly related to the quality of test writing. We should treat the snapshot file in `.csv` format like a code file. + +If there is a problem with this step, there are usually 2 ways to solve it. +1. The validated fields contain fields like create_at runtime or self-incrementing ids, which cannot be repeatedly validated and should be excluded. +2. there is `\n` or `\r\n` or other escape mismatch fields in the run results. Generally, when parsing the `httpResponse` error, you can follow these solutions: + 1. modify the field type of the content in the api model to `json. + 2. convert it to string when parsing + 3. so that the `\n` symbol can be kept intact, avoiding the parsing of line breaks by the database or the operating system + + +For example, in the `github` plugin, this is how it is handled. +![image](https://user-images.githubusercontent.com/3294100/175098219-c04b810a-deaf-4958-9295-d5ad4ec152e6.png) +![image](https://user-images.githubusercontent.com/3294100/175098273-e4a18f9a-51c8-4637-a80c-3901a3c2934e.png) + +Well, at this point, the E2E writing is done. We have added a total of 3 new files to complete the testing of the meeting length collection task. It's pretty easy. +![image](https://user-images.githubusercontent.com/3294100/175098574-ae6c7fb7-7123-4d80-aa85-790b492290ca.png) + +## Run E2E tests for all plugins like CI + +It's straightforward. Just run `make e2e-plugins` because DevLake has already solidified it into a script~ + diff --git a/versioned_docs/version-v0.21/DeveloperManuals/Notifications.md b/versioned_docs/version-v0.21/DeveloperManuals/Notifications.md new file mode 100644 index 00000000000..23456b4f1e7 --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/Notifications.md @@ -0,0 +1,32 @@ +--- +title: "Notifications" +description: > + Notifications +sidebar_position: 4 +--- + +## Request +Example request +``` +POST /lake/notify?nouce=3-FDXxIootApWxEVtz&sign=424c2f6159bd9e9828924a53f9911059433dc14328a031e91f9802f062b495d5 + +{"TaskID":39,"PluginName":"jenkins","CreatedAt":"2021-09-30T15:28:00.389+08:00","UpdatedAt":"2021-09-30T15:28:00.785+08:00"} +``` + +## Configuration +If you want to use the notification feature, you should add two configuration key to `.env` file. +```shell +# .env +# notification request url, e.g.: http://example.com/lake/notify +NOTIFICATION_ENDPOINT= +# secret is used to calculate signature +NOTIFICATION_SECRET= +``` + +## Signature +You should check the signature before accepting the notification request. We use sha256 algorithm to calculate the checksum. +```go +// calculate checksum +sum := sha256.Sum256([]byte(requestBody + NOTIFICATION_SECRET + nouce)) +return hex.EncodeToString(sum[:]) +``` diff --git a/versioned_docs/version-v0.21/DeveloperManuals/PluginImplementation.md b/versioned_docs/version-v0.21/DeveloperManuals/PluginImplementation.md new file mode 100644 index 00000000000..e94646781c5 --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/PluginImplementation.md @@ -0,0 +1,15 @@ +--- +title: "Plugin Implementation" +sidebar_position: 2 +description: > + Plugin Implementation +--- + +Plugins are code extensions that enable you to pull data from data-sources and present them in DevLake. +They can be implemented in both Go and Python. The framework itself is written in Go, and Python (called PyDevLake) is a supplemental extension to +support developers who prefer it using it. PyDevLake is relatively brand new, and we would like to see it gain more traction; we encourage you to give it +a try if you are familiar with Python. + +The Go development manual can be found [here](https://github.com/apache/incubator-devlake/blob/main/backend/DevelopmentManual.md). This manual also covers the framework in detail. + +The Python development manual can be found [here](https://github.com/apache/incubator-devlake/blob/main/backend/python/README.md). diff --git a/versioned_docs/version-v0.21/DeveloperManuals/Project.md b/versioned_docs/version-v0.21/DeveloperManuals/Project.md new file mode 100644 index 00000000000..158d15eb8ce --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/Project.md @@ -0,0 +1,251 @@ +--- +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 project、the 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. \ No newline at end of file diff --git a/versioned_docs/version-v0.21/DeveloperManuals/Release-SOP.md b/versioned_docs/version-v0.21/DeveloperManuals/Release-SOP.md new file mode 100644 index 00000000000..5c2866ebcbe --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/Release-SOP.md @@ -0,0 +1,295 @@ +# DevLake Release Guide + +**Please make sure your public key was included in the https://downloads.apache.org/incubator/devlake/KEYS , if not, please update this file first.** + +## How to update KEYS + +1. Clone the svn repository + ```shell + svn co https://dist.apache.org/repos/dist/dev/incubator/devlake + ``` +2. Append your public key to the KEYS file + cd devlake + + - Check if your public key is in the KEYS file + - If it does not, create a new [GPG key](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key), and then run the following command to see if it was successful. + + ```shell + gpg --list-sigs + ``` + + - Append your publick key + + ```shell + gpg --armor --export >> KEYS + ``` + +3. Upload + ```shell + svn add KEYS + svn commit -m "update KEYS" + svn cp https://dist.apache.org/repos/dist/dev/incubator/devlake/KEYS https://dist.apache.org/repos/dist/release/incubator/devlake/ -m "update KEYS" + ``` + We will use `v0.16.0` as an example to demonstrate the release process. + +## ASF Release Policy + +- https://www.apache.org/legal/release-policy.html +- https://incubator.apache.org/guides/releasemanagement.html + +## Tools: + +- `gpg` creating and verifying the signature +- `shasum` creating and verifying the checksum +- `git` checkout and pack the codebase +- `svn` uploading the code to the Apache code hosting server + +## Prepare + +- Check against the Incubator Release Checklist +- Create folder `releases/lake-v0.16.0` and put the two files `docker-compose.yml` and `env.example` in there. +- Update the file `.github/ISSUE_TEMPLATE/bug-report.yml` to include the version `v0.16.0` + +## Pack + +- Checkout to the branch/commit + +```shell +git clone https://github.com/apache/incubator-devlake.git +cd incubator-devlake +git checkout b268d53a48edb26d3c9b73b782798703f068f655 +``` + +- Tag the commit and push to origin + + ```shell + git tag v0.16.0-rc2 + git push origin v0.16.0-rc2 + ``` + +- Pack the code + ```shell + git archive --format=tar.gz --output="/apache-devlake-0.16.0-incubating-src.tar.gz" --prefix="apache-devlake-0.16.0-incubating-src/" v0.16.0-rc2 + ``` +- Before proceeding to the next step, please make sure your public key was included in the https://downloads.apache.org/incubator/devlake/KEYS +- Create signature and checksum + ```shell + cd + gpg -s --armor --output apache-devlake-0.16.0-incubating-src.tar.gz.asc --detach-sig apache-devlake-0.16.0-incubating-src.tar.gz + shasum -a 512 apache-devlake-0.16.0-incubating-src.tar.gz > apache-devlake-0.16.0-incubating-src.tar.gz.sha512 + ``` +- Verify signature and checksum + ```shell + gpg --verify apache-devlake-0.16.0-incubating-src.tar.gz.asc apache-devlake-0.16.0-incubating-src.tar.gz + shasum -a 512 --check apache-devlake-0.16.0-incubating-src.tar.gz.sha512 + ``` + +## Upload + +- Clone the svn repository + ```shell + svn co https://dist.apache.org/repos/dist/dev/incubator/devlake + ``` +- Copy the files into the svn local directory + ```shell + cd devlake + mkdir -p 0.16.0-incubating-rc2 + cp /apache-devlake-0.16.0-incubating-src.tar.gz* 0.16.0-incubating-rc2/ + ``` +- Upload local files + ```shell + svn add 0.16.0-incubating-rc2 + svn commit -m "add 0.16.0-incubating-rc2" + ``` + +## Vote + +You can check [Incubator Release Checklist](https://cwiki.apache.org/confluence/display/INCUBATOR/Incubator+Release+Checklist) before voting. + +1. Devlake community vote: + + - Start the [vote](https://lists.apache.org/thread/2v2so22fj9mg5h7jck1opsqhjyc86k06) by sending an email to + + Title: [VOTE] Release Apache DevLake (Incubating) v{{.Version}}-rc{{.RC}} + + Content: + ``` + Hello everyone, + + This is a call for vote to release Apache DevLake (Incubating) v{{.Version}}-rc{{.RC}} + + The release candidates: + https://dist.apache.org/repos/dist/dev/incubator/devlake/{{.Version}}-incubating-rc{{.RC}}/ + + Git tag for the release: + https://github.com/apache/incubator-devlake/releases/tag/v{{.Version}}-rc{{.RC}} + + Keys to verify the Release Candidate: + https://downloads.apache.org/incubator/devlake/KEYS + + How to build: + https://devlake.apache.org/docs/DeveloperManuals/DeveloperSetup + + The vote will be open for at least 72 hours or until the necessary number of votes are reached. + If approved we will seek final release approval from the IPMC. + + Please vote accordingly: + + [ ] +1 approve + [ ] +0 no opinion + [ ] -1 disapprove with the reason + + Thanks + {{.YourName}} + ``` + - Announce the [vote](https://lists.apache.org/thread/wfzzjv53vfxml54098o6dt4913j47d4j) result: + Title: [RESULT][VOTE] Release Apache DevLake (Incubating) v{{.Version}}-rc{{.RC}} + + Content: + ``` + Hello everyone, + + The vote closes now with the following results: + + {{.TotalVotes}} (+1 binding) votes + {{range .Votes}}- {{.Name}}{{end}} + + I will bring the vote results to general@incubator.apache.org + + Thanks + {{.YourName}} + + ``` + +2. Apache incubator community vote: + - Start the [vote](https://lists.apache.org/thread/5dbqc3t2bq7kfqccobrh7j9vqopj030k) by sending an email to general@incubator.apache.org + Title: [VOTE] Release Apache DevLake (Incubating) v{{.Version}}-rc{{.RC}} + + Content: + ``` + Hello everyone, + + This is a call for vote to release Apache DevLake (Incubating) v{{.Version}}-rc{{.RC}}. + The Apache DevLake community has voted on and approved a proposal to release Apache DevLake (Incubating) version v{{.Version}}-rc{{.RC}}. + + Community vote thread: + [Community Vote Thread]({{.VoteThreadURL}}) + + Community vote result thread: + [Community Vote Result Thread]({{.VoteResultThreadURL}}) + + The release candidates: + [Release Candidates]({{.RCURL}}) + + Git tag for the release: + [Git Tag]({{.GitTagURL}}) + + Keys to verify the Release Candidate: + https://downloads.apache.org/incubator/devlake/KEYS + + How to build: + https://devlake.apache.org/docs/DeveloperManuals/DeveloperSetup/ + + The vote will be open for at least 72 hours or until the necessary number of votes are reached. + + Please vote accordingly: + [ ] +1 approve + [ ] +0 no opinion + [ ] -1 disapprove with the reason + + Thanks + + {{.YourName}} + ``` + - Announce the [vote](https://lists.apache.org/thread/40ktrw42c7hpok7vj33ql6wgdq2mpg92) result: + Title: + [RESULT][VOTE] Release Apache DevLake (Incubating) v{{.Version}}-rc{{.RC}} + + Content: + ``` + Hello everyone, + + I am pleased to announce that the vote for Apache DevLake (Incubating) v{{.Version}}-rc{{.RC}} has now concluded. Thank you all for your review and participation in the voting process. + + The release voting has passed with {{bindingVotes}} binding votes, {{nonBindingVotes}} non-binding vote and no +0 or -1 votes. + + The individuals who provided binding votes are: + {{bindingVotesList}} + + The non-binding vote{{pluralNonBindingVotes}} is from: + {{nonBindingVotesList}} + + You can find the voting thread at the following link: [Voting Thread](https://lists.apache.org/thread/{{votingThreadURL}}) + + In closing, I want to express my gratitude to everyone who has offered us help, advice, and guidance throughout this process. We will proceed with completing the remaining tasks. + + Thank you all once again! + + Best Regards, + {{.YourName}} + ``` + + +## Release + +### Apache + +- Move the release to the ASF content distribution system + ```shell + svn mv https://dist.apache.org/repos/dist/dev/incubator/devlake/0.16.0-incubating-rc2 https://dist.apache.org/repos/dist/release/incubator/devlake/0.16.0-incubating -m "transfer packages for 0.16.0-incubating-rc2" + ``` +- Wait until the directory `https://downloads.apache.org/incubator/devlake/0.16.0-incubating/` was created +- Remove the last release from `https://downloads.apache.org/` (according the Apache release policy, this link should be pointing to the current release) + ```shell + svn rm https://dist.apache.org/repos/dist/release/incubator/devlake/0.15.0-incubating -m "remove 0.15.0-incubating" + ``` +- Announce [release](https://lists.apache.org/thread/czf6p3xtlkq6t8g4q35blkbf2xclsl3p) by sending an email to general@incubator.apache.org + Title: + [[ANNOUNCE] Release Apache Devlake(incubating) {{.Version}}-incubating + + Content: + ``` + Hello everyone, + + The Apache DevLake (Incubating) {{.Version}}-incubating has been released! + + **Apache DevLake** is an open-source dev data platform that ingests, analyzes, and visualizes the fragmented data from DevOps tools to distill insights for engineering productivity. + + Download Links: https://downloads.apache.org/incubator/devlake/ + + Changelogs: + - xxx. + - xxx. + - xxx. + + Website: https://devlake.apache.org/ + + Resources: + - Issue:https://github.com/apache/incubator-devlake/issues + - Mailing list: dev@devlake.apache.org + + Best Regards, + {{.YourName}} + + ---- + Disclaimer: Apache DevLake(incubating) is an effort undergoing incubation at the Apache + Software Foundation (ASF), sponsored by the Apache Incubator PMC. + + Incubation is required of all newly accepted projects until a further review + indicates that the infrastructure, communications, and decision making process + have stabilized in a manner consistent with other successful ASF projects. + + While incubation status is not necessarily a reflection of the completeness + or stability of the code, it does indicate that the project has yet to be + fully endorsed by the ASF. + + ``` +### GitHub + +- Create tag v0.16.0 and push + ```shell + git checkout v0.16.0-rc2 + git tag v0.16.0 + git push origin v0.16.0 + ``` +- Open the URL `https://github.com/apache/incubator-devlake/releases/`, draft a new release, fill in the form and upload two files `docker-compose.yml` and `env.example` diff --git a/versioned_docs/version-v0.21/DeveloperManuals/SourceCodeReference.md b/versioned_docs/version-v0.21/DeveloperManuals/SourceCodeReference.md new file mode 100644 index 00000000000..de4002c805e --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/SourceCodeReference.md @@ -0,0 +1,12 @@ +--- +title: "Source Code References" +description: > + Source Code References +sidebar_position: 1 +--- + +For developers who wish to contribute to or develop based on the Apache DevLake, the +[pkg.go.dev](https://pkg.go.dev/github.com/apache/incubator-devlake#section-documentation) +is a good resource for reference, you can learn the overall structure of the code base or +the definition of a specific function. + diff --git a/versioned_docs/version-v0.21/DeveloperManuals/TagNamingConventions.md b/versioned_docs/version-v0.21/DeveloperManuals/TagNamingConventions.md new file mode 100644 index 00000000000..3417c29b638 --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/TagNamingConventions.md @@ -0,0 +1,13 @@ +--- +title: "Tag Naming Conventions" +description: > + Tag Naming Conventions +sidebar_position: 6 +--- + +Please refer to the rules when creating a new tag for Apache DevLake +- alpha: internal testing/preview, i.e. v0.12.0-alpha1 +- beta: community/customer testing/preview, i.e. v0.12.0-beta1 +- rc: asf release candidate, i.e. v0.12.0-rc1 + + diff --git a/versioned_docs/version-v0.21/DeveloperManuals/UnitTest.md b/versioned_docs/version-v0.21/DeveloperManuals/UnitTest.md new file mode 100644 index 00000000000..b7599dd26e8 --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/UnitTest.md @@ -0,0 +1,42 @@ +--- +title: "UnitTest Test Guide" +description: > + The steps to write UnitTest tests for plugins. +--- + +# Introduction of UnitTest + +A unit test is a type of software testing that tests individual units or components of a software application. The goal of unit testing is to validate that each unit of the software performs as expected. Unit tests are typically written by developers as they work on the code, to ensure that the code they are writing is correct and behaves as intended. + +Unit tests are automated and are typically written in the same programming language as the code being tested. They are usually run as part of a continuous integration process, ensuring that changes to the codebase don't break existing functionality. + +Unit tests are typically small and focus on a specific function or method of the code. They are usually designed to run quickly and in isolation, so that any issues that are discovered can be easily traced back to the specific code that is causing the problem. + +# How to write UnitTest for golang + +Here are some resources for writing UnitTest for golang: + +- [Add a test - The Go Programming Language](https://go.dev/doc/tutorial/add-a-test) + +- [How To Write Unit Tests in Go | DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-write-unit-tests-in-go-using-go-test-and-the-testing-package) + + +# Test case examples + +- [Source code](https://github.com/apache/incubator-devlake/blob/243cc8a80aa5b37828e2a142ac9f7e3269b7e1dc/backend/core/migration/migrator_test.go) + +# Recommended Libraries for writing UnitTest cases + +- [Library-1](https://github.com/stretchr/testify/tree/master/assert) +- [Library-2](https://github.com/stretchr/testify/tree/master/mock) + + + + + + + + + + + diff --git a/versioned_docs/version-v0.21/DeveloperManuals/_category_.json b/versioned_docs/version-v0.21/DeveloperManuals/_category_.json new file mode 100644 index 00000000000..f921ae47152 --- /dev/null +++ b/versioned_docs/version-v0.21/DeveloperManuals/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Developer Manuals", + "position": 8, + "link":{ + "type": "generated-index", + "slug": "DeveloperManuals" + } +} diff --git a/versioned_docs/version-v0.21/GettingStarted/Authentication.md b/versioned_docs/version-v0.21/GettingStarted/Authentication.md new file mode 100644 index 00000000000..92184ba05dc --- /dev/null +++ b/versioned_docs/version-v0.21/GettingStarted/Authentication.md @@ -0,0 +1,43 @@ +--- +title: "Security and Authentication" +sidebar_position: 8 +description: How to secure your deployment and enable the Authentication +--- + +The document explains how you can set up Apache DevLake securely. + +First of all, there are 4 services included in the deployment: + +- database: `mysql` is supported, you may use it or any other compatible DBS like cloud-based systems. You should follow the document from the database to make it secure. +- grafana: You are likely to use it most of the time, browsing built-in dashboards, and creating your own customized metric. grafana supports [User Management](https://grafana.com/docs/grafana/latest/administration/user-management/), please follow the official document to set it up based on your need. +- devlake: This is the core service for Data Collection and Metric Calculation, all collected/calculated data would be stored to the database, and accessed by the `grafana` service. `devlake` itself doesn't support User Management of any kind, so we don't recommend that you expose its port to the outside world. +- config-ui: A web interface to set up `devlake` to do the work. You may set up an automated `blueprint` to collect data. `config-ui` supports `Basic Authentication`, by simply set up the Environment Variable `ADMIN_USER` and `ADMIN_PASS` for the container. There are commented lines in `config-ui.environment` section in our `docker-compose.yml` file for your convenience. +In General, we suggest that you reduce the Attack Surface as small as possible. + + +### Internal Deployment (Recommended) + +- database: Remove the `ports` if you don't need to access the database directly +- devlake: Remove the `ports` section. If you want to call the API directly, do it via `config-ui/api` endpoint. +- grafana: We have no choice but to expose the `ports` for people to browse the dashboards. However, you may want to set up the User Management, and a read-only database account for `grafana` +- config-ui: Normally, exposing the `ports` with `Basic Authentication` is sufficient for Internal Deployment, you may choose to remove the `ports` and use techniques like `k8s port-forwarding` or `expose-port-when-needed` to enhance the security. Keep in mind config-ui is NOT designed to be used by many people, and it shouldn't be. Do NOT grant access if NOT necessary. + + +### Internet Deployment (NOT Recommended) + +THIS IS DANGEROUS, DON'T DO IT. If you insist, here are some suggestions you may follow, please consult Security Advisor before everything: + +- database: Same as above. +- grafana: Same as above. In addition, set up the `HTTPS` for the transportation. +- devlake: Same as above. +- config-ui: Same as above. In addition, use port-forward if you are using `k8s`, otherwise, set up `HTTPS` for the transportation. + + +## Disclaimer + +Security is complicated, all suggestions listed above are based on what we learned so far. Apache Devlake makes no guarantee of any kind, please consult your Security Advisor before applying. + + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Installation.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/GettingStarted/DockerComposeSetup.md b/versioned_docs/version-v0.21/GettingStarted/DockerComposeSetup.md new file mode 100644 index 00000000000..915b016cb5c --- /dev/null +++ b/versioned_docs/version-v0.21/GettingStarted/DockerComposeSetup.md @@ -0,0 +1,178 @@ +--- +title: "Install via Docker Compose" +description: > + The steps to install DevLake via Docker Compose +sidebar_position: 2 +--- + +## Prerequisites + +- [Docker v19.03.10+](https://docs.docker.com/get-docker) +- [docker-compose v2.2.3+](https://docs.docker.com/compose/install/) (If you have Docker Desktop installed then you already have the Compose plugin installed) + +## Launch DevLake + +1. Download `docker-compose.yml` and `env.example` from the [latest release](https://github.com/apache/incubator-devlake/releases) into a folder. +2. Rename `env.example` to `.env`. For Mac/Linux users, please run `mv env.example .env` in the terminal. This file contains the environment variables that the Devlake server will use. Additional ones can be found in the compose file(s). +3. Generate a secure encryption key using a method such as OpenSSL. For example, run the following command to generate a 128-character string consisting of uppercase letters: + + ``` + openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1 + ``` + + Copy the generated string. Set the value of the ENCRYPTION_SECRET environment variable: + + - Method 1: In the docker-compose.yml, set an environment variable ENCRYPTION_SECRET: "copied string" + - Method 2: Alternatively, you can set the ENCRYPTION_SECRET environment variable in the .env file: ENCRYPTION_SECRET="copied string" + + If you set the ENCRYPTION_SECRET environment variable in both docker-compose.yml and the .env file, the value set in docker-compose.yml takes precedence. + + **Please make sure to keep the ENCRYPTION_SECRET safe as it is used to encrypt sensitive information in the database, such as personal access tokens and passwords. If ENCRYPTION_SECRET is lost, it may not be possible to decrypt this sensitive information.** + +4. By default, the timezone is UTC. You can change it by adjusting the env variable TZ in docker-compose.yml + +5. Run `docker-compose up -d` if the version of Docker Desktop is too low to use `docker compose up -d`. + +## Collect data and view dashboards + +1. Visit "config-ui" at `http://localhost:4000` in your browser to configure DevLake and collect data. + - Please follow the [tutorial](Configuration/Tutorial.md) + - "devlake" container takes a while to fully boot up. If "config-ui" complains about API being unreachable, please wait a few seconds and refresh the page. +2. To view dashboards, click _View Dashboards_ button in the top left corner, or visit `localhost:3002` (username: "admin", password: "admin"). + - We use [Grafana](https://grafana.com/) to visualize the DevOps [data](/Overview/SupportedDataSources.md) and build dashboards. + - For how to customize and provision dashboards, please see our [Grafana doc](../Configuration/Dashboards/GrafanaUserGuide.md). + +## Upgrade to a newer version + +Please note: + +Note 1: **Back up your Grafana dashboards** before upgrading if you have modified/customized any dashboards. You can re-import these dashboards to Grafana after the upgrade. + +Note 2: **If you're upgrading from DevLake v0.17.x or earlier versions to v0.18.x or later versions**, you need to find the ENCODE_KEY value in the .env file of devlake container, and assign the value to ENCRYPTION_SECRET via .env file or environment variable in docker-compose.yml + +1. Run `docker-compose down` to stop services; +2. Download `docker-compose.yml` and `env.example` from the [latest release](https://github.com/apache/incubator-devlake/releases). +3. Use the new `docker-compose.yml` and `env.example` to replace the old `docker-compose.yml` and `.env`; Or if you have modified/customized values in the old files, compare the new files with the old ones, adjust the old files according to the new ones. +4. If upgrading from earlier versions to v0.18.0+, set the ENCRYPTION_SECRET environment variable in docker-compose.yml or .env file, refer to above Note 2. +5. Run `docker-compose up -d` to start DevLake services. + +## FAQ + +### Can I use a managed cloud database service instead of running database in Docker? + +Yes, please follow the steps below: + +1. Comment out the 'mysql' part in `docker-compose.yml`: + +```yaml +mysql: + image: mysql:8 + volumes: + - mysql-storage:/var/lib/mysql + restart: always + ports: + - "127.0.0.1:3306:3306" + environment: + MYSQL_ROOT_PASSWORD: admin + MYSQL_DATABASE: lake + MYSQL_USER: merico + MYSQL_PASSWORD: merico + command: --character-set-server=utf8mb4 + --collation-server=utf8mb4_bin +``` + +2. Comment out the 'mysql' volume in `docker-compose.yml`: + +```yaml +volumes: + mysql-storage: +``` + +3. Comment out the 'depends_on mysql' part in `docker-compose.yml`: + +```yaml +depends_on: + - mysql +``` + +4. Provide your managed cloud database connection info in the 'grafana' section in `docker-compose.yml`: + +- MYSQL_URL: This parameter specifies the URL of your database instance. For example, if your database is hosted on a server with IP address 123.45.67.89 and port number 3306, the URL would be "123.45.67.89:3306". +- MYSQL_DATABASE: This parameter specifies the name of your database. For example, if your database is named "mydatabase", you would set this parameter to "mydatabase". +- MYSQL_USER: This parameter specifies the username that you will use to connect to your database. For example, if your username is "myuser", you would set this parameter to "myuser". +- MYSQL_PASSWORD: This parameter specifies the password that you will use to connect to your database. For example, if your password is "mypassword", you would set this parameter to "mypassword". + +```yaml +MYSQL_URL: 123.45.67.89:3306 +MYSQL_DATABASE: mydatabase +MYSQL_USER: myuser +MYSQL_PASSWORD: mypassword +``` + +5. Set DB_URL to your own DB_URL in `.env`: + +```bash +DB_URL="mysql://YOUR_USER:YOUR_PASSWORD@YOUR_IP:YOUR_PORT/lake?charset=utf8mb4&parseTime=True" +# Don't forget to create db named `lake` in your own db, and set character-set-server=utf8mb4, collation-server=utf8mb4_bin as below +# character-set-server=utf8mb4 +# collation-server=utf8mb4_bin +``` + +6. Final step: `docker compose up -d` + +### Can I use an external Grafana instead of running Grafana in Docker? + +Yes, please follow the steps below: + +1. Comment out the 'grafana' part: + +```yaml +grafana: + image: mericodev/devlake-dashboard:latest + build: + context: grafana/ + ports: + - "3002:3000" + volumes: + - grafana-storage:/var/lib/grafana + environment: + GF_SERVER_ROOT_URL: "http://localhost:4000/grafana" + GF_USERS_DEFAULT_THEME: "light" + MYSQL_URL: mysql:3306 + MYSQL_DATABASE: lake + MYSQL_USER: merico + MYSQL_PASSWORD: merico + restart: always + depends_on: + - mysql +``` + +2. Comment out grafana volume: + +```yaml +volumes: + grafana-storage: +``` + +3. Set up the `config-ui` container to adopt the external Grafana in the `docker-compose.yml` + +```yaml +config-ui: + ... + environment: + USE_EXTERNAL_GRAFANA: "true" + GRAFANA_ENDPOINT: "http://grafana.example.com" + ... +``` + +4. Please connect your Grafana to DevLake's database by following https://grafana.com/docs/grafana/latest/administration/data-source-management/ + +5. If you want to import dashboards, please check https://grafana.com/docs/grafana/latest/dashboards/export-import/. + +- You can find DevLake's self-built Grafana dashboards here (https://github.com/apache/incubator-devlake/tree/main/grafana/dashboards). + +6. Final step: `docker compose up -d` + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Installation.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/GettingStarted/HelmSetup.md b/versioned_docs/version-v0.21/GettingStarted/HelmSetup.md new file mode 100644 index 00000000000..bade88d772d --- /dev/null +++ b/versioned_docs/version-v0.21/GettingStarted/HelmSetup.md @@ -0,0 +1,330 @@ +--- +title: "Install via Helm" +description: > + The steps to install Apache DevLake via Helm for Kubernetes +sidebar_position: 3 +--- + +## Prerequisites + +- Helm >= 3.6.0 +- Kubernetes >= 1.19.0 + +## Quick Start + +#### You can also check https://github.com/apache/incubator-devlake-helm-chart to make contribution + +#### To install or upgrade to the latest version, please check [here](https://github.com/apache/incubator-devlake-helm-chart/releases) + +### Install + +To install the chart with release name `devlake`,follow these steps: + +1. Generate a secure encryption key using a method such as OpenSSL. For example, run the following command to generate a 128-character string consisting of uppercase letters: + + ``` + openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1 + ``` + +2. Copy the generated string, set the value of the ENCRYPTION_SECRET environment variable by running the following command: + + ``` + export ENCRYPTION_SECRET="copied string" + ``` + + This command will set the `ENCRYPTION_SECRET` environment variable to the value of the copied string. + + **Please make sure to keep the ENCRYPTION_SECRET safe as it is used to encrypt sensitive information in the database, such as personal access tokens and passwords. If ENCRYPTION_SECRET is lost, it may not be possible to decrypt this sensitive information.** + +3. By default, the timezone is UTC. To customize the timezone settings, apply the `--set commonEnvs.TZ="your timezone",grafana.env.TZ="your timezone"` command. For further guidance, please refer to [FAQ](#faq). + +4. By default, a random password is generated and stored in a Kubernetes Secret for the Grafana admin user. Alternatively, you can explicitly set the password via `--set grafana.adminPassword=`. For further guidance, please refer to [FAQ](#faq). + +5. Install the chart by running the following commands: + + ```shell + helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart + helm repo update + helm install devlake devlake/devlake --version=0.21.0-beta1 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET + ``` + +And visit your devlake from the node port (32001 by default). + +http://YOUR-NODE-IP:32001 + +#### Tips: + +If you are using minikube inside your mac, please use the following command to forward the port: + +```shell +kubectl port-forward service/devlake-ui 30090:4000 +``` + +and open another terminal: + +```shell +kubectl port-forward service/devlake-grafana 30091:3000 +``` + +Then you can visit: +config-ui by url `http://YOUR-NODE-IP:30090` +grafana by url `http://YOUR-NODE-IP:30091` + +### Upgrade + +**Note:** + +**Back up your Grafana dashboards** before upgrading if you have modified/customized any dashboards. You can re-import these dashboards to Grafana after the upgrade. + +**If you're upgrading from DevLake v0.17.x or earlier versions to v0.18.x or later versions:** + +1. Copy the ENCODE_KEY value from /app/config/.env of the lake pod (e.g. devlake-lake-0), and replace the in the upgrade command below. + +2. You may encounter the below error when upgrading because the built-in grafana has been replaced by the official grafana dependency. So you may need to delete the grafana deployment first. + +> Error: UPGRADE FAILED: cannot patch "devlake-grafana" with kind Deployment: Deployment.apps "devlake-grafana" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app.kubernetes.io/instance":"devlake", "app.kubernetes.io/name":"grafana"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable + +```shell +helm repo update +helm upgrade devlake devlake/devlake --version=0.21.0-beta1 --set lake.encryptionSecret.secret= +``` + +**If you're upgrading from DevLake v0.18.x or later versions:** + +```shell +helm repo update +helm upgrade devlake devlake/devlake --version=0.21.0-beta1 +``` + +### Uninstall + +To uninstall/delete the `devlake` release: + +```shell +helm uninstall devlake +``` + +## Some example deployments + +### Deploy with NodePort + +Conditions: + +- IP Address of Kubernetes node: 192.168.0.6 +- Want to visit devlake with port 30000. + +``` +ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1) +helm install devlake devlake/devlake --set service.uiPort=30000 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET +``` + +After deployed, visit devlake: http://192.168.0.6:30000 + +### Deploy with Ingress + +Conditions: + +- I have already configured default ingress for the Kubernetes cluster +- I want to use http://devlake.example.com for visiting devlake + +``` +ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1) +helm install devlake devlake/devlake --set "ingress.enabled=true,ingress.hostname=devlake.example.com" --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET +``` + +After deployed, visit devlake: http://devlake.example.com, and grafana at http://devlake.example.com/grafana + +### Deploy with Ingress (Https) + +Conditions: + +- I have already configured ingress(class: nginx) for the Kubernetes cluster, and the https using 8443 port. +- I want to use https://devlake-0.example.com:8443 for visiting devlake. +- The https certificates are generated by letsencrypt.org, and the certificate and key files: `cert.pem` and `key.pem` + +First, create the secret: + +``` +kubectl create secret tls ssl-certificate --cert cert.pem --key secret.pem +``` + +Then, deploy the devlake: + +``` +ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1) +helm install devlake devlake/devlake \ + --set "ingress.enabled=true,ingress.enableHttps=true,ingress.hostname=devlake-0.example.com" \ + --set "ingress.className=nginx,ingress.httpsPort=8443" \ + --set "ingress.tlsSecretName=ssl-certificate" + --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET +``` + +After deployed, visit devlake: https://devlake-0.example.com:8443, and grafana at https://devlake-0.example.com:8443/grafana + +## Parameters + +Some useful parameters for the chart, you could also check them in values.yaml + +| Parameter | Description | Default | +| ----------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------ | +| replicaCount | Replica Count for devlake, currently not used | 1 | +| imageTag | The version tag for all images | see Values.yaml | +| commonEnvs | The common envs for all pods except grafana | {TZ: "UTC"} | +| mysql.useExternal | If use external mysql server, set true | false | +| mysql.externalServer | External mysql server address | 127.0.0.1 | +| mysql.externalPort | External mysql server port | 3306 | +| mysql.username | username for mysql | merico | +| mysql.password | password for mysql | merico | +| mysql.database | database for mysql | lake | +| mysql.rootPassword | root password for mysql | admin | +| mysql.storage.type | storage type, pvc or hostpath | pvc | +| mysql.storage.class | storage class for mysql's volume | "" | +| mysql.storage.size | volume size for mysql's data | 5Gi | +| mysql.storage.hostPath | the host path if mysql.storage.type is hostpath | /devlake/mysql/data | +| mysql.image.repository | repository for mysql's image | mysql | +| mysql.image.tag | image tag for mysql's image | 8 | +| mysql.image.pullPolicy | pullPolicy for mysql's image | IfNotPresent | +| mysql.initContainers | init containers to run to complete before mysql | [] | +| mysql.extraLabels | extra labels for mysql's statefulset | {} | +| mysql.securityContext | pod security context values | {} | +| mysql.containerSecurityContext | container security context values | {} | +| mysql.service.type | mysql service type | ClusterIP | +| mysql.service.nodePort | specify mysql nodeport | "" | +| grafana | dashboard, datasource, etc. settings for grafana, installed by grafana official chart | | +| lake.image.repository | repository for lake's image | apache/devlake | +| lake.image.pullPolicy | pullPolicy for lake's image | Always | +| lake.port | the port of devlake backend | 8080 | +| lake.envs | initial envs for lake | see Values.yaml | +| lake.extraEnvsFromSecret | existing secret name of extra envs | "" | +| lake.encryptionSecret.secretName | the k8s secret name for ENCRYPTION_SECRET | "" | +| lake.encryptionSecret.secret | the secret for ENCRYPTION_SECRET | "" | +| lake.encryptionSecret.autoCreateSecret | whether let the helm chart create the secret | true | +| lake.extraLabels | extra labels for lake's statefulset | {} | +| lake.securityContext | pod security context values | {} | +| lake.containerSecurityContext | container security context values | {} | +| ui.image.repository | repository for ui's image | apache/devlake-config-ui | +| ui.image.pullPolicy | pullPolicy for ui's image | Always | +| ui.basicAuth.enabled | If the basic auth in ui is enabled | false | +| ui.basicAuth.user | The user name for the basic auth | "admin" | +| ui.basicAuth.password | The password for the basic auth | "admin" | +| ui.basicAuth.autoCreateSecret | If let the helm chart create the secret | true | +| ui.basicAuth.secretName | The basic auth secret name | "" | +| ui.extraLabels | extra labels for ui's statefulset | {} | +| ui.securityContext | pod security context values | {} | +| ui.containerSecurityContext | container security context values | {} | +| service.type | Service type for exposed service | NodePort | +| service.uiPort | Node port for config ui | 32001 | +| service.ingress.enabled | If enable ingress | false | +| service.ingress.enableHttps | If enable https | false | +| service.ingress.className | Name for ingressClass. leave empty for using default | "" | +| service.ingress.hostname | The hostname/domainname for ingress | localhost | +| service.ingress.prefix | The prefix for endpoints, currently not used | / | +| service.ingress.tlsSecretName | The secret name for tls's certificate for https | "" | +| service.ingress.httpPort | The http port for ingress | 80 | +| service.ingress.httpsPort | The https port for ingress | 443 | +| option.database | The database type, valids: mysql | mysql | +| option.connectionSecretName | The database connection details secret name | devlake-mysql-auth | +| option.autoCreateSecret | If let the helm chart create the secret | true | + + +## FAQ + +1. Can I use a managed Cloud database service instead of running database in docker? + +Yes, it just set useExternal value to true while you deploy devlake with helm chart. Below we'll use MySQL on AWS RDS as an example. + +a. (Optional) Create a MySQL instance on AWS RDS following this [doc](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_GettingStarted.CreatingConnecting.MySQL.html), skip this step if you'd like to use an existing instance +b. Proviede below values while install from helm: + + - `mysql.useExternal`: this should be `true` + - `mysql.externalServer`: use your RDS instance's IP address or domain name. + - `mysql.externalPort`: use your RDS instance's database port. + - `mysql.username`: use your `username` for access RDS instance's DB + - `mysql.password`: use your `password` for access RDS instance's DB + - `mysql.database`: use your RDS instance's DB name, you may need to create a database first with `CREATE DATABASE ;` + +Here is the example: + +``` +helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart +helm repo update +ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1) +helm install devlake devlake/devlake \ + --set mysql.useExternal=true \ + --set mysql.externalServer=db.example.com \ + --set mysql.externalPort=3306 \ + --set mysql.username=admin \ + --set mysql.password=password_4_admin \ + --set mysql.database=devlake + --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET + +``` + +2. Can I use a secret to store the database connection details? + +Yes, to do so, you need to have a secret in your Kubernetes Cluster that contains the following values: + +- `MYSQL_USER`: The user to connect to your DB. +- `MYSQL_PASSWORD`: The password to connect to your DB. +- `MYSQL_DATABASE`: The database to connect to your DB. +- `MYSQL_ROOT_PASSWORD`: The root password to connect to your DB. +- `DB_URL`: mysql://`username`:`password`@`dbserver`:`port`/`database`?charset=utf8mb4&parseTime=True + +The secret name needs to be the same as the value `option.connectionSecretName` + +3. Can I use an external Grafana instead of running built-in Grafana? + +Yes, the devlake helm chart supports using an external Grafana. You can set the following values while installing from helm: + +- `grafana.enabled`: this should be `false` +- `grafana.external.url`: use your Grafana's URL, e.g. `https://grafana.example.com` + +Here is the example: + +``` +helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart +helm repo update +ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1) +helm install devlake devlake/devlake \ + --set grafana.enabled=false \ + --set grafana.external.url=https://grafana.example.com + --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET + +``` + +4. How to set the timezone? If not explicitly set, the default is UTC + +- `commonEnvs.TZ`: your timezone +- `grafana.env.TZ`: your timezone + +Here is the example: + +``` +helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart +helm repo update +ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1) +helm install devlake devlake/devlake \ + --set commonEnvs.TZ= \ + --set grafana.env.TZ= + +``` + +5. How to set the Grafana admin password? If not explicitly set, a random password will be generated and saved in a Kubernetes Secret + +- `grafana.adminPassword`: your password + +Here is the example: + +``` +helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart +helm repo update +ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1) +helm install devlake devlake/devlake \ + --set grafana.adminPassword= \ + --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET + +``` + +## Troubleshooting + +If you run into any problem, please check the [Troubleshooting](/Troubleshooting/Installation.md) or [create an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/GettingStarted/QuickStart.md b/versioned_docs/version-v0.21/GettingStarted/QuickStart.md new file mode 100644 index 00000000000..686a8ba421f --- /dev/null +++ b/versioned_docs/version-v0.21/GettingStarted/QuickStart.md @@ -0,0 +1,17 @@ +--- +title: "Quick Start" +description: > + The steps to utilize Apache DevLake +sidebar_position: 1 +--- + +The key steps to deploy and utilize Apache DevLake. + +## Step 1. Install DevLake +Install DevLake using either Docker Compose or Helm. If you want to upgrade DevLake to a newer version, please refer to the upgrade manuals. + +## Step 2. Configure DevLake +Configure DevLake via the Config UI. Follow the turorial for configuration instructions. If you specifically want to configure DORA metrics, please refer to the DORA manuals for detailed instructions. + +## Step 3. View Data in Grafana Dashboards +After configuring DevLake and collecting data, access the Config UI and click the "Dashboards" button in the top-right corner to view the data in Grafana dashboards. For comprehensive instructions, please refer to the [Grafana manuals](/docs/Configuration/Dashboards/GrafanaUserGuide.md). diff --git a/versioned_docs/version-v0.21/GettingStarted/Upgrade.md b/versioned_docs/version-v0.21/GettingStarted/Upgrade.md new file mode 100644 index 00000000000..c54fbd1b848 --- /dev/null +++ b/versioned_docs/version-v0.21/GettingStarted/Upgrade.md @@ -0,0 +1,21 @@ +--- +title: "Upgrade" +sidebar_position: 3 +description: How to upgrade your Apache DevLake to a newer version +--- + +1. ENCRYPTION_SECRET: It is important to keep the ENCRYPTION_SECRET safe as it is used to encrypt sensitive information in the database, such as personal access tokens and passwords. Losing the ENCRYPTION_SECRET may result in the inability to decrypt this sensitive information. + +2. .env file: The .env file is now optional. You can choose to store your variables in the environment instead. Remember to consider important variables such as ENCRYPTION_SECRET and DB_URL. If both the environment variables and the .env file exist, the values in the environment variables will take precedence. However, make sure that these variables are defined in either one of them to avoid any issues with DevLake. + +3. Back up your Grafana dashboards before upgrade if you have modified/customized any dashboards. You can re-import these dashboards to Grafana after the upgrade. + +4. Upgrade to v0.18.0+: When upgrading from a previous version of DevLake, you need to find the ENCODE_KEY value in the .env file of devlake container, and assign the value to ENCRYPTION_SECRET according to the upgrade steps, see [helm setup](https://devlake.apache.org/docs/GettingStarted/HelmSetup) or [docker compose setup](https://devlake.apache.org/docs/GettingStarted/DockerComposeSetup). This will ensure that the encryption process continues to work as expected. + +5. Upgrade to v0.18.0+: When upgrading from a previous version of DevLake, You may encounter the below error when upgrading because the built-in grafana has been replaced by the official grafana dependency. So you may need to delete the grafana deployment first, please also take care of Note 3 before deleting. + +> Error: UPGRADE FAILED: cannot patch "devlake-grafana" with kind Deployment: Deployment.apps "devlake-grafana" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app.kubernetes.io/instance":"devlake", "app.kubernetes.io/name":"grafana"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable + +6. When upgrading via docker-compose.yml, please download the new docker-compose.yml and env.example from [release assets](https://github.com/apache/incubator-devlake/releases) to do the upgrade, please refer to [docker compose upgrade notes](./DockerComposeSetup.md) + +These notes provide guidance on upgrading your Apache DevLake to a newer version. Ensure you follow them carefully to avoid any issues during the upgrade process. diff --git a/versioned_docs/version-v0.21/GettingStarted/_category_.json b/versioned_docs/version-v0.21/GettingStarted/_category_.json new file mode 100644 index 00000000000..063400ae119 --- /dev/null +++ b/versioned_docs/version-v0.21/GettingStarted/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Getting Started", + "position": 2, + "link":{ + "type": "generated-index", + "slug": "GettingStarted" + } +} diff --git a/versioned_docs/version-v0.21/Metrics/AddedLinesOfCode.md b/versioned_docs/version-v0.21/Metrics/AddedLinesOfCode.md new file mode 100644 index 00000000000..2d9443e58d3 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/AddedLinesOfCode.md @@ -0,0 +1,79 @@ +--- +title: "Added Lines of Code" +description: > + Added Lines of Code +sidebar_position: 11 +--- + +## What is this metric? +The accumulated number of added lines of code. + +## Why is it important? +1. identify potential bottlenecks that may affect the output +2. Encourage the team to implement a development model that matches the business requirements; develop excellent coding habits + +## Which dashboard(s) does it exist in +N/A + +## How is it calculated? +This metric is calculated by summing the additions of commits in the given data range. + +Data Sources Required + +This metric relies on `commits` collected from GitHub, GitLab or BitBucket. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the added lines of code in specific repositories, eg. 'repo-1' and 'repo-2'. + +``` +SELECT + sum(c.additions) as added_lines_of_code +FROM + commits c + LEFT JOIN repo_commits rc ON c.sha = rc.commit_sha + LEFT JOIN repos r ON r.id = rc.repo_id +WHERE + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + r.id in ('repo-1','repo-2') + and message not like '%Merge%' + and $__timeFilter(c.authored_date) + -- the following condition will remove the month with incomplete data + and c.authored_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) +``` + + +If you want to measure the monthly trend of `added lines of code` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/added-loc-monthly.png) + +``` +WITH _commits as( + SELECT + DATE_ADD(date(authored_date), INTERVAL -DAY(date(authored_date))+1 DAY) as time, + sum(additions) as added_lines_of_code + FROM commits + WHERE + message not like '%Merge%' + and $__timeFilter(authored_date) + -- the following condition will remove the month with incomplete data + and authored_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + group by 1 +) + +SELECT + date_format(time,'%M %Y') as month, + added_lines_of_code +FROM _commits +ORDER BY time +``` + + +## How to improve? +1. From the project/team dimension, observe the accumulated change in added lines to assess the team activity and code growth rate +2. From version cycle dimension, observe the active time distribution of code changes, and evaluate the effectiveness of project development model. +3. From the member dimension, observe the trend and stability of code output of each member, and identify the key points that affect code output by comparison. diff --git a/versioned_docs/version-v0.21/Metrics/BugAge.md b/versioned_docs/version-v0.21/Metrics/BugAge.md new file mode 100644 index 00000000000..dddced271b0 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/BugAge.md @@ -0,0 +1,77 @@ +--- +title: "Bug Age" +description: > + Bug Age +sidebar_position: 5 +--- + +## What is this metric? +The amount of time it takes a bug to fix. + +## Why is it important? +1. Help the team to establish an effective hierarchical response mechanism for bugs. Focus on the resolution of important problems in the backlog. +2. Improve team's and individual's bug fixing efficiency. Identify good/to-be-improved practices that affect bug age age + +## Which dashboard(s) does it exist in +- [Jira](https://devlake.apache.org/livedemo/DataSources/Jira) +- [GitHub](https://devlake.apache.org/livedemo/DataSources/GitHub) +- [Weekly Bug Retro](https://devlake.apache.org/livedemo/QAEngineers/WeeklyBugRetro) + + +## How is it calculated? +Similar to [requirement lead time](./RequirementLeadTime.md), this metric equals `resolution_date - created_date` of issues in type "BUG". + +Data Sources Required + +This metric relies on `issues` collected from Jira, GitHub, or TAPD. + +Data Transformation Required + +This metric relies on the 'type-bug' configuration in Jira, GitHub or TAPD's transformation rules while adding/editing a blueprint. This configuration tells DevLake what issues are `bugs`. + +SQL Queries + +The following SQL shows how to find the bug age of a specific `bug`. +``` +-- lead_time_minutes is a pre-calculated field whose value equals 'resolution_date - created_date' +SELECT + lead_time_minutes/1440 as bug_age_in_days +FROM + issues +WHERE + type = 'BUG' +``` + +If you want to measure the `mean bug age` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/bug-age-monthly.png) + +``` +with _bugs as( + SELECT + DATE_ADD(date(i.resolution_date), INTERVAL -DAY(date(i.resolution_date))+1 DAY) as time, + AVG(i.lead_time_minutes/1440) as issue_lead_time + FROM issues i + join board_issues bi on i.id = bi.issue_id + join boards b on bi.board_id = b.id + WHERE + -- $board_id is a variable defined in Grafana's dashboard settings to filter out issues by boards + b.id in ($board_id) + and i.status = "DONE" + and i.type = 'BUG' + and $__timeFilter(i.resolution_date) + -- the following condition will remove the month with incomplete data + and i.resolution_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + group by 1 +) + +SELECT + date_format(time,'%M %Y') as month, + issue_lead_time as "Mean Bug Age in Days" +FROM _bugs +ORDER BY time +``` + +## How to improve? +1. Observe the trend of bug age and locate the key reasons. +2. Compare the age of bugs by severity levels, types (business, functional classification), affected components, etc. \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Metrics/BugCountPer1kLinesOfCode.md b/versioned_docs/version-v0.21/Metrics/BugCountPer1kLinesOfCode.md new file mode 100644 index 00000000000..99e9128901c --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/BugCountPer1kLinesOfCode.md @@ -0,0 +1,88 @@ +--- +title: "Bug Count per 1k Lines of Code" +description: > + Bug Count per 1k Lines of Code +sidebar_position: 6 +--- + +## What is this metric? +Amount of bugs per 1,000 lines of code. + +## Why is it important? +1. Defect drill-down analysis to inform the development of design and code review strategies and to improve the internal QA process +2. Assist teams to locate projects/modules with higher defect severity and density, and clean up technical debts +3. Identify good/to-be-improved practices that affect defect count or defect rate, to reduce the number of future defects + +## Which dashboard(s) does it exist in +N/A + + +## How is it calculated? +The number of bugs divided by the total accumulated lines of code (additions + deletions) in the given data range. + +Data sources required + +- `issues` collected from Jira, GitHub or TAPD. +- `commits` collected from GitHub, GitLab or BitBucket. + +Data Transformation Required + +This metric relies on the 'type-bug' configuration in Jira, GitHub or TAPD's transformation rules while adding/editing a blueprint. This configuration tells DevLake what issues are `bugs`. + +SQL Queries + +If you want to measure the monthly trend of `Bugs per 1k lines of code` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/bug-per-1k-loc-monthly.png) + +``` +with _line_of_code as ( + select + DATE_ADD(date(authored_date), INTERVAL -DAY(date(authored_date))+1 DAY) as time, + sum(additions + deletions) as line_count + from + commits + where + message not like 'Merge%' + and $__timeFilter(authored_date) + group by 1 +), + + +_bug_count as( + select + DATE_ADD(date(created_date), INTERVAL -DAY(date(created_date))+1 DAY) as time, + count(*) as bug_count + from issues i + where + type = 'Bug' + and $__timeFilter(created_date) + group by 1 +), + + +_bug_count_per_1k_loc as( + select + loc.time, + 1.0 * bc.bug_count / loc.line_count * 1000 as bug_count_per_1k_loc + from + _line_of_code loc + left join _bug_count bc on bc.time = loc.time + where + bc.bug_count is not null + and loc.line_count is not null + and loc.line_count != 0 +) + +select + date_format(time,'%M %Y') as month, + bug_count_per_1k_loc as 'Bug Count per 1000 Lines of Code' +from _bug_count_per_1k_loc +order by time; +``` + +## How to improve? +1. From the project or team dimension, observe the statistics on the total number of defects, the distribution of the number of defects in each severity level/type/owner, the cumulative trend of defects, and the change trend of the defect rate in thousands of lines, etc. +2. From version cycle dimension, observe the statistics on the cumulative trend of the number of defects/defect rate, which can be used to determine whether the growth rate of defects is slowing down, showing a flat convergence trend, and is an important reference for judging the stability of software version quality +3. From the time dimension, analyze the trend of the number of test defects, defect rate to locate the key items/key points +4. Evaluate whether the software quality and test plan are reasonable by referring to CMMI standard values diff --git a/versioned_docs/version-v0.21/Metrics/BuildCount.md b/versioned_docs/version-v0.21/Metrics/BuildCount.md new file mode 100644 index 00000000000..ff91addda5d --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/BuildCount.md @@ -0,0 +1,72 @@ +--- +title: "Build Count" +description: > + Build Count +sidebar_position: 23 +--- + +## What is this metric? +The number of successful builds. + +## Why is it important? +1. As a process indicator, it reflects the value flow efficiency of upstream production and research links +2. Identify excellent/to-be-improved practices that impact the build, and drive the team to precipitate reusable tools and mechanisms to build infrastructure for fast and high-frequency delivery + +## Which dashboard(s) does it exist in +- [Jenkins](https://grafana-lake.demo.devlake.io/grafana/d/W8AiDFQnk/jenkins?orgId=1) + + +## How is it calculated? +This metric is calculated by counting the number of successful cicd_pipelines, such as Jenkins builds, GitLab pipelines and GitHub workflow runs in the given data range. + +Data Sources Required + +This metric relies on Jenkins builds, GitLab pipelines or GitHub workflow runs. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the total number of successful CI builds **finished** in the given time range. +``` +SELECT + count(*) +FROM + cicd_pipelines +WHERE + result = 'SUCCESS' + and $__timeFilter(finished_date) +ORDER BY 1 +``` + +If you want to measure the monthly trend of the `successful build count` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/build-count-monthly.png) + +``` +WITH _builds as( + SELECT + DATE_ADD(date(finished_date), INTERVAL -DAYOFMONTH(date(finished_date))+1 DAY) as time, + count(*) as build_count + FROM + cicd_pipelines + WHERE + result = "SUCCESS" + and $__timeFilter(finished_date) + -- the following condition will remove the month with incomplete data + and finished_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + GROUP BY 1 +) + +SELECT + date_format(time,'%M %Y') as month, + build_count as "Build Count" +FROM _builds +ORDER BY time +``` + +## How to improve? +1. From the project dimension, compare the number of builds and success rate by combining the project phase and the complexity of tasks. +2. From the time dimension, analyze the trend of the number of builds and success rate to see if it has improved over time. diff --git a/versioned_docs/version-v0.21/Metrics/BuildDuration.md b/versioned_docs/version-v0.21/Metrics/BuildDuration.md new file mode 100644 index 00000000000..b4319725007 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/BuildDuration.md @@ -0,0 +1,72 @@ +--- +title: "Build Duration" +description: > + Build Duration +sidebar_position: 24 +--- + +## What is this metric? +The duration of successful builds. + +## Why is it important? +1. As a process indicator, it reflects the value flow efficiency of upstream production and research links +2. Identify excellent/to-be-improved practices that impact the build, and drive the team to precipitate reusable tools and mechanisms to build infrastructure for fast and high-frequency delivery + +## Which dashboard(s) does it exist in +- [Jenkins](https://grafana-lake.demo.devlake.io/grafana/d/W8AiDFQnk/jenkins?orgId=1) + + +## How is it calculated? +This metric is calculated by getting the duration of successful cicd_pipelines, such as Jenkins builds, GitLab pipelines and GitHub workflow runs in the given data range. + +Data Sources Required + +This metric relies on Jenkins builds, GitLab pipelines or GitHub workflow runs. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the mean duration of successful CI builds **finished** in the given time range. +``` +SELECT + avg(duration_sec/60) as duration_in_minutes +FROM cicd_pipelines +WHERE + result = 'SUCCESS' + and $__timeFilter(finished_date) +ORDER BY 1 +``` + +If you want to measure the `mean duration of builds` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/build-duration-monthly.png) + +``` +WITH _builds as( + SELECT + DATE_ADD(date(finished_date), INTERVAL -DAYOFMONTH(date(finished_date))+1 DAY) as time, + avg(duration_sec) as mean_duration_sec + FROM + cicd_pipelines + WHERE + $__timeFilter(finished_date) + and id like "%jenkins%" + and name in ($job_id) + -- the following condition will remove the month with incomplete data + and finished_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + GROUP BY 1 +) + +SELECT + date_format(time,'%M %Y') as month, + mean_duration_sec/60 as mean_duration_minutes +FROM _builds +ORDER BY time +``` + +## How to improve? +1. From the project dimension, compare the number of builds and success rate by combining the project phase and the complexity of tasks. +2. From the time dimension, analyze the trend of the number of builds and success rate to see if it has improved over time. diff --git a/versioned_docs/version-v0.21/Metrics/BuildSuccessRate.md b/versioned_docs/version-v0.21/Metrics/BuildSuccessRate.md new file mode 100644 index 00000000000..e9ea2e2d743 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/BuildSuccessRate.md @@ -0,0 +1,89 @@ +--- +title: "Build Success Rate" +description: > + Build Success Rate +sidebar_position: 25 +--- + +## What is this metric? +The ratio of successful builds to all builds. + +## Why is it important? +1. As a process indicator, it reflects the value flow efficiency of upstream production and research links +2. Identify excellent/to-be-improved practices that impact the build, and drive the team to precipitate reusable tools and mechanisms to build infrastructure for fast and high-frequency delivery + +## Which dashboard(s) does it exist in +- [Jenkins](https://grafana-lake.demo.devlake.io/grafana/d/W8AiDFQnk/jenkins?orgId=1) + +## How is it calculated? +The number of successful builds divided by the total number of builds in the given data range. + +Data Sources Required + +This metric relies on Jenkins builds, GitLab pipelines or GitHub workflow runs. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the success rate of CI builds **finished** in the given time range. +``` +SELECT + 1.0 * sum(case when result = 'SUCCESS' then 1 else 0 end)/ count(*) as "Build Success Rate" +FROM + cicd_pipelines +WHERE + $__timeFilter(finished_date) +ORDER BY 1 +``` + +If you want to measure the distribution of CI build result like the donut chart below, please run the following SQL in Grafana. + +![](/img/Metrics/build-result-distribution.png) + +``` +SELECT + result, + count(*) as build_count +FROM + cicd_pipelines +WHERE + $__timeFilter(finished_date) + and id like "%jenkins%" + and name in ($job_id) + -- the following condition will remove the month with incomplete data + and finished_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) +GROUP BY 1 +ORDER BY 2 DESC +``` + +If you want to measure the `mean build success rate per month` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/build-success-rate-monthly.png) + +``` +WITH _build_success_rate as( + SELECT + DATE_ADD(date(finished_date), INTERVAL -DAYOFMONTH(date(finished_date))+1 DAY) as time, + result + FROM + cicd_pipelines + WHERE + $__timeFilter(finished_date) + -- the following condition will remove the month with incomplete data + and finished_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) +) + +SELECT + date_format(time,'%M %Y') as month, + 1.0 * sum(case when result = 'SUCCESS' then 1 else 0 end)/ count(*) as "Build Success Rate" +FROM _build_success_rate +GROUP BY 1 +ORDER BY 1 +``` + +## How to improve? +1. From the project dimension, compare the number of builds and success rate by combining the project phase and the complexity of tasks. +2. From the time dimension, analyze the trend of the number of builds and success rate to see if it has improved over time. diff --git a/versioned_docs/version-v0.21/Metrics/CFR.md b/versioned_docs/version-v0.21/Metrics/CFR.md new file mode 100644 index 00000000000..7aa2dd2b7e1 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/CFR.md @@ -0,0 +1,163 @@ +--- +title: "DORA - Change Failure Rate" +description: > + DORA - Change Failure Rate +sidebar_position: 29 +--- + +## What is this metric? + +The percentage of changes that were made to a code that then resulted in incidents, rollbacks, or any type of production failure. + +## Why is it important? + +Unlike Deployment Frequency and Lead Time for Changes that measure the throughput, Change Failure Rate measures the stability and quality of software delivery. A low CFR reflects a bad end-user experience as the production failure is relatively high. + +## Which dashboard(s) does it exist in + +DORA dashboard. See [live demo](https://grafana-lake.demo.devlake.io/grafana/d/qNo8_0M4z/dora?orgId=1). + +## How is it calculated? + +The number of deployments affected by incidents/total number of deployments. For example, if there are five deployments and two deployments cause one or more incidents, that is a 40% change failure rate. + +![](/img/Metrics/cfr-definition.png) + +When there are multiple deployments triggered by one pipeline, tools like GitLab and BitBucket will generate more than one deployment. In these cases, DevLake will consider these deployments as ONE deployment and use the last deployment's finished date as the deployment finished date. + +Below are the benchmarks for different development teams from Google's report. However, it's difficult to tell which group a team falls into when the team's change failure rate is `18%` or `40%`. Therefore, DevLake provides its own benchmarks to address this problem: + +| Groups | Benchmarks | DevLake Benchmarks | +| ----------------- | ---------- | ------------------ | +| Elite performers | 0%-15% | 0%-15% | +| High performers | 16%-30% | 16-20% | +| Medium performers | 16%-30% | 21%-30% | +| Low performers | 16%-30% | > 30% | + +

Source: 2021 Accelerate State of DevOps, Google

+ +Data Sources Required + +- `Deployments` from Jenkins, GitLab CI, GitHub Action, BitBucket Pipelines, or Webhook, etc. +- `Incidents` from Jira issues, GitHub issues, TAPD issues, PagerDuty Incidents, etc. + +Transformation Rules Required + +Define `deployment` and `incident` in [data transformations](https://devlake.apache.org/docs/Configuration/Tutorial#step-3---add-transformations-optional) while configuring the blueprint of a project to let DevLake know what CI/issue records can be regarded as deployments or incidents. + +SQL Queries + +If you want to measure the monthly trend of Change Failure Rate, run the following SQL in Grafana. + +![](/img/Metrics/cfr-monthly.jpeg) + +``` +-- Metric 4: change failure rate per month +with _deployments as ( +-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date. + SELECT + cdc.cicd_deployment_id as deployment_id, + max(cdc.finished_date) as deployment_finished_date + FROM + cicd_deployment_commits cdc + JOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes' + WHERE + pm.project_name in ($project) + and cdc.result = 'SUCCESS' + and cdc.environment = 'PRODUCTION' + GROUP BY 1 + HAVING $__timeFilter(max(cdc.finished_date)) +), + +_failure_caused_by_deployments as ( +-- calculate the number of incidents caused by each deployment + SELECT + d.deployment_id, + d.deployment_finished_date, + count(distinct case when i.type = 'INCIDENT' then d.deployment_id else null end) as has_incident + FROM + _deployments d + left join project_issue_metrics pim on d.deployment_id = pim.deployment_id + left join issues i on pim.id = i.id + GROUP BY 1,2 +), + +_change_failure_rate_for_each_month as ( + SELECT + date_format(deployment_finished_date,'%y/%m') as month, + case + when count(deployment_id) is null then null + else sum(has_incident)/count(deployment_id) end as change_failure_rate + FROM + _failure_caused_by_deployments + GROUP BY 1 +) + +SELECT + cm.month, + cfr.change_failure_rate +FROM + calendar_months cm + LEFT JOIN _change_failure_rate_for_each_month cfr on cm.month = cfr.month + WHERE $__timeFilter(cm.month_timestamp) +``` + +If you want to measure in which category your team falls, run the following SQL in Grafana. + +![](/img/Metrics/cfr-text.jpeg) + +``` +with _deployments as ( +-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date. + SELECT + cdc.cicd_deployment_id as deployment_id, + max(cdc.finished_date) as deployment_finished_date + FROM + cicd_deployment_commits cdc + JOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id + WHERE + pm.project_name in ($project) + and cdc.result = 'SUCCESS' + and cdc.environment = 'PRODUCTION' + GROUP BY 1 + HAVING $__timeFilter(max(cdc.finished_date)) +), + +_failure_caused_by_deployments as ( +-- calculate the number of incidents caused by each deployment + SELECT + d.deployment_id, + d.deployment_finished_date, + count(distinct case when i.type = 'INCIDENT' then d.deployment_id else null end) as has_incident + FROM + _deployments d + left join project_issue_metrics pim on d.deployment_id = pim.deployment_id + left join issues i on pim.id = i.id + GROUP BY 1,2 +), + +_change_failure_rate as ( + SELECT + case + when count(deployment_id) is null then null + else sum(has_incident)/count(deployment_id) end as change_failure_rate + FROM + _failure_caused_by_deployments +) + +SELECT + case + when change_failure_rate <= .15 then "0-15%" + when change_failure_rate <= .20 then "16%-20%" + when change_failure_rate <= .30 then "21%-30%" + else "> 30%" + end as change_failure_rate +FROM + _change_failure_rate +``` + +## How to improve? + +- Add unit tests for all new feature +- "Shift left", start QA early and introduce more automated tests +- Enforce code review if it's not strictly executed diff --git a/versioned_docs/version-v0.21/Metrics/CQDuplicatedBlocks.md b/versioned_docs/version-v0.21/Metrics/CQDuplicatedBlocks.md new file mode 100644 index 00000000000..e91f15ed440 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/CQDuplicatedBlocks.md @@ -0,0 +1,42 @@ +--- +title: "Code Quality Duplicated Blocks" +description: > + Code Quality Duplicated Blocks +sidebar_position: 33 +--- + +## What is this metric? + +This metric is the number of duplicated blocks of lines. This metric is collected from SonarQube, check [this doc](https://docs.sonarqube.org/latest/user-guide/metric-definitions/#duplications) for detailed definition. + +## Why is it important? + +Duplicated Blocks is a code metric that measures the amount of duplicated code in a project. Duplicated blocks are sequences of code that are identical or nearly identical to each other, and can occur within a single file or across multiple files. Duplicated code can make the codebase harder to maintain, increase the risk of bugs and errors, and make it more difficult to understand and modify the code. Identifying and removing duplicated code can improve the maintainability, reliability, and readability of the codebase, and reduce the risk of introducing bugs or errors in the future. + +## Which dashboard(s) does it exist in? + +- [SonarQube](/livedemo/DataSources/SonarQube) + +## How is it calculated? + +This metric is calculated by counting the total number of duplicated_blocks. + +Data Sources Required + +This metric relies on file metrics collected from SonarQube. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find duplicated blocks of lines in specific projects, eg. 'project1' and 'project2'. + +``` +SELECT + sum(duplicated_blocks) +FROM cq_file_metrics +WHERE + project_key in ('project1', 'project2') +``` diff --git a/versioned_docs/version-v0.21/Metrics/CQDuplicatedLines.md b/versioned_docs/version-v0.21/Metrics/CQDuplicatedLines.md new file mode 100644 index 00000000000..73c2b2c0586 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/CQDuplicatedLines.md @@ -0,0 +1,43 @@ +--- +title: "Code Quality Duplicated Lines" +description: > + Code Quality Duplicated Lines +sidebar_position: 34 +--- + +## What is this metric? + +This metric is the number of files involved in duplications. This metric is collected from SonarQube, check [this doc](https://docs.sonarqube.org/latest/user-guide/metric-definitions/#duplications) for detailed definition. + +## Why is it important? + +Duplicated lines are individual lines of code that are identical or nearly identical to each other, and can occur within a single file or across multiple files. Duplicated code can make the codebase harder to maintain, increase the risk of bugs and errors, and make it more difficult to understand and modify the code. Identifying and removing duplicated code can improve the maintainability, reliability, and readability of the codebase, and reduce the risk of introducing bugs or errors in the future. + +## Which dashboard(s) does it exist in? + +- [SonarQube](/livedemo/DataSources/SonarQube) + +## How is it calculated? + +This SQL query calculates the percentage of duplicated lines in a project, as well as the total number of lines in the project. +The sum(duplicated_lines) represents the total number of duplicated lines in the project, while sum(num_of_lines) represents the total number of lines of code. These two values are divided and multiplied by 100 to get the percentage of duplicated lines in the project. + +Data Sources Required + +This metric relies on file metrics collected from SonarQube. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the number of files involved in duplications in specific projects, eg. 'project1' and 'project2'. + +``` +SELECT + CONCAT(ROUND(sum(duplicated_lines) / sum(num_of_lines) * 100, 1), '% ', 'Duplications on ', ROUND(sum(ncloc) / 1000, 0),'k Lines') +FROM cq_file_metrics +WHERE + project_key in ('project1', 'project2') +``` diff --git a/versioned_docs/version-v0.21/Metrics/CQIssueCount.md b/versioned_docs/version-v0.21/Metrics/CQIssueCount.md new file mode 100644 index 00000000000..e3eb5c12644 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/CQIssueCount.md @@ -0,0 +1,97 @@ +--- +title: "Code Quality Issue Count" +description: > + Code Quality Issue Count +sidebar_position: 30 +--- + +## What is this metric? + +This metric is a the total number of issues found in a project by SonarQube. It includes various types of issues such as bugs, vulnerabilities, code smells, and security hotspots. This metric is collected from SonarQube, check [this doc](https://docs.sonarqube.org/latest/user-guide/metric-definitions/#issues) for detailed definition. + +## Why is it important? + +Issue provides information about potential problems or issues in the code. Issues can include bugs, vulnerabilities, and code smells, which can all affect the maintainability, reliability, and security of the codebase. By identifying and addressing issues, developers can improve the quality of their code and reduce technical debt. Additionally, tracking issues over time can help to identify trends and measure progress in improving code quality. + +## Which dashboard(s) does it exist in? + +- [SonarQube](/livedemo/DataSources/SonarQube) + +## How is it calculated? + +This metric is calculated by counting the total number of cq_issues. + +Data Sources Required + +This metric relies on issues collected from SonarQube. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find issues in specific projects, eg. 'project1' and 'project2'. + +1. To get the issue count of 'BUG', please add the condition `type = BUG` + +``` +SELECT + count(*) as 'Bugs' +FROM cq_issues +WHERE + $__timeFilter(created_date) + and project_key in ('project1', 'project2') + and `type` = 'BUG' +ORDER BY created_date +``` + +2. To get the issue count of 'VULNERABILITY', please add the condition `type = VULNERABILITY` + +``` +SELECT + count(*) as 'Vulnerabilities' +FROM cq_issues +WHERE + $__timeFilter(created_date) + and project_key in ('project1', 'project2') + and `type` = 'VULNERABILITY' +ORDER BY created_date +``` + +3. To get the issue count of 'HOTSPOTS', please add the condition `type = HOTSPOTS` + +``` +SELECT + COUNT(IF(status = 'TO_REVIEW', 1, NULL)) AS 'Security Hotspots' +FROM cq_issues +WHERE + $__timeFilter(created_date) + and project_key in ('project1', 'project2') + and `type` = 'HOTSPOTS' +ORDER BY created_date +``` + +``` +SELECT + CONCAT(ROUND(COUNT(IF(status != 'TO_REVIEW', 1, NULL)) / COUNT(*) * 100, 2), '%') AS 'Reviewed' +FROM cq_issues +WHERE + $__timeFilter(created_date) + and project_key in ('project1', 'project2') + and `type` = 'HOTSPOTS' +ORDER BY created_date +``` + +4. To get the issue count of 'CODE_SMELL', please add the condition `type = CODE_SMELL` + +``` +SELECT + COUNT(if(type = 'CODE_SMELL', 1, null)) as 'Code Smells' +FROM cq_issues +WHERE + $__timeFilter(created_date) + and project_key in ('project1', 'project2') +``` + +![](/img/Metrics/issue-type-count.png) diff --git a/versioned_docs/version-v0.21/Metrics/CQMaintainability-Debt.md b/versioned_docs/version-v0.21/Metrics/CQMaintainability-Debt.md new file mode 100644 index 00000000000..fa5e80a7e2a --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/CQMaintainability-Debt.md @@ -0,0 +1,43 @@ +--- +title: "Code Quality Maintainability-Debt" +description: > + Code Quality Maintainability-Debt +sidebar_position: 32 +--- + +## What is this metric? + +This metric is a measure of effort to fix all code smells. This metric is collected from SonarQube, check [this doc](https://docs.sonarqube.org/latest/user-guide/metric-definitions/#maintainability) for detailed definition. + +## Why is it important? + +It helps developers and project managers understand the costs and risks associated with maintaining the codebase. High levels of technical debt can lead to more bugs, slower development cycles, and higher maintenance costs over time. By monitoring technical debt and working to reduce it, developers can ensure that their code is easier to maintain, more reliable, and more scalable. + +## Which dashboard(s) does it exist in? + +- [SonarQube](/livedemo/DataSources/SonarQube) + +## How is it calculated? + +This SQL query calculates the total technical debt in days for all issues in the SonarQube instance. check [this doc](https://docs.sonarqube.org/latest/user-guide/metric-definitions/#maintainability) for detailed info. + +Data Sources Required + +This metric relies on issues collected from SonarQube. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find effort to fix all code smells in specific projects, eg. 'project1' and 'project2'. + +``` +SELECT + CONCAT(ROUND(SUM(debt) / (8 * 60), 0), ' days') AS 'Debt' +FROM cq_issues +WHERE + $__timeFilter(created_date) + project_key in ('project1', 'project2') +``` diff --git a/versioned_docs/version-v0.21/Metrics/CQTest.md b/versioned_docs/version-v0.21/Metrics/CQTest.md new file mode 100644 index 00000000000..c2977a776f8 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/CQTest.md @@ -0,0 +1,42 @@ +--- +title: "Code Quality Test" +description: > + Code Quality Test +sidebar_position: 31 +--- + +## What is this metric? + +This metric is the number of unit tests that have been executed against the code. This metric is collected from SonarQube, check [this doc](https://docs.sonarqube.org/latest/user-guide/metric-definitions/#tests) for detailed definition. + +## Why is it important? + +Test is an indicator used to indicate the test coverage of the code. This means that SonarQube checks that your code contains enough test cases to cover the various paths and branches in your code. This metric can help you understand the extent of your code test coverage, thereby determining your code quality and stability. + +## Which dashboard(s) does it exist in? + +- [SonarQube](/livedemo/DataSources/SonarQube) + +## How is it calculated? + +This SQL query retrieves the test coverage percentage for the lines to cover in a project from the cq_file_metrics table in SonarQube. The query calculates the percentage by subtracting the number of uncovered lines from the total number of lines to cover, then dividing the result by the total number of lines to cover, and multiplying by 100. The result is rounded to one decimal point and displayed as a percentage. Additionally, the query also includes a message that shows the total number of lines to cover in thousands. + +Data Sources Required + +This metric relies on file_metrics collected from SonarQube. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find unit tests that have been executed against the code in specific projects, eg. 'project1' and 'project2'. + +``` +SELECT + CONCAT(ROUND((sum(lines_to_cover) - sum(uncovered_lines)) / sum(lines_to_cover) * 100, 1), '% ', 'Coverage on ', ROUND(sum(lines_to_cover) / 1000, 0),'k Lines to cover') +FROM cq_file_metrics +WHERE + project_key in ('project1', 'project2') +``` diff --git a/versioned_docs/version-v0.21/Metrics/CommitAuthorCount.md b/versioned_docs/version-v0.21/Metrics/CommitAuthorCount.md new file mode 100644 index 00000000000..46bf55934c7 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/CommitAuthorCount.md @@ -0,0 +1,52 @@ +--- +title: "Commit Author Count" +description: > + Commit Author Count +sidebar_position: 10 +--- + +## What is this metric? +The number of commit authors who have committed code. + +## Why is it important? +Take inventory of project/team R&D resource inputs, assess input-output ratio, and rationalize resource deployment. + + +## Which dashboard(s) does it exist in +N/A + + +## How is it calculated? +This metric is calculated by counting the number of commit authors in the given data range. + +Data Sources Required + +This metric relies on commits collected from GitHub, GitLab or BitBucket. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the `commit author count` in specific repositories, eg. 'repo-1' and 'repo-2'. + +``` +SELECT + count(distinct c.author_id) +FROM + commits c + LEFT JOIN repo_commits rc ON c.sha = rc.commit_sha + LEFT JOIN repos r ON r.id = rc.repo_id +WHERE + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + r.id in ('repo-1', 'repo-2') + and message not like '%Merge%' + and $__timeFilter(c.authored_date) + -- the following condition will remove the month with incomplete data + and c.authored_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) +``` + + +## How to improve? +As a secondary indicator, this helps assess the labor cost of participating in coding. diff --git a/versioned_docs/version-v0.21/Metrics/CommitCount.md b/versioned_docs/version-v0.21/Metrics/CommitCount.md new file mode 100644 index 00000000000..336accb7205 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/CommitCount.md @@ -0,0 +1,83 @@ +--- +title: "Commit Count" +description: > + Commit Count +sidebar_position: 9 +--- + +## What is this metric? +The number of commits created. + +## Why is it important? +1. Identify potential bottlenecks that may affect output +2. Encourage R&D practices of small step submissions and develop excellent coding habits + +## Which dashboard(s) does it exist in +- GitHub Release Quality and Contribution Analysis +- Demo-Is this month more productive than last? +- Demo-Commit Count by Author + +## How is it calculated? +This metric is calculated by counting the number of commits in the given data range. + +Data Sources Required + +This metric relies on commits collected from GitHub, GitLab or BitBucket. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find commits in specific repositories, eg. 'repo-1' and 'repo-2'. +``` +SELECT + r.id, + c.* +FROM + commits c + LEFT JOIN repo_commits rc ON c.sha = rc.commit_sha + LEFT JOIN repos r ON r.id = rc.repo_id +WHERE + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + r.id in ('repo-1','repo-2') + and message not like '%Merge%' + and $__timeFilter(c.authored_date) + -- the following condition will remove the month with incomplete data + and c.authored_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) +``` + +If you want to measure the monthly trend of `commit count` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/commit-count-monthly.png) + +``` +with _commits as( + SELECT + DATE_ADD(date(c.authored_date), INTERVAL -DAY(date(c.authored_date))+1 DAY) as time, + count(c.sha) as commit_count + FROM + commits c + LEFT JOIN repo_commits rc ON c.sha = rc.commit_sha + LEFT JOIN repos r ON r.id = rc.repo_id + WHERE + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + r.id in ($repo_id) + and message not like '%Merge%' + and $__timeFilter(c.authored_date) + -- the following condition will remove the month with incomplete data + and c.authored_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + group by 1 +) + +SELECT + date_format(time,'%M %Y') as month, + commit_count as "Commit Count" +FROM _commits +ORDER BY time +``` + +## How to improve? +1. Identify the main reasons for the unusual number of commits and the possible impact on the number of commits through comparison +2. Evaluate whether the number of commits is reasonable in conjunction with more microscopic workload metrics (e.g. lines of code/code equivalents) diff --git a/versioned_docs/version-v0.21/Metrics/DeletedLinesOfCode.md b/versioned_docs/version-v0.21/Metrics/DeletedLinesOfCode.md new file mode 100644 index 00000000000..a1491a1b07b --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/DeletedLinesOfCode.md @@ -0,0 +1,77 @@ +--- +title: "Deleted Lines of Code" +description: > + Deleted Lines of Code +sidebar_position: 12 +--- + +## What is this metric? +The accumulated number of deleted lines of code. + +## Why is it important? +1. identify potential bottlenecks that may affect the output +2. Encourage the team to implement a development model that matches the business requirements; develop excellent coding habits + +## Which dashboard(s) does it exist in +N/A + +## How is it calculated? +This metric is calculated by summing the deletions of commits in the given data range. + +Data Sources Required + +This metric relies on `commits` collected from GitHub, GitLab or BitBucket. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the `deleted lines of code` in specific repositories, eg. 'repo-1' and 'repo-2'. + +``` +SELECT + sum(c.deletions) as deleted_lines_of_code +FROM + commits c + LEFT JOIN repo_commits rc ON c.sha = rc.commit_sha + LEFT JOIN repos r ON r.id = rc.repo_id +WHERE + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + r.id in ('repo-1','repo-2') + and message not like '%Merge%' + and $__timeFilter(c.authored_date) + -- the following condition will remove the month with incomplete data + and c.authored_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) +``` + +If you want to measure the monthly trend of `deleted lines of code` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/deleted-loc-monthly.png) + +``` +with _commits as( + SELECT + DATE_ADD(date(authored_date), INTERVAL -DAY(date(authored_date))+1 DAY) as time, + sum(deletions) as deleted_lines_of_code + FROM commits + WHERE + message not like '%Merge%' + and $__timeFilter(authored_date) + -- the following condition will remove the month with incomplete data + and authored_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + group by 1 +) + +SELECT + date_format(time,'%M %Y') as month, + deleted_lines_of_code +FROM _commits +ORDER BY time +``` + +## How to improve? +1. From the project/team dimension, observe the accumulated change in Added lines to assess the team activity and code growth rate +2. From version cycle dimension, observe the active time distribution of code changes, and evaluate the effectiveness of project development model. +3. From the member dimension, observe the trend and stability of code output of each member, and identify the key points that affect code output by comparison. diff --git a/versioned_docs/version-v0.21/Metrics/DeploymentFrequency.md b/versioned_docs/version-v0.21/Metrics/DeploymentFrequency.md new file mode 100644 index 00000000000..bae538ef0c0 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/DeploymentFrequency.md @@ -0,0 +1,180 @@ +--- +title: "DORA - Deployment Frequency" +description: > + DORA - Deployment Frequency +sidebar_position: 26 +--- + +## What is this metric? + +How often an organization deploys code to production or release it to end users. Below is a picture showing the definition of DevLake `deployments`. + +![](../Configuration/images/deployment_definition.png) + +## Why is it important? + +Deployment frequency reflects the efficiency of a team's deployment. A team that deploys more frequently can deliver the product faster and users' feature requirements can be met faster. + +## Which dashboard(s) does it exist in + +DORA dashboard. See [live demo](https://grafana-lake.demo.devlake.io/grafana/d/qNo8_0M4z/dora?orgId=1). + +## How is it calculated? + +Deployment frequency is calculated based on the number of `deployment days`, not the number of deployments, e.g., daily, weekly, monthly, yearly. + +When there are multiple deployments triggered by one pipeline, tools like GitLab and BitBucket will generate more than one deployment. In these cases, DevLake will consider these deployments as ONE deployment and use the last deployment's finished date as the deployment finished date. + +Below are the benchmarks for different development teams from Google's report. DevLake uses the same benchmarks. + +| Groups | Benchmarks | DevLake Benchmarks | The Criteria of DevLake Benchmarks | +| ----------------- | ---------------------------------------------- | ---------------------------------------------- | --------------------------------------------------| +| Elite performers | On-demand (multiple deploys per day) | On-demand | Median Number of `Deployment Days` per Week >= 3 | +| High performers | Between once per week and once per month | Between once per week and once per month | Median Number of `Deployment Days` per Week >= 1 | +| Medium performers | Between once per month and once every 6 months | Between once per month and once every 6 months | Median Number of `Deployment Days` per Month >= 1 | +| Low performers | Fewer than once per six months | Fewer than once per six months | Median Number of `Deployment Days` per Month < 1 | + +

Source: 2021 Accelerate State of DevOps, Google

+ +Data Sources Required + +`Deployments` from Jenkins, GitLab CI, GitHub Action, BitBucket Pipelines, Webhook, etc. + +Transformation Rules Required + +Define `deployment` in [data transformations](https://devlake.apache.org/docs/Configuration/Tutorial#step-3---add-transformations-optional) while configuring the blueprint of a project to let DevLake know what CI records can be regarded as deployments. + +SQL Queries + +DevLake deployments can be found in table [cicd_deployment_commits](/docs/DataModels/DevLakeDomainLayerSchema.md#cicd_deployment_commits). If you want to measure the monthly trend of deployment count as the picture shown below, run the following SQL in Grafana. + +![](/img/Metrics/deployment-frequency-monthly.jpeg) + +``` +-- Metric 1: Number of deployments per month +with _deployments as( +-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date. + SELECT + date_format(deployment_finished_date,'%y/%m') as month, + count(cicd_deployment_id) as deployment_count + FROM ( + SELECT + cdc.cicd_deployment_id, + max(cdc.finished_date) as deployment_finished_date + FROM cicd_deployment_commits cdc + JOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes' + WHERE + pm.project_name in ($project) + and cdc.result = 'SUCCESS' + and cdc.environment = 'PRODUCTION' + GROUP BY 1 + HAVING $__timeFilter(max(cdc.finished_date)) + ) _production_deployments + GROUP BY 1 +) + +SELECT + cm.month, + case when d.deployment_count is null then 0 else d.deployment_count end as deployment_count +FROM + calendar_months cm + LEFT JOIN _deployments d on cm.month = d.month + WHERE $__timeFilter(cm.month_timestamp) +``` + +If you want to measure in which category your team falls as in the picture shown below, run the following SQL in Grafana. Unlike monthly deployments which are based on the number of deployments, the metric below is based on `deployment days`. + +![](/img/Metrics/deployment-frequency-text.jpeg) + +``` +with last_few_calendar_months as( +-- construct the last few calendar months within the selected time period in the top-right corner + SELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day + FROM ( SELECT 0 H + UNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300 + ) H CROSS JOIN ( SELECT 0 T + UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30 + UNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60 + UNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90 + ) T CROSS JOIN ( SELECT 0 U + UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 + UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 + UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 + ) U + WHERE + (SYSDATE()-INTERVAL (H+T+U) DAY) > $__timeFrom() +), + +_production_deployment_days as( +-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date. + SELECT + cdc.cicd_deployment_id as deployment_id, + max(DATE(cdc.finished_date)) as day + FROM cicd_deployment_commits cdc + JOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id + WHERE + pm.project_name in ($project) + and cdc.result = 'SUCCESS' + and cdc.environment = 'PRODUCTION' + GROUP BY 1 +), + +_days_weeks_deploy as( +-- calculate the number of deployment days every week + SELECT + date(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week, + MAX(if(_production_deployment_days.day is not null, 1, 0)) as weeks_deployed, + COUNT(distinct _production_deployment_days.day) as days_deployed + FROM + last_few_calendar_months + LEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day + GROUP BY week + ), + +_monthly_deploy as( +-- calculate the number of deployment days every month + SELECT + date(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month, + MAX(if(_production_deployment_days.day is not null, 1, 0)) as months_deployed + FROM + last_few_calendar_months + LEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day + GROUP BY month + ), + +_median_number_of_deployment_days_per_week_ranks as( + SELECT *, percent_rank() over(order by days_deployed) as ranks + FROM _days_weeks_deploy +), + +_median_number_of_deployment_days_per_week as( + SELECT max(days_deployed) as median_number_of_deployment_days_per_week + FROM _median_number_of_deployment_days_per_week_ranks + WHERE ranks <= 0.5 +), + +_median_number_of_deployment_days_per_month_ranks as( + SELECT *, percent_rank() over(order by months_deployed) as ranks + FROM _monthly_deploy +), + +_median_number_of_deployment_days_per_month as( + SELECT max(months_deployed) as median_number_of_deployment_days_per_month + FROM _median_number_of_deployment_days_per_month_ranks + WHERE ranks <= 0.5 +) + +SELECT + CASE + WHEN median_number_of_deployment_days_per_week >= 3 THEN 'On-demand' + WHEN median_number_of_deployment_days_per_week >= 1 THEN 'Between once per week and once per month' + WHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per month and once every 6 months' + ELSE 'Fewer than once per six months' END AS 'Deployment Frequency' +FROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month +``` + +## How to improve? + +- Trunk development. Work in small batches and often merge their work into shared trunks. +- Integrate CI/CD tools for automated deployment +- Improve automated test coverage diff --git a/versioned_docs/version-v0.21/Metrics/IncidentAge.md b/versioned_docs/version-v0.21/Metrics/IncidentAge.md new file mode 100644 index 00000000000..edf0307725d --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/IncidentAge.md @@ -0,0 +1,76 @@ +--- +title: "Incident Age" +description: > + Incident Age +sidebar_position: 7 +--- + +## What is this metric? +The amount of time it takes an incident to fix. + +## Why is it important? +1. Help the team to establish an effective hierarchical response mechanism for incidents. Focus on the resolution of important problems in the backlog. +2. Improve team's and individual's incident fixing efficiency. Identify good/to-be-improved practices that affect incident age + +## Which dashboard(s) does it exist in +- [Jira](https://devlake.apache.org/livedemo/DataSources/Jira) +- [GitHub](https://devlake.apache.org/livedemo/DataSources/GitHub) + + +## How is it calculated? +Similar to [requirement lead time](./RequirementLeadTime.md), this metric equals `resolution_date - created_date` of issues in type "INCIDENT". + +Data Sources Required + +This metric relies on `issues` collected from Jira, GitHub, TAPD, or PagerDuty. + +Transformation Rules Required + +This metric relies on the 'type-incident' configuration in Jira, GitHub or TAPD's transformation rules while adding/editing a blueprint. This configuration tells DevLake what issues are `incidents`. + +SQL Queries + +The following SQL shows how to find the incident age of a specific `incident`. +``` +-- lead_time_minutes is a pre-calculated field whose value equals 'resolution_date - created_date' +SELECT + lead_time_minutes/1440 as incident_age_in_days +FROM + issues +WHERE + type = 'INCIDENT' +``` + +If you want to measure the `mean incident age` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/incident-age-monthly.png) + +``` +with _incidents as( + SELECT + DATE_ADD(date(i.resolution_date), INTERVAL -DAY(date(i.resolution_date))+1 DAY) as time, + AVG(i.lead_time_minutes/1440) as issue_lead_time + FROM issues i + join board_issues bi on i.id = bi.issue_id + join boards b on bi.board_id = b.id + WHERE + -- $board_id is a variable defined in Grafana's dashboard settings to filter out issues by boards + b.id in ($board_id) + and i.status = "DONE" + and i.type = 'INCIDENT' + and $__timeFilter(i.resolution_date) + -- the following condition will remove the month with incomplete data + and i.resolution_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + group by 1 +) + +SELECT + date_format(time,'%M %Y') as month, + issue_lead_time as "Mean Incident Age in Days" +FROM _incidents +ORDER BY time +``` + +## How to improve? +1. Observe the trend of incident age and locate the key reasons. +2. Compare the age of incidents by severity levels, types (business, functional classification), affected components, etc. \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Metrics/IncidentCountPer1kLinesOfCode.md b/versioned_docs/version-v0.21/Metrics/IncidentCountPer1kLinesOfCode.md new file mode 100644 index 00000000000..c789c0667bb --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/IncidentCountPer1kLinesOfCode.md @@ -0,0 +1,88 @@ +--- +title: "Incident Count per 1k Lines of Code" +description: > + Incident Count per 1k Lines of Code +sidebar_position: 8 +--- + +## What is this metric? +Amount of incidents per 1,000 lines of code. + +## Why is it important? +1. Defect drill-down analysis to inform the development of design and code review strategies and to improve the internal QA process +2. Assist teams to locate projects/modules with higher defect severity and density, and clean up technical debts +3. Identify good/to-be-improved practices that affect defect count or defect rate, to reduce the number of future defects + +## Which dashboard(s) does it exist in +N/A + + +## How is it calculated? +The number of incidents divided by total accumulated lines of code (additions + deletions) in the given data range. + +Data Sources Required + +- `issues` collected from Jira, GitHub, TAPD or PagerDuty. +- `commits` collected from GitHub, GitLab or BitBucket. + +Data Transformation Required + +This metric relies on the 'type-incident' configuration in Jira, GitHub or TAPD's transformation rules while adding/editing a blueprint. This configuration tells DevLake what issues are `incidents`. + +SQL Queries + +If you want to measure the monthly trend of `Incidents per 1k lines of code` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/incident-per-1k-loc-monthly.png) + +``` +with _line_of_code as ( + select + DATE_ADD(date(authored_date), INTERVAL -DAY(date(authored_date))+1 DAY) as time, + sum(additions + deletions) as line_count + from + commits + where + message not like 'Merge%' + and $__timeFilter(authored_date) + group by 1 +), + + +_incident_count as( + select + DATE_ADD(date(created_date), INTERVAL -DAY(date(created_date))+1 DAY) as time, + count(*) as incident_count + from issues i + where + type = 'INCIDENT' + and $__timeFilter(created_date) + group by 1 +), + + +_incident_count_per_1k_loc as( + select + loc.time, + 1.0 * ic.incident_count / loc.line_count * 1000 as incident_count_per_1k_loc + from + _line_of_code loc + left join _incident_count ic on ic.time = loc.time + where + ic.incident_count is not null + and loc.line_count is not null + and loc.line_count != 0 +) + +select + date_format(time,'%M %Y') as month, + incident_count_per_1k_loc as 'Incident Count per 1000 Lines of Code' +from _incident_count_per_1k_loc +order by time; +``` + +## How to improve? +1. From the project or team dimension, observe the statistics on the total number of defects, the distribution of the number of defects in each severity level/type/owner, the cumulative trend of defects, and the change trend of the defect rate in thousands of lines, etc. +2. From version cycle dimension, observe the statistics on the cumulative trend of the number of defects/defect rate, which can be used to determine whether the growth rate of defects is slowing down, showing a flat convergence trend, and is an important reference for judging the stability of software version quality +3. From the time dimension, analyze the trend of the number of test defects, defect rate to locate the key items/key points +4. Evaluate whether the software quality and test plan are reasonable by referring to CMMI standard values diff --git a/versioned_docs/version-v0.21/Metrics/LeadTimeForChanges.md b/versioned_docs/version-v0.21/Metrics/LeadTimeForChanges.md new file mode 100644 index 00000000000..f18ec3963be --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/LeadTimeForChanges.md @@ -0,0 +1,150 @@ +--- +title: "DORA - Median Lead Time for Changes" +description: > + DORA - Median Lead Time for Changes +sidebar_position: 27 +--- + +## What is this metric? + +The median amount of time for a code change to be deployed into production. + +## Why is it important? + +This metric measures the time it takes to a code change to the production environment and reflects the speed of software delivery. A lower average change preparation time means that your team is efficient at coding and deploying your project. + +## Which dashboard(s) does it exist in + +DORA dashboard. See [live demo](https://grafana-lake.demo.devlake.io/grafana/d/qNo8_0M4z/dora?orgId=1). + +## How is it calculated? +This metric is quite similar to [PR Cycle Time](PRCycleTime.md). The difference is that 'Lead Time for Changes' uses a different method to filter PRs. + +1. Find the PRs' associated deployment commits whose finished_date falls into the time range that users select. +2. Find the associated pull requests of the commits diff between two consecutive successful `deployment commits` in the production environment. +3. Calculate the PRs' median cycle time. This will be the Median Lead Time for Changes. + +![](../Configuration/images/lead_time_for_changes_definition.png) + +PR cycle time is pre-calculated by the `dora` plugin during every data collection. You can find it in `pr_cycle_time` in [table.project_pr_metrics](https://devlake.apache.org/docs/DataModels/DevLakeDomainLayerSchema/#project_pr_metrics) of DevLake's database. + +Below are the benchmarks for different development teams from Google's report. However, it's difficult to tell which group a team falls into when the team's median lead time for changes is `between one week and one month`. Therefore, DevLake provides its own benchmarks to address this problem: + +| Groups | Benchmarks | DevLake Benchmarks | +| ----------------- | -------------------------------- | ------------------------------- | +| Elite performers | Less than one hour | Less than one hour | +| High performers | Between one day and one week | Less than one week | +| Medium performers | Between one month and six months | Between one week and six months | +| Low performers | More than six months | More than six months | + +

Source: 2021 Accelerate State of DevOps, Google

+ +Data Sources Required + +- `Deployments` from Jenkins, GitLab CI, GitHub Action, BitBucket Pipelines, Webhook, etc. +- `Pull Requests` from GitHub PRs, GitLab MRs, BitBucket PRs, Azure DevOps PRs, etc. + +Transformation Rules Required + +Define `deployment` in [data transformations](https://devlake.apache.org/docs/Configuration/Tutorial#step-3---add-transformations-optional) while configuring the blueprint of a project to let DevLake know what CI records can be regarded as deployments. + +SQL Queries + +If you want to measure the monthly trend of median lead time for changes as the picture shown below, run the following SQL in Grafana. + +![](/img/Metrics/lead-time-for-changes-monthly.jpeg) + +``` +-- Metric 2: median change lead time per month +with _pr_stats as ( +-- get the cycle time of PRs deployed by the deployments finished each month + SELECT + distinct pr.id, + date_format(cdc.finished_date,'%y/%m') as month, + ppm.pr_cycle_time + FROM + pull_requests pr + join project_pr_metrics ppm on ppm.id = pr.id + join project_mapping pm on pr.base_repo_id = pm.row_id and pm.`table` = 'repos' + join cicd_deployment_commits cdc on ppm.deployment_commit_id = cdc.id + WHERE + pm.project_name in ($project) + and pr.merged_date is not null + and ppm.pr_cycle_time is not null + and $__timeFilter(cdc.finished_date) +), + +_find_median_clt_each_month_ranks as( + SELECT *, percent_rank() over(PARTITION BY month order by pr_cycle_time) as ranks + FROM _pr_stats +), + +_clt as( + SELECT month, max(pr_cycle_time) as median_change_lead_time + FROM _find_median_clt_each_month_ranks + WHERE ranks <= 0.5 + group by month +) + +SELECT + cm.month, + case + when _clt.median_change_lead_time is null then 0 + else _clt.median_change_lead_time/60 end as median_change_lead_time_in_hour +FROM + calendar_months cm + LEFT JOIN _clt on cm.month = _clt.month + WHERE $__timeFilter(cm.month_timestamp) +``` + +If you want to measure in which category your team falls as in the picture shown below, run the following SQL in Grafana. + +![](/img/Metrics/lead-time-for-changes-text.jpeg) + +``` +with _pr_stats as ( +-- get the cycle time of PRs deployed by the deployments finished in the selected period + SELECT + distinct pr.id, + ppm.pr_cycle_time + FROM + pull_requests pr + join project_pr_metrics ppm on ppm.id = pr.id + join project_mapping pm on pr.base_repo_id = pm.row_id + join cicd_deployment_commits cdc on ppm.deployment_commit_id = cdc.id + WHERE + pm.project_name in ($project) + and pr.merged_date is not null + and ppm.pr_cycle_time is not null + and $__timeFilter(cdc.finished_date) +), + +_median_change_lead_time_ranks as( + SELECT *, percent_rank() over(order by pr_cycle_time) as ranks + FROM _pr_stats +), + +_median_change_lead_time as( +-- use median PR cycle time as the median change lead time + SELECT max(pr_cycle_time) as median_change_lead_time + FROM _median_change_lead_time_ranks + WHERE ranks <= 0.5 +) + +SELECT + CASE + WHEN median_change_lead_time < 60 then "Less than one hour" + WHEN median_change_lead_time < 7 * 24 * 60 then "Less than one week" + WHEN median_change_lead_time < 180 * 24 * 60 then "Between one week and six months" + WHEN median_change_lead_time >= 180 * 24 * 60 then "More than six months" + ELSE "N/A.Please check if you have collected deployments/incidents." + END as median_change_lead_time +FROM _median_change_lead_time +``` + +## How to improve? + +- Break requirements into smaller, more manageable deliverables +- Optimize the code review process +- "Shift left", start QA early and introduce more automated tests +- Integrate CI/CD tools to automate the deployment process diff --git a/versioned_docs/version-v0.21/Metrics/MTTR.md b/versioned_docs/version-v0.21/Metrics/MTTR.md new file mode 100644 index 00000000000..34829efdc23 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/MTTR.md @@ -0,0 +1,143 @@ +--- +title: "DORA - Median Time to Restore Service" +description: > + DORA - Median Time to Restore Service +sidebar_position: 28 +--- + +## What is this metric? + +The time to restore service after service incidents, rollbacks, or any type of production failure happened. + +## Why is it important? + +This metric is essential to measure the disaster control capability of your team and the robustness of the software. + +## Which dashboard(s) does it exist in + +DORA dashboard. See [live demo](https://grafana-lake.demo.devlake.io/grafana/d/qNo8_0M4z/dora?orgId=1). + +## How is it calculated? + +MTTR = Total [incident age](./IncidentAge.md) (in hours)/number of incidents. + +If you have three incidents that happened in the given data range, one lasting 1 hour, one lasting 2 hours and one lasting 3 hours. Your MTTR will be: (1 + 2 + 3) / 3 = 2 hours. + +Below are the benchmarks for different development teams from Google's report. However, it's difficult to tell which group a team falls into when the team's median time to restore service is `between one week and six months`. Therefore, DevLake provides its own benchmarks to address this problem: + +| Groups | Benchmarks | DevLake Benchmarks | +| ----------------- | ---------------------------- | ---------------------------- | +| Elite performers | Less than one hour | Less than one hour | +| High performers | Less one day | Less than one day | +| Medium performers | Between one day and one week | Between one day and one week | +| Low performers | More than six months | More than one week | + +

Source: 2021 Accelerate State of DevOps, Google

+ +Data Sources Required + +- `Deployments` from Jenkins, GitLab CI, GitHub Action, BitBucket Pipelines, or Webhook, etc. +- `Incidents` from Jira issues, GitHub issues, TAPD issues, PagerDuty Incidents, etc. + +Transformation Rules Required + +Define `deployment` and `incident` in [data transformations](https://devlake.apache.org/docs/Configuration/Tutorial#step-3---add-transformations-optional) while configuring the blueprint of a project to let DevLake know what CI/issue records can be regarded as deployments or incidents. + +SQL Queries + +If you want to measure the monthly trend of the Median Time to Restore Service as the picture shown below, run the following SQL in Grafana. + +![](/img/Metrics/mttr-monthly.jpeg) + +``` +-- Metric 3: median time to restore service - MTTR +with _incidents as ( +-- get the number of incidents created each month + SELECT + distinct i.id, + date_format(i.created_date,'%y/%m') as month, + cast(lead_time_minutes as signed) as lead_time_minutes + FROM + issues i + join board_issues bi on i.id = bi.issue_id + join boards b on bi.board_id = b.id + join project_mapping pm on b.id = pm.row_id and pm.`table` = 'boards' + WHERE + pm.project_name in ($project) + and i.type = 'INCIDENT' + and i.lead_time_minutes is not null +), + +_find_median_mttr_each_month_ranks as( + SELECT *, percent_rank() over(PARTITION BY month order by lead_time_minutes) as ranks + FROM _incidents +), + +_mttr as( + SELECT month, max(lead_time_minutes) as median_time_to_resolve + FROM _find_median_mttr_each_month_ranks + WHERE ranks <= 0.5 + GROUP BY month +) + +SELECT + cm.month, + case + when m.median_time_to_resolve is null then 0 + else m.median_time_to_resolve/60 end as median_time_to_resolve_in_hour +FROM + calendar_months cm + LEFT JOIN _mttr m on cm.month = m.month + WHERE $__timeFilter(cm.month_timestamp) +``` + +If you want to measure in which category your team falls into as in the picture shown below, run the following SQL in Grafana. + +![](/img/Metrics/mttr-text.jpeg) + +``` +with _incidents as ( +-- get the incidents created within the selected time period in the top-right corner + SELECT + distinct i.id, + cast(lead_time_minutes as signed) as lead_time_minutes + FROM + issues i + join board_issues bi on i.id = bi.issue_id + join boards b on bi.board_id = b.id + join project_mapping pm on b.id = pm.row_id + WHERE + pm.project_name in ($project) + and i.type = 'INCIDENT' + and $__timeFilter(i.created_date) +), + +_median_mttr_ranks as( + SELECT *, percent_rank() over(order by lead_time_minutes) as ranks + FROM _incidents +), + +_median_mttr as( + SELECT max(lead_time_minutes) as median_time_to_resolve + FROM _median_mttr_ranks + WHERE ranks <= 0.5 +) + +SELECT + case + WHEN median_time_to_resolve < 60 then "Less than one hour" + WHEN median_time_to_resolve < 24 * 60 then "Less than one Day" + WHEN median_time_to_resolve < 7 * 24 * 60 then "Between one day and one week" + WHEN median_time_to_resolve >= 7 * 24 * 60 then "More than one week" + ELSE "N/A.Please check if you have collected deployments/incidents." + END as median_time_to_resolve +FROM + _median_mttr +``` + +## How to improve? + +- Use automated tools to quickly report failure +- Prioritize recovery when a failure happens +- Establish a go-to action plan to respond to failures immediately +- Reduce the deployment time for failure-fixing diff --git a/versioned_docs/version-v0.21/Metrics/PRCodingTime.md b/versioned_docs/version-v0.21/Metrics/PRCodingTime.md new file mode 100644 index 00000000000..8d721946354 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRCodingTime.md @@ -0,0 +1,56 @@ +--- +title: "PR Coding Time" +description: > + PR Coding Time +sidebar_position: 15 +--- + +## What is this metric? +The time it takes from the first commit until a PR is issued. + +## Why is it important? +It is recommended that you keep every task on a workable and manageable scale for a reasonably short amount of coding time. The average coding time of most engineering teams is around 3-4 days. + +## Which dashboard(s) does it exist in? +- [Engineering Throughput and Cycle Time](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTime) +- [Engineering Throughput and Cycle Time - Team View](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTimeTeamView) + + +## How is it calculated? +Data Sources Required + +This metric relies on PRs/MRs collected from GitHub, GitLab, BitBucket, Gitee or other code review tools. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the `coding time` of a specific PR. DevLake pre-calculates the metric and stores it in table.project_pr_metrics. + +``` +SELECT + pr_coding_time/60 as 'PR Coding Time(h)' +FROM + project_pr_metrics +``` + + +If you want to measure the monthly trend of `PR coding time` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-coding-time-monthly.png) + +``` +SELECT + DATE_ADD(date(pr.created_date), INTERVAL -DAY(date(pr.created_date))+1 DAY) as time, + avg(ppm.pr_coding_time)/60 as 'PR Coding Time(h)' +FROM + pull_requests pr + JOIN project_pr_metrics ppm ON pr.id = ppm.id +GROUP BY 1 +ORDER BY 1 +``` + +## How to improve? +Divide coding tasks into workable and manageable pieces. diff --git a/versioned_docs/version-v0.21/Metrics/PRCount.md b/versioned_docs/version-v0.21/Metrics/PRCount.md new file mode 100644 index 00000000000..179bcd7dd98 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRCount.md @@ -0,0 +1,85 @@ +--- +title: "PR Count" +description: > + Pull Request Count +sidebar_position: 13 +--- + +## What is this metric? +The number of pull requests (eg. GitHub PRs, Bitbucket PRs, GitLab MRs) created. + +## Why is it important? +1. Code review metrics are process indicators to provide quick feedback on developers' code quality +2. Promote the team to establish a unified coding specification and standardize the code review criteria +3. Identify modules with low-quality risks in advance, optimize practices, and precipitate into reusable knowledge and tools to avoid technical debt accumulation + +## Which dashboard(s) does it exist in +- [GitHub](/livedemo/DataSources/GitHub) +- [GitLab](/livedemo/DataSources/GitLab) +- [Weekly Community Retro](/livedemo/OSSMaintainers/WeeklyCommunityRetro) +- [Engineering Throughput and Cycle Time](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTime) +- [Engineering Throughput and Cycle Time - Team View](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTimeTeamView) + + +## How is it calculated? +This metric is calculated by counting the number of PRs in the given data range. + +Data Sources Required + +This metric relies on PRs/MRs collected from GitHub, GitLab, BitBucket, Gitee or other code review tools. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find PRs **created** in specific repositories and given time range. + +``` +select + count(*) as pull_request_count +from + pull_requests pr +where + -- $__timeFilter will take Grafana's time range + $__timeFilter(created_date) + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + and base_repo_id in ('repo_1', 'repo_2') + -- remove PRs submitted by bots, comment it out if you don't need it + and author_name not rlike '^robot-|-robot$|\\[bot\\]|-bot$|-ci$|-testing$' +``` + +If you want to measure the monthly trend of `PR count` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-count-monthly.png) + +``` +WITH _prs as( + SELECT + DATE_ADD(date(created_date), INTERVAL -DAY(date(created_date))+1 DAY) as time, + count(*) as pr_count + FROM pull_requests + WHERE + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + base_repo_id in ('repo_1', 'repo_2') + and $__timeFilter(created_date) + -- the following condition will remove the month with incomplete data + and created_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + -- remove PRs submitted by bots, comment it out if you don't need it + and author_name not rlike '^robot-|-robot$|\\[bot\\]|-bot$|-ci$|-testing$' + GROUP BY 1 +) + +SELECT + date_format(time,'%M %Y') as month, + pr_count as "Pull Request Count" +FROM _prs +ORDER BY time +``` + + +## How to improve? +1. From the developer dimension, we evaluate the code quality of developers by combining the task complexity with the metrics related to the number of review passes and review rounds. +2. From the reviewer dimension, we observe the reviewer's review style by taking into account the task complexity, the number of passes and the number of review rounds. +3. From the project/team dimension, we combine the project phase and team task complexity to aggregate the metrics related to the number of review passes and review rounds, and identify the modules with abnormal code review process and possible quality risks. diff --git a/versioned_docs/version-v0.21/Metrics/PRCycleTime.md b/versioned_docs/version-v0.21/Metrics/PRCycleTime.md new file mode 100644 index 00000000000..f2e00ccc49d --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRCycleTime.md @@ -0,0 +1,67 @@ +--- +title: "PR Cycle Time" +description: > + PR Cycle Time +sidebar_position: 14 +--- + +## What is this metric? +PR Cycle Time is the sum of PR Coding Time, PR Time-to-Merge and PR Deploy Time. It is the total time from the first commit to when the PR is deployed. + +The reason why we use PR Time-to-Merge rather than PR Pickup Time + PR Review Time is that a merged PR may not have any review. In this case, PR Pickup Time and PR Review Time will be NULL, while PR Time-to-Merge is not. + +## Why is it important? +PR Cycle Time indicates the overall velocity of the delivery progress in terms of PR. + +## Which dashboard(s) does it exist in? +- [Engineering Throughput and Cycle Time](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTime) +- [Engineering Throughput and Cycle Time - Team View](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTimeTeamView) + + +## How is it calculated? +You can define `deployment` based on your actual practice. For a full list of `deployment`'s definitions that DevLake support, please refer to [Deployment Frequency](/docs/Metrics/DeploymentFrequency.md). + +Data Sources Required + +This metric relies on PRs/MRs collected from GitHub, GitLab, BitBucket, Gitee or other code review tools. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the `cycle time` of a specific PR. DevLake pre-calculates the metric and stores it in table.project_pr_metrics. + +``` +SELECT + pr_cycle_time/60 as 'PR Cycle Time(h)' +FROM + project_pr_metrics +``` + + +If you want to measure the monthly trend of `PR cycle time` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-cycle-time-monthly.png) + +``` +SELECT + DATE_ADD(date(pr.created_date), INTERVAL -DAY(date(pr.created_date))+1 DAY) as time, + avg(ppm.pr_cycle_time)/60 as 'PR Cycle Time(h)' +FROM + pull_requests pr + JOIN project_pr_metrics ppm ON pr.id = ppm.id +GROUP BY 1 +ORDER BY 1 +``` + + +## How to improve? +1. Divide coding tasks into workable and manageable pieces; +2. Use DevLake's dashboards to monitor your delivery progress; +3. Have a habit to check for hanging PRs regularly; +4. Set up alerts for your communication tools (e.g. Slack, Lark) when new PRs are issued; +2. Use automated tests for the initial work; +5. Reduce PR size; +6. Analyze the causes for long reviews. \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Metrics/PRDeployTime.md b/versioned_docs/version-v0.21/Metrics/PRDeployTime.md new file mode 100644 index 00000000000..5f616f19e41 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRDeployTime.md @@ -0,0 +1,72 @@ +--- +title: "PR Deploy Time" +description: > + PR Deploy Time +sidebar_position: 18 +--- + +## What is this metric? +The time it takes from when a PR is merged to when it is deployed. + +## Why is it important? +1. Based on historical data, establish a baseline of the delivery capacity of a single iteration to improve the organization and planning of R&D resources. +2. Evaluate whether the delivery capacity matches the business phase and demand scale. Identify key bottlenecks and reasonably allocate resources. + +## Which dashboard(s) does it exist in? +- [Engineering Throughput and Cycle Time](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTime) +- [Engineering Throughput and Cycle Time - Team View](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTimeTeamView) + +## How is it calculated? +`PR deploy time` is calculated by subtracting a PR's deployed_date and merged_date. Hence, we should associate PR/MRs with deployments. + +Here are the detailed steps: + +![](/img/Metrics/pr-commit-deployment-relation.png) + +1. Find the [commits diff](https://devlake.apache.org/docs/Plugins/refdiff/) between two consecutive deployments by deployments' commit_sha +under the same scope and environment (in terms of TESTING/STAGING/PRODUCTION), + for example, we will get commit-2 and commit-3 by calculating commits_diff between deployment-1 and deployment-2, which means commit-2 and commit-3 are deployed by deployment-2 +2. Connect PR/MR and commits_diff through merge_commit or pr_commit, for example, +we get pr-3 connected to commit-3 +3. Now we can get pr-3's deploy time by finish_time of deployment-2 minus merge_time of pr-3. + +Data Transformation Required + +This metric relies on two sources: +1. PR/MRs collected from GitHub or GitLab by enabling "Code Review" under the Data Entities section. +2. Deployments collected in one of the following ways:: + - Open APIs of Jenkins, GitLab, GitHub, etc by enabling "CICD" under the Data Entities section. + - Webhook for general CI tools. + - Releases and PR/MRs from GitHub, GitLab APIs, etc. + + +SQL Queries + +The following SQL shows how to find the `deploy time` of a specific PR. DevLake pre-calculates the metric and stores it in table.project_pr_metrics. + +``` +SELECT + pr_deploy_time/60 as 'PR Deploy Time(h)' +FROM + project_pr_metrics +``` + + +If you want to measure the monthly trend of `PR deploy time` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-deploy-time-monthly.png) + +``` +SELECT + DATE_ADD(date(pr.created_date), INTERVAL -DAY(date(pr.created_date))+1 DAY) as time, + avg(ppm.pr_deploy_time)/60 as 'PR Deploy Time(h)' +FROM + pull_requests pr + JOIN project_pr_metrics ppm ON pr.id = ppm.id +GROUP BY 1 +ORDER BY 1 +``` + +## How to improve? +N/A + diff --git a/versioned_docs/version-v0.21/Metrics/PRMergeRate.md b/versioned_docs/version-v0.21/Metrics/PRMergeRate.md new file mode 100644 index 00000000000..75f07c08660 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRMergeRate.md @@ -0,0 +1,95 @@ +--- +title: "PR Merge Rate" +description: > + Pull Request Merge Rate +sidebar_position: 20 +--- + +## What is this metric? +The ratio of PRs/MRs that get merged. + +## Why is it important? +1. Code review metrics are process indicators to provide quick feedback on developers' code quality +2. Promote the team to establish a unified coding specification and standardize the code review criteria +3. Identify modules with low-quality risks in advance, optimize practices, and precipitate into reusable knowledge and tools to avoid technical debt accumulation + +## Which dashboard(s) does it exist in +- [GitHub](/livedemo/DataSources/GitHub) +- [GitLab](/livedemo/DataSources/GitLab) +- [Weekly Community Retro](/livedemo/OSSMaintainers/WeeklyCommunityRetro) +- [Engineering Throughput and Cycle Time](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTime) +- [Engineering Throughput and Cycle Time - Team View](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTimeTeamView) + + +## How is it calculated? +The number of merged PRs divided by the number of all PRs in the given data range. + +Data Sources Required + +This metric relies on PRs/MRs collected from GitHub, GitLab, BitBucket, Gitee or other code review tools. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the PR merged rate in specific repositories and given time range, eg. 'repo-1' and 'repo-2'. + +``` +select + count(distinct case when merged_date is not null then id else null end)/count(*) as pr_merged_rate +from + pull_requests pr +where + -- $__timeFilter will take Grafana's time range + $__timeFilter(created_date) + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + and base_repo_id in ('repo_1', 'repo_2') + -- remove PRs submitted by bots, comment it out if you don't need it + and author_name not rlike '^robot-|-robot$|\\[bot\\]|-bot$|-ci$|-testing$' +``` + +If you want to measure the monthly trend of `PR merge rate` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-merge-rate-monthly.png) + +``` +SELECT + DATE_ADD(date(created_date), INTERVAL -DAYOFMONTH(date(created_date))+1 DAY) as time, + count(distinct case when merged_date is not null then id else null end)/count(*) as pr_merged_rate +FROM pull_requests +WHERE + $__timeFilter(created_date) + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + and base_repo_id in ('repo_1', 'repo_2') + -- remove PRs submitted by bots, comment it out if you don't need it + and author_name not rlike '^robot-|-robot$|\\[bot\\]|-bot$|-ci$|-testing$' +GROUP BY 1 +``` + +If you want to measure the monthly trend of `PR status distribution`, please run the following SQL in Grafana. + +![](/img/Metrics/pr-status-distribution-monthly.png) + +``` +SELECT + DATE_ADD(date(created_date), INTERVAL -DAYOFMONTH(date(created_date))+1 DAY) as time, + count(distinct case when status != 'closed' then id else null end) as "PR: Open", + count(distinct case when status = 'closed' and merged_date is null then id else null end) as "PR: Closed without merging", + count(distinct case when status = 'closed' and merged_date is not null then id else null end) as "PR: Closed and merged" +FROM pull_requests +WHERE + $__timeFilter(created_date) + and created_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + and base_repo_id in ('repo_1', 'repo_2') + -- remove PRs submitted by bots, comment it out if you don't need it + and author_name not rlike '^robot-|-robot$|\\[bot\\]|-bot$|-ci$|-testing$' +GROUP BY 1 +``` + + +## How to improve? +1. From the developer dimension, we evaluate the code quality of developers by combining the task complexity with the metrics related to the number of review passes and review rounds. +2. From the reviewer dimension, we observe the reviewer's review style by taking into account the task complexity, the number of passes and the number of review rounds. +3. From the project/team dimension, we combine the project phase and team task complexity to aggregate the metrics related to the number of review passes and review rounds, and identify the modules with abnormal code review process and possible quality risks. diff --git a/versioned_docs/version-v0.21/Metrics/PRPickupTime.md b/versioned_docs/version-v0.21/Metrics/PRPickupTime.md new file mode 100644 index 00000000000..ea0efde6e28 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRPickupTime.md @@ -0,0 +1,59 @@ +--- +title: "PR Pickup Time" +description: > + PR Pickup Time +sidebar_position: 16 +--- + +## What is this metric? +The time it takes from when a PR is issued until the first comment is added to that PR. + +## Why is it important? +PR Pickup Time shows how engaged your team is in collaborative work by identifying the delay in picking up PRs. + +## Which dashboard(s) does it exist in? +- [Engineering Throughput and Cycle Time](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTime) +- [Engineering Throughput and Cycle Time - Team View](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTimeTeamView) + + +## How is it calculated? +Data Sources Required + +This metric relies on PRs/MRs collected from GitHub, GitLab, BitBucket, Gitee or other code review tools. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the `pickup time` of a specific PR. DevLake pre-calculates the metric and stores it in table.project_pr_metrics. + +``` +SELECT + pr_pickup_time/60 as 'PR Pickup Time(h)' +FROM + project_pr_metrics +``` + + +If you want to measure the monthly trend of `PR pickup time` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-pickup-time-monthly.png) + +``` +SELECT + DATE_ADD(date(pr.created_date), INTERVAL -DAY(date(pr.created_date))+1 DAY) as time, + avg(ppm.pr_pickup_time)/60 as 'PR Pickup Time(h)' +FROM + pull_requests pr + JOIN project_pr_metrics ppm ON pr.id = ppm.id +GROUP BY 1 +ORDER BY 1 +``` + + +## How to improve? +1. Use DevLake's dashboard to monitor your delivery progress; +2. Have a habit to check for hanging PRs regularly; +3. Set up alerts for your communication tools (e.g. Slack, Lark) when new PRs are issued. diff --git a/versioned_docs/version-v0.21/Metrics/PRReviewDepth.md b/versioned_docs/version-v0.21/Metrics/PRReviewDepth.md new file mode 100644 index 00000000000..4f6a6370713 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRReviewDepth.md @@ -0,0 +1,52 @@ +--- +title: "PR Review Depth" +description: > + PR Review Depth +sidebar_position: 21 +--- + +## What is this metric? +The average number of comments of PRs in the selected time range. + +## Why is it important? +PR Review Depth (in Comments per RR) is related to the quality of code review, indicating how thorough your team reviews PRs. + +## Which dashboard(s) does it exist in? +- [Engineering Throughput and Cycle Time](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTime) +- [Engineering Throughput and Cycle Time - Team View](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTimeTeamView) + +## How is it calculated? +This metric is calculated by counting the total number of PR comments divided by the total number of PRs in the selected time range. + +Data Sources Required + +This metric relies on PRs/MRs collected from GitHub, GitLab, BitBucket, Gitee or other code review tools. + +Data Transformation Required + +N/A + +SQL Queries + +If you want to measure the monthly trend of `PR review time` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-review-depth-monthly.png) + +``` +SELECT + DATE_ADD(date(pr.created_date), INTERVAL -$interval(date(pr.created_date))+1 DAY) as time, + count(distinct prc.id)/count(pr.id) as "PR Review Depth" +FROM + pull_requests pr + left join pull_request_comments prc on pr.id = prc.pull_request_id +WHERE + $__timeFilter(pr.created_date) + and pr.base_repo_id in ($repo_id) + and pr.merged_date is not null +GROUP BY 1 +``` + + +## How to improve? +1. Encourage multiple reviewers to review a PR; +2. Review Depth is an indicator for generally how thorough your PRs are reviewed, but it does not mean the deeper the better. In some cases, spending an excessive amount of resources on reviewing PRs is also not recommended. \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Metrics/PRReviewTime.md b/versioned_docs/version-v0.21/Metrics/PRReviewTime.md new file mode 100644 index 00000000000..7add75f2ed8 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRReviewTime.md @@ -0,0 +1,63 @@ +--- +title: "PR Review Time" +description: > + PR Review Time +sidebar_position: 17 +--- + +## What is this metric? +The time it takes to complete a code review of a PR before it gets merged. + +## Why is it important? +Code review should be conducted almost in real-time and usually take less than two days. Abnormally long PR Review Time may indicate one or more of the following problems: +1. The PR size is too large that makes it difficult to review. +2. The team is too busy to review code. + +## Which dashboard(s) does it exist in? +- [Engineering Throughput and Cycle Time](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTime) +- [Engineering Throughput and Cycle Time - Team View](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTimeTeamView) + + +## How is it calculated? +This metric is the time frame between when the first comment is added to a PR, to when the PR is merged. + +Data Sources Required + +This metric relies on PRs/MRs collected from GitHub, GitLab, BitBucket, Gitee or other code review tools. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the `review time` of a specific PR. DevLake pre-calculates the metric and stores it in table.project_pr_metrics. + +``` +SELECT + pr_review_time/60 as 'PR Review Time(h)' +FROM + project_pr_metrics +``` + + +If you want to measure the monthly trend of `PR review time` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-review-time-monthly.png) + +``` +SELECT + DATE_ADD(date(pr.created_date), INTERVAL -DAY(date(pr.created_date))+1 DAY) as time, + avg(ppm.pr_review_time)/60 as 'PR Review Time(h)' +FROM + pull_requests pr + JOIN project_pr_metrics ppm ON pr.id = ppm.id +GROUP BY 1 +ORDER BY 1 +``` + +## How to improve? +1. Use DevLake's dashboards to monitor your delivery progress; +2. Use automated tests for the initial work; +3. Reduce PR size; +4. Analyze the causes for long reviews. \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Metrics/PRSize.md b/versioned_docs/version-v0.21/Metrics/PRSize.md new file mode 100644 index 00000000000..3e24baecc2a --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRSize.md @@ -0,0 +1,63 @@ +--- +title: "PR Size" +description: > + PR Size +sidebar_position: 22 +--- + +## What is this metric? +The average code changes (in Lines of Code) of PRs in the selected time range. + +## Why is it important? +Small PRs can reduce risks of introducing new bugs and increase code review quality, as problems may often be hidden in big chuncks of code and difficult to identify. + +## Which dashboard(s) does it exist in? +- [Engineering Throughput and Cycle Time](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTime) +- [Engineering Throughput and Cycle Time - Team View](/livedemo/EngineeringLeads/EngineeringThroughputAndCycleTimeTeamView) + + +## How is it calculated? +This metric is calculated by counting the total number of code changes (in LOC) divided by the total number of PRs in the selected time range. + +Data Sources Required + +This metric relies on PRs/MRs collected from GitHub, GitLab, BitBucket, Gitee or other code review tools. + +Data Transformation Required + +N/A + +SQL Queries + +If you want to measure the monthly trend of `PR review time` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-size-monthly.png) + +``` +with _pr_commits_data as( + SELECT + DATE_ADD(date(pr.created_date), INTERVAL -$interval(date(pr.created_date))+1 DAY) as time, + pr.id as pr_id, + prc.commit_sha, + sum(c.additions)+sum(c.deletions) as loc + FROM + pull_requests pr + left join pull_request_commits prc on pr.id = prc.pull_request_id + left join commits c on prc.commit_sha = c.sha + WHERE + $__timeFilter(pr.created_date) + and pr.base_repo_id in ($repo_id) + group by 1,2,3 +) + +SELECT + time, + sum(loc)/count(distinct pr_id) as 'PR Size' +FROM _pr_commits_data +GROUP BY 1 +``` + + +## How to improve? +1. Divide coding tasks into workable and manageable pieces; +1. Encourage developers to submit small PRs and only keep related changes in the same PR. diff --git a/versioned_docs/version-v0.21/Metrics/PRTimeToMerge.md b/versioned_docs/version-v0.21/Metrics/PRTimeToMerge.md new file mode 100644 index 00000000000..5a83db129e2 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/PRTimeToMerge.md @@ -0,0 +1,78 @@ +--- +title: "PR Time To Merge" +description: > + PR Time To Merge +sidebar_position: 19 +--- + +## What is this metric? +The time it takes from when a PR is issued to when it is merged. Essentially, PR Time to Merge = PR Pickup Time + PR Review Time. + +## Why is it important? +The delay of reviewing and waiting to review PRs has large impact on delivery speed, while reasonably short PR Time to Merge can indicate frictionless teamwork. Improving on this metric is the key to reduce PR cycle time. + +## Which dashboard(s) does it exist in? +- [GitHub](/livedemo/DataSources/GitHub) +- [Weekly Community Retro](/livedemo/OSSMaintainers/WeeklyCommunityRetro) + + +## How is it calculated? +Data Sources Required + +This metric relies on PRs/MRs collected from GitHub, GitLab, BitBucket, Gitee or other code review tools. + +Data Transformation Required + +N/A + +SQL Queries + +The following SQL shows how to find the `mean time to merge of PRs` in specific repositories and given time range. + +![](/img/Metrics/pr-time-to-merge-text.png) + +``` +SELECT + avg(TIMESTAMPDIFF(Minute,created_date,merged_date)/1440) +FROM + pull_requests +WHERE + -- $__timeFilter will take Grafana's time range + $__timeFilter(created_date) + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + and base_repo_id in ('repo_1', 'repo_2') + and merged_date is not null +``` + +If you want to measure the monthly trend of `PR time to merge` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/pr-time-to-merge-monthly.png) + +``` +with _prs as( + SELECT + DATE_ADD(date(created_date), INTERVAL -DAY(date(created_date))+1 DAY) as time, + avg(TIMESTAMPDIFF(Minute,created_date,merged_date)/1440) as time_to_merge + FROM pull_requests + WHERE + $__timeFilter(created_date) + -- the following condition will remove the month with incomplete data + and created_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + -- please replace the repo ids with your own, or create a '$repo_id' variable in Grafana + and base_repo_id in ('repo_1', 'repo_2') + GROUP BY 1 +) + +SELECT + date_format(time,'%M %Y') as month, + time_to_merge as "Time to Merge" +FROM _prs +ORDER BY time +``` + +## How to improve? +1. Use DevLake's dashboards to monitor your delivery progress; +2. Have a habit to check for hanging PRs regularly; +3. Set up alerts for your communication tools (e.g. Slack, Lark) when new PRs are issued; +4. Reduce PR size; +5. Analyze the causes for long reviews. diff --git a/versioned_docs/version-v0.21/Metrics/RequirementCount.md b/versioned_docs/version-v0.21/Metrics/RequirementCount.md new file mode 100644 index 00000000000..f8ea3986587 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/RequirementCount.md @@ -0,0 +1,72 @@ +--- +title: "Requirement Count" +description: > + Requirement Count +sidebar_position: 1 +--- + +## What is this metric? +The number of delivered requirements or features. + +## Why is it important? +1. Based on historical data, establish a baseline of the delivery capacity of a single iteration to improve the organization and planning of R&D resources. +2. Evaluate whether the delivery capacity matches the business phase and demand scale. Identify key bottlenecks and reasonably allocate resources. + +## Which dashboard(s) does it exist in +- [Jira](https://devlake.apache.org/livedemo/DataSources/Jira) +- [GitHub](https://devlake.apache.org/livedemo/DataSources/GitHub) + + +## How is it calculated? +This metric is calculated by counting the number of delivered issues in type "REQUIREMENT" in the given data range. + +Data Sources Required + +This metric relies on the `issues` collected from Jira, GitHub, or TAPD. + +Data Transformation Required + +This metric relies on the 'type-requirement' configuration in Jira, GitHub or TAPD's transformation rules while adding/editing a blueprint. This configuration tells DevLake what issues are `requirements`. + +SQL Queries + +The following SQL shows how to find the total count of requirements in specific boards, eg. 'board-1' and 'board-2'. + +``` +select + count(*) as "Requirement Count" +from issues i + join board_issues bi on i.id = bi.issue_id +where + i.type = 'REQUIREMENT' + and i.status = 'DONE' + -- please replace the board ids with your own, or create a '$board_id' variable in Grafana + and bi.board_id in ('board-1','board-2') + and $__timeFilter(i.created_date) +``` + +If you want to see the monthly trend of `requirement count` in the screenshot below, please run the following SQL + +![](/img/Metrics/requirement-count-monthly.png) + +``` +SELECT + DATE_ADD(date(i.created_date), INTERVAL -DAYOFMONTH(date(i.created_date))+1 DAY) as time, + count(distinct case when status != 'DONE' then i.id else null end) as "Number of Open Requirements", + count(distinct case when status = 'DONE' then i.id else null end) as "Number of Delivered Requirements" +FROM issues i + join board_issues bi on i.id = bi.issue_id + join boards b on bi.board_id = b.id +where + i.type = 'REQUIREMENT' + and $__timeFilter(i.created_date) + -- please replace the board ids with your own, or create a '$board_id' variable in Grafana + and bi.board_id in ($board_id) +group by 1 +``` + +## How to improve? +1. Analyze the number of requirements and delivery rate of different time cycles to find the stability and trend of the development process. +2. Analyze and compare the number of requirements delivered and delivery rate of each project/team, and compare the scale of requirements of different projects. +3. Based on historical data, establish a baseline of the delivery capacity of a single iteration (optimistic, probable and pessimistic values) to provide a reference for iteration estimation. +4. Drill down to analyze the number and percentage of requirements in different phases of SDLC. Analyze rationality and identify the requirements stuck in the backlog. diff --git a/versioned_docs/version-v0.21/Metrics/RequirementDeliveryRate.md b/versioned_docs/version-v0.21/Metrics/RequirementDeliveryRate.md new file mode 100644 index 00000000000..1c1b245eb8b --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/RequirementDeliveryRate.md @@ -0,0 +1,88 @@ +--- +title: "Requirement Delivery Rate" +description: > + Requirement Delivery Rate +sidebar_position: 3 +--- + +## What is this metric? +The ratio of delivered requirements to all requirements. + +## Why is it important? +1. Based on historical data, establish a baseline of the delivery capacity of a single iteration to improve the organization and planning of R&D resources. +2. Evaluate whether the delivery capacity matches the business phase and demand scale. Identify key bottlenecks and reasonably allocate resources. + +## Which dashboard(s) does it exist in +- [Jira](https://devlake.apache.org/livedemo/DataSources/Jira) +- [GitHub](https://devlake.apache.org/livedemo/DataSources/GitHub) + + +## How is it calculated? +The number of delivered requirements divided by the total number of requirements in the given data range. + +Data Sources Required + +This metric relies on the `issues` collected from Jira, GitHub, or TAPD. + +Data Transformation Required + +This metric relies on the 'type-requirement' configuration in Jira, GitHub or TAPD's transformation rules while adding/editing a blueprint. This configuration tells DevLake what issues are `requirements`. + +SQL Queries + +The following SQL shows how to find the `requirement delivery rate` in specific boards, eg. 'board-1' and 'board-2'. + +![](/img/Metrics/requirement-delivery-rate-text.png) + +``` +WITH _requirements as( + SELECT + count(distinct i.id) as total_count, + count(distinct case when i.status = 'DONE' then i.id else null end) as delivered_count + FROM issues i + join board_issues bi on i.id = bi.issue_id + WHERE + i.type = 'REQUIREMENT' + and $__timeFilter(i.created_date) + -- please replace the board ids with your own, or create a '$board_id' variable in Grafana + and bi.board_id in ('board_1', 'board_2') +) + +SELECT + now() as time, + 1.0 * delivered_count/total_count as requirement_delivery_rate +FROM _requirements +``` + +If you want to measure the monthly trend of `requirement delivery rate` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/requirement-delivery-rate-monthly.png) + +``` +WITH _requirements as( + SELECT + DATE_ADD(date(i.created_date), INTERVAL -DAYOFMONTH(date(i.created_date))+1 DAY) as time, + 1.0 * count(distinct case when i.status = 'DONE' then i.id else null end)/count(distinct i.id) as delivered_rate + FROM issues i + join board_issues bi on i.id = bi.issue_id + WHERE + i.type = 'REQUIREMENT' + and $__timeFilter(i.created_date) + -- please replace the board ids with your own, or create a '$board_id' variable in Grafana + and bi.board_id in ($board_id) + GROUP BY 1 +) + +SELECT + time, + delivered_rate +FROM _requirements +ORDER BY time +``` + + +## How to improve? +1. Analyze the number of requirements and delivery rate of different time cycles to find the stability and trend of the development process. +2. Analyze and compare the number of requirements delivered and delivery rate of each project/team, and compare the scale of requirements of different projects. +3. Based on historical data, establish a baseline of the delivery capacity of a single iteration (optimistic, probable and pessimistic values) to provide a reference for iteration estimation. +4. Drill down to analyze the number and percentage of requirements in different phases of SDLC. Analyze rationality and identify the requirements stuck in the backlog. diff --git a/versioned_docs/version-v0.21/Metrics/RequirementGranularity.md b/versioned_docs/version-v0.21/Metrics/RequirementGranularity.md new file mode 100644 index 00000000000..97476602192 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/RequirementGranularity.md @@ -0,0 +1,36 @@ +--- +title: "Requirement Granularity" +description: > + Requirement Granularity +sidebar_position: 4 +--- + +## What is this metric? +The average number of story points per requirement. + +## Why is it important? +1. Promote product teams to split requirements carefully, improve requirements quality, help developers understand requirements clearly, deliver efficiently and with high quality, and improve the project management capability of the team. +2. Establish a data-supported workload estimation model to help R&D teams calibrate their estimation methods and more accurately assess the granularity of requirements, which is useful to achieve better issue planning in project management. + +## Which dashboard(s) does it exist in +- [Jira](https://devlake.apache.org/livedemo/DataSources/Jira) +- [GitHub](https://devlake.apache.org/livedemo/DataSources/GitHub) + + +## How is it calculated? +The average story points of issues in type "REQUIREMENT" in the given data range. + +Data Sources Required + +This metric relies on `issues` collected from Jira, GitHub, or TAPD. + +Data Transformation Required + +This metric relies on the 'type-requirement' configuration in Jira, GitHub or TAPD's transformation rules while adding/editing a blueprint. This configuration tells DevLake what issues are `requirements`. + +Besides, if you are importing Jira issues, you also need to configure the field of 'story_points' in the transformation. + + +## How to improve? +1. Analyze the story points/requirement lead time of requirements to evaluate whether the ticket size, ie. requirement complexity is optimal. +2. Compare the estimated requirement granularity with the actual situation and evaluate whether the difference is reasonable by combining more microscopic workload metrics (e.g. lines of code/code equivalents) diff --git a/versioned_docs/version-v0.21/Metrics/RequirementLeadTime.md b/versioned_docs/version-v0.21/Metrics/RequirementLeadTime.md new file mode 100644 index 00000000000..96c64dd6a6f --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/RequirementLeadTime.md @@ -0,0 +1,79 @@ +--- +title: "Requirement Lead Time" +description: > + Requirement Lead Time +sidebar_position: 2 +--- + +## What is this metric? +The amount of time it takes a requirement to deliver. + +## Why is it important? +1. Analyze key projects and critical points, identify good/to-be-improved practices that affect requirement lead time, and reduce the risk of delays +2. Focus on the end-to-end velocity of value delivery process; coordinate different parts of R&D to avoid efficiency shafts; make targeted improvements to bottlenecks. + +## Which dashboard(s) does it exist in +- [Jira](https://devlake.apache.org/livedemo/DataSources/Jira) +- [GitHub](https://devlake.apache.org/livedemo/DataSources/GitHub) +- [Community Experience](https://devlake.apache.org/livedemo/OSSMaintainers/CommunityExperience) + + +## How is it calculated? +This metric equals `resolution_date - created_date` of issues in type "REQUIREMENT". + +Data Sources Required + +This metric relies on issues collected from Jira, GitHub, or TAPD. + +Data Transformation Required + +This metric relies on the 'type-requirement' configuration in Jira, GitHub or TAPD's transformation rules while adding/editing a blueprint. This configuration tells DevLake what issues are `requirements`. + +SQL Queries + +The following SQL shows how to find the lead time of a specific `requirement`. +``` +-- lead_time_minutes is a pre-calculated field whose value equals 'resolution_date - created_date' +SELECT + lead_time_minutes/1440 as requirement_lead_time_in_days +FROM + issues +WHERE + type = 'REQUIREMENT' +``` + + +If you want to measure the `mean requirement lead time` in the screenshot below, please run the following SQL in Grafana. + +![](/img/Metrics/requirement-lead-time-monthly.png) + +``` +with _issues as( + SELECT + DATE_ADD(date(i.resolution_date), INTERVAL -DAY(date(i.resolution_date))+1 DAY) as time, + AVG(i.lead_time_minutes/1440) as issue_lead_time + FROM issues i + join board_issues bi on i.id = bi.issue_id + join boards b on bi.board_id = b.id + WHERE + -- $board_id is a variable defined in Grafana's dashboard settings to filter out issues by boards + b.id in ($board_id) + and i.type = 'REQUIREMENT' + and i.status = "DONE" + and $__timeFilter(i.resolution_date) + -- the following condition will remove the month with incomplete data + and i.resolution_date >= DATE_ADD(DATE_ADD($__timeFrom(), INTERVAL -DAY($__timeFrom())+1 DAY), INTERVAL +1 MONTH) + group by 1 +) + +SELECT + date_format(time,'%M %Y') as month, + issue_lead_time as "Mean Requirement Lead Time in Days" +FROM _issues +ORDER BY time +``` + +## How to improve? +1. Analyze the trend of requirement lead time to observe if it has improved over time. +2. Compare the requirement lead time of each project/team to identify key projects with abnormal lead time. +3. Drill down to analyze a requirement's staying time in different phases of SDLC. Analyze the bottleneck of delivery velocity and improve the workflow. \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Metrics/_category_.json b/versioned_docs/version-v0.21/Metrics/_category_.json new file mode 100644 index 00000000000..e944147d528 --- /dev/null +++ b/versioned_docs/version-v0.21/Metrics/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Metrics", + "position": 5, + "link":{ + "type": "generated-index", + "slug": "Metrics" + } +} diff --git a/versioned_docs/version-v0.21/Overview/Architecture.md b/versioned_docs/version-v0.21/Overview/Architecture.md new file mode 100755 index 00000000000..b0eb280c296 --- /dev/null +++ b/versioned_docs/version-v0.21/Overview/Architecture.md @@ -0,0 +1,41 @@ +--- +title: "Architecture" +description: > + Understand the architecture of Apache DevLake +sidebar_position: 2 +--- + +## Overview + +

+

DevLake Components

+ +A DevLake installation typically consists of the following components: + +- Config UI: A handy user interface to create, trigger, and debug Blueprints. A Blueprint specifies the where (data connection), what (data scope), how (transformation rule), and when (sync frequency) of a data pipeline. +- API Server: The main programmatic interface of DevLake. +- Runner: The runner does all the heavy-lifting for executing tasks. In the default DevLake installation, it runs within the API Server, but DevLake provides a temporal-based runner (beta) for production environments. +- Database: The database stores both DevLake's metadata and user data collected by data pipelines. DevLake supports MySQL and PostgreSQL as of v0.11. +- Plugins: Plugins enable DevLake to collect and analyze dev data from any DevOps tools with an accessible API. DevLake community is actively adding plugins for popular DevOps tools, but if your preferred tool is not covered yet, feel free to open a GitHub issue to let us know or check out our doc on how to build a new plugin by yourself. +- Dashboards: Dashboards deliver data and insights to DevLake users. A dashboard is simply a collection of SQL queries along with corresponding visualization configurations. DevLake's official dashboard tool is Grafana and pre-built dashboards are shipped in Grafana's JSON format. Users are welcome to swap for their own choice of dashboard/BI tool if desired. + +## Dataflow +

+ + ![](../Configuration/images/arch-dataflow.svg) + +

+ +A typical plugin's dataflow is illustrated below: + +1. The Raw layer stores the API responses from data sources (DevOps tools) in JSON. This saves developers' time if the raw data is to be transformed differently later on. Please note that communicating with data sources' APIs is usually the most time-consuming step. +2. The Tool layer extracts raw data from JSONs into a relational schema that's easier to consume by analytical tasks. Each DevOps tool would have a schema that's tailored to its data structure, hence the name, the Tool layer. +3. The Domain layer attempts to build a layer of abstraction on top of the Tool layer so that analytics logics can be re-used across different tools. For example, GitHub's Pull Request (PR) and GitLab's Merge Request (MR) are similar entities. They each have their own table name and schema in the Tool layer, but they're consolidated into a single entity in the Domain layer, so that developers only need to implement metrics like Cycle Time and Code Review Rounds once against the domain layer schema. + +## Principles + +1. Extensible: DevLake's plugin system allows users to integrate with any DevOps tool. DevLake also provides a dbt plugin that enables users to define their own data transformation and analysis workflows. +2. Portable: DevLake has a modular design and provides multiple options for each module. Users of different setups can freely choose the right configuration for themselves. +3. Robust: DevLake provides an SDK to help plugins efficiently and reliably collect data from data sources while respecting their API rate limits and constraints. + +
diff --git a/versioned_docs/version-v0.21/Overview/Introduction.md b/versioned_docs/version-v0.21/Overview/Introduction.md new file mode 100755 index 00000000000..aa79e51cb05 --- /dev/null +++ b/versioned_docs/version-v0.21/Overview/Introduction.md @@ -0,0 +1,51 @@ +--- +title: "Introduction" +description: General introduction of Apache DevLake +sidebar_position: 1 +--- + + + Introduction to Apache DevLake and Implementing DORA Metrics + + + + +## What is Apache DevLake? + +Apache DevLake (Incubating) is an open-source dev data platform that ingests, analyzes, and visualizes the fragmented data from DevOps tools to extract insights for engineering excellence, developer experience, and community growth. + +Apache DevLake is designed for developer teams looking to make better sense of their development process and to bring a more data-driven approach to their own practices. You can ask Apache DevLake many questions regarding your development process. Just connect and query. + +## What can be accomplished with DevLake? +- Unified data integration: Bring together DevOps data from across the Software Development Life Cycle (SDLC) with our [standard data model](/docs/DataModels/DevLakeDomainLayerSchema.md). +- Out-of-the-box insights: Access key engineering metrics through intuitive, use-case driven dashboards. +- Customizable: Extend DevLake to align with your unique needs, adding [data sources](SupportedDataSources.md), [metrics](/docs/Metrics/), and [dashboards](/livedemo/EngineeringLeads/DORA) as required. +- Industry standards implementation: Use DevLake to apply recognized [DORA metrics](/docs/DORA.md) to optimize DevOps performance. +- Create a thriving culture: DevLake is centered on healthy practices that may help teams adopt and build a practical data-driven culture. + +## How do I use DevLake? +### 1. Setting-up DevLake +- To implement a proof of concept for Apache DevLake tailored to your specific use cases, you can install it on your local machines using Docker Compose. The detailed instructions for this setup can be found in the [Docker Compose setup documentation](/docs/GettingStarted/DockerComposeSetup.md). +- Alternatively, if your infrastructure is powered by Kubernetes, you can explore the [Helm setup](../GettingStarted/HelmSetup.md) option. The Helm setup documentation provides guidance on deploying and configuring Apache DevLake using Helm. + +### 2. Configuring Data Source +- Once Installed, you can start configuring DevLake with [supported data sources](SupportedDataSources.md) like GitHub, GitLab, Jira, Jenkins, BitBucket, Azure DevOps, SonarQube, PagerDuty, TAPD, ZenTao, Teambition, and we are extending our support to many other tools, feel free to check out the [roadmap](Roadmap.md). +- However, if your CI/CD tool is not currently supported by DevLake, you can utilize the [webhooks](https://devlake.apache.org/docs/Plugins/webhook/) feature. The Webhooks feature allows you to actively push data to DevLake when there is not a specific plugin available for your DevOps tool. + + ![img](../Configuration/images/introduction-userflow1.png) + + ![img](../Configuration/images/introduction-userflow2.png) + +### 3. Creating your Project +- Once you have connected a data source to Apache DevLake, you can create a "Project" to ensure that you are all set for execution. The process of setting up a project in DevLake typically involves four steps: + + ![img](../Configuration/images/introduction-userflow3.png) + +### 4. Checking the Dashboards and Metrics +- After configuring your project in DevLake, you can access pre-built dashboards in Grafana. These dashboards provide visualizations and insights for various metrics related to software development. + + ![img](/img/Introduction/userflow3.png) + +- To customize the dashboards according to your specific goals and requirements, you can tweak them using Grafana's features. Additionally, if you prefer to create your own dashboards, you have the option to use SQL queries to fetch the necessary data from DevLake referring to the [domain layer data schema](/docs/DataModels/DevLakeDomainLayerSchema.md) and SQL examples in the [metrics documentation](/docs/Metrics/). + + ![img](../Configuration/images/introduction-userflow5.png) \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Overview/KeyConcepts.md b/versioned_docs/version-v0.21/Overview/KeyConcepts.md new file mode 100644 index 00000000000..39d227365b1 --- /dev/null +++ b/versioned_docs/version-v0.21/Overview/KeyConcepts.md @@ -0,0 +1,114 @@ +--- +sidebar_position: 4 +title: "Key Concepts" +linkTitle: "KeyConcepts" +description: > + DevLake Key Concepts +--- + +*Last updated: Nov 9, 2023* + + +## In Config UI + +The following terms are arranged in the order of their appearance in the actual user workflow in the config UI. + +### Data Source +**A data source is a specific DevOps tool from which you wish to sync your data, such as GitHub, GitLab, Jira and Jenkins.** + +Typically, DevLake uses one [data plugin](#data-plugins) to pull data for a single data source. For example, the [jira](/docs/Plugins/jira.md) plugin is used to fetch data from Jira. + +However, there are cases where DevLake may use multiple data plugins for a single data source. This approach is employed to enhance the synchronization speed and provide other advantages. For instance, when retrieving data from GitHub or GitLab, aside from the [github](/docs/Plugins/github.md) and [gitlab](/docs/Plugins/gitlab.md) plugins, the [gitextractor](/docs/Plugins/gitextractor.md) is also used to fetch data. In these cases, DevLake still recognizes GitHub or GitLab as a single data source. + +### Data Connection +**A data connection is a specific instance of a [data source](#data-source).** It stores the necessary access information, such as the endpoint URL and authentication token, to establish a connection to that data source. + +A single data source can have one or more data connections associated with it. This allows you to connect to and retrieve data from different instances or installations of the same data source. + +To set up a new data connection, it is recommended to use the 'Data Connections' page in DevLake. This page provides a convenient interface for adding and configuring data connections. Once a data connection is set up, you can later associate it with a DevLake project. + +### Data Scope +**A data scope is the top-level 'container' in a data source**. For example, a data scope for Jira is a Jira board, for TAPD is a TAPD workspace, for GitHub/GitLab/BitBucket is a repo, for Jenkins is a Jenkins job, etc. + +You can add multiple data scopes to a data connection to determine which data to collect. Data scopes vary for different data sources. + +### Scope Config +**A scope config refers to the configuration of a data scope.** It defines the specific data entities to be collected and the transformations to be applied to that data. + +Each data scope can have at most one scope config associated with it; while a scope config can be shared among multiple data scopes under the same data connection. + +A scope config consists of two parts: [Data Entities](#data-entities) and [Transformations](#transformations). + +#### Data Entities +Data entities refer to the specific data fields that are collected from different data domains. Check the [supported data entities](/docs/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) of each data source. + +Data entities are categorized into [six data domains](/docs/DataModels/DevLakeDomainLayerSchema.md#data-models) in DevLake: Issue Tracking, Source Code Management, Code Review, CI/CD, Code Quality, and Cross-Domain. + +When setting up the scope config of a GitHub data connection, you have the flexibility to choose which specific data entities you want to collect. if you only want to collect 'repos', 'commits', and 'pull requests' while excluding 'issues' and 'workflow runs', you need to check the 'Source Code Management' and 'Code Review' domains, and uncheck 'Issue Tracking' or 'CI/CD' domains. + +#### Transformations +Transformations are configurations for users to customize how DevLake transforms raw API responses to the domain layer data. + +Although configuring transformation rules is not mandatory, certain pre-built dashboards, such as [DORA](/livedemo/EngineeringLeads/DORA) and [Weekly Bug Retro](/livedemo/QAEngineers/WeeklyBugRetro) require the them to display the metrics accurately. If you leave the rules blank or have not configured them correctly, only a few [data source dashboards](/livedemo/DataSources/GitHub) will be displayed as expected. + +You can find the required transformations in the 'Dashboard Introduction' panel in each pre-built dashboard. + +### Project +**On a high level, a DevLake project can be viewed as a real-world project or product line.** It represents a specific initiative or endeavor within the software development domain. + +**On a lower level, a DevLake project is a way of organizing and grouping data from different domains.** DevLake uses various [data scopes](#data-scope), such as repos, boards, cicd_scopes, and cq_projects as the 'container' to associate different types of data to a specific project. + +- A project has a [blueprint](#Bluepirnts) for data collection and metric computation. +- DevLake measures DORA metrics at the project level. Each project has a set of DORA metrics. For example, if a user associates 'Jenkins Job A' and 'Jira board B' with project M, only the 'deployments' from 'Jenkins Job A' and the 'incidents' from 'Jira board B' will be considered when calculating the Change Failure Rate metric for project M. + ![](../Configuration/images/HowToOrganizeDevlakeProjects/project_pipeline.png) + +### Blueprint +**A blueprint serves as the plan to synchronize data from data sources into the DevLake platform.** Creating a blueprint consists of four steps: +1. Adding [data connections](#data-connections): You can add one or more data connections to a blueprint, depending on the data sources you want to sync with DevLake. Each data connection represents a specific data source, such as GitHub or Jira. +2. Setting up the [data scope](#data-scope): When adding a data connection, you can choose to collect all or part of the configured data scopes of the data connection. +3. Setting up the sync policy: You can specify the sync frequency and the time range for data collection. + +The relationship between 'Blueprint', 'Data Connection' and 'Scope COnfig' is explained as follows: + +![Blueprint ERD](../Configuration/images/blueprint-erd.svg) +- Each blueprint can have multiple data connections. +- Each data connection can have multiple data scopes. +- Each set of data scope only consists of one GitHub/GitLab project or Jira board, along with their corresponding data entities. +- Each set of data scope can only have one set of transformation rules. + +## APIs and Config UI Advanced Mode + +Typically, the following terms do not appear in the regular mode of the Config UI, but can be very useful if you use [DevLake's APIs](References.md) or the advanced mode of Config UI. + +### Data Plugins +**A data plugin is a specific module that syncs or transforms data.** There are two types of data plugins: Data Collection Plugins and Data Transformation Plugins. + +Data Collection Plugins pull data from one or more data sources. DevLake supports 8 data plugins in this category: `ae`, `feishu`, `gitextractor`, `github`, `gitlab`, `jenkins`, `jira` and `tapd`. + +Data Transformation Plugins transform the data pulled by other Data Collection Plugins. `refdiff` is currently the only plugin in this category. + +Although the names of the data plugins are not displayed in the regular mode of DevLake Configuration UI, they can be used directly in JSON in the Advanced Mode. + +For detailed information about the relationship between data sources and data plugins, please refer to [Supported Data Sources](SupportedDataSources.md). + + +### Pipelines +**A pipeline is an orchestration of [tasks](#tasks) of data `collection`, `extraction`, `conversion` and `enrichment`, defined in the DevLake API.** A pipeline is composed of one or multiple [stages](#stages) that are executed in a sequential order. Any error occurring during the execution of any stage, task or subtask will cause the immediate fail of the pipeline. + +The composition of a pipeline is explained as follows: +![Blueprint ERD](/img/Glossary/pipeline-erd.svg) +Notice: **You can manually orchestrate the pipeline in Configuration UI Advanced Mode and the DevLake API; whereas in Configuration UI regular mode, an optimized pipeline orchestration will be automatically generated for you.** + + +### Stages +**A stages is a collection of tasks performed by data plugins.** Stages are executed in a sequential order in a pipeline. + +### Tasks +**A task is a collection of [subtasks](#subtasks) that perform any of the `collection`, `extraction`, `conversion` and `enrichment` jobs of a particular data plugin.** Tasks are executed in a parallel order in any stages. + +### Subtasks +**A subtask is the minimal work unit in a pipeline that performs in any of the four roles: `Collectors`, `Extractors`, `Converters` and `Enrichers`.** Subtasks are executed in sequential orders. +- `Collectors`: Collect raw data from data sources, normally via DevLake API and stored into `raw data table` +- `Extractors`: Extract data from `raw data tables` to `tool layer tables` +- `Converters`: Convert data from `tool layer tables` into `domain layer tables` +- `Enrichers`: Enrich data from one domain to other domains. For instance, the Fourier Transformation can examine `issue_changelog` to show time distribution of an issue on every assignee. diff --git a/versioned_docs/version-v0.21/Overview/References.md b/versioned_docs/version-v0.21/Overview/References.md new file mode 100644 index 00000000000..eb2ed0dbfdb --- /dev/null +++ b/versioned_docs/version-v0.21/Overview/References.md @@ -0,0 +1,19 @@ +--- +title: "API References" +description: > + API References +sidebar_position: 6 +--- + +For users/developers who wish to interact with the Apache DevLake by using the RESTful APIs, +the Swagger Document would very useful for you. The `devlake` docker image has it packaged, you may access it from: +If you are using the `devlake` container alone without `config-ui`: +``` +http://:/swagger/index.html +``` +or +``` +http://:/api/swagger/index.html +``` + + diff --git a/versioned_docs/version-v0.21/Overview/Roadmap.md b/versioned_docs/version-v0.21/Overview/Roadmap.md new file mode 100644 index 00000000000..cc249348f25 --- /dev/null +++ b/versioned_docs/version-v0.21/Overview/Roadmap.md @@ -0,0 +1,33 @@ +--- +title: "Roadmap" +description: > + The goals and roadmap for DevLake +sidebar_position: 10 +--- + +## Goals + +DevLake has joined the Apache Incubator and is aiming to become a top-level project. To achieve this goal, the Apache DevLake (Incubating) community will continue to make efforts in helping development teams to analyze and improve their engineering productivity. In this roadmap, we have summarized three major goals followed by the feature breakdown to invite the broader community to join us and grow together. + +1. As a dev data analysis application, discover and implement 3 (or even more!) usage scenarios: + - A collection of metrics to track the contribution, quality and growth of open-source projects + - DORA metrics for DevOps engineers + - To be decided ([let us know](https://join.slack.com/t/devlake-io/shared_invite/zt-20envwfbk-JUTZ4z9jSeRnrvNhBFLg9w) if you have any suggestions!) +2. As dev data infrastructure, provide robust data collection modules, customizable data models, and data extensibility. +3. Design better user experience for end-users and contributors. + +## Feature Breakdown + +Apache DevLake is currently under rapid development. You are more than welcome to use the following table to explore your intereted features and make contributions. We deeply appreciate the collective effort of our community to make this project possible! + +| Category | Features | +| -------- | -------- | +| More data sources across different DevOps domains (Goal No.1 & 2). See [existing data sources](/docs/Overview/SupportedDataSources.md) | Issue Tracking:
  • Jira (cloud) [#886 (Done)](https://github.com/apache/incubator-devlake/issues/886)
  • Jira (server/data center) [#1687 (Done)](https://github.com/apache/incubator-devlake/issues/1687)
  • GitHub Issues [#407 (Done)](https://github.com/apache/incubator-devlake/issues/407)
  • GitLab Issues [#715 (Done)](https://github.com/apache/incubator-devlake/issues/715)
  • TAPD [#560 (Beta)](https://github.com/apache/incubator-devlake/issues/560)
  • Zentao [#2961 (Beta)](https://github.com/apache/incubator-devlake/issues/2961)
  • Teambition [#1882 (Beta)](https://github.com/apache/incubator-devlake/issues/1882)
  • Trello [#1881 (Pending)](https://github.com/apache/incubator-devlake/issues/1881)
  • Ones [#1884 (Pending)](https://github.com/apache/incubator-devlake/issues/1884)
Source Code Management:
  • GitHub (Done)
  • GitLab (Done)
  • BitBucket [#2100 (Supported from v0.16)](https://github.com/apache/incubator-devlake/issues/2100)
  • Azure DevOps [#2604 (Supported from v0.16)](https://github.com/apache/incubator-devlake/issues/2604)
  • Gitee [#1883 (WIP)](https://github.com/apache/incubator-devlake/issues/1883)
  • Coder [#3447 (Pending)](https://github.com/apache/incubator-devlake/issues/3447)
Code Review:
  • GitHub PRs (Done)
  • GitLab MRs (Done)
  • BitBucket PRs [#2100 (Supported from v0.16)](https://github.com/apache/incubator-devlake/issues/2100)
  • Azure DevOps PRs [#2604 (Supported from v0.16)](https://github.com/apache/incubator-devlake/issues/2604)
  • Phabricator (Pending)
  • Gerrit (Pending)
CI/CD:
  • GitHub Action [#2584 (Done)](https://github.com/apache/incubator-devlake/issues/2584)
  • GitLab CI [#2583 (Done)](https://github.com/apache/incubator-devlake/issues/2583)
  • Jenkins [#2637 (Done)](https://github.com/apache/incubator-devlake/issues/2637)
  • Bamboo CI [#3322 (WIP)](https://github.com/apache/incubator-devlake/issues/3322)
  • Argo CI [#2585 (Pending)](https://github.com/apache/incubator-devlake/issues/2584)
  • Argo CD [#5207 (Pending)](https://github.com/apache/incubator-devlake/issues/5207)
  • TeamCity (Pending)
Code Quality:
  • SonarQube [#2305 (Supported from v0.16)](https://github.com/apache/incubator-devlake/issues/2305)
  • Coverity (Pending)
Incident Management:
  • PagerDuty [#3498 (WIP)](https://github.com/apache/incubator-devlake/issues/3498)
  • ServiceNow [#4234 (Planned)](https://github.com/apache/incubator-devlake/issues/4234)
QA:
  • Selenium (Pending)
  • Junit (Pending)
  • JMeter (Pending)
  • Cucumber Test (Pending)
Documentation:
  • Google Docs (Pending)
  • Lark Docs (Pending)
  • Tencent Docs (Pending)
Calendar:
  • Lark Calendar [#261 (Done)](https://github.com/apache/incubator-devlake/issues/261)
  • Google Calendar (Pending)
  • Zoom Calendar (Pending)
  • Tencent Calendar (Pending)
OSS Community Metrics:
  • GitHub stars, clones, watches [#3721 (WIP)](https://github.com/apache/incubator-devlake/issues/3721)
Instant Messaging:
  • Slack (Pending)
  • Discord (Pending)
  • Lark messages (Pending)
| +| Improved data collection, [data models](../DataModels/DevLakeDomainLayerSchema.md) and data extensibility (Goal No.2) | Data Collection:
  • Complete the logging system
  • Implement a good error handling mechanism during data collection
Data Models:
  • Introduce DBT to allow users to create and modify the domain layer schema. [#1479 (Done)](https://github.com/apache/incubator-devlake/issues/1479)
  • Design the data models for 6 new domains, please refers to the data models of the tools under each domain (see the cell above):
    • Code Quality (WIP)
    • Testing
    • Calendar
    • Documentation
    • OSS Community Metrics (WIP)
    • Instant messaging
  • Polish the data models for [existing domains](../DataModels/DevLakeDomainLayerSchema.md): Issue/Task Management, Source Code Management, Code Review and CI/CD.
Data Extensibility:
  • Enhance the performance of data application under large-scaled usage scenarios
  • Support OLAP databases for more flexible data storage options
| +| Better user experience (Goal No.3) | For new users:
  • Iterate on a clearer step-by-step guide to improve the pre-configuration experience.
  • Provide a new Config UI to reduce frictions for data configuration [#1700 (Done)](https://github.com/apache/incubator-devlake/issues/1700)
  • Showcase dashboard live demos to let users explore and learn about the dashboards. [#1784 (Done)](https://github.com/apache/incubator-devlake/issues/1784)
For returning users:
  • Provide detailed guides to help users customize Grafana dashboards.
  • Work on the documentation for advanced features in the Config UI, such as the usage of Advanced Mode and replacements of old auth tokens for data connections.
For contributors:
  • Add more guide to set up DevLake in different operating system.
  • Provide clearer docs for contributors to get on board easier.
  • Add Swagger to document API [#292 (Done)](https://github.com/apache/incubator-devlake/issues/292)
  • More docs about raw/tool/domain data models
+ +## How to Influence the Roadmap + +A roadmap is only useful when it captures real user needs. We are glad to hear from you if you have specific use cases, feedback, or ideas. You can submit an issue to let us know! +Also, if you plan to work (or are already working) on a new or existing feature, tell us, so that we can update the roadmap accordingly. We are happy to share knowledge and context to help your feature land successfully. +


diff --git a/versioned_docs/version-v0.21/Overview/SupportedDataSources.md b/versioned_docs/version-v0.21/Overview/SupportedDataSources.md new file mode 100644 index 00000000000..de3e7ff7d21 --- /dev/null +++ b/versioned_docs/version-v0.21/Overview/SupportedDataSources.md @@ -0,0 +1,257 @@ +--- +title: "Supported Data Sources" +description: > + Data sources that DevLake supports +sidebar_position: 5 +--- + +## Data Sources and Data Plugins + +Apache DevLake(incubating) supports the following data sources. The data from each data source is collected with one or +more plugins. Detailed plugin docs can be found [here](/docs/Plugins). + +| Data Source | Domain(s) | Supported Versions | Config UI Availability | Triggered Plugins | Collection Mode | +|---------------------|-----------------------------------------------------------------------------|------------------------------------|-------------------------|-------------------------------|---------------------------------------------------------------------| +| GitHub | Source Code Management, Code Review, Issue Tracking, CI/CD (GitHub Actions) | Cloud | Available | `github`, `gitextractor` | Incremental Sync | +| GitLab | Source Code Management, Code Review, Issue Tracking, CI/CD (GitLab CI) | Cloud, Community Edition 11+ | Available | `gitlab`, `gitextractor` | Full Refresh, Incremental Sync(for `issues`,`MRs`) | +| Jira | Issue Tracking | Cloud, Server/Data Center 7.x, 8.x | Available | `jira` | Full Refresh, Incremental Sync(for `issues` and related) | +| Jenkins | CI/CD | 2.263.x+ | Available | `jenkins` | Incremental Sync | +| BitBucket (Beta) | Source Code Management, Code Review | Cloud | Advanced Mode Available | `bitbucket`, `gitextractor` | Full Refresh | +| TAPD (Beta) | Issue Tracking | Cloud | Advanced Mode Available | `tapd` | Full Refresh, Incremental Sync(for `stories`, `bugs`, `tasks`) | +| Teambition (Beta) | Issue Tracking | Cloud | Advanced Mode Available | `teambition` | Full Refresh | +| Zentao (Beta) | Issue Tracking | v17.x, v18.x | Advanced Mode Available | `zentao` | Full Refresh | +| Gitee (WIP) | Source Code Management, Code Review, Issue Tracking | Cloud | Not Available | `gitee`, `gitextractor` | Full Refresh, Incremental Sync(for `issues`,`MRs`) | +| PagerDuty | Issue Tracking | Cloud | Available | `pagerduty` | Incremental Sync | +| Opsgenie | Issue Tracking | Cloud | Available | `opsgenie` | Full Refresh (for `users`,`teams`), Incremental Sync (for `issues`) | +| Feishu (WIP) | Calendar | Cloud | Not Available | `feishu` | Full Refresh | +| AE | Source Code Management | On-prem | Not Available | `ae` | Full Refresh | +| Sonarqube | CODE QUALITY | SonarQube v8.x, v9.x | Available | `sonarqube` | Full Refresh | +| Bamboo CI(WIP) | CI/CD | v6.8.1 | Not Available | `bamboo` | Full Refresh | +| Azure Devops (Beta) | CI/CD, Source Code Management, Code Review | Cloud | Available | `azuredevops`, `gitextractor` | Full Refresh | +| CircleCI | CI/CD | Cloud | Available | `circleci` | Full Refresh | + +## Data Collection Scope By Each Plugin + +This table shows the entities collected by each plugin. Domain layer entities in this table are consistent with the +entities [here](/DataModels/DevLakeDomainLayerSchema.md). +✅ : Collect by default. +💪 : Collect not by default. You need to add the corresponding subtasks to collect these entities in +the [advanced mode](../Configuration/AdvancedMode.md). + +| Domain Layer Entities | ae | dora | gitextractor | incoming webhook | github | gitlab | jenkins | jira | refdiff | tapd | sonarqube | bamboo | azuredevops | opsgenie | circleci | +|---------------------------------------------------------------------------------------------|----|------|--------------|------------------|--------|--------|---------|------|---------|------|-----------|--------|-------------|----------|----------| +| [accounts](../DataModels/DevLakeDomainLayerSchema.md/#accounts) | | | | | ✅ | ✅ | | ✅ | | ✅ | ✅ | | | | ✅ | +| [board_issues](../DataModels/DevLakeDomainLayerSchema.md/#board_issues) | | | | | ✅ | ✅ | | ✅ | | ✅ | | | | ✅ | | +| [board_repos](../DataModels/DevLakeDomainLayerSchema.md/#board_repos) | | | | | ✅ | ✅ | | | | | | | | | | +| [board_sprints](../DataModels/DevLakeDomainLayerSchema.md/#board_sprints) | | | | | ✅ | | | ✅ | | ✅ | | | | | | +| [boards](../DataModels/DevLakeDomainLayerSchema.md/#boards) | | | | | ✅ | ✅ | | ✅ | | ✅ | | | | ✅ | | +| [cicd_pipeline_commits](../DataModels/DevLakeDomainLayerSchema.md/#cicd_pipeline_commits) | | ✅ | | | ✅ | ✅ | ✅ | | | | | ✅ | ✅ | | ✅ | +| [cicd_pipelines](../DataModels/DevLakeDomainLayerSchema.md/#cicd_pipelines) | | ✅ | | | ✅ | ✅ | ✅ | | | | | ✅ | ✅ | | ✅ | +| [cicd_scopes](../DataModels/DevLakeDomainLayerSchema.md/#cicd_scopes) | | ✅ | | | ✅ | ✅ | ✅ | | | | | ✅ | ✅ | | ✅ | +| [cicd_tasks](../DataModels/DevLakeDomainLayerSchema.md/#cicd_tasks) | | ✅ | | 💪 | ✅ | ✅ | ✅ | | | | | ✅ | ✅ | | ✅ | +| [commit_file_components](../DataModels/DevLakeDomainLayerSchema.md/#commit_file_components) | | | ✅ | | | | | | | | | | | | | +| [commit_files](../DataModels/DevLakeDomainLayerSchema.md/#commit_files) | | | ✅ | | | | | | | | | | | | | +| [commit_line_change](../DataModels/DevLakeDomainLayerSchema.md/#commit_line_change) | | | ✅ | | | | | | | | | | | | | +| [commit_parents](../DataModels/DevLakeDomainLayerSchema.md/#commit_parents) | | | ✅ | | | | | | | | | | | | | +| [commits](../DataModels/DevLakeDomainLayerSchema.md/#commits) | ✅ | | ✅ | | 💪 | 💪 | | | | | | | | | | +| [commits_diffs](../DataModels/DevLakeDomainLayerSchema.md/#commits_diffs) | | | | | | | | | ✅ | | | | | | | +| [components](../DataModels/DevLakeDomainLayerSchema.md/#components) | | | | | | | | | | | | | | | | +| [finished_commits_diffs](../DataModels/DevLakeDomainLayerSchema.md/#finished_commits_diffs) | | | | | | | | | | | | | | | | +| [issue_changelogs](../DataModels/DevLakeDomainLayerSchema.md/#issue_changelogs) | | | | | | | | ✅ | | ✅ | | | | | | +| [issue_comments](../DataModels/DevLakeDomainLayerSchema.md/#issue_comments) | | | | | ✅ | | | | | ✅ | | | | | | +| [issue_commits](../DataModels/DevLakeDomainLayerSchema.md/#issue_commits) | | | | | | | | ✅ | | ✅ | | | | | | +| [issue_labels](../DataModels/DevLakeDomainLayerSchema.md/#issue_labels) | | | | | ✅ | ✅ | | | | ✅ | | | | | | +| [issue_repo_commits](../DataModels/DevLakeDomainLayerSchema.md/#issue_repo_commits) | | | | | | | | ✅ | | | | | | | | +| [issue_worklogs](../DataModels/DevLakeDomainLayerSchema.md/#issue_worklogs) | | | | | | | | ✅ | | ✅ | | | | | | +| [issues](../DataModels/DevLakeDomainLayerSchema.md/#issues) | | | | | ✅ | | | ✅ | | ✅ | | | | ✅ | | +| [project_issue_metrics](../DataModels/DevLakeDomainLayerSchema.md/#project_issue_metrics) | | ✅ | | | ✅ | ✅ | | ✅ | | ✅ | | | | | | +| [project_mapping](../DataModels/DevLakeDomainLayerSchema.md/#project_mapping) | | ✅ | | | ✅ | ✅ | ✅ | ✅ | | ✅ | | | | | | +| [project_metrics](../DataModels/DevLakeDomainLayerSchema.md/#project_metrics) | | ✅ | | | ✅ | ✅ | ✅ | ✅ | | ✅ | | | | | | +| [project_pr_metrics](../DataModels/DevLakeDomainLayerSchema.md/#project_pr_metrics) | | ✅ | | | ✅ | ✅ | | | | ✅ | | | | | | +| [project](../DataModels/DevLakeDomainLayerSchema.md/#project) | | ✅ | | | ✅ | ✅ | ✅ | ✅ | | ✅ | | | | | ✅ | +| [pull_request_comments](../DataModels/DevLakeDomainLayerSchema.md/#pull_request_comments) | | | | | ✅ | ✅ | | | | | | | | | | +| [pull_request_commits](../DataModels/DevLakeDomainLayerSchema.md/#pull_request_commits) | | | | | ✅ | ✅ | | | | | | | ✅ | | | +| [pull_request_issues](../DataModels/DevLakeDomainLayerSchema.md/#pull_request_issues) | | | | | ✅ | | | | | | | | | | | +| [pull_request_labels](../DataModels/DevLakeDomainLayerSchema.md/#pull_request_labels) | | | | | ✅ | ✅ | | | | | | | | | | +| [pull_requests](../DataModels/DevLakeDomainLayerSchema.md/#pull_requests) | | | | | ✅ | ✅ | | | | | | | ✅ | | | +| [ref_commits](../DataModels/DevLakeDomainLayerSchema.md/#ref_commits) | | | | | | | | | ✅ | | | | | | | +| [refs](../DataModels/DevLakeDomainLayerSchema.md/#refs) | | | ✅ | | | | | | ✅ | | | | | | | +| [refs_issues_diffs](../DataModels/DevLakeDomainLayerSchema.md/#refs_issues_diffs) | | | | | | | | | ✅ | | | | | | | +| [ref_pr_cherry_picks](../DataModels/DevLakeDomainLayerSchema.md/#ref_pr_cherry_picks) | | | | | | | | | ✅ | | | | | | | +| [repo_commits](../DataModels/DevLakeDomainLayerSchema.md/#repo_commits) | | | ✅ | | 💪 | 💪 | | | | | | | | | | +| [repo_snapshot](../DataModels/DevLakeDomainLayerSchema.md/#repo_snapshot) | | | ✅ | | | | | | | | | | | | | +| [repos](../DataModels/DevLakeDomainLayerSchema.md/#repos) | | | | | ✅ | ✅ | | | | | | | | | | +| [sprint_issues](../DataModels/DevLakeDomainLayerSchema.md/#sprint_issues) | | | | | ✅ | | | ✅ | | ✅ | | | | | | +| [sprints](../DataModels/DevLakeDomainLayerSchema.md/#sprints) | | | | | ✅ | | | ✅ | | ✅ | | | | | | +| [team_users](../DataModels/DevLakeDomainLayerSchema.md/#team_users) | | | | | | | | | | | | | | | | +| [teams](../DataModels/DevLakeDomainLayerSchema.md/#teams) | | | | | | | | | | | | | | ✅ | | +| [user_account](../DataModels/DevLakeDomainLayerSchema.md/#user_accounts) | | | | | | | | | | | | | | | | +| [users](../DataModels/DevLakeDomainLayerSchema.md/#users) | | | | | | | | ✅ | | ✅ | | | | ✅ | | +| [cq_projects](../DataModels/DevLakeDomainLayerSchema.md/#cq_projects) | | | | | | | | | | | ✅ | | | | | +| [cq_issues](../DataModels/DevLakeDomainLayerSchema.md/#cq_issues) | | | | | | | | | | | ✅ | | | | | +| [cq_issue_code_blocks](../DataModels/DevLakeDomainLayerSchema.md/#cq_issue_code_blocks) | | | | | | | | | | | ✅ | | | | | +| [cq_file_metrics](../DataModels/DevLakeDomainLayerSchema.md/#cq_file_metrics) | | | | | | | | | | | ✅ | | | | | + +## Data Sync Policy + +**bold:** means it may collect slowly. + +**\*bold\*:** means it may collect very slowly. + +### Jira + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|----------------------------|---------------------------------|-----------------------------------------|------------------------------| +| CollectStatusMeta | 1 | - | - | +| CollectProjectsMeta | <10 | ❌ | - | +| CollectIssueTypesMeta | <10 | ❌ | - | +| CollectIssuesMeta | <10^4 | ✅ | ✅ | +| CollectIssueChangelogsMeta | 1000~10^5 | ✅ | ✅ | +| CollectAccountsMeta | <10^3 | ❌ | ❌ | +| CollectWorklogsMeta | 1000~10^5 | ✅ | ✅ | +| CollectRemotelinksMeta | 1000~10^5 | ✅ | ✅ | +| CollectSprintsMeta | <100 | ❌ | ❌ | +| CollectEpicsMeta | <100 | ❌ | ✅ | + +### Jenkins + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|----------------------|---------------------------------|-----------------------------------------|------------------------------| +| CollectApiBuildsMeta | ≈100 | ❌ | ❌ | +| CollectApiStagesMeta | ≈10^4 | ❌ | ✅ | + +### GitLab + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|-----------------------------|---------------------------------|-----------------------------------------|------------------------------| +| CollectApiIssuesMeta | <10^4 | ✅ | ✅ | +| CollectApiMergeRequestsMeta | <10^3 | ✅ | ✅ | +| CollectApiMrNotesMeta | <10^5 | ❌ | ✅ | +| CollectApiMrCommitsMeta | <10^5 | ❌ | ✅ | +| **CollectApiPipelinesMeta** | <10^4 | ✅ | ❌ | +| CollectApiJobsMeta | <10^5 | ❌ | ✅ | + +### Github + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|------------------------------------|-------------------------------------|-----------------------------------------|------------------------------| +| --------------------------------- | Common | ----------------------- | | +| CollectMilestonesMeta | ≈10 | ✅ | ❌ | +| CollectRunsMeta | <10^4 | ✅ | ✅ | +| CollectApiCommentsMeta | 400 (max page that GitHub supports) | ✅ | ✅ | +| **CollectApiEventsMeta** | 400 (max page that GitHub supports) | ❌ | ❌ | +| CollectApiPullRequestReviewsMeta | <10^5 | ✅ | ✅ | +| --------------------------------- | Graphql Only (Default) | ----------------------- | | +| CollectIssueMeta | ≈10^4 | ❌ | ✅ | +| CollectPrMeta | ≈10^3 | ❌ | ✅ | +| CollectCheckRunMeta | <10^4 | ❌ | ✅ | +| CollectAccountMeta | ≈10^2 | ❌ | - | +| --------------------------------- | Restful Only (Not by Default) | ----------------------- | | +| CollectApiIssuesMeta | ≈10^4 | ✅ | ❌ | +| CollectApiPullRequestsMeta | ≈10^2 | ❌ | ❌ | +| CollectApiPullRequestCommitsMeta | ≈10^4 | ✅ | ✅ | +| **CollectApiPrReviewCommentsMeta** | ≈10^4 | ✅ | ✅ | +| **CollectAccountsMeta** | ≈10^4 | ❌ | ❌ | +| **CollectAccountOrgMeta** | ≈10^4 | ❌ | ❌ | +| CollectJobsMeta | <10^6 | ❌ | ✅ | +| CollectApiCommitsMeta | Not enabled | - | - | +| CollectApiCommitStatsMeta | Not enabled | - | - | + +### Feishu + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|-------------------------------|---------------------------------|-----------------------------------------|------------------------------| +| CollectMeetingTopUserItemMeta | ≈10^3 | ❌ | ✅ | + +### Bitbucket + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|-------------------------------------|---------------------------------|-----------------------------------------|------------------------------| +| ~~CollectApiRepoMeta~~ | 1 | ❌ | ❌ | +| CollectApiPullRequestsMeta | ≈10^3 | ❌ | ❌ | +| **CollectApiIssuesMeta** | ≈10^4 | ❌ | ❌ | +| **CollectApiPrCommentsMeta** | ≈10^5 | ❌ | ❌ | +| **\*CollectApiIssueCommentsMeta\*** | ≈10^6 | ❌ | ❌ | +| **CollectApiPipelinesMeta** | <10^4 | ❌ | ❌ | +| CollectApiDeploymentsMeta | <10^2 | ❌ | ❌ | + +### Gitee + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|--------------------------------------|---------------------------------|-----------------------------------------|------------------------------| +| ~~CollectApiRepoMeta~~ | 1 | ❌ | ❌ | +| CollectApiPullRequestsMeta | ≈10^3 | ✅ | ❌ | +| **CollectApiIssuesMeta** | ≈10^4 | ✅ | ❌ | +| **CollectCommitsMeta?** | ≈10^4 | ✅ | ❌ | +| **CollectApiPrCommentsMeta** | ≈10^5 | ❌ | ❌ | +| **\*CollectApiIssueCommentsMeta\*** | ≈10^6 | ✅ | ❌ | +| **CollectApiPullRequestCommitsMeta** | ≈10^5 | ❌ | ❌ | +| **CollectApiPullRequestReviewsMeta** | ≈10^5 | ❌ | ❌ | +| **\*CollectApiCommitStatsMeta\*** | ≈10^6 (Not enable) | ❌ | ❌ | + +### SonarQube + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|------------------------------|---------------------------------|-----------------------------------------|------------------------------| +| CollectAccounts | <10^4 | ❌ | ❌ | +| CollectIssues | <10^4 | ❌ | ❌ | +| CollectHotspots | <10^4 | ❌ | ❌ | +| CollectFilemetrics | <10^4 | ❌ | ❌ | +| CollectAdditionalFilemetrics | <10^4 | ❌ | ❌ | + +### Bamboo + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|----------------------|---------------------------------|-----------------------------------------|------------------------------| +| CollectPlanMeta | <10^4 | ❌ | ❌ | +| CollectJobMeta | <10^5 | ❌ | ❌ | +| CollectPlanBuildMeta | <10^6 | ❌ | ❌ | +| CollectJobBuildMeta | <10^6 | ❌ | ❌ | +| CollectDeployMeta | 1 | ❌ | ❌ | + +### Zentao + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|-----------------------|---------------------------------|-----------------------------------------|------------------------------| +| CollectExecutionMeta | <10^3 | ❌ | ❌ | +| CollectStoryMeta | <10^4 | ❌ | ❌ | +| CollectBugMeta | <10^4 | ❌ | ❌ | +| CollectTaskMeta | <10^4 | ❌ | ❌ | +| CollectAccountMeta | ≈10^2 | ❌ | ❌ | +| CollectDepartmentMeta | ≈10^2 | ❌ | ❌ | + +### Tapd + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|--------------------------------|---------------------------------|-----------------------------------------|------------------------------| +| CollectWorkitemTypesMeta | ≈10 | - | - | +| CollectStoryCustomFieldsMeta | ≈10 | - | - | +| CollectTaskCustomFieldsMeta | ≈10 | - | - | +| CollectBugCustomFieldsMeta | ≈10 | - | - | +| CollectStoryCategoriesMeta | ≈10 | - | - | +| CollectStoryStatusMeta | ≈10 | - | - | +| CollectStoryStatusLastStepMeta | ≈10 | - | - | +| CollectBugStatusMeta | ≈10 | - | - | +| CollectBugStatusLastStepMeta | ≈10 | - | - | +| CollectAccountsMeta | ≈10^3 | ❌ | ❌ | +| CollectIterationMeta | ≈10^4 | ✅ | ✅ | +| CollectStoryMeta | ≈10^4 | ✅ | ✅ | +| CollectBugMeta | ≈10^4 | ✅ | ✅ | +| CollectTaskMeta | ≈10^4 | ✅ | ✅ | +| CollectBugChangelogMeta | ≈10^6 | ✅ | ✅ | +| CollectStoryChangelogMeta | ≈10^6 | ✅ | ✅ | +| CollectTaskChangelogMeta | ≈10^6 | ✅ | ✅ | +| CollectWorklogMeta | ≈10^6 | ✅ | ✅ | +| CollectBugCommitMeta | ≈10^6 | ✅ | ✅ | +| CollectStoryCommitMeta | ≈10^6 | ✅ | ✅ | +| CollectTaskCommitMeta | ≈10^6 | ✅ | ✅ | +| CollectStoryBugMeta | ≈10^6 | ✅ | ✅ | + +### Azure Devops + +| Subtask Name | Estimated Max Number of Request | Does It support Incremental Collection? | Does It Support Time Filter? | +|---------------------------|---------------------------------|-----------------------------------------|------------------------------| +| CollectBuilds | <10^3 | ❌ | ❌ | +| CollectJobs | <10^4 | ❌ | ❌ | +| CollectPullRequests | <10^3 | ❌ | ❌ | +| CollectPullRequestCommits | <10^4 | ❌ | ❌ | diff --git a/versioned_docs/version-v0.21/Overview/_category_.json b/versioned_docs/version-v0.21/Overview/_category_.json new file mode 100644 index 00000000000..3e819ddc4ff --- /dev/null +++ b/versioned_docs/version-v0.21/Overview/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Overview", + "position": 1, + "link":{ + "type": "generated-index", + "slug": "Overview" + } +} diff --git a/versioned_docs/version-v0.21/Plugins/_category_.json b/versioned_docs/version-v0.21/Plugins/_category_.json new file mode 100644 index 00000000000..bbea8d5910c --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Plugins", + "position": 9, + "link":{ + "type": "generated-index", + "slug": "Plugins" + } +} diff --git a/versioned_docs/version-v0.21/Plugins/azuredevops.md b/versioned_docs/version-v0.21/Plugins/azuredevops.md new file mode 100644 index 00000000000..3a337448976 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/azuredevops.md @@ -0,0 +1,71 @@ +--- +title: "Azure DevOps" +description: > + Azure DevOps Plugin +--- + +## Summary + +This plugin collects Azure DevOps data through Azure DevOps REST API. + +## Supported Versions + +Available for Azure DevOps Cloud. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Entities + +Check out the [Azure DevOps entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Data Refresh Policy + +Right now, this plugin supports only full refresh. +Check out the [data refresh policy](/Overview/SupportedDataSources.md#Azure DevOps) of this plugin. + +## Metrics + +Metrics that can be calculated based on the data collected from Azure DevOps: + +- [Commit Count](/Metrics/CommitCount.md) +- [Commit Author Count](/Metrics/CommitAuthorCount.md) +- [Added Lines of Code](/Metrics/AddedLinesOfCode.md) +- [Deleted Lines of Code](/Metrics/DeletedLinesOfCode.md) +- [Build Count](/Metrics/BuildCount.md) +- [Build Duration](/Metrics/BuildDuration.md) +- [Build Success Rate](/Metrics/BuildSuccessRate.md) +- [DORA - Deployment Frequency](/Metrics/DeploymentFrequency.md) +- [DORA - Lead Time for Changes](/Metrics/LeadTimeForChanges.md) +- [DORA - Median Time to Restore Service](/Metrics/MTTR.md) +- [DORA - Change Failure Rate](/Metrics/CFR.md) + +## Configuration + +Configuring Azure DevOps via [config-ui](/Configuration/AzureDevOps.md). + +## API Sample Request + +You can trigger data collection by making a POST request to `/pipelines`. + +```shell +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "MY PIPELINE", + "plan": [ + [ + { + "plugin": "azuredevops", + "options": { + "connectionId": 1, + "scopeId": "orgname/reponame", + "transformationRules": { + "deploymentPattern": "", + "productionPattern": "" + } + } + } + ] + ] +} +' +``` diff --git a/versioned_docs/version-v0.21/Plugins/bamboo.md b/versioned_docs/version-v0.21/Plugins/bamboo.md new file mode 100644 index 00000000000..8dc9b49aa9f --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/bamboo.md @@ -0,0 +1,67 @@ +--- +title: "Bamboo" +description: > + Bamboo Plugin +--- + +## Summary + +This plugin collects Bamboo's CI data through [API](https://developer.atlassian.com/server/bamboo/rest/). It then computes and visualizes various DevOps metrics from the Bamboo data, which helps tech leads, QA and DevOps engineers, and project managers to answer questions such as: + +- What is the deployment frequency of your team? +- How long does it take for your codes to get deployed? + +## Supported Versions + +Only Bamboo v6.8.1+ is supported as of v0.20. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Entities + +Check out the [Bamboo entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Data Refresh Policy + +Check out the [data refresh policy](/Overview/SupportedDataSources.md#bamboo) of this plugin. + +## Metrics + +Metrics that can be calculated based on the data collected from Bamboo: + +- [DORA - Deployment Frequency](/Metrics/DeploymentFrequency.md) +- [DORA - Lead Time for Changes](/Metrics/LeadTimeForChanges.md) +- [DORA - Median Time to Restore Service](/Metrics/MTTR.md) +- [DORA - Change Failure Rate](/Metrics/CFR.md) + +## API Sample Request + +You can trigger data collection by making a POST request to `/pipelines`. + +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "project1-BLUEPRINT", + "blueprintId": 1, + "plan": [ + [ + { + "plugin": "bamboo", + "options": { + "connectionId": 1, + "key": "TEST", + "transformationRules":{ + "deploymentPattern":"", + "productionPattern":"", + } + } + } + ] + ] +} +' +``` + +## References + +- [references](/DeveloperManuals/DeveloperSetup.md#references) diff --git a/versioned_docs/version-v0.21/Plugins/bitbucket.md b/versioned_docs/version-v0.21/Plugins/bitbucket.md new file mode 100644 index 00000000000..17a4cd8119c --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/bitbucket.md @@ -0,0 +1,80 @@ +--- +title: "BitBucket Cloud" +description: > + BitBucket Plugin +--- + + + +## Summary + +This plugin collects various entities from Bitbucket, including pull requests, issues, comments, pipelines, git commits, and etc. + +As of v0.14.2, `bitbucket` plugin can only be invoked through DevLake API. Its support in Config-UI is WIP. + +## Supported Versions + +Available for BitBucket Cloud. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + + +## Entities + +Check out the [BitBucket entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Metrics + +Metrics that can be calculated based on the data collected from bitbucket: + +- [Commit Count](/Metrics/CommitCount.md) +- [Commit Author Count](/Metrics/CommitAuthorCount.md) +- [Added Lines of Code](/Metrics/AddedLinesOfCode.md) +- [Deleted Lines of Code](/Metrics/DeletedLinesOfCode.md) +- [PR Count](/Metrics/PRCount.md) +- [PR Time To Merge](/Metrics/PRTimeToMerge.md) +- [PR Merge Rate](/Metrics/PRMergeRate.md) +- [PR Review Depth](/Metrics/PRReviewDepth.md) +- [PR Size](/Metrics/PRSize.md) +- [Build Count](/Metrics/BuildCount.md) +- [Build Duration](/Metrics/BuildDuration.md) +- [Build Success Rate](/Metrics/BuildSuccessRate.md) + +## Configuration + +- Configuring Bitbucket via [Config UI](/Configuration/BitBucket.md) + +## API Sample Request +> Note: Please replace the `http://localhost:8080` in the sample requests with your actual DevLake API endpoint. For how to view DevLake API's swagger documentation, please refer to the "Using DevLake API" section of [Developer Setup](../DeveloperManuals/DeveloperSetup.md). + +You can trigger data collection by making a POST request to `/pipelines`. +```shell +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "project1", + "plan": [ + [ + { + "plugin": "bitbucket", + "options": { + "connectionId": 1, + "fullName": "likyh/likyhphp", + "transformationRules":{ + "deploymentPattern":"", + "productionPattern":"", + "issueStatusTodo":"new,open", + "issueStatusInProgress":"", + "issueStatusDone":"resolved,closed", + "issueStatusOther":"on hold,wontfix,duplicate,invalid" + } + } + } + ] + ] +} +' +``` + +## References + +- [references](/DeveloperManuals/DeveloperSetup.md#references) diff --git a/versioned_docs/version-v0.21/Plugins/circleci.md b/versioned_docs/version-v0.21/Plugins/circleci.md new file mode 100644 index 00000000000..568accea0c2 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/circleci.md @@ -0,0 +1,72 @@ +--- +title: "CircleCI" +description: > + CircleCI Plugin +--- + + +## Summary + +This plugin collects various entities from CircleCI, including accounts, jobs, workflows, pipelines and projects. + +## Supported Versions + +Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + + +## Entities + +Check out the [CircleCI entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Metrics + +Metrics that can be calculated based on the data collected from CircleCI: +- [Build Count](/Metrics/BuildCount.md) +- [Build Duration](/Metrics/BuildDuration.md) +- [Build Success Rate](/Metrics/BuildSuccessRate.md) +- [DORA - Deployment Frequency](/Metrics/DeploymentFrequency.md) +- [DORA - Lead Time for Changes](/Metrics/LeadTimeForChanges.md) +- [DORA - Median Time to Restore Service](/Metrics/MTTR.md) +- [DORA - Change Failure Rate](/Metrics/CFR.md) + + +## Configuration + +- Configuring CircleCI via [Config UI](/Configuration/CircleCI.md) + +## API Sample Request +> Note: Please replace the `http://localhost:8080` in the sample requests with your actual DevLake API endpoint. For how to view DevLake API's swagger documentation, please refer to the "Using DevLake API" section of [Developer Setup](../DeveloperManuals/DeveloperSetup.md). + +You can trigger data collection by making a POST request to `/pipelines`. +```shell +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "project1", + "plan": [ + [ + { + "plugin": "circleci", + "options": { + "connectionId": 1, + "fullName": "likyh/likyhphp", + "transformationRules":{ + "deploymentPattern":"", + "productionPattern":"", + "issueStatusTodo":"new,open", + "issueStatusInProgress":"", + "issueStatusDone":"resolved,closed", + "issueStatusOther":"on hold,wontfix,duplicate,invalid" + } + } + } + ] + ] +} +' +``` + +## References + +- [references](/DeveloperManuals/DeveloperSetup.md#references) diff --git a/versioned_docs/version-v0.21/Plugins/customize.md b/versioned_docs/version-v0.21/Plugins/customize.md new file mode 100644 index 00000000000..17d1840acf2 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/customize.md @@ -0,0 +1,218 @@ +--- +title: "Customize" +description: > + Customize Plugin +--- + + + +## Summary + +This plugin provides users the ability to: +- Add/delete columns in domain layer tables +- Insert values to certain columns with data extracted from some raw layer tables +- Import data from CSV files(only `issues` and `issue_commits` two tables are supported) + +**NOTE:** The names of columns added via this plugin must start with the prefix `x_` + +For now, only the following five types were supported: +- varchar(255) +- text +- bigint +- float +- timestamp +- array + +## Sample Request + +### Trigger Data Extraction +To extract data, switch to `Advanced Mode` on the first step of creating a Blueprint and paste a JSON config as the following: + +The example below demonstrates how to extract status name from the table `_raw_jira_api_issues`: + 1. For non-array types: Extract the status name from the `_raw_jira_api_issues` table and assign it to the `x_test` column in the [issues](/DataModels/DevLakeDomainLayerSchema.md#issues) table. + 2. For array types: Extract the status name from the `_raw_jira_api_issues` table, and create a new [issue_custom_array_fields](/DataModels/DevLakeDomainLayerSchema.md#issue_custom_array_fields) table containing `issue_id`, `field_id`, and `value` columns. This table has a one-to-many relationship with the `issues` table. `issue_id` is the id corresponding to the issue, `x_test` corresponds to the `field_id` column, and the value of `x_test` corresponds to the `value` column. + +We leverage the package `https://github.com/tidwall/gjson` to extract value from the JSON. For the extraction syntax, please refer to this [docs](https://github.com/tidwall/gjson/blob/master/SYNTAX.md) + +- `table`: domain layer table name +- `rawDataTable`: raw layer table, from which we extract values by json path +- `rawDataParams`: the filter to select records from the raw layer table (**The value should be a string not an object**) +- `mapping`: the extraction rule; the key is the extension field name; the value is json path + +```json +[ + [ + { + "plugin":"customize", + "options":{ + "transformationRules":[ + { + "table":"issues", + "rawDataTable":"_raw_jira_api_issues", + "rawDataParams":"{\"ConnectionId\":1,\"BoardId\":8}", + "mapping":{ + "x_test":"fields.status.name" + } + } + ] + } + } + ] +] +``` + +You can also trigger data extraction by making a POST request to `/pipelines`. +```shell +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "extract fields", + "plan": [ + [ + { + "plugin": "customize", + "options": { + "transformationRules": [ + { + "table": "issues", + "rawDataTable": "_raw_jira_api_issues", + "rawDataParams": "{\"ConnectionId\":1,\"BoardId\":8}", + "mapping": { + "x_test": "fields.status.name" + } + } + ] + } + } + ] + ] +} +' +``` + +### List Columns +Get all columns of the table `issues` +> GET /plugins/customize/issues/fields + +**NOTE** some fields are omitted in the following example +response +```json +[ + { + "columnName": "id", + "displayName": "", + "dataType": "varchar(255)", + "description": "" + }, + { + "columnName": "created_at", + "displayName": "", + "dataType": "datetime(3)", + "description": "" + }, + { + "columnName": "x_time", + "displayName": "time", + "dataType": "timestamp", + "description": "test for time" + }, + { + "columnName": "x_int", + "displayName": "bigint", + "dataType": "bigint", + "description": "test for int" + }, + { + "columnName": "x_float", + "displayName": "float", + "dataType": "float", + "description": "test for float" + }, + { + "columnName": "x_text", + "displayName": "text", + "dataType": "text", + "description": "test for text" + }, + { + "columnName": "x_varchar", + "displayName": "varchar", + "dataType": "varchar(255)", + "description": "test for varchar" + } +] + +``` + +### Create a Customized Column +Create a new column `x_abc` with datatype `varchar(255)` for the table `issues`. + +The value of `columnName` must start with `x_` and consist of no more than 50 alphanumerics and underscores. +The value of field `dataType` must be one of the following 5 types: +- varchar(255) +- text +- bigint +- float +- timestamp + +> POST /plugins/customize/issues/fields +```json +{ + "columnName": "x_abc", + "displayName": "ABC", + "dataType": "varchar(255)", + "description": "test field" +} +``` + +### Drop A Column +Drop the column `x_text` of the table `issues` + +> DELETE /plugins/customize/issues/fields/x_test + +### Upload `issues.csv` file + +> POST /plugins/customize/csvfiles/issues.csv + +The HTTP `Content-Type` must be `multipart/form-data`, and the form should have three fields: + +- `file`: The CSV file +- `boardId`: It will be written to the `id` field of the `boards` table, the `board_id` field of `board_issues`, and the `_raw_data_params` field of `issues` +- `boardName`: It will be written to the `name` field of the `boards` table + +Upload a CSV file and import it to the `issues` table via this API. There should be no extra fields in the file except the `labels` field, and if the field value is `NULL`, it should be `NULL` in the CSV instead of the empty string. +DevLake will parse the CSV file and store it in the `issues` table, where the `labels` are stored in the `issue_labels` table. +If the `boardId` does not appear, a new record will be created in the boards table. The `board_issues` table will be updated at the same time as the import. +The following is an issues.CSV file sample: + +|id |_raw_data_params |url |icon_url|issue_key|title |description |epic_key|type |status|original_status|story_point|resolution_date|created_date |updated_date |parent_issue_id|priority|original_estimate_minutes|time_spent_minutes|time_remaining_minutes|creator_id |creator_name|assignee_id |assignee_name|severity|component|lead_time_minutes|original_project|original_type|x_int |x_time |x_varchar|x_float|labels | +|-----------------------------|---------------------|--------------------------------------------------------------------|--------|---------|-------------|---------------------------------|--------|-----|------|---------------|-----------|---------------|-----------------------------|-----------------------------|---------------|--------|-------------------------|------------------|----------------------|-----------------------------------------------------|------------|-----------------------------------------------------|-------------|--------|---------|-----------------|----------------|-------------|--------------|-------------------|---------|-------|--------------------| +|bitbucket:BitbucketIssue:1:1 |board789 |https://api.bitbucket.org/2.0/repositories/thenicetgp/lake/issues/1 | |1 |issue test |bitbucket issues test for devlake| |issue|TODO |new |0 |NULL |2022-07-17 07:15:55.959+00:00|2022-07-17 09:11:42.656+00:00| |major |0 |0 |0 |bitbucket:BitbucketAccount:1:62abf394192edb006fa0e8cf|tgp |bitbucket:BitbucketAccount:1:62abf394192edb006fa0e8cf|tgp | | |NULL |NULL |NULL |10 |2022-09-15 15:27:56|world |8 |NULL | +|bitbucket:BitbucketIssue:1:10|board789 |https://api.bitbucket.org/2.0/repositories/thenicetgp/lake/issues/10| |10 |issue test007|issue test007 | |issue|TODO |new |0 |NULL |2022-08-12 13:43:00.783+00:00|2022-08-12 13:43:00.783+00:00| |trivial |0 |0 |0 |bitbucket:BitbucketAccount:1:62abf394192edb006fa0e8cf|tgp |bitbucket:BitbucketAccount:1:62abf394192edb006fa0e8cf|tgp | | |NULL |NULL |NULL |30 |2022-09-15 15:27:56|abc |2456790|hello worlds | +|bitbucket:BitbucketIssue:1:13|board789 |https://api.bitbucket.org/2.0/repositories/thenicetgp/lake/issues/13| |13 |issue test010|issue test010 | |issue|TODO |new |0 |NULL |2022-08-12 13:44:46.508+00:00|2022-08-12 13:44:46.508+00:00| |critical|0 |0 |0 |bitbucket:BitbucketAccount:1:62abf394192edb006fa0e8cf|tgp | | | | |NULL |NULL |NULL |1 |2022-09-15 15:27:56|NULL |0.00014|NULL | +|bitbucket:BitbucketIssue:1:14|board789 |https://api.bitbucket.org/2.0/repositories/thenicetgp/lake/issues/14| |14 |issue test011|issue test011 | |issue|TODO |new |0 |NULL |2022-08-12 13:45:12.810+00:00|2022-08-12 13:45:12.810+00:00| |blocker |0 |0 |0 |bitbucket:BitbucketAccount:1:62abf394192edb006fa0e8cf|tgp |bitbucket:BitbucketAccount:1:62abf394192edb006fa0e8cf|tgp | | |NULL |NULL |NULL |41534568464351|2022-09-15 15:27:56|NULL |NULL |label1,label2,label3| + + +### Upload `issue_commits.csv` file + +> POST /plugins/customize/csvfiles/issue_commits.csv + +The `Content-Type` should be `multipart/form-data`, and the form should have two fields: + +- `file`: The CSV file +- `boardId`: It will be written to the `_raw_data_params` field of `issue_commits` + +The following is an issue_commits.CSV file sample: + +|issue_id |commit_sha | +|----------------------|----------------------------------------| +|jira:JiraIssue:1:10063|8748a066cbaf67b15e86f2c636f9931347e987cf| +|jira:JiraIssue:1:10064|e6bde456807818c5c78d7b265964d6d48b653af6| +|jira:JiraIssue:1:10065|8f91020bcf684c6ad07adfafa3d8a2f826686c42| +|jira:JiraIssue:1:10066|0dfe2e9ed88ad4e27f825d9b67d4d56ac983c5ef| +|jira:JiraIssue:1:10145|07aa2ebed68e286dc51a7e0082031196a6135f74| +|jira:JiraIssue:1:10145|d70d6687e06304d9b6e0cb32b3f8c0f0928400f7| +|jira:JiraIssue:1:10159|d28785ff09229ac9e3c6734f0c97466ab00eb4da| +|jira:JiraIssue:1:10202|0ab12c4d4064003602edceed900d1456b6209894| +|jira:JiraIssue:1:10203|980e9fe7bc3e22a0409f7241a024eaf9c53680dd| diff --git a/versioned_docs/version-v0.21/Plugins/dbt.md b/versioned_docs/version-v0.21/Plugins/dbt.md new file mode 100644 index 00000000000..059bf12c61d --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/dbt.md @@ -0,0 +1,67 @@ +--- +title: "DBT" +description: > + DBT Plugin +--- + + +## Summary + +dbt (data build tool) enables analytics engineers to transform data in their warehouses by simply writing select statements. dbt handles turning these select statements into tables and views. +dbt does the T in ELT (Extract, Load, Transform) processes – it doesn’t extract or load data, but it’s extremely good at transforming data that’s already loaded into your warehouse. + +## User setup +- If you plan to use this product, you need to install some environments first. + +#### Required Packages to Install +- [python3.7+](https://www.python.org/downloads/) +- [dbt-mysql](https://pypi.org/project/dbt-mysql/#configuring-your-profile) + +#### Commands to run or create in your terminal and the dbt project +1. pip install dbt-mysql +2. dbt init demoapp (demoapp is project name) +3. create your SQL transformations and data models + +## Convert Data By DBT + +Use the Raw JSON API to manually initiate a run using **cURL** or graphical API tool such as **Postman**. `POST` the following request to the DevLake API Endpoint. + +```json +[ + [ + { + "plugin": "dbt", + "options": { + "projectPath": "/Users/abeizn/demoapp", + "projectName": "demoapp", + "projectTarget": "dev", + "selectedModels": ["my_first_dbt_model","my_second_dbt_model"], + "projectVars": { + "demokey1": "demovalue1", + "demokey2": "demovalue2" + } + } + } + ] +] +``` + +- `projectPath`: the absolute path of the dbt project. (required) +- `projectName`: the name of the dbt project. (required) +- `projectTarget`: this is the default target your dbt project will use. (optional) +- `selectedModels`: a model is a select statement. Models are defined in .sql files, and typically in your models directory. (required) +And selectedModels accepts one or more arguments. Each argument can be one of: +1. a package name, runs all models in your project, example: example +2. a model name, runs a specific model, example: my_fisrt_dbt_model +3. a fully-qualified path to a directory of models. + +- `projectVars`: variables to parametrize dbt models. (optional) +example: +`select * from events where event_type = '{{ var("event_type") }}'` +To execute this SQL query in your model, you need set a value for `event_type`. + +### Resources: +- Learn more about dbt [in the docs](https://docs.getdbt.com/docs/introduction) +- Check out [Discourse](https://discourse.getdbt.com/) for commonly asked questions and answers + +


diff --git a/versioned_docs/version-v0.21/Plugins/feishu.md b/versioned_docs/version-v0.21/Plugins/feishu.md new file mode 100644 index 00000000000..eb3ed1ba2ad --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/feishu.md @@ -0,0 +1,74 @@ +--- +title: "Feishu" +description: > + Feishu Plugin +--- + +## Summary + +This plugin collects Feishu meeting data through [Feishu Openapi](https://open.feishu.cn/document/home/user-identity-introduction/introduction). + +## Supported Versions +Will be available for all versions. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Configuration + +In order to fully use this plugin, you need to get `app_id` and `app_secret` from a Feishu administrator (for help on App info, please see [official Feishu Docs](https://open.feishu.cn/document/ukTMukTMukTM/ukDNz4SO0MjL5QzM/auth-v3/auth/tenant_access_token_internal)). + +A connection should be created before you can collect any data. Currently, this plugin supports creating connection by requesting the `connections` API: + +``` +curl 'http://localhost:8080/plugins/feishu/connections' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "feishu", + "endpoint": "https://open.feishu.cn/open-apis/vc/v1/", + "proxy": "http://localhost:1080", + "rateLimitPerHour": 20000, + "appId": "", + "appSecret": "" +} +' +``` + +## Collect data from Feishu + +To collect data, select `Advanced Mode` on the `Create Pipeline Run` page and paste a JSON config like the following: + + +```json +[ + [ + { + "plugin": "feishu", + "options": { + "connectionId": 1, + "numOfDaysToCollect" : 80 + } + } + ] +] +``` + +> `numOfDaysToCollect`: The number of days you want to collect + +> `rateLimitPerSecond`: The number of requests to send(Maximum is 8) + +You can also trigger data collection by making a POST request to `/pipelines`. +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "feishu 20211126", + "plan": [[{ + "plugin": "feishu", + "options": { + "connectionId": 1, + "numOfDaysToCollect" : 80 + } + }]] +} +' +``` diff --git a/versioned_docs/version-v0.21/Plugins/gitee.md b/versioned_docs/version-v0.21/Plugins/gitee.md new file mode 100644 index 00000000000..742c4498852 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/gitee.md @@ -0,0 +1,110 @@ +--- +title: "Gitee(WIP)" +description: > + Gitee Plugin +--- + +## Summary + +This plugin collects `Gitee` data through [Gitee Openapi](https://gitee.com/api/v5/swagger). + +## Supported Versions + +Will be available for Gitee Cloud. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Configuration + +In order to fully use this plugin, you need to get the `token` on the Gitee website. + +A connection should be created before you can collect any data. Currently, this plugin supports creating connection by requesting the `connections` API: + +``` +curl 'http://localhost:8080/plugins/gitee/connections' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "gitee", + "endpoint": "https://gitee.com/api/v5/", + "proxy": "http://localhost:1080", + "rateLimitPerHour": 20000, + "token": "" +} +' +``` + + + +## Collect data from Gitee + +In order to collect data, you have to compose a JSON looks like following one, and send it by selecting `Advanced Mode` on `Create Pipeline Run` page: + +1. Configure-UI Mode +```json +[ + [ + { + "plugin": "gitee", + "options": { + "connectionId": 1, + "repo": "lake", + "owner": "merico-dev" + } + } + ] +] +``` +and if you want to perform certain subtasks. +```json +[ + [ + { + "plugin": "gitee", + "subtasks": ["collectXXX", "extractXXX", "convertXXX"], + "options": { + "connectionId": 1, + "repo": "lake", + "owner": "merico-dev" + } + } + ] +] +``` + +2. Curl Mode: + You can also trigger data collection by making a POST request to `/pipelines`. +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "gitee 20211126", + "plan": [[{ + "plugin": "gitee", + "options": { + "connectionId": 1, + "repo": "lake", + "owner": "merico-dev" + } + }]] +} +' +``` +and if you want to perform certain subtasks. +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "gitee 20211126", + "plan": [[{ + "plugin": "gitee", + "subtasks": ["collectXXX", "extractXXX", "convertXXX"], + "options": { + "connectionId": 1, + "repo": "lake", + "owner": "merico-dev" + } + }]] +} +' +``` diff --git a/versioned_docs/version-v0.21/Plugins/gitextractor.md b/versioned_docs/version-v0.21/Plugins/gitextractor.md new file mode 100644 index 00000000000..b4e4a206fb2 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/gitextractor.md @@ -0,0 +1,137 @@ +--- +title: "GitExtractor" +description: > + GitExtractor Plugin +--- + +## Summary + +This plugin extracts commits and references from a remote or local git repository. It then saves the data into the database or csv files. + +## Steps to make this plugin work + +1. Use the Git repo extractor to retrieve data about commits and branches from your repository. +2. Use the GitHub plugin to retrieve data about Github issues and PRs from your repository. + NOTE: you can run only one issue collection stage as described in the Github Plugin README. +3. Use the [RefDiff](./refdiff.md) plugin to calculate version diff, which will be stored in `refs_commits` table. + +Note: If you do not want to collect commit files, you can bypass this step by setting the SKIP_COMMIT_FILES=true in the .env file. This will prevent the plugin from collecting commit file data. + +## Sample Request + +``` +curl --location --request POST 'localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "git repo extractor", + "plan": [ + [ + { + "Plugin": "gitextractor", + "Options": { + "url": "https://github.com/merico-dev/lake.git", + "repoId": "github:GithubRepo:384111310" + } + } + ] + ] +} +' +``` + +- `url`: the location of the git repository. It should start with `http`/`https` for a remote git repository and with `/` for a local one. +- `repoId`: column `id` of `repos`. + Note : For GitHub, to find the repo id run `$("meta[name=octolytics-dimension-repository_id]").getAttribute('content')` in browser console. +- `proxy`: optional, http proxy, e.g. `http://your-proxy-server.com:1080`. +- `user`: optional, for cloning private repository using HTTP/HTTPS +- `password`: optional, for cloning private repository using HTTP/HTTPS +- `privateKey`: optional, for SSH cloning, base64 encoded `PEM` file +- `passphrase`: optional, passphrase for the private key + +## Standalone Mode + +You call also run this plugin in a standalone mode without any DevLake service running using the following command: + +``` +go run plugins/gitextractor/main.go -url https://github.com/merico-dev/lake.git -id github:GithubRepo:384111310 -db "merico:merico@tcp(127.0.0.1:3306)/lake?charset=utf8mb4&parseTime=True" +``` + +For more options (e.g., saving to a csv file instead of a db), please read `plugins/gitextractor/main.go`. + +## Development + +This plugin depends on `libgit2`, you need to install version 1.3.0 to run and debug this plugin on your local +machine. + +### Linux + +``` +1. require cmake +[ubuntu] +apt install cmake -y +[centos] +yum install cmake -y + +2. compiling +git clone -b v1.3.0 https://github.com/libgit2/libgit2.git && cd libgit2 +mkdir build && cd build && cmake .. +make && make install + +3.PKG_CONFIG and LD_LIBRARY_PATH +[centos] +export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib64:/usr/local/lib64/pkgconfig +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64 +[ubuntu] +export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib:/usr/local/lib/pkgconfig +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +``` + +#### Troubleshooting (Linux) + +> Q: # pkg-config --cflags -- libgit2 Package libgit2 was not found in the pkg-config search path. +> Perhaps you should add the directory containing `libgit2.pc` to the PKG_CONFIG_PATH environment variable +> No package 'libgit2' found pkg-config: exit status 1 + +> A: +> Make sure your pkg config path covers the installation: +> if your libgit2.pc in `/usr/local/lib64/pkgconfig`(like centos) +> +> `export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib64:/usr/local/lib64/pkgconfig` +> +> else if your libgit2.pc in `/usr/local/lib/pkgconfig`(like ubuntu) +> +> `export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib:/usr/local/lib/pkgconfig` +> +> else consider install pkgconfig or rebuild the libgit2 + +### MacOS + +NOTE: **Do NOT** install libgit2 via `MacPorts` or `homebrew`, install from source instead. + +``` +brew install cmake +git clone https://github.com/libgit2/libgit2.git +cd libgit2 +git checkout v1.3.0 +mkdir build +cd build +cmake .. +make +make install +``` + +#### Troubleshooting (MacOS) + +> Q: I got an error saying: `pkg-config: exec: "pkg-config": executable file not found in $PATH` + +> A: +> +> 1. Make sure you have pkg-config installed: +> +> `brew install pkg-config` +> +> 2. Make sure your pkg config path covers the installation: +> `export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib:/usr/local/lib/pkgconfig` + +


diff --git a/versioned_docs/version-v0.21/Plugins/github.md b/versioned_docs/version-v0.21/Plugins/github.md new file mode 100644 index 00000000000..e14cd532abc --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/github.md @@ -0,0 +1,145 @@ +--- +title: "GitHub" +description: > + GitHub Plugin +--- + +## Summary + +This plugin collects GitHub data through [REST API](https://docs.github.com/en/rest/) and [GraphQL API](https://docs.github.com/en/graphql). It then computes and visualizes various DevOps metrics from the GitHub data, which helps tech leads, QA and DevOps engineers, and project managers to answer questions such as: + +- Is this month more productive than last? +- How fast do we respond to customer requirements? +- Was our quality improved or not? + +## Supported Versions + +Available for GitHub Cloud. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Entities + +Check out the [GitHub entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Data Refresh Policy + +Check out the [data refresh policy](/Overview/SupportedDataSources.md#github) of this plugin. + +## Metrics + +Metrics that can be calculated based on the data collected from GitHub: + +- [Requirement Count](/Metrics/RequirementCount.md) +- [Requirement Lead Time](/Metrics/RequirementLeadTime.md) +- [Requirement Delivery Rate](/Metrics/RequirementDeliveryRate.md) +- [Requirement Granularity](/Metrics/RequirementGranularity.md) +- [Bug Age](/Metrics/BugAge.md) +- [Bug Count per 1k Lines of Code](/Metrics/BugCountPer1kLinesOfCode.md) +- [Incident Age](/Metrics/IncidentAge.md) +- [Incident Count per 1k Lines of Code](/Metrics/IncidentCountPer1kLinesOfCode.md) +- [Commit Count](/Metrics/CommitCount.md) +- [Commit Author Count](/Metrics/CommitAuthorCount.md) +- [Added Lines of Code](/Metrics/AddedLinesOfCode.md) +- [Deleted Lines of Code](/Metrics/DeletedLinesOfCode.md) +- [PR Count](/Metrics/PRCount.md) +- [PR Cycle Time](/Metrics/PRCycleTime.md) +- [PR Coding Time](/Metrics/PRCodingTime.md) +- [PR Pickup Time](/Metrics/PRPickupTime.md) +- [PR Review Time](/Metrics/PRReviewTime.md) +- [PR Deploy Time](/Metrics/PRDeployTime.md) +- [PR Time To Merge](/Metrics/PRTimeToMerge.md) +- [PR Merge Rate](/Metrics/PRMergeRate.md) +- [PR Review Depth](/Metrics/PRReviewDepth.md) +- [PR Size](/Metrics/PRSize.md) +- [Build Count](/Metrics/BuildCount.md) +- [Build Duration](/Metrics/BuildDuration.md) +- [Build Success Rate](/Metrics/BuildSuccessRate.md) +- [DORA - Deployment Frequency](/Metrics/DeploymentFrequency.md) +- [DORA - Lead Time for Changes](/Metrics/LeadTimeForChanges.md) +- [DORA - Median Time to Restore Service](/Metrics/MTTR.md) +- [DORA - Change Failure Rate](/Metrics/CFR.md) + +## Configuration + +- Configuring GitHub via [Config UI](/Configuration/GitHub.md) +- Configuring GitHub via Config UI's [advanced mode](/Configuration/AdvancedMode.md#1-github). + +## API Sample Request + +You can trigger data collection by making a POST request to `/pipelines`. + +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "project1-BLUEPRINT", + "blueprintId": 1, + "plan": [ + [ + { + "plugin": "github", + "options": { + "connectionId": 1, + "scopeId": "384111310", + "transformationRules":{ + "deploymentPattern":"", + "productionPattern":"", + "issueComponent":"", + "issuePriority":"(high|medium|low)$", + "issueSeverity":"", + "issueTypeBug":"(bug)$", + "issueTypeIncident":"", + "issueTypeRequirement":"(feature|feature-request)$", + "prBodyClosePattern":"", + "prComponent":"", + "prType":"" + } + } + } + ] + ] +} +' +``` + +or + +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "project1-BLUEPRINT", + "blueprintId": 1, + "plan": [ + [ + { + "plugin": "github", + "options": { + "connectionId": 1, + "owner": "apache", + "repo": "incubator-devlake", + "transformationRules":{ + "deploymentPattern":"", + "productionPattern":"", + "issueComponent":"", + "issuePriority":"(high|medium|low)$", + "issueSeverity":"", + "issueTypeBug":"(bug)$", + "issueTypeIncident":"", + "issueTypeRequirement":"(feature|feature-request)$", + "prBodyClosePattern":"", + "prComponent":"", + "prType":"" + } + } + } + ] + ] +} +' +``` + +## References + +- [references](/DeveloperManuals/DeveloperSetup.md#references) diff --git a/versioned_docs/version-v0.21/Plugins/gitlab.md b/versioned_docs/version-v0.21/Plugins/gitlab.md new file mode 100644 index 00000000000..59f4a63f4f8 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/gitlab.md @@ -0,0 +1,100 @@ +--- +title: "GitLab" +description: > + GitLab Plugin +--- + +## Summary + +This plugin collects GitLab data through [API](https://docs.gitlab.com/ee/api/). It then computes and visualizes various DevOps metrics from the GitLab data, which helps tech leads, QA and DevOps engineers, and project managers to answer questions such as: + +- How long does it take for your codes to get merged? +- How much time is spent on code review? +- How long does it take for your codes to get merged? +- How much time is spent on code review? + +## Supported Versions + +Available for GitLab Cloud, Community Edition 11+. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Entities + +Check out the [GitLab entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Data Refresh Policy + +Check out the [data refresh policy](/Overview/SupportedDataSources.md#gitlab) of this plugin. + +## Metrics + +Metrics that can be calculated based on the data collected from GitLab: + +- [Commit Count](/Metrics/CommitCount.md) +- [Commit Author Count](/Metrics/CommitAuthorCount.md) +- [Added Lines of Code](/Metrics/AddedLinesOfCode.md) +- [Deleted Lines of Code](/Metrics/DeletedLinesOfCode.md) +- [PR Count](/Metrics/PRCount.md) +- [PR Cycle Time](/Metrics/PRCycleTime.md) +- [PR Coding Time](/Metrics/PRCodingTime.md) +- [PR Pickup Time](/Metrics/PRPickupTime.md) +- [PR Review Time](/Metrics/PRReviewTime.md) +- [PR Deploy Time](/Metrics/PRDeployTime.md) +- [PR Time To Merge](/Metrics/PRTimeToMerge.md) +- [PR Merge Rate](/Metrics/PRMergeRate.md) +- [PR Review Depth](/Metrics/PRReviewDepth.md) +- [PR Size](/Metrics/PRSize.md) +- [Build Count](/Metrics/BuildCount.md) +- [Build Duration](/Metrics/BuildDuration.md) +- [Build Success Rate](/Metrics/BuildSuccessRate.md) +- [DORA - Deployment Frequency](/Metrics/DeploymentFrequency.md) +- [DORA - Lead Time for Changes](/Metrics/LeadTimeForChanges.md) +- [DORA - Median Time to Restore Service](/Metrics/MTTR.md) +- [DORA - Change Failure Rate](/Metrics/CFR.md) + +## Configuration + +- Configuring GitLab via [config-ui](/Configuration/GitLab.md). +- Configuring GitLab via Config UI's [advanced mode](/Configuration/AdvancedMode.md#2-gitlab). + +## API Sample Request + +You can trigger data collection by making a POST request to `/pipelines`. + +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "project1-BLUEPRINT", + "blueprintId": 1, + "plan": [ + [ + { + "plugin": "gitlab", + "options": { + "connectionId": 1, + "projectId": 33728042, + "transformationRules":{ + "deploymentPattern":"", + "productionPattern":"", + "issueComponent":"", + "issuePriority":"(high|medium|low)$", + "issueSeverity":"", + "issueTypeBug":"(bug)$", + "issueTypeIncident":"", + "issueTypeRequirement":"(feature|feature-request)$", + "prBodyClosePattern":"", + "prComponent":"", + "prType":"" + } + } + } + ] + ] +} +' +``` + +## References + +- [references](/DeveloperManuals/DeveloperSetup.md#references) diff --git a/versioned_docs/version-v0.21/Plugins/jenkins.md b/versioned_docs/version-v0.21/Plugins/jenkins.md new file mode 100644 index 00000000000..8ea5c3315ba --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/jenkins.md @@ -0,0 +1,108 @@ +--- +title: "Jenkins" +description: > + Jenkins Plugin +--- + +## Summary + +This plugin collects Jenkins data through [Remote Access API](https://www.jenkins.io/doc/book/using/remote-access-api/). It then computes and visualizes various DevOps metrics from the Jenkins data, which helps tech leads and DevOps engineers to answer questions such as: + +- What is the deployment frequency of your team? +- What is the build success rate? +- How long does it take for a code change to be deployed into production? + +## Supported Versions + +Available for Jenkins v2.263.x+. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +### Note + +Please note that it is important to avoid [rerunning Jenkins builds in place](https://www.jenkins.io/doc/pipeline/tour/running-multiple-steps/#timeouts-retries-and-more), and instead ensure that each rerun has a unique build number. This is because rerunning builds with the same build number can lead to inconsistencies in the data collected by the Jenkins plugin. + +## Entities + +Check out the [Jenkins entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Data Refresh Policy + +Check out the [data refresh policy](/Overview/SupportedDataSources.md#jenkins) of this plugin. + +## Metrics + +Metrics that can be calculated based on the data collected from Jenkins: + +- [Build Count](/Metrics/BuildCount.md) +- [Build Duration](/Metrics/BuildDuration.md) +- [Build Success Rate](/Metrics/BuildSuccessRate.md) +- [DORA - Deployment Frequency](/Metrics/DeploymentFrequency.md) +- [DORA - Lead Time for Changes](/Metrics/LeadTimeForChanges.md) +- [DORA - Median Time to Restore Service](/Metrics/MTTR.md) +- [DORA - Change Failure Rate](/Metrics/CFR.md) + +## Configuration + +- Configuring Jenkins via [Config UI](/Configuration/Jenkins.md) +- Configuring Jenkins via Config UI's [advanced mode](/Configuration/AdvancedMode.md#3-jenkins). + +## API Sample Request + +You can trigger data collection by making a POST request to `/pipelines`. + +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "project1-BLUEPRINT", + "blueprintId": 1, + "plan": [ + [ + { + "plugin": "jenkins", + "options": { + "connectionId": 1, + "scopeId": "auto_deploy", + "transformationRules":{ + "deploymentPattern":"", + "productionPattern":"" + } + } + } + ] + ] +} +' +``` + +or + +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "project1-BLUEPRINT", + "blueprintId": 2, + "plan": [ + [ + { + "plugin": "jenkins", + "options": { + "connectionId": 1, + "jobFullName": "auto_deploy", + "transformationRules":{ + "deploymentPattern":"", + "productionPattern":"" + } + } + } + ] + ] +} +' +``` + +## References + +- [references](/DeveloperManuals/DeveloperSetup.md#references) diff --git a/versioned_docs/version-v0.21/Plugins/jira.md b/versioned_docs/version-v0.21/Plugins/jira.md new file mode 100644 index 00000000000..8efc1a07113 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/jira.md @@ -0,0 +1,74 @@ +--- +title: "Jira" +description: > + Jira Plugin +--- + +## Summary + +This plugin collects Jira data through Jira REST API. It then computes and visualizes various engineering metrics from the Jira data. + +## Supported Versions +Available for Jira Cloud, Sever/Data Center 7.x, 8.x. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Entities + +Check out the [Jira entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Data Refresh Policy + +Check out the [data refresh policy](/Overview/SupportedDataSources.md#jira) of this plugin. + +## Metrics + +Metrics that can be calculated based on the data collected from Jira: + +- [Requirement Count](/Metrics/RequirementCount.md) +- [Requirement Lead Time](/Metrics/RequirementLeadTime.md) +- [Requirement Delivery Rate](/Metrics/RequirementDeliveryRate.md) +- [Requirement Granularity](/Metrics/RequirementGranularity.md) +- [Bug Age](/Metrics/BugAge.md) +- [Bug Count per 1k Lines of Code](/Metrics/BugCountPer1kLinesOfCode.md) +- [Incident Age](/Metrics/IncidentAge.md) +- [Incident Count per 1k Lines of Code](/Metrics/IncidentCountPer1kLinesOfCode.md) + +## Configuration + +- Configuring Jira via [config-ui](/Configuration/Jira.md). +- Configuring Jira via Config UI's [advanced mode](/Configuration/AdvancedMode.md#4-jira). + +## API Sample Request + +You can trigger data collection by making a POST request to `/pipelines`. + +```shell +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "MY PIPELINE", + "plan": [ + [ + { + "plugin": "jira", + "options": { + "connectionId": 1, + "boardId": 8, + "transformationRules": { + "epicKeyField": "", + "storyPointField": "", + "remotelinkCommitShaPattern": "", + "typeMappings": { + "10040": { + "standardType": "Incident", + "statusMappings": null + } + } + } + } + } + ] + ] +} +' +``` diff --git a/versioned_docs/version-v0.21/Plugins/opsgenie.md b/versioned_docs/version-v0.21/Plugins/opsgenie.md new file mode 100644 index 00000000000..785d562dc82 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/opsgenie.md @@ -0,0 +1,21 @@ +--- +title: "Opsgenie" +description: > + Opsgenie Plugin +--- + +## Summary + +This plugin collects Opsgenie incident data, users and teams, and uses them to compute incident-type DORA metrics. Namely, +* [Median time to restore service](/Metrics/MTTR.md) +* [Change failure rate](/Metrics/CFR.md). +* [Incident Age](/Metrics/IncidentAge.md) +* [Incident Count Per 1k Lines of Code](/Metrics/IncidentCountPer1kLinesOfCode.md) + +## Supported Versions +Available for Atlassian Opsgenie Cloud, for both US or EU instances. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + + +## Configuration +* Configure Opsgenie via Config UI. See instructions [here](/Configuration/Opsgenie.md). +* Configure Opsgenie via Config UI's [advanced mode](/Configuration/AdvancedMode.md). diff --git a/versioned_docs/version-v0.21/Plugins/pagerduty.md b/versioned_docs/version-v0.21/Plugins/pagerduty.md new file mode 100644 index 00000000000..438f1562a1c --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/pagerduty.md @@ -0,0 +1,21 @@ +--- +title: "PagerDuty" +description: > + PagerDuty Plugin +--- + +## Summary + +This plugin collects all incidents from PagerDuty, and uses them to compute incident-type DORA metrics. Namely, +* [Median time to restore service](/Metrics/MTTR.md) +* [Change failure rate](/Metrics/CFR.md). +* [Incident Age](/Metrics/IncidentAge.md) +* [Incident Count Per 1k Lines of Code](/Metrics/IncidentCountPer1kLinesOfCode.md) + +## Supported Versions +Available for PagerDuty Cloud. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + + +## Configuration +* Configure PagerDuty via Config UI. See instructions [here](/Configuration/PagerDuty.md). +* Configure PagerDuty via Config UI's [advanced mode](/Configuration/AdvancedMode.md). \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Plugins/refdiff.md b/versioned_docs/version-v0.21/Plugins/refdiff.md new file mode 100644 index 00000000000..d4908c07d62 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/refdiff.md @@ -0,0 +1,132 @@ +--- +title: "RefDiff" +description: > + RefDiff Plugin +--- + +## Summary + +RefDiff is a plugin that performs calculation tasks and has 2 main purposes. + +- Calculate the difference in commits between releases/tags to [analyze the amount of code in each release](https://github.com/apache/incubator-devlake/blob/main/backend/plugins/refdiff/tasks/commit_diff_calculator.go) +- Calculate the difference in commits between deployments to [calculate DORA metrics](https://github.com/apache/incubator-devlake/blob/main/backend/plugins/refdiff/tasks/deployment_commit_diff_calculator.go) + +And the output of RefDiff is stored in the table commits_diffs, finished_commits_diffs, ref_commits. + +## Important Note + +You need to run `gitextractor` before the `refdiff` plugin. The `gitextractor` plugin should create records in the `refs` table in your database before this plugin can be run. + +## Configuration + +This is an enrichment plugin based on the domain layer data, no configuration is needed. + +## How to use refdiff + +To trigger the enrichment, you need to insert a new task into your pipeline. + +1. Make sure `commits` and `refs` are collected into your database, `refs` table should contain records like following: + ``` + id ref_type + github:GithubRepo:1:384111310:refs/tags/0.3.5 TAG + github:GithubRepo:1:384111310:refs/tags/0.3.6 TAG + github:GithubRepo:1:384111310:refs/tags/0.5.0 TAG + github:GithubRepo:1:384111310:refs/tags/v0.0.1 TAG + github:GithubRepo:1:384111310:refs/tags/v0.2.0 TAG + github:GithubRepo:1:384111310:refs/tags/v0.3.0 TAG + github:GithubRepo:1:384111310:refs/tags/v0.4.0 TAG + github:GithubRepo:1:384111310:refs/tags/v0.6.0 TAG + github:GithubRepo:1:384111310:refs/tags/v0.6.1 TAG + ``` +2. If you want to run calculatePrCherryPick, please configure GITHUB_PR_TITLE_PATTERN in .env, you can check the example in .env.example(we have a default value, please make sure your pattern is disclosed by single quotes '') +3. And then, trigger a pipeline like the following format: + +```shell +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "test-refdiff", + "plan": [ + [ + { + "plugin": "refdiff", + "options": { + "repoId": "github:GithubRepo:1:384111310", + "pairs": [ + { "newRef": "refs/tags/v0.6.0", "oldRef": "refs/tags/0.5.0" }, + { "newRef": "refs/tags/0.5.0", "oldRef": "refs/tags/0.4.0" } + ], + "tasks": [ + "calculateCommitsDiff", + "calculateIssuesDiff", + "calculatePrCherryPick", + ] + } + } + ] + ] +}' +``` + +Or if you preferred calculating latest releases + +```shell +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "test-refdiff", + "plan": [ + [ + { + "plugin": "refdiff", + "options": { + "repoId": "github:GithubRepo:1:384111310", + "tagsPattern": "v\d+\.\d+.\d+", + "tagsLimit": 10, + "tagsOrder": "reverse semver", + "tasks": [ + "calculateCommitsDiff", + "calculateIssuesDiff", + "calculatePrCherryPick", + ] + } + } + ] + ] +}' +``` + +## How to use refdiff in DORA + +RefDiff can be called by the [DORA plugin](https://github.com/apache/incubator-devlake/tree/main/backend/plugins/dora) to support the calculation of [DORA metrics](https://devlake.apache.org/docs/DORA). RefDiff has a subtask called 'calculateProjectDeploymentCommitsDiff'. This subtask takes the `project_name` from task options to calculate the commits diff between two consecutive deployments in this project. That is to say, refdiff will generate the relationship between `deployed commit(s)` and the `deployment` in which these commits get deployed. + +```shell +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "test-refdiff-dora", + "plan": [ + [ + { + "plugin": "refdiff", + "options": { + "projectName": "project_name_1", + "tasks": [ + "calculateProjectDeploymentCommitsDiff" + ] + } + } + ] + ] +}' +``` + +## Development + +This plugin depends on `libgit2`, you need to install version 1.3.0 in order to run and debug this plugin on your local +machine. [Click here](./gitextractor.md#Development) for a brief guide. + +


diff --git a/versioned_docs/version-v0.21/Plugins/sonarqube.md b/versioned_docs/version-v0.21/Plugins/sonarqube.md new file mode 100644 index 00000000000..81e42a966c1 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/sonarqube.md @@ -0,0 +1,73 @@ +--- +title: "SonarQube" +description: > + SonarQube Plugin +--- + +## Summary + +This plugin collects SonarQube data through its REST APIs. SonarQube is a tool for static code analysis and code quality management. It can help you discover potential problems and defects in your code, and provide suggestions and solutions. + +When collecting issues under a certain SonarQube project, divide the issues into smaller groups to collect, so as not to obtain 10,000 issues at once and exceed the result limit of SonarQube APIs themselves. Specific rules include: +1. First, classify the issues according to "severity", "status", and "type" and collect them separately. +2. Secondly, issues are classified according to the time fields "createdBefore" and "createdAfter" and collected separately. +3. Finally, the issues are classified according to "the file to which the issue belongs" and collected separately. + + + +## Supported Versions + +Available for SonarQube Server v8.x, v9.x. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Entities + +Check out the [SonarQube entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Data Refresh Policy + +Check out the [data refresh policy](/Overview/SupportedDataSources.md#sonarqube) of this plugin. + +## Metrics + +Most of SonarQube metrics are collected and can be found in DevLake's SonarQube dashboard. + +- [Code Quality Issue Count](/Metrics/CQIssueCount.md) +- [Code Quality Test](/Metrics/CQTest.md) +- [Code Quality Maintainability-Debt](/Metrics/CQMaintainability-Debt.md) +- [Code Quality Duplicated Blocks](/Metrics/CQDuplicatedBlocks.md) +- [Code Quality Duplicated Lines](/Metrics/CQDuplicatedLines.md) + +## Configuration + +- Configuring SonarQube via [config-ui](/Configuration/SonarQube.md). +- Configuring SonarQube via Config UI's [advanced mode](/Configuration/AdvancedMode.md#10-sonarqube). + +## API Sample Request + +You can trigger data collection by making a POST request to `/pipelines`. + +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "project1-BLUEPRINT", + "blueprintId": 1, + "plan": [ + [ + { + "plugin": "sonarqube", + "options": { + "connectionId": 1, + "projectKey": "testDevLake" + } + } + ] + ] +} +' +``` + +## References + +- [references](/DeveloperManuals/DeveloperSetup.md#references) diff --git a/versioned_docs/version-v0.21/Plugins/tapd.md b/versioned_docs/version-v0.21/Plugins/tapd.md new file mode 100644 index 00000000000..fde52d1f924 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/tapd.md @@ -0,0 +1,27 @@ +--- +title: "TAPD" +description: > + Tapd Plugin +--- + +## Summary + +This plugin collects TAPD data through its REST APIs. TAPD is an issue-tracking tool similar to Jira. + +## Supported Versions +Advanced mode available for Tapd Cloud. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Metrics + +Metrics that can be calculated based on the data collected from Tapd: + +- [Requirement Count](/Metrics/RequirementCount.md) +- [Requirement Lead Time](/Metrics/RequirementLeadTime.md) +- [Requirement Delivery Rate](/Metrics/RequirementDeliveryRate.md) +- [Bug Age](/Metrics/BugAge.md) +- [Incident Age](/Metrics/IncidentAge.md) + +## Configuration + +- Configuring Tapd via [config-ui](/Configuration/Tapd.md). +- Configuring Tapd via Config UI's [advanced mode](/Configuration/AdvancedMode.md#6-tapd). diff --git a/versioned_docs/version-v0.21/Plugins/teambition.md b/versioned_docs/version-v0.21/Plugins/teambition.md new file mode 100644 index 00000000000..2bf5f77bf20 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/teambition.md @@ -0,0 +1,29 @@ +--- + +title: "Teambition(WIP)" +description: > + Teambition Plugin +--- + +## Summary + +This plugin collects Teambition data through its REST APIs. Teambition is an issue-tracking tool similar to Trello. + +## Supported Versions + +Available for Teambition Cloud. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Metrics + +Metrics that can be calculated based on the data collected from Teambition: + +- [Requirement Count](/Metrics/RequirementCount.md) +- [Requirement Lead Time](/Metrics/RequirementLeadTime.md) +- [Requirement Delivery Rate](/Metrics/RequirementDeliveryRate.md) +- [Bug Age](/Metrics/BugAge.md) +- [Incident Age](/Metrics/IncidentAge.md) + +## Configuration + +- Configuring Teambition via [config-ui](/Configuration/Teambition.md). +- Configuring Teambition via Config UI's [advanced mode](/Configuration/AdvancedMode.md#11-teambition). diff --git a/versioned_docs/version-v0.21/Plugins/trello.md b/versioned_docs/version-v0.21/Plugins/trello.md new file mode 100644 index 00000000000..19a568ba0ad --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/trello.md @@ -0,0 +1,103 @@ +--- +title: "Trello(WIP)" +description: > + Trello Plugin +--- + +## Summary + +This plugin collects `Trello` data through [Trello's rest api](https://developer.atlassian.com/cloud/trello/guides/rest-api/api-introduction/). + +## Configuration + +In order to fully use this plugin, you will need to get `apikey` and `token` on the [Trello website](https://developer.atlassian.com/cloud/trello/guides/rest-api/api-introduction/). + +A connection should be created before you can collect any data. Currently, this plugin supports creating connection by requesting `connections` API: + +``` +curl 'http://localhost:8080/plugins/trello/connections' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name": "trello", + "endpoint": "https://api.trello.com/", + "rateLimitPerHour": 20000, + "appId": "", + "secretKey": "" +} +' +``` + +## Collect data from Trello + + + +You can make the following request to get all the boards. + +``` +curl 'http://localhost:8080/plugins/trello/connections//proxy/rest/1/members/me/boards?fields=name,id' +``` + + +In order to collect data, you have to compose a JSON looks like following one, and send it by selecting `Advanced Mode` on `Create Pipeline Run` page: + +1. Configure-UI Mode +```json +[ + [ + { + "plugin": "trello", + "options": { + "connectionId": , + "boardId": "" + } + } + ] +] +``` +and if you want to perform certain subtasks. +```json +[ + [ + { + "plugin": "trello", + "subtasks": ["collectXXX", "extractXXX", "convertXXX"], + "options": { + "connectionId": , + "boardId": "" + } + } + ] +] +``` + +2. Curl Mode: + +In order to collect data, you have to make a POST request to `/pipelines`. + +``` +curl 'http://localhost:8080/pipelines' \ +--header 'Content-Type: application/json' \ +--data-raw ' +{ + "name":"MY PIPELINE", + "plan":[ + [ + { + "plugin":"trello", + "options":{ + "connectionId":, + "boardId":"" + } + } + ] + ] +} +' +``` + +You can make the following request to get all the boards. + +``` +curl 'http://localhost:8080/plugins/trello/connections//proxy/rest/1/members/me/boards?fields=name,id' +``` diff --git a/versioned_docs/version-v0.21/Plugins/webhook.md b/versioned_docs/version-v0.21/Plugins/webhook.md new file mode 100644 index 00000000000..3b35d4ca749 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/webhook.md @@ -0,0 +1,260 @@ +--- +title: "Webhook" +description: > + Webhook Plugin +--- + +## Summary + +Incoming Webhooks are your solution to bring data to Apache DevLake when there isn't a specific plugin ready for your DevOps tool. An Incoming Webhook allows users to actively push data to DevLake. + +When you create an Incoming Webhook within DevLake, DevLake generates a unique URL. You can then post JSON payloads to this URL to push data directly to your DevLake instance. + +In v0.14+, users can push "incidents" and "deployments" required by DORA metrics to DevLake via Incoming Webhooks. + +Webhooks are meant to be used at the lowest level that you want to relate incidents with deployments. For example, if you want to relate incidents at the individual service level, you will need a webhook per service. If you wish to relate incidents at the product level, you will need a webhook for the product. This is because incidents on a project will be related to the last deployment on the project with a timestamp that is before the incident's timestamp. This is true regardless of the source of incidents or deployments. + +Diagram of the relationship between incidents and deployments: + +![Change Failure Reporting](/img/Metrics/cfr-definition.png) + +## Entities + +Check out the [Incoming Webhooks entities](/Overview/SupportedDataSources.md#data-collection-scope-by-each-plugin) collected by this plugin. + +## Metrics + +Metrics that can be calculated based on the data collected from Incoming Webhooks: + +- [Requirement Delivery Rate](/Metrics/RequirementDeliveryRate.md) +- [Requirement Granularity](/Metrics/RequirementGranularity.md) +- [Bug Age](/Metrics/BugAge.md) +- [Bug Count per 1k Lines of Code](/Metrics/BugCountPer1kLinesOfCode.md) +- [Incident Age](/Metrics/IncidentAge.md) +- [Incident Count per 1k Lines of Code](/Metrics/IncidentCountPer1kLinesOfCode.md) +- [DORA - Deployment Frequency](/Metrics/DeploymentFrequency.md) +- [DORA - Lead Time for Changes](/Metrics/LeadTimeForChanges.md) +- [DORA - Median Time to Restore Service](/Metrics/MTTR.md) +- [DORA - Change Failure Rate](/Metrics/CFR.md) + +## Configuration + +- Configuring Incoming Webhooks via [Config UI](/Configuration/webhook.md) + +## API Sample Request + +### Deployment + +If you want to collect deployment data from your system, you can use the incoming webhooks for deployment. + +#### Payload Schema + +You can copy the generated deployment curl commands to your CI/CD script to post deployments to Apache DevLake. Below is the detailed payload schema: + +| Key | Required | Notes | +| :---------: | :------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| pipeline_id | ✖️ No | related Domain Layer `cicd_pipelines.id` | +| environment | ✖️ No | the environment this deployment happens. For example, `PRODUCTION` `STAGING` `TESTING` `DEVELOPMENT`.
The default value is `PRODUCTION` | +| repo_url | ✔️ Yes | the repo URL of the deployment commit
If there is a row in the domain layer table `repos` where `repos.url` equals `repo_url`, the `repoId` will be filled with `repos.id`. | +| repo_id | ✖️ No | related Domain Layer `repos.id`
No default value. | +| name | ✖️ No | deployment name. The default value is "deployment for `request.commit_sha`" | +| ref_name | ✖️ No | related branch/tag
No default value. | +| commit_sha | ✔️ Yes | the sha of the deployment commit | +| commit_msg | ✖️ No | the sha of the deployment commit message | +| create_time | ✖️ No | Time. Eg. 2020-01-01T12:00:00+00:00
No default value. | +| start_time | ✔️ Yes | Time. Eg. 2020-01-01T12:00:00+00:00
No default value. | +| end_time | ✖️ No | Time. Eg. 2020-01-01T12:00:00+00:00
The default value is the time when DevLake receives the POST request. | +| result | ✖️ No | deployment result, one of the values : `SUCCESS`, `FAILURE`, `ABORT`, `MANUAL`,
The default value is `SUCCESS`. | +| deploymentCommits[] | ✖️ yes | Allow deployment webhook to push deployments to multiple repos in one request, includes repo_url,commit_sha,commit_msg,name,ref_name | + + + +#### Register a Deployment - Sample API Calls + +To deploy on a single repository, use the following command: +``` +curl /api/rest/plugins/webhook/1/deployments -X 'POST' -d '{ + "pipeline_id": "optional-pipeline-id", + "environment":"PRODUCTION", + "repo_url":"https://github.com/apache/incubator-devlake/", + "repo_id": "optional-repo-id", + "name": "optional-deployment-name. If you do not post a name, DevLake will generate one for you.", + "ref_name": "optional-release-v0.17", + "commit_sha":"015e3d3b480e417aede5a1293bd61de9b0fd051d", + "commit_msg":"optional-commit-message", + "create_time":"2020-01-01T11:00:00+00:00", + "start_time":"2020-01-01T12:00:00+00:00", + "end_time":"2020-01-02T13:00:00+00:00", + "result": "FAILURE" + }' +``` + +To deploy across multiple repositories (refer to the [discussion](https://github.com/apache/incubator-devlake/discussions/6162)), use the following command: +``` +curl /api/rest/plugins/webhook/1/deployments -X 'POST' -d '{ + "pipeline_id": "optional-pipeline-id", + "environment":"PRODUCTION", + "repo_id": "optional-repo-id", + "name": "optional-deployment-name. If you do not post a name, DevLake will generate one for you.", + "create_time":"2020-01-01T11:00:00+00:00", + "start_time":"2020-01-01T12:00:00+00:00", + "end_time":"2020-01-02T13:00:00+00:00", + "result": "FAILURE", + "deploymentCommits":[ + { + "repo_url":"repo-1", + "name":"optional, if null, it will be deployment for {commit_sha}", + "ref_name": "optional-release-v0.17", + "commit_sha":"c1", + "commit_msg":"optional-msg-1" + }, + { + "repo_url":"repo-2", + "name":"optional, if null, it will be deployment for {commit_sha}", + "ref_name": "optional-release-v0.17", + "commit_sha":"c2", + "commit_msg":"optional-msg-2" + } + ] + }' +``` + +If you have set a [username/password](GettingStarted/Authentication.md) for Config UI, you'll need to add them to the curl command to register a `deployment`: + +``` +curl /api/rest/plugins/webhook/1/deployments -X 'POST' -u 'username:password' -d '{ + "deploymentCommits":[ + { + "commit_sha":"the sha of deployment commit1", + "repo_url":"the repo URL of the deployment commit" + } + ], + "start_time":"2020-01-01T12:00:00+00:00", + "end_time":"2020-01-02T12:00:00+00:00" + }' +``` + +#### A real-world example - Push CircleCI deployments to DevLake + +The following demo shows how to post "deployments" to DevLake from CircleCI. In this example, the CircleCI job 'deploy' is used to manage deployments. + +``` +version: 2.1 + +jobs: + build: + docker: + - image: cimg/base:stable + steps: + - checkout + - run: + name: "build" + command: | + echo Hello, World! + + deploy: + docker: + - image: cimg/base:stable + steps: + - checkout + - run: + name: "deploy" + command: | + # The time a deploy started + start_time=`date '+%Y-%m-%dT%H:%M:%S%z'` + + # Some deployment tasks here ... + echo Hello, World! + + # Send the request to DevLake after deploy + # The values start with a '$CIRCLE_' are CircleCI's built-in variables + curl /api/rest/plugins/webhook/1/deployments -X 'POST' -d "{ + \"commit_sha\":\"$CIRCLE_SHA1\", + \"repo_url\":\"$CIRCLE_REPOSITORY_URL\", + \"start_time\":\"$start_time\" + }" + +workflows: + build_and_deploy_workflow: + jobs: + - build + - deploy +``` + +### Incident / Issue + +If you want to collect issue or incident data from your system, you can use the two webhooks for issues. + +#### Register Issues - Update or Create Issues + +`POST /api/rest/plugins/webhook/1/issues` + +needs to be called when an issue or incident is created. The body should be a JSON and include columns as follows: + +| Keyname | Required | Notes | +| :-----------------------: | :------: | ------------------------------------------------------------- | +| url | ✖️ No | issue's URL | +| issue_key | ✔️ Yes | issue's key, needs to be unique in a connection | +| title | ✔️ Yes | | +| description | ✖️ No | | +| epic_key | ✖️ No | in which epic. | +| type | ✖️ No | type, such as bug/incident/epic/... | +| status | ✔️ Yes | issue's status. Must be one of `TODO` `DONE` `IN_PROGRESS` | +| original_status | ✔️ Yes | status in your system, such as created/open/closed/... | +| story_point | ✖️ No | | +| resolution_date | ✖️ No | date, Format should be 2020-01-01T12:00:00+00:00 | +| created_date | ✔️ Yes | date, Format should be 2020-01-01T12:00:00+00:00 | +| updated_date | ✖️ No | date, Format should be 2020-01-01T12:00:00+00:00 | +| lead_time_minutes | ✖️ No | how long from this issue accepted to develop | +| parent_issue_key | ✖️ No | | +| priority | ✖️ No | | +| original_estimate_minutes | ✖️ No | | +| time_spent_minutes | ✖️ No | | +| time_remaining_minutes | ✖️ No | | +| creator_id | ✖️ No | the user id of the creator | +| creator_name | ✖️ No | the user name of the creator, it will just be used to display | +| assignee_id | ✖️ No | | +| assignee_name | ✖️ No | | +| severity | ✖️ No | | +| component | ✖️ No | which component is this issue in. | + +More information about these columns at [DomainLayerIssueTracking](https://devlake.apache.org/docs/DataModels/DevLakeDomainLayerSchema#domain-1---issue-tracking). + +#### Register Issues - Close Issues (Optional) + +`POST /api/rest/plugins/webhook/1/issue/:issueId/close` + +needs to be called when an issue or incident is closed. Replace `:issueId` with specific strings and keep the body empty. + +#### Register Issues - Sample API Calls + +Sample CURL for creating an incident: + +``` +curl /api/rest/plugins/webhook/1/issues -X 'POST' -d '{ + "issue_key":"DLK-1234", + "title":"a feature from DLK", + "description":"", + "url":"", + "type":"INCIDENT", + "status":"TODO", + "created_date":"2020-01-01T12:00:00+00:00", + "updated_date":"2020-01-01T12:00:00+00:00", + "priority":"", + "severity":"", + "creator_id":"user1131", + "creator_name":"Nick name 1", + "assignee_id":"user1132", + "assignee_name":"Nick name 2" +}' +``` + +Sample CURL for Issue Closing: + +``` +curl /api/rest/plugins/webhook/1/issue/DLK-1234/close -X 'POST' +``` + +## References + +- [references](/DeveloperManuals/DeveloperSetup.md#references) diff --git a/versioned_docs/version-v0.21/Plugins/zentao.md b/versioned_docs/version-v0.21/Plugins/zentao.md new file mode 100644 index 00000000000..1ceb9f508a1 --- /dev/null +++ b/versioned_docs/version-v0.21/Plugins/zentao.md @@ -0,0 +1,28 @@ +--- +title: "Zentao" +description: > + Zentao Plugin +--- + +## Summary + +This plugin collects Zentao data through its REST APIs. [Zentao](https://github.com/easysoft/zentaopms) is an issue-tracking tool similar to Jira. + +## Supported Versions + +Advanced mode vailable for Zentao OSS v18.3, Enterprise v8.2, Flagship v4.3. Check [this doc](https://devlake.apache.org/docs/Overview/SupportedDataSources#data-sources-and-data-plugins) for more details. + +## Metrics + +Metrics that can be calculated based on the data collected from Zentao: + +- [Requirement Count](/Metrics/RequirementCount.md) +- [Requirement Lead Time](/Metrics/RequirementLeadTime.md) +- [Requirement Delivery Rate](/Metrics/RequirementDeliveryRate.md) +- [Bug Age](/Metrics/BugAge.md) +- [Incident Age](/Metrics/IncidentAge.md) + +## Configuration + +- Configuring Zentao via [config-ui](/Configuration/Zentao.md). +- Configuring Zentao via Config UI's [advanced mode](/Configuration/AdvancedMode.md#8-zentao). diff --git a/versioned_docs/version-v0.21/Troubleshooting/Configuration.md b/versioned_docs/version-v0.21/Troubleshooting/Configuration.md new file mode 100644 index 00000000000..e440af452a3 --- /dev/null +++ b/versioned_docs/version-v0.21/Troubleshooting/Configuration.md @@ -0,0 +1,83 @@ +--- +title: "Configuration and Blueprint Troubleshooting" +sidebar_position: 2 +description: > + Debug errors found in Config UI or during data collection. +--- + +### Common Error Code while collecting/processing data + +| Error code | An example | Causes | Solutions | +| ---------- | ----------------------------|--------|-----------| +| 429 | subtask collectAPiPipelines ended unexpectedly caused: Error waiting for async Collector execution caused by: retry exceeded 3 times calling projects/{projectId}/pipelines {429} | This error exmaple is caused by GitLab's Pipeline APIs. These APIs are implemented via Cloudflare, which is different from other GitLab entities. | Two ways:
- Enable `fixed rate limit` in the GitLab connection, lower the API rates to 2,000. If it works, you can try increase the rates to accerlerate. This solution also applies to other plugins that return the 429 while collecting data, such as GitHub, TAPD, etc.
- Upgrade to v0.15.x | +| 403 | error: preparing task data for gitextractor caused by: unexpected http status code: 403 | This is usually caused by the permission of your tokens. For example, if you're using an un-supported auth method, or using a token without ticking permissions to certain entities you want to collect. | Find the supported authentication methods and token permissions that should be selected in the corresponding plugin's Config UI manuals, for example, [configuring GitHub](/docs/Configuration/GitHub.md#auth-tokens) | +| 1406 | subtask extractApiBuilds ended unexpectedly caused by: error adding the result to batch caused by: Error 1406: Data too long for column 'full_display_name' at row 138. See bug [#4053](https://github.com/apache/incubator-devlake/issues/4053) | This is usually thrown by MySQL because a certain value is too long | A work-around is to manually change the field length to varchar(255) or longer in MySQL. Also, please put up a [bug](https://github.com/apache/incubator-devlake/issues/new?assignees=&labels=type%2Fbug&template=bug-report.yml&title=%5BBug%5D%5BModule+Name%5D+Bug+title+) to let us know. | + + +### Failed to collect data from the server with a self-signed certificate + +There might be two problems when trying to collect data from a private GitLab server with a self-signed certificate: + +1. "Test Connection" error. This can be solved by setting the environment variable `IN_SECURE_SKIP_VERIFY=true` for the `devlake` container +2. "GitExtractor" fails to clone the repository due to certificate verification, sadly, neither gogit nor git2go we are using supports insecure HTTPS. + +A better approach would be adding your root CA to the `devlake` container: + +1. Mount your `rootCA.crt` into the `devlake` container +2. Add a `command` node to install the mounted certificate + +Here is an example of the `docker-compose`` installation, the idea applies to other installation methods. +``` + devlake: + image: apache/devlake:v... + ... + volumes: + ... + - /path/to/your/rootCA.crt:/usr/local/share/ca-certificates/rootCA.crt + command: [ "sh", "-c", "update-ca-certificates; lake" ] + ... +``` + +### GitExtractor task failed in a GitHub/GitLab/BitBucket blueprint +See bug [#3719](https://github.com/apache/incubator-devlake/issues/3719) + +This bug happens occasionally in v0.14.x and previous versions. It is fixed by changing the docker base image. Please upgrade to v0.15.x to get it fixed if you encounter it. + + +### Pipeline failed with "The total number of locks exceeds the lock table size" + +We have had a couple of reports suggesting MySQL InnoDB would fail with the message. + +- [Error 1206: The total number of locks exceeds the lock table size · Issue #3849 · apache/incubator-devlake](https://github.com/apache/incubator-devlake/issues/3849) +- [[Bug][GitLab] gitlab collectApiJobs task failed for mysql locks error · Issue #3653 · apache/incubator-devlake](https://github.com/apache/incubator-devlake/issues/3653) + +The cause of the problem is: + +- Before Apache DevLake data collection starts, it must purge expired data in the database. +- MySQL InnoDB Engine would create locks in memory for the records being deleted. +- When deleting huge amounts of records, the memory bursts, hence the error. + +You are likely to see the error when dealing with a huge repository or board. For MySQL, you can solve it by increasing the `innodb_buffer_pool_size` to a higher value. + +Here is an example of the `docker-compose` installation, the idea applies to other installation methods. +``` + mysql: + image: mysql:8..... + ... + # add the follow line to the mysql container + command: --innodb-buffer-pool-size=200M +``` + +### GitHub repositories keep loading when adding data scopes + +See issue [#6038](https://github.com/apache/incubator-devlake/issues/6038) + +If you're having trouble adding data scopes to a GitHub connection because the repositories keep loading, there are a few things you can check: +1. Make sure your access token has the necessary permissions. +2. If your account is protected by organization SAML enforcement, make sure you've authorized the token using SSO. + +For more details about authenticating with SAML single sign-on, see here: https://docs.github.com/en/enterprise-cloud@latest/authentication/authenticating-with-saml-single-sign-on. + +## None of them solve your problem? + +Sorry for the inconvenience, please help us improve by [creating an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Troubleshooting/Dashboard.md b/versioned_docs/version-v0.21/Troubleshooting/Dashboard.md new file mode 100644 index 00000000000..9bf31d04eeb --- /dev/null +++ b/versioned_docs/version-v0.21/Troubleshooting/Dashboard.md @@ -0,0 +1,55 @@ +--- +title: "Dashboard Troubleshooting" +sidebar_position: 3 +description: > + Dashboard Troubleshooting +--- + +## Debugging DORA Issue Metrics + +This section may help if `Median Time to Restore Service (MTTR)` or `Change Failure Rate (CFR)` do not appear on the dashboards or you want to learn more about how these issue-based metrics are built. + +### DORA Validation Dashboard +Starting from DevLake v0.18 this dashboard can be found near the `DORA` dashboard. Also, it can be accessed by a direct link in the `Dashboard Instruction` panel in the `DORA` dashboard. + +This dashboard is a step-by-step guide to check which step went wrong **for all 4 of the DORA metrics**. The sections are: +- Check "Deployment Frequency" +- Check "Median Lead Time for Changes" +- Check "Change Failure Rate" & "Median Time to Restore Service + +### SQL scripts behind Grafana charts +Each chart has a hidden button in the top-right corner to access the context menu. In that menu, click `Edit` to open a more detailed view with the script that tells how exactly the data is queried. + +### How issues and deployments are associated to projects + +Following Entity-Relationship diagrams below represent how the data is mapped and used for each of the 4 DORA metrics. +They are based on the SQL queries for each of the charts. + +Legend: +- Blue box: user data source, be it **deployments**, **pull requests** from the source code, or **issues** +- White box: a table or entity used by DevLake +- Connections: lines that tell how the tables are mapped, also specify which fields are used. + +The `project_mapping` is responsible for mapping **deployments**, **pull requests** from the source code, or **issues**. +To do so, it must be filtered using either `table = 'cicd_scopes'`, `table = 'repos'`, or `table = 'boards'` when connecting to another table. + +![](../Configuration/images/cfr.png) + +![](../Configuration/images/deployments.png) + +![](../Configuration/images/lead_time.png) + +![](../Configuration/images/mttr.png) + +### If you use webhooks + +DevLake knows to which project an issue or a deployment belongs only by segregation between the webhooks. +I.e. **each project should have its own webhook**. A webhook used by multiple projects means that all the +issues or deployments published by that webhook **will be replicated among those projects**, as they belong to both of them. + +WIP + + +## None of them solve your problem? + +Sorry for the inconvenience, please help us improve by [creating an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Troubleshooting/Installation.md b/versioned_docs/version-v0.21/Troubleshooting/Installation.md new file mode 100644 index 00000000000..14037e14cf6 --- /dev/null +++ b/versioned_docs/version-v0.21/Troubleshooting/Installation.md @@ -0,0 +1,21 @@ +--- +title: "Installation Troubleshooting" +sidebar_position: 1 +description: > + Installation Troubleshooting +--- + +### `panic: invalid encKey` error + +The cause is the `devlake` container trying to decrypt data in the database with the wrong key. +Please check the [GettingStarted/Upgrade](../GettingStarted/Upgrade.md) doc for more detail. + +### Go Panic in OpenShift Kubernetes + +One of the known root causes of the phonomenon is the Dynatrace agent being injected into the container. +Excluding the namespace from the Dynatrace deployments should fix the problem. +Check [#5612](https://github.com/apache/incubator-devlake/issues/5612) if you needed more detail. + +## None of them solve your problem? + +Sorry for the inconvenience, please help us improve by [creating an issue](https://github.com/apache/incubator-devlake/issues) diff --git a/versioned_docs/version-v0.21/Troubleshooting/MySqlIssue.md b/versioned_docs/version-v0.21/Troubleshooting/MySqlIssue.md new file mode 100644 index 00000000000..c05dadf13cc --- /dev/null +++ b/versioned_docs/version-v0.21/Troubleshooting/MySqlIssue.md @@ -0,0 +1,111 @@ +--- +title: "Mysql Troubleshooting" +sidebar_position: 4 +description: > + Mysql Troubleshooting +--- + +## How to manage the quickly increasing MySQL disk consumption? + +DevLake is designed to collect data by first deleting the existing data and +then inserting new data. While this approach ensures that the latest data is +always available, it leads to a rapid increase in MySQL disk consumption. +This growth is primarily caused by the large size of the binary logs generated +after each data collection cycle. + +### Why dose DevLake choose to delete the existing data and then insert new data? + +Because we want to ensure that the latest data is +always available. If we don't delete the existing data, some old data which has been deleted +from the previous step will still be available in the DevLake database. + + +### How to purge old binary logs? + +1. Connect to your MySQL server using the MySQL client or any other database management tool such as PhpMyAdmin, MySQL Workbench, etc. + +2. Run the following command to check the current status of your binary log files: + +```sql +SHOW BINARY LOGS; +``` +This will display a list of all the binary log files that are currently available on your MySQL server. + +3. Determine the last binary log file that you want to keep. This is the file that you want to retain for any future point-in-time recovery or replication purposes. + +4. Run the following command to purge all binary logs that are older than the binary log file that you want to retain: + +```sql +PURGE BINARY LOGS BEFORE 'DATE' ; +``` +You need to provide the specific date and time up to which you want to purge the binary logs. The date and time should be formatted as a string in the 'YYYY-MM-DD hh:mm:ss' format. +For example, if you want to purge all binary logs before March 22, 2023, 15:30:00, you would replace DATE with '2023-03-22 15:30:00', like this: + +```sql +PURGE BINARY LOGS BEFORE '2023-03-22 15:30:00' ; +``` + + +5. After running the command, MySQL will delete all binary log files that are older than the specified file. You can verify that the purge was successful by running the SHOW BINARY LOGS; command again. + +Note: Keep in mind that deleting old binary log files can affect point-in-time recovery and replication capabilities, so it's important to only delete files that are no longer needed. + +Additionally, it's recommended to take a backup before deleting any binary log files in case you need to restore to a point before the binary logs were purged. + +### How to "automate" the purge of old binary logs? + +1. Connect to your MySQL server using the MySQL client or any other database management tool such as PhpMyAdmin, MySQL Workbench, etc. + +2. Run the following command to set the expire_logs_days global variable to the number of days that you want to keep binary logs for: + +```sql +SET GLOBAL expire_logs_days = 1; +``` + +### How to skip bin logs? + +1. To skip bin logs, you can set the skip-log-bin configuration option directly in the docker-compose.yaml file using the command option. Here's an example of how to do this: +```yaml +services: + mysql: + image: mysql:8 + volumes: + - mysql-storage:/var/lib/mysql + restart: always + ports: + - "127.0.0.1:3306:3306" + environment: + MYSQL_ROOT_PASSWORD: admin + MYSQL_DATABASE: lake + MYSQL_USER: merico + MYSQL_PASSWORD: merico + command: + --character-set-server=utf8mb4 + --collation-server=utf8mb4_bin + --skip-log-bin +``` + +2. After making the changes, you can restart the MySQL container using the following command: +```bash + docker-compose restart mysql +``` + + +### How to connect mysql server which requires SSL? +1. Skip-verifying the SSL certificate: you can add &tls=skip-verify to DB_URL variable, for example: + ``` + DB_URL=mysql://merico:merico@localhost:3306/lake?charset=utf8mb4&parseTime=True&loc=UTC&tls=skip-verify + ``` +2. Verify the SSL certificate: you can add &tls=custom&ca-cert=/path/to/your/ca-certificate.crt to DB_URL variable, for example: + ``` + DB_URL=mysql://merico:merico@lake.mysql.database.azure.com:3306/lake?charset=utf8mb4&parseTime=True&tls=custom&ca-cert=/path/to/your/DigiCertGlobalRootCA.crt.pem + ``` + Note: in Python plugins, it will fallback to the `skip-verify` policy. + +### How to skip "subtask collectGitCommits ended unexpectedly, deadlock found when trying to get lock"? +When users have large repositories with a substantial number of commit files to collect, it can lead to the following issues: + + 1. The time to collect Git data is too long + 2. Errors occurred while writing data to the DevLake database + +To address this, you can bypass this step by setting the SKIP_COMMIT_FILES=true in the .env file. \ No newline at end of file diff --git a/versioned_docs/version-v0.21/Troubleshooting/_category_.json b/versioned_docs/version-v0.21/Troubleshooting/_category_.json new file mode 100644 index 00000000000..ceac2b5c73e --- /dev/null +++ b/versioned_docs/version-v0.21/Troubleshooting/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Troubleshooting", + "position": 10, + "link":{ + "type": "generated-index", + "slug": "Troubleshooting" + } +} diff --git a/versioned_sidebars/version-v0.21-sidebars.json b/versioned_sidebars/version-v0.21-sidebars.json new file mode 100644 index 00000000000..39332bfe752 --- /dev/null +++ b/versioned_sidebars/version-v0.21-sidebars.json @@ -0,0 +1,8 @@ +{ + "docsSidebar": [ + { + "type": "autogenerated", + "dirName": "." + } + ] +} diff --git a/versions.json b/versions.json index edcdf565c28..b6999665ef4 100644 --- a/versions.json +++ b/versions.json @@ -1,4 +1,5 @@ [ + "v0.21", "v0.20", "v0.19", "v0.18",