in controllers/codebasebranch/chain/put_branch_in_git/put_branch_in_git.go [27:148]
func (h PutBranchInGit) ServeRequest(ctx context.Context, branch *codebaseApi.CodebaseBranch) error {
log := ctrl.LoggerFrom(ctx)
if branch.Status.Git == codebaseApi.CodebaseBranchGitStatusBranchCreated {
log.Info("Branch is already created in git")
if err := handler.NextServeOrNil(ctx, h.Next, branch); err != nil {
return fmt.Errorf("failed to process next handler in chain: %w", err)
}
return nil
}
log.Info("Start creating branch in git")
if err := h.setIntermediateSuccessFields(branch, codebaseApi.AcceptCodebaseBranchRegistration); err != nil {
return err
}
codebase := &codebaseApi.Codebase{}
if err := h.Client.Get(ctx, client.ObjectKey{
Namespace: branch.Namespace,
Name: branch.Spec.CodebaseName,
}, codebase); err != nil {
setFailedFields(branch, codebaseApi.PutGitBranch, err.Error())
return fmt.Errorf("failed to fetch Codebase: %w", err)
}
if !codebase.Status.Available {
log.Info("failed to start reconciling for branch; codebase is unavailable", "codebase", codebase.Name)
return util.NewCodebaseBranchReconcileError(fmt.Sprintf("%v codebase is unavailable", codebase.Name))
}
gitServer := &codebaseApi.GitServer{}
if err := h.Client.Get(
ctx,
client.ObjectKey{
Namespace: branch.Namespace,
Name: codebase.Spec.GitServer,
},
gitServer,
); err != nil {
setFailedFields(branch, codebaseApi.PutGitBranch, err.Error())
return fmt.Errorf("failed to fetch GitServer: %w", err)
}
secret := &corev1.Secret{}
if err := h.Client.Get(
ctx,
client.ObjectKey{
Namespace: branch.Namespace,
Name: gitServer.Spec.NameSshKeySecret,
},
secret,
); err != nil {
err = fmt.Errorf("failed to get %v secret: %w", gitServer.Spec.NameSshKeySecret, err)
setFailedFields(branch, codebaseApi.PutGitBranch, err.Error())
return err
}
wd := util.GetWorkDir(branch.Spec.CodebaseName, fmt.Sprintf("%v-%v", branch.Namespace, branch.Spec.BranchName))
if !checkDirectory(wd) {
repoSshUrl := util.GetSSHUrl(gitServer, codebase.Spec.GetProjectID())
if err := h.Git.CloneRepositoryBySsh(
ctx,
string(secret.Data[util.PrivateSShKeyName]),
gitServer.Spec.GitUser,
repoSshUrl,
wd,
gitServer.Spec.SshPort,
); err != nil {
setFailedFields(branch, codebaseApi.PutGitBranch, err.Error())
return fmt.Errorf("failed to clone repository: %w", err)
}
}
currentBranchName, err := h.Git.GetCurrentBranchName(wd)
if err != nil {
return fmt.Errorf("failed to get current branch name: %w", err)
}
if currentBranchName != codebase.Spec.DefaultBranch {
if err = h.Git.CheckoutRemoteBranchBySSH(string(secret.Data[util.PrivateSShKeyName]), gitServer.Spec.GitUser, wd, codebase.Spec.DefaultBranch); err != nil {
return fmt.Errorf("failed to checkout to default branch %s: %w", codebase.Spec.DefaultBranch, err)
}
}
err = h.Git.CreateRemoteBranch(string(secret.Data[util.PrivateSShKeyName]), gitServer.Spec.GitUser, wd, branch.Spec.BranchName, branch.Spec.FromCommit, gitServer.Spec.SshPort)
if err != nil {
setFailedFields(branch, codebaseApi.PutGitBranch, err.Error())
// We need to remove work directory if branch creation failed(push error).
// Otherwise, the next time the branch creation will be skipped because local branch already exists.
if err = util.RemoveDirectory(wd); err != nil {
log.Error(err, "failed to remove directory", "path", wd)
}
return fmt.Errorf("failed to create remote branch: %w", err)
}
branch.Status.Git = codebaseApi.CodebaseBranchGitStatusBranchCreated
if err = h.Client.Status().Update(ctx, branch); err != nil {
branch.Status.Git = ""
setFailedFields(branch, codebaseApi.PutGitBranch, err.Error())
return fmt.Errorf("failed to update CodebaseBranch status: %w", err)
}
log.Info("Branch has been created in git")
err = handler.NextServeOrNil(ctx, h.Next, branch)
if err != nil {
return fmt.Errorf("failed to process next handler in chain: %w", err)
}
return nil
}