Class: Build::GitLabHelper

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/core_blur/gitlab_helper.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGitLabHelper

Returns a new instance of GitLabHelper.



14
15
16
17
18
19
20
21
# File 'lib/core_blur/gitlab_helper.rb', line 14

def initialize
  super
  @endpoint = nil
  @private_token = nil
  init_endpoint
  init_private_token
  init_gitlab
end

Instance Attribute Details

#endpointObject

Returns the value of attribute endpoint.



11
12
13
# File 'lib/core_blur/gitlab_helper.rb', line 11

def endpoint
  @endpoint
end

#private_tokenObject

Returns the value of attribute private_token.



12
13
14
# File 'lib/core_blur/gitlab_helper.rb', line 12

def private_token
  @private_token
end

#pusherObject

Returns the value of attribute pusher.



13
14
15
# File 'lib/core_blur/gitlab_helper.rb', line 13

def pusher
  @pusher
end

Instance Method Details

#branch_contain_commit(project_id, branch, commit) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/core_blur/gitlab_helper.rb', line 110

def branch_contain_commit(project_id, branch, commit)
  current_page = 1
  per_page = 20
  commits = Gitlab.commits(project_id, { ref_name: branch , page:current_page, per_page: per_page})
  commits.each { |obj|
    if obj.to_hash["id"] == commit
      return true
    end
  }
  while commits.size == per_page
    current_page += 1
    commits = Gitlab.repo_commits(project_id, { ref_name: branch , page:current_page, per_page: per_page})
    commits.each { |obj|
      if obj.to_hash["id"] == commit
        return true
      end
    }
  end
  false
end

#create_project_if_need(project_name, http_url, private = false, description = nil) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/core_blur/gitlab_helper.rb', line 22

def create_project_if_need(project_name, http_url, private = false , description = nil)
  puts ""
  unless is_gitlab_url(http_url)
    puts "不使用gitlab接口检查和创建项目"
    return
  end
  puts "-> 检查gitlab项目(#{http_url})是否存在"
  repo_url = http_url.gsub("+", "_")
  project_obj = fetch_project(project_name, http_url, false)
  if project_obj
    puts "已存在 项目ID: #{project_obj.id} 群组:#{project_obj.namespace.id} 无需新建"
    project_obj.id
  else
    puts "不存在 需要创建项目,项目描述: #{description}"
    do_create_project(project_name, http_url, description, false, private)
  end
end

#do_create_project(pod_name, http_url, description, allow_force_push, private) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/core_blur/gitlab_helper.rb', line 74

def do_create_project(pod_name, http_url, description, allow_force_push, private)
  url = URI(http_url)
  repo_path = url.path.gsub("/#{pod_name}.git", "")
  repo_path = repo_path.gsub("#{pod_name}", "")
  namespace_id = get_project_namespace_id(repo_path)
  if namespace_id == nil
    error = "获取namespace_id失败, 无法创建项目"
    pusher.push("❌ 打包失败", error)
    Process.exit(-1)
  end
  visibility = !!private ? "private" : "internal"
  puts "创建的项目在群组ID:#{namespace_id} "
  res = Gitlab.create_project(pod_name, { description: description, initialize_with_readme: true, default_branch: "master", namespace_id: namespace_id, "merge_method":"ff", visibility:visibility})
  unless res.id
    error = "创建项目失败"
    pusher.push("❌ 打包失败", error)
    Process.exit(-1)
  end
  if allow_force_push
    Gitlab.unprotect_branch(res.id, "master")
    Gitlab.protect_branch(res.id, "master", allow_force_push: true)
  end
  res.id
end

#fetch_project(pod_name, http_url, can_raise = true) ⇒ Object



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
# File 'lib/core_blur/gitlab_helper.rb', line 39

def fetch_project(pod_name, http_url, can_raise = true)
  unless is_gitlab_url(http_url)
    puts "不使用gitlab接口查询项目ID"
    return
  end
  project_obj = nil
  projects = Gitlab.project_search(pod_name)
  projects.each { |project|
    project_hash = project.to_hash
    if project.name == pod_name
      if http_url == project_hash["http_url_to_repo"] or http_url == project_hash["ssh_url_to_repo"]  or http_url == project_hash["web_url"]
        project_obj = project
        break
      end
    end
  }
  if not project_obj and can_raise
    error = "当前配置private_token检索不到#{pod_name},可能是如下原因:\n"
    error += "1、该组件在git仓库中的名字和#{pod_name}不一致\n"
    error += "2、打包的该账号在该链接下#{http_url没有}权限,注:添加需要Maintainer权限\n"
    pusher.push("❌ 打包失败", error)
    Process.exit(-1)
  end
  project_obj
end

#get_project_namespace_id(repo_path) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/core_blur/gitlab_helper.rb', line 98

def get_project_namespace_id(repo_path)
  puts "仓库命名空间路径:#{repo_path}"
  group_name = repo_path.split('/').last
  puts "组名:#{group_name}"
  groups = Gitlab.group_search(group_name)
  groups.each { |group|
    if repo_path.include? group.full_path
      return group.id
    end
  }
  nil
end

#lock_branch(project_id, branch) ⇒ Object



64
65
66
67
68
69
70
71
72
73
# File 'lib/core_blur/gitlab_helper.rb', line 64

def lock_branch(project_id, branch)
  res = Gitlab.protected_branches(project_id)
  res.each { |obj|
    if obj.name == branch
      Gitlab.unprotect_branch(project_id, branch)
      break
    end
  }
  Gitlab.protect_branch(project_id, branch, {allow_force_push: false, push_access_level: 0, merge_access_level: 0})
end

#merge_branch(repo_module, target_branch) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/core_blur/gitlab_helper.rb', line 130

def merge_branch(repo_module, target_branch)
  puts "\n⏩ 开始合并分支到#{target_branch}(#{File.basename(repo_module.path)}):"
  unless repo_module.ssh_url.is_gitlab_url
    puts "非gitlab项目, 不支持此功能"
    return
  end
  unless check_merge_branch(repo_module, target_branch)
    return 
  end
  project_id = repo_module.project_id
  Gitlab.edit_project(project_id, { merge_method: 'ff' })
  sleep 1
  message = "#ignore_scan# [merge] #{repo_module.branch} => #{target_branch}"
  merge_request = Gitlab.create_merge_request(project_id, message,{ source_branch: repo_module.branch, target_branch:target_branch})
  merge_url = "#{self.endpoint}/projects/#{project_id}/merge_requests/#{merge_request.iid}/merge"
  puts "合并请求的ID: #{merge_request.iid} 链接: #{merge_url}"
  merge_request = Gitlab.merge_request(project_id, merge_request.iid)
  merge_status = merge_request.to_hash["merge_status"]
  state = merge_request.to_hash["state"]
  can_be_merged = (merge_status == "can_be_merged")
  retry_count = 0
  while retry_count <= 60 and not can_be_merged
    puts "合并请求检查中...(当前状态: #{state} #{merge_status})"
    merge_request = Gitlab.merge_request(project_id, merge_request.iid)
    merge_status = merge_request.to_hash["merge_status"]
    can_be_merged = (merge_status == "can_be_merged")
    retry_count += 1
    sleep 2
  end
  if state != "opened"
    error = "自动合并失败, 合并请求状态错误:#{state} #{merge_url}"
    pusher.push("【❌ 组件分支合并到#{target_branch}失败】", error)
    Process.exit(-1)
  end
  unless can_be_merged
    error = "自动合并失败, 检查状态超时: #{merge_status} #{merge_url}"
    pusher.push("【❌ 组件分支合并到#{target_branch}失败】", error)
    Process.exit(-1)
  end
  puts "merge_request检查完毕,当前状态:#{state} #{merge_status}"
  res = Gitlab.accept_merge_request(project_id, merge_request.iid, { merge_commit_message: message })
  if res.state == "merged"
    puts "自动合并完毕 #{repo_module.branch} => #{target_branch}"
    pusher.push("【✅组件合并到#{target_branch}成功】")
  else
    error = "自动合并失败, 请检查:#{merge_url}"
    pusher.push("【❌ 组件分支合并到#{target_branch}失败】", error)
    Process.exit(-1)
  end
end