summaryrefslogtreecommitdiff
path: root/lib/gitlab/github_import/importer/pull_requests_importer.rb
blob: a52866c4b08bf3681b061defbc05a3e3f7b6d4d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
68
69
70
71
72
73
74
75
76
77
78
79
80
# frozen_string_literal: true

module Gitlab
  module GithubImport
    module Importer
      class PullRequestsImporter
        include ParallelScheduling

        def importer_class
          PullRequestImporter
        end

        def representation_class
          Representation::PullRequest
        end

        def sidekiq_worker_class
          ImportPullRequestWorker
        end

        def id_for_already_imported_cache(pr)
          pr.number
        end

        def each_object_to_import
          super do |pr|
            update_repository if update_repository?(pr)
            yield pr
          end
        end

        def update_repository
          # We set this column _before_ fetching the repository, and this is
          # deliberate. If we were to update this column after the fetch we may
          # miss out on changes pushed during the fetch or between the fetch and
          # updating the timestamp.
          project.update_column(:last_repository_updated_at, Time.zone.now)

          project.repository.fetch_remote('github', forced: false)

          pname = project.path_with_namespace

          Rails.logger
            .info("GitHub importer finished updating repository for #{pname}")

          repository_updates_counter.increment
        end

        def update_repository?(pr)
          last_update = project.last_repository_updated_at || project.created_at

          return false if pr.updated_at < last_update

          # PRs may be updated without there actually being new commits, thus we
          # check to make sure we only re-fetch if truly necessary.
          !(commit_exists?(pr.head.sha) && commit_exists?(pr.base.sha))
        end

        def commit_exists?(sha)
          project.repository.commit(sha).present?
        end

        def collection_method
          :pull_requests
        end

        def collection_options
          { state: 'all', sort: 'created', direction: 'asc' }
        end

        def repository_updates_counter
          @repository_updates_counter ||= Gitlab::Metrics.counter(
            :github_importer_repository_updates,
            'The number of times repositories have to be updated again'
          )
        end
      end
    end
  end
end