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 edd3510c7 feat: github support scope and transformation rule (#3803)
edd3510c7 is described below
commit edd3510c78216ef83dafe49e24b4b292221706cd
Author: mindlesscloud <[email protected]>
AuthorDate: Tue Nov 29 17:44:20 2022 +0800
feat: github support scope and transformation rule (#3803)
* feat: github support scope and transformation rule
* fix: fix e2e test
* fix: implement core.PluginSource
* feat: pagenation support add refdiff_rule to
_tool_github_transformation_rules
* fix: remove scopeId from _tool_jira_boards
---
plugins/github/api/scope.go | 164 +++++++++++++++++++++
plugins/github/api/transformation_rule.go | 128 ++++++++++++++++
.../migrationscripts/register.go => api/utils.go} | 37 +++--
plugins/github/e2e/cicd_test.go | 7 +-
plugins/github/e2e/comment_test.go | 7 +-
plugins/github/e2e/issue_test.go | 7 +-
plugins/github/e2e/milestone_test.go | 2 +-
plugins/github/e2e/pr_enrich_issue_test.go | 6 +-
plugins/github/e2e/pr_test.go | 7 +-
plugins/github/e2e/repo_test.go | 11 +-
plugins/github/impl/impl.go | 45 +++++-
plugins/github/models/connection.go | 13 --
.../20221124_add_trasformation_rule_table.go} | 23 ++-
.../archived/transformation_rules.go | 43 ++++++
plugins/github/models/migrationscripts/register.go | 1 +
plugins/github/models/repo.go | 25 ++--
plugins/github/models/transformation_rule.go | 43 ++++++
plugins/github/tasks/issue_extractor.go | 2 +-
plugins/github/tasks/repo_extractor.go | 1 -
plugins/github/tasks/task_data.go | 47 ++----
plugins/jira/api/scope.go | 3 -
plugins/jira/impl/impl.go | 3 +
plugins/jira/models/board.go | 1 -
.../20221116_add_trasformation_rule_table.go | 1 -
.../archived/transformation_rules.go | 4 +
plugins/jira/models/transformation_rules.go | 4 +
26 files changed, 516 insertions(+), 119 deletions(-)
diff --git a/plugins/github/api/scope.go b/plugins/github/api/scope.go
new file mode 100644
index 000000000..0bafb01a9
--- /dev/null
+++ b/plugins/github/api/scope.go
@@ -0,0 +1,164 @@
+/*
+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 api
+
+import (
+ "net/http"
+ "strconv"
+
+ "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"
+ "github.com/apache/incubator-devlake/plugins/helper"
+ "github.com/mitchellh/mapstructure"
+)
+
+// PutScope create or update github repo
+// @Summary create or update github repo
+// @Description Create or update github repo
+// @Tags plugins/github
+// @Accept application/json
+// @Param connectionId path int true "connection ID"
+// @Param repoId path int true "repo ID"
+// @Param scope body models.GithubRepo true "json"
+// @Success 200 {object} models.GithubRepo
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Router /plugins/github/connections/{connectionId}/scopes/{repoId} [PUT]
+func PutScope(input *core.ApiResourceInput) (*core.ApiResourceOutput,
errors.Error) {
+ connectionId, repoId := extractParam(input.Params)
+ if connectionId*repoId == 0 {
+ return nil, errors.BadInput.New("invalid connectionId or
repoId")
+ }
+ var repo models.GithubRepo
+ err := errors.Convert(mapstructure.Decode(input.Body, &repo))
+ if err != nil {
+ return nil, errors.BadInput.Wrap(err, "decoding Github repo
error")
+ }
+ err = verifyRepo(&repo)
+ if err != nil {
+ return nil, err
+ }
+ err = basicRes.GetDal().CreateOrUpdate(repo)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error on saving
GithubRepo")
+ }
+ return &core.ApiResourceOutput{Body: repo, Status: http.StatusOK}, nil
+}
+
+// UpdateScope patch to github repo
+// @Summary patch to github repo
+// @Description patch to github repo
+// @Tags plugins/github
+// @Accept application/json
+// @Param connectionId path int true "connection ID"
+// @Param repoId path int true "repo ID"
+// @Param scope body models.GithubRepo true "json"
+// @Success 200 {object} models.GithubRepo
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Router /plugins/github/connections/{connectionId}/scopes/{repoId} [PATCH]
+func UpdateScope(input *core.ApiResourceInput) (*core.ApiResourceOutput,
errors.Error) {
+ connectionId, repoId := extractParam(input.Params)
+ if connectionId*repoId == 0 {
+ return nil, errors.BadInput.New("invalid connectionId or
repoId")
+ }
+ var repo models.GithubRepo
+ err := basicRes.GetDal().First(&repo, dal.Where("connection_id = ? AND
github_id = ?", connectionId, repoId))
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "getting GithubRepo error")
+ }
+ err = helper.DecodeMapStruct(input.Body, &repo)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "patch github repo error")
+ }
+ err = verifyRepo(&repo)
+ if err != nil {
+ return nil, err
+ }
+ err = basicRes.GetDal().Update(repo)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error on saving
GithubRepo")
+ }
+ return &core.ApiResourceOutput{Body: repo, Status: http.StatusOK}, nil
+}
+
+// GetScopeList get Github repos
+// @Summary get Github repos
+// @Description get Github repos
+// @Tags plugins/github
+// @Param connectionId path int true "connection ID"
+// @Param pageSize query int false "page size, default 50"
+// @Param page query int false "page size, default 1"
+// @Success 200 {object} []models.GithubRepo
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Router /plugins/github/connections/{connectionId}/scopes/ [GET]
+func GetScopeList(input *core.ApiResourceInput) (*core.ApiResourceOutput,
errors.Error) {
+ var repos []models.GithubRepo
+ connectionId, _ := extractParam(input.Params)
+ if connectionId == 0 {
+ return nil, errors.BadInput.New("invalid path params")
+ }
+ limit, offset := getLimitOffset(input.Query)
+ err := basicRes.GetDal().All(&repos, dal.Where("connection_id = ?",
connectionId), dal.Limit(limit), dal.Offset(offset))
+ if err != nil {
+ return nil, err
+ }
+ return &core.ApiResourceOutput{Body: repos, Status: http.StatusOK}, nil
+}
+
+// GetScope get one Github repo
+// @Summary get one Github repo
+// @Description get one Github repo
+// @Tags plugins/github
+// @Param connectionId path int true "connection ID"
+// @Param repoId path int true "repo ID"
+// @Success 200 {object} models.GithubRepo
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Router /plugins/github/connections/{connectionId}/scopes/{repoId} [GET]
+func GetScope(input *core.ApiResourceInput) (*core.ApiResourceOutput,
errors.Error) {
+ var repo models.GithubRepo
+ connectionId, repoId := extractParam(input.Params)
+ if connectionId*repoId == 0 {
+ return nil, errors.BadInput.New("invalid path params")
+ }
+ err := basicRes.GetDal().First(&repo, dal.Where("connection_id = ? AND
github_id = ?", connectionId, repoId))
+ if err != nil {
+ return nil, err
+ }
+ return &core.ApiResourceOutput{Body: repo, Status: http.StatusOK}, nil
+}
+
+func extractParam(params map[string]string) (uint64, uint64) {
+ connectionId, _ := strconv.ParseUint(params["connectionId"], 10, 64)
+ repoId, _ := strconv.ParseUint(params["repoId"], 10, 64)
+ return connectionId, repoId
+}
+
+func verifyRepo(repo *models.GithubRepo) errors.Error {
+ if repo.ConnectionId == 0 {
+ return errors.BadInput.New("invalid connectionId")
+ }
+ if repo.GithubId <= 0 {
+ return errors.BadInput.New("invalid github ID")
+ }
+ return nil
+}
diff --git a/plugins/github/api/transformation_rule.go
b/plugins/github/api/transformation_rule.go
new file mode 100644
index 000000000..f027be902
--- /dev/null
+++ b/plugins/github/api/transformation_rule.go
@@ -0,0 +1,128 @@
+/*
+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 api
+
+import (
+ "net/http"
+ "strconv"
+
+ "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"
+ "github.com/apache/incubator-devlake/plugins/helper"
+ "github.com/mitchellh/mapstructure"
+)
+
+// CreateTransformationRule create transformation rule for Github
+// @Summary create transformation rule for Github
+// @Description create transformation rule for Github
+// @Tags plugins/github
+// @Accept application/json
+// @Param transformationRule body models.TransformationRules true
"transformation rule"
+// @Success 200 {object} models.TransformationRules
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Router /plugins/github/transformation_rules [POST]
+func CreateTransformationRule(input *core.ApiResourceInput)
(*core.ApiResourceOutput, errors.Error) {
+ var rule models.TransformationRules
+ err := mapstructure.Decode(input.Body, &rule)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error in decoding
transformation rule")
+ }
+ err = basicRes.GetDal().Create(&rule)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error on saving
TransformationRule")
+ }
+ return &core.ApiResourceOutput{Body: rule, Status: http.StatusOK}, nil
+}
+
+// UpdateTransformationRule update transformation rule for Github
+// @Summary update transformation rule for Github
+// @Description update transformation rule for Github
+// @Tags plugins/github
+// @Accept application/json
+// @Param id path int true "id"
+// @Param transformationRule body models.TransformationRules true
"transformation rule"
+// @Success 200 {object} models.TransformationRules
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Router /plugins/github/transformation_rules/{id} [PATCH]
+func UpdateTransformationRule(input *core.ApiResourceInput)
(*core.ApiResourceOutput, errors.Error) {
+ transformationRuleId, err := strconv.ParseUint(input.Params["id"], 10,
64)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "the transformation rule
ID should be an integer")
+ }
+ var old models.TransformationRules
+ err = basicRes.GetDal().First(&old, dal.Where("id = ?",
transformationRuleId))
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error on saving
TransformationRule")
+ }
+ err = helper.DecodeMapStruct(input.Body, &old)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error decoding map into
transformationRule")
+ }
+ old.ID = transformationRuleId
+ err = basicRes.GetDal().Update(&old, dal.Where("id = ?",
transformationRuleId))
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error on saving
TransformationRule")
+ }
+ return &core.ApiResourceOutput{Body: old, Status: http.StatusOK}, nil
+}
+
+// GetTransformationRule return one transformation rule
+// @Summary return one transformation rule
+// @Description return one transformation rule
+// @Tags plugins/github
+// @Param id path int true "id"
+// @Success 200 {object} models.TransformationRules
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Router /plugins/github/transformation_rules/{id} [GET]
+func GetTransformationRule(input *core.ApiResourceInput)
(*core.ApiResourceOutput, errors.Error) {
+ transformationRuleId, err := strconv.ParseUint(input.Params["id"], 10,
64)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "the transformation rule
ID should be an integer")
+ }
+ var rule models.TransformationRules
+ err = basicRes.GetDal().First(&rule, dal.Where("id = ?",
transformationRuleId))
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error on get
TransformationRule")
+ }
+ return &core.ApiResourceOutput{Body: rule, Status: http.StatusOK}, nil
+}
+
+// GetTransformationRuleList return all transformation rules
+// @Summary return all transformation rules
+// @Description return all transformation rules
+// @Tags plugins/github
+// @Param pageSize query int false "page size, default 50"
+// @Param page query int false "page size, default 1"
+// @Success 200 {object} []models.TransformationRules
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Router /plugins/github/transformation_rules [GET]
+func GetTransformationRuleList(input *core.ApiResourceInput)
(*core.ApiResourceOutput, errors.Error) {
+ var rules []models.TransformationRules
+ limit, offset := getLimitOffset(input.Query)
+ err := basicRes.GetDal().All(&rules, dal.Limit(limit),
dal.Offset(offset))
+ if err != nil {
+ return nil, errors.Default.Wrap(err, "error on get
TransformationRule list")
+ }
+ return &core.ApiResourceOutput{Body: rules, Status: http.StatusOK}, nil
+}
diff --git a/plugins/github/models/migrationscripts/register.go
b/plugins/github/api/utils.go
similarity index 62%
copy from plugins/github/models/migrationscripts/register.go
copy to plugins/github/api/utils.go
index 9378bf9dd..5a4682b8e 100644
--- a/plugins/github/models/migrationscripts/register.go
+++ b/plugins/github/api/utils.go
@@ -15,21 +15,34 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-package migrationscripts
+package api
import (
- "github.com/apache/incubator-devlake/plugins/core"
+ "net/url"
+ "strconv"
)
-// All return all the migration scripts
-func All() []core.MigrationScript {
- return []core.MigrationScript{
- new(addInitTables),
- new(addGithubRunsTable),
- new(addGithubJobsTable),
- new(addGithubPipelineTable),
- new(deleteGithubPipelineTable),
- new(addHeadRepoIdFieldInGithubPr),
- new(addEnableGraphqlForConnection),
+const pageSize = 50
+
+func getPageParam(q url.Values) (int, int) {
+ var size, page int
+ if ps := q["pageSize"]; len(ps) > 0 {
+ size, _ = strconv.Atoi(ps[0])
+ }
+ if p := q["page"]; len(p) > 0 {
+ page, _ = strconv.Atoi(p[0])
+ }
+ if size < 1 {
+ size = pageSize
}
+ if page < 1 {
+ page = 1
+ }
+ return size, page
+}
+
+func getLimitOffset(q url.Values) (int, int) {
+ limit, page := getPageParam(q)
+ offset := (page - 1) * limit
+ return limit, offset
}
diff --git a/plugins/github/e2e/cicd_test.go b/plugins/github/e2e/cicd_test.go
index 4890aed00..2ac4748fe 100644
--- a/plugins/github/e2e/cicd_test.go
+++ b/plugins/github/e2e/cicd_test.go
@@ -34,9 +34,10 @@ func TestGithubCICDDataFlow(t *testing.T) {
taskData := &tasks.GithubTaskData{
Options: &tasks.GithubOptions{
- ConnectionId: 1,
- Owner: "panjf2000",
- Repo: "ants",
+ ConnectionId: 1,
+ Owner: "panjf2000",
+ Repo: "ants",
+ TransformationRules: new(models.TransformationRules),
},
Repo: &models.GithubRepo{
GithubId: 134018330,
diff --git a/plugins/github/e2e/comment_test.go
b/plugins/github/e2e/comment_test.go
index de87f90b2..3d7d8d029 100644
--- a/plugins/github/e2e/comment_test.go
+++ b/plugins/github/e2e/comment_test.go
@@ -20,13 +20,12 @@ package e2e
import (
"testing"
+ "github.com/apache/incubator-devlake/helpers/e2ehelper"
"github.com/apache/incubator-devlake/models/domainlayer/code"
"github.com/apache/incubator-devlake/models/domainlayer/ticket"
+ "github.com/apache/incubator-devlake/plugins/github/impl"
"github.com/apache/incubator-devlake/plugins/github/models"
"github.com/apache/incubator-devlake/plugins/github/tasks"
-
- "github.com/apache/incubator-devlake/helpers/e2ehelper"
- "github.com/apache/incubator-devlake/plugins/github/impl"
)
func TestCommentDataFlow(t *testing.T) {
@@ -41,7 +40,7 @@ func TestCommentDataFlow(t *testing.T) {
ConnectionId: 1,
Owner: "panjf2000",
Repo: "ants",
- TransformationRules: models.TransformationRules{
+ TransformationRules: &models.TransformationRules{
PrType: "type/(.*)$",
PrComponent: "component/(.*)$",
PrBodyClosePattern:
"(?mi)(fix|close|resolve|fixes|closes|resolves|fixed|closed|resolved)[\\s]*.*(((and
)?(#|https:\\/\\/github.com\\/%s\\/%s\\/issues\\/)\\d+[ ]*)+)",
diff --git a/plugins/github/e2e/issue_test.go b/plugins/github/e2e/issue_test.go
index 794ec946b..7706dfb66 100644
--- a/plugins/github/e2e/issue_test.go
+++ b/plugins/github/e2e/issue_test.go
@@ -20,11 +20,10 @@ package e2e
import (
"testing"
- "github.com/apache/incubator-devlake/models/domainlayer/ticket"
- "github.com/apache/incubator-devlake/plugins/github/models"
-
"github.com/apache/incubator-devlake/helpers/e2ehelper"
+ "github.com/apache/incubator-devlake/models/domainlayer/ticket"
"github.com/apache/incubator-devlake/plugins/github/impl"
+ "github.com/apache/incubator-devlake/plugins/github/models"
"github.com/apache/incubator-devlake/plugins/github/tasks"
)
@@ -40,7 +39,7 @@ func TestIssueDataFlow(t *testing.T) {
ConnectionId: 1,
Owner: "panjf2000",
Repo: "ants",
- TransformationRules: models.TransformationRules{
+ TransformationRules: &models.TransformationRules{
PrType: "type/(.*)$",
PrComponent: "component/(.*)$",
PrBodyClosePattern:
"(?mi)(fix|close|resolve|fixes|closes|resolves|fixed|closed|resolved)[\\s]*.*(((and
)?(#|https:\\/\\/github.com\\/%s\\/%s\\/issues\\/)\\d+[ ]*)+)",
diff --git a/plugins/github/e2e/milestone_test.go
b/plugins/github/e2e/milestone_test.go
index 4384c0ce6..b6b6153f6 100644
--- a/plugins/github/e2e/milestone_test.go
+++ b/plugins/github/e2e/milestone_test.go
@@ -44,7 +44,7 @@ func TestMilestoneDataFlow(t *testing.T) {
ConnectionId: 1,
Owner: "panjf2000",
Repo: "ants",
- TransformationRules: models.TransformationRules{
+ TransformationRules: &models.TransformationRules{
PrType: "type/(.*)$",
PrComponent: "component/(.*)$",
PrBodyClosePattern:
"(?mi)(fix|close|resolve|fixes|closes|resolves|fixed|closed|resolved)[\\s]*.*(((and
)?(#|https:\\/\\/github.com\\/%s\\/%s\\/issues\\/)\\d+[ ]*)+)",
diff --git a/plugins/github/e2e/pr_enrich_issue_test.go
b/plugins/github/e2e/pr_enrich_issue_test.go
index b5b6458cf..7a06e3ec4 100644
--- a/plugins/github/e2e/pr_enrich_issue_test.go
+++ b/plugins/github/e2e/pr_enrich_issue_test.go
@@ -18,12 +18,12 @@ limitations under the License.
package e2e
import (
- "github.com/apache/incubator-devlake/models/domainlayer/crossdomain"
- "github.com/apache/incubator-devlake/plugins/github/models"
"testing"
"github.com/apache/incubator-devlake/helpers/e2ehelper"
+ "github.com/apache/incubator-devlake/models/domainlayer/crossdomain"
"github.com/apache/incubator-devlake/plugins/github/impl"
+ "github.com/apache/incubator-devlake/plugins/github/models"
"github.com/apache/incubator-devlake/plugins/github/tasks"
)
@@ -39,7 +39,7 @@ func TestPrEnrichIssueDataFlow(t *testing.T) {
ConnectionId: 1,
Owner: "panjf2000",
Repo: "ants",
- TransformationRules: models.TransformationRules{
+ TransformationRules: &models.TransformationRules{
PrType: "type/(.*)$",
PrComponent: "component/(.*)$",
PrBodyClosePattern:
"(?mi)(fix|close|resolve|fixes|closes|resolves|fixed|closed|resolved)[\\s]*.*(((and
)?(#|https:\\/\\/github.com\\/%s\\/%s\\/issues\\/)\\d+[ ]*)+)",
diff --git a/plugins/github/e2e/pr_test.go b/plugins/github/e2e/pr_test.go
index 2c7bd82df..c06dce8f2 100644
--- a/plugins/github/e2e/pr_test.go
+++ b/plugins/github/e2e/pr_test.go
@@ -20,11 +20,10 @@ package e2e
import (
"testing"
- "github.com/apache/incubator-devlake/models/domainlayer/code"
- "github.com/apache/incubator-devlake/plugins/github/models"
-
"github.com/apache/incubator-devlake/helpers/e2ehelper"
+ "github.com/apache/incubator-devlake/models/domainlayer/code"
"github.com/apache/incubator-devlake/plugins/github/impl"
+ "github.com/apache/incubator-devlake/plugins/github/models"
"github.com/apache/incubator-devlake/plugins/github/tasks"
)
@@ -40,7 +39,7 @@ func TestPrDataFlow(t *testing.T) {
ConnectionId: 1,
Owner: "panjf2000",
Repo: "ants",
- TransformationRules: models.TransformationRules{
+ TransformationRules: &models.TransformationRules{
PrType: "type/(.*)$",
PrComponent: "component/(.*)$",
PrBodyClosePattern:
"(?mi)(fix|close|resolve|fixes|closes|resolves|fixed|closed|resolved)[\\s]*.*(((and
)?(#|https:\\/\\/github.com\\/%s\\/%s\\/issues\\/)\\d+[ ]*)+)",
diff --git a/plugins/github/e2e/repo_test.go b/plugins/github/e2e/repo_test.go
index ee35282fd..1e33e1912 100644
--- a/plugins/github/e2e/repo_test.go
+++ b/plugins/github/e2e/repo_test.go
@@ -18,17 +18,16 @@ limitations under the License.
package e2e
import (
- "github.com/apache/incubator-devlake/models/common"
- "github.com/apache/incubator-devlake/models/domainlayer/devops"
"testing"
+ "github.com/apache/incubator-devlake/helpers/e2ehelper"
+ "github.com/apache/incubator-devlake/models/common"
"github.com/apache/incubator-devlake/models/domainlayer/code"
"github.com/apache/incubator-devlake/models/domainlayer/crossdomain"
+ "github.com/apache/incubator-devlake/models/domainlayer/devops"
"github.com/apache/incubator-devlake/models/domainlayer/ticket"
- "github.com/apache/incubator-devlake/plugins/github/models"
-
- "github.com/apache/incubator-devlake/helpers/e2ehelper"
"github.com/apache/incubator-devlake/plugins/github/impl"
+ "github.com/apache/incubator-devlake/plugins/github/models"
"github.com/apache/incubator-devlake/plugins/github/tasks"
)
@@ -44,7 +43,7 @@ func TestRepoDataFlow(t *testing.T) {
ConnectionId: 1,
Owner: "panjf2000",
Repo: "ants",
- TransformationRules: models.TransformationRules{
+ TransformationRules: &models.TransformationRules{
PrType: "type/(.*)$",
PrComponent: "component/(.*)$",
},
diff --git a/plugins/github/impl/impl.go b/plugins/github/impl/impl.go
index 84ef2151b..e8281794d 100644
--- a/plugins/github/impl/impl.go
+++ b/plugins/github/impl/impl.go
@@ -23,6 +23,7 @@ import (
"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/api"
"github.com/apache/incubator-devlake/plugins/github/models"
"github.com/apache/incubator-devlake/plugins/github/models/migrationscripts"
@@ -39,9 +40,22 @@ var _ core.PluginApi = (*Github)(nil)
var _ core.PluginModel = (*Github)(nil)
var _ core.PluginBlueprintV100 = (*Github)(nil)
var _ core.CloseablePluginTask = (*Github)(nil)
+var _ core.PluginSource = (*Github)(nil)
type Github struct{}
+func (plugin Github) Connection() interface{} {
+ return &models.GithubConnection{}
+}
+
+func (plugin Github) Scope() interface{} {
+ return &models.GithubRepo{}
+}
+
+func (plugin Github) TransformationRule() interface{} {
+ return &models.TransformationRules{}
+}
+
func (plugin Github) Init(config *viper.Viper, logger core.Logger, db
*gorm.DB) errors.Error {
api.Init(config, logger, db)
return nil
@@ -153,7 +167,19 @@ func (plugin Github) PrepareTaskData(taskCtx
core.TaskContext, options map[strin
return nil, errors.BadInput.Wrap(err, "invalid value
for `since`")
}
}
-
+ if op.TransformationRules == nil && op.TransformationRuleId != 0 {
+ var transformationRule models.TransformationRules
+ err = taskCtx.GetDal().First(&transformationRule, dal.Where("id
= ?", op.TransformationRuleId))
+ if err != nil {
+ return nil, errors.BadInput.Wrap(err, "fail to get
transformationRule")
+ }
+ op.TransformationRules = &transformationRule
+ }
+ var repo models.GithubRepo
+ err = taskCtx.GetDal().First(&repo, dal.Where("name = ? AND owner_login
= ", op.Repo, op.Owner))
+ if err != nil {
+ return nil, errors.BadInput.Wrap(err, "fail to get repo")
+ }
apiClient, err := tasks.CreateApiClient(taskCtx, connection)
if err != nil {
return nil, errors.Default.Wrap(err, "unable to get github API
client instance")
@@ -161,6 +187,7 @@ func (plugin Github) PrepareTaskData(taskCtx
core.TaskContext, options map[strin
taskData := &tasks.GithubTaskData{
Options: op,
ApiClient: apiClient,
+ Repo: &repo,
}
if !since.IsZero() {
@@ -192,6 +219,22 @@ func (plugin Github) ApiResources()
map[string]map[string]core.ApiResourceHandle
"PATCH": api.PatchConnection,
"DELETE": api.DeleteConnection,
},
+ "connections/:connectionId/scopes/:repoId": {
+ "GET": api.GetScope,
+ "PUT": api.PutScope,
+ "PATCH": api.UpdateScope,
+ },
+ "connections/:connectionId/scopes": {
+ "GET": api.GetScopeList,
+ },
+ "transformation_rules": {
+ "POST": api.CreateTransformationRule,
+ "GET": api.GetTransformationRuleList,
+ },
+ "transformation_rules/:id": {
+ "PATCH": api.UpdateTransformationRule,
+ "GET": api.GetTransformationRule,
+ },
"connections/:connectionId/proxy/rest/*path": {
"GET": api.Proxy,
},
diff --git a/plugins/github/models/connection.go
b/plugins/github/models/connection.go
index da522e774..474bd5a6d 100644
--- a/plugins/github/models/connection.go
+++ b/plugins/github/models/connection.go
@@ -33,19 +33,6 @@ type GithubConnection struct {
EnableGraphql bool `mapstructure:"enableGraphql"
json:"enableGraphql"`
}
-type TransformationRules struct {
- PrType string `mapstructure:"prType" json:"prType"`
- PrComponent string `mapstructure:"prComponent"
json:"prComponent"`
- PrBodyClosePattern string `mapstructure:"prBodyClosePattern"
json:"prBodyClosePattern"`
- IssueSeverity string `mapstructure:"issueSeverity"
json:"issueSeverity"`
- IssuePriority string `mapstructure:"issuePriority"
json:"issuePriority"`
- IssueComponent string `mapstructure:"issueComponent"
json:"issueComponent"`
- IssueTypeBug string `mapstructure:"issueTypeBug"
json:"issueTypeBug"`
- IssueTypeIncident string `mapstructure:"issueTypeIncident"
json:"issueTypeIncident"`
- IssueTypeRequirement string `mapstructure:"issueTypeRequirement"
json:"issueTypeRequirement"`
- DeploymentPattern string `mapstructure:"deploymentPattern"
json:"deploymentPattern"`
-}
-
func (GithubConnection) TableName() string {
return "_tool_github_connections"
}
diff --git
a/plugins/jira/models/migrationscripts/20221116_add_trasformation_rule_table.go
b/plugins/github/models/migrationscripts/20221124_add_trasformation_rule_table.go
similarity index 58%
copy from
plugins/jira/models/migrationscripts/20221116_add_trasformation_rule_table.go
copy to
plugins/github/models/migrationscripts/20221124_add_trasformation_rule_table.go
index e5d2f863c..d6305ae23 100644
---
a/plugins/jira/models/migrationscripts/20221116_add_trasformation_rule_table.go
+++
b/plugins/github/models/migrationscripts/20221124_add_trasformation_rule_table.go
@@ -21,28 +21,27 @@ import (
"github.com/apache/incubator-devlake/errors"
"github.com/apache/incubator-devlake/helpers/migrationhelper"
"github.com/apache/incubator-devlake/plugins/core"
-
"github.com/apache/incubator-devlake/plugins/jira/models/migrationscripts/archived"
+
"github.com/apache/incubator-devlake/plugins/github/models/migrationscripts/archived"
)
-type jiraBoard20221116 struct {
+type githubRepo20221124 struct {
TransformationRuleId uint64
- ScopeId string `gorm:"type:varchar(255)"`
}
-func (jiraBoard20221116) TableName() string {
- return "_tool_jira_boards"
+func (githubRepo20221124) TableName() string {
+ return "_tool_github_repos"
}
-type addTransformationRule20221116 struct{}
+type addTransformationRule20221124 struct{}
-func (script *addTransformationRule20221116) Up(basicRes core.BasicRes)
errors.Error {
- return migrationhelper.AutoMigrateTables(basicRes,
&jiraBoard20221116{}, &archived.JiraTransformationRule{})
+func (*addTransformationRule20221124) Up(basicRes core.BasicRes) errors.Error {
+ return migrationhelper.AutoMigrateTables(basicRes,
&githubRepo20221124{}, &archived.TransformationRules{})
}
-func (*addTransformationRule20221116) Version() uint64 {
- return 20221117122532
+func (*addTransformationRule20221124) Version() uint64 {
+ return 20221124095900
}
-func (*addTransformationRule20221116) Name() string {
- return "add table _tool_jira_transformation_rules, add
transformation_rule_id to _tool_jira_boards"
+func (*addTransformationRule20221124) Name() string {
+ return "add table _tool_github_transformation_rules, add
transformation_rule_id to _tool_github_repos"
}
diff --git
a/plugins/github/models/migrationscripts/archived/transformation_rules.go
b/plugins/github/models/migrationscripts/archived/transformation_rules.go
new file mode 100644
index 000000000..52a6a0a1b
--- /dev/null
+++ b/plugins/github/models/migrationscripts/archived/transformation_rules.go
@@ -0,0 +1,43 @@
+/*
+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 archived
+
+import (
+ "encoding/json"
+
+ "github.com/apache/incubator-devlake/models/migrationscripts/archived"
+)
+
+type TransformationRules struct {
+ archived.Model
+ PrType string `mapstructure:"prType"
json:"prType" gorm:"type:varchar(255)"`
+ PrComponent string `mapstructure:"prComponent"
json:"prComponent" gorm:"type:varchar(255)"`
+ PrBodyClosePattern string `mapstructure:"prBodyClosePattern"
json:"prBodyClosePattern" gorm:"type:varchar(255)"`
+ IssueSeverity string `mapstructure:"issueSeverity"
json:"issueSeverity" gorm:"type:varchar(255)"`
+ IssuePriority string `mapstructure:"issuePriority"
json:"issuePriority" gorm:"type:varchar(255)"`
+ IssueComponent string `mapstructure:"issueComponent"
json:"issueComponent" gorm:"type:varchar(255)"`
+ IssueTypeBug string `mapstructure:"issueTypeBug"
json:"issueTypeBug" gorm:"type:varchar(255)"`
+ IssueTypeIncident string `mapstructure:"issueTypeIncident"
json:"issueTypeIncident" gorm:"type:varchar(255)"`
+ IssueTypeRequirement string
`mapstructure:"issueTypeRequirement" json:"issueTypeRequirement"
gorm:"type:varchar(255)"`
+ DeploymentPattern string `mapstructure:"deploymentPattern"
json:"deploymentPattern" gorm:"type:varchar(255)"`
+ RefdiffRule json.RawMessage `mapstructure:"refdiffRule"
json:"refdiffRule"`
+}
+
+func (TransformationRules) TableName() string {
+ return "_tool_github_transformation_rules"
+}
diff --git a/plugins/github/models/migrationscripts/register.go
b/plugins/github/models/migrationscripts/register.go
index 9378bf9dd..137406707 100644
--- a/plugins/github/models/migrationscripts/register.go
+++ b/plugins/github/models/migrationscripts/register.go
@@ -31,5 +31,6 @@ func All() []core.MigrationScript {
new(deleteGithubPipelineTable),
new(addHeadRepoIdFieldInGithubPr),
new(addEnableGraphqlForConnection),
+ new(addTransformationRule20221124),
}
}
diff --git a/plugins/github/models/repo.go b/plugins/github/models/repo.go
index a60dbc36d..5ae5516ba 100644
--- a/plugins/github/models/repo.go
+++ b/plugins/github/models/repo.go
@@ -23,18 +23,19 @@ import (
)
type GithubRepo struct {
- ConnectionId uint64 `gorm:"primaryKey"`
- GithubId int `gorm:"primaryKey"`
- Name string `gorm:"type:varchar(255)"`
- HTMLUrl string `gorm:"type:varchar(255)"`
- Description string
- OwnerId int `json:"ownerId"`
- OwnerLogin string `json:"ownerLogin" gorm:"type:varchar(255)"`
- Language string `json:"language" gorm:"type:varchar(255)"`
- ParentGithubId int `json:"parentId"`
- ParentHTMLUrl string `json:"parentHtmlUrl"`
- CreatedDate time.Time `json:"createdDate"`
- UpdatedDate *time.Time `json:"updatedDate"`
+ ConnectionId uint64 `gorm:"primaryKey"`
+ GithubId int `gorm:"primaryKey"`
+ TransformationRuleId uint64
+ Name string `gorm:"type:varchar(255)"`
+ HTMLUrl string `gorm:"type:varchar(255)"`
+ Description string
+ OwnerId int `json:"ownerId"`
+ OwnerLogin string `json:"ownerLogin"
gorm:"type:varchar(255)"`
+ Language string `json:"language"
gorm:"type:varchar(255)"`
+ ParentGithubId int `json:"parentId"`
+ ParentHTMLUrl string `json:"parentHtmlUrl"`
+ CreatedDate time.Time `json:"createdDate"`
+ UpdatedDate *time.Time `json:"updatedDate"`
common.NoPKModel
}
diff --git a/plugins/github/models/transformation_rule.go
b/plugins/github/models/transformation_rule.go
new file mode 100644
index 000000000..f53eece58
--- /dev/null
+++ b/plugins/github/models/transformation_rule.go
@@ -0,0 +1,43 @@
+/*
+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 (
+ "encoding/json"
+
+ "github.com/apache/incubator-devlake/models/common"
+)
+
+type TransformationRules struct {
+ common.Model
+ PrType string `mapstructure:"prType"
json:"prType" gorm:"type:varchar(255)"`
+ PrComponent string `mapstructure:"prComponent"
json:"prComponent" gorm:"type:varchar(255)"`
+ PrBodyClosePattern string `mapstructure:"prBodyClosePattern"
json:"prBodyClosePattern" gorm:"type:varchar(255)"`
+ IssueSeverity string `mapstructure:"issueSeverity"
json:"issueSeverity" gorm:"type:varchar(255)"`
+ IssuePriority string `mapstructure:"issuePriority"
json:"issuePriority" gorm:"type:varchar(255)"`
+ IssueComponent string `mapstructure:"issueComponent"
json:"issueComponent" gorm:"type:varchar(255)"`
+ IssueTypeBug string `mapstructure:"issueTypeBug"
json:"issueTypeBug" gorm:"type:varchar(255)"`
+ IssueTypeIncident string `mapstructure:"issueTypeIncident"
json:"issueTypeIncident" gorm:"type:varchar(255)"`
+ IssueTypeRequirement string
`mapstructure:"issueTypeRequirement" json:"issueTypeRequirement"
gorm:"type:varchar(255)"`
+ DeploymentPattern string `mapstructure:"deploymentPattern"
json:"deploymentPattern" gorm:"type:varchar(255)"`
+ RefdiffRule json.RawMessage `mapstructure:"refdiffRule"
json:"refdiffRule"`
+}
+
+func (TransformationRules) TableName() string {
+ return "_tool_github_transformation_rules"
+}
diff --git a/plugins/github/tasks/issue_extractor.go
b/plugins/github/tasks/issue_extractor.go
index eb290b772..e95bbc474 100644
--- a/plugins/github/tasks/issue_extractor.go
+++ b/plugins/github/tasks/issue_extractor.go
@@ -223,7 +223,7 @@ func convertGithubLabels(issueRegexes *IssueRegexes, issue
*IssuesResponse, gith
return results, nil
}
-func NewIssueRegexes(config models.TransformationRules) (*IssueRegexes,
errors.Error) {
+func NewIssueRegexes(config *models.TransformationRules) (*IssueRegexes,
errors.Error) {
var issueRegexes IssueRegexes
var issueSeverity = config.IssueSeverity
var err error
diff --git a/plugins/github/tasks/repo_extractor.go
b/plugins/github/tasks/repo_extractor.go
index faa4a6e22..59ed2d362 100644
--- a/plugins/github/tasks/repo_extractor.go
+++ b/plugins/github/tasks/repo_extractor.go
@@ -21,7 +21,6 @@ import (
"encoding/json"
"fmt"
"github.com/apache/incubator-devlake/errors"
-
"github.com/apache/incubator-devlake/plugins/core"
"github.com/apache/incubator-devlake/plugins/github/models"
"github.com/apache/incubator-devlake/plugins/helper"
diff --git a/plugins/github/tasks/task_data.go
b/plugins/github/tasks/task_data.go
index 728f22833..0516b807b 100644
--- a/plugins/github/tasks/task_data.go
+++ b/plugins/github/tasks/task_data.go
@@ -27,12 +27,13 @@ import (
)
type GithubOptions struct {
- ConnectionId uint64 `json:"connectionId"`
- Tasks []string `json:"tasks,omitempty"`
- Since string
- Owner string
- Repo string
- models.TransformationRules `mapstructure:"transformationRules"
json:"transformationRules"`
+ ConnectionId uint64 `json:"connectionId"`
+ TransformationRuleId uint64 `json:"transformationRuleId"`
+ Tasks []string `json:"tasks,omitempty"`
+ Since string
+ Owner string
+ Repo string
+ *models.TransformationRules `mapstructure:"transformationRules"
json:"transformationRules"`
}
type GithubTaskData struct {
@@ -55,40 +56,12 @@ func DecodeAndValidateTaskOptions(options
map[string]interface{}) (*GithubOption
if op.Repo == "" {
return nil, errors.BadInput.New("repo is required for GitHub
execution")
}
- if op.PrType == "" {
- op.PrType = "type/(.*)$"
- }
- if op.PrComponent == "" {
- op.PrComponent = "component/(.*)$"
- }
- if op.PrBodyClosePattern == "" {
- op.PrBodyClosePattern =
"(?mi)(fix|close|resolve|fixes|closes|resolves|fixed|closed|resolved)[\\s]*.*(((and
)?(#|https:\\/\\/github.com\\/%s\\/%s\\/issues\\/)\\d+[ ]*)+)"
- }
- if op.IssueSeverity == "" {
- op.IssueSeverity = "severity/(.*)$"
- }
- if op.IssuePriority == "" {
- op.IssuePriority = "^(highest|high|medium|low)$"
- }
- if op.IssueComponent == "" {
- op.IssueComponent = "component/(.*)$"
- }
- if op.IssueTypeBug == "" {
- op.IssueTypeBug = "^(bug|failure|error)$"
- }
- if op.IssueTypeIncident == "" {
- op.IssueTypeIncident = ""
- }
- if op.IssueTypeRequirement == "" {
- op.IssueTypeRequirement =
"^(feat|feature|proposal|requirement)$"
- }
- if op.DeploymentPattern == "" {
- op.DeploymentPattern = "(?i)deploy"
- }
-
// find the needed GitHub now
if op.ConnectionId == 0 {
return nil, errors.BadInput.New("connectionId is invalid")
}
+ if op.TransformationRules == nil && op.TransformationRuleId == 0 {
+ op.TransformationRules = new(models.TransformationRules)
+ }
return &op, nil
}
diff --git a/plugins/jira/api/scope.go b/plugins/jira/api/scope.go
index d6ce8c33c..2a241455c 100644
--- a/plugins/jira/api/scope.go
+++ b/plugins/jira/api/scope.go
@@ -157,8 +157,5 @@ func verifyBoard(board *models.JiraBoard) errors.Error {
if board.BoardId == 0 {
return errors.BadInput.New("invalid boardId")
}
- if board.ScopeId != strconv.FormatUint(board.BoardId, 10) {
- return errors.BadInput.New("the scope_id does not match the
board_id")
- }
return nil
}
diff --git a/plugins/jira/impl/impl.go b/plugins/jira/impl/impl.go
index 8c01cb351..330ceebfa 100644
--- a/plugins/jira/impl/impl.go
+++ b/plugins/jira/impl/impl.go
@@ -95,6 +95,9 @@ func (plugin Jira) Description() string {
func (plugin Jira) SubTaskMetas() []core.SubTaskMeta {
return []core.SubTaskMeta{
+ tasks.CollectBoardMeta,
+ tasks.ExtractBoardMeta,
+
tasks.CollectStatusMeta,
tasks.ExtractStatusMeta,
diff --git a/plugins/jira/models/board.go b/plugins/jira/models/board.go
index a091ebca0..17568b142 100644
--- a/plugins/jira/models/board.go
+++ b/plugins/jira/models/board.go
@@ -25,7 +25,6 @@ type JiraBoard struct {
common.NoPKModel
ConnectionId uint64 `gorm:"primaryKey"`
BoardId uint64 `gorm:"primaryKey"`
- ScopeId string
TransformationRuleId uint64
ProjectId uint
Name string `gorm:"type:varchar(255)"`
diff --git
a/plugins/jira/models/migrationscripts/20221116_add_trasformation_rule_table.go
b/plugins/jira/models/migrationscripts/20221116_add_trasformation_rule_table.go
index e5d2f863c..475388c88 100644
---
a/plugins/jira/models/migrationscripts/20221116_add_trasformation_rule_table.go
+++
b/plugins/jira/models/migrationscripts/20221116_add_trasformation_rule_table.go
@@ -26,7 +26,6 @@ import (
type jiraBoard20221116 struct {
TransformationRuleId uint64
- ScopeId string `gorm:"type:varchar(255)"`
}
func (jiraBoard20221116) TableName() string {
diff --git
a/plugins/jira/models/migrationscripts/archived/transformation_rules.go
b/plugins/jira/models/migrationscripts/archived/transformation_rules.go
index a13420baf..c0d59d75a 100644
--- a/plugins/jira/models/migrationscripts/archived/transformation_rules.go
+++ b/plugins/jira/models/migrationscripts/archived/transformation_rules.go
@@ -30,3 +30,7 @@ type JiraTransformationRule struct {
RemotelinkCommitShaPattern string
`json:"remotelinkCommitShaPattern" gorm:"type:varchar(255)"`
TypeMappings json.RawMessage `json:"typeMappings"`
}
+
+func (JiraTransformationRule) TableName() string {
+ return "_tool_jira_transformation_rules"
+}
diff --git a/plugins/jira/models/transformation_rules.go
b/plugins/jira/models/transformation_rules.go
index 1aa3aa055..998290e82 100644
--- a/plugins/jira/models/transformation_rules.go
+++ b/plugins/jira/models/transformation_rules.go
@@ -30,3 +30,7 @@ type JiraTransformationRule struct {
RemotelinkCommitShaPattern string
`json:"remotelinkCommitShaPattern" gorm:"type:varchar(255)"`
TypeMappings json.RawMessage `json:"typeMappings"`
}
+
+func (JiraTransformationRule) TableName() string {
+ return "_tool_jira_transformation_rules"
+}