Class: ProcessCommitWorker

Inherits:
Object
  • Object
show all
Includes:
ApplicationWorker
Defined in:
app/workers/process_commit_worker.rb

Overview

Worker for processing individual commit messages pushed to a repository.

Jobs for this worker are scheduled for every commit that contains mentionable references in its message and does not exist in the upstream project. As a result of this the workload of this worker should be kept to a bare minimum. Consider using an extra worker if you need to add any extra (and potentially slow) processing of commits.

Constant Summary

Constants included from ApplicationWorker

ApplicationWorker::LOGGING_EXTRA_KEY, ApplicationWorker::SAFE_PUSH_BULK_LIMIT

Constants included from Gitlab::Loggable

Gitlab::Loggable::ANONYMOUS

Constants included from WorkerAttributes

WorkerAttributes::DEFAULT_DATA_CONSISTENCY, WorkerAttributes::DEFAULT_DEFER_DELAY, WorkerAttributes::NAMESPACE_WEIGHTS, WorkerAttributes::VALID_DATA_CONSISTENCIES, WorkerAttributes::VALID_RESOURCE_BOUNDARIES, WorkerAttributes::VALID_URGENCIES

Instance Method Summary collapse

Methods included from Gitlab::Loggable

#build_structured_payload

Methods included from Gitlab::SidekiqVersioning::Worker

#job_version

Methods included from WorkerContext

#with_context

Instance Method Details

#close_issues(project, user, author, commit, issues) ⇒ Object



54
55
56
57
58
59
60
61
62
# File 'app/workers/process_commit_worker.rb', line 54

def close_issues(project, user, author, commit, issues)
  Issues::CloseWorker.bulk_perform_async_with_contexts(
    issues,
    arguments_proc: -> (issue) {
      [project.id, issue.id, issue.class.to_s, { closed_by: author.id, commit_hash: commit.to_hash }]
    },
    context_proc: -> (issue) { { project: project } }
  )
end

#issues_to_close(project, commit, user) ⇒ Object



64
65
66
67
68
# File 'app/workers/process_commit_worker.rb', line 64

def issues_to_close(project, commit, user)
  Gitlab::ClosingIssueExtractor
    .new(project, user)
    .closed_by_message(commit.safe_message)
end

#perform(project_id, user_id, commit_hash, default = false) ⇒ Object

project_id - The ID of the project this commit belongs to. user_id - The ID of the user that pushed the commit. commit_hash - Hash containing commit details to use for constructing a

Commit object without having to use the Git repository.

default - The data was pushed to the default branch.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'app/workers/process_commit_worker.rb', line 29

def perform(project_id, user_id, commit_hash, default = false)
  project = Project.id_in(project_id).first

  return unless project

  user = User.id_in(user_id).first

  return unless user

  commit = Commit.build_from_sidekiq_hash(project, commit_hash)
  author = commit.author || user

  process_commit_message(project, commit, user, author, default)
  update_issue_metrics(commit, author)
end

#process_commit_message(project, commit, user, author, default = false) ⇒ Object



45
46
47
48
49
50
51
52
# File 'app/workers/process_commit_worker.rb', line 45

def process_commit_message(project, commit, user, author, default = false)
  # Ignore closing references from GitLab-generated commit messages.
  find_closing_issues = default && !commit.merged_merge_request?(user)
  closed_issues = find_closing_issues ? issues_to_close(project, commit, user) : []

  close_issues(project, user, author, commit, closed_issues) if closed_issues.any?
  commit.create_cross_references!(author, closed_issues)
end

#update_issue_metrics(commit, author) ⇒ Object



70
71
72
73
74
75
76
77
78
# File 'app/workers/process_commit_worker.rb', line 70

def update_issue_metrics(commit, author)
  mentioned_issues = commit.all_references(author).issues

  return if mentioned_issues.empty?

  Issue::Metrics.for_issues(mentioned_issues)
    .with_first_mention_not_earlier_than(commit.committed_date)
    .update_all(first_mentioned_in_commit_at: commit.committed_date)
end