Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update application git path on piped started #5328

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
54 changes: 54 additions & 0 deletions pkg/app/server/grpcapi/piped_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type pipedAPIApplicationStore interface {
UpdateDeployingStatus(ctx context.Context, id string, deploying bool) error
UpdateBasicInfo(ctx context.Context, id, name, desc string, labels map[string]string) error
UpdateMostRecentDeployment(ctx context.Context, id string, status model.DeploymentStatus, d *model.ApplicationDeploymentReference) error
UpdateGitPath(ctx context.Context, id string, gitPath *model.ApplicationGitPath) error
}

type pipedAPIDeploymentStore interface {
Expand Down Expand Up @@ -198,6 +199,12 @@ func (a *PipedAPI) ReportPipedMeta(ctx context.Context, req *pipedservice.Report
if err != nil {
return nil, err
}

// application git path may be changed.
if err := a.updateApplicationsGitPath(ctx, piped); err != nil {
return nil, err
}

return &pipedservice.ReportPipedMetaResponse{
Name: piped.Name,
WebBaseUrl: a.webBaseURL,
Expand Down Expand Up @@ -1197,3 +1204,50 @@ func (a *PipedAPI) validateDeploymentBelongsToPiped(ctx context.Context, deploym

return nil
}

// updateApplicationsGitPath updates the git path in order to reflect the changes in the piped.
func (a *PipedAPI) updateApplicationsGitPath(ctx context.Context, piped *model.Piped) error {
opts := datastore.ListOptions{
Filters: []datastore.ListFilter{
{
Field: "ProjectId",
Operator: datastore.OperatorEqual,
Value: piped.ProjectId,
},
{
Field: "PipedId",
Operator: datastore.OperatorEqual,
Value: piped.Id,
},
{
Field: "Disabled",
Operator: datastore.OperatorEqual,
Value: false,
},
},
}
apps, _, err := a.applicationStore.List(ctx, opts)
if err != nil {
return gRPCStoreError(err, "fetch applications")
}
for _, app := range apps {
gitpath, err := makeGitPath(
app.GitPath.Repo.Id,
app.GitPath.Path,
app.GitPath.ConfigFilename,
piped,
a.logger,
)
if err != nil {
return err
}
if gitpath.Repo.Branch == app.GitPath.Repo.Branch &&
gitpath.Repo.Remote == app.GitPath.Repo.Remote {
continue
}
if err := a.applicationStore.UpdateGitPath(ctx, app.Id, gitpath); err != nil {
return gRPCStoreError(err, fmt.Sprintf("update git path of application %s", app.Id))
}
}
return nil
}
283 changes: 283 additions & 0 deletions pkg/app/server/grpcapi/piped_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"go.uber.org/zap"

"github.com/pipe-cd/pipecd/pkg/cache"
"github.com/pipe-cd/pipecd/pkg/cache/cachetest"
Expand Down Expand Up @@ -212,3 +213,285 @@ func TestValidateDeploymentBelongsToPiped(t *testing.T) {
})
}
}

func TestUpdateApplicationsGitPath(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

tests := []struct {
name string
piped *model.Piped
applicationStore datastore.ApplicationStore
wantErr bool
}{
{
name: "failed to list applications",
piped: &model.Piped{
Id: "pipedID",
ProjectId: "projectID",
},
applicationStore: func() datastore.ApplicationStore {
s := datastoretest.NewMockApplicationStore(ctrl)
opts := datastore.ListOptions{
Filters: []datastore.ListFilter{
{
Field: "ProjectId",
Operator: datastore.OperatorEqual,
Value: "projectID",
},
{
Field: "PipedId",
Operator: datastore.OperatorEqual,
Value: "pipedID",
},
{
Field: "Disabled",
Operator: datastore.OperatorEqual,
Value: false,
},
},
}
s.EXPECT().List(gomock.Any(), opts).
Return(nil, "", assert.AnError)
return s
}(),
wantErr: true,
},
{
name: "no need to update",
piped: &model.Piped{
Id: "pipedID",
ProjectId: "projectID",
Repositories: []*model.ApplicationGitRepository{
{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "branch",
},
},
},
applicationStore: func() datastore.ApplicationStore {
s := datastoretest.NewMockApplicationStore(ctrl)
opts := datastore.ListOptions{
Filters: []datastore.ListFilter{
{
Field: "ProjectId",
Operator: datastore.OperatorEqual,
Value: "projectID",
},
{
Field: "PipedId",
Operator: datastore.OperatorEqual,
Value: "pipedID",
},
{
Field: "Disabled",
Operator: datastore.OperatorEqual,
Value: false,
},
},
}
s.EXPECT().List(gomock.Any(), opts).
Return([]*model.Application{
{
Id: "appID",
GitPath: &model.ApplicationGitPath{
Repo: &model.ApplicationGitRepository{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "branch",
},
},
},
}, "", nil)
return s
}(),
wantErr: false,
},
{
name: "failed to make git path",
piped: &model.Piped{
Id: "pipedID",
ProjectId: "projectID",
Repositories: []*model.ApplicationGitRepository{
{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "",
},
},
},
applicationStore: func() datastore.ApplicationStore {
s := datastoretest.NewMockApplicationStore(ctrl)
opts := datastore.ListOptions{
Filters: []datastore.ListFilter{
{
Field: "ProjectId",
Operator: datastore.OperatorEqual,
Value: "projectID",
},
{
Field: "PipedId",
Operator: datastore.OperatorEqual,
Value: "pipedID",
},
{
Field: "Disabled",
Operator: datastore.OperatorEqual,
Value: false,
},
},
}
s.EXPECT().List(gomock.Any(), opts).
Return([]*model.Application{
{
Id: "appID",
GitPath: &model.ApplicationGitPath{
Repo: &model.ApplicationGitRepository{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "branch",
},
},
},
}, "", nil)
return s
}(),
wantErr: true,
},
{
name: "failed to update git path",
piped: &model.Piped{
Id: "pipedID",
ProjectId: "projectID",
Repositories: []*model.ApplicationGitRepository{
{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "branch-changed",
},
},
},
applicationStore: func() datastore.ApplicationStore {
s := datastoretest.NewMockApplicationStore(ctrl)
opts := datastore.ListOptions{
Filters: []datastore.ListFilter{
{
Field: "ProjectId",
Operator: datastore.OperatorEqual,
Value: "projectID",
},
{
Field: "PipedId",
Operator: datastore.OperatorEqual,
Value: "pipedID",
},
{
Field: "Disabled",
Operator: datastore.OperatorEqual,
Value: false,
},
},
}
s.EXPECT().List(gomock.Any(), opts).
Return([]*model.Application{
{
Id: "appID",
GitPath: &model.ApplicationGitPath{
Repo: &model.ApplicationGitRepository{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "branch",
},
},
},
}, "", nil)
gitpath := &model.ApplicationGitPath{
Repo: &model.ApplicationGitRepository{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "branch-changed",
},
Url: "https://test-repo.git//tree/branch-changed/",
}
s.EXPECT().UpdateGitPath(gomock.Any(), "appID", gitpath).
Return(assert.AnError)
return s
}(),
wantErr: true,
},
{
name: "successfully updated",
piped: &model.Piped{
Id: "pipedID",
ProjectId: "projectID",
Repositories: []*model.ApplicationGitRepository{
{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "branch-changed",
},
},
},
applicationStore: func() datastore.ApplicationStore {
s := datastoretest.NewMockApplicationStore(ctrl)
opts := datastore.ListOptions{
Filters: []datastore.ListFilter{
{
Field: "ProjectId",
Operator: datastore.OperatorEqual,
Value: "projectID",
},
{
Field: "PipedId",
Operator: datastore.OperatorEqual,
Value: "pipedID",
},
{
Field: "Disabled",
Operator: datastore.OperatorEqual,
Value: false,
},
},
}
s.EXPECT().List(gomock.Any(), opts).
Return([]*model.Application{
{
Id: "appID",
GitPath: &model.ApplicationGitPath{
Repo: &model.ApplicationGitRepository{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "branch",
},
},
},
}, "", nil)
gitpath := &model.ApplicationGitPath{
Repo: &model.ApplicationGitRepository{
Id: "repoID",
Remote: "https://test-repo.git",
Branch: "branch-changed",
},
Url: "https://test-repo.git//tree/branch-changed/",
}
s.EXPECT().UpdateGitPath(gomock.Any(), "appID", gitpath).
Return(nil)
return s
}(),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
api := &PipedAPI{
applicationStore: tt.applicationStore,
logger: zap.NewNop(),
}
err := api.updateApplicationsGitPath(ctx, tt.piped)
assert.Equal(t, tt.wantErr, err != nil)
})
}
}
8 changes: 8 additions & 0 deletions pkg/datastore/applicationstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ type ApplicationStore interface {
UpdateBasicInfo(ctx context.Context, id, name, description string, labels map[string]string) error
UpdateConfiguration(ctx context.Context, id, pipedID, platformProvider, configFilename string) error
UpdatePlatformProvider(ctx context.Context, id string, provider string) error
UpdateGitPath(ctx context.Context, id string, gitPath *model.ApplicationGitPath) error
}

type applicationStore struct {
Expand Down Expand Up @@ -377,3 +378,10 @@ func (s *applicationStore) UpdatePlatformProvider(ctx context.Context, id string
return nil
})
}

func (s *applicationStore) UpdateGitPath(ctx context.Context, id string, gitPath *model.ApplicationGitPath) error {
return s.update(ctx, id, func(app *model.Application) error {
app.GitPath = gitPath
return nil
})
}
Loading
Loading