func()

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
}