/
azure.rb
116 lines (94 loc) 路 3.41 KB
/
azure.rb
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# frozen_string_literal: true
require "dependabot/clients/azure"
require "securerandom"
module Dependabot
class PullRequestUpdater
class Azure
class PullRequestUpdateFailed < Dependabot::DependabotError; end
OBJECT_ID_FOR_BRANCH_DELETE = "0000000000000000000000000000000000000000"
attr_reader :source, :files, :base_commit, :old_commit, :credentials,
:pull_request_number
def initialize(source:, files:, base_commit:, old_commit:,
credentials:, pull_request_number:)
@source = source
@files = files
@base_commit = base_commit
@old_commit = old_commit
@credentials = credentials
@pull_request_number = pull_request_number
end
def update
return unless pull_request_exists? && source_branch_exists?
update_source_branch
end
private
def azure_client_for_source
@azure_client_for_source ||=
Dependabot::Clients::Azure.for_source(
source: source,
credentials: credentials
)
end
def pull_request_exists?
pull_request
rescue Dependabot::Clients::Azure::NotFound
false
end
def source_branch_exists?
azure_client_for_source.branch(source_branch_name)
rescue Dependabot::Clients::Azure::NotFound
false
end
# Currently the PR diff in ADO shows difference in commits instead of actual diff in files.
# This workaround is done to get the target branch commit history on the source branch alongwith file changes
def update_source_branch
# 1) Push the file changes to a newly created temporary branch (from base commit)
new_commit = create_temp_branch
# 2) Update PR source branch to point to the temp branch head commit.
response = update_branch(source_branch_name, old_source_branch_commit, new_commit)
# 3) Delete temp branch
update_branch(temp_branch_name, new_commit, OBJECT_ID_FOR_BRANCH_DELETE)
raise PullRequestUpdateFailed, response.fetch("customMessage", nil) unless response.fetch("success", false)
end
def pull_request
@pull_request ||=
azure_client_for_source.pull_request(pull_request_number.to_s)
end
def source_branch_name
@source_branch_name ||= pull_request&.fetch("sourceRefName")&.gsub("refs/heads/", "")
end
def create_temp_branch
response = azure_client_for_source.create_commit(
temp_branch_name,
base_commit,
commit_message,
files,
nil
)
JSON.parse(response.body).fetch("refUpdates").first.fetch("newObjectId")
end
def temp_branch_name
@temp_branch_name ||=
"#{source_branch_name}-temp-#{SecureRandom.uuid[0..6]}"
end
def update_branch(branch_name, old_commit, new_commit)
azure_client_for_source.update_ref(
branch_name,
old_commit,
new_commit
)
end
# For updating source branch, we require the latest commit for the source branch.
def commit_being_updated
@commit_being_updated ||=
azure_client_for_source.commits(source_branch_name).first
end
def old_source_branch_commit
commit_being_updated.fetch("commitId")
end
def commit_message
commit_being_updated.fetch("comment")
end
end
end
end