This is an automated email from the ASF dual-hosted git repository.
klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/devlake.git
The following commit(s) were added to refs/heads/main by this push:
new ca79876d6 fix: widen unbounded GitHub and CI/CD string columns (#9063)
ca79876d6 is described below
commit ca79876d65ffa8aa3c743d6ea96f95834ecbf7a1
Author: Dan Crews <[email protected]>
AuthorDate: Thu Aug 20 20:16:14 2026 -0700
fix: widen unbounded GitHub and CI/CD string columns (#9063)
* fix: add blueprint_id index to _devlake_pipelines
GET /blueprints/:blueprintId/pipelines runs COUNT(*) and a filtered
SELECT on _devlake_pipelines.blueprint_id, but the column was
unindexed. On instances with tens of thousands of pipeline rows this
forces a full table scan on every request; observed ~30s for a table
of 34k rows, causing upstream request timeouts in config-ui.
Add a gorm index tag on Pipeline.BlueprintId for fresh installs and a
migration script to add the index to existing installs.
Signed-off-by: Dan Crews <[email protected]>
* fix(github): widen unbounded tool fields
Signed-off-by: Dan Crews <[email protected]>
* fix(domain): widen unbounded CI/CD fields
Signed-off-by: Dan Crews <[email protected]>
---------
Signed-off-by: Dan Crews <[email protected]>
---
.../domainlayer/devops/cicd_deployment_commit.go | 6 +-
.../models/domainlayer/devops/cicd_pipeline.go | 2 +-
.../core/models/domainlayer/devops/cicd_release.go | 4 +-
.../core/models/domainlayer/devops/cicd_scope.go | 2 +-
.../core/models/domainlayer/devops/cicd_task.go | 2 +-
.../models/domainlayer/devops/text_columns_test.go | 51 ++++++++++++
backend/core/models/domainlayer/ticket/incident.go | 2 +-
.../ticket/incident_text_column_test.go | 34 ++++++++
...20260818_add_blueprint_id_index_to_pipelines.go | 46 +++++++++++
.../20260819_expand_text_columns.go | 59 ++++++++++++++
.../20260819_expand_text_columns_test.go | 88 ++++++++++++++++++++
backend/core/models/migrationscripts/register.go | 2 +
backend/core/models/pipeline.go | 2 +-
backend/plugins/github/models/account.go | 4 +-
backend/plugins/github/models/deployment.go | 6 +-
backend/plugins/github/models/job.go | 6 +-
.../20260819_expand_text_columns.go | 65 +++++++++++++++
.../20260819_expand_text_columns_test.go | 94 ++++++++++++++++++++++
.../github/models/migrationscripts/register.go | 1 +
backend/plugins/github/models/pr.go | 8 +-
backend/plugins/github/models/run.go | 4 +-
backend/plugins/github/models/text_columns_test.go | 57 +++++++++++++
22 files changed, 521 insertions(+), 24 deletions(-)
diff --git a/backend/core/models/domainlayer/devops/cicd_deployment_commit.go
b/backend/core/models/domainlayer/devops/cicd_deployment_commit.go
index 0dd0e2ee6..3bcce440b 100644
--- a/backend/core/models/domainlayer/devops/cicd_deployment_commit.go
+++ b/backend/core/models/domainlayer/devops/cicd_deployment_commit.go
@@ -25,7 +25,7 @@ type CicdDeploymentCommit struct {
domainlayer.DomainEntity
CicdScopeId string `gorm:"index;type:varchar(255)"`
CicdDeploymentId string `gorm:"type:varchar(255)"` // if it is
converted from a cicd_pipeline_commit
- Name string `gorm:"type:varchar(255)"`
+ Name string `gorm:"type:text"`
DisplayTitle string
Url string
Result string `gorm:"type:varchar(100)"`
@@ -39,11 +39,11 @@ type CicdDeploymentCommit struct {
QueuedDurationSec *float64
CommitSha string
`gorm:"primaryKey;type:varchar(255)"`
CommitMsg string
- RefName string `gorm:"type:varchar(255)"` // to
delete?
+ RefName string `gorm:"type:text"` // to delete?
RepoId string `gorm:"type:varchar(255)"`
RepoUrl string `gorm:"index;not null"`
PrevSuccessDeploymentCommitId string `gorm:"type:varchar(255)"`
- SubtaskName string `gorm:"type:varchar(255)"`
+ SubtaskName string `gorm:"type:text"`
}
func (cicdDeploymentCommit CicdDeploymentCommit) TableName() string {
diff --git a/backend/core/models/domainlayer/devops/cicd_pipeline.go
b/backend/core/models/domainlayer/devops/cicd_pipeline.go
index 3a0a34f46..2ac969b37 100644
--- a/backend/core/models/domainlayer/devops/cicd_pipeline.go
+++ b/backend/core/models/domainlayer/devops/cicd_pipeline.go
@@ -27,7 +27,7 @@ import (
type CICDPipeline struct {
domainlayer.DomainEntity
- Name string `gorm:"type:varchar(255)"`
+ Name string `gorm:"type:text"`
DisplayTitle string
Url string
Result string `gorm:"type:varchar(100)"`
diff --git a/backend/core/models/domainlayer/devops/cicd_release.go
b/backend/core/models/domainlayer/devops/cicd_release.go
index 7a8b62061..d49427855 100644
--- a/backend/core/models/domainlayer/devops/cicd_release.go
+++ b/backend/core/models/domainlayer/devops/cicd_release.go
@@ -28,8 +28,8 @@ type CicdRelease struct {
CicdScopeId string `gorm:"index;type:varchar(255)"`
- Name string `gorm:"type:varchar(255)"`
- DisplayTitle string `gorm:"type:varchar(255)"`
+ Name string `gorm:"type:text"`
+ DisplayTitle string `gorm:"type:text"`
Description string `json:"description"`
URL string `json:"url"`
diff --git a/backend/core/models/domainlayer/devops/cicd_scope.go
b/backend/core/models/domainlayer/devops/cicd_scope.go
index 2af66accf..5bfc7b6ff 100644
--- a/backend/core/models/domainlayer/devops/cicd_scope.go
+++ b/backend/core/models/domainlayer/devops/cicd_scope.go
@@ -28,7 +28,7 @@ var _ plugin.Scope = (*CicdScope)(nil)
type CicdScope struct {
domainlayer.DomainEntity
- Name string `gorm:"type:varchar(255)"`
+ Name string `gorm:"type:text"`
Description string
Url string `gorm:"type:varchar(255)"`
CreatedDate *time.Time
diff --git a/backend/core/models/domainlayer/devops/cicd_task.go
b/backend/core/models/domainlayer/devops/cicd_task.go
index 5fd00bbe4..a32d06201 100644
--- a/backend/core/models/domainlayer/devops/cicd_task.go
+++ b/backend/core/models/domainlayer/devops/cicd_task.go
@@ -38,7 +38,7 @@ const ENV_NAME_PATTERN = "ENV_NAME_PATTERN"
type CICDTask struct {
domainlayer.DomainEntity
- Name string `gorm:"type:varchar(255)"`
+ Name string `gorm:"type:text"`
PipelineId string `gorm:"index;type:varchar(255)"`
Result string `gorm:"type:varchar(100)"`
Status string `gorm:"type:varchar(100)"`
diff --git a/backend/core/models/domainlayer/devops/text_columns_test.go
b/backend/core/models/domainlayer/devops/text_columns_test.go
new file mode 100644
index 000000000..1a1ed37a7
--- /dev/null
+++ b/backend/core/models/domainlayer/devops/text_columns_test.go
@@ -0,0 +1,51 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package devops
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+)
+
+func TestUnboundedStringFieldsUseText(t *testing.T) {
+ tests := []struct {
+ model any
+ field string
+ }{
+ {CICDTask{}, "Name"},
+ {CicdScope{}, "Name"},
+ {CicdRelease{}, "Name"},
+ {CicdRelease{}, "DisplayTitle"},
+ {CicdDeploymentCommit{}, "Name"},
+ {CicdDeploymentCommit{}, "SubtaskName"},
+ {CicdDeploymentCommit{}, "RefName"},
+ {CICDPipeline{}, "Name"},
+ }
+
+ for _, test := range tests {
+ modelType := reflect.TypeOf(test.model)
+ field, found := modelType.FieldByName(test.field)
+ if !found {
+ t.Fatalf("%s.%s not found", modelType.Name(),
test.field)
+ }
+ if !strings.Contains(field.Tag.Get("gorm"), "type:text") {
+ t.Errorf("%s.%s gorm tag = %q, want type:text",
modelType.Name(), test.field, field.Tag.Get("gorm"))
+ }
+ }
+}
diff --git a/backend/core/models/domainlayer/ticket/incident.go
b/backend/core/models/domainlayer/ticket/incident.go
index 073e0b2bd..3f715757a 100644
--- a/backend/core/models/domainlayer/ticket/incident.go
+++ b/backend/core/models/domainlayer/ticket/incident.go
@@ -46,7 +46,7 @@ type Incident struct {
Priority string `gorm:"type:varchar(255)"`
Severity string `gorm:"type:varchar(255)"`
Urgency string `gorm:"type:varchar(255)"`
- Component string `gorm:"type:varchar(255)"`
+ Component string `gorm:"type:text"`
OriginalProject string `gorm:"type:varchar(255)"`
Table string
`gorm:"index:idx_table_scope_id;type:varchar(255)"`
ScopeId string
`gorm:"index:idx_table_scope_id;type:varchar(255)"`
diff --git
a/backend/core/models/domainlayer/ticket/incident_text_column_test.go
b/backend/core/models/domainlayer/ticket/incident_text_column_test.go
new file mode 100644
index 000000000..77c085640
--- /dev/null
+++ b/backend/core/models/domainlayer/ticket/incident_text_column_test.go
@@ -0,0 +1,34 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package ticket
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+)
+
+func TestIncidentComponentUsesText(t *testing.T) {
+ field, found := reflect.TypeOf(Incident{}).FieldByName("Component")
+ if !found {
+ t.Fatal("Incident.Component not found")
+ }
+ if !strings.Contains(field.Tag.Get("gorm"), "type:text") {
+ t.Fatalf("Incident.Component gorm tag = %q, want type:text",
field.Tag.Get("gorm"))
+ }
+}
diff --git
a/backend/core/models/migrationscripts/20260818_add_blueprint_id_index_to_pipelines.go
b/backend/core/models/migrationscripts/20260818_add_blueprint_id_index_to_pipelines.go
new file mode 100644
index 000000000..8b541468a
--- /dev/null
+++
b/backend/core/models/migrationscripts/20260818_add_blueprint_id_index_to_pipelines.go
@@ -0,0 +1,46 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package migrationscripts
+
+import (
+ "github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/helpers/migrationhelper"
+)
+
+type addBlueprintIdIndexToPipelines struct{}
+
+type pipeline20260818 struct {
+ BlueprintId uint64 `gorm:"index"`
+}
+
+func (pipeline20260818) TableName() string {
+ return "_devlake_pipelines"
+}
+
+func (u *addBlueprintIdIndexToPipelines) Up(basicRes context.BasicRes)
errors.Error {
+ return migrationhelper.AutoMigrateTables(basicRes, &pipeline20260818{})
+}
+
+func (*addBlueprintIdIndexToPipelines) Version() uint64 {
+ return 20260818000001
+}
+
+func (*addBlueprintIdIndexToPipelines) Name() string {
+ return "add blueprint_id index for _devlake_pipelines"
+}
diff --git
a/backend/core/models/migrationscripts/20260819_expand_text_columns.go
b/backend/core/models/migrationscripts/20260819_expand_text_columns.go
new file mode 100644
index 000000000..6f8d396d3
--- /dev/null
+++ b/backend/core/models/migrationscripts/20260819_expand_text_columns.go
@@ -0,0 +1,59 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package migrationscripts
+
+import (
+ "github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/core/plugin"
+)
+
+var _ plugin.MigrationScript = (*expandDomainTextColumns)(nil)
+
+type expandDomainTextColumns struct{}
+
+func (*expandDomainTextColumns) Up(basicRes context.BasicRes) errors.Error {
+ db := basicRes.GetDal()
+ columns := []struct {
+ tableName string
+ columnName string
+ }{
+ {"cicd_tasks", "name"},
+ {"cicd_scopes", "name"},
+ {"cicd_releases", "name"},
+ {"cicd_releases", "display_title"},
+ {"cicd_deployment_commits", "name"},
+ {"cicd_deployment_commits", "subtask_name"},
+ {"cicd_deployment_commits", "ref_name"},
+ {"incidents", "component"},
+ }
+ for _, column := range columns {
+ if err := db.ModifyColumnType(column.tableName,
column.columnName, "text"); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (*expandDomainTextColumns) Version() uint64 {
+ return 20260819000001
+}
+
+func (*expandDomainTextColumns) Name() string {
+ return "expand domain text columns"
+}
diff --git
a/backend/core/models/migrationscripts/20260819_expand_text_columns_test.go
b/backend/core/models/migrationscripts/20260819_expand_text_columns_test.go
new file mode 100644
index 000000000..3269f0486
--- /dev/null
+++ b/backend/core/models/migrationscripts/20260819_expand_text_columns_test.go
@@ -0,0 +1,88 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package migrationscripts
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/dal"
+ "github.com/apache/incubator-devlake/core/errors"
+)
+
+type domainTextColumnCall struct {
+ tableName string
+ columnName string
+ columnType string
+}
+
+type domainTextColumnRecordingDal struct {
+ dal.Dal
+ calls []domainTextColumnCall
+}
+
+func (d *domainTextColumnRecordingDal) ModifyColumnType(tableName, columnName,
columnType string) errors.Error {
+ d.calls = append(d.calls, domainTextColumnCall{tableName, columnName,
columnType})
+ return nil
+}
+
+type domainTextColumnBasicRes struct {
+ context.BasicRes
+ database dal.Dal
+}
+
+func (r *domainTextColumnBasicRes) GetDal() dal.Dal {
+ return r.database
+}
+
+func TestExpandDomainTextColumns(t *testing.T) {
+ database := new(domainTextColumnRecordingDal)
+ script := new(expandDomainTextColumns)
+
+ if err := script.Up(&domainTextColumnBasicRes{database: database}); err
!= nil {
+ t.Fatalf("migration failed: %v", err)
+ }
+
+ want := []domainTextColumnCall{
+ {"cicd_tasks", "name", "text"},
+ {"cicd_scopes", "name", "text"},
+ {"cicd_releases", "name", "text"},
+ {"cicd_releases", "display_title", "text"},
+ {"cicd_deployment_commits", "name", "text"},
+ {"cicd_deployment_commits", "subtask_name", "text"},
+ {"cicd_deployment_commits", "ref_name", "text"},
+ {"incidents", "component", "text"},
+ }
+ if !reflect.DeepEqual(database.calls, want) {
+ t.Fatalf("ModifyColumnType calls = %#v, want %#v",
database.calls, want)
+ }
+ if script.Version() != 20260819000001 {
+ t.Fatalf("Version() = %d, want 20260819000001",
script.Version())
+ }
+ if script.Name() != "expand domain text columns" {
+ t.Fatalf("Name() = %q, want %q", script.Name(), "expand domain
text columns")
+ }
+
+ for _, registeredScript := range All() {
+ if registeredScript.Version() == script.Version() {
+ return
+ }
+ }
+ t.Fatalf("migration version %d is not registered", script.Version())
+}
diff --git a/backend/core/models/migrationscripts/register.go
b/backend/core/models/migrationscripts/register.go
index 69ab4d673..dd015b9b1 100644
--- a/backend/core/models/migrationscripts/register.go
+++ b/backend/core/models/migrationscripts/register.go
@@ -150,5 +150,7 @@ func All() []plugin.MigrationScript {
new(addCqProjectMetricsHistory),
new(addIsBotToAccounts),
new(addSprintVelocityFields),
+ new(addBlueprintIdIndexToPipelines),
+ new(expandDomainTextColumns),
}
}
diff --git a/backend/core/models/pipeline.go b/backend/core/models/pipeline.go
index f9613dd0e..a3c0dcae7 100644
--- a/backend/core/models/pipeline.go
+++ b/backend/core/models/pipeline.go
@@ -54,7 +54,7 @@ func (plan PipelinePlan) IsEmpty() bool {
type Pipeline struct {
common.Model
Name string `json:"name" gorm:"index"`
- BlueprintId uint64 `json:"blueprintId"`
+ BlueprintId uint64 `json:"blueprintId" gorm:"index"`
Plan PipelinePlan `json:"plan" gorm:"serializer:encdec"`
TotalTasks int `json:"totalTasks"`
FinishedTasks int `json:"finishedTasks"`
diff --git a/backend/plugins/github/models/account.go
b/backend/plugins/github/models/account.go
index d98985349..7747eafb6 100644
--- a/backend/plugins/github/models/account.go
+++ b/backend/plugins/github/models/account.go
@@ -25,8 +25,8 @@ type GithubAccount struct {
ConnectionId uint64 `gorm:"primaryKey"`
Id int `json:"id" gorm:"primaryKey;autoIncrement:false"`
Login string `json:"login" gorm:"type:varchar(255)"`
- Name string `json:"name" gorm:"type:varchar(255)"`
- Company string `json:"company" gorm:"type:varchar(255)"`
+ Name string `json:"name" gorm:"type:text"`
+ Company string `json:"company" gorm:"type:text"`
Email string `json:"Email" gorm:"type:varchar(255)"`
AvatarUrl string `json:"avatar_url" gorm:"type:varchar(255)"`
Url string `json:"url" gorm:"type:varchar(255)"`
diff --git a/backend/plugins/github/models/deployment.go
b/backend/plugins/github/models/deployment.go
index 16d2d742c..ec459b612 100644
--- a/backend/plugins/github/models/deployment.go
+++ b/backend/plugins/github/models/deployment.go
@@ -32,15 +32,15 @@ type GithubDeployment struct {
Url string
DatabaseId uint `json:"database_id"`
CommitOid string `json:"commit_oid"
gorm:"type:varchar(255)"`
- Description string `json:"description"
gorm:"type:varchar(255)"`
- Environment string `json:"environment"
gorm:"type:varchar(255)"`
+ Description string `json:"description" gorm:"type:text"`
+ Environment string `json:"environment" gorm:"type:text"`
State string `json:"state" gorm:"type:varchar(255)"`
LatestStatusState string `json:"latest_status_state"
gorm:"type:varchar(255)"`
LatestUpdatedDate *time.Time `json:"latest_status_update_date"`
RepositoryID string `json:"repository_id"
gorm:"type:varchar(255)"`
RepositoryName string `json:"repository_name"
gorm:"type:varchar(255)"`
RepositoryUrl string `json:"repository_url"
gorm:"type:varchar(255)"`
- RefName string `json:"ref_name" gorm:"type:varchar(255)"`
+ RefName string `json:"ref_name" gorm:"type:text"`
Payload string `json:"payload" gorm:"type:text"`
FinishedDate *time.Time `json:"finished_at"`
CreatedDate time.Time `json:"created_at"`
diff --git a/backend/plugins/github/models/job.go
b/backend/plugins/github/models/job.go
index bc4f72960..7dbc69f52 100644
--- a/backend/plugins/github/models/job.go
+++ b/backend/plugins/github/models/job.go
@@ -39,15 +39,15 @@ type GithubJob struct {
Conclusion string `json:"conclusion"
gorm:"type:varchar(255)"`
StartedAt *time.Time `json:"started_at"`
CompletedAt *time.Time `json:"completed_at"`
- Name string `json:"name" gorm:"type:varchar(255)"`
+ Name string `json:"name" gorm:"type:text"`
Steps datatypes.JSON `json:"steps"`
CheckRunURL string `json:"check_run_url"
gorm:"type:varchar(255)"`
Labels datatypes.JSON `json:"labels"`
RunnerID int `json:"runner_id"`
- RunnerName string `json:"runner_name"
gorm:"type:varchar(255)"`
+ RunnerName string `json:"runner_name" gorm:"type:text"`
RunnerGroupID int `json:"runner_group_id"`
Type string `json:"type" gorm:"type:varchar(255)"`
- Environment string `gorm:"type:varchar(255)"`
+ Environment string `gorm:"type:text"`
}
func (GithubJob) TableName() string {
diff --git
a/backend/plugins/github/models/migrationscripts/20260819_expand_text_columns.go
b/backend/plugins/github/models/migrationscripts/20260819_expand_text_columns.go
new file mode 100644
index 000000000..3ae32faf9
--- /dev/null
+++
b/backend/plugins/github/models/migrationscripts/20260819_expand_text_columns.go
@@ -0,0 +1,65 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package migrationscripts
+
+import (
+ "github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/core/plugin"
+)
+
+var _ plugin.MigrationScript = (*expandGithubTextColumns)(nil)
+
+type expandGithubTextColumns struct{}
+
+func (*expandGithubTextColumns) Up(basicRes context.BasicRes) errors.Error {
+ db := basicRes.GetDal()
+ columns := []struct {
+ tableName string
+ columnName string
+ }{
+ {"_tool_github_jobs", "name"},
+ {"_tool_github_jobs", "runner_name"},
+ {"_tool_github_jobs", "environment"},
+ {"_tool_github_runs", "head_branch"},
+ {"_tool_github_runs", "path"},
+ {"_tool_github_pull_requests", "head_ref"},
+ {"_tool_github_pull_requests", "base_ref"},
+ {"_tool_github_pull_requests", "author_name"},
+ {"_tool_github_pull_requests", "merged_by_name"},
+ {"_tool_github_deployments", "environment"},
+ {"_tool_github_deployments", "ref_name"},
+ {"_tool_github_deployments", "description"},
+ {"_tool_github_accounts", "company"},
+ {"_tool_github_accounts", "name"},
+ }
+ for _, column := range columns {
+ if err := db.ModifyColumnType(column.tableName,
column.columnName, "text"); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (*expandGithubTextColumns) Version() uint64 {
+ return 20260819000000
+}
+
+func (*expandGithubTextColumns) Name() string {
+ return "expand GitHub text columns"
+}
diff --git
a/backend/plugins/github/models/migrationscripts/20260819_expand_text_columns_test.go
b/backend/plugins/github/models/migrationscripts/20260819_expand_text_columns_test.go
new file mode 100644
index 000000000..8c979d4c8
--- /dev/null
+++
b/backend/plugins/github/models/migrationscripts/20260819_expand_text_columns_test.go
@@ -0,0 +1,94 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package migrationscripts
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/dal"
+ "github.com/apache/incubator-devlake/core/errors"
+)
+
+type githubTextColumnCall struct {
+ tableName string
+ columnName string
+ columnType string
+}
+
+type githubTextColumnRecordingDal struct {
+ dal.Dal
+ calls []githubTextColumnCall
+}
+
+func (d *githubTextColumnRecordingDal) ModifyColumnType(tableName, columnName,
columnType string) errors.Error {
+ d.calls = append(d.calls, githubTextColumnCall{tableName, columnName,
columnType})
+ return nil
+}
+
+type githubTextColumnBasicRes struct {
+ context.BasicRes
+ database dal.Dal
+}
+
+func (r *githubTextColumnBasicRes) GetDal() dal.Dal {
+ return r.database
+}
+
+func TestExpandGithubTextColumns(t *testing.T) {
+ database := new(githubTextColumnRecordingDal)
+ script := new(expandGithubTextColumns)
+
+ if err := script.Up(&githubTextColumnBasicRes{database: database}); err
!= nil {
+ t.Fatalf("migration failed: %v", err)
+ }
+
+ want := []githubTextColumnCall{
+ {"_tool_github_jobs", "name", "text"},
+ {"_tool_github_jobs", "runner_name", "text"},
+ {"_tool_github_jobs", "environment", "text"},
+ {"_tool_github_runs", "head_branch", "text"},
+ {"_tool_github_runs", "path", "text"},
+ {"_tool_github_pull_requests", "head_ref", "text"},
+ {"_tool_github_pull_requests", "base_ref", "text"},
+ {"_tool_github_pull_requests", "author_name", "text"},
+ {"_tool_github_pull_requests", "merged_by_name", "text"},
+ {"_tool_github_deployments", "environment", "text"},
+ {"_tool_github_deployments", "ref_name", "text"},
+ {"_tool_github_deployments", "description", "text"},
+ {"_tool_github_accounts", "company", "text"},
+ {"_tool_github_accounts", "name", "text"},
+ }
+ if !reflect.DeepEqual(database.calls, want) {
+ t.Fatalf("ModifyColumnType calls = %#v, want %#v",
database.calls, want)
+ }
+ if script.Version() != 20260819000000 {
+ t.Fatalf("Version() = %d, want 20260819000000",
script.Version())
+ }
+ if script.Name() != "expand GitHub text columns" {
+ t.Fatalf("Name() = %q, want %q", script.Name(), "expand GitHub
text columns")
+ }
+
+ for _, registeredScript := range All() {
+ if registeredScript.Version() == script.Version() {
+ return
+ }
+ }
+ t.Fatalf("migration version %d is not registered", script.Version())
+}
diff --git a/backend/plugins/github/models/migrationscripts/register.go
b/backend/plugins/github/models/migrationscripts/register.go
index 0a35123ed..04a1fb5c9 100644
--- a/backend/plugins/github/models/migrationscripts/register.go
+++ b/backend/plugins/github/models/migrationscripts/register.go
@@ -59,5 +59,6 @@ func All() []plugin.MigrationScript {
new(modifyTokenExpiresAtToNullable),
new(addPrSizeExcludedFileExtensions),
new(addGithubIssueFields),
+ new(expandGithubTextColumns),
}
}
diff --git a/backend/plugins/github/models/pr.go
b/backend/plugins/github/models/pr.go
index fbbca1ee6..6ac45d179 100644
--- a/backend/plugins/github/models/pr.go
+++ b/backend/plugins/github/models/pr.go
@@ -47,14 +47,14 @@ type GithubPullRequest struct {
Type string `gorm:"type:varchar(255)"`
Component string `gorm:"type:varchar(255)"`
MergeCommitSha string `gorm:"type:varchar(40)"`
- HeadRef string `gorm:"type:varchar(255)"`
- BaseRef string `gorm:"type:varchar(255)"`
+ HeadRef string `gorm:"type:text"`
+ BaseRef string `gorm:"type:text"`
BaseCommitSha string `gorm:"type:varchar(255)"`
HeadCommitSha string `gorm:"type:varchar(255)"`
Url string `gorm:"type:varchar(255)"`
- AuthorName string `gorm:"type:varchar(100)"`
+ AuthorName string `gorm:"type:text"`
AuthorId int
- MergedByName string `gorm:"type:varchar(100)"`
+ MergedByName string `gorm:"type:text"`
MergedById int
common.NoPKModel
}
diff --git a/backend/plugins/github/models/run.go
b/backend/plugins/github/models/run.go
index 34d211647..910c1fdbe 100644
--- a/backend/plugins/github/models/run.go
+++ b/backend/plugins/github/models/run.go
@@ -30,9 +30,9 @@ type GithubRun struct {
ID int `json:"id"
gorm:"primaryKey;autoIncrement:false"`
Name string `json:"name" gorm:"type:text"`
NodeID string `json:"node_id" gorm:"type:varchar(255)"`
- HeadBranch string `json:"head_branch"
gorm:"type:varchar(255)"`
+ HeadBranch string `json:"head_branch" gorm:"type:text"`
HeadSha string `json:"head_sha" gorm:"type:varchar(255)"`
- Path string `json:"path" gorm:"type:varchar(255)"`
+ Path string `json:"path" gorm:"type:text"`
RunNumber int `json:"run_number"`
Event string `json:"event" gorm:"type:varchar(255)"`
Status string `json:"status" gorm:"type:varchar(255)"`
diff --git a/backend/plugins/github/models/text_columns_test.go
b/backend/plugins/github/models/text_columns_test.go
new file mode 100644
index 000000000..33d159492
--- /dev/null
+++ b/backend/plugins/github/models/text_columns_test.go
@@ -0,0 +1,57 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package models
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+)
+
+func TestUnboundedStringFieldsUseText(t *testing.T) {
+ tests := []struct {
+ model any
+ field string
+ }{
+ {GithubJob{}, "Name"},
+ {GithubJob{}, "RunnerName"},
+ {GithubJob{}, "Environment"},
+ {GithubRun{}, "HeadBranch"},
+ {GithubRun{}, "Path"},
+ {GithubPullRequest{}, "HeadRef"},
+ {GithubPullRequest{}, "BaseRef"},
+ {GithubPullRequest{}, "AuthorName"},
+ {GithubPullRequest{}, "MergedByName"},
+ {GithubDeployment{}, "Environment"},
+ {GithubDeployment{}, "RefName"},
+ {GithubDeployment{}, "Description"},
+ {GithubAccount{}, "Company"},
+ {GithubAccount{}, "Name"},
+ }
+
+ for _, test := range tests {
+ modelType := reflect.TypeOf(test.model)
+ field, found := modelType.FieldByName(test.field)
+ if !found {
+ t.Fatalf("%s.%s not found", modelType.Name(),
test.field)
+ }
+ if !strings.Contains(field.Tag.Get("gorm"), "type:text") {
+ t.Errorf("%s.%s gorm tag = %q, want type:text",
modelType.Name(), test.field, field.Tag.Get("gorm"))
+ }
+ }
+}