forked from Gitlink/forgeplus
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
5877474f59
2
Gemfile
2
Gemfile
|
@ -135,4 +135,4 @@ gem 'doorkeeper'
|
|||
|
||||
gem 'doorkeeper-jwt'
|
||||
|
||||
gem 'gitea-client', '~> 0.10.4'
|
||||
gem 'gitea-client', '~> 0.10.5'
|
|
@ -2,6 +2,7 @@ class Api::V1::BaseController < ApplicationController
|
|||
|
||||
include Api::ProjectHelper
|
||||
include Api::UserHelper
|
||||
include Api::PullHelper
|
||||
|
||||
# before_action :doorkeeper_authorize!
|
||||
# skip_before_action :user_setup
|
||||
|
@ -30,18 +31,18 @@ class Api::V1::BaseController < ApplicationController
|
|||
# 具有对仓库的管理权限
|
||||
def require_manager_above
|
||||
@project = load_project
|
||||
return render_forbidden unless current_user.admin? && @project.manager?(current_user)
|
||||
return render_forbidden if !current_user.admin? && !@project.manager?(current_user)
|
||||
end
|
||||
|
||||
# 具有对仓库的操作权限
|
||||
def require_operate_above
|
||||
@project = load_project
|
||||
return render_forbidden unless current_user.admin? && @project.operator?(current_user)
|
||||
return render_forbidden if !current_user.admin? && !@project.operator?(current_user)
|
||||
end
|
||||
|
||||
# 具有对仓库的访问权限
|
||||
def require_public_and_member_above
|
||||
@project = load_project
|
||||
return render_forbidden unless @project.is_public || (current_user.admin? && @project.member?(current_user))
|
||||
return render_forbidden if !@project.is_public && !current_user.admin? && !@project.member?(current_user)
|
||||
end
|
||||
end
|
|
@ -2,19 +2,4 @@ class Api::V1::Projects::Pulls::BaseController < Api::V1::BaseController
|
|||
before_action :require_public_and_member_above
|
||||
before_action :load_pull_request
|
||||
|
||||
def load_pull_request
|
||||
pull_request_id = params[:pull_id] || params[:id]
|
||||
@pull_request = @project.pull_requests.where(gitea_number: pull_request_id).where.not(id: pull_request_id).take || PullRequest.find_by_id(pull_request_id)
|
||||
@issue = @pull_request&.issue
|
||||
if @pull_request
|
||||
logger.info "###########pull_request founded"
|
||||
@pull_request
|
||||
else
|
||||
logger.info "###########pull_request not found"
|
||||
@pull_request = nil
|
||||
render_not_found and return
|
||||
end
|
||||
|
||||
@pull_request
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
class Api::V1::Projects::Pulls::CommentsController < Api::V1::Projects::Pulls::BaseController
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
class Api::V1::Projects::Pulls::ReviewsController < Api::V1::Projects::Pulls::BaseController
|
||||
|
||||
def index
|
||||
@reviews = @pull_request.reviews
|
||||
@reviews = kaminari_paginate(@reviews)
|
||||
end
|
||||
|
||||
before_action :require_reviewer, only: [:create]
|
||||
|
||||
def create
|
||||
@journal, @review = Api::V1::Projects::Pulls::Reviews::CreateService.call(@project, @pull_request, review_params, current_user)
|
||||
end
|
||||
|
||||
private
|
||||
def require_reviewer
|
||||
return render_forbidden('您没有审查权限,请联系项目管理员') if !current_user.admin? && !@pull_request.reviewers.exists?(current_user.id)
|
||||
end
|
||||
|
||||
def review_params
|
||||
params.require(:review).permit(:content, :commit_id, :status)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
class Api::V1::Projects::PullsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above
|
||||
|
||||
def index
|
||||
@pulls = Api::V1::Projects::Pulls::ListService.call(@project, query_params)
|
||||
@pulls = kaminari_paginate(@pulls)
|
||||
end
|
||||
|
||||
before_action :load_pull_request, only: [:show]
|
||||
|
||||
def show
|
||||
@result_object = Api::V1::Projects::Pulls::GetService.call(@project, @pull_request, current_user&.gitea_token)
|
||||
@last_review = @pull_request.reviews.take
|
||||
end
|
||||
|
||||
private
|
||||
def query_params
|
||||
params.permit(:status, :keyword, :priority_id, :issue_tag_id, :version_id, :reviewer_id, :sort_by, :sort_direction)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
module Api::PullHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def load_pull_request
|
||||
pull_request_id = params[:pull_id] || params[:id]
|
||||
@pull_request = @project.pull_requests.where(gitea_number: pull_request_id).where.not(id: pull_request_id).take || PullRequest.find_by_id(pull_request_id)
|
||||
@issue = @pull_request&.issue
|
||||
if @pull_request
|
||||
logger.info "###########pull_request founded"
|
||||
@pull_request
|
||||
else
|
||||
logger.info "###########pull_request not found"
|
||||
@pull_request = nil
|
||||
render_not_found and return
|
||||
end
|
||||
|
||||
@pull_request
|
||||
end
|
||||
end
|
|
@ -176,7 +176,7 @@ class PullRequestsController < ApplicationController
|
|||
@issue_assign_to = @issue.get_assign_user
|
||||
@gitea_pull = Gitea::PullRequest::GetService.call(@owner.login,
|
||||
@repository.identifier, @pull_request.gitea_number, current_user&.gitea_token)
|
||||
@last_review = @pull_request.issue.reviews.take
|
||||
@last_review = @pull_request.reviews.take
|
||||
end
|
||||
|
||||
def pr_merge
|
||||
|
|
|
@ -68,7 +68,6 @@ class Issue < ApplicationRecord
|
|||
has_many :issue_tags, through: :issue_tags_relates
|
||||
has_many :issue_times, dependent: :destroy
|
||||
has_many :issue_depends, dependent: :destroy
|
||||
has_many :reviews, dependent: :destroy
|
||||
scope :issue_includes, ->{includes(:user)}
|
||||
scope :issue_many_includes, ->{includes(journals: :user)}
|
||||
scope :issue_issue, ->{where(issue_classify: [nil,"issue"])}
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
class Journal < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :issue, foreign_key: :journalized_id, :touch => true
|
||||
belongs_to :issue, foreign_key: :journalized_id, :touch => true, optional: true
|
||||
belongs_to :journalized, polymorphic: true
|
||||
has_many :journal_details, :dependent => :delete_all
|
||||
has_many :attachments, as: :container, dependent: :destroy
|
||||
|
||||
|
|
|
@ -32,12 +32,17 @@ class PullRequest < ApplicationRecord
|
|||
belongs_to :issue
|
||||
belongs_to :user
|
||||
belongs_to :project, counter_cache: true, touch: true
|
||||
# belongs_to :fork_project, foreign_key: :fork_project_id
|
||||
belongs_to :fork_project, class_name: 'Project', foreign_key: :fork_project_id, optional: true
|
||||
has_many :pull_request_assigns, foreign_key: :pull_request_id
|
||||
has_many :pull_request_tags, foreign_key: :pull_request_id
|
||||
has_many :project_trends, as: :trend, dependent: :destroy
|
||||
has_many :attachments, as: :container, dependent: :destroy
|
||||
has_one :gitea_pull, foreign_key: :id, primary_key: :gitea_number, class_name: 'Gitea::Pull'
|
||||
has_many :journals, :as => :journalized, :dependent => :destroy
|
||||
has_many :journal_details, through: :journals
|
||||
has_many :reviews, dependent: :destroy
|
||||
has_many :pull_requests_reviewers, dependent: :destroy
|
||||
has_many :reviewers, through: :pull_requests_reviewers
|
||||
|
||||
scope :merged_and_closed, ->{where.not(status: 0)}
|
||||
scope :opening, -> {where(status: 0)}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: pull_requests_reviewers
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# pull_request_id :integer
|
||||
# reviewer_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_pull_requests_reviewers_on_pull_request_id (pull_request_id)
|
||||
# index_pull_requests_reviewers_on_reviewer_id (reviewer_id)
|
||||
#
|
||||
|
||||
class PullRequestsReviewer < ApplicationRecord
|
||||
|
||||
belongs_to :pull_request
|
||||
belongs_to :reviewers, class_name: 'User', foreign_key: :reviewer_id
|
||||
end
|
|
@ -2,24 +2,24 @@
|
|||
#
|
||||
# Table name: reviews
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# issue_id :integer
|
||||
# reviewer_id :integer
|
||||
# content :text(65535)
|
||||
# commit_id :string(255)
|
||||
# status :integer default("0")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# id :integer not null, primary key
|
||||
# reviewer_id :integer
|
||||
# content :text(65535)
|
||||
# commit_id :string(255)
|
||||
# status :integer default("0")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# pull_request_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_reviews_on_issue_id (issue_id)
|
||||
# index_reviews_on_reviewer_id (reviewer_id)
|
||||
# index_reviews_on_pull_request_id (pull_request_id)
|
||||
# index_reviews_on_reviewer_id (reviewer_id)
|
||||
#
|
||||
|
||||
class Review < ApplicationRecord
|
||||
|
||||
belongs_to :issue
|
||||
belongs_to :pull_request
|
||||
belongs_to :reviewer, class_name: 'User', foreign_key: :reviewer_id
|
||||
has_one :journal, dependent: :destroy
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
class Api::V1::Projects::Pulls::GetService < ApplicationService
|
||||
|
||||
attr_reader :project, :pull_request, :owner, :repo, :index, :token
|
||||
attr_accessor :gitea_data
|
||||
|
||||
def initialize(project, pull_request, token = nil)
|
||||
@project = project
|
||||
@pull_request = pull_request
|
||||
@owner = project&.owner.login
|
||||
@repo = project&.identifier
|
||||
@index = pull_request.gitea_number
|
||||
@token = token
|
||||
end
|
||||
|
||||
def call
|
||||
load_gitea_data
|
||||
|
||||
gitea_data
|
||||
end
|
||||
|
||||
private
|
||||
def request_params
|
||||
{
|
||||
access_token: token
|
||||
}
|
||||
end
|
||||
|
||||
def load_gitea_data
|
||||
@gitea_data = $gitea_client.get_repos_pulls_by_owner_repo_index(owner, repo, index, {query: request_params})
|
||||
# raise Error, '获取合并请求失败!' unless @gitea_data.is_a?(Hash)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
class Api::V1::Projects::Pulls::ListService < ApplicationService
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_reader :project, :keyword, :status, :priority_id, :issue_tag_id, :version_id, :reviewer_id, :sort_by, :sort_direction
|
||||
attr_accessor :queried_pull_requests
|
||||
|
||||
validates :status, inclusion: {in: [0, 1, 2], message: "请输入正确的Status"}, allow_nil: true
|
||||
validates :sort_by, inclusion: {in: PullRequest.column_names, message: '请输入正确的SortBy'}
|
||||
validates :sort_direction, inclusion: {in: %w(asc desc), message: '请输入正确的SortDirection'}
|
||||
|
||||
def initialize(project, params={})
|
||||
@project = project
|
||||
@keyword = params[:keyword]
|
||||
@status = params[:status].to_i
|
||||
@priority_id = params[:priority_id]
|
||||
@issue_tag_id = params[:issue_tag_id]
|
||||
@version_id = params[:version_id]
|
||||
@reviewer_id = params[:reviewer_id]
|
||||
@sort_by = params[:sort_by] || 'created_at'
|
||||
@sort_direction = params[:sort_direction] || 'desc'
|
||||
end
|
||||
|
||||
def call
|
||||
raise Error, errors.full_messages.join(",") unless valid?
|
||||
pull_request_query_data
|
||||
|
||||
queried_pull_requests
|
||||
end
|
||||
|
||||
private
|
||||
def pull_request_query_data
|
||||
pull_requests = @project.pull_requests
|
||||
|
||||
pull_requests = pull_requests.where(status: status) if status.present?
|
||||
pull_requests = pull_requests.where(issues: {priority_id: priority_id}) if priority_id.present?
|
||||
pull_requests = pull_requests.where(issue_tags: {id: issue_tag_id}) if issue_tag_id.present?
|
||||
pull_requests = pull_requests.where(issues: {fixed_version_id: version_id}) if version_id.present?
|
||||
pull_requests = pull_requests.where(users: {id: reviewer_id}) if reviewer_id.present?
|
||||
|
||||
q = pull_requests.ransack(title_or_body_cont: keyword)
|
||||
scope = q.result.includes(:fork_project, :journals, :reviews, :reviewers, issue: [:journals, :priority, :version, :issue_tags])
|
||||
scope = scope.order("pull_requests.#{sort_by} #{sort_direction}")
|
||||
|
||||
@queried_pull_requests = scope
|
||||
end
|
||||
end
|
|
@ -24,17 +24,17 @@ class Api::V1::Projects::Pulls::Reviews::CreateService < ApplicationService
|
|||
end
|
||||
|
||||
return @journal, @review
|
||||
rescue
|
||||
raise Error, '服务器错误,请联系系统管理员!'
|
||||
# rescue
|
||||
# raise Error, '服务器错误,请联系系统管理员!'
|
||||
end
|
||||
|
||||
private
|
||||
def create_review
|
||||
@review = issue.reviews.create!(status: status, content: content, commit_id: commit_id, reviewer_id: @current_user.id)
|
||||
@review = pull_request.reviews.create!(status: status, content: content, commit_id: commit_id, reviewer_id: @current_user.id)
|
||||
end
|
||||
|
||||
def create_journal
|
||||
@journal = issue.journals.create!(notes: content, user_id: @current_user.id, review_id: @review.id)
|
||||
@journal = pull_request.journals.create!(notes: content, user_id: @current_user.id, review_id: @review.id)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,25 @@
|
|||
json.(pull, :id, :head, :base, :is_original)
|
||||
json.index pull.gitea_number
|
||||
json.status pull.status == 1 ? "merged" : (pull.status == 2 ? "closed" : "open")
|
||||
|
||||
fork_project = pull&.fork_project
|
||||
if fork_project.present?
|
||||
json.fork_project do
|
||||
json.(fork_project, :id, :identifier)
|
||||
json.login fork_project&.owner&.login
|
||||
end
|
||||
end
|
||||
|
||||
issue = pull&.issue
|
||||
json.issue do
|
||||
json.id issue&.id
|
||||
json.author do
|
||||
json.partial! '/api/v1/users/simple_user', user: issue&.user
|
||||
end
|
||||
json.priority issue&.priority.try(:name)
|
||||
json.version issue&.version.try(:name)
|
||||
json.comments_count issue.journals.count
|
||||
json.issue_tags issue.get_issue_tags
|
||||
end
|
||||
|
||||
json.comments_count pull.journals.count
|
|
@ -0,0 +1,4 @@
|
|||
json.total_count @pulls.total_count
|
||||
json.pulls @pulls.each do |pull|
|
||||
json.partial! 'api/v1/projects/pulls/simple_detail', pull: pull
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
json.reviewer do
|
||||
json.partial! "api/v1/users/simple_user", user: @review.reviewer
|
||||
end
|
||||
json.pull_request do
|
||||
json.partial! "api/v1/projects/pulls/simple_detail", pull: @review.pull_request
|
||||
end
|
||||
json.(@review, :id, :commit_id, :content, :status)
|
||||
json.created_at format_time(@review.created_at)
|
|
@ -0,0 +1,29 @@
|
|||
json.partial! "api/v1/projects/pulls/simple_detail", pull: @pull_request
|
||||
json.merge_base @result_object['merge_base']
|
||||
json.base_commit_sha @result_object['base']['sha']
|
||||
json.head_commit_sha @result_object['head']['sha']
|
||||
json.commit_num @result_object['commit_num']
|
||||
json.changed_files @result_object['changed_files']
|
||||
json.is_locked @result_object['is_locked']
|
||||
json.mergeable @result_object['mergeable'] # 是否能合并
|
||||
json.merged @result_object['merged']
|
||||
json.merged_at @result_object['merged_at'].nil? ? '' : render_unix_time( @result_object['merged_at'])
|
||||
json.merge_commit_sha @result_object['merge_commit_sha']
|
||||
json.merge_by do
|
||||
if @result_object['merged_by']
|
||||
json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(@result_object['merged_by']), name: @result_object['merged_by']['login'] }
|
||||
else
|
||||
json.nil!
|
||||
end
|
||||
end
|
||||
json.last_review do
|
||||
if @last_review.present?
|
||||
json.(@last_review, :id, :commit_id, :content, :status)
|
||||
json.created_at format_time(@last_review.created_at)
|
||||
json.reviewer do
|
||||
json.partial! "api/v1/users/simple_user", user: @last_review.reviewer
|
||||
end
|
||||
else
|
||||
json.nil!
|
||||
end
|
||||
end
|
|
@ -25,6 +25,7 @@ defaults format: :json do
|
|||
get :diff
|
||||
end
|
||||
end
|
||||
resources :reviews, only: [:index, :create]
|
||||
end
|
||||
|
||||
resources :versions
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
class CreatePullRequestsReviewers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :pull_requests_reviewers do |t|
|
||||
t.belongs_to :pull_request, index: true
|
||||
t.belongs_to :reviewer, class_name: User, index:true
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,6 @@
|
|||
class ChangeReviewsReferenceToPullRequests < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
remove_reference :reviews, :issue
|
||||
add_reference :reviews, :pull_request
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe PullRequestsReviewer, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
Loading…
Reference in New Issue