diff --git a/cmd/decorate.go b/cmd/decorate.go index b08e3e3..b936e5a 100644 --- a/cmd/decorate.go +++ b/cmd/decorate.go @@ -118,7 +118,7 @@ func decoratePullRequest(qualityGate sonar.QualityGate, tag string, timeout time return } - err = decorator.ClearPreviousComments(qualityGate.Source) + err = decorator.ClearPreviousComments(qualityGate.Source, tag) if err != nil { log.Printf("Failue at remove old comments from pull request (%s): %s", qualityGate.Source, err.Error()) } diff --git a/decoration/azuredevops/clear_previous_comments.go b/decoration/azuredevops/clear_previous_comments.go index 5b1a8c6..63a9066 100644 --- a/decoration/azuredevops/clear_previous_comments.go +++ b/decoration/azuredevops/clear_previous_comments.go @@ -10,8 +10,8 @@ import ( const routeListPullRequestThreadsComments = "%s/_apis/git/repositories/%s/pullRequests/%s/threads?api-version=6.0" const routeDeletePullRequestThreadComment = "%s/_apis/git/repositories/%s/pullRequests/%s/threads/%d/comments/%d?api-version=6.0" -func (decorator *PullRequestDecorator) ClearPreviousComments(pullRequest string) error { - comments, err := decorator._loadMyPullRequestThreadsComments(pullRequest) +func (decorator *PullRequestDecorator) ClearPreviousComments(pullRequest string, tag string) error { + comments, err := decorator._loadMyPullRequestThreadsComments(pullRequest, tag) if err != nil { return err } @@ -32,7 +32,7 @@ func (decorator *PullRequestDecorator) ClearPreviousComments(pullRequest string) return nil } -func (decorator *PullRequestDecorator) _loadMyPullRequestThreadsComments(pullRequest string) ([]_commentToDelete, error) { +func (decorator *PullRequestDecorator) _loadMyPullRequestThreadsComments(pullRequest string, tag string) ([]_commentToDelete, error) { chBuff, chErr := decorator.Get(fmt.Sprintf(routeListPullRequestThreadsComments, formatPath(decorator.Project), formatPath(decorator.Repository), pullRequest)) err := <-chErr @@ -49,7 +49,9 @@ func (decorator *PullRequestDecorator) _loadMyPullRequestThreadsComments(pullReq var commentsToDelete []_commentToDelete for _, thread := range threadsWrapper.Value { - if !thread.IsDeleted && strings.ToLower(thread.Properties.GeneratedBySonarCI.Value) == "true" { + if !thread.IsDeleted && + strings.ToLower(thread.Properties.GeneratedBySonarCI.Value) == "true" && + thread.Properties.Tag.Value == tag { for _, comment := range thread.Comments { if !comment.IsDeleted { commentsToDelete = append(commentsToDelete, diff --git a/decoration/azuredevops/clear_previous_comments_test.go b/decoration/azuredevops/clear_previous_comments_test.go index 6200f81..a022645 100644 --- a/decoration/azuredevops/clear_previous_comments_test.go +++ b/decoration/azuredevops/clear_previous_comments_test.go @@ -23,7 +23,7 @@ func TestPullRequestDecorator_ClearPreviousComments_CheckErrorOnLoadComments(t * } decorator := NewPullRequestDecorator(mockConn, &mocks.MockEngine{}, "project-test", "repo-test") - gotError := decorator.ClearPreviousComments("pullrequest-test") + gotError := decorator.ClearPreviousComments("pullrequest-test", "") if gotError != wantError { t.Fail() @@ -62,7 +62,7 @@ func TestPullRequestDecorator_ClearPreviousComments_CheckErrorOnDeleteComments(t } decorator := NewPullRequestDecorator(mockConn, &mocks.MockEngine{}, "project-test", "repo-test") - gotError := decorator.ClearPreviousComments("pullrequest-test") + gotError := decorator.ClearPreviousComments("pullrequest-test", "") if gotError != wantError { t.Fail() @@ -98,7 +98,7 @@ func TestPullRequestDecorator_ClearPreviousComments_CheckNoError(t *testing.T) { } decorator := NewPullRequestDecorator(mockConn, &mocks.MockEngine{}, "project-test", "repo-test") - gotError := decorator.ClearPreviousComments("pullrequest-test") + gotError := decorator.ClearPreviousComments("pullrequest-test", "") if gotError != nil { t.Fail() @@ -119,7 +119,7 @@ func TestPullRequestDecorator_loadMyPullRequestThreadsComments_CheckErrorOnReque } decorator := NewPullRequestDecorator(mockConn, &mocks.MockEngine{}, "project-test", "repo-test") - _, gotErr := decorator._loadMyPullRequestThreadsComments("anything") + _, gotErr := decorator._loadMyPullRequestThreadsComments("anything", "") if gotErr != wantError { t.FailNow() @@ -140,7 +140,7 @@ func TestPullRequestDecorator_loadMyPullRequestThreadsComments_CheckErrorOnReadR } decorator := NewPullRequestDecorator(mockConn, &mocks.MockEngine{}, "project-test", "repo-test") - _, gotErr := decorator._loadMyPullRequestThreadsComments("anything") + _, gotErr := decorator._loadMyPullRequestThreadsComments("anything", "") if gotErr == nil { t.FailNow() @@ -156,7 +156,10 @@ func TestPullRequestDecorator_loadMyPullRequestThreadsComments_CheckResult(t *te {Id: 11, IsDeleted: true}, {Id: 12, IsDeleted: false}, }, - Properties: models.ThreadPropertyModel{GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "True"}}, + Properties: models.ThreadPropertyModel{ + GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "True"}, + Tag: models.ThreadPropertySonarCIModel{Value: "123"}, + }, }, {Id: 2, IsDeleted: true, Comments: []models.ThreadCommentModel{ @@ -164,28 +167,50 @@ func TestPullRequestDecorator_loadMyPullRequestThreadsComments_CheckResult(t *te {Id: 21, IsDeleted: false}, {Id: 22, IsDeleted: false}, }, - Properties: models.ThreadPropertyModel{GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "True"}}, + Properties: models.ThreadPropertyModel{ + GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "True"}, + Tag: models.ThreadPropertySonarCIModel{Value: "123"}, + }, }, {Id: 3, IsDeleted: false, Comments: []models.ThreadCommentModel{ {Id: 31, IsDeleted: false}, {Id: 32, IsDeleted: false}, }, - Properties: models.ThreadPropertyModel{GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "true"}}, + Properties: models.ThreadPropertyModel{ + GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "true"}, + Tag: models.ThreadPropertySonarCIModel{Value: "123"}, + }, }, {Id: 4, IsDeleted: false, Comments: []models.ThreadCommentModel{ {Id: 41, IsDeleted: false}, {Id: 42, IsDeleted: false}, }, - Properties: models.ThreadPropertyModel{GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "false"}}, + Properties: models.ThreadPropertyModel{ + GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "false"}, + Tag: models.ThreadPropertySonarCIModel{Value: "123"}, + }, }, {Id: 5, IsDeleted: false, Comments: []models.ThreadCommentModel{ {Id: 51, IsDeleted: false}, {Id: 52, IsDeleted: false}, }, - Properties: models.ThreadPropertyModel{GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "anything"}}, + Properties: models.ThreadPropertyModel{ + GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "false"}, + Tag: models.ThreadPropertySonarCIModel{Value: "123"}, + }, + }, + {Id: 6, IsDeleted: false, + Comments: []models.ThreadCommentModel{ + {Id: 61, IsDeleted: false}, + {Id: 62, IsDeleted: false}, + }, + Properties: models.ThreadPropertyModel{ + GeneratedBySonarCI: models.ThreadPropertySonarCIModel{Value: "true"}, + Tag: models.ThreadPropertySonarCIModel{Value: "999"}, + }, }, }, } @@ -212,7 +237,7 @@ func TestPullRequestDecorator_loadMyPullRequestThreadsComments_CheckResult(t *te } decorator := NewPullRequestDecorator(mockConn, &mocks.MockEngine{}, "project-test", "repo-test") - gotThreads, err := decorator._loadMyPullRequestThreadsComments(pullRequest) + gotThreads, err := decorator._loadMyPullRequestThreadsComments(pullRequest, "123") if err != nil { t.Fail() diff --git a/decoration/azuredevops/comment_qualitygate.go b/decoration/azuredevops/comment_qualitygate.go index 4e51da7..9b43a77 100644 --- a/decoration/azuredevops/comment_qualitygate.go +++ b/decoration/azuredevops/comment_qualitygate.go @@ -18,7 +18,7 @@ func (decorator *PullRequestDecorator) CommentQualityGate(qualityGate sonar.Qual return err } - commentModel := models.ParseCommentModel(qualityGate, report) + commentModel := models.ParseCommentModel(qualityGate, report, tag) body, _ := json.Marshal(commentModel) endpoint := fmt.Sprintf(routeCommentPullRequest, formatPath(decorator.Project), formatPath(decorator.Repository), qualityGate.Source) diff --git a/decoration/azuredevops/models/comment_model.go b/decoration/azuredevops/models/comment_model.go index 797cebf..100444c 100644 --- a/decoration/azuredevops/models/comment_model.go +++ b/decoration/azuredevops/models/comment_model.go @@ -16,7 +16,8 @@ type CommentWrapperModel struct { } type CommentPropertyModel struct { - GeneratedBySonarCI bool + GeneratedBySonarCI bool `json:"generatedBySonarCi"` + Tag string `json:"tag"` } type CommentModel struct { @@ -24,7 +25,7 @@ type CommentModel struct { CommentType string `json:"commentType"` } -func ParseCommentModel(qualityGate sonar.QualityGate, report string) CommentWrapperModel { +func ParseCommentModel(qualityGate sonar.QualityGate, report string, tag string) CommentWrapperModel { var status string if qualityGate.HasPassed() { status = statusClosed @@ -34,7 +35,7 @@ func ParseCommentModel(qualityGate sonar.QualityGate, report string) CommentWrap return CommentWrapperModel{ Status: status, - Properties: CommentPropertyModel{GeneratedBySonarCI: true}, + Properties: CommentPropertyModel{GeneratedBySonarCI: true, Tag: tag}, Comments: []CommentModel{ {CommentType: commentType, Content: report}, }} diff --git a/decoration/azuredevops/models/comment_model_test.go b/decoration/azuredevops/models/comment_model_test.go index e03a71c..8c5bcb0 100644 --- a/decoration/azuredevops/models/comment_model_test.go +++ b/decoration/azuredevops/models/comment_model_test.go @@ -20,7 +20,7 @@ func Test_ParseCommentModel_CheckStatus(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := ParseCommentModel(tt.args.qualityGate, tt.args.report); got.Status != tt.wantStatus { + if got := ParseCommentModel(tt.args.qualityGate, tt.args.report, "any-tag"); got.Status != tt.wantStatus { t.Errorf("parseCommentModel() Status = %v, want %v", got.Status, tt.wantStatus) } }) @@ -28,7 +28,7 @@ func Test_ParseCommentModel_CheckStatus(t *testing.T) { } func Test_ParseCommentModel_CheckPropertiesGeneratedBySonarCI_IsTrue(t *testing.T) { - got := ParseCommentModel(sonar.QualityGate{Status: "anything"}, "report-test").Properties.GeneratedBySonarCI + got := ParseCommentModel(sonar.QualityGate{Status: "anything"}, "report-test", "any-tag").Properties.GeneratedBySonarCI if got != true { t.Errorf("parseCommentModel() Properties.GeneratedBySonarCI want true") } diff --git a/decoration/azuredevops/models/thread_model.go b/decoration/azuredevops/models/thread_model.go index ef50fbe..c26f86f 100644 --- a/decoration/azuredevops/models/thread_model.go +++ b/decoration/azuredevops/models/thread_model.go @@ -19,6 +19,7 @@ type ThreadCommentModel struct { type ThreadPropertyModel struct { GeneratedBySonarCI ThreadPropertySonarCIModel `json:"generatedBySonarCI"` + Tag ThreadPropertySonarCIModel `json:"tag"` } type ThreadPropertySonarCIModel struct { diff --git a/decoration/pullrequest_decorator.go b/decoration/pullrequest_decorator.go index eb220e9..daaf385 100644 --- a/decoration/pullrequest_decorator.go +++ b/decoration/pullrequest_decorator.go @@ -3,6 +3,6 @@ package decoration import "sonarci/sonar" type PullRequestDecorator interface { - ClearPreviousComments(pullRequest string) error + ClearPreviousComments(pullRequest string, tag string) error CommentQualityGate(qualityGate sonar.QualityGate, tag string) error }