This is an automated email from the ASF dual-hosted git repository.

warren 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 46fbd483 feat: add check_run collector in github graphql (#3705)
46fbd483 is described below

commit 46fbd48397ce4feef84ec34252e021c461bb1183
Author: Likyh <[email protected]>
AuthorDate: Thu Nov 10 14:43:50 2022 +0800

    feat: add check_run collector in github graphql (#3705)
    
    * feat: add check_run collector in github graphql
    
    * fix: fix for review
---
 plugins/github_graphql/plugin_main.go              |  12 ++
 .../github_graphql/tasks/check_run_collector.go    | 192 +++++++++++++++++++++
 2 files changed, 204 insertions(+)

diff --git a/plugins/github_graphql/plugin_main.go 
b/plugins/github_graphql/plugin_main.go
index a5c4bb2b..ddce4e94 100644
--- a/plugins/github_graphql/plugin_main.go
+++ b/plugins/github_graphql/plugin_main.go
@@ -42,6 +42,7 @@ var _ core.PluginMeta = (*GithubGraphql)(nil)
 var _ core.PluginInit = (*GithubGraphql)(nil)
 var _ core.PluginTask = (*GithubGraphql)(nil)
 var _ core.PluginApi = (*GithubGraphql)(nil)
+var _ core.CloseablePluginTask = (*GithubGraphql)(nil)
 
 // PluginEntry exports a symbol for Framework to load
 var PluginEntry GithubGraphql //nolint
@@ -60,12 +61,20 @@ func (plugin GithubGraphql) SubTaskMetas() 
[]core.SubTaskMeta {
        return []core.SubTaskMeta{
                tasks.CollectRepoMeta,
 
+               // collect millstones
                githubTasks.CollectMilestonesMeta,
                githubTasks.ExtractMilestonesMeta,
 
+               // collect issue & pr, deps on millstone
                tasks.CollectIssueMeta,
                tasks.CollectPrMeta,
 
+               // collect workflow run & job
+               githubTasks.CollectRunsMeta,
+               githubTasks.ExtractRunsMeta,
+               tasks.CollectCheckRunMeta,
+
+               // collect others
                githubTasks.CollectApiCommentsMeta,
                githubTasks.ExtractApiCommentsMeta,
                githubTasks.CollectApiEventsMeta,
@@ -73,8 +82,11 @@ func (plugin GithubGraphql) SubTaskMetas() 
[]core.SubTaskMeta {
                githubTasks.CollectApiPrReviewCommentsMeta,
                githubTasks.ExtractApiPrReviewCommentsMeta,
 
+               // collect account, deps on all before
                tasks.CollectAccountMeta,
 
+               // convert to domain layer
+               githubTasks.ConvertRunsMeta,
                githubTasks.ConvertJobsMeta,
                githubTasks.EnrichPullRequestIssuesMeta,
                githubTasks.ConvertRepoMeta,
diff --git a/plugins/github_graphql/tasks/check_run_collector.go 
b/plugins/github_graphql/tasks/check_run_collector.go
new file mode 100644
index 00000000..85ec1af3
--- /dev/null
+++ b/plugins/github_graphql/tasks/check_run_collector.go
@@ -0,0 +1,192 @@
+/*
+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 tasks
+
+import (
+       "encoding/json"
+       "github.com/apache/incubator-devlake/errors"
+       "github.com/apache/incubator-devlake/plugins/core"
+       "github.com/apache/incubator-devlake/plugins/core/dal"
+       "github.com/apache/incubator-devlake/plugins/github/models"
+       githubTasks "github.com/apache/incubator-devlake/plugins/github/tasks"
+       "github.com/apache/incubator-devlake/plugins/helper"
+       "github.com/merico-dev/graphql"
+       "reflect"
+       "time"
+)
+
+const RAW_CHECK_RUNS_TABLE = "github_graphql_check_runs"
+
+type GraphqlQueryCheckRunWrapper struct {
+       RateLimit struct {
+               Cost int
+       }
+       Node []GraphqlQueryCheckSuite `graphql:"node(id: $id)" 
graphql-extend:"true"`
+}
+
+type GraphqlQueryCheckSuite struct {
+       Id         string
+       Typename   string `graphql:"__typename"`
+       CheckSuite struct {
+               WorkflowRun struct {
+                       DatabaseId int
+               }
+               CheckRuns struct {
+                       TotalCount int
+                       Nodes      []struct {
+                               Id          string
+                               Name        string
+                               DetailsUrl  string
+                               DatabaseId  int
+                               Status      string
+                               StartedAt   *time.Time
+                               Conclusion  string
+                               CompletedAt *time.Time
+                               //ExternalId   string
+                               //Url          string
+                               //Title        interface{}
+                               //Text         interface{}
+                               //Summary      interface{}
+
+                               Steps struct {
+                                       TotalCount int
+                                       Nodes      []struct {
+                                               CompletedAt         *time.Time 
`json:"completed_at"`
+                                               Conclusion          string     
`json:"conclusion"`
+                                               Name                string     
`json:"name"`
+                                               Number              int        
`json:"number"`
+                                               SecondsToCompletion int        
`json:"seconds_to_completion"`
+                                               StartedAt           *time.Time 
`json:"started_at"`
+                                               Status              string     
`json:"status"`
+                                       }
+                               } `graphql:"steps(first: 50)"`
+                       }
+               } `graphql:"checkRuns(first: 50)"`
+       } `graphql:"... on CheckSuite"`
+}
+
+type SimpleWorkflowRun struct {
+       CheckSuiteNodeID string
+}
+
+var CollectCheckRunMeta = core.SubTaskMeta{
+       Name:             "CollectCheckRun",
+       EntryPoint:       CollectCheckRun,
+       EnabledByDefault: true,
+       Description:      "Collect CheckRun data from GithubGraphql api",
+}
+
+var _ core.SubTaskEntryPoint = CollectAccount
+
+func CollectCheckRun(taskCtx core.SubTaskContext) errors.Error {
+       logger := taskCtx.GetLogger()
+       db := taskCtx.GetDal()
+       data := taskCtx.GetData().(*githubTasks.GithubTaskData)
+
+       cursor, err := db.Cursor(
+               dal.Select("check_suite_node_id"),
+               dal.From(models.GithubRun{}.TableName()),
+               dal.Where("repo_id = ? and connection_id=?", 
data.Repo.GithubId, data.Options.ConnectionId),
+       )
+       if err != nil {
+               return err
+       }
+       iterator, err := helper.NewDalCursorIterator(db, cursor, 
reflect.TypeOf(SimpleWorkflowRun{}))
+       if err != nil {
+               return err
+       }
+
+       collector, err := 
helper.NewGraphqlCollector(helper.GraphqlCollectorArgs{
+               RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
+                       Ctx: taskCtx,
+                       Params: githubTasks.GithubApiParams{
+                               ConnectionId: data.Options.ConnectionId,
+                               Owner:        data.Options.Owner,
+                               Repo:         data.Options.Repo,
+                       },
+                       Table: RAW_CHECK_RUNS_TABLE,
+               },
+               Input:         iterator,
+               InputStep:     60,
+               GraphqlClient: data.GraphqlClient,
+               BuildQuery: func(reqData *helper.GraphqlRequestData) 
(interface{}, map[string]interface{}, error) {
+                       workflowRuns := reqData.Input.([]interface{})
+                       query := &GraphqlQueryCheckRunWrapper{}
+                       checkSuiteIds := []map[string]interface{}{}
+                       for _, iWorkflowRuns := range workflowRuns {
+                               workflowRun := 
iWorkflowRuns.(*SimpleWorkflowRun)
+                               checkSuiteIds = append(checkSuiteIds, 
map[string]interface{}{
+                                       `id`: 
graphql.ID(workflowRun.CheckSuiteNodeID),
+                               })
+                       }
+                       variables := map[string]interface{}{
+                               "node": checkSuiteIds,
+                       }
+                       return query, variables, nil
+               },
+               ResponseParserWithDataErrors: func(iQuery interface{}, 
variables map[string]interface{}, dataErrors []graphql.DataError) 
([]interface{}, error) {
+                       for _, dataError := range dataErrors {
+                               // log and ignore
+                               taskCtx.GetLogger().Warn(dataError, `query 
check run get error but ignore`)
+                       }
+                       query := iQuery.(*GraphqlQueryCheckRunWrapper)
+                       nodes := query.Node
+
+                       results := make([]interface{}, 0, 1)
+                       for _, node := range nodes {
+                               for _, checkRun := range 
node.CheckSuite.CheckRuns.Nodes {
+
+                                       paramsBytes, err := 
json.Marshal(checkRun.Steps.Nodes)
+                                       if err != nil {
+                                               logger.Error(err, `Marshal 
checkRun.Steps.Nodes fail and ignore`)
+                                       }
+                                       githubJob := &models.GithubJob{
+                                               ConnectionId: 
data.Options.ConnectionId,
+                                               RunID:        
node.CheckSuite.WorkflowRun.DatabaseId,
+                                               RepoId:       
data.Repo.GithubId,
+                                               ID:           
checkRun.DatabaseId,
+                                               NodeID:       checkRun.Id,
+                                               HTMLURL:      
checkRun.DetailsUrl,
+                                               Status:       checkRun.Status,
+                                               Conclusion:   
checkRun.Conclusion,
+                                               StartedAt:    
checkRun.StartedAt,
+                                               CompletedAt:  
checkRun.CompletedAt,
+                                               Name:         checkRun.Name,
+                                               Steps:        paramsBytes,
+                                               // these columns can not fill 
by graphql
+                                               //HeadSha:       ``,  // use 
_tool_github_runs
+                                               //RunURL:        ``,
+                                               //CheckRunURL:   ``,
+                                               //Labels:        ``, // not on 
use
+                                               //RunnerID:      ``, // not on 
use
+                                               //RunnerName:    ``, // not on 
use
+                                               //RunnerGroupID: ``, // not on 
use
+                                       }
+                                       results = append(results, githubJob)
+                               }
+                       }
+                       return results, nil
+               },
+       })
+
+       if err != nil {
+               return err
+       }
+
+       return collector.Execute()
+}

Reply via email to