Skip to content

Commit

Permalink
fix(api,vcs,repositories): improve migrate ascode (#5083)
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlt authored Apr 15, 2020
1 parent a07869f commit bae5d4e
Show file tree
Hide file tree
Showing 23 changed files with 243 additions and 219 deletions.
5 changes: 4 additions & 1 deletion cli/cdsctl/template_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ func suggestTemplate() (*sdk.WorkflowTemplate, error) {
if err != nil {
return nil, err
}
if len(wts) == 0 {
return nil, fmt.Errorf("no existing template found from CDS")
}
opts := make([]string, len(wts))
for i := range wts {
opts[i] = fmt.Sprintf("%s (%s/%s)", wts[i].Name, wts[i].Group.Name, wts[i].Slug)
Expand Down Expand Up @@ -292,7 +295,7 @@ func templateApplyRun(v cli.Values) error {
}
}

if !importAsCode && !importPush && !detached {
if !importAsCode && !importPush {
if localRepoURL != "" {
importAsCode = cli.AskConfirm(fmt.Sprintf("Import the generated workflow as code to the %s project", projectKey))
}
Expand Down
18 changes: 11 additions & 7 deletions engine/api/ascode/sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ func SyncAsCodeEvent(ctx context.Context, db *gorp.DbMap, store cache.Store, pro
log.Debug("Pull request %s #%d not found", app.RepositoryFullname, int(ascodeEvt.PullRequestID))
}

// If the PR was merged we want to set the repo url on the workflow
if ascodeEvt.Migrate && len(ascodeEvt.Data.Workflows) == 1 {
for id := range ascodeEvt.Data.Workflows {
if pr.Merged {
if err := workflow.UpdateFromRepository(tx, id, fromRepo); err != nil {
return nil, fromRepo, err
}
}
}
}

// If event ended, delete it from db
if prNotFound || pr.Merged || pr.Closed {
eventToDelete = append(eventToDelete, ascodeEvt)
Expand All @@ -74,13 +85,6 @@ func SyncAsCodeEvent(ctx context.Context, db *gorp.DbMap, store cache.Store, pro
if err := ascode.DeleteAsCodeEvent(tx, ascodeEvt); err != nil {
return nil, fromRepo, err
}
if ascodeEvt.Migrate && len(ascodeEvt.Data.Workflows) == 1 {
for id := range ascodeEvt.Data.Workflows {
if err := workflow.UpdateFromRepository(tx, id, fromRepo); err != nil {
return nil, fromRepo, err
}
}
}
}

if err := tx.Commit(); err != nil {
Expand Down
1 change: 0 additions & 1 deletion engine/api/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (

func (api *API) updateAsCodePipelineHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
// Get project name in URL
vars := mux.Vars(r)
key := vars[permProjectKey]
name := vars["pipelineKey"]
Expand Down
1 change: 1 addition & 0 deletions engine/api/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ func (api *API) postTemplateBulkHandler() service.Handler {

errorDefer := func(err error) error {
if err != nil {
log.Error(ctx, "%v", err)
bulk.Operations[i].Status = sdk.OperationStatusError
bulk.Operations[i].Error = fmt.Sprintf("%s", sdk.Cause(err))
if err := workflowtemplate.UpdateBulk(api.mustDB(), &bulk); err != nil {
Expand Down
1 change: 0 additions & 1 deletion engine/api/workflow/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ func UpdateFromRepository(db gorp.SqlExecutor, workflowID int64, fromRepository
if _, err := db.Exec("UPDATE workflow SET from_repository = $1, last_modified = current_timestamp WHERE id = $2", fromRepository, workflowID); err != nil {
return sdk.WithStack(err)
}

return nil
}

Expand Down
3 changes: 2 additions & 1 deletion engine/api/workflow_ascode.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ func (api *API) getWorkflowAsCodeHandler() service.Handler {
}

// postWorkflowAsCodeHandler Update an as code workflow
// @title Make the workflow as code // @title Update an as code workflow
// @title Make the workflow as code
// @title Update an as code workflow
func (api *API) postWorkflowAsCodeHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
Expand Down
2 changes: 1 addition & 1 deletion engine/repositories/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (s *Service) checkOrCreateFS(r *sdk.OperationRepo) error {
path := filepath.Join(s.Cfg.Basedir, r.ID())
fi, err := os.Stat(path)
if os.IsNotExist(err) {
return sdk.WrapError(os.MkdirAll(path, os.FileMode(0700)), "checkOrCreateFS> unable to create directory %s", path)
return sdk.WrapError(os.MkdirAll(path, os.FileMode(0700)), "unable to create directory %s", path)
}
if fi.IsDir() {
return nil
Expand Down
24 changes: 24 additions & 0 deletions engine/repositories/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package repositories

import (
"context"
"fmt"
"time"

"github.com/sirupsen/logrus"

"github.com/ovh/cds/sdk"
"github.com/ovh/cds/sdk/log"
)
Expand Down Expand Up @@ -45,6 +48,13 @@ func (s *Service) do(ctx context.Context, op sdk.Operation) error {
// Load workflow as code file
case op.Setup.Checkout.Branch != "" || op.Setup.Checkout.Tag != "":
if err := s.processCheckout(ctx, &op); err != nil {
isErrWithStack := sdk.IsErrorWithStack(err)
fields := logrus.Fields{}
if isErrWithStack {
fields["stack_trace"] = fmt.Sprintf("%+v", err)
}
log.ErrorWithFields(ctx, fields, "%s", err)

op.Error = sdk.Cause(err).Error()
op.Status = sdk.OperationStatusError
} else {
Expand All @@ -53,6 +63,13 @@ func (s *Service) do(ctx context.Context, op sdk.Operation) error {
switch {
case op.LoadFiles.Pattern != "":
if err := s.processLoadFiles(ctx, &op); err != nil {
isErrWithStack := sdk.IsErrorWithStack(err)
fields := logrus.Fields{}
if isErrWithStack {
fields["stack_trace"] = fmt.Sprintf("%+v", err)
}
log.ErrorWithFields(ctx, fields, "%s", err)

op.Error = sdk.Cause(err).Error()
op.Status = sdk.OperationStatusError
} else {
Expand All @@ -67,6 +84,13 @@ func (s *Service) do(ctx context.Context, op sdk.Operation) error {
// Push workflow as code file
case op.Setup.Push.FromBranch != "":
if err := s.processPush(ctx, &op); err != nil {
isErrWithStack := sdk.IsErrorWithStack(err)
fields := logrus.Fields{}
if isErrWithStack {
fields["stack_trace"] = fmt.Sprintf("%+v", err)
}
log.ErrorWithFields(ctx, fields, "%s", err)

op.Error = sdk.Cause(err).Error()
op.Status = sdk.OperationStatusError
} else {
Expand Down
37 changes: 14 additions & 23 deletions engine/repositories/processor_checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,58 +14,49 @@ func (s *Service) processCheckout(ctx context.Context, op *sdk.Operation) error
}

if err := gitRepo.ResetHard("origin/" + currentBranch); err != nil {
log.Error(ctx, "Repositories> processCheckout> ResetHard> [%s] Error: %v", op.UUID, err)
return err
return sdk.WithStack(err)
}

if op.Setup.Checkout.Tag != "" {
log.Debug("Repositories> processCheckout> fetching tag %s from %s", op.Setup.Checkout.Tag, op.URL)
log.Debug("processCheckout> fetching tag %s from %s", op.Setup.Checkout.Tag, op.URL)
if err := gitRepo.FetchRemoteTag("origin", op.Setup.Checkout.Tag); err != nil {
log.Error(ctx, "Repositories> processCheckout> FetchRemoteTag> [%s] error %v", op.UUID, err)
return err
return sdk.WithStack(err)
}
} else {
if op.Setup.Checkout.Branch == "" {
op.Setup.Checkout.Branch = op.RepositoryInfo.DefaultBranch
}

log.Debug("Repositories> processCheckout> fetching branch %s from %s", op.Setup.Checkout.Branch, op.URL)
log.Debug("processCheckout> fetching branch %s from %s", op.Setup.Checkout.Branch, op.URL)
if err := gitRepo.FetchRemoteBranch("origin", op.Setup.Checkout.Branch); err != nil {
log.Error(ctx, "Repositories> processCheckout> FetchRemoteBranch> [%s] error %v", op.UUID, err)
return err
return sdk.WithStack(err)
}
}

//Check commit
// Check commit
if op.Setup.Checkout.Commit == "" {
log.Debug("Repositories> processCheckout> pulling branch %s", op.Setup.Checkout.Branch)
log.Debug("processCheckout> pulling branch %s", op.Setup.Checkout.Branch)
if err := gitRepo.Pull("origin", op.Setup.Checkout.Branch); err != nil {
log.Error(ctx, "Repositories> processCheckout> Pull without commit> [%s] error %v", op.UUID, err)
return err
return sdk.WithStack(err)
}
} else {
currentCommit, err := gitRepo.LatestCommit()
if err != nil {
log.Error(ctx, "Repositories> processCheckout> LatestCommit> [%s] error %v", op.UUID, err)
return err
return sdk.WithStack(err)
}
if currentCommit.LongHash != op.Setup.Checkout.Commit {
//Not the same commit
//Pull and reset HARD the commit
log.Debug("Repositories> processCheckout> resetting the branch %s from remote", op.Setup.Checkout.Branch)
// Not the same commit, pull and reset HARD the commit
log.Debug("processCheckout> resetting the branch %s from remote", op.Setup.Checkout.Branch)
if err := gitRepo.ResetHard("origin/" + op.Setup.Checkout.Branch); err != nil {
log.Error(ctx, "Repositories> processCheckout> ResetHard> [%s] error %v", op.UUID, err)
return err
return sdk.WithStack(err)
}

log.Debug("Repositories> processCheckout> reseting commit %s", op.Setup.Checkout.Commit)
if err := gitRepo.ResetHard(op.Setup.Checkout.Commit); err != nil {
log.Error(ctx, "Repositories> processCheckout> ResetHard> [%s] error %v", op.UUID, err)
return err
return sdk.WithStack(err)
}
}
}

log.Info(ctx, "Repositories> processCheckout> repository %s ready", op.URL)
log.Info(ctx, "processCheckout> repository %s ready", op.URL)
return nil
}
11 changes: 4 additions & 7 deletions engine/repositories/processor_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,36 @@ func (s *Service) processGitClone(ctx context.Context, op *sdk.Operation) (repo.

r := s.Repo(*op)
if err := s.checkOrCreateFS(r); err != nil {
log.Error(ctx, "Repositories> processGitClone> checkOrCreateFS> [%s] Error %v", op.UUID, err)
return gitRepo, "", "", err
}

// Get the git repository
opts := []repo.Option{repo.WithVerbose()}

if op.RepositoryStrategy.ConnectionType == "ssh" {
log.Debug("Repositories> processGitClone> using ssh key %s", op.RepositoryStrategy.SSHKey)
log.Debug("processGitClone> using ssh key %s", op.RepositoryStrategy.SSHKey)
opts = append(opts, repo.WithSSHAuth([]byte(op.RepositoryStrategy.SSHKeyContent)))
} else if op.RepositoryStrategy.User != "" && op.RepositoryStrategy.Password != "" {
log.Debug("processGitClone> using user %s", op.RepositoryStrategy.User)
opts = append(opts, repo.WithHTTPAuth(op.RepositoryStrategy.User, op.RepositoryStrategy.Password))
}

gitRepo, err := repo.New(r.Basedir, opts...)
if err != nil {
log.Info(ctx, "Repositories> processGitClone> cloning %s into %s", r.URL, r.Basedir)
log.Info(ctx, "processGitClone> cloning %s into %s", r.URL, r.Basedir)
gitRepo, err = repo.Clone(r.Basedir, r.URL, opts...)
if err != nil {
log.Error(ctx, "Repositories> processGitClone> Clone> [%s] error %v", op.UUID, err)
return gitRepo, "", "", err
}
}

f, err := gitRepo.FetchURL()
if err != nil {
log.Error(ctx, "Repositories> processGitClone> gitRepo.FetchURL> [%s] Error: %v", op.UUID, err)
return gitRepo, "", "", err
}

d, err := gitRepo.DefaultBranch()
if err != nil {
log.Error(ctx, "Repositories> processGitClone> DefaultBranch> [%s] Error: %v", op.UUID, err)
return gitRepo, "", "", err
}

Expand All @@ -58,7 +56,6 @@ func (s *Service) processGitClone(ctx context.Context, op *sdk.Operation) (repo.
//Check branch
currentBranch, err := gitRepo.CurrentBranch()
if err != nil {
log.Error(ctx, "Repositories> processGitClone> CurrentBranch> [%s] error %v", op.UUID, err)
return gitRepo, "", "", err
}
return gitRepo, r.Basedir, currentBranch, nil
Expand Down
Loading

0 comments on commit bae5d4e

Please sign in to comment.