func CalculateDeploymentCommitsDiff()

in backend/plugins/refdiff/tasks/deployment_commit_diff_calculator.go [41:136]


func CalculateDeploymentCommitsDiff(taskCtx plugin.SubTaskContext) errors.Error {
	data := taskCtx.GetData().(*RefdiffTaskData)
	db := taskCtx.GetDal()
	ctx := taskCtx.GetContext()
	logger := taskCtx.GetLogger()

	if data.Options.ProjectName == "" {
		return nil
	}

	// step 1. select all deployment commits that need to be calculated
	pairs := make([]*deploymentCommitPair, 0)
	err := db.All(
		&pairs,
		dal.Select("dc.id, dc.commit_sha, p.commit_sha as prev_commit_sha"),
		dal.From("cicd_deployment_commits dc"),
		dal.Join("LEFT JOIN project_mapping pm ON (pm.table = 'cicd_scopes' AND pm.row_id = dc.cicd_scope_id)"),
		dal.Join("LEFT JOIN cicd_deployment_commits p ON (dc.prev_success_deployment_commit_id = p.id)"),
		dal.Where(
			`
			pm.project_name = ?
			AND NOT EXISTS (
				SELECT 1
				FROM _tool_refdiff_finished_commits_diffs fcd
				WHERE fcd.new_commit_sha = dc.commit_sha AND fcd.old_commit_sha = p.commit_sha
			)
			`,
			data.Options.ProjectName,
		),
		dal.Orderby(`dc.cicd_scope_id, dc.repo_url, dc.environment, dc.started_date`),
	)
	if err != nil {
		return err
	}
	pairsCount := len(pairs)
	if pairsCount == 0 {
		// graph is expensive, we should avoid creating one for nothing
		return nil
	}

	// step 2. construct a commit node graph and batch save
	graph, err := loadCommitGraph(ctx, db, data)
	if err != nil {
		return err
	}
	batch_save, err := api.NewBatchSave(taskCtx, reflect.TypeOf(&code.CommitsDiff{}), 1000)
	if err != nil {
		return err
	}

	// step 3. iterate all pairs and calculate diff
	taskCtx.SetProgress(0, pairsCount)
	for _, pair := range pairs {
		select {
		case <-ctx.Done():
			return errors.Convert(ctx.Err())
		default:
		}
		lostSha, oldCount, newCount := graph.CalculateLostSha(pair.PrevCommitSha, pair.CommitSha)
		for i, sha := range lostSha {
			commitsDiff := &code.CommitsDiff{
				NewCommitSha: pair.CommitSha,
				OldCommitSha: pair.PrevCommitSha,
				CommitSha:    sha,
				SortingIndex: i + 1,
			}
			err = batch_save.Add(commitsDiff)
			if err != nil {
				return err
			}
		}
		err = batch_save.Flush()
		if err != nil {
			return err
		}
		// mark commits_diff were calculated, no need to do it again in the future
		finishedCommitsDiff := &models.FinishedCommitsDiff{
			NewCommitSha: pair.CommitSha,
			OldCommitSha: pair.PrevCommitSha,
		}
		err = db.CreateOrUpdate(finishedCommitsDiff)
		if err != nil {
			return err
		}

		logger.Info(
			"total %d commits of difference found between [new][%s] and [old][%s(total:%d)]",
			newCount,
			pair.CommitSha,
			pair.PrevCommitSha,
			oldCount,
		)
		taskCtx.IncProgress(1)
	}
	return nil
}