Class: Deployments::LinkMergeRequestsService
- Inherits:
-
Object
- Object
- Deployments::LinkMergeRequestsService
- Defined in:
- app/services/deployments/link_merge_requests_service.rb
Overview
Service class for linking merge requests to deployments.
Constant Summary collapse
- COMMITS_PER_QUERY =
The number of commits per query for which to find merge requests.
5_000
Instance Attribute Summary collapse
-
#deployment ⇒ Object
readonly
Returns the value of attribute deployment.
Instance Method Summary collapse
- #execute ⇒ Object
-
#initialize(deployment) ⇒ LinkMergeRequestsService
constructor
A new instance of LinkMergeRequestsService.
- #link_all_merged_merge_requests ⇒ Object
- #link_merge_requests_for_range(from, to) ⇒ Object
Constructor Details
#initialize(deployment) ⇒ LinkMergeRequestsService
Returns a new instance of LinkMergeRequestsService.
11 12 13 |
# File 'app/services/deployments/link_merge_requests_service.rb', line 11 def initialize(deployment) @deployment = deployment end |
Instance Attribute Details
#deployment ⇒ Object (readonly)
Returns the value of attribute deployment.
6 7 8 |
# File 'app/services/deployments/link_merge_requests_service.rb', line 6 def deployment @deployment end |
Instance Method Details
#execute ⇒ Object
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 |
# File 'app/services/deployments/link_merge_requests_service.rb', line 15 def execute # Review apps have the environment type set (e.g. to `review`, though the # exact value may differ). We don't want to link merge requests to review # app deployments, as this is not useful. return unless deployment.environment.should_link_to_merge_requests? # This service is triggered by a Sidekiq worker, which only runs when a # deployment is successful. We add an extra check here in case we ever # call this service elsewhere and forget to check the status there. # # The reason we only want to link successful deployments is as follows: # when we link a merge request, we don't link it to future deployments for # the same environment. If we were to link an MR to a failed deploy, we # wouldn't be able to later on link it to a successful deploy (e.g. after # the deploy is retried). # # In addition, showing failed deploys in the UI of a merge request isn't # useful to users, as they can't act upon the information in any # meaningful way (i.e. they can't just retry the deploy themselves). return unless deployment.success? if (prev = deployment.previous_deployment) link_merge_requests_for_range(prev.sha, deployment.sha) else # When no previous deployment is found we fall back to linking all merge # requests merged into the deployed branch. This will not always be # accurate, but it's better than having no data. # # We can't use the first commit in the repository as a base to compare # to, as this will not scale to large repositories. For example, GitLab # itself has over 150 000 commits. link_all_merged_merge_requests end end |
#link_all_merged_merge_requests ⇒ Object
83 84 85 86 87 88 |
# File 'app/services/deployments/link_merge_requests_service.rb', line 83 def link_all_merged_merge_requests merge_requests = project.merge_requests.merged.by_target_branch(deployment.ref) deployment.link_merge_requests(merge_requests) end |
#link_merge_requests_for_range(from, to) ⇒ Object
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 81 |
# File 'app/services/deployments/link_merge_requests_service.rb', line 50 def link_merge_requests_for_range(from, to) commits = project .repository .commits_between(from, to) .map(&:id) # For some projects the list of commits to deploy may be very large. To # ensure we do not end up running SQL queries with thousands of WHERE IN # values, we run one query per a certain number of commits. # # In most cases this translates to only a single query. For very large # deployment we may end up running a handful of queries to get and insert # the data. commits.each_slice(COMMITS_PER_QUERY) do |slice| merge_requests = project.merge_requests.merged.by_merge_commit_sha(slice) deployment.link_merge_requests(merge_requests) # The cherry picked commits are tracked via `notes.commit_id` # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22209 # # NOTE: cross-joining `merge_requests` table and `notes` table could # result in very poor performance because PG planner often uses an # inappropriate index. # See https://gitlab.com/gitlab-org/gitlab/-/issues/321032. mr_ids = project.notes.cherry_picked_merge_requests(slice) picked_merge_requests = project.merge_requests.id_in(mr_ids) deployment.link_merge_requests(picked_merge_requests) end end |