Skip to content

Commit 5d5047a

Browse files
authored
Merge pull request #1421 from cloudflare/gitlab
Fix comments on renamed files
2 parents cd806eb + f50050f commit 5d5047a

File tree

4 files changed

+146
-24
lines changed

4 files changed

+146
-24
lines changed

docs/changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## v0.73.6
4+
5+
### Fixed
6+
7+
- Fixed a bug in GitLab integration causing some problems fail to create comments when files were renamed.
8+
39
## v0.73.5
410

511
### Fixed

internal/reporter/comments.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,10 @@ func updateDestination(ctx context.Context, s Summary, c Commenter, dst any, sho
335335
if !c.CanDelete(existing) {
336336
goto NEXTDelete
337337
}
338+
slog.Info("Trying to delete a stale existing comment",
339+
slog.String("path", existing.path),
340+
slog.Int("line", existing.line),
341+
)
338342
if err := c.Delete(ctx, dst, existing); err != nil {
339343
slog.Error("Failed to delete a stale comment",
340344
slog.String("reporter", c.Describe()),

internal/reporter/gitlab.go

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,9 @@ func (gl GitLabReporter) List(_ context.Context, dst any) ([]ExistingComment, er
191191
c = gl.noteToExisting(disc.ID, note)
192192
break
193193
}
194-
comments = append(comments, c)
194+
if c.path != "" && c.line > 0 && c.meta != nil {
195+
comments = append(comments, c)
196+
}
195197
NEXT:
196198
}
197199
return comments, nil
@@ -426,8 +428,8 @@ func (gl GitLabReporter) unresolveIfPresent(ctx context.Context, dst any, commen
426428
}
427429

428430
func reportToGitLabDiscussion(pending PendingComment, diffs []*gitlab.MergeRequestDiff, ver *gitlab.MergeRequestDiffVersion) *gitlab.CreateMergeRequestDiscussionOptions {
429-
diff := getDiffForPath(diffs, pending.path)
430-
if diff == nil {
431+
pathDiffs := getDiffsForPath(diffs, pending.path)
432+
if len(pathDiffs) == 0 {
431433
slog.Debug("Skipping report for path with no GitLab diff",
432434
slog.String("path", pending.path),
433435
)
@@ -441,39 +443,51 @@ func reportToGitLabDiscussion(pending PendingComment, diffs []*gitlab.MergeReque
441443
BaseSHA: gitlab.Ptr(ver.BaseCommitSHA),
442444
HeadSHA: gitlab.Ptr(ver.HeadCommitSHA),
443445
StartSHA: gitlab.Ptr(ver.StartCommitSHA),
444-
OldPath: gitlab.Ptr(diff.OldPath),
445-
NewPath: gitlab.Ptr(diff.NewPath),
446446
},
447447
}
448448

449-
dl, ok := diffLineFor(parseDiffLines(diff.Diff), pending.line)
450-
switch {
451-
case !ok:
452-
// No diffLine for this line, most likely unmodified ?.
453-
d.Position.NewLine = gitlab.Ptr(pending.line)
454-
d.Position.OldLine = gitlab.Ptr(pending.line)
455-
case pending.anchor == checks.AnchorBefore:
456-
// Comment on removed line.
457-
d.Position.OldLine = gitlab.Ptr(dl.old)
458-
case ok && !dl.wasModified:
459-
// Comment on unmodified line.
460-
d.Position.NewLine = gitlab.Ptr(dl.new)
461-
d.Position.OldLine = gitlab.Ptr(dl.old)
462-
default:
463-
// Comment on new or modified line.
464-
d.Position.NewLine = gitlab.Ptr(dl.new)
449+
var renamed bool
450+
for _, diff := range pathDiffs {
451+
d.Position.OldPath = gitlab.Ptr(diff.OldPath)
452+
if d.Position.NewPath == nil {
453+
d.Position.NewPath = gitlab.Ptr(diff.NewPath)
454+
}
455+
if diff.OldPath != diff.NewPath {
456+
renamed = true
457+
}
458+
459+
dl, ok := diffLineFor(parseDiffLines(diff.Diff), pending.line)
460+
switch {
461+
case !ok:
462+
// No diffLine for this line, could be a file rename.
463+
d.Position.NewLine = gitlab.Ptr(pending.line)
464+
d.Position.OldLine = gitlab.Ptr(pending.line)
465+
case pending.anchor == checks.AnchorBefore:
466+
// Comment on removed line.
467+
d.Position.OldLine = gitlab.Ptr(dl.old)
468+
case ok && !dl.wasModified:
469+
// Comment on unmodified line.
470+
d.Position.NewLine = gitlab.Ptr(dl.new)
471+
d.Position.OldLine = gitlab.Ptr(dl.old)
472+
default:
473+
// Comment on new or modified line.
474+
d.Position.NewLine = gitlab.Ptr(dl.new)
475+
}
476+
}
477+
if renamed {
478+
d.Position.OldLine = nil
465479
}
466480

467481
return &d
468482
}
469483

470-
func getDiffForPath(diffs []*gitlab.MergeRequestDiff, path string) *gitlab.MergeRequestDiff {
484+
func getDiffsForPath(diffs []*gitlab.MergeRequestDiff, path string) (changes []*gitlab.MergeRequestDiff) {
471485
for _, change := range diffs {
472486
if change.NewPath == path {
473-
return change
487+
changes = append(changes, change)
474488
}
475489
}
476-
return nil
490+
return changes
477491
}
478492

479493
type diffLine struct {

internal/reporter/gitlab_test.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http/httptest"
99
"os"
1010
"path/filepath"
11+
"regexp"
1112
"strconv"
1213
"strings"
1314
"testing"
@@ -234,6 +235,19 @@ func TestGitLabReporter(t *testing.T) {
234235
maxComments int
235236
showDuplicates bool
236237
}{
238+
{
239+
description: "bogus JSON responses",
240+
timeout: time.Minute,
241+
maxComments: 1,
242+
summary: reporter.NewSummary([]reporter.Report{fooReport}),
243+
mock: httpmock.New(func(s *httpmock.Server) {
244+
s.ExpectGet(apiUser).ReturnJSON(gitlab.User{ID: 123})
245+
s.ExpectGet(regexp.MustCompile(".+")).Times(4).Return(`[{"iid": 333}]`)
246+
}),
247+
errorHandler: func(err error) error {
248+
return err
249+
},
250+
},
237251
{
238252
description: "empty list of merge requests",
239253
timeout: time.Minute,
@@ -878,6 +892,90 @@ Below is the list of checks that were disabled for each Prometheus server define
878892
return err
879893
},
880894
},
895+
{
896+
description: "rule moved to a different file, old deleted",
897+
timeout: time.Minute,
898+
maxComments: 1,
899+
summary: reporter.NewSummary([]reporter.Report{
900+
{
901+
Path: discovery.Path{
902+
SymlinkTarget: mockPath,
903+
Name: mockPath,
904+
},
905+
ModifiedLines: []int{2, 3},
906+
Rule: mockFile.Groups[0].Rules[0],
907+
Problem: checks.Problem{
908+
Reporter: "a",
909+
Summary: "foo error1",
910+
Details: "foo details",
911+
Diagnostics: []diags.Diagnostic{
912+
{
913+
Message: "Diagnostic message",
914+
Pos: diags.PositionRanges{
915+
{
916+
Line: 2,
917+
FirstColumn: 3,
918+
LastColumn: 24,
919+
},
920+
{
921+
Line: 3,
922+
FirstColumn: 3,
923+
LastColumn: 15,
924+
},
925+
},
926+
FirstColumn: 1,
927+
LastColumn: 24,
928+
},
929+
},
930+
Lines: diags.LineRange{First: 1, Last: 3},
931+
Severity: checks.Fatal,
932+
Anchor: checks.AnchorAfter,
933+
},
934+
},
935+
}),
936+
mock: httpmock.New(func(s *httpmock.Server) {
937+
s.ExpectGet(apiUser).ReturnJSON(gitlab.User{ID: 123})
938+
s.ExpectGet(apiOpenMergeRequests).ReturnJSON([]gitlab.BasicMergeRequest{
939+
{IID: 1},
940+
})
941+
s.ExpectGet(apiVersions(1)).ReturnJSON([]gitlab.MergeRequestDiffVersion{
942+
{ID: 2, HeadCommitSHA: "head", BaseCommitSHA: "base", StartCommitSHA: "start"},
943+
{ID: 1, HeadCommitSHA: "head", BaseCommitSHA: "base", StartCommitSHA: "start"},
944+
})
945+
s.ExpectGet(apiDiffs(1)).ReturnJSON([]gitlab.MergeRequestDiff{
946+
{
947+
Diff: "",
948+
NewPath: mockPath,
949+
OldPath: "foo.old",
950+
AMode: "100644",
951+
BMode: "100644",
952+
RenamedFile: true,
953+
},
954+
{
955+
Diff: fooDiff,
956+
NewPath: "foo.txt",
957+
OldPath: "foo.txt",
958+
},
959+
})
960+
s.ExpectGet(apiDiscussions(1, true)).ReturnJSON([]gitlab.Discussion{})
961+
s.ExpectPost(apiDiscussions(1, false)).WithBodyJSON(gitlab.CreateMergeRequestDiscussionOptions{
962+
Body: discBodyWithDiag("a", "foo error1", "foo details", "```yaml\n2 | - record: target is down\n3 | expr: up == 0\n ^^ \n```", "Diagnostic message"),
963+
Position: gitlab.Ptr(gitlab.PositionOptions{
964+
BaseSHA: gitlab.Ptr("base"),
965+
StartSHA: gitlab.Ptr("start"),
966+
HeadSHA: gitlab.Ptr("head"),
967+
OldPath: gitlab.Ptr("foo.old"),
968+
NewPath: gitlab.Ptr(mockPath),
969+
PositionType: gitlab.Ptr("text"),
970+
NewLine: gitlab.Ptr(3),
971+
// Old file is gone so we don't have OldLine here at all
972+
}),
973+
}).ReturnJSON(gitlab.Response{})
974+
}),
975+
errorHandler: func(err error) error {
976+
return err
977+
},
978+
},
881979
}
882980

883981
for _, tc := range testCases {

0 commit comments

Comments
 (0)