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/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new fb6f20d9f Fix/circleci column names (#8799)
fb6f20d9f is described below

commit fb6f20d9f36055349b21c6357dc0c3c79d947737
Author: Chris Pavlicek <[email protected]>
AuthorDate: Mon Mar 23 14:21:55 2026 +0000

    Fix/circleci column names (#8799)
    
    * fix(circleci): rename created_at to created_date in jobs/workflows
    Add migration to copy created_at -> created_date and update 
models/converters.
    
    * fix(circleci): update pipeline parsing
    
    * test(circleci): add incremental tests for collectors
---
 backend/plugins/circleci/e2e/incremental_test.go   | 154 +++++++++++++++++++++
 .../_raw_circleci_api_jobs_incremental.csv         |  73 ++++++++++
 .../_raw_circleci_api_workflows_incremental.csv    |  67 +++++++++
 .../e2e/snapshot_tables/_tool_circleci_jobs.csv    |  20 +--
 .../_tool_circleci_jobs_incremental.csv            |   7 +
 .../snapshot_tables/_tool_circleci_pipelines.csv   |  22 +--
 .../_tool_circleci_workflows_incremental.csv       |   7 +
 .../e2e/snapshot_tables/cicd_pipelines.csv         |  20 +--
 backend/plugins/circleci/e2e/workflow_test.go      |   2 +-
 backend/plugins/circleci/models/job.go             |   2 +-
 .../20260322_rename_created_at_to_created_date.go  |  71 ++++++++++
 .../circleci/models/migrationscripts/register.go   |   1 +
 backend/plugins/circleci/models/pipeline.go        |   4 +-
 backend/plugins/circleci/models/workflow.go        |   2 +-
 backend/plugins/circleci/tasks/job_converter.go    |   4 +-
 .../plugins/circleci/tasks/workflow_converter.go   |   6 +-
 .../plugins/circleci/tasks/workflow_extractor.go   |   4 +-
 17 files changed, 423 insertions(+), 43 deletions(-)

diff --git a/backend/plugins/circleci/e2e/incremental_test.go 
b/backend/plugins/circleci/e2e/incremental_test.go
new file mode 100644
index 000000000..85de8a7ba
--- /dev/null
+++ b/backend/plugins/circleci/e2e/incremental_test.go
@@ -0,0 +1,154 @@
+/*
+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 e2e
+
+import (
+       "sort"
+       "testing"
+       "time"
+
+       "github.com/apache/incubator-devlake/core/dal"
+       "github.com/apache/incubator-devlake/core/models/common"
+       "github.com/apache/incubator-devlake/helpers/e2ehelper"
+       "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+       "github.com/apache/incubator-devlake/plugins/circleci/impl"
+       "github.com/apache/incubator-devlake/plugins/circleci/models"
+       "github.com/apache/incubator-devlake/plugins/circleci/tasks"
+       "github.com/stretchr/testify/assert"
+)
+
+// TestCircleciWorkflowIncremental verifies that the workflow collector's 
incremental
+// logic correctly filters pipelines by created_date. This is a regression 
test for
+// the created_at -> created_date column rename.
+func TestCircleciWorkflowIncremental(t *testing.T) {
+       var circleci impl.Circleci
+
+       dataflowTester := e2ehelper.NewDataFlowTester(t, "circleci", circleci)
+       taskData := &tasks.CircleciTaskData{
+               Options: &tasks.CircleciOptions{
+                       ConnectionId: 1,
+                       ProjectSlug:  "github/coldgust/coldgust.github.io",
+               },
+               RegexEnricher: api.NewRegexEnricher(),
+       }
+
+       // seed pipelines table via extraction
+       
dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_circleci_api_pipelines.csv",
 "_raw_circleci_api_pipelines")
+       dataflowTester.FlushTabler(&models.CircleciPipeline{})
+       dataflowTester.Subtask(tasks.ExtractPipelinesMeta, taskData)
+
+       // Part 1: verify the SQL query used by BuildInputIterator works with 
created_date.
+       // Pipelines #4-10 have created_date > 17:45 — assert the exact IDs 
returned.
+       createdAfter := time.Date(2023, 3, 25, 17, 45, 0, 0, time.UTC)
+       var pipelines []models.CircleciPipeline
+       assert.Nil(t, dataflowTester.Dal.All(&pipelines,
+               dal.Where("connection_id = ? AND project_slug = ? AND 
created_date > ?",
+                       1, "github/coldgust/coldgust.github.io", createdAfter),
+       ))
+       pipelineIds := make([]string, len(pipelines))
+       for i, p := range pipelines {
+               pipelineIds[i] = p.Id
+       }
+       sort.Strings(pipelineIds)
+       assert.Equal(t, []string{
+               "23622ee4-e150-4920-9d66-81533fa765a4", // pipeline #5
+               "2c45280f-7fb3-4025-b703-a547c4a94916", // pipeline #4
+               "70f3eb15-3b94-4f80-b65e-f23f4b74c33a", // pipeline #6
+               "7fcc1623-edcc-4a76-ad20-cd81aa83519f", // pipeline #9
+               "866e967d-f826-4470-aed6-fc0c92e98703", // pipeline #7
+               "afe0cabe-e7ee-4eb7-bf13-bb6170d139f0", // pipeline #8
+               "d323f088-02fa-4ed5-9696-fc2f89a27150", // pipeline #10
+       }, pipelineIds)
+
+       // Part 2: verify extraction with only the incrementally-collected 
workflow raw data
+       // (workflows for pipelines #4-9 only).
+       
dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_circleci_api_workflows_incremental.csv",
 "_raw_circleci_api_workflows")
+       dataflowTester.FlushTabler(&models.CircleciWorkflow{})
+       dataflowTester.Subtask(tasks.ExtractWorkflowsMeta, taskData)
+       dataflowTester.VerifyTableWithOptions(
+               models.CircleciWorkflow{},
+               e2ehelper.TableOptions{
+                       CSVRelPath:   
"./snapshot_tables/_tool_circleci_workflows_incremental.csv",
+                       IgnoreTypes:  []interface{}{common.NoPKModel{}},
+                       IgnoreFields: []string{"started_at", "stopped_at"},
+               },
+       )
+}
+
+// TestCircleciJobIncremental verifies that the job collector's incremental 
logic
+// correctly filters workflows by created_date. Regression test for the column 
rename.
+func TestCircleciJobIncremental(t *testing.T) {
+       var circleci impl.Circleci
+
+       dataflowTester := e2ehelper.NewDataFlowTester(t, "circleci", circleci)
+       taskData := &tasks.CircleciTaskData{
+               Options: &tasks.CircleciOptions{
+                       ConnectionId: 1,
+                       ProjectSlug:  "github/coldgust/coldgust.github.io",
+               },
+               RegexEnricher: api.NewRegexEnricher(),
+               Project: &models.CircleciProject{
+                       Id: "abcd",
+               },
+       }
+
+       // seed workflows table via extraction (all 10 workflows including 
b3b77371 with null created_date)
+       
dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_circleci_api_workflows.csv",
 "_raw_circleci_api_workflows")
+       dataflowTester.FlushTabler(&models.CircleciWorkflow{})
+       dataflowTester.Subtask(tasks.ExtractWorkflowsMeta, taskData)
+
+       // Part 1: verify the SQL query used by BuildInputIterator works with 
created_date.
+       // Workflows for pipelines #4-9 have created_date > 17:45 — assert the 
exact IDs returned.
+       // Workflow b3b77371 (null created_date) is excluded by the > 
comparison.
+       createdAfter := time.Date(2023, 3, 25, 17, 45, 0, 0, time.UTC)
+       var workflows []models.CircleciWorkflow
+       assert.Nil(t, dataflowTester.Dal.All(&workflows,
+               dal.Where("connection_id = ? AND project_slug = ? AND 
created_date > ?",
+                       1, "github/coldgust/coldgust.github.io", createdAfter),
+       ))
+       workflowIds := make([]string, len(workflows))
+       for i, w := range workflows {
+               workflowIds[i] = w.Id
+       }
+       sort.Strings(workflowIds)
+       assert.Equal(t, []string{
+               "6731159f-5275-4bfa-ba70-39d343d63814", // pipeline #5
+               "7370985a-9de3-4a47-acbc-e6a1fe8e5812", // pipeline #7
+               "b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14", // pipeline #6
+               "c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943", // pipeline #4
+               "fc76deef-bcdd-4856-8e96-a8e2d1c5a85f", // pipeline #8
+               "fd0bd4f5-264f-4e3c-a151-06153c018f78", // pipeline #9
+       }, workflowIds)
+
+       // Part 2: verify extraction with only the incrementally-collected job 
raw data
+       // (jobs for workflows from pipelines #4-9 only).
+       
dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_circleci_api_projects.csv",
 "_raw_circleci_api_projects")
+       dataflowTester.FlushTabler(&models.CircleciProject{})
+       dataflowTester.Subtask(tasks.ExtractProjectsMeta, taskData)
+
+       
dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_circleci_api_jobs_incremental.csv",
 "_raw_circleci_api_jobs")
+       dataflowTester.FlushTabler(&models.CircleciJob{})
+       dataflowTester.Subtask(tasks.ExtractJobsMeta, taskData)
+       dataflowTester.VerifyTableWithOptions(
+               models.CircleciJob{},
+               e2ehelper.TableOptions{
+                       CSVRelPath:  
"./snapshot_tables/_tool_circleci_jobs_incremental.csv",
+                       IgnoreTypes: []interface{}{common.NoPKModel{}},
+               },
+       )
+}
diff --git 
a/backend/plugins/circleci/e2e/raw_tables/_raw_circleci_api_jobs_incremental.csv
 
b/backend/plugins/circleci/e2e/raw_tables/_raw_circleci_api_jobs_incremental.csv
new file mode 100644
index 000000000..24e3fbdcb
--- /dev/null
+++ 
b/backend/plugins/circleci/e2e/raw_tables/_raw_circleci_api_jobs_incremental.csv
@@ -0,0 +1,73 @@
+id,params,data,url,input,created_at
+20,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""dependencies"" : [ ],
+    ""job_number"" : 5,
+    ""id"" : ""ab8c3282-0e74-4a41-834e-152a71280bed"",
+    ""started_at"" : ""2023-03-25T17:52:20Z"",
+    ""created_at"" : ""2023-03-25T17:52:20Z"",
+    ""name"" : ""build"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""type"" : ""build"",
+    ""stopped_at"" : ""2023-03-25T17:52:23Z""
+  
}",https://circleci.com/api/v2/workflow/6731159f-5275-4bfa-ba70-39d343d63814/job,"{""id"":
 ""6731159f-5275-4bfa-ba70-39d343d63814"", ""tag"": """", ""name"": """", 
""status"": """", ""createdAt"": ""0001-01-01T00:00:00Z"", ""updatedAt"": 
""0001-01-01T00:00:00Z"", ""created_at"": null, ""errored_by"": """", 
""started_by"": """", ""stopped_at"": null, ""canceled_by"": """", 
""pipeline_id"": ""23622ee4-e150-4920-9d66-81533fa765a4"", ""ConnectionId"": 0, 
""_raw_data_id"": 0, ""duration_sec [...]
+21,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""dependencies"" : [ ],
+    ""job_number"" : 7,
+    ""id"" : ""a00f80bc-f759-4900-97a5-2d121d80bde8"",
+    ""started_at"" : ""2023-03-25T17:56:27Z"",
+    ""created_at"" : ""2023-03-25T17:56:27Z"",
+    ""name"" : ""build"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""type"" : ""build"",
+    ""stopped_at"" : ""2023-03-25T17:56:43Z""
+  
}",https://circleci.com/api/v2/workflow/7370985a-9de3-4a47-acbc-e6a1fe8e5812/job,"{""id"":
 ""7370985a-9de3-4a47-acbc-e6a1fe8e5812"", ""tag"": """", ""name"": """", 
""status"": """", ""createdAt"": ""0001-01-01T00:00:00Z"", ""updatedAt"": 
""0001-01-01T00:00:00Z"", ""created_at"": null, ""errored_by"": """", 
""started_by"": """", ""stopped_at"": null, ""canceled_by"": """", 
""pipeline_id"": ""866e967d-f826-4470-aed6-fc0c92e98703"", ""ConnectionId"": 0, 
""_raw_data_id"": 0, ""duration_sec [...]
+23,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""dependencies"" : [ ],
+    ""job_number"" : 9,
+    ""id"" : ""2ff3594e-9da1-4306-aefa-77b72a97971e"",
+    ""started_at"" : ""2023-03-25T18:13:25Z"",
+    ""created_at"" : ""2023-03-25T18:13:25Z"",
+    ""name"" : ""build"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""success"",
+    ""type"" : ""build"",
+    ""stopped_at"" : ""2023-03-25T18:13:38Z""
+  
}",https://circleci.com/api/v2/workflow/fd0bd4f5-264f-4e3c-a151-06153c018f78/job,"{""id"":
 ""fd0bd4f5-264f-4e3c-a151-06153c018f78"", ""tag"": """", ""name"": """", 
""status"": """", ""createdAt"": ""0001-01-01T00:00:00Z"", ""updatedAt"": 
""0001-01-01T00:00:00Z"", ""created_at"": null, ""errored_by"": """", 
""started_by"": """", ""stopped_at"": null, ""canceled_by"": """", 
""pipeline_id"": ""7fcc1623-edcc-4a76-ad20-cd81aa83519f"", ""ConnectionId"": 0, 
""_raw_data_id"": 0, ""duration_sec [...]
+24,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""dependencies"" : [ ],
+    ""job_number"" : 6,
+    ""id"" : ""76c1f2cc-27ea-47aa-8167-48d2633abdba"",
+    ""started_at"" : ""2023-03-25T17:54:11Z"",
+    ""created_at"" : ""2023-03-25T17:54:11Z"",
+    ""name"" : ""build"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""type"" : ""build"",
+    ""stopped_at"" : ""2023-03-25T17:54:23Z""
+  
}",https://circleci.com/api/v2/workflow/b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14/job,"{""id"":
 ""b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14"", ""tag"": """", ""name"": """", 
""status"": """", ""createdAt"": ""0001-01-01T00:00:00Z"", ""updatedAt"": 
""0001-01-01T00:00:00Z"", ""created_at"": null, ""errored_by"": """", 
""started_by"": """", ""stopped_at"": null, ""canceled_by"": """", 
""pipeline_id"": ""70f3eb15-3b94-4f80-b65e-f23f4b74c33a"", ""ConnectionId"": 0, 
""_raw_data_id"": 0, ""duration_sec [...]
+25,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""dependencies"" : [ ],
+    ""job_number"" : 4,
+    ""id"" : ""a4af3dd5-a3ae-48e8-b634-e2d63aafbb5b"",
+    ""started_at"" : ""2023-03-25T17:50:22Z"",
+    ""created_at"" : ""2023-03-25T17:50:22Z"",
+    ""name"" : ""build"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""type"" : ""build"",
+    ""stopped_at"" : ""2023-03-25T17:50:25Z""
+  
}",https://circleci.com/api/v2/workflow/c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943/job,"{""id"":
 ""c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943"", ""tag"": """", ""name"": """", 
""status"": """", ""createdAt"": ""0001-01-01T00:00:00Z"", ""updatedAt"": 
""0001-01-01T00:00:00Z"", ""created_at"": null, ""errored_by"": """", 
""started_by"": """", ""stopped_at"": null, ""canceled_by"": """", 
""pipeline_id"": ""2c45280f-7fb3-4025-b703-a547c4a94916"", ""ConnectionId"": 0, 
""_raw_data_id"": 0, ""duration_sec [...]
+27,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""dependencies"" : [ ],
+    ""job_number"" : 8,
+    ""id"" : ""004e3e27-17d7-4ccb-9b21-a7f55bcf2b3e"",
+    ""started_at"" : ""2023-03-25T18:06:15Z"",
+    ""created_at"" : ""2023-03-25T18:06:15Z"",
+    ""name"" : ""build"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""type"" : ""build"",
+    ""stopped_at"" : ""2023-03-25T18:06:28Z""
+  
}",https://circleci.com/api/v2/workflow/fc76deef-bcdd-4856-8e96-a8e2d1c5a85f/job,"{""id"":
 ""fc76deef-bcdd-4856-8e96-a8e2d1c5a85f"", ""tag"": """", ""name"": """", 
""status"": """", ""createdAt"": ""0001-01-01T00:00:00Z"", ""updatedAt"": 
""0001-01-01T00:00:00Z"", ""created_at"": null, ""errored_by"": """", 
""started_by"": """", ""stopped_at"": null, ""canceled_by"": """", 
""pipeline_id"": ""afe0cabe-e7ee-4eb7-bf13-bb6170d139f0"", ""ConnectionId"": 0, 
""_raw_data_id"": 0, ""duration_sec [...]
diff --git 
a/backend/plugins/circleci/e2e/raw_tables/_raw_circleci_api_workflows_incremental.csv
 
b/backend/plugins/circleci/e2e/raw_tables/_raw_circleci_api_workflows_incremental.csv
new file mode 100644
index 000000000..2a70cdd51
--- /dev/null
+++ 
b/backend/plugins/circleci/e2e/raw_tables/_raw_circleci_api_workflows_incremental.csv
@@ -0,0 +1,67 @@
+id,params,data,url,input,created_at
+19,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""pipeline_id"" : ""23622ee4-e150-4920-9d66-81533fa765a4"",
+    ""id"" : ""6731159f-5275-4bfa-ba70-39d343d63814"",
+    ""name"" : ""workflow"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""started_by"" : ""1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7"",
+    ""pipeline_number"" : 5,
+    ""created_at"" : ""2023-03-25T17:52:15Z"",
+    ""stopped_at"" : ""2023-03-25T17:52:23Z""
+  
}",https://circleci.com/api/v2/pipeline/23622ee4-e150-4920-9d66-81533fa765a4/workflow,"{""id"":
 ""23622ee4-e150-4920-9d66-81533fa765a4"", ""vcs"": {""tag"": """", ""branch"": 
"""", ""commit"": {""body"": """", ""subject"": """"}, ""revision"": """", 
""review_id"": """", ""review_url"": """", ""provider_name"": """", 
""origin_repository_url"": """", ""target_repository_url"": """"}, ""state"": 
"""", ""errors"": null, ""number"": 0, ""trigger"": {""type"": """", ""actor"": 
{""login"": "" [...]
+20,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""pipeline_id"" : ""2c45280f-7fb3-4025-b703-a547c4a94916"",
+    ""id"" : ""c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943"",
+    ""name"" : ""workflow"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""started_by"" : ""1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7"",
+    ""pipeline_number"" : 4,
+    ""created_at"" : ""2023-03-25T17:50:20Z"",
+    ""stopped_at"" : ""2023-03-25T17:50:25Z""
+  
}",https://circleci.com/api/v2/pipeline/2c45280f-7fb3-4025-b703-a547c4a94916/workflow,"{""id"":
 ""2c45280f-7fb3-4025-b703-a547c4a94916"", ""vcs"": {""tag"": """", ""branch"": 
"""", ""commit"": {""body"": """", ""subject"": """"}, ""revision"": """", 
""review_id"": """", ""review_url"": """", ""provider_name"": """", 
""origin_repository_url"": """", ""target_repository_url"": """"}, ""state"": 
"""", ""errors"": null, ""number"": 0, ""trigger"": {""type"": """", ""actor"": 
{""login"": "" [...]
+22,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""pipeline_id"" : ""7fcc1623-edcc-4a76-ad20-cd81aa83519f"",
+    ""id"" : ""fd0bd4f5-264f-4e3c-a151-06153c018f78"",
+    ""name"" : ""workflow"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""success"",
+    ""started_by"" : ""1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7"",
+    ""pipeline_number"" : 9,
+    ""created_at"" : ""2023-03-25T18:13:21Z"",
+    ""stopped_at"" : ""2023-03-25T18:13:38Z""
+  
}",https://circleci.com/api/v2/pipeline/7fcc1623-edcc-4a76-ad20-cd81aa83519f/workflow,"{""id"":
 ""7fcc1623-edcc-4a76-ad20-cd81aa83519f"", ""vcs"": {""tag"": """", ""branch"": 
"""", ""commit"": {""body"": """", ""subject"": """"}, ""revision"": """", 
""review_id"": """", ""review_url"": """", ""provider_name"": """", 
""origin_repository_url"": """", ""target_repository_url"": """"}, ""state"": 
"""", ""errors"": null, ""number"": 0, ""trigger"": {""type"": """", ""actor"": 
{""login"": "" [...]
+24,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""pipeline_id"" : ""866e967d-f826-4470-aed6-fc0c92e98703"",
+    ""id"" : ""7370985a-9de3-4a47-acbc-e6a1fe8e5812"",
+    ""name"" : ""workflow"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""started_by"" : ""1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7"",
+    ""pipeline_number"" : 7,
+    ""created_at"" : ""2023-03-25T17:56:24Z"",
+    ""stopped_at"" : ""2023-03-25T17:56:43Z""
+  
}",https://circleci.com/api/v2/pipeline/866e967d-f826-4470-aed6-fc0c92e98703/workflow,"{""id"":
 ""866e967d-f826-4470-aed6-fc0c92e98703"", ""vcs"": {""tag"": """", ""branch"": 
"""", ""commit"": {""body"": """", ""subject"": """"}, ""revision"": """", 
""review_id"": """", ""review_url"": """", ""provider_name"": """", 
""origin_repository_url"": """", ""target_repository_url"": """"}, ""state"": 
"""", ""errors"": null, ""number"": 0, ""trigger"": {""type"": """", ""actor"": 
{""login"": "" [...]
+26,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""pipeline_id"" : ""70f3eb15-3b94-4f80-b65e-f23f4b74c33a"",
+    ""id"" : ""b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14"",
+    ""name"" : ""workflow"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""started_by"" : ""1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7"",
+    ""pipeline_number"" : 6,
+    ""created_at"" : ""2023-03-25T17:54:09Z"",
+    ""stopped_at"" : ""2023-03-25T17:54:23Z""
+  
}",https://circleci.com/api/v2/pipeline/70f3eb15-3b94-4f80-b65e-f23f4b74c33a/workflow,"{""id"":
 ""70f3eb15-3b94-4f80-b65e-f23f4b74c33a"", ""vcs"": {""tag"": """", ""branch"": 
"""", ""commit"": {""body"": """", ""subject"": """"}, ""revision"": """", 
""review_id"": """", ""review_url"": """", ""provider_name"": """", 
""origin_repository_url"": """", ""target_repository_url"": """"}, ""state"": 
"""", ""errors"": null, ""number"": 0, ""trigger"": {""type"": """", ""actor"": 
{""login"": "" [...]
+27,"{""ConnectionId"":1,""ProjectSlug"":""github/coldgust/coldgust.github.io""}","{
+    ""pipeline_id"" : ""afe0cabe-e7ee-4eb7-bf13-bb6170d139f0"",
+    ""id"" : ""fc76deef-bcdd-4856-8e96-a8e2d1c5a85f"",
+    ""name"" : ""workflow"",
+    ""project_slug"" : ""gh/coldgust/coldgust.github.io"",
+    ""status"" : ""failed"",
+    ""started_by"" : ""1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7"",
+    ""pipeline_number"" : 8,
+    ""created_at"" : ""2023-03-25T18:06:13Z"",
+    ""stopped_at"" : ""2023-03-25T18:06:28Z""
+  
}",https://circleci.com/api/v2/pipeline/afe0cabe-e7ee-4eb7-bf13-bb6170d139f0/workflow,"{""id"":
 ""afe0cabe-e7ee-4eb7-bf13-bb6170d139f0"", ""vcs"": {""tag"": """", ""branch"": 
"""", ""commit"": {""body"": """", ""subject"": """"}, ""revision"": """", 
""review_id"": """", ""review_url"": """", ""provider_name"": """", 
""origin_repository_url"": """", ""target_repository_url"": """"}, ""state"": 
"""", ""errors"": null, ""number"": 0, ""trigger"": {""type"": """", ""actor"": 
{""login"": "" [...]
diff --git 
a/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_jobs.csv 
b/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_jobs.csv
index 82f2b4c45..517060bd3 100644
--- a/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_jobs.csv
+++ b/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_jobs.csv
@@ -1,10 +1,10 @@
-connection_id,workflow_id,id,project_slug,canceled_by,dependencies,job_number,queued_at,started_at,name,approved_by,status,type,approval_request_id,stopped_at,duration_sec,pipeline_id,duration
-1,6731159f-5275-4bfa-ba70-39d343d63814,ab8c3282-0e74-4a41-834e-152a71280bed,github/coldgust/coldgust.github.io,,[],5,,2023-03-25T17:52:20.000+00:00,build,,failed,build,,2023-03-25T17:52:23.000+00:00,3,23622ee4-e150-4920-9d66-81533fa765a4,0
-1,7370985a-9de3-4a47-acbc-e6a1fe8e5812,a00f80bc-f759-4900-97a5-2d121d80bde8,github/coldgust/coldgust.github.io,,[],7,,2023-03-25T17:56:27.000+00:00,build,,failed,build,,2023-03-25T17:56:43.000+00:00,16,866e967d-f826-4470-aed6-fc0c92e98703,0
-1,89054eb2-8e85-4f5c-9a93-66d753a0e970,c46092f9-6f82-4a52-8d8b-bd70d365dfc2,github/coldgust/coldgust.github.io,,[],3,,2023-03-25T17:39:25.000+00:00,say-hello,,success,build,,2023-03-25T17:39:28.000+00:00,3,625ca634-68fe-4515-91f0-7ba8af51dc99,0
-1,8971a56b-5547-4824-94dd-07bb467524c5,7b96e45b-b10e-47a0-95d0-96580b88bdda,github/coldgust/coldgust.github.io,,[],2,,2023-03-25T17:12:20.000+00:00,say-hello,,success,build,,2023-03-25T17:12:23.000+00:00,3,87aad008-1ad5-486a-8174-fdeed846561a,0
-1,8fe60291-68f7-40e2-acec-d99bff4da713,afde48dd-7319-4973-b3c8-e00308ff7667,github/coldgust/coldgust.github.io,,[],1,,2023-03-25T17:12:20.000+00:00,say-hello,,success,build,,2023-03-25T17:12:22.000+00:00,2,afef32b3-5ffe-48d2-8d9e-46dcedd82554,0
-1,b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14,76c1f2cc-27ea-47aa-8167-48d2633abdba,github/coldgust/coldgust.github.io,,[],6,,2023-03-25T17:54:11.000+00:00,build,,failed,build,,2023-03-25T17:54:23.000+00:00,12,70f3eb15-3b94-4f80-b65e-f23f4b74c33a,0
-1,c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943,a4af3dd5-a3ae-48e8-b634-e2d63aafbb5b,github/coldgust/coldgust.github.io,,[],4,,2023-03-25T17:50:22.000+00:00,build,,failed,build,,2023-03-25T17:50:25.000+00:00,3,2c45280f-7fb3-4025-b703-a547c4a94916,0
-1,fc76deef-bcdd-4856-8e96-a8e2d1c5a85f,004e3e27-17d7-4ccb-9b21-a7f55bcf2b3e,github/coldgust/coldgust.github.io,,[],8,,2023-03-25T18:06:15.000+00:00,build,,failed,build,,2023-03-25T18:06:28.000+00:00,13,afe0cabe-e7ee-4eb7-bf13-bb6170d139f0,0
-1,fd0bd4f5-264f-4e3c-a151-06153c018f78,2ff3594e-9da1-4306-aefa-77b72a97971e,github/coldgust/coldgust.github.io,,[],9,,2023-03-25T18:13:25.000+00:00,build,,success,build,,2023-03-25T18:13:38.000+00:00,13,7fcc1623-edcc-4a76-ad20-cd81aa83519f,0
+connection_id,workflow_id,id,project_slug,canceled_by,dependencies,job_number,created_date,queued_at,started_at,name,approved_by,status,type,approval_request_id,stopped_at,duration_sec,pipeline_id,duration
+1,6731159f-5275-4bfa-ba70-39d343d63814,ab8c3282-0e74-4a41-834e-152a71280bed,github/coldgust/coldgust.github.io,,[],5,2023-03-25T17:52:20.000+00:00,,2023-03-25T17:52:20.000+00:00,build,,failed,build,,2023-03-25T17:52:23.000+00:00,3,23622ee4-e150-4920-9d66-81533fa765a4,0
+1,7370985a-9de3-4a47-acbc-e6a1fe8e5812,a00f80bc-f759-4900-97a5-2d121d80bde8,github/coldgust/coldgust.github.io,,[],7,2023-03-25T17:56:27.000+00:00,,2023-03-25T17:56:27.000+00:00,build,,failed,build,,2023-03-25T17:56:43.000+00:00,16,866e967d-f826-4470-aed6-fc0c92e98703,0
+1,89054eb2-8e85-4f5c-9a93-66d753a0e970,c46092f9-6f82-4a52-8d8b-bd70d365dfc2,github/coldgust/coldgust.github.io,,[],3,2023-03-25T17:39:25.000+00:00,,2023-03-25T17:39:25.000+00:00,say-hello,,success,build,,2023-03-25T17:39:28.000+00:00,3,625ca634-68fe-4515-91f0-7ba8af51dc99,0
+1,8971a56b-5547-4824-94dd-07bb467524c5,7b96e45b-b10e-47a0-95d0-96580b88bdda,github/coldgust/coldgust.github.io,,[],2,2023-03-25T17:12:20.000+00:00,,2023-03-25T17:12:20.000+00:00,say-hello,,success,build,,2023-03-25T17:12:23.000+00:00,3,87aad008-1ad5-486a-8174-fdeed846561a,0
+1,8fe60291-68f7-40e2-acec-d99bff4da713,afde48dd-7319-4973-b3c8-e00308ff7667,github/coldgust/coldgust.github.io,,[],1,2023-03-25T17:12:20.000+00:00,,2023-03-25T17:12:20.000+00:00,say-hello,,success,build,,2023-03-25T17:12:22.000+00:00,2,afef32b3-5ffe-48d2-8d9e-46dcedd82554,0
+1,b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14,76c1f2cc-27ea-47aa-8167-48d2633abdba,github/coldgust/coldgust.github.io,,[],6,2023-03-25T17:54:11.000+00:00,,2023-03-25T17:54:11.000+00:00,build,,failed,build,,2023-03-25T17:54:23.000+00:00,12,70f3eb15-3b94-4f80-b65e-f23f4b74c33a,0
+1,c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943,a4af3dd5-a3ae-48e8-b634-e2d63aafbb5b,github/coldgust/coldgust.github.io,,[],4,2023-03-25T17:50:22.000+00:00,,2023-03-25T17:50:22.000+00:00,build,,failed,build,,2023-03-25T17:50:25.000+00:00,3,2c45280f-7fb3-4025-b703-a547c4a94916,0
+1,fc76deef-bcdd-4856-8e96-a8e2d1c5a85f,004e3e27-17d7-4ccb-9b21-a7f55bcf2b3e,github/coldgust/coldgust.github.io,,[],8,2023-03-25T18:06:15.000+00:00,,2023-03-25T18:06:15.000+00:00,build,,failed,build,,2023-03-25T18:06:28.000+00:00,13,afe0cabe-e7ee-4eb7-bf13-bb6170d139f0,0
+1,fd0bd4f5-264f-4e3c-a151-06153c018f78,2ff3594e-9da1-4306-aefa-77b72a97971e,github/coldgust/coldgust.github.io,,[],9,2023-03-25T18:13:25.000+00:00,,2023-03-25T18:13:25.000+00:00,build,,success,build,,2023-03-25T18:13:38.000+00:00,13,7fcc1623-edcc-4a76-ad20-cd81aa83519f,0
diff --git 
a/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_jobs_incremental.csv
 
b/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_jobs_incremental.csv
new file mode 100644
index 000000000..ea9a23a44
--- /dev/null
+++ 
b/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_jobs_incremental.csv
@@ -0,0 +1,7 @@
+connection_id,workflow_id,id,project_slug,canceled_by,dependencies,job_number,created_date,queued_at,started_at,name,approved_by,status,type,approval_request_id,stopped_at,duration_sec,pipeline_id,duration
+1,6731159f-5275-4bfa-ba70-39d343d63814,ab8c3282-0e74-4a41-834e-152a71280bed,github/coldgust/coldgust.github.io,,[],5,2023-03-25T17:52:20.000+00:00,,2023-03-25T17:52:20.000+00:00,build,,failed,build,,2023-03-25T17:52:23.000+00:00,3,23622ee4-e150-4920-9d66-81533fa765a4,0
+1,7370985a-9de3-4a47-acbc-e6a1fe8e5812,a00f80bc-f759-4900-97a5-2d121d80bde8,github/coldgust/coldgust.github.io,,[],7,2023-03-25T17:56:27.000+00:00,,2023-03-25T17:56:27.000+00:00,build,,failed,build,,2023-03-25T17:56:43.000+00:00,16,866e967d-f826-4470-aed6-fc0c92e98703,0
+1,b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14,76c1f2cc-27ea-47aa-8167-48d2633abdba,github/coldgust/coldgust.github.io,,[],6,2023-03-25T17:54:11.000+00:00,,2023-03-25T17:54:11.000+00:00,build,,failed,build,,2023-03-25T17:54:23.000+00:00,12,70f3eb15-3b94-4f80-b65e-f23f4b74c33a,0
+1,c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943,a4af3dd5-a3ae-48e8-b634-e2d63aafbb5b,github/coldgust/coldgust.github.io,,[],4,2023-03-25T17:50:22.000+00:00,,2023-03-25T17:50:22.000+00:00,build,,failed,build,,2023-03-25T17:50:25.000+00:00,3,2c45280f-7fb3-4025-b703-a547c4a94916,0
+1,fc76deef-bcdd-4856-8e96-a8e2d1c5a85f,004e3e27-17d7-4ccb-9b21-a7f55bcf2b3e,github/coldgust/coldgust.github.io,,[],8,2023-03-25T18:06:15.000+00:00,,2023-03-25T18:06:15.000+00:00,build,,failed,build,,2023-03-25T18:06:28.000+00:00,13,afe0cabe-e7ee-4eb7-bf13-bb6170d139f0,0
+1,fd0bd4f5-264f-4e3c-a151-06153c018f78,2ff3594e-9da1-4306-aefa-77b72a97971e,github/coldgust/coldgust.github.io,,[],9,2023-03-25T18:13:25.000+00:00,,2023-03-25T18:13:25.000+00:00,build,,success,build,,2023-03-25T18:13:38.000+00:00,13,7fcc1623-edcc-4a76-ad20-cd81aa83519f,0
diff --git 
a/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_pipelines.csv 
b/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_pipelines.csv
index dd01015be..3d55ea884 100644
--- a/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_pipelines.csv
+++ b/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_pipelines.csv
@@ -1,11 +1,11 @@
-connection_id,id,project_slug,errors,updated_at,number,trigger_parameters,state,created_at,trigger,vcs,_raw_data_params,_raw_data_table,_raw_data_id,_raw_data_remark
-1,23622ee4-e150-4920-9d66-81533fa765a4,github/coldgust/coldgust.github.io,[],2023-03-25
 17:52:15.651,5,,created,2023-03-25 
17:52:15.651,"{""type"":""webhook"",""received_at"":""2023-03-25T17:52:15.446Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"""",""revisio
 [...]
-1,2c45280f-7fb3-4025-b703-a547c4a94916,github/coldgust/coldgust.github.io,[],2023-03-25
 17:50:20.316,4,,created,2023-03-25 
17:50:20.316,"{""type"":""webhook"",""received_at"":""2023-03-25T17:50:20.150Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"""",""revisio
 [...]
-1,625ca634-68fe-4515-91f0-7ba8af51dc99,github/coldgust/coldgust.github.io,[],2023-03-25
 17:39:23.233,3,,created,2023-03-25 
17:39:23.233,"{""type"":""webhook"",""received_at"":""2023-03-25T17:39:22.921Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""circleci-project-setup"",""review_id"":"""",""review_url";
 [...]
-1,70f3eb15-3b94-4f80-b65e-f23f4b74c33a,github/coldgust/coldgust.github.io,[],2023-03-25
 17:54:08.987,6,,created,2023-03-25 
17:54:08.987,"{""type"":""webhook"",""received_at"":""2023-03-25T17:54:08.742Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"""",""revisio
 [...]
-1,7fcc1623-edcc-4a76-ad20-cd81aa83519f,github/coldgust/coldgust.github.io,[],2023-03-25
 18:13:21.590,9,,created,2023-03-25 
18:13:21.590,"{""type"":""webhook"",""received_at"":""2023-03-25T18:13:21.404Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"""",""revisio
 [...]
-1,866e967d-f826-4470-aed6-fc0c92e98703,github/coldgust/coldgust.github.io,[],2023-03-25
 17:56:24.409,7,,created,2023-03-25 
17:56:24.409,"{""type"":""webhook"",""received_at"":""2023-03-25T17:56:24.245Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"""",""revisio
 [...]
-1,87aad008-1ad5-486a-8174-fdeed846561a,github/coldgust/coldgust.github.io,[],2023-03-25
 17:12:18.747,2,,created,2023-03-25 
17:12:18.747,"{""type"":""webhook"",""received_at"":""2023-03-25T17:12:18.624Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""circleci-project-setup"",""review_id"":"""",""review_url";
 [...]
-1,afe0cabe-e7ee-4eb7-bf13-bb6170d139f0,github/coldgust/coldgust.github.io,[],2023-03-25
 18:06:13.404,8,,created,2023-03-25 
18:06:13.404,"{""type"":""webhook"",""received_at"":""2023-03-25T18:06:13.246Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"""",""revisio
 [...]
-1,afef32b3-5ffe-48d2-8d9e-46dcedd82554,github/coldgust/coldgust.github.io,[],2023-03-25
 17:12:18.398,1,,created,2023-03-25 
17:12:18.398,"{""type"":""api"",""received_at"":""2023-03-25T17:12:16.438Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""circleci-project-setup"",""review_id"":"""",""review_url"":"";
 [...]
-1,d323f088-02fa-4ed5-9696-fc2f89a27150,github/coldgust/coldgust.github.io,"[{""type"":""config-fetch"",""message"":""Failed
 to fetch config.yml file.""}]",2023-03-25 
18:13:43.446,10,"{""circleci"":{""org_name"":""coldgust"",""project_name"":""coldgust.github.io"",""provider_name"":""github""},""git"":{""checkout_sha"":""6ba0cdaf7e7791c5bc5aa89a13b9cd184f8ad296""}}",errored,2023-03-25
 18:13:43.446,"{""type"":""Decoupled Ingestion 
System"",""received_at"":""1970-01-01T00:00:00.000Z"",""act [...]
+connection_id,id,project_slug,errors,updated_date,number,trigger_parameters,state,created_date,trigger,vcs,_raw_data_params,_raw_data_table,_raw_data_id,_raw_data_remark
+1,23622ee4-e150-4920-9d66-81533fa765a4,github/coldgust/coldgust.github.io,[],2023-03-25T17:52:15.651+00:00,5,,created,2023-03-25T17:52:15.651+00:00,"{""type"":""webhook"",""received_at"":""2023-03-25T17:52:15.446Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"";
 [...]
+1,2c45280f-7fb3-4025-b703-a547c4a94916,github/coldgust/coldgust.github.io,[],2023-03-25T17:50:20.316+00:00,4,,created,2023-03-25T17:50:20.316+00:00,"{""type"":""webhook"",""received_at"":""2023-03-25T17:50:20.150Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"";
 [...]
+1,625ca634-68fe-4515-91f0-7ba8af51dc99,github/coldgust/coldgust.github.io,[],2023-03-25T17:39:23.233+00:00,3,,created,2023-03-25T17:39:23.233+00:00,"{""type"":""webhook"",""received_at"":""2023-03-25T17:39:22.921Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""circleci-project-setup"",""review_id"":"""",";
 [...]
+1,70f3eb15-3b94-4f80-b65e-f23f4b74c33a,github/coldgust/coldgust.github.io,[],2023-03-25T17:54:08.987+00:00,6,,created,2023-03-25T17:54:08.987+00:00,"{""type"":""webhook"",""received_at"":""2023-03-25T17:54:08.742Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"";
 [...]
+1,7fcc1623-edcc-4a76-ad20-cd81aa83519f,github/coldgust/coldgust.github.io,[],2023-03-25T18:13:21.590+00:00,9,,created,2023-03-25T18:13:21.590+00:00,"{""type"":""webhook"",""received_at"":""2023-03-25T18:13:21.404Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"";
 [...]
+1,866e967d-f826-4470-aed6-fc0c92e98703,github/coldgust/coldgust.github.io,[],2023-03-25T17:56:24.409+00:00,7,,created,2023-03-25T17:56:24.409+00:00,"{""type"":""webhook"",""received_at"":""2023-03-25T17:56:24.245Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"";
 [...]
+1,87aad008-1ad5-486a-8174-fdeed846561a,github/coldgust/coldgust.github.io,[],2023-03-25T17:12:18.747+00:00,2,,created,2023-03-25T17:12:18.747+00:00,"{""type"":""webhook"",""received_at"":""2023-03-25T17:12:18.624Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""circleci-project-setup"",""review_id"":"""",";
 [...]
+1,afe0cabe-e7ee-4eb7-bf13-bb6170d139f0,github/coldgust/coldgust.github.io,[],2023-03-25T18:06:13.404+00:00,8,,created,2023-03-25T18:06:13.404+00:00,"{""type"":""webhook"",""received_at"":""2023-03-25T18:06:13.246Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""master"",""review_id"":"""",""review_url"":"";
 [...]
+1,afef32b3-5ffe-48d2-8d9e-46dcedd82554,github/coldgust/coldgust.github.io,[],2023-03-25T17:12:18.398+00:00,1,,created,2023-03-25T17:12:18.398+00:00,"{""type"":""api"",""received_at"":""2023-03-25T17:12:16.438Z"",""actor"":{""login"":""coldgust"",""avatar_url"":""https://avatars.githubusercontent.com/u/115207009?v=4""}}","{""provider_name"":""GitHub"",""target_repository_url"":""https://github.com/coldgust/coldgust.github.io"",""branch"":""circleci-project-setup"",""review_id"":"""",""rev
 [...]
+1,d323f088-02fa-4ed5-9696-fc2f89a27150,github/coldgust/coldgust.github.io,"[{""type"":""config-fetch"",""message"":""Failed
 to fetch config.yml 
file.""}]",2023-03-25T18:13:43.446+00:00,10,"{""circleci"":{""org_name"":""coldgust"",""project_name"":""coldgust.github.io"",""provider_name"":""github""},""git"":{""checkout_sha"":""6ba0cdaf7e7791c5bc5aa89a13b9cd184f8ad296""}}",errored,2023-03-25T18:13:43.446+00:00,"{""type"":""Decoupled
 Ingestion System"",""received_at"":""1970-01-01T00:00:00. [...]
diff --git 
a/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_workflows_incremental.csv
 
b/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_workflows_incremental.csv
new file mode 100644
index 000000000..529e84744
--- /dev/null
+++ 
b/backend/plugins/circleci/e2e/snapshot_tables/_tool_circleci_workflows_incremental.csv
@@ -0,0 +1,7 @@
+connection_id,id,project_slug,pipeline_id,canceled_by,name,errored_by,tag,status,started_by,pipeline_number,created_date,stopped_date,duration_sec
+1,6731159f-5275-4bfa-ba70-39d343d63814,github/coldgust/coldgust.github.io,23622ee4-e150-4920-9d66-81533fa765a4,,workflow,,,failed,1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7,5,2023-03-25T17:52:15.000+00:00,2023-03-25T17:52:23.000+00:00,8
+1,7370985a-9de3-4a47-acbc-e6a1fe8e5812,github/coldgust/coldgust.github.io,866e967d-f826-4470-aed6-fc0c92e98703,,workflow,,,failed,1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7,7,2023-03-25T17:56:24.000+00:00,2023-03-25T17:56:43.000+00:00,19
+1,b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14,github/coldgust/coldgust.github.io,70f3eb15-3b94-4f80-b65e-f23f4b74c33a,,workflow,,,failed,1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7,6,2023-03-25T17:54:09.000+00:00,2023-03-25T17:54:23.000+00:00,14
+1,c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943,github/coldgust/coldgust.github.io,2c45280f-7fb3-4025-b703-a547c4a94916,,workflow,,,failed,1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7,4,2023-03-25T17:50:20.000+00:00,2023-03-25T17:50:25.000+00:00,5
+1,fc76deef-bcdd-4856-8e96-a8e2d1c5a85f,github/coldgust/coldgust.github.io,afe0cabe-e7ee-4eb7-bf13-bb6170d139f0,,workflow,,,failed,1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7,8,2023-03-25T18:06:13.000+00:00,2023-03-25T18:06:28.000+00:00,15
+1,fd0bd4f5-264f-4e3c-a151-06153c018f78,github/coldgust/coldgust.github.io,7fcc1623-edcc-4a76-ad20-cd81aa83519f,,workflow,,,success,1c762fc2-b0fb-4fe2-97d2-5e54ddd1eba7,9,2023-03-25T18:13:21.000+00:00,2023-03-25T18:13:38.000+00:00,17
diff --git a/backend/plugins/circleci/e2e/snapshot_tables/cicd_pipelines.csv 
b/backend/plugins/circleci/e2e/snapshot_tables/cicd_pipelines.csv
index 45f61d9ce..54a7ede5d 100644
--- a/backend/plugins/circleci/e2e/snapshot_tables/cicd_pipelines.csv
+++ b/backend/plugins/circleci/e2e/snapshot_tables/cicd_pipelines.csv
@@ -1,10 +1,10 @@
-id,name,display_title,url,result,status,original_status,original_result,type,duration_sec,queued_duration_sec,environment,queued_date,started_date,cicd_scope_id
-circleci:CircleciWorkflow:1:6731159f-5275-4bfa-ba70-39d343d63814,workflow,workflow#5,,FAILURE,DONE,failed,,,8,,PRODUCTION,,2023-03-25T17:52:15.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
-circleci:CircleciWorkflow:1:7370985a-9de3-4a47-acbc-e6a1fe8e5812,workflow,workflow#7,,FAILURE,DONE,failed,,,19,,PRODUCTION,,2023-03-25T17:56:24.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
-circleci:CircleciWorkflow:1:89054eb2-8e85-4f5c-9a93-66d753a0e970,say-hello-workflow,say-hello-workflow#3,,SUCCESS,DONE,success,,,5,,PRODUCTION,,2023-03-25T17:39:23.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
-circleci:CircleciWorkflow:1:8971a56b-5547-4824-94dd-07bb467524c5,say-hello-workflow,say-hello-workflow#2,,SUCCESS,DONE,success,,,5,,PRODUCTION,,2023-03-25T17:12:18.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
-circleci:CircleciWorkflow:1:8fe60291-68f7-40e2-acec-d99bff4da713,say-hello-workflow,say-hello-workflow#1,,SUCCESS,DONE,success,,,4,,PRODUCTION,,2023-03-25T17:12:18.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
-circleci:CircleciWorkflow:1:b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14,workflow,workflow#6,,FAILURE,DONE,failed,,,14,,PRODUCTION,,2023-03-25T17:54:09.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
-circleci:CircleciWorkflow:1:c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943,workflow,workflow#4,,FAILURE,DONE,failed,,,5,,PRODUCTION,,2023-03-25T17:50:20.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
-circleci:CircleciWorkflow:1:fc76deef-bcdd-4856-8e96-a8e2d1c5a85f,workflow,workflow#8,,FAILURE,DONE,failed,,,15,,PRODUCTION,,2023-03-25T18:06:13.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
-circleci:CircleciWorkflow:1:fd0bd4f5-264f-4e3c-a151-06153c018f78,workflow,workflow#9,,SUCCESS,DONE,success,,,17,,PRODUCTION,,2023-03-25T18:13:21.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
+id,name,display_title,url,result,status,original_status,original_result,type,duration_sec,queued_duration_sec,environment,queued_date,started_date,created_date,cicd_scope_id
+circleci:CircleciWorkflow:1:6731159f-5275-4bfa-ba70-39d343d63814,workflow,workflow#5,,FAILURE,DONE,failed,,,8,,PRODUCTION,,2023-03-25T17:52:15.000+00:00,2023-03-25T17:52:15.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
+circleci:CircleciWorkflow:1:7370985a-9de3-4a47-acbc-e6a1fe8e5812,workflow,workflow#7,,FAILURE,DONE,failed,,,19,,PRODUCTION,,2023-03-25T17:56:24.000+00:00,2023-03-25T17:56:24.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
+circleci:CircleciWorkflow:1:89054eb2-8e85-4f5c-9a93-66d753a0e970,say-hello-workflow,say-hello-workflow#3,,SUCCESS,DONE,success,,,5,,PRODUCTION,,2023-03-25T17:39:23.000+00:00,2023-03-25T17:39:23.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
+circleci:CircleciWorkflow:1:8971a56b-5547-4824-94dd-07bb467524c5,say-hello-workflow,say-hello-workflow#2,,SUCCESS,DONE,success,,,5,,PRODUCTION,,2023-03-25T17:12:18.000+00:00,2023-03-25T17:12:18.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
+circleci:CircleciWorkflow:1:8fe60291-68f7-40e2-acec-d99bff4da713,say-hello-workflow,say-hello-workflow#1,,SUCCESS,DONE,success,,,4,,PRODUCTION,,2023-03-25T17:12:18.000+00:00,2023-03-25T17:12:18.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
+circleci:CircleciWorkflow:1:b9ab7bbe-2f30-4c59-b4e2-eb2005bffb14,workflow,workflow#6,,FAILURE,DONE,failed,,,14,,PRODUCTION,,2023-03-25T17:54:09.000+00:00,2023-03-25T17:54:09.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
+circleci:CircleciWorkflow:1:c7df82a6-0d2b-4e19-a36a-3f3aa9fd3943,workflow,workflow#4,,FAILURE,DONE,failed,,,5,,PRODUCTION,,2023-03-25T17:50:20.000+00:00,2023-03-25T17:50:20.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
+circleci:CircleciWorkflow:1:fc76deef-bcdd-4856-8e96-a8e2d1c5a85f,workflow,workflow#8,,FAILURE,DONE,failed,,,15,,PRODUCTION,,2023-03-25T18:06:13.000+00:00,2023-03-25T18:06:13.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
+circleci:CircleciWorkflow:1:fd0bd4f5-264f-4e3c-a151-06153c018f78,workflow,workflow#9,,SUCCESS,DONE,success,,,17,,PRODUCTION,,2023-03-25T18:13:21.000+00:00,2023-03-25T18:13:21.000+00:00,circleci:CircleciProject:1:github/coldgust/coldgust.github.io
diff --git a/backend/plugins/circleci/e2e/workflow_test.go 
b/backend/plugins/circleci/e2e/workflow_test.go
index cc542fdb2..ba5194cea 100644
--- a/backend/plugins/circleci/e2e/workflow_test.go
+++ b/backend/plugins/circleci/e2e/workflow_test.go
@@ -72,7 +72,7 @@ func TestCircleciWorkflow(t *testing.T) {
                devops.CICDPipeline{},
                e2ehelper.TableOptions{
                        CSVRelPath:   "./snapshot_tables/cicd_pipelines.csv",
-                       IgnoreFields: []string{"finished_date", "created_date", 
"is_child"},
+                       IgnoreFields: []string{"finished_date", "is_child"},
                        IgnoreTypes:  []interface{}{domainlayer.DomainEntity{}},
                },
        )
diff --git a/backend/plugins/circleci/models/job.go 
b/backend/plugins/circleci/models/job.go
index bafaf5b9e..c8a3bea31 100644
--- a/backend/plugins/circleci/models/job.go
+++ b/backend/plugins/circleci/models/job.go
@@ -29,7 +29,7 @@ type CircleciJob struct {
        CanceledBy        string              `gorm:"type:varchar(100)" 
json:"canceled_by"`
        Dependencies      []string            `gorm:"serializer:json;type:text" 
json:"dependencies"`
        JobNumber         int64               `json:"job_number"`
-       CreatedAt         *common.Iso8601Time `json:"created_at"`
+       CreatedDate       *common.Iso8601Time `json:"created_at"`
        QueuedAt          *common.Iso8601Time `json:"queued_at"`
        StartedAt         *common.Iso8601Time `json:"started_at"`
        Name              string              `gorm:"type:varchar(255)" 
json:"name"`
diff --git 
a/backend/plugins/circleci/models/migrationscripts/20260322_rename_created_at_to_created_date.go
 
b/backend/plugins/circleci/models/migrationscripts/20260322_rename_created_at_to_created_date.go
new file mode 100644
index 000000000..497c0d3b5
--- /dev/null
+++ 
b/backend/plugins/circleci/models/migrationscripts/20260322_rename_created_at_to_created_date.go
@@ -0,0 +1,71 @@
+/*
+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 (
+       "time"
+
+       "github.com/apache/incubator-devlake/core/context"
+       "github.com/apache/incubator-devlake/core/errors"
+)
+
+type circleciWorkflow20260322 struct {
+       CreatedDate *time.Time
+}
+
+func (circleciWorkflow20260322) TableName() string {
+       return "_tool_circleci_workflows"
+}
+
+type circleciJob20260322 struct {
+       CreatedDate *time.Time
+}
+
+func (circleciJob20260322) TableName() string {
+       return "_tool_circleci_jobs"
+}
+
+type renameCreatedAtToCreatedDate20260322 struct{}
+
+func (*renameCreatedAtToCreatedDate20260322) Up(basicRes context.BasicRes) 
errors.Error {
+       db := basicRes.GetDal()
+
+       if err := db.AutoMigrate(&circleciWorkflow20260322{}); err != nil {
+               return err
+       }
+       if err := db.Exec("UPDATE _tool_circleci_workflows SET created_date = 
created_at WHERE created_date IS NULL"); err != nil {
+               return err
+       }
+
+       if err := db.AutoMigrate(&circleciJob20260322{}); err != nil {
+               return err
+       }
+       if err := db.Exec("UPDATE _tool_circleci_jobs SET created_date = 
created_at WHERE created_date IS NULL"); err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func (*renameCreatedAtToCreatedDate20260322) Version() uint64 {
+       return 20260322000001
+}
+
+func (*renameCreatedAtToCreatedDate20260322) Name() string {
+       return "circleci rename created_at to created_date in workflows and 
jobs"
+}
diff --git a/backend/plugins/circleci/models/migrationscripts/register.go 
b/backend/plugins/circleci/models/migrationscripts/register.go
index 5a23f27cc..af8472a3c 100644
--- a/backend/plugins/circleci/models/migrationscripts/register.go
+++ b/backend/plugins/circleci/models/migrationscripts/register.go
@@ -24,5 +24,6 @@ func All() []plugin.MigrationScript {
        return []plugin.MigrationScript{
                new(addInitTables),
                new(addFieldsToCircleciJob20231129),
+               new(renameCreatedAtToCreatedDate20260322),
        }
 }
diff --git a/backend/plugins/circleci/models/pipeline.go 
b/backend/plugins/circleci/models/pipeline.go
index a18cded10..a775ac4b2 100644
--- a/backend/plugins/circleci/models/pipeline.go
+++ b/backend/plugins/circleci/models/pipeline.go
@@ -49,8 +49,8 @@ type CircleciPipeline struct {
        ConnectionId      uint64              `gorm:"primaryKey;type:BIGINT" 
json:"connectionId" mapstructure:"connectionId"`
        Id                string              
`gorm:"primaryKey;type:varchar(100)" json:"id" mapstructure:"id"`
        ProjectSlug       string              `gorm:"type:varchar(255)" 
json:"projectSlug" mapstructure:"projectSlug"`
-       UpdatedDate       *common.Iso8601Time `json:"updatedDate" 
mapstructure:"updatedDate"`
-       CreatedDate       *common.Iso8601Time `json:"createdDate" 
mapstructure:"createdDate"`
+       UpdatedDate       *common.Iso8601Time `json:"updated_at"`
+       CreatedDate       *common.Iso8601Time `json:"created_at"`
        Number            int64               `json:"number" 
mapstructure:"number"` // pipeline number within the project?
        TriggerParameters any                 `gorm:"serializer:json" 
json:"trigger_parameters" mapstructure:"triggerParameters"`
        State             string              `gorm:"type:varchar(100)" 
json:"state" mapstructure:"state"`
diff --git a/backend/plugins/circleci/models/workflow.go 
b/backend/plugins/circleci/models/workflow.go
index f4e5e9f71..0b1a33028 100644
--- a/backend/plugins/circleci/models/workflow.go
+++ b/backend/plugins/circleci/models/workflow.go
@@ -33,7 +33,7 @@ type CircleciWorkflow struct {
        Status         string              `gorm:"type:varchar(100)" 
json:"status"`
        StartedBy      string              `gorm:"type:varchar(100)" 
json:"started_by"`
        PipelineNumber int64               `json:"pipeline_number"`
-       CreatedAt      *common.Iso8601Time `json:"created_at"`
+       CreatedDate    *common.Iso8601Time `json:"created_at"`
        StoppedAt      *common.Iso8601Time `json:"stopped_at"`
        DurationSec    float64             `json:"duration_sec"`
 
diff --git a/backend/plugins/circleci/tasks/job_converter.go 
b/backend/plugins/circleci/tasks/job_converter.go
index 2cb8de120..5a085609d 100644
--- a/backend/plugins/circleci/tasks/job_converter.go
+++ b/backend/plugins/circleci/tasks/job_converter.go
@@ -58,8 +58,8 @@ func ConvertJobs(taskCtx plugin.SubTaskContext) errors.Error {
                Convert: func(inputRow interface{}) ([]interface{}, 
errors.Error) {
                        userTool := inputRow.(*models.CircleciJob)
                        createdAt := time.Now()
-                       if userTool.CreatedAt != nil {
-                               createdAt = userTool.CreatedAt.ToTime()
+                       if userTool.CreatedDate != nil {
+                               createdAt = userTool.CreatedDate.ToTime()
                        }
                        task := &devops.CICDTask{
                                DomainEntity: domainlayer.DomainEntity{
diff --git a/backend/plugins/circleci/tasks/workflow_converter.go 
b/backend/plugins/circleci/tasks/workflow_converter.go
index a023accc7..bf6b029e3 100644
--- a/backend/plugins/circleci/tasks/workflow_converter.go
+++ b/backend/plugins/circleci/tasks/workflow_converter.go
@@ -61,11 +61,11 @@ func ConvertWorkflows(taskCtx plugin.SubTaskContext) 
errors.Error {
                Convert: func(inputRow interface{}) ([]interface{}, 
errors.Error) {
                        userTool := inputRow.(*models.CircleciWorkflow)
                        // Skip if CreatedAt is null or empty string - still 
enters into the `_tool_circleci_workflows` table with null values
-                       if userTool.CreatedAt.ToNullableTime() == nil {
-                               logger.Info("CreatedAt is null or empty string 
in the CircleCI API response for %s", userTool.PipelineId)
+                       if userTool.CreatedDate.ToNullableTime() == nil {
+                               logger.Info("CreatedDate is null or empty 
string in the CircleCI API response for %s", userTool.PipelineId)
                                return []interface{}{}, nil
                        }
-                       createdAt := userTool.CreatedAt.ToTime()
+                       createdAt := userTool.CreatedDate.ToTime()
                        pipeline := &devops.CICDPipeline{
                                DomainEntity: domainlayer.DomainEntity{
                                        Id: 
getWorkflowIdGen().Generate(data.Options.ConnectionId, userTool.Id),
diff --git a/backend/plugins/circleci/tasks/workflow_extractor.go 
b/backend/plugins/circleci/tasks/workflow_extractor.go
index ba0639bc8..165c6d635 100644
--- a/backend/plugins/circleci/tasks/workflow_extractor.go
+++ b/backend/plugins/circleci/tasks/workflow_extractor.go
@@ -48,8 +48,8 @@ func ExtractWorkflows(taskCtx plugin.SubTaskContext) 
errors.Error {
                        toolL := userRes
                        toolL.ConnectionId = data.Options.ConnectionId
                        toolL.ProjectSlug = data.Options.ProjectSlug
-                       if userRes.CreatedAt != nil && userRes.StoppedAt != nil 
{
-                               startTime := userRes.CreatedAt.ToTime()
+                       if userRes.CreatedDate != nil && userRes.StoppedAt != 
nil {
+                               startTime := userRes.CreatedDate.ToTime()
                                endTime := userRes.StoppedAt.ToTime()
                                toolL.DurationSec = 
float64(endTime.Sub(startTime).Milliseconds() / 1e3)
                        }

Reply via email to