Skip to content

Commit

Permalink
Add maxComments to BitBucket and GitHub reporters
Browse files Browse the repository at this point in the history
  • Loading branch information
prymitive committed Mar 25, 2024
1 parent 0ef4580 commit 6cc4900
Show file tree
Hide file tree
Showing 12 changed files with 400 additions and 52 deletions.
2 changes: 2 additions & 0 deletions cmd/pint/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ func actionCI(c *cli.Context) error {
token,
meta.cfg.Repository.BitBucket.Project,
meta.cfg.Repository.BitBucket.Repository,
meta.cfg.Repository.BitBucket.MaxComments,
git.RunGit,
)
reps = append(reps, br)
Expand Down Expand Up @@ -178,6 +179,7 @@ func actionCI(c *cli.Context) error {
meta.cfg.Repository.GitHub.Owner,
meta.cfg.Repository.GitHub.Repo,
prNum,
meta.cfg.Repository.GitHub.MaxComments,
git.RunGit,
); err != nil {
return err
Expand Down
8 changes: 8 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## v0.57.0

### Added

- GitHub and BitBucker reporters now supports `maxComments` option to limit the number
of comments pint can create on a single pull request.
Default value of `maxComments` is `50`.

## v0.56.2

### Fixed
Expand Down
23 changes: 14 additions & 9 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,11 @@ Syntax:
```js
repository {
bitbucket {
uri = "https://..."
timeout = "1m"
project = "..."
repository = "..."
uri = "https://..."
timeout = "1m"
project = "..."
repository = "..."
maxComments = 50
}
}
```
Expand All @@ -171,15 +172,18 @@ repository {
- `bitbucket:timeout` - timeout to be used for API requests, defaults to 1 minute.
- `bitbucket:project` - name of the BitBucket project for this repository.
- `bitbucket:repository` - name of the BitBucket repository.
- `bitbucket:maxComments` - the maximum number of comments pint can create on a single
pull request. Default is 50.

```js
repository {
github {
baseuri = "https://..."
uploaduri = "https://..."
timeout = "1m"
owner = "..."
repo = "..."
baseuri = "https://..."
uploaduri = "https://..."
timeout = "1m"
owner = "..."
repo = "..."
maxComments = 50
}
}
```
Expand All @@ -196,6 +200,7 @@ If `github:baseuri` _or_ `github:uploaduri` are not specified, then [GitHub](htt
If not set, `pint` will try to use the `GITHUB_REPOSITORY` environment variable instead (if set).
- `github:repo` - name of the GitHub repository (e.g. `monitoring`).
If not set, `pint` will try to use the `GITHUB_REPOSITORY` environment variable instead (if set).
- `github:maxComments` - the maximum number of comments pint can create on a single pull request. Default is 50.

Most GitHub settings can be detected from environment variables that are set inside GitHub Actions
environment. The only exception is `GITHUB_AUTH_TOKEN` environment variable that must be set
Expand Down
6 changes: 6 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ func Load(path string, failOnMissing bool) (cfg Config, err error) {
if cfg.Repository.BitBucket.Timeout == "" {
cfg.Repository.BitBucket.Timeout = time.Minute.String()
}
if cfg.Repository.BitBucket.MaxComments == 0 {
cfg.Repository.BitBucket.MaxComments = 50
}
if err = cfg.Repository.BitBucket.validate(); err != nil {
return cfg, err
}
Expand All @@ -271,6 +274,9 @@ func Load(path string, failOnMissing bool) (cfg Config, err error) {
if cfg.Repository.GitHub.Timeout == "" {
cfg.Repository.GitHub.Timeout = time.Minute.String()
}
if cfg.Repository.GitHub.MaxComments == 0 {
cfg.Repository.GitHub.MaxComments = 50
}
if err = cfg.Repository.GitHub.validate(); err != nil {
return cfg, err
}
Expand Down
27 changes: 17 additions & 10 deletions internal/config/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import (
)

type BitBucket struct {
URI string `hcl:"uri"`
Timeout string `hcl:"timeout,optional"`
Project string `hcl:"project"`
Repository string `hcl:"repository"`
URI string `hcl:"uri"`
Timeout string `hcl:"timeout,optional"`
Project string `hcl:"project"`
Repository string `hcl:"repository"`
MaxComments int `hcl:"maxComments,optional"`
}

func (bb BitBucket) validate() error {
Expand All @@ -27,15 +28,19 @@ func (bb BitBucket) validate() error {
if bb.URI == "" {
return fmt.Errorf("uri cannot be empty")
}
if bb.MaxComments < 0 {
return fmt.Errorf("maxComments cannot be negative")
}
return nil
}

type GitHub struct {
BaseURI string `hcl:"baseuri,optional"`
UploadURI string `hcl:"uploaduri,optional"`
Timeout string `hcl:"timeout,optional"`
Owner string `hcl:"owner,optional"`
Repo string `hcl:"repo,optional"`
BaseURI string `hcl:"baseuri,optional"`
UploadURI string `hcl:"uploaduri,optional"`
Timeout string `hcl:"timeout,optional"`
Owner string `hcl:"owner,optional"`
Repo string `hcl:"repo,optional"`
MaxComments int `hcl:"maxComments,optional"`
}

func (gh GitHub) validate() error {
Expand Down Expand Up @@ -73,7 +78,9 @@ func (gh GitHub) validate() error {
return fmt.Errorf("invalid uploaduri: %w", err)
}
}

if gh.MaxComments < 0 {
return fmt.Errorf("maxComments cannot be negative")
}
return nil
}

Expand Down
19 changes: 19 additions & 0 deletions internal/config/repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ func TestBitBucketSettings(t *testing.T) {
},
err: errors.New(`not a valid duration string: "abc"`),
},
{
conf: BitBucket{
URI: "http://localhost",
Timeout: "5m",
MaxComments: -1,
Project: "foo",
Repository: "bar",
},
err: errors.New("maxComments cannot be negative"),
},
}

for _, tc := range testCases {
Expand Down Expand Up @@ -165,6 +175,15 @@ func TestGitHubSettings(t *testing.T) {
env: map[string]string{"GITHUB_REPOSITORY": "foo/"},
err: errors.New("repo cannot be empty"),
},
{
conf: GitHub{
Owner: "bob",
Repo: "foo",
Timeout: "5m",
MaxComments: -1,
},
err: errors.New("maxComments cannot be negative"),
},
}

for _, tc := range testCases {
Expand Down
10 changes: 8 additions & 2 deletions internal/reporter/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const (
"Checks can be either offline (static checks using only rule definition) or online (validate rule against live Prometheus server)."
)

func NewBitBucketReporter(version, uri string, timeout time.Duration, token, project, repo string, gitCmd git.CommandRunner) BitBucketReporter {
func NewBitBucketReporter(version, uri string, timeout time.Duration, token, project, repo string, maxComments int, gitCmd git.CommandRunner) BitBucketReporter {
return BitBucketReporter{
api: newBitBucketAPI(version, uri, timeout, token, project, repo),
api: newBitBucketAPI(version, uri, timeout, token, project, repo, maxComments),
gitCmd: gitCmd,
}
}
Expand Down Expand Up @@ -79,6 +79,12 @@ func (r BitBucketReporter) Submit(summary Summary) (err error) {
pendingComments := r.api.makeComments(summary, changes)
slog.Info("Generated comments to add to BitBucket", slog.Int("count", len(pendingComments)))

pendingComments = r.api.limitComments(pendingComments)
slog.Info("Will add comments to BitBucket",
slog.Int("count", len(pendingComments)),
slog.Int("limit", r.api.maxComments),
)

slog.Info("Deleting stale comments from BitBucket")
r.api.pruneComments(pr, existingComments, pendingComments)

Expand Down
27 changes: 22 additions & 5 deletions internal/reporter/bitbucket_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,11 @@ func (pc pendingComment) toBitBucketComment(changes *bitBucketPRChanges) BitBuck
}

type BitBucketPendingCommentAnchor struct {
Path string `json:"path"`
LineType string `json:"lineType"`
FileType string `json:"fileType"`
Path string `json:"path,omitempty"`
LineType string `json:"lineType,omitempty"`
FileType string `json:"fileType,omitempty"`
DiffType string `json:"diffType"`
Line int `json:"line"`
Line int `json:"line,omitempty"`
}

type BitBucketPendingComment struct {
Expand All @@ -249,14 +249,15 @@ type BitBucketCommentSeverityUpdate struct {
Version int `json:"version"`
}

func newBitBucketAPI(pintVersion, uri string, timeout time.Duration, token, project, repo string) *bitBucketAPI {
func newBitBucketAPI(pintVersion, uri string, timeout time.Duration, token, project, repo string, maxComments int) *bitBucketAPI {
return &bitBucketAPI{
pintVersion: pintVersion,
uri: uri,
timeout: timeout,
authToken: token,
project: project,
repo: repo,
maxComments: maxComments,
}
}

Expand Down Expand Up @@ -650,6 +651,22 @@ func (bb bitBucketAPI) makeComments(summary Summary, changes *bitBucketPRChanges
return comments
}

func (bb bitBucketAPI) limitComments(src []BitBucketPendingComment) []BitBucketPendingComment {
if len(src) <= bb.maxComments {
return src
}
comments := src[:bb.maxComments]
comments = append(comments, BitBucketPendingComment{
Text: fmt.Sprintf(`This pint run would create %d comment(s), which is more than %d limit configured for pint.
%d comments were skipped and won't be visibile on this PR.`, len(src), bb.maxComments, len(src)-bb.maxComments),
Severity: "NORMAL",
Anchor: BitBucketPendingCommentAnchor{
DiffType: "EFFECTIVE",
},
})
return comments
}

func (bb bitBucketAPI) pruneComments(pr *bitBucketPR, currentComments []bitBucketComment, pendingComments []BitBucketPendingComment) {
for _, cur := range currentComments {
slog.Debug(
Expand Down
Loading

0 comments on commit 6cc4900

Please sign in to comment.