Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 @@ -371,13 +372,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 @@ -408,14 +424,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 @@ -442,9 +454,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 @@ -518,11 +519,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 @@ -550,11 +564,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 @@ -576,9 +586,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 @@ -949,6 +950,7 @@ func TestGetFiles(t *testing.T) {
wantDeletedFilesCount int
wantModifiedFilesCount int
wantRenamedFilesCount int
wantAPIRequestCount int64
}{
{
name: "pull-request",
Expand Down Expand Up @@ -977,6 +979,7 @@ func TestGetFiles(t *testing.T) {
wantDeletedFilesCount: 1,
wantModifiedFilesCount: 1,
wantRenamedFilesCount: 1,
wantAPIRequestCount: 2,
},
{
name: "push",
Expand Down Expand Up @@ -1007,51 +1010,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 @@ -1060,17 +1035,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 @@ -1089,6 +1073,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 @@ -1439,18 +1428,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