【问题标题】:How to get commit history of users in gitlab in rails如何在rails的gitlab中获取用户的提交历史
【发布时间】:2020-01-16 22:07:38
【问题描述】:

我正在尝试创建一个应用程序,该应用程序将获取用户的 gitlab/github 提交历史记录,我可以将其显示在侧面板中,并且可以根据我的标准进行检查。我想知道是否有办法获取当前登录用户的 gitlab/github 提交历史。我尝试使用 gem

https://github.com/libgit2/rugged

但找不到满足我需求的方法。如果有人知道如何实现这一点,那将非常有帮助。谢谢。

更新

我现在已经设法通过使用来获得用户:

Gitlab.endpoint = 'https://gitlab.com/api/v4'
Gitlab.private_token = 'token'
g = Gitlab.client(
  endpoint: 'https://gitlab.com/api/v4',
  private_token: 'token',
  httparty: {
    headers: { 'Cookie' => 'gitlab_canary=true' }
  }
)

通过使用命令g.user,我可以获取用户,但我需要获取用户在gitlab 中所做的提交。

【问题讨论】:

    标签: ruby git ruby-on-rails-5 gitlab


    【解决方案1】:
    1. 使用此 gitlab API GET /projects/:id/repository/commits 获取存储库 gitlab api 上的所有提交。详情请查看随附的代码。

    2. 基本上,这个git log --author="user_name" 命令可以为您提供特定用户的 git 提交历史记录,您甚至可以在上述命令中仅使用名字或姓氏的电子邮件地址。

    3. 通过 gitlab 进行身份验证后,您可以从 ruby​​ 运行以下命令。

        cmd = 'git log --author="user_name"'
        system(cmd)
    
    • 使用私有令牌连接到 gitlab 的 ruby​​ 示例代码并不理想,只是一个示例
    require 'json'
    require 'curb'
    require 'net/http'
    
    begin
    
     def parseCoverageReport(report_text) 
       coverage_perc = report_text.match /All files\s+\|\s+(\d+\.?\d+).*\n/
       if not coverage_perc then
         coverage_perc = report_text.match /^TOTAL\s+\d+\s+\d+\s+(\d+)%$/
       end
    
       if coverage_perc then 
         #if we found coverage value in job trace
         #puts "coverage_perc[1]: #{coverage_perc[1]}"
         coverage_perc[1].to_i
       end
     end
    
     gen_config = YAML.load_file("config/general.yml")
     gitlab_config = YAML.load_file("config/gitlab.yml")
    
     SCHEDULER.every gen_config[:job_trigger_interval], :first_in => 0 do |job|
    
     table = {
         title: "Projects",
         hrows: Array.new.push({cols: [
           {value: "Project name"}, 
           {value: "Open Merge Requests"},
           {value: "Code coverage"}
         ]}),
         rows: Array.new
     }
    
     instances = gitlab_config['instances']
    
     instances.each do |instance|
    
       gitlab_url = gitlab_config['instances'][instance.first]['url']
       # gitlab_token = gitlab_config['instances'][instance.first]['api_key']
       gitlab_token = ENV[gitlab_config['instances'][instance.first]['api_key']]
       red_threshold = gitlab_config['instances'][instance.first]['red_threshold']
       orange_threshold = gitlab_config['instances'][instance.first]['orange_threshold']
       cov_red_threshold = gitlab_config['instances'][instance.first]['cov_red_threshold']
       cov_orange_threshold = gitlab_config['instances'][instance.first]['cov_orange_threshold']
       projects = gitlab_config['instances'][instance.first]['projects']
    
       projects.each do |name, project|
    
           merge_reqs = JSON.parse(Curl.get("#{gitlab_url}/api/v4/projects/#{project['id']}/merge_requests?state=opened&private_token=#{gitlab_token}&per_page=200").body_str)
           git_project =  JSON.parse(Curl.get("#{gitlab_url}/api/v4/projects/#{project['id']}?private_token=#{gitlab_token}").body_str)
           opened_mrs = merge_reqs.select { |merge_reqs| %w[opened].include? merge_reqs['state'] }
           repo_name  = git_project['name']
           repo_url  = git_project['web_url']
    
    
           status = case
           when opened_mrs.size >= red_threshold then 'danger'
           when opened_mrs.size >= orange_threshold then 'warning'
           else
             'ok'
           end
    
           mrs_count = "#{opened_mrs.size}"
           send_event("#{name}_mr", { current: mrs_count, status: status })
    
           color = case
           when opened_mrs.size >= red_threshold then 'red'
           when opened_mrs.size >= orange_threshold then 'orange'
           else
             'green'
           end
    
           font_color = color == 'orange' ? 'black' : 'white'
    
           cov_color = color
           font_cov_color = 'white'
    
           code_coverage = "---"
           code_coverage_tag = "---"
           cov_job_url = ''
    
           jobs = JSON.parse(Curl.get("#{gitlab_url}/api/v4/projects/#{project['id']}/jobs?scope=success&private_token=#{gitlab_token}&per_page=30").body_str)
           code_cov_job = jobs.find { |gitlab_job| !gitlab_job['coverage'].nil? }
    
           if not code_cov_job then
             #if no job has 'coverage' feature set up in Gitlab try to parse 
             #'coverage' from jobs trace manually
             jobs.each do |job|
                   trace_report = Curl.get("#{gitlab_url}/api/v4/projects/#{project['id']}/jobs/#{job['id']}/trace?private_token=#{gitlab_token}").body_str
                   code_cov_percentage = parseCoverageReport(trace_report)
                   if code_cov_percentage then
                     code_cov_job = job
                     code_cov_job['coverage'] = code_cov_percentage
                     break 
                   end
             end
           end
    
           if code_cov_job then
             #found code coverage data => process them
             code_coverage = code_cov_job['coverage'].to_i
             cov_job_url = code_cov_job['web_url'].to_s
    
             #update code covergate SprintProgress widgets at the same job
             widget_title = "code_coverage_progress_#{project['id']}"
             send_event(widget_title, { 
               title: "Code Coverage - #{git_project['name']}", 
               sprintboard_url: cov_job_url,
               min: 0, 
               max: 100, 
               value: code_coverage, 
               moreinfo: ''
             })
    
             cov_color = case
             when code_coverage <= cov_red_threshold then 'red'
             when code_coverage <= cov_orange_threshold then 'orange'
             else
               'green'
             end
    
             code_coverage = "#{code_coverage}%"
             code_coverage_tag = "<a href='#{cov_job_url}' target='_blank'>#{code_coverage.to_s}</a>"
           end
    
           repo_name_a_tag = "<a href='#{repo_url}' target='_blank'>#{repo_name}</a>"
           open_mrs_size = "<a href='#{repo_url}/merge_requests' target='_blank'>#{opened_mrs.size}</a>"
    
           table[:rows].push({ 
             cols: [
               { value: repo_name_a_tag, style: "color: #{font_color}; background-color: #{color}" }, 
               { value: open_mrs_size, style: "color: #{font_color}; background-color: #{color}" },
               { value: code_coverage_tag, style: "color: #{cov_color == 'orange' ? 'black' : 'white'}; background-color: #{cov_color}" } 
             ]
           })
    
         end
       end
    
       send_event('open_merge_requests_table', table)
    
    end
    rescue Errno::ENOENT
     puts "No config file found for gitlab - not starting the Gitlab job"
    end
    
    
    • 在上面的 ruby​​ 例子中请看下面的代码 sn-p
    merge_reqs = JSON.parse(Curl.get("#{gitlab_url}/api/v4/projects/#{project['id']}/merge_requests?state=opened&private_token=#{gitlab_token}&per_page=200").body_str)
           git_project =  JSON.parse(Curl.get("#{gitlab_url}/api/v4/projects/#{project['id']}?private_token=#{gitlab_token}").body_str)
           opened_mrs = merge_reqs.select { |merge_reqs| %w[opened].include? merge_reqs['state'] }
           repo_name  = git_project['name']
           repo_url  = git_project['web_url']
    

    在这里,我要做的是使用 private_token 连接到我们的 gitlab 实例,然后针对特定的项目 ID(您可以从 gitlab 的 UI 中获取它)检查打开的合并请求。我还获得了 git_project,从中获得了名称和 web_url(这是我的用例)。

    • 对于您的用例,您必须获取 project_id(用于 gitlab UI),然后使用一些适当的方法来获取提交。gitlab docs

    【讨论】:

    • gitlab.Gitlab('https://git.xxx.xxx.xxx', private_token='xxxxxxxxxx') 是否与此 gem 相关联?我需要从所有项目中获取用户所有提交的日志,这是否适用?
    • @amal 我已经更新了我的答案,它使用 ruby​​ 代码使用私有令牌连接到 gitlab。 JSON.parse(Curl.get("#{gitlab_url}/api/v4/projects/#{project['id']}/jobs?scope=success&private_token=#{gitlab_token}&per_page=30").body_str)跨度>
    • 很抱歉,您能举一个更简单的例子吗?
    • 在您的帮助下,我设法从 gitlab 获取用户,但我不知道如何获取用户的提交历史记录。您指定 cmd = 'git log --author="user_name"' system(cmd) 的这段代码适用于系统,但我无法操纵它来获取提交的内容。
    • @Amal 我已经更新了答案,希望最后2点对你有帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 2021-10-29
    • 1970-01-01
    相关资源
    最近更新 更多