git_push.rb 2.85 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
module GitPush
  def observe_push(oldrev, newrev, ref, user)
    data = post_receive_data(oldrev, newrev, ref, user)

    Event.create(
      :project => self,
      :action => Event::Pushed,
      :data => data,
      :author_id => data[:user_id]
    )
  end

  def update_merge_requests(oldrev, newrev, ref, user)
    return true unless ref =~ /heads/
    branch_name = ref.gsub("refs/heads/", "")
    c_ids = self.commits_between(oldrev, newrev).map(&:id)

    # Update code for merge requests
    mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
    mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }

    # Close merge requests
    mrs = self.merge_requests.opened.where(:target_branch => branch_name).all
24
    mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
25 26 27 28 29
    mrs.each { |merge_request| merge_request.merge!(user.id) }

    true
  end

30
  def execute_hooks(oldrev, newrev, ref, user)
31 32 33 34 35 36 37
    ref_parts = ref.split('/')

    # Return if this is not a push to a branch (e.g. new commits)
    return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000"

    data = post_receive_data(oldrev, newrev, ref, user)

38
    hooks.each { |hook| hook.execute(data) }
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
  end

  def post_receive_data(oldrev, newrev, ref, user)

    push_commits = commits_between(oldrev, newrev)

    # Total commits count
    push_commits_count = push_commits.size

    # Get latest 20 commits ASC
    push_commits_limited = push_commits.last(20)

    # Hash to be passed as post_receive_data
    data = {
      before: oldrev,
      after: newrev,
      ref: ref,
      user_id: user.id,
      user_name: user.name,
      repository: {
        name: name,
        url: web_url,
        description: description,
        homepage: web_url,
      },
      commits: [],
      total_commits_count: push_commits_count
    }

68
    # For perfomance purposes maximum 20 latest commits
69 70 71 72 73 74 75
    # will be passed as post receive hook data.
    #
    push_commits_limited.each do |commit|
      data[:commits] << {
        id: commit.id,
        message: commit.safe_message,
        timestamp: commit.date.xmlschema,
76
        url: "#{Gitlab.config.url}/#{code}/commits/#{commit.id}",
77 78 79 80 81 82 83 84 85 86 87 88
        author: {
          name: commit.author_name,
          email: commit.author_email
        }
      }
    end

    data
  end


  # This method will be called after each post receive
89
  # and only if user present in gitlab.
90 91
  # All callbacks for post receive should be placed here
  #
92
  def trigger_post_receive(oldrev, newrev, ref, user)
93 94 95
    # Create push event
    self.observe_push(oldrev, newrev, ref, user)

96
    # Close merged MR
97 98 99
    self.update_merge_requests(oldrev, newrev, ref, user)

    # Execute web hooks
100
    self.execute_hooks(oldrev, newrev, ref, user)
101 102 103 104 105

    # Create satellite
    self.satellite.create unless self.satellite.exists?
  end
end