# Module PushObserver

- app/roles/push_observer.rb

Includes methods for handling Git Push events

Triggered by PostReceive job

Methods

E
  - execute_hooks,
  - execute_services
O
  - observe_push
P
  - post_receive_data,
  - push_to_branch?
T
  - trigger_post_receive
U
  - update_merge_requests

Instance Public methods
execute_hooks(data) Link

Source: show

    # File app/roles/push_observer.rb, line 52
    def execute_hooks(data)
      hooks.each { |hook| hook.execute(data) }
    end

execute_services(data) Link

Source: show

    # File app/roles/push_observer.rb, line 56
    def execute_services(data)
      services.each do |service|

        # Call service hook only if it is active
        service.execute(data) if service.active
      end
    end

observe_push(data) Link

Source: show

    # File app/roles/push_observer.rb, line 43
    def observe_push(data)
      Event.create(
        project: self,
        action: Event::Pushed,
        data: data,
        author_id: data[:user_id]
      )
    end

post_receive_data(oldrev, newrev, ref, user) Link

Produce a hash of post-receive data

data = {

    before: String,
    after: String,
    ref: String,
    user_id: String,
    user_name: String,
    repository: {
      name: String,
      url: String,
      description: String,
      homepage: String,
    },
    commits: Array,
    total_commits_count: Fixnum

}

Source: show

    # File app/roles/push_observer.rb, line 82
    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: url_to_repo,
          description: description,
          homepage: web_url,
        },
        commits: [],
        total_commits_count: push_commits_count
      }

      # For perfomance purposes maximum 20 latest commits
      # 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,
          url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}",
          author: {
            name: commit.author_name,
            email: commit.author_email
          }
        }
      end

      data
    end

push_to_branch?(ref, oldrev) Link

Source: show

    # File app/roles/push_observer.rb, line 36
    def push_to_branch? ref, oldrev
      ref_parts = ref.split('/')

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

trigger_post_receive(oldrev, newrev, ref, user) Link

This method will be called after each post receive and only if the provided user is present in GitLab.

All callbacks for post receive should be placed here.

Source: show

    # File app/roles/push_observer.rb, line 9
    def trigger_post_receive(oldrev, newrev, ref, user)
      data = post_receive_data(oldrev, newrev, ref, user)

      # Create push event
      self.observe_push(data)

      if push_to_branch? ref, oldrev
        # Close merged MR
        self.update_merge_requests(oldrev, newrev, ref, user)

        # Execute web hooks
        self.execute_hooks(data.dup)

        # Execute project services
        self.execute_services(data.dup)
      end

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

      # Discover the default branch, but only if it hasn't already been set to
      # something else
      if default_branch.nil?
        update_attributes(default_branch: discover_default_branch)
      end
    end

update_merge_requests(oldrev, newrev, ref, user) Link

Source: show

    # File app/roles/push_observer.rb, line 128
    def update_merge_requests(oldrev, newrev, ref, user)
      return true unless ref =~ %rheads/
      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
      mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
      mrs.each { |merge_request| merge_request.merge!(user.id) }

      true
    end