You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

pull_requests_controller.rb 22 kB

10 years ago
10 years ago
​
10 years ago
10 years ago
10 years ago
​
​
​
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
​
​
10 years ago
​
​
​
​
​
​
​
​
​
10 years ago
​
10 years ago
​
​
​
​
10 years ago
​
10 years ago
​
​
10 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
10 years ago
10 years ago
​
​
10 years ago
10 years ago
10 years ago
10 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
10 years ago
​
10 years ago
10 years ago
10 years ago
​
​
10 years ago
​
​
​
10 years ago
​
​
​
​
​
​
​
8 years ago
​
​
10 years ago
​
10 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
10 years ago
​
​
​
​
​
​
10 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
10 years ago
​
​
​
​
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. # encoding: utf-8
  2. # 如果你对改模块任何功能不清楚,请不要随便改
  3. # @Hjqreturn
  4. class PullRequestsController < ApplicationController
  5. before_filter :authorize_logged
  6. before_filter :find_project_and_repository
  7. before_filter :connect_gitlab, :only => [:index, :show, :create, :accept_pull_request, :pull_request_commits, :pull_request_changes, :new, :update_pull_request, :pull_request_comments, :create_pull_request_comment, :compare_pull_request]
  8. before_filter :member_allowed, :only => [:new, :create, :create_pull_request_comment]
  9. before_filter :manager_allowed, :only => [:accept_pull_request]
  10. layout "base_projects"
  11. include PullRequestsHelper
  12. include ApplicationHelper
  13. require 'ostruct'
  14. require 'nokogiri'
  15. require 'json'
  16. require 'open-uri'
  17. require 'uri'
  18. # 返回json格式
  19. def index
  20. # project_menu_type 为了控制base顶部导航
  21. @project_menu_type = 6
  22. set_nav_status(NavStatues::PROJECT)
  23. # 不符合pullrequest条件的给出提示
  24. @allow_to_pull_request = allow_pull_request(@project) > 0
  25. type = params[:type]
  26. merge_requests = @g.merge_requests(@project.gpid)
  27. merge_requests_count = merge_requests.count
  28. case type
  29. when nil, "1"
  30. @requests = merge_requests.select{|request| request.state == "opened" || request.state == "reopened"}
  31. # 更新统计数字
  32. project_score = @project.project_score.update_column(:pull_request_num, merge_requests_count)
  33. when "2"
  34. @requests = merge_requests.select{|request| request.state == "merged"}
  35. when "3"
  36. @requests = merge_requests.select{|request| request.state == "closed"}
  37. end
  38. @requests_opened_count = @requests.count
  39. @requests_merged_count = merge_requests.select{|request| request.state == "merged"}.count
  40. @requests_closed_count = merge_requests.select{|request| request.state == "closed"}.count
  41. @limit = 20
  42. @is_remote = true
  43. @count = type_count(type, @requests_opened_count, @requests_merged_count, @requests_closed_count)
  44. @pages = Paginator.new @count, @limit, params['page'] || 1
  45. @offset ||= @pages.offset
  46. @requests = paginateHelper @requests, 20
  47. respond_to do |format|
  48. format.html
  49. format.js
  50. end
  51. end
  52. # 主要取源项目和目标项目分支及标识(用户名/版本库名)
  53. # @tip 为空的时候表明发送的pr请求有改动,为1的时候源分支和目标分支没有改动,则不能成功创建
  54. def new
  55. # project_menu_type 为了控制base顶部导航
  56. @project_menu_type = 6
  57. @tip = params[:show_tip]
  58. identifier = get_rep_identifier_by_project @project
  59. @source_project_name = "#{get_user_name(@project.user_id)}/#{identifier}"
  60. @source_rev = @g.branches(@project.gpid).map{|b| b.name}
  61. # 获取forked源项目信息
  62. if @project.forked_from_project_id
  63. @forked_project = Project.find(@project.forked_from_project_id)
  64. identifier = get_rep_identifier_by_project @forked_project
  65. @forked_project_name = "#{get_user_name(@forked_project.user_id)}/#{identifier}"
  66. @forked_rev = @g.branches(@forked_project.gpid).map{|b| b.name}
  67. end
  68. end
  69. # Creates a merge request.
  70. # If the operation is successful, 200 and the newly created merge request is returned. If an error occurs, an error number and a message explaining the reason is returned.
  71. #
  72. # @example
  73. # Gitlab.create_merge_request(5, 'New merge request',
  74. # :source_branch => 'source_branch', :target_branch => 'target_branch')
  75. # Gitlab.create_merge_request(5, 'New merge request',
  76. # :source_branch => 'source_branch', :target_branch => 'target_branch', :assignee_id => 42)
  77. #
  78. # @param [Integer] project The ID of a project.
  79. # @param [String] title The title of a merge request.
  80. # @param [Hash] options A customizable set of options.
  81. # @option options [String] :source_branch (required) The source branch name.
  82. # @option options [String] :target_branch (required) The target branch name.
  83. # @option options [Integer] :assignee_id (optional) The ID of a user to assign merge request.
  84. # @return [Gitlab::ObjectifiedHash] Information about created merge request.
  85. def create
  86. title = params[:title]
  87. description = params[:description]
  88. source_branch = params[:source_branch]
  89. target_branch = params[:target_branch]
  90. target_project_id = params[:target_project_id]
  91. # begin
  92. @gitlab_address = Redmine::Configuration['gitlab_address']
  93. identifier = @project.repository.try(:identifier)
  94. logger.info("1111111111111111#{identifier}")
  95. git_url = @gitlab_address.to_s+"/"+@project.owner.to_s+"/"+ identifier + "."+"git"
  96. job_name = "pr-" + "#{Time.now.to_i}"
  97. # 如果分支有改动
  98. if compare_pull_request(source_branch, target_project_id, target_branch)
  99. logger.info("2222222222222222222222")
  100. # 自动生成配置Jenkinsjob,在merge事件的时候触发jenkins、sonar
  101. # merge发送的时候还没有接收,所以分析对象应该源项目
  102. language = swith_language_type(@project.language)
  103. # exec_jenkins(source_branch, @project.gpid, git_url, job_name, language)
  104. logger.info("33333333333333333333")
  105. qa = QualityAnalysis.create(:project_id => @project.id, :author_login => User.current.login, :sonar_version => 1, :path => "./",
  106. :branch => source_branch, :language => "java", :sonar_name => "#{job_name}")
  107. logger.info("4444444444444444444444444")
  108. # 如果传送了目标项目ID即向fork源项目发送请求
  109. # if params[:forked_project_id] && params[:source_project] == "forked_project_name"
  110. if !params[:target_project_id].blank? && params[:target_project_id].to_i != @project.id
  111. target_project_id = params[:forked_project_id].to_i
  112. request = @g.create_merge_request(@project.gpid, title, User.current.gid, :description => description, :source_branch => source_branch, :target_branch => target_branch, :target_project_id => target_project_id)
  113. unless request&.id
  114. @message = "#{target_branch} 和 #{source_branch}分支的pull request已存在且未处理,等待处理后再创建!" and return
  115. end
  116. @fork_project_name = Project.find(params[:target_project_id]).try(:name)
  117. @fork_pr_message = true if @fork_project_name
  118. # 向管理员发送消息
  119. send_message_to_manager(params[:target_project_id].to_i, request.id, 1)
  120. pr = PullRequest.create(:pull_request_id => request.id, :user_id => User.current.id, :status => 1, :project_id => target_project_id, :title => title)
  121. else
  122. @project_member = Member.where(:project_id => @project.id)
  123. request = @g.create_merge_request(@project.gpid, title, User.current.gid, :description => description, :source_branch => source_branch, :target_branch => target_branch)
  124. # 发送消息
  125. send_message_to_manager(@project.id, request.id, 1)
  126. # 创建Trustie数据
  127. pr = PullRequest.create(:pull_request_id => request.id, :user_id => User.current.id, :status => 1, :project_id => @project.id, :title => title)
  128. respond_to do |format|
  129. format.js{redirect_to project_pull_request_path(request.id, :project_id => @project.id)}
  130. end
  131. end
  132. # 关联pr和qa
  133. qa.update_attribute(:pull_request_id, request.try(:id))
  134. else
  135. tip = 1
  136. respond_to do |format|
  137. format.js{redirect_to new_project_pull_request_path(:show_tip => tip)}
  138. end
  139. end
  140. # rescue Exception => e
  141. # logger.info("create PR failed ####{e}")
  142. # end
  143. end
  144. def exec_jenkins branch, gpid, git_url, job_name, language
  145. # 发送PR之前先发送创建Jenkins Job、gitlab hook,调用sonar自动分析代码
  146. logger.info("5555555555555555#{branch}, git_url#{git_url}, job_name #{job_name}")
  147. @jenkins_address = Redmine::Configuration['jenkins_address']
  148. jenkins_username = Redmine::Configuration['jenkins_username']
  149. jenkins_password = Redmine::Configuration['jenkins_password']
  150. # connect jenkins
  151. @client_jenkins = JenkinsApi::Client.new(:server_url => @jenkins_address, :username => jenkins_username, :password => jenkins_password)
  152. @g = Gitlab.client
  153. language = language.present? ? language : "java"
  154. path = "./"
  155. # qa = QualityAnalysis.where(:project_id => @project.id, :author_login => user_name).first
  156. version = 1
  157. if language == "java"
  158. properties = "sonar.projectKey=#{job_name}
  159. sonar.projectName=#{job_name}
  160. sonar.projectVersion=#{version}
  161. sonar.sources=#{path}
  162. sonar.language=#{language.downcase}
  163. sonar.sourceEncoding=utf-8
  164. sonar.java.binaries=./"
  165. else
  166. properties = "sonar.projectKey=#{job_name}
  167. sonar.projectName=#{job_name}
  168. sonar.projectVersion=#{version}
  169. sonar.sources=#{path}
  170. sonar.language=#{language.downcase}
  171. sonar.sourceEncoding=utf-8"
  172. end
  173. # 替换配置文件
  174. @doc = Nokogiri::XML(File.open(File.join(Rails.root, 'tmp', 'config.xml')))
  175. @doc.at_xpath("//hudson.plugins.git.UserRemoteConfig/url").content = git_url
  176. @doc.at_xpath("//hudson.plugins.git.BranchSpec/name").content = "*/#{branch}"
  177. @doc.at_xpath("//hudson.plugins.sonar.SonarRunnerBuilder/properties").content = properties # sonar-properties
  178. logger.info("6666666666666666666666666")
  179. # jenkins job创建
  180. jenkins_job = @client_jenkins.job.create("#{job_name}", @doc.to_xml)
  181. logger.info("777777777777777777")
  182. # 将地址作为hook值添加到gitlab
  183. # @g.add_project_hook(@project.gpid, (@jenkins_address + "/project/#{job_name}"), merge_requests_events: true)
  184. # job创建完成后自动运行job,如果运行成功则返回‘200’
  185. code = @client_jenkins.job.build("#{job_name}")
  186. end
  187. # Compare branch for MR
  188. # 判断源分支和目标分支是否有改动
  189. # status 为true 表示有改动; false:便是没有改动
  190. def compare_pull_request source_branch, target_project, target_branch
  191. user_name_source = @project.owner.try(:login)
  192. identifier = @repository.identifier.downcase
  193. git_source_tree = '--git-dir=/home/git/repositories/' + user_name_source + '/' + identifier + '.git'
  194. if target_project
  195. forked_source_project = Project.find(target_project)
  196. user_name_target = forked_source_project.owner.try(:login)
  197. git_target_tree = '--git-dir=/home/git/repositories/' + user_name_target + '/' + identifier + '.git'
  198. # git_sourse_commit_id = @g.get_branch_commit_id(@project.gpid, git_source_tree, source_branch)
  199. git_sourse_commit_id = @g.commits(@project.gpid, :ref_name => source_branch).first.try(:id)
  200. # git_target_commit_id = @g.get_branch_commit_id(forked_source_project.gpid, git_target_tree, target_branch)
  201. git_target_commit_id = @g.commits(forked_source_project.gpid, :ref_name => target_branch).first.try(:id)
  202. else
  203. git_sourse_commit_id = @g.commits(@project.gpid, :ref_name => source_branch).first.try(:id)
  204. git_target_commit_id = @g.commits(@project.gpid, :ref_name => target_branch).first.try(:id)
  205. end
  206. logger.info("compare source_branch################{source_branch}")
  207. logger.info("compare target_project################{target_project}")
  208. logger.info("compare git_sourse_commit_id################{git_sourse_commit_id}")
  209. logger.info("compare git_target_commit_id################{git_target_commit_id}")
  210. status = (git_sourse_commit_id == git_target_commit_id ? false : true)
  211. end
  212. # 获取jenkins输出结果
  213. def pr_console
  214. job_name = params[:job_name]
  215. pr = PullRequest.where(:pull_request_id => params[:pr_id]).first
  216. jenkins_address = Redmine::Configuration['jenkins_address']
  217. jenkins_username = Redmine::Configuration['jenkins_username']
  218. jenkins_password = Redmine::Configuration['jenkins_password']
  219. # connect jenkins
  220. client_jenkins = JenkinsApi::Client.new(:server_url => jenkins_address, :username => jenkins_username, :password => jenkins_password)
  221. @output = client_jenkins.job.get_console_output("#{job_name}", build_num = 0, start = 0, mode = 'html')["output"]
  222. @output = @output.force_encoding("UTF-8") if @output.present?
  223. end
  224. # @project_menu_type 为了控制base顶部导航
  225. # merge_when_succeeds
  226. def show
  227. # compare_pull_request source_project, source_branch, target_project, target_branch
  228. # compare_pull_request
  229. # 如何从个人主页点击进入,则将该消息设为“已读”
  230. ForgeMessage.where(:forge_message_id => params[:id], :forge_message_type => "PullRequest", :user_id => User.current.id, :viewed => false).update_all(:viewed => true)
  231. @project_menu_type = 6
  232. @type = params[:type]
  233. @request = @g.merge_request(@project.gpid, params[:id])
  234. @commits = @g.merge_request_commits(@project.gpid, params[:id].to_i)
  235. @commits_count = @commits.count
  236. # @commits_day = @commits.chunk
  237. @changes = @g.merge_request_changes(@project.gpid, params[:id]).try(:changes)
  238. @changes_count = @changes.count
  239. @comments = @g.merge_request_comments(@project.gpid, params[:id]).reverse
  240. @comments_count = @comments.count
  241. @limit = 10
  242. @is_remote = true
  243. @count = @comments_count
  244. @pages = Paginator.new @count, @limit, params['page'] || 1
  245. @offset ||= @pages.offset
  246. @comments = paginateHelper @comments, 10
  247. end
  248. # Accept a merge request.
  249. # If merge success you get 200 OK.
  250. # Accept a merge request.
  251. #
  252. # @example
  253. # Gitlab.accept_pull_rquest(5, 1)
  254. #
  255. # @param [Integer] project The ID of a project.
  256. # @param [Integer] id The ID of a merge request.
  257. # @return [Gitlab::ObjectifiedHash]
  258. def accept_pull_request
  259. begin
  260. @status = @g.accept_merge_rquest(@project.gpid, params[:id], User.current.gid)
  261. user = User.find_by_login(@status.author.try(:username))
  262. # 更新管理员的pullrequest消息
  263. update_pullrequest_message(params[:id].to_i, @project.id, "PullRequest", 2)
  264. # 接受后,给用户发消息
  265. if ForgeMessage.where(:forge_message_id => params[:id].to_i, :project_id => @project.id, :forge_message_type => "PullRequest", :user_id => user.id).count == 0
  266. send_message_to_author(@project.id, @status.author.try(:username), params[:id], 2)
  267. end
  268. respond_to do |format|
  269. format.js{redirect_to project_pull_request_path(@status.id, :project_id => @project.id)}
  270. end
  271. rescue Gitlab::Error::Forbidden => e
  272. @message = l(:label_pull_request_forbidden)
  273. rescue Gitlab::Error::DataNotAccepted => e
  274. @message = l(:label_pull_request_datanotaccepted)
  275. rescue Gitlab::Error::NotFound => e
  276. @message = l(:label_pull_request_notfound)
  277. rescue Exception => e
  278. logger.info e
  279. end
  280. end
  281. # Updates a merge request.
  282. #
  283. # @example
  284. # Gitlab.update_merge_request(5, 42, :title => 'New title')
  285. #
  286. # @param [Integer] project The ID of a project.
  287. # @param [Integer] id The ID of a merge request.
  288. # @param [Hash] options A customizable set of options.
  289. # @option options [String] :title The title of a merge request.
  290. # @option options [String] :source_branch The source branch name.
  291. # @option options [String] :target_branch The target branch name.
  292. # @option options [Integer] :assignee_id The ID of a user to assign merge request.
  293. # @option options [String] :state_event New state (close|reopen|merge).
  294. # @return [Gitlab::ObjectifiedHash] Information about updated merge request.
  295. def update_pull_request
  296. begin
  297. request = @g.update_merge_request(@project.gpid, params[:id], User.current.gid, :state_event => params[:state])
  298. user = User.find_by_login(request.author.try(:username))
  299. status = params[:state] == "close" ? 4 : 3
  300. #send_message_to_manager(@project.id, params[:id], status)
  301. update_pullrequest_message(request.id, @project.id, "PullRequest", status)
  302. # 给作者发送消息,如何已经发送了消息,则不发
  303. if is_project_manager?(User.current.id, @project.id) && ForgeMessage.where(:forge_message_id => request.id, :project_id => @project.id, :forge_message_type => "PullRequest", :user_id => user.id).count == 0
  304. send_message_to_author(@project.id, user.login, request.id, status)
  305. end
  306. respond_to do |format|
  307. format.html{redirect_to project_pull_request_path(params[:id], :project_id => @project.id)}
  308. end
  309. rescue Exception => e
  310. @message = e.message
  311. end
  312. end
  313. # Creates a merge request.
  314. #
  315. # @example
  316. # Gitlab.create_merge_request(5, 'New merge request',
  317. # :source_branch => 'source_branch', :target_branch => 'target_branch')
  318. # Gitlab.create_merge_request(5, 'New merge request',
  319. # :source_branch => 'source_branch', :target_branch => 'target_branch', :assignee_id => 42)
  320. def create_pull_request_comment
  321. content = params[:pull_request_comment]
  322. begin
  323. @comments = @g.create_merge_request_comment(@project.gpid, params[:id], content, User.current.gid)
  324. respond_to do |format|
  325. format.js{redirect_to project_pull_request_path(params[:id], :project_id => @project.id)}
  326. end
  327. rescue Exception => e
  328. @message = e.message
  329. end
  330. end
  331. # Gets the comments on a merge request.
  332. #
  333. # @example
  334. # Gitlab.merge_request_comments(5, 1)
  335. def pull_request_comments
  336. begin
  337. @comments = @g.merge_request_comments(@project.gpid, params[:id]).reverse
  338. @comments_count = @comments.count
  339. @limit = 10
  340. @is_remote = true
  341. @count = @comments_count
  342. @pages = Paginator.new @count, @limit, params['page'] || 1
  343. @offset ||= @pages.offset
  344. @comments = paginateHelper @comments, 10
  345. rescue Exception => e
  346. @message = e.message
  347. end
  348. end
  349. # Get a list of merge request commits.
  350. # Parameters:
  351. # id (required) - The ID of a project
  352. # merge_request_id (required) - The ID of MR
  353. def pull_request_commits
  354. begin
  355. @type = params[:type]
  356. @commits = @g.merge_request_commits(@project.gpid, params[:id])
  357. @commits_count = @commits.count
  358. @limit = 10
  359. @is_remote = true
  360. @count = @commits_count
  361. @pages = Paginator.new @count, @limit, params['page'] || 1
  362. @offset ||= @pages.offset
  363. @commits = paginateHelper @commits, 10
  364. rescue Exception => e
  365. @message = e.message
  366. end
  367. end
  368. # Shows information about the merge request including its files and changes. With GitLab 8.2 the return fields upvotes and downvotes are deprecated and always return 0.
  369. # Parameters:
  370. # id (required) - The ID of a project
  371. # merge_request_id (required) - The ID of MR
  372. def pull_request_changes
  373. @type = params[:type]
  374. @changes = @g.merge_request_changes(@project.gpid, params[:id]).try(:changes)
  375. @changes_count = @changes.count
  376. @limit = 10
  377. @is_remote = true
  378. @count = @changes_count
  379. @pages = Paginator.new @count, @limit, params['page'] || 1
  380. @offset ||= @pages.offset
  381. @changes = paginateHelper @changes, 10
  382. end
  383. private
  384. # post 相关操作权限控制
  385. # 项目管理员可操作
  386. def manager_allowed
  387. unless is_project_manager?(User.current.id, @project.id)
  388. return render_403
  389. end
  390. end
  391. # 项目成员可操作
  392. def member_allowed
  393. unless User.current.member_of?(@project)
  394. return render_403
  395. end
  396. end
  397. def send_message user_id, project_id, pull_request_id
  398. ForgeMessage.create(:user_id => user_id, :project_id => project_id,
  399. :forge_message_id => pull_request_id, :forge_message_type => "PullRequest", :viewed => true)
  400. end
  401. def send_message_to_manager project_id, pull_request_id, status
  402. project = Project.find(project_id)
  403. project.members.each do |member|
  404. if is_project_manager?(member.user_id, project_id) && User.current.id != member.user_id
  405. add_message(member.user_id, project_id, pull_request_id, status)
  406. end
  407. end
  408. end
  409. def send_message_to_author(project_id, user_login, request_id, status)
  410. user = get_user_by_login_and(user_login)
  411. if user.id != User.current.id
  412. add_message(user.id, project_id, request_id, status)
  413. end
  414. end
  415. def add_message(user_id, project_id, pull_request_id, status)
  416. ForgeMessage.create(:user_id => user_id,
  417. :project_id => project_id,
  418. :forge_message_id => pull_request_id,
  419. :forge_message_type => "PullRequest",
  420. :viewed => false,
  421. :status => status,
  422. :operate_user_id => User.current.id,
  423. )
  424. end
  425. def update_pullrequest_message forge_message_id, project_id, forge_message_type, status
  426. # 更新这条pullrequest消息所有相关的信息
  427. ForgeMessage.where(:forge_message_id => forge_message_id, :project_id => project_id, :forge_message_type => forge_message_type).update_all(:status => status, :operate_user_id => User.current.id, :updated_at => Time.now)
  428. # 更新自己的消息为已读
  429. ForgeMessage.where(:forge_message_id => forge_message_id, :project_id => project_id, :forge_message_type => forge_message_type, :user_id => User.current.id).update_all(:viewed => true)
  430. # 更新pullrequest的status字段
  431. PullRequest.where(:pull_request_id => forge_message_id).update_all(:status => status)
  432. end
  433. def authorize_logged
  434. if !User.current.logged?
  435. redirect_to signin_path
  436. return
  437. end
  438. end
  439. def connect_gitlab
  440. @g = Gitlab.client
  441. end
  442. def find_project_and_repository
  443. @project = Project.find(params[:project_id])
  444. render_404 if @project.gpid.blank?
  445. @repository = Repository.where(:project_id => @project.id, :type => "Repository::Gitlab").first
  446. rescue ActiveRecord::RecordNotFound
  447. render_404
  448. end
  449. end

软件技术创新是当今国家整体创新能力的重要基础和发展引擎。近年来,大众参与的软件创新与创业活动已经成为网络时代软件开发和应用的新形态,正在快速改变着全球软件创新模式和软件产业格局。 ...