in controller/merge_request/controller.go [411:515]
func (c *Controller) prepareMergeRequest(ctx context.Context, instance *gerritService.GerritMergeRequest) error {
if instance.Labels[registry.MRLabelAction] != registry.MRLabelActionBranchMerge ||
instance.Spec.SourceBranch != "" || instance.Status.ChangeID != "" {
c.logger.Infow("nothing need to be done", "Request.Namespace", instance.Namespace,
"Request.Name", instance.Name)
return nil
}
_, backupFolderPath, projectPath, err := prepareControllerFolders(c.cnf.TempFolder, instance.Spec.ProjectName)
if err != nil {
return fmt.Errorf("unable to prepare controller tmp folders, err: %w", err)
}
gitService, err := c.initGitService(ctx, projectPath)
if err != nil {
return fmt.Errorf("unable to init git service, err: %w", err)
}
targetBranch, sourceBranch, err := getBranchesFromLabels(instance.Labels)
if err != nil {
return fmt.Errorf("unable to get branches from instance labels, err: %w", err)
}
if err := gitService.Clone(fmt.Sprintf("%s/%s", codebase.GerritSSHURL(c.cnf), instance.Spec.ProjectName)); err != nil {
return fmt.Errorf("unable to clone repo, err: %w", err)
}
if err := gitService.RawCheckout(targetBranch, false); err != nil {
return fmt.Errorf("unable to checkout branch, err: %w", err)
}
//backup values.yaml
valuesBackupPath := path.Join(backupFolderPath, "backup-values.yaml")
projectValuesPath := path.Join(projectPath, registry.ValuesLocation)
if err := CopyFile(projectValuesPath, valuesBackupPath); err != nil {
return fmt.Errorf("unable to backup values yaml, err: %w", err)
}
if err := gitService.RawCheckout(sourceBranch, false); err != nil {
return fmt.Errorf("unable to checkout, err: %w", err)
}
//backup source branch
projectBackupPath, err := backupProject(backupFolderPath, projectPath, instance.Spec.ProjectName)
if err != nil {
return fmt.Errorf("unable to backup source branch, err: %w", err)
}
//checkout to target branch
if err := gitService.RawCheckout(targetBranch, false); err != nil {
return fmt.Errorf("unable to checkout, err: %w", err)
}
//delete source branch
if err := gitService.DeleteBranch(sourceBranch); err != nil {
return fmt.Errorf("unable to delete source branch, err: %w", err)
}
//recreate source branch
if err := gitService.RawCheckout(sourceBranch, true); err != nil {
return fmt.Errorf("unable to checkout to source branch, err: %w", err)
}
//restore source branch
if err := CopyFolder(fmt.Sprintf("%s/.", projectBackupPath), fmt.Sprintf("%s/", projectPath)); err != nil {
return fmt.Errorf("unable to restore source branch, err: %w", err)
}
//merge values from target branch
if err := MergeValuesFiles(valuesBackupPath, projectValuesPath); err != nil {
return fmt.Errorf("unable to merge values, err: %w", err)
}
//add all changes
if err := gitService.Add("."); err != nil {
return fmt.Errorf("unable to add all files, err: %w", err)
}
changeID, err := gitService.GenerateChangeID()
if err != nil {
return fmt.Errorf("unable to generate change id, err: %w", err)
}
if err := gitService.RawCommit(&git.User{Name: instance.Spec.AuthorName, Email: instance.Spec.AuthorEmail},
git.CommitMessageWithChangeID(
fmt.Sprintf("Add new branch %s\n\nupdate branch values.yaml from [%s] branch", sourceBranch,
targetBranch),
changeID)); err != nil && !strings.Contains(err.Error(), "nothing to commit") {
return fmt.Errorf("unable to commit changes, %w", err)
}
if err := gitService.Push("origin", fmt.Sprintf("refs/heads/%s:%s", sourceBranch, sourceBranch), "--force"); err != nil {
return fmt.Errorf("unable to push repo, err: %w", err)
}
var reloadInstance gerritService.GerritMergeRequest
if err := c.k8sClient.Get(ctx, types.NamespacedName{Namespace: instance.Namespace, Name: instance.Name}, &reloadInstance); err != nil {
return fmt.Errorf("unable to reload instance, err: %w", err)
}
reloadInstance.Spec.SourceBranch = sourceBranch
reloadInstance.Name = fmt.Sprintf("%s-update-%d", instance.Spec.ProjectName, time.Now().Unix())
reloadInstance.ResourceVersion = ""
if err := c.k8sClient.Create(ctx, &reloadInstance); err != nil {
return fmt.Errorf("unable to create duplicate instance, %w", err)
}
if err := c.k8sClient.Delete(ctx, instance); err != nil {
return fmt.Errorf("unable to delete old mr CR, %w", err)
}
return nil
}