Skip to content

Commit 2183f3f

Browse files
committed
feat(dora): add issue lead time metrics calculation [DX-85]
1 parent fad1ac0 commit 2183f3f

File tree

10 files changed

+436
-18
lines changed

10 files changed

+436
-18
lines changed

.github/workflows/build-push-ecr.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
name: DevLake Build and Push to ECR
19+
run-name: DevLake build and push to ECR by @${{ github.actor }}
20+
21+
on:
22+
workflow_dispatch:
23+
push:
24+
branches:
25+
- master
26+
- andy/dx-85
27+
28+
permissions:
29+
id-token: write # Required for JWT
30+
contents: read # Required for checkout
31+
32+
env:
33+
LATEST_TAG: v1.0.2-beta4
34+
COMMIT_TAG: ${{ github.sha }}
35+
AWS_REGION: us-east-1
36+
IAM_ROLE_ARN: arn:aws:iam::130726505375:role/github-actions-ecr
37+
ECR: 130726505375.dkr.ecr.us-east-1.amazonaws.com
38+
IMAGE_NAME_SERVER: devlake-server
39+
IMAGE_NAME_CONFIG_UI: devlake-config-ui
40+
41+
jobs:
42+
build-and-push-server:
43+
runs-on: ubuntu-latest
44+
steps:
45+
- name: Checkout repo
46+
uses: actions/checkout@83b7061638ee4956cf7545a6f7efe594e5ad0247 #v3.5.1
47+
48+
- name: Configure AWS credentials
49+
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0
50+
with:
51+
role-to-assume: ${{ env.IAM_ROLE_ARN }}
52+
role-session-name: github-action-devlake-server-build
53+
aws-region: ${{ env.AWS_REGION }}
54+
55+
- name: Login to Amazon ECR
56+
id: login-ecr
57+
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
58+
with:
59+
registry: ${{ env.ECR }}
60+
61+
- name: Set up QEMU
62+
uses: docker/setup-qemu-action@v2
63+
64+
- name: Set up Docker Buildx
65+
uses: docker/setup-buildx-action@4b4e9c3e2d4531116a6f8ba8e71fc6e2cb6e6c8c
66+
67+
- name: Build and push container image
68+
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
69+
with:
70+
context: ./backend
71+
push: true
72+
file: ./backend/Dockerfile
73+
tags: |
74+
${{ env.ECR }}/${{ env.IMAGE_NAME_SERVER }}:${{ env.LATEST_TAG }}
75+
${{ env.ECR }}/${{ env.IMAGE_NAME_SERVER }}:${{ env.COMMIT_TAG }}
76+
platforms: linux/amd64,linux/arm64
77+
build-args: |
78+
TAG=${{ github.ref_name }}
79+
SHA=${{ github.sha }}
80+
81+
build-and-push-config-ui:
82+
runs-on: ubuntu-latest
83+
steps:
84+
- name: Checkout repo
85+
uses: actions/checkout@83b7061638ee4956cf7545a6f7efe594e5ad0247 #v3.5.1
86+
87+
- name: Configure AWS credentials
88+
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0
89+
with:
90+
role-to-assume: ${{ env.IAM_ROLE_ARN }}
91+
role-session-name: github-action-devlake-config-ui-build
92+
aws-region: ${{ env.AWS_REGION }}
93+
94+
- name: Login to Amazon ECR
95+
id: login-ecr
96+
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
97+
with:
98+
registry: ${{ env.ECR }}
99+
100+
- name: Set up QEMU
101+
uses: docker/setup-qemu-action@v2
102+
103+
- name: Set up Docker Buildx
104+
uses: docker/setup-buildx-action@4b4e9c3e2d4531116a6f8ba8e71fc6e2cb6e6c8c
105+
106+
- name: Build and push container image
107+
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
108+
with:
109+
context: ./config-ui
110+
push: true
111+
file: ./config-ui/Dockerfile
112+
tags: |
113+
${{ env.ECR }}/${{ env.IMAGE_NAME_CONFIG_UI }}:${{ env.LATEST_TAG }}
114+
${{ env.ECR }}/${{ env.IMAGE_NAME_CONFIG_UI }}:${{ env.COMMIT_TAG }}
115+
platforms: linux/amd64,linux/arm64
116+
build-args: |
117+
TAG=${{ github.ref_name }}
118+
SHA=${{ github.sha }}

backend/plugins/dora/impl/impl.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func (p Dora) SubTaskMetas() []plugin.SubTaskMeta {
9494
tasks.EnrichPrevSuccessDeploymentCommitMeta,
9595
tasks.EnrichTaskEnvMeta,
9696
tasks.CalculateChangeLeadTimeMeta,
97+
tasks.CalculateIssueLeadTimeMeta,
9798
tasks.IssuesToIncidentsMeta,
9899
tasks.ConnectIncidentToDeploymentMeta,
99100
}
@@ -160,6 +161,7 @@ func (p Dora) MakeMetricPluginPipelinePlanV200(projectName string, options json.
160161
},
161162
Subtasks: []string{
162163
"calculateChangeLeadTime",
164+
"calculateIssueLeadTime",
163165
tasks.IssuesToIncidentsMeta.Name,
164166
"ConnectIncidentToDeployment",
165167
},
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package models
19+
20+
import (
21+
"time"
22+
)
23+
24+
// IssueLeadTimeMetric tracks lead time for issues from in-progress to done
25+
type IssueLeadTimeMetric struct {
26+
ProjectName string `json:"projectName" gorm:"primaryKey;type:varchar(255)"`
27+
IssueId string `json:"issueId" gorm:"primaryKey;type:varchar(255)"`
28+
InProgressDate *time.Time `json:"InProgressDate"`
29+
DoneDate *time.Time `json:"DoneDate"`
30+
31+
// Lead time in minutes from first 'In Progress' to first 'Done'
32+
InProgressToDoneMinutes *int64 `json:"inProgressToDoneMinutes"`
33+
}
34+
35+
// TableName specifies the database table name
36+
func (IssueLeadTimeMetric) TableName() string {
37+
return "_tool_dora_issue_lead_time_metrics"
38+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package migrationscripts
19+
20+
import (
21+
"time"
22+
23+
"github.com/apache/incubator-devlake/core/context"
24+
"github.com/apache/incubator-devlake/core/errors"
25+
)
26+
27+
// Define the actual table structure directly in the migration script
28+
type issueLeadTimeMetric struct {
29+
ProjectName string `gorm:"primaryKey;type:varchar(255)"`
30+
IssueId string `gorm:"primaryKey;type:varchar(255)"`
31+
InProgressDate *time.Time
32+
DoneDate *time.Time
33+
InProgressToDoneMinutes *int64
34+
}
35+
36+
// TableName specifies the table name
37+
func (issueLeadTimeMetric) TableName() string {
38+
return "_tool_dora_issue_lead_time_metrics"
39+
}
40+
41+
type addIssueLeadTimeMetricsTable struct{}
42+
43+
func (script *addIssueLeadTimeMetricsTable) Up(baseRes context.BasicRes) errors.Error {
44+
db := baseRes.GetDal()
45+
// Use our directly defined model instead of importing from models
46+
return db.AutoMigrate(&issueLeadTimeMetric{})
47+
}
48+
49+
func (*addIssueLeadTimeMetricsTable) Version() uint64 {
50+
return 2025042401
51+
}
52+
53+
func (*addIssueLeadTimeMetricsTable) Name() string {
54+
return "dora add _tool_dora_issue_lead_time_metrics table"
55+
}

backend/plugins/dora/models/migrationscripts/register.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ func All() []plugin.MigrationScript {
2727
new(addDoraBenchmark),
2828
new(fixDoraBenchmarkMetric),
2929
new(adddoraBenchmark2023),
30+
new(addIssueLeadTimeMetricsTable),
3031
}
3132
}

backend/plugins/dora/tasks/deployment_commits_generator.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ func GenerateDeploymentCommits(taskCtx plugin.SubTaskContext) errors.Error {
103103
noneSkippedResult,
104104
),
105105
}
106-
if data.Options.ScopeId != nil {
107-
clauses = append(clauses, dal.Where(`p.cicd_scope_id = ?`, data.Options.ScopeId))
106+
if data.ScopeId != "" {
107+
clauses = append(clauses, dal.Where(`p.cicd_scope_id = ?`, data.ScopeId))
108108
// Clear previous results from the project
109109
deleteSql := `DELETE FROM cicd_deployment_commits WHERE cicd_scope_id = ? and subtask_name = ?;`
110-
err := db.Exec(deleteSql, data.Options.ScopeId, DORAGenerateDeploymentCommits)
110+
err := db.Exec(deleteSql, data.ScopeId, DORAGenerateDeploymentCommits)
111111
if err != nil {
112112
return errors.Default.Wrap(err, "error deleting previous cicd_deployment_commits")
113113
}

backend/plugins/dora/tasks/deployment_generator.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,13 @@ func GenerateDeployment(taskCtx plugin.SubTaskContext) errors.Error {
7676
noneSkippedResult,
7777
),
7878
}
79-
if data.Options.ScopeId != nil {
79+
if data.ScopeId != "" {
8080
clauses = append(clauses,
81-
dal.Where("p.cicd_scope_id = ?", data.Options.ScopeId),
81+
dal.Where("p.cicd_scope_id = ?", data.ScopeId),
8282
)
8383
// Clear previous results from the cicd_scope_id
8484
deleteSql := `DELETE FROM cicd_deployments WHERE cicd_scope_id = ? and subtask_name = ?;`
85-
err := db.Exec(deleteSql, data.Options.ScopeId, DORAGenerateDeployment)
85+
err := db.Exec(deleteSql, data.ScopeId, DORAGenerateDeployment)
8686
if err != nil {
8787
return errors.Default.Wrap(err, "error deleting previous deployments")
8888
}

0 commit comments

Comments
 (0)