Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ linters:
- zerologlint
settings:
misspell:
ignore-words:
ignore-rules:
- cancelled
extra-words:
- typo: "canceled"
Expand All @@ -72,6 +72,8 @@ linters:
- fmt.Fprintln
- (io.Closer).Close
- updateConfigMap
exhaustive:
default-signifies-exhaustive: true
gocritic:
disabled-checks:
- unlambda
Expand Down
37 changes: 25 additions & 12 deletions pkg/provider/bitbucketdatacenter/bitbucketdatacenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type Provider struct {
projectKey string
repo *v1alpha1.Repository
triggerEvent string
cachedChangedFiles *changedfiles.ChangedFiles
}

func (v Provider) Client() *scm.Client {
Expand Down Expand Up @@ -370,13 +371,28 @@ func (v *Provider) GetConfig() *info.ProviderConfig {
}
}

// GetFiles gets and caches the list of files changed by a given event.
func (v *Provider) GetFiles(ctx context.Context, runevent *info.Event) (changedfiles.ChangedFiles, error) {
OrgAndRepo := fmt.Sprintf("%s/%s", runevent.Organization, runevent.Repository)
if runevent.TriggerTarget == triggertype.PullRequest {
if v.cachedChangedFiles == nil {
changes, err := v.fetchChangedFiles(ctx, runevent)
if err != nil {
return changedfiles.ChangedFiles{}, err
}
v.cachedChangedFiles = &changes
}
return *v.cachedChangedFiles, nil
}

func (v *Provider) fetchChangedFiles(ctx context.Context, runevent *info.Event) (changedfiles.ChangedFiles, error) {
changedFiles := changedfiles.ChangedFiles{}

orgAndRepo := fmt.Sprintf("%s/%s", runevent.Organization, runevent.Repository)

switch runevent.TriggerTarget {
case triggertype.PullRequest:
opts := &scm.ListOptions{Page: 1, Size: apiResponseLimit}
changedFiles := changedfiles.ChangedFiles{}
for {
changes, _, err := v.Client().PullRequests.ListChanges(ctx, OrgAndRepo, runevent.PullRequestNumber, opts)
changes, _, err := v.Client().PullRequests.ListChanges(ctx, orgAndRepo, runevent.PullRequestNumber, opts)
if err != nil {
return changedfiles.ChangedFiles{}, fmt.Errorf("failed to list changes for pull request: %w", err)
}
Expand Down Expand Up @@ -407,14 +423,10 @@ func (v *Provider) GetFiles(ctx context.Context, runevent *info.Event) (changedf

opts.Page++
}
return changedFiles, nil
}

if runevent.TriggerTarget == triggertype.Push {
case triggertype.Push:
opts := &scm.ListOptions{Page: 1, Size: apiResponseLimit}
changedFiles := changedfiles.ChangedFiles{}
for {
changes, _, err := v.Client().Git.ListChanges(ctx, OrgAndRepo, runevent.SHA, opts)
changes, _, err := v.Client().Git.ListChanges(ctx, orgAndRepo, runevent.SHA, opts)
if err != nil {
return changedfiles.ChangedFiles{}, fmt.Errorf("failed to list changes for commit %s: %w", runevent.SHA, err)
}
Expand All @@ -441,9 +453,10 @@ func (v *Provider) GetFiles(ctx context.Context, runevent *info.Event) (changedf

opts.Page++
}
return changedFiles, nil
default:
// No action necessary
Comment on lines +457 to +458
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default here is for the switch to be "exhaustive"

}
return changedfiles.ChangedFiles{}, nil
return changedFiles, nil
}

func (v *Provider) CreateToken(_ context.Context, _ []string, _ *info.Event) (string, error) {
Expand Down
25 changes: 22 additions & 3 deletions pkg/provider/bitbucketdatacenter/bitbucketdatacenter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ import (
"github.com/openshift-pipelines/pipelines-as-code/pkg/params/triggertype"
"github.com/openshift-pipelines/pipelines-as-code/pkg/provider"
bbtest "github.com/openshift-pipelines/pipelines-as-code/pkg/provider/bitbucketdatacenter/test"
"github.com/openshift-pipelines/pipelines-as-code/pkg/test/metrics"

"github.com/jenkins-x/go-scm/scm"
"go.uber.org/zap"
zapobserver "go.uber.org/zap/zaptest/observer"
"gotest.tools/v3/assert"
"knative.dev/pkg/metrics/metricstest"
_ "knative.dev/pkg/metrics/testing"
rtesting "knative.dev/pkg/reconciler/testing"
)

Expand Down Expand Up @@ -796,6 +799,7 @@ func TestGetFiles(t *testing.T) {
ctx, _ := rtesting.SetupFakeContext(t)
client, mux, tearDown, tURL := bbtest.SetupBBDataCenterClient()
defer tearDown()
metrics.ResetMetrics()

stats := &bbtest.DiffStats{
Values: tt.changeFiles,
Expand All @@ -821,13 +825,17 @@ func TestGetFiles(t *testing.T) {
}
})
}
v := &Provider{client: client, baseURL: tURL}

metricsTags := map[string]string{"provider": "bitbucket-datacenter", "event-type": string(tt.event.TriggerTarget)}
metricstest.CheckStatsNotReported(t, "pipelines_as_code_git_provider_api_request_count")

v := &Provider{client: client, baseURL: tURL, triggerEvent: string(tt.event.TriggerTarget)}
changedFiles, err := v.GetFiles(ctx, tt.event)
if tt.wantError {
assert.Equal(t, err.Error(), tt.errMsg)
return
} else {
assert.NilError(t, err, nil)
}
assert.NilError(t, err, nil)
assert.Equal(t, tt.wantAddedFilesCount, len(changedFiles.Added))
assert.Equal(t, tt.wantDeletedFilesCount, len(changedFiles.Deleted))
assert.Equal(t, tt.wantModifiedFilesCount, len(changedFiles.Modified))
Expand All @@ -844,6 +852,17 @@ func TestGetFiles(t *testing.T) {
assert.Equal(t, tt.changeFiles[i].Path.ToString, changedFiles.All[i])
}
}

// Check caching
metricstest.CheckCountData(t, "pipelines_as_code_git_provider_api_request_count", metricsTags, 1)
_, _ = v.GetFiles(ctx, tt.event)
if tt.wantError {
// No caching on error
metricstest.CheckCountData(t, "pipelines_as_code_git_provider_api_request_count", metricsTags, 2)
} else {
// Cache API results on success
metricstest.CheckCountData(t, "pipelines_as_code_git_provider_api_request_count", metricsTags, 1)
}
})
}
}
33 changes: 22 additions & 11 deletions pkg/provider/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ type Provider struct {
PaginedNumber int
userType string // The type of user i.e bot or not
skippedRun
triggerEvent string
triggerEvent string
cachedChangedFiles *changedfiles.ChangedFiles
}

type skippedRun struct {
Expand Down Expand Up @@ -517,11 +518,24 @@ func (v *Provider) getPullRequest(ctx context.Context, runevent *info.Event) (*i
return runevent, nil
}

// GetFiles get a files from pull request.
// GetFiles gets and caches the list of files changed by a given event.
func (v *Provider) GetFiles(ctx context.Context, runevent *info.Event) (changedfiles.ChangedFiles, error) {
if runevent.TriggerTarget == triggertype.PullRequest {
if v.cachedChangedFiles == nil {
changes, err := v.fetchChangedFiles(ctx, runevent)
if err != nil {
return changedfiles.ChangedFiles{}, err
}
v.cachedChangedFiles = &changes
}
return *v.cachedChangedFiles, nil
}

func (v *Provider) fetchChangedFiles(ctx context.Context, runevent *info.Event) (changedfiles.ChangedFiles, error) {
changedFiles := changedfiles.ChangedFiles{}

switch runevent.TriggerTarget {
case triggertype.PullRequest:
opt := &github.ListOptions{PerPage: v.PaginedNumber}
changedFiles := changedfiles.ChangedFiles{}
for {
repoCommit, resp, err := wrapAPI(v, "list_pull_request_files", func() ([]*github.CommitFile, *github.Response, error) {
return v.Client().PullRequests.ListFiles(ctx, runevent.Organization, runevent.Repository, runevent.PullRequestNumber, opt)
Expand Down Expand Up @@ -549,11 +563,7 @@ func (v *Provider) GetFiles(ctx context.Context, runevent *info.Event) (changedf
}
opt.Page = resp.NextPage
}
return changedFiles, nil
}

if runevent.TriggerTarget == "push" {
changedFiles := changedfiles.ChangedFiles{}
case triggertype.Push:
rC, _, err := wrapAPI(v, "get_commit_files", func() (*github.RepositoryCommit, *github.Response, error) {
return v.Client().Repositories.GetCommit(ctx, runevent.Organization, runevent.Repository, runevent.SHA, &github.ListOptions{})
})
Expand All @@ -575,9 +585,10 @@ func (v *Provider) GetFiles(ctx context.Context, runevent *info.Event) (changedf
changedFiles.Renamed = append(changedFiles.Renamed, *rC.Files[i].Filename)
}
}
return changedFiles, nil
default:
// No action necessary
}
return changedfiles.ChangedFiles{}, nil
return changedFiles, nil
}

// getObject Get an object from a repository.
Expand Down
69 changes: 23 additions & 46 deletions pkg/provider/github/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/jonboulle/clockwork"
"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/keys"
"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1"
"github.com/openshift-pipelines/pipelines-as-code/pkg/metrics"
"github.com/openshift-pipelines/pipelines-as-code/pkg/params"
"github.com/openshift-pipelines/pipelines-as-code/pkg/params/clients"
"github.com/openshift-pipelines/pipelines-as-code/pkg/params/info"
Expand All @@ -29,6 +28,8 @@ import (
testclient "github.com/openshift-pipelines/pipelines-as-code/pkg/test/clients"
ghtesthelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test/github"
"github.com/openshift-pipelines/pipelines-as-code/pkg/test/logger"
"github.com/openshift-pipelines/pipelines-as-code/pkg/test/metrics"

"go.uber.org/zap"
zapobserver "go.uber.org/zap/zaptest/observer"
"gotest.tools/v3/assert"
Expand Down Expand Up @@ -347,7 +348,7 @@ func TestGetTektonDir(t *testing.T) {
}
for _, tt := range testGetTektonDir {
t.Run(tt.name, func(t *testing.T) {
resetMetrics()
metrics.ResetMetrics()
observer, exporter := zapobserver.New(zap.InfoLevel)
fakelogger := zap.New(observer).Sugar()
ctx, _ := rtesting.SetupFakeContext(t)
Expand Down Expand Up @@ -892,6 +893,7 @@ func TestGetFiles(t *testing.T) {
wantDeletedFilesCount int
wantModifiedFilesCount int
wantRenamedFilesCount int
wantAPIRequestCount int64
}{
{
name: "pull-request",
Expand Down Expand Up @@ -920,6 +922,7 @@ func TestGetFiles(t *testing.T) {
wantDeletedFilesCount: 1,
wantModifiedFilesCount: 1,
wantRenamedFilesCount: 1,
wantAPIRequestCount: 2,
},
{
name: "push",
Expand Down Expand Up @@ -950,51 +953,23 @@ func TestGetFiles(t *testing.T) {
wantDeletedFilesCount: 1,
wantModifiedFilesCount: 1,
wantRenamedFilesCount: 1,
wantAPIRequestCount: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
defer teardown()
prCommitFiles := []*github.CommitFile{
{
Filename: ptr.String("modified.yaml"),
Status: ptr.String("modified"),
}, {
Filename: ptr.String("added.doc"),
Status: ptr.String("added"),
}, {
Filename: ptr.String("removed.yaml"),
Status: ptr.String("removed"),
}, {
Filename: ptr.String("renamed.doc"),
Status: ptr.String("renamed"),
},
}
metrics.ResetMetrics()

pushCommitFiles := []*github.CommitFile{
{
Filename: ptr.String("modified.yaml"),
Status: ptr.String("modified"),
}, {
Filename: ptr.String("added.doc"),
Status: ptr.String("added"),
}, {
Filename: ptr.String("removed.yaml"),
Status: ptr.String("removed"),
}, {
Filename: ptr.String("renamed.doc"),
Status: ptr.String("renamed"),
},
}
if tt.event.TriggerTarget == "pull_request" {
mux.HandleFunc(fmt.Sprintf("/repos/%s/%s/pulls/%d/files",
tt.event.Organization, tt.event.Repository, tt.event.PullRequestNumber), func(rw http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("page") == "" || r.URL.Query().Get("page") == "1" {
rw.Header().Add("Link", fmt.Sprintf("<https://api.github.com/repos/%s/%s/pulls/%d/files?page=2>; rel=\"next\"", tt.event.Organization, tt.event.Repository, tt.event.PullRequestNumber))
fmt.Fprint(rw, "[]")
} else {
b, _ := json.Marshal(prCommitFiles)
b, _ := json.Marshal(tt.commitFiles)
fmt.Fprint(rw, string(b))
}
})
Expand All @@ -1003,17 +978,26 @@ func TestGetFiles(t *testing.T) {
mux.HandleFunc(fmt.Sprintf("/repos/%s/%s/commits/%s",
tt.event.Organization, tt.event.Repository, tt.event.SHA), func(rw http.ResponseWriter, _ *http.Request) {
c := &github.RepositoryCommit{
Files: pushCommitFiles,
Files: tt.commit.Files,
}
b, _ := json.Marshal(c)
fmt.Fprint(rw, string(b))
})
}

metricsTags := map[string]string{"provider": "github", "event-type": string(tt.event.TriggerTarget)}
metricstest.CheckStatsNotReported(t, "pipelines_as_code_git_provider_api_request_count")

log, _ := logger.GetLogger()
ctx, _ := rtesting.SetupFakeContext(t)
provider := &Provider{
ghClient: fakeclient,
PaginedNumber: 1,

// necessary for metrics
providerName: "github",
triggerEvent: string(tt.event.TriggerTarget),
Logger: log,
}
changedFiles, err := provider.GetFiles(ctx, tt.event)
assert.NilError(t, err, nil)
Expand All @@ -1032,6 +1016,11 @@ func TestGetFiles(t *testing.T) {
assert.Equal(t, *tt.commit.Files[i].Filename, changedFiles.All[i])
}
}

// Check caching
metricstest.CheckCountData(t, "pipelines_as_code_git_provider_api_request_count", metricsTags, tt.wantAPIRequestCount)
_, _ = provider.GetFiles(ctx, tt.event)
metricstest.CheckCountData(t, "pipelines_as_code_git_provider_api_request_count", metricsTags, tt.wantAPIRequestCount)
})
}
}
Expand Down Expand Up @@ -1382,18 +1371,6 @@ func TestIsHeadCommitOfBranch(t *testing.T) {
}
}

func resetMetrics() {
metricstest.Unregister(
"pipelines_as_code_pipelinerun_count",
"pipelines_as_code_pipelinerun_duration_seconds_sum",
"pipelines_as_code_running_pipelineruns_count",
"pipelines_as_code_git_provider_api_request_count",
)

// have to reset sync.Once to allow recreation of Recorder.
metrics.ResetRecorder()
}

func TestCreateComment(t *testing.T) {
tests := []struct {
name string
Expand Down
Loading