FIX Merge master branch
This commit is contained in:
commit
837aa1ea9e
|
@ -0,0 +1,22 @@
|
||||||
|
kind: pipeline
|
||||||
|
name: default
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: arm64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: install
|
||||||
|
image: ruby:2.4.5
|
||||||
|
commands:
|
||||||
|
- gem install bundler
|
||||||
|
- bundle -v
|
||||||
|
- bundle install --jobs=1 --retry=1
|
||||||
|
|
||||||
|
- name: test
|
||||||
|
image: ruby:2.4.5
|
||||||
|
volumes:
|
||||||
|
- name: bundle
|
||||||
|
path: /usr/local/bundle
|
||||||
|
commands:
|
||||||
|
- rake
|
5
Gemfile
5
Gemfile
|
@ -1,8 +1,6 @@
|
||||||
source 'https://gems.ruby-china.com'
|
source 'https://gems.ruby-china.com'
|
||||||
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
||||||
|
|
||||||
ruby '2.3.7'
|
|
||||||
|
|
||||||
gem 'rails', '~> 5.2.0'
|
gem 'rails', '~> 5.2.0'
|
||||||
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
|
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
|
||||||
gem 'puma', '~> 3.11'
|
gem 'puma', '~> 3.11'
|
||||||
|
@ -19,8 +17,6 @@ gem 'kaminari', '~> 1.1', '>= 1.1.1'
|
||||||
|
|
||||||
gem 'bootsnap', '>= 1.1.0', require: false
|
gem 'bootsnap', '>= 1.1.0', require: false
|
||||||
|
|
||||||
gem 'gitlab', path: 'lib/gitlab-cli'
|
|
||||||
|
|
||||||
gem 'chinese_pinyin'
|
gem 'chinese_pinyin'
|
||||||
|
|
||||||
gem 'rack-cors'
|
gem 'rack-cors'
|
||||||
|
@ -74,6 +70,7 @@ group :development do
|
||||||
gem 'listen', '>= 3.0.5', '< 3.2'
|
gem 'listen', '>= 3.0.5', '< 3.2'
|
||||||
gem 'spring'
|
gem 'spring'
|
||||||
gem 'spring-watcher-listen', '~> 2.0.0'
|
gem 'spring-watcher-listen', '~> 2.0.0'
|
||||||
|
gem "annotate", "~> 2.6.0"
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
|
23
Gemfile.lock
23
Gemfile.lock
|
@ -1,10 +1,3 @@
|
||||||
PATH
|
|
||||||
remote: lib/gitlab-cli
|
|
||||||
specs:
|
|
||||||
gitlab (3.2.0)
|
|
||||||
httparty
|
|
||||||
terminal-table
|
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://gems.ruby-china.com/
|
remote: https://gems.ruby-china.com/
|
||||||
specs:
|
specs:
|
||||||
|
@ -61,6 +54,9 @@ GEM
|
||||||
public_suffix (>= 2.0.2, < 5.0)
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
ancestry (3.0.7)
|
ancestry (3.0.7)
|
||||||
activerecord (>= 3.2.0)
|
activerecord (>= 3.2.0)
|
||||||
|
annotate (2.6.5)
|
||||||
|
activerecord (>= 2.3.0)
|
||||||
|
rake (>= 0.8.7)
|
||||||
archive-zip (0.12.0)
|
archive-zip (0.12.0)
|
||||||
io-like (~> 0.3.0)
|
io-like (~> 0.3.0)
|
||||||
arel (9.0.0)
|
arel (9.0.0)
|
||||||
|
@ -138,9 +134,6 @@ GEM
|
||||||
harmonious_dictionary (0.0.1)
|
harmonious_dictionary (0.0.1)
|
||||||
hashie (3.6.0)
|
hashie (3.6.0)
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
httparty (0.18.0)
|
|
||||||
mime-types (~> 3.0)
|
|
||||||
multi_xml (>= 0.5.2)
|
|
||||||
i18n (1.8.2)
|
i18n (1.8.2)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
io-like (0.3.1)
|
io-like (0.3.1)
|
||||||
|
@ -177,9 +170,6 @@ GEM
|
||||||
mimemagic (~> 0.3.2)
|
mimemagic (~> 0.3.2)
|
||||||
maruku (0.7.3)
|
maruku (0.7.3)
|
||||||
method_source (0.9.2)
|
method_source (0.9.2)
|
||||||
mime-types (3.3.1)
|
|
||||||
mime-types-data (~> 3.2015)
|
|
||||||
mime-types-data (3.2019.1009)
|
|
||||||
mimemagic (0.3.4)
|
mimemagic (0.3.4)
|
||||||
mini_mime (1.0.2)
|
mini_mime (1.0.2)
|
||||||
mini_portile2 (2.4.0)
|
mini_portile2 (2.4.0)
|
||||||
|
@ -402,8 +392,6 @@ GEM
|
||||||
actionpack (>= 4.0)
|
actionpack (>= 4.0)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
terminal-table (1.8.0)
|
|
||||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
|
||||||
thor (1.0.1)
|
thor (1.0.1)
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
tilt (2.0.10)
|
tilt (2.0.10)
|
||||||
|
@ -437,6 +425,7 @@ DEPENDENCIES
|
||||||
acts-as-taggable-on (~> 6.0)
|
acts-as-taggable-on (~> 6.0)
|
||||||
acts_as_list
|
acts_as_list
|
||||||
ancestry
|
ancestry
|
||||||
|
annotate (~> 2.6.0)
|
||||||
awesome_print
|
awesome_print
|
||||||
axlsx (~> 3.0.0.pre)
|
axlsx (~> 3.0.0.pre)
|
||||||
axlsx_rails (~> 0.5.2)
|
axlsx_rails (~> 0.5.2)
|
||||||
|
@ -452,7 +441,6 @@ DEPENDENCIES
|
||||||
enumerize
|
enumerize
|
||||||
faraday (~> 0.15.4)
|
faraday (~> 0.15.4)
|
||||||
font-awesome-sass (= 4.7.0)
|
font-awesome-sass (= 4.7.0)
|
||||||
gitlab!
|
|
||||||
grape-entity (~> 0.7.1)
|
grape-entity (~> 0.7.1)
|
||||||
groupdate (~> 4.1.0)
|
groupdate (~> 4.1.0)
|
||||||
harmonious_dictionary (~> 0.0.1)
|
harmonious_dictionary (~> 0.0.1)
|
||||||
|
@ -502,8 +490,5 @@ DEPENDENCIES
|
||||||
web-console (>= 3.3.0)
|
web-console (>= 3.3.0)
|
||||||
wkhtmltopdf-binary
|
wkhtmltopdf-binary
|
||||||
|
|
||||||
RUBY VERSION
|
|
||||||
ruby 2.3.7p456
|
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.1.4
|
2.1.4
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -110,33 +110,33 @@ class AccountsController < ApplicationController
|
||||||
# params[:login] 邮箱或者手机号
|
# params[:login] 邮箱或者手机号
|
||||||
# params[:code] 验证码
|
# params[:code] 验证码
|
||||||
# code_type 1:注册手机验证码 8:邮箱注册验证码
|
# code_type 1:注册手机验证码 8:邮箱注册验证码
|
||||||
|
# 本地forge注册入口
|
||||||
def register
|
def register
|
||||||
begin
|
begin
|
||||||
# 查询验证码是否正确;type只可能是1或者8
|
# 查询验证码是否正确;type只可能是1或者8
|
||||||
type = phone_mail_type(params[:login].strip)
|
type = phone_mail_type(params[:login].strip)
|
||||||
code = params[:code].strip
|
# code = params[:code].strip
|
||||||
|
|
||||||
if type == 1
|
if type == 1
|
||||||
uid_logger("start register by phone: type is #{type}")
|
uid_logger("start register by phone: type is #{type}")
|
||||||
pre = 'p'
|
pre = 'p'
|
||||||
email = nil
|
email = nil
|
||||||
phone = params[:login]
|
phone = params[:login]
|
||||||
verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last
|
# verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last
|
||||||
|
# TODO: 暂时限定邮箱注册
|
||||||
|
return normal_status(-1, '只支持邮箱注册')
|
||||||
else
|
else
|
||||||
uid_logger("start register by email: type is #{type}")
|
uid_logger("start register by email: type is #{type}")
|
||||||
pre = 'm'
|
pre = 'm'
|
||||||
email = params[:login]
|
email = params[:login]
|
||||||
phone = nil
|
phone = nil
|
||||||
verifi_code = VerificationCode.where(email: email, code: code, code_type: 8).last
|
return normal_status(-1, "该邮箱已注册") if User.exists?(mail: params[:login])
|
||||||
|
return normal_status(-1, "邮箱格式错误") unless params[:login] =~ CustomRegexp::EMAIL
|
||||||
|
# verifi_code = VerificationCode.where(email: email, code: code, code_type: 8).last
|
||||||
end
|
end
|
||||||
uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}")
|
# uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}")
|
||||||
# check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60)
|
# check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60)
|
||||||
# todo 上线前请删除万能验证码"513231"
|
# todo 上线前请删除万能验证码"513231"
|
||||||
unless code == "513231" && request.subdomain == "test-newweb"
|
|
||||||
return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip
|
|
||||||
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
|
|
||||||
end
|
|
||||||
|
|
||||||
return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:password] =~ CustomRegexp::PASSWORD
|
return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:password] =~ CustomRegexp::PASSWORD
|
||||||
|
|
||||||
code = generate_identifier User, 8, pre
|
code = generate_identifier User, 8, pre
|
||||||
|
@ -146,23 +146,20 @@ class AccountsController < ApplicationController
|
||||||
# 现在因为是验证码,所以在注册的时候就可以激活
|
# 现在因为是验证码,所以在注册的时候就可以激活
|
||||||
@user.activate
|
@user.activate
|
||||||
# 必须要用save操作,密码的保存是在users中
|
# 必须要用save操作,密码的保存是在users中
|
||||||
if @user.save!
|
|
||||||
# todo user_extension
|
interactor = Gitea::RegisterInteractor.call({username: login, email: email, password: params[:password]})
|
||||||
UserExtension.create!(user_id: @user.id)
|
if interactor.success?
|
||||||
# 注册完成,手机号或邮箱想可以奖励500金币
|
gitea_user = interactor.result
|
||||||
# RewardGradeService.call(
|
result = Gitea::User::GenerateTokenService.new(login, params[:password]).call
|
||||||
# @user,
|
@user.gitea_token = result['sha1']
|
||||||
# container_id: @user.id,
|
@user.gitea_uid = gitea_user['id']
|
||||||
# container_type: pre == 'p' ? 'Phone' : 'Mail',
|
if @user.save!
|
||||||
# score: 500
|
UserExtension.create!(user_id: @user.id)
|
||||||
# )
|
successful_authentication(@user)
|
||||||
# 注册时,记录是否是引流用户
|
normal_status("注册成功")
|
||||||
ip = request.remote_ip
|
end
|
||||||
ua = UserAgent.find_by_ip(ip)
|
else
|
||||||
ua.update_column(:agent_type, UserAgent::USER_REGISTER) if ua
|
tip_exception(-1, interactor.error)
|
||||||
successful_authentication(@user)
|
|
||||||
# session[:user_id] = @user.id
|
|
||||||
normal_status("注册成功")
|
|
||||||
end
|
end
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
uid_logger_error(e.message)
|
uid_logger_error(e.message)
|
||||||
|
|
|
@ -6,6 +6,12 @@ class Admins::LaboratoriesController < Admins::BaseController
|
||||||
@laboratories = paginate laboratories.preload(:laboratory_users)
|
@laboratories = paginate laboratories.preload(:laboratory_users)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
Admins::CreateLaboratoryService.call(create_params)
|
Admins::CreateLaboratoryService.call(create_params)
|
||||||
render_ok
|
render_ok
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
class Admins::LaboratorySettingsController < Admins::BaseController
|
class Admins::LaboratorySettingsController < Admins::BaseController
|
||||||
|
|
||||||
|
def new
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@laboratory = current_laboratory
|
@laboratory = current_laboratory
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ class ApplicationController < ActionController::Base
|
||||||
include LoggerHelper
|
include LoggerHelper
|
||||||
include LoginHelper
|
include LoginHelper
|
||||||
include RegisterHelper
|
include RegisterHelper
|
||||||
|
|
||||||
protect_from_forgery prepend: true, unless: -> { request.format.json? }
|
protect_from_forgery prepend: true, unless: -> { request.format.json? }
|
||||||
|
|
||||||
before_action :check_sign
|
before_action :check_sign
|
||||||
|
@ -343,7 +343,8 @@ class ApplicationController < ActionController::Base
|
||||||
elsif params[:debug] == 'student'
|
elsif params[:debug] == 'student'
|
||||||
User.current = User.find 8686
|
User.current = User.find 8686
|
||||||
elsif params[:debug] == 'admin'
|
elsif params[:debug] == 'admin'
|
||||||
user = User.find 1
|
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
|
||||||
|
user = User.find 36480
|
||||||
User.current = user
|
User.current = user
|
||||||
cookies.signed[:user_id] = user.id
|
cookies.signed[:user_id] = user.id
|
||||||
end
|
end
|
||||||
|
@ -384,11 +385,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_user
|
def current_user
|
||||||
if Rails.env.development?
|
User.current
|
||||||
User.current = User.find 1
|
|
||||||
else
|
|
||||||
User.current
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
## 默认输出json
|
## 默认输出json
|
||||||
|
@ -744,12 +741,12 @@ class ApplicationController < ActionController::Base
|
||||||
namespace = params[:owner]
|
namespace = params[:owner]
|
||||||
id = params[:repo] || params[:id]
|
id = params[:repo] || params[:id]
|
||||||
|
|
||||||
@project = Project.find_with_namespace(namespace, id)
|
@project, @owner = Project.find_with_namespace(namespace, id)
|
||||||
|
|
||||||
if @project and current_user.can_read_project?(@project)
|
if @project and current_user.can_read_project?(@project)
|
||||||
logger.info "###########: has project and can read project"
|
logger.info "###########: has project and can read project"
|
||||||
@project
|
@project
|
||||||
elsif current_user.is_a?(AnonymousUser)
|
elsif @project && current_user.is_a?(AnonymousUser)
|
||||||
logger.info "###########:This is AnonymousUser"
|
logger.info "###########:This is AnonymousUser"
|
||||||
@project = nil if !@project.is_public?
|
@project = nil if !@project.is_public?
|
||||||
render_forbidden and return
|
render_forbidden and return
|
||||||
|
@ -762,7 +759,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_repository
|
def load_repository
|
||||||
@repository ||= load_project.repository
|
@repository ||= load_project&.repository
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#
|
#
|
||||||
# 文件上传
|
# 文件上传
|
||||||
class AttachmentsController < ApplicationController
|
class AttachmentsController < ApplicationController
|
||||||
before_action :require_login, :check_auth, except: [:show]
|
before_action :require_login, :check_auth, except: [:show, :preview_attachment, :get_file]
|
||||||
before_action :find_file, only: %i[show destroy]
|
before_action :find_file, only: %i[show destroy]
|
||||||
before_action :attachment_candown, only: [:show]
|
before_action :attachment_candown, only: [:show]
|
||||||
skip_before_action :check_sign, only: [:show, :create]
|
skip_before_action :check_sign, only: [:show, :create]
|
||||||
|
@ -28,6 +28,15 @@ class AttachmentsController < ApplicationController
|
||||||
update_downloads(@file)
|
update_downloads(@file)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def get_file
|
||||||
|
normal_status(-1, "参数缺失") if params[:download_url].blank?
|
||||||
|
url = URI.encode(params[:download_url].to_s.gsub("http:", "https:"))
|
||||||
|
response = Faraday.get(url)
|
||||||
|
filename = params[:download_url].to_s.split("/").pop()
|
||||||
|
send_data(response.body.force_encoding("UTF-8"), filename: filename, type: "application/octet-stream", disposition: 'attachment')
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
# 1. 本地存储
|
# 1. 本地存储
|
||||||
# 2. 上传到云
|
# 2. 上传到云
|
||||||
|
@ -107,6 +116,26 @@ class AttachmentsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# 附件为视频时,点击播放
|
||||||
|
def preview_attachment
|
||||||
|
attachment = Attachment.find_by(id: params[:id])
|
||||||
|
dir_path = "#{Rails.root}/public/preview"
|
||||||
|
Dir.mkdir(dir_path) unless Dir.exist?(dir_path)
|
||||||
|
if params[:status] == "preview"
|
||||||
|
if system("cp -r #{absolute_path(local_path(attachment))} #{dir_path}/")
|
||||||
|
render json: {status: 1, url: "/preview/#{attachment.disk_filename}"}
|
||||||
|
else
|
||||||
|
normal_status(-1, "出现错误,请稍后重试")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if system("rm -rf #{dir_path}/#{attachment.disk_filename}")
|
||||||
|
normal_status(1, "操作成功")
|
||||||
|
else
|
||||||
|
normal_status(-1, "出现错误,请稍后重试")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def find_file
|
def find_file
|
||||||
@file =
|
@file =
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
class Ci::BaseController < ApplicationController
|
||||||
|
include Ci::DbConnectable
|
||||||
|
|
||||||
|
before_action :require_login
|
||||||
|
before_action :connect_to_ci_database, if: -> { current_user && !current_user.is_a?(AnonymousUser) && !current_user.devops_uninit? }
|
||||||
|
before_action :connect_to_ci_database, only: :load_repo
|
||||||
|
|
||||||
|
def load_repo
|
||||||
|
namespace = params[:owner]
|
||||||
|
id = params[:repo] || params[:id]
|
||||||
|
|
||||||
|
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def authorize_access_project!
|
||||||
|
unless @project.manager?(current_user)
|
||||||
|
return render_forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_manager!
|
||||||
|
unless @project.manager?(current_user)
|
||||||
|
return render_forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_admin!
|
||||||
|
return render_forbidden unless current_user.admin?
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorize_owner!
|
||||||
|
unless @project.owner?(current_user)
|
||||||
|
return render_forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_cloud_account
|
||||||
|
@cloud_account ||= current_user.ci_cloud_account
|
||||||
|
@cloud_account.blank? ? nil : @cloud_account
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_ci_user
|
||||||
|
@ci_user ||= Ci::User.find_by(user_login: params[:owner])
|
||||||
|
@ci_user.blank? ? raise("未找到相关的记录") : @ci_user
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,54 @@
|
||||||
|
class Ci::BuildsController < Ci::BaseController
|
||||||
|
include RepositoriesHelper
|
||||||
|
|
||||||
|
before_action :load_project
|
||||||
|
before_action :authorize_owner!, only: [:restart, :stop]
|
||||||
|
before_action :load_repo
|
||||||
|
before_action :find_cloud_account, except: [:index, :show]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@user = current_user
|
||||||
|
scope = @repo.builds
|
||||||
|
|
||||||
|
scope = Ci::Builds::ListQuery.call(@repo, params)
|
||||||
|
|
||||||
|
@total_count = scope.map(&:build_id).size
|
||||||
|
@builds = paginate scope
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@build = @repo.builds.includes(stages: [:steps]).find_by(build_number: params[:build])
|
||||||
|
end
|
||||||
|
|
||||||
|
def restart
|
||||||
|
result = Ci::Drone::API.new(@ci_user.user_hash, @cloud_account.drone_url, @repo.repo_namespace, @repo.repo_name, number: params[:build]).restart
|
||||||
|
|
||||||
|
render json: result
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop
|
||||||
|
result = Ci::Drone::API.new(@ci_user.user_hash, @cloud_account.drone_url, @repo.repo_namespace, @repo.repo_name, number: params[:build]).stop
|
||||||
|
render json: result
|
||||||
|
end
|
||||||
|
|
||||||
|
def logs
|
||||||
|
# TODO **待优化**
|
||||||
|
# 因直接操作ci库,如下查询待优化,可直接根据log id查询即可
|
||||||
|
build = @repo.builds.find_by(build_number: params[:build])
|
||||||
|
return render_not_found("Couldn't found build with 'number'= #{params[:build]}") if build.blank?
|
||||||
|
|
||||||
|
stage = build.stages.includes(steps: [:log]).find_by(stage_number: params[:stage])
|
||||||
|
return render_not_found("Couldn't found build with 'number'= #{params[:stage]}") if stage.blank?
|
||||||
|
|
||||||
|
step = stage.steps.find_by(step_number: params[:step])
|
||||||
|
return render_not_found("Couldn't found build with 'number'= #{params[:step]}") if step.blank?
|
||||||
|
|
||||||
|
log = step.log
|
||||||
|
|
||||||
|
result = log.blank? ? nil : (log.log_data[0..5].include?('null') ? nil : JSON.parse(log.log_data))
|
||||||
|
|
||||||
|
# result = Ci::Drone::API.new(@user.user_hash, @cloud_account.drone_url, @repo.repo_namespace, @repo.repo_name, build: params[:build], stage: params[:stage], step: params[:step]).logs
|
||||||
|
|
||||||
|
render json: result
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,101 @@
|
||||||
|
class Ci::CloudAccountsController < Ci::BaseController
|
||||||
|
include Ci::CloudAccountManageable
|
||||||
|
|
||||||
|
skip_before_action :connect_to_ci_database, only: %i[create bind]
|
||||||
|
before_action :load_project, only: %i[create activate]
|
||||||
|
before_action :authorize_owner!, only: %i[create activate]
|
||||||
|
before_action :load_repo, only: %i[activate]
|
||||||
|
before_action :find_cloud_account, only: %i[show oauth_grant]
|
||||||
|
before_action :validate_params!, only: %i[create bind]
|
||||||
|
before_action only: %i[create bind] do
|
||||||
|
connect_to_ci_database(master_db: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
flag, msg = check_bind_cloud_account!
|
||||||
|
return render_error(msg) if flag === true
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
@cloud_account = bind_account!
|
||||||
|
if @cloud_account.blank?
|
||||||
|
render_error('激活失败, 请检查你的云服务器信息是否正确.')
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
||||||
|
render_ok(redirect_url: @cloud_account.authenticate_url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def activate
|
||||||
|
return render_error('请先认证') unless current_user.ci_certification?
|
||||||
|
|
||||||
|
begin
|
||||||
|
@cloud_account = Ci::CloudAccount.find params[:id]
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
if @repo
|
||||||
|
return render_error('该项目已经激活') if @repo.repo_active?
|
||||||
|
@repo.activate!(@ci_user.user_id)
|
||||||
|
else
|
||||||
|
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
||||||
|
@user.update_column(:user_syncing, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
result = bind_hook!(current_user, @cloud_account, @repo)
|
||||||
|
@project.update_columns(open_devops: true, gitea_webhook_id: result['id'])
|
||||||
|
@cloud_account.update_column(:ci_user_id, @ci_user.user_id)
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def bind
|
||||||
|
flag, msg = check_bind_cloud_account!
|
||||||
|
return render_error(msg) if flag === true
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
@cloud_account = bind_account!
|
||||||
|
if @cloud_account.blank?
|
||||||
|
render_error('激活失败, 请检查你的云服务器信息是否正确.')
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unbind
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
unbind_account!
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def oauth_grant
|
||||||
|
password = params[:password].to_s
|
||||||
|
return render_error('你输入的密码不正确.') unless current_user.check_password?(password)
|
||||||
|
|
||||||
|
oauth = current_user.oauths.last
|
||||||
|
return render_error("服务器出小差了.") if oauth.blank?
|
||||||
|
|
||||||
|
result = gitea_oauth_grant!(password, oauth)
|
||||||
|
return render_error('授权失败.') unless result === true
|
||||||
|
current_user.set_drone_step!(User::DEVOPS_CERTIFICATION)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def validate_params!
|
||||||
|
Ci::CreateCloudAccountForm.new(devops_params).validate!
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,20 @@
|
||||||
|
class Ci::LanguagesController < Ci::BaseController
|
||||||
|
# TODO 需要开启权限认证,只有该项目devops初始化成功后才能获取语言列表
|
||||||
|
before_action :find_langugae, only: :show
|
||||||
|
|
||||||
|
def index
|
||||||
|
@languages = Ci::Language.by_usage_amount_desc
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def common
|
||||||
|
@languages = Ci::Language.six_common
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_langugae
|
||||||
|
@language = Ci::Language.find params[:id]
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,73 @@
|
||||||
|
class Ci::ProjectsController < Ci::BaseController
|
||||||
|
include RepositoriesHelper
|
||||||
|
include Ci::CloudAccountManageable
|
||||||
|
|
||||||
|
before_action :load_project
|
||||||
|
before_action :load_repo, only: [:update_trustie_pipeline, :activate, :deactivate]
|
||||||
|
before_action :authorize_owner!, only: [:authorize]
|
||||||
|
before_action :find_cloud_account, only: [:authorize, :activate, :deactivate]
|
||||||
|
|
||||||
|
def authorize
|
||||||
|
@user = current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
# get .trustie-pipeline.yml file
|
||||||
|
def get_trustie_pipeline
|
||||||
|
file_path_uri = URI.parse('.trustie-pipeline.yml')
|
||||||
|
interactor = Repositories::EntriesInteractor.call(@project.owner, @project.identifier, file_path_uri, ref: params[:ref] || "master")
|
||||||
|
if interactor.success?
|
||||||
|
file = interactor.result
|
||||||
|
return render json: {} if file[:status]
|
||||||
|
|
||||||
|
json = {name: file['name'], path: file['path'], sha: file['sha'], content: render_decode64_content(file['content'])}
|
||||||
|
render json: json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_trustie_pipeline
|
||||||
|
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, params[:owner], params.merge(identifier: @project.identifier))
|
||||||
|
if interactor.success?
|
||||||
|
@file = interactor.result
|
||||||
|
render_result(1, "更新成功")
|
||||||
|
else
|
||||||
|
render_error(interactor.error)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def activate
|
||||||
|
return render_error('你还未认证') unless current_user.ci_certification?
|
||||||
|
|
||||||
|
begin
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
if @repo
|
||||||
|
return render_error('该项目已经激活') if @repo.repo_active?
|
||||||
|
if @project.ci_reactivate?
|
||||||
|
@project.ci_reactivate!(@repo)
|
||||||
|
return render_ok
|
||||||
|
end
|
||||||
|
@repo.activate!(@ci_user.user_id)
|
||||||
|
else
|
||||||
|
@repo = Ci::Repo.auto_create!(@ci_user, @project)
|
||||||
|
@ci_user.update_column(:user_syncing, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
result = bind_hook!(current_user, @cloud_account, @repo)
|
||||||
|
@project.update_columns(open_devops: true, gitea_webhook_id: result['id'])
|
||||||
|
@project.increment!(:open_devops_count)
|
||||||
|
@cloud_account.update_column(:ci_user_id, @ci_user.user_id)
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
rescue Exception => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def deactivate
|
||||||
|
return render_error('该项目已经取消激活') if !@repo.repo_active?
|
||||||
|
|
||||||
|
@project.update_column(:open_devops, false)
|
||||||
|
@repo.deactivate!
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
class CompareController < ApplicationController
|
||||||
|
# skip_before_action :require_login
|
||||||
|
before_action :load_repository
|
||||||
|
|
||||||
|
def index
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
base_ref = Addressable::URI.unescape(params[:base])
|
||||||
|
@ref = head_ref = Addressable::URI.unescape(params[:head]&.split('.json')[0])
|
||||||
|
@compare_result = Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base_ref, head_ref)
|
||||||
|
|
||||||
|
# render json: @compare_result
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,138 @@
|
||||||
|
module Ci::CloudAccountManageable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
end
|
||||||
|
|
||||||
|
def bind_account!
|
||||||
|
# 1. 保存华为云服务器帐号
|
||||||
|
create_params = devops_params.merge(ip_num: IPAddr.new(devops_params[:ip_num].strip).to_i, secret: Ci::CloudAccount.encrypted_secret(devops_params[:secret]))
|
||||||
|
|
||||||
|
cloud_account = Ci::CloudAccount.new(create_params)
|
||||||
|
cloud_account.user = current_user
|
||||||
|
cloud_account.save!
|
||||||
|
|
||||||
|
# 2. 生成oauth2应用程序的client_id和client_secrete
|
||||||
|
gitea_oauth = Gitea::Oauth2::CreateService.call(current_user.gitea_token, {name: "pipeline-#{SecureRandom.hex(8)}", redirect_uris: ["#{cloud_account.drone_url}/login"]})
|
||||||
|
logger.info "######### gitea_oauth: #{gitea_oauth}"
|
||||||
|
oauth = Oauth.new(client_id: gitea_oauth['client_id'],
|
||||||
|
client_secret: gitea_oauth['client_secret'],
|
||||||
|
redirect_uri: gitea_oauth['redirect_uris'],
|
||||||
|
gitea_oauth_id: gitea_oauth['id'],
|
||||||
|
user_id: current_user.id)
|
||||||
|
oauth.save!
|
||||||
|
|
||||||
|
# 创建数据ci端数据库
|
||||||
|
database_result = auto_create_database!(@connection, "#{current_user.login}_drone")
|
||||||
|
logger.info "[CI::DbConnectable] auto_create_database's result: #{database_result}"
|
||||||
|
|
||||||
|
# 初始化表结构
|
||||||
|
sub_connection = connect_to_ci_database
|
||||||
|
auto_create_table_structure!(sub_connection)
|
||||||
|
|
||||||
|
rpc_secret = SecureRandom.hex 16
|
||||||
|
logger.info "######### rpc_secret: #{rpc_secret}"
|
||||||
|
|
||||||
|
# 3. 创建drone server
|
||||||
|
drone_server_cmd = Ci::Drone::Server.new(current_user.login, oauth.client_id, oauth.client_secret, cloud_account.drone_host, rpc_secret).generate_cmd
|
||||||
|
logger.info "######### drone_server_cmd: #{drone_server_cmd}"
|
||||||
|
|
||||||
|
# 4. 创建drone client
|
||||||
|
drone_client_cmd = Ci::Drone::Client.new(oauth.client_id, cloud_account.drone_ip, rpc_secret).generate_cmd
|
||||||
|
logger.info "######### drone_client_cmd: #{drone_client_cmd}"
|
||||||
|
|
||||||
|
# 5. 登录远程服务器,启动drone服务
|
||||||
|
result = Ci::Drone::Start.new(cloud_account.account, cloud_account.visible_secret, cloud_account.drone_ip, drone_server_cmd, drone_client_cmd).run
|
||||||
|
logger.info "######### result: #{result}"
|
||||||
|
|
||||||
|
|
||||||
|
redirect_url = "#{cloud_account.drone_url}/login"
|
||||||
|
logger.info "######### redirect_url: #{redirect_url}"
|
||||||
|
|
||||||
|
return nil unless result.present?
|
||||||
|
result && !result.blank? ? cloud_account : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def unbind_account!
|
||||||
|
cloud_account = current_user.ci_cloud_account
|
||||||
|
return render_error('你未绑定CI服务器') if current_user.devops_step == User::DEVOPS_UNINIT || cloud_account.blank?
|
||||||
|
|
||||||
|
cloud_account.destroy! unless cloud_account.blank?
|
||||||
|
@connection.execute("DROP DATABASE IF EXISTS #{current_user.login}_drone") # TOTO drop drone database
|
||||||
|
|
||||||
|
current_user.unbind_account!
|
||||||
|
end
|
||||||
|
|
||||||
|
def bind_hook!(user, cloud_account, repo)
|
||||||
|
hook_params = {
|
||||||
|
active: true,
|
||||||
|
config: {
|
||||||
|
content_type: "json",
|
||||||
|
url: cloud_account.drone_url + "/hook?secret=#{repo.repo_signer}"
|
||||||
|
},
|
||||||
|
type: "gitea"
|
||||||
|
}
|
||||||
|
result = Gitea::Hooks::CreateService.call(user.gitea_token, user.login, repo.repo_name, hook_params)
|
||||||
|
|
||||||
|
result[:status].present? ? nil : result
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_bind_cloud_account!
|
||||||
|
return [true, "你已经绑定了云帐号."] unless current_user.ci_cloud_account.blank?
|
||||||
|
|
||||||
|
ip_num = IPAddr.new(devops_params[:ip_num]).to_i
|
||||||
|
Ci::CloudAccount.exists?(ip_num: ip_num) ? [true, "#{devops_params[:ip_num]}服务器已被使用."] : [false, nil]
|
||||||
|
end
|
||||||
|
|
||||||
|
def gitea_auto_create_auth_grant!(gitea_oauth_id)
|
||||||
|
connection = Gitea::Database.set_connection.connection
|
||||||
|
unix_time = Time.now.to_i
|
||||||
|
|
||||||
|
# 目前直接操作db,可以建立对应的model进行操作
|
||||||
|
sql = "INSERT INTO oauth2_grant ( user_id, application_id, counter, created_unix, updated_unix ) VALUES ( #{current_user.gitea_uid}, #{gitea_oauth_id}, 0, #{unix_time}, #{unix_time} );"
|
||||||
|
connection.execute(sql)
|
||||||
|
end
|
||||||
|
|
||||||
|
def gitea_oauth_grant!(password, oauth)
|
||||||
|
gitea_auto_create_auth_grant!(oauth&.gitea_oauth_id)
|
||||||
|
|
||||||
|
state = SecureRandom.hex(8)
|
||||||
|
|
||||||
|
# redirect_uri eg:
|
||||||
|
# https://localhost:3000/login/oauth/authorize?client_id=94976481-ad0e-4ed4-9247-7eef106007a2&redirect_uri=http%3A%2F%2F121.69.81.11%3A80%2Flogin&response_type=code&state=9cab990b9cfb1805
|
||||||
|
redirect_uri = CGI.escape("#{@cloud_account.drone_url}/login")
|
||||||
|
grant_url = "#{Gitea.gitea_config[:domain]}/login/oauth/authorize?client_id=#{oauth&.client_id}&redirect_uri=#{redirect_uri}&response_type=code&state=#{state}"
|
||||||
|
logger.info "[gitea] grant_url: #{grant_url}"
|
||||||
|
|
||||||
|
conn = Faraday.new(url: grant_url) do |req|
|
||||||
|
req.request :url_encoded
|
||||||
|
req.adapter Faraday.default_adapter
|
||||||
|
req.basic_auth(current_user.login, password)
|
||||||
|
end
|
||||||
|
|
||||||
|
response = conn.get
|
||||||
|
logger.info "[gitea] response headers: #{response.headers}"
|
||||||
|
|
||||||
|
drone_oauth_user!(response.headers.to_h['location'], state)
|
||||||
|
end
|
||||||
|
|
||||||
|
def drone_oauth_user!(url, state)
|
||||||
|
logger.info "[drone] drone_oauth_user url: #{url}"
|
||||||
|
conn = Faraday.new(url: url) do |req|
|
||||||
|
req.request :url_encoded
|
||||||
|
req.adapter Faraday.default_adapter
|
||||||
|
req.headers["cookie"] = "_session_=#{SecureRandom.hex(28)}; _oauth_state_=#{state}"
|
||||||
|
end
|
||||||
|
|
||||||
|
response = conn.get
|
||||||
|
logger.info "[drone] response headers: #{response.headers}"
|
||||||
|
|
||||||
|
response.headers['location'].include?('error') ? false : true
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def devops_params
|
||||||
|
params.permit(:account, :secret, :ip_num)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,40 @@
|
||||||
|
module Ci::DbConnectable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
end
|
||||||
|
|
||||||
|
# Dynamically sets the database connection.
|
||||||
|
def connect_to_ci_database(options={})
|
||||||
|
master_db = options[:master_db] || false
|
||||||
|
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||||
|
db_config = config[:ci_db_server].symbolize_keys!
|
||||||
|
raise 'ci database config missing' if db_config.blank?
|
||||||
|
|
||||||
|
req_params = {
|
||||||
|
host: db_config[:host],
|
||||||
|
username: db_config[:username],
|
||||||
|
password: db_config[:password],
|
||||||
|
port: db_config[:port]
|
||||||
|
}
|
||||||
|
req_params = req_params.merge(database: "#{current_user.login}_#{db_config[:database]}") unless master_db === true
|
||||||
|
|
||||||
|
db_params = Ci::Database.get_connection_params(req_params)
|
||||||
|
@connection = Ci::Database.set_connection(db_params).connection
|
||||||
|
end
|
||||||
|
|
||||||
|
def auto_create_database!(connection, database)
|
||||||
|
Rails.logger.info "[CI::DbConnectable] auto_create_database's connection: #{connection}"
|
||||||
|
connection.execute("CREATE DATABASE IF NOT EXISTS #{database}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def auto_create_table_structure!(connection)
|
||||||
|
Rails.logger.info "[CI::DbConnectable] auto_create_table_structure's connection: #{connection}"
|
||||||
|
|
||||||
|
sqls = Ci::Schema.statement.split(';').map(&:strip).reject { |e| e.to_s.empty? }
|
||||||
|
sqls.each do |sql|
|
||||||
|
con_result = connection.execute(sql)
|
||||||
|
Rails.logger.info "=============> ci create tabels result: #{con_result}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -17,7 +17,7 @@ module LoginHelper
|
||||||
:expires => 1.month.from_now,
|
:expires => 1.month.from_now,
|
||||||
:path => '/',
|
:path => '/',
|
||||||
:secure => false,
|
:secure => false,
|
||||||
:httponly => false
|
:httponly => true
|
||||||
}
|
}
|
||||||
if edu_setting('cookie_domain').present?
|
if edu_setting('cookie_domain').present?
|
||||||
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
|
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
|
||||||
|
@ -51,11 +51,16 @@ module LoginHelper
|
||||||
Rails.logger.info("####################__User.current_id______######{current_user.try(:id)}###___#{current_user&.logged?}")
|
Rails.logger.info("####################__User.current_id______######{current_user.try(:id)}###___#{current_user&.logged?}")
|
||||||
|
|
||||||
if User.current.logged?
|
if User.current.logged?
|
||||||
if autologin = cookies.delete(autologin_cookie_name)
|
user = User.current
|
||||||
|
autologin =
|
||||||
|
if edu_setting('cookie_domain').present?
|
||||||
|
cookies.delete(autologin_cookie_name, domain: edu_setting('cookie_domain'))
|
||||||
|
else
|
||||||
|
cookies.delete(autologin_cookie_name)
|
||||||
|
end
|
||||||
|
|
||||||
User.current.delete_autologin_token(autologin)
|
user.delete_autologin_token(autologin)
|
||||||
end
|
user.delete_session_token(session[:tk])
|
||||||
User.current.delete_session_token(session[:tk])
|
|
||||||
self.logged_user = nil
|
self.logged_user = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -68,7 +73,7 @@ module LoginHelper
|
||||||
|
|
||||||
# Sets the logged in user
|
# Sets the logged in user
|
||||||
def logged_user=(user)
|
def logged_user=(user)
|
||||||
# reset_session
|
reset_session
|
||||||
if user && user.is_a?(User)
|
if user && user.is_a?(User)
|
||||||
Rails.logger.info("########________logged_user___________###########{user.id}")
|
Rails.logger.info("########________logged_user___________###########{user.id}")
|
||||||
|
|
||||||
|
@ -111,4 +116,34 @@ module LoginHelper
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO 同步token到trustie平台,保持同步登录状态
|
||||||
|
def sync_user_token_to_trustie(login, token_value)
|
||||||
|
|
||||||
|
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||||
|
|
||||||
|
token = config[:sync_token]
|
||||||
|
api_host = config[:sync_url]
|
||||||
|
|
||||||
|
return if api_host.blank?
|
||||||
|
|
||||||
|
url = "#{api_host}/api/v1/users/sync_user_token"
|
||||||
|
sync_json = {
|
||||||
|
"token": token,
|
||||||
|
"login": login,
|
||||||
|
"user_token": token_value
|
||||||
|
}
|
||||||
|
uri = URI.parse(url)
|
||||||
|
|
||||||
|
if api_host
|
||||||
|
http = Net::HTTP.new(uri.hostname, uri.port)
|
||||||
|
|
||||||
|
if api_host.include?("https://")
|
||||||
|
http.use_ssl = true
|
||||||
|
end
|
||||||
|
|
||||||
|
http.send_request('POST', uri.path, sync_json.to_json, {'Content-Type' => 'application/json'})
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module RegisterHelper
|
module RegisterHelper
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
def autologin_register(username, email, password, platform= '')
|
def autologin_register(username, email, password, platform= 'forge')
|
||||||
result = {message: nil, user: nil}
|
result = {message: nil, user: nil}
|
||||||
email ||= "#{username@example.org}"
|
email ||= "#{username@example.org}"
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,18 @@ class HooksController < ApplicationController
|
||||||
before_action :check_user
|
before_action :check_user
|
||||||
before_action :set_repository
|
before_action :set_repository
|
||||||
|
|
||||||
def index
|
def index
|
||||||
hooks_response = Gitea::Hooks::ListService.new(@user, @repository.try(:identifier)).call
|
hooks_response = Gitea::Hooks::ListService.new(@user.gitea_token, @user.login, @repository.try(:identifier)).call
|
||||||
if hooks_response.status == 200
|
if hooks_response.status == 200
|
||||||
lists = JSON.parse(hooks_response.body)
|
lists = JSON.parse(hooks_response.body)
|
||||||
@hooks_size = lists.size
|
@hooks_size = lists.size
|
||||||
@hooks = paginate(lists)
|
@hooks = paginate(lists)
|
||||||
else
|
else
|
||||||
normal_status(-1, "出现错误")
|
normal_status(-1, "出现错误")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
#根据gitea的api
|
#根据gitea的api
|
||||||
# hook_params = {
|
# hook_params = {
|
||||||
# active: true,
|
# active: true,
|
||||||
|
@ -36,17 +36,17 @@ class HooksController < ApplicationController
|
||||||
# content_type: params[:content_type].to_i,
|
# content_type: params[:content_type].to_i,
|
||||||
# secret: params[:secret],
|
# secret: params[:secret],
|
||||||
# events: {
|
# events: {
|
||||||
# push_only: params[:push_only] || false, # 是否为推送事件
|
# push_only: params[:push_only] || false, # 是否为推送事件
|
||||||
# send_everything: params[:send_everything] || false, #是否为所有事件
|
# send_everything: params[:send_everything] || false, #是否为所有事件
|
||||||
# choose_events: params[:choose_events] || false, #是否为自定义事件
|
# choose_events: params[:choose_events] || false, #是否为自定义事件
|
||||||
# branch_filter: params[:branch_filter] || "*",
|
# branch_filter: params[:branch_filter] || "*",
|
||||||
# events: {
|
# events: {
|
||||||
# create: params[:create] || false, #创建分支/标签
|
# create: params[:create] || false, #创建分支/标签
|
||||||
# delete: params[:delete] || false, #删除分支/标签
|
# delete: params[:delete] || false, #删除分支/标签
|
||||||
# fork: params[:fork] || false, #仓库被派生
|
# fork: params[:fork] || false, #仓库被派生
|
||||||
# issues: params[:issues] || false, #工单
|
# issues: params[:issues] || false, #工单
|
||||||
# issue_comment: params[:issue_comment] || false, #评论
|
# issue_comment: params[:issue_comment] || false, #评论
|
||||||
# push: params[:push] || false # 推送
|
# push: params[:push] || false # 推送
|
||||||
# pull_request: params[:pull_request] || false #合并请求
|
# pull_request: params[:pull_request] || false #合并请求
|
||||||
# repository: params[:repository] || false #仓库
|
# repository: params[:repository] || false #仓库
|
||||||
# release: params[:release] || false #版本发布
|
# release: params[:release] || false #版本发布
|
||||||
|
@ -58,28 +58,28 @@ class HooksController < ApplicationController
|
||||||
Gitea::Hooks::CreateService.new(@user, @repository.try(:identifier), hook_params).call #创建gitea的hook功能
|
Gitea::Hooks::CreateService.new(@user, @repository.try(:identifier), hook_params).call #创建gitea的hook功能
|
||||||
Gitea::Hooks::CreateService.new(user, p.try(:identifier), hook_params).call #创建gitea的hook功能
|
Gitea::Hooks::CreateService.new(user, p.try(:identifier), hook_params).call #创建gitea的hook功能
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
hook_params = params[:hook_params]
|
hook_params = params[:hook_params]
|
||||||
response = Gitea::Hooks::UpdateService.new(@user, @repository.try(:identifier), hook_params, params[:id]).call
|
response = Gitea::Hooks::UpdateService.new(@user, @repository.try(:identifier), hook_params, params[:id]).call
|
||||||
if response.status == 200
|
if response.status == 200
|
||||||
normal_status(1, "更新成功")
|
normal_status(1, "更新成功")
|
||||||
else
|
else
|
||||||
normal_status(-1, "更新失败")
|
normal_status(-1, "更新失败")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
response = Gitea::Hooks::DestroyService.new(@user, @repository.try(:identifier), params[:id]).call
|
response = Gitea::Hooks::DestroyService.new(@user, @repository.try(:identifier), params[:id]).call
|
||||||
if response.status == 204
|
if response.status == 204
|
||||||
normal_status(1, "删除成功")
|
normal_status(1, "删除成功")
|
||||||
else
|
else
|
||||||
normal_status(-1, "删除失败")
|
normal_status(-1, "删除失败")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_repository
|
def set_repository
|
||||||
@repository = @project.repository
|
@repository = @project.repository
|
||||||
|
@ -88,9 +88,9 @@ class HooksController < ApplicationController
|
||||||
normal_status(-1, "用户不存在") unless @user.present?
|
normal_status(-1, "用户不存在") unless @user.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_user
|
def check_user
|
||||||
unless @project.user_id == current_user.id
|
unless @project.user_id == current_user.id
|
||||||
tip_exception(403, "您没有权限进入")
|
tip_exception(403, "您没有权限进入")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -105,9 +105,6 @@ class IssuesController < ApplicationController
|
||||||
normal_status(-1, "标题不能为空")
|
normal_status(-1, "标题不能为空")
|
||||||
elsif params[:subject].to_s.size > 255
|
elsif params[:subject].to_s.size > 255
|
||||||
normal_status(-1, "标题不能超过255个字符")
|
normal_status(-1, "标题不能超过255个字符")
|
||||||
elsif (params[:issue_type].to_s == "2")
|
|
||||||
return normal_status(-1, "悬赏的奖金必须大于0") if params[:token].to_i == 0
|
|
||||||
|
|
||||||
else
|
else
|
||||||
issue_params = issue_send_params(params)
|
issue_params = issue_send_params(params)
|
||||||
|
|
||||||
|
@ -137,17 +134,16 @@ class IssuesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
||||||
# normal_status(0, "创建成功",)
|
render json: {status: 0, message: "创建成", id: @issue.id}
|
||||||
render :json => { status: 0, message: "创建成功", id: @issue.id}
|
|
||||||
else
|
else
|
||||||
normal_status(-1, @issue.errors.messages.values[0][0])
|
normal_status(-1, @issue.errors.messages.values[0][0])
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
# @all_branches = get_branches
|
|
||||||
# @issue_chosen = issue_left_chosen(@project, @issue.id)
|
# @issue_chosen = issue_left_chosen(@project, @issue.id)
|
||||||
@issue_attachments = @issue.attachments
|
@issue_attachments = @issue.attachments
|
||||||
end
|
end
|
||||||
|
@ -204,7 +200,6 @@ class IssuesController < ApplicationController
|
||||||
else
|
else
|
||||||
normal_status(-1, @issue.errors.messages.values[0][0])
|
normal_status(-1, @issue.errors.messages.values[0][0])
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -306,6 +301,9 @@ class IssuesController < ApplicationController
|
||||||
if type == 5
|
if type == 5
|
||||||
@issue&.project_trends&.update_all(action_type: "close")
|
@issue&.project_trends&.update_all(action_type: "close")
|
||||||
@issue.issue_times.update_all(end_time: Time.now)
|
@issue.issue_times.update_all(end_time: Time.now)
|
||||||
|
if @issue.issue_type.to_s == "2"
|
||||||
|
post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login))
|
||||||
|
end
|
||||||
if @issue.issue_classify.to_s == "pull_request"
|
if @issue.issue_classify.to_s == "pull_request"
|
||||||
@issue&.pull_request&.update_attribute(:status, 2)
|
@issue&.pull_request&.update_attribute(:status, 2)
|
||||||
end
|
end
|
||||||
|
@ -399,17 +397,6 @@ class IssuesController < ApplicationController
|
||||||
tracker_array
|
tracker_array
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_branches
|
|
||||||
all_branches = []
|
|
||||||
get_all_branches = Gitea::Repository::Branches::ListService.new(@user, @project&.repository.try(:identifier)).call
|
|
||||||
if get_all_branches && get_all_branches.size > 0
|
|
||||||
get_all_branches.each do |b|
|
|
||||||
all_branches.push(b["name"])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
all_branches
|
|
||||||
end
|
|
||||||
|
|
||||||
def issue_send_params(params)
|
def issue_send_params(params)
|
||||||
{
|
{
|
||||||
subject: params[:subject],
|
subject: params[:subject],
|
||||||
|
|
|
@ -2,7 +2,7 @@ class MainController < ApplicationController
|
||||||
protect_from_forgery except: :index
|
protect_from_forgery except: :index
|
||||||
skip_before_action :check_sign
|
skip_before_action :check_sign
|
||||||
skip_before_action :user_setup
|
skip_before_action :user_setup
|
||||||
# skip_before_action :setup_laboratory
|
skip_before_action :setup_laboratory
|
||||||
|
|
||||||
def first_stamp
|
def first_stamp
|
||||||
render :json => { status: 0, message: Time.now.to_i }
|
render :json => { status: 0, message: Time.now.to_i }
|
||||||
|
|
|
@ -7,7 +7,7 @@ class Oauth::EducoderController < Oauth::BaseController
|
||||||
token = params[:token]
|
token = params[:token]
|
||||||
|
|
||||||
::OauthEducoderForm.new({login: login, token: token, callback_url: callback_url}).validate!
|
::OauthEducoderForm.new({login: login, token: token, callback_url: callback_url}).validate!
|
||||||
|
|
||||||
open_user= OpenUsers::Educoder.find_by(uid: login)
|
open_user= OpenUsers::Educoder.find_by(uid: login)
|
||||||
|
|
||||||
if open_user.present? && open_user.user.present? && open_user.user.email_binded?
|
if open_user.present? && open_user.user.present? && open_user.user.email_binded?
|
||||||
|
@ -17,15 +17,15 @@ class Oauth::EducoderController < Oauth::BaseController
|
||||||
redirect_to callback_url
|
redirect_to callback_url
|
||||||
else
|
else
|
||||||
Rails.logger.info "######## open user not exits"
|
Rails.logger.info "######## open user not exits"
|
||||||
user = User.find_by('login = ? or mail = ?', login, mail)
|
user = User.find_by(login: login) || User.find_by(mail: mail)
|
||||||
|
|
||||||
if user.is_a?(User)
|
if user.is_a?(User) && !user.is_a?(AnonymousUser)
|
||||||
OpenUsers::Educoder.create!(user: user, uid: login)
|
OpenUsers::Educoder.create!(user: user, uid: login)
|
||||||
successful_authentication(user)
|
successful_authentication(user)
|
||||||
|
|
||||||
redirect_to callback_url
|
redirect_to callback_url
|
||||||
else
|
else
|
||||||
redirect_to oauth_register_path(login: login, callback_url: callback_url)
|
redirect_to oauth_register_path(login: login, mail: mail, callback_url: callback_url)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue WechatOauth::Error => ex
|
rescue WechatOauth::Error => ex
|
||||||
|
|
|
@ -40,8 +40,5 @@ class PraiseTreadController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def render_result
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,16 +6,6 @@ class ProjectCategoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def group_list
|
def group_list
|
||||||
# if current_user&.logged?
|
@project_categories = ProjectCategory.where('projects_count > 0').order(projects_count: :desc)
|
||||||
# projects = Project.list_user_projects(current_user.id)
|
|
||||||
# else
|
|
||||||
# projects = Project.visible
|
|
||||||
# end
|
|
||||||
@project_children_categories = ProjectCategory.descendants
|
|
||||||
projects = Project.no_anomory_projects.visible
|
|
||||||
categories = projects.joins(:project_category).where(project_categories: {ancestry: nil}).group("project_categories.name", "project_categories.id").size.keys.to_h
|
|
||||||
extra_category_id = categories.delete("其他")
|
|
||||||
categories = categories.merge({"其他": extra_category_id}) if extra_category_id.present? #其他的放在最后面
|
|
||||||
@category_group_list = categories
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,16 +2,26 @@ class ProjectsController < ApplicationController
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
include OperateProjectAbilityAble
|
include OperateProjectAbilityAble
|
||||||
include ProjectsHelper
|
include ProjectsHelper
|
||||||
before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users]
|
before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about]
|
||||||
before_action :load_project, except: %i[index group_type_list migrate create]
|
before_action :load_project, except: %i[index group_type_list migrate create recommend]
|
||||||
before_action :authorizate_user_can_edit_project!, only: %i[update]
|
before_action :authorizate_user_can_edit_project!, only: %i[update]
|
||||||
before_action :project_public?, only: %i[fork_users praise_users watch_users]
|
before_action :project_public?, only: %i[fork_users praise_users watch_users]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
scope = Projects::ListQuery.call(params)
|
scope = Projects::ListQuery.call(params)
|
||||||
|
|
||||||
@projects = kaminari_paginate(scope)
|
# @projects = kaminari_paginate(scope)
|
||||||
@total_count = @projects.total_count
|
@projects = paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, owner: :user_extension)
|
||||||
|
|
||||||
|
category_id = params[:category_id]
|
||||||
|
@total_count =
|
||||||
|
if category_id.blank?
|
||||||
|
ps = ProjectStatistic.first
|
||||||
|
ps.common_projects_count + ps.mirror_projects_count unless ps.blank?
|
||||||
|
else
|
||||||
|
cate = ProjectCategory.find_by(id: category_id)
|
||||||
|
cate&.projects_count || 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -34,7 +44,7 @@ class ProjectsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def branches
|
def branches
|
||||||
@branches = Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call
|
@branches = @project.forge? ? Gitea::Repository::Branches::ListService.new(@owner, @project.identifier).call : []
|
||||||
end
|
end
|
||||||
|
|
||||||
def group_type_list
|
def group_type_list
|
||||||
|
@ -52,9 +62,13 @@ class ProjectsController < ApplicationController
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
# Projects::CreateForm.new(project_params).validate!
|
# Projects::CreateForm.new(project_params).validate!
|
||||||
private = params[:private]
|
private = params[:private]
|
||||||
|
gitea_params = {
|
||||||
|
private: private,
|
||||||
|
default_branch: params[:default_branch]
|
||||||
|
}
|
||||||
if [true, false].include? private
|
if [true, false].include? private
|
||||||
new_project_params = project_params.merge(is_public: !private)
|
new_project_params = project_params.merge(is_public: !private)
|
||||||
Gitea::Repository::UpdateService.new(@project.owner, @project.repository.identifier, {private: private}).call
|
Gitea::Repository::UpdateService.call(@owner, @project.identifier, gitea_params)
|
||||||
@project.repository.update_column(:hidden, private)
|
@project.repository.update_column(:hidden, private)
|
||||||
end
|
end
|
||||||
@project.update_attributes!(new_project_params)
|
@project.update_attributes!(new_project_params)
|
||||||
|
@ -95,13 +109,44 @@ class ProjectsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def fork_users
|
def fork_users
|
||||||
fork_users = @project.fork_users.includes(:user, :project).order("fork_users.created_at desc").distinct
|
fork_users = @project.fork_users.includes(:user, :project, :fork_project).order("fork_users.created_at desc").distinct
|
||||||
@forks_count = fork_users.size
|
@forks_count = fork_users.size
|
||||||
@fork_users = paginate(fork_users)
|
@fork_users = paginate(fork_users)
|
||||||
end
|
end
|
||||||
|
|
||||||
def simple
|
def simple
|
||||||
json_response(@project)
|
json_response(@project, current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def recommend
|
||||||
|
@projects = Project.recommend.includes(:repository, :project_category, owner: :user_extension).limit(5)
|
||||||
|
end
|
||||||
|
|
||||||
|
def about
|
||||||
|
@project_detail = @project.project_detail
|
||||||
|
@attachments = Array(@project_detail&.attachments) if request.get?
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
if request.post?
|
||||||
|
require_login
|
||||||
|
authorizate_user_can_edit_project!
|
||||||
|
unless @project_detail.present?
|
||||||
|
@project_detail = ProjectDetail.new(
|
||||||
|
content: params[:content],
|
||||||
|
project_id: @project.id)
|
||||||
|
else
|
||||||
|
@project_detail.content = params[:content]
|
||||||
|
end
|
||||||
|
if @project_detail.save!
|
||||||
|
attachment_ids = Array(params[:attachment_ids])
|
||||||
|
@attachments = Attachment.where(id: attachment_ids)
|
||||||
|
@attachments.update_all(
|
||||||
|
container_id: @project_detail.id,
|
||||||
|
container_type: @project_detail.model_name.name,
|
||||||
|
author_id: current_user.id,
|
||||||
|
description: "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
class ProtectedBranchesController < ApplicationController
|
||||||
|
include OperateProjectAbilityAble
|
||||||
|
|
||||||
|
before_action :require_login
|
||||||
|
before_action :load_repository
|
||||||
|
before_action :authorizate_user_can_edit_project!
|
||||||
|
|
||||||
|
def index
|
||||||
|
scope = @repository.protected_branches
|
||||||
|
@total_count = scope.size
|
||||||
|
@protected_branches = paginate(scope)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@protected_branch = ProtectedBranches::CreateService.call(@repository, @owner, params)
|
||||||
|
|
||||||
|
render_protected_branch_json
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@protected_branch = ProtectedBranches::UpdateService.call(@repository, @owner, params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
ProtectedBranches::DestroyService.call(@repository, @owner, params[:branch_name])
|
||||||
|
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@protected_branch = ProtectedBranches::GetService.call(@repository, @owner, params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@branch, @protected_branch = ProtectedBranches::EditService.call(@repository, @owner, params[:branch_name])
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def render_protected_branch_json
|
||||||
|
@protected_branch.persisted? ? @protected_branch : render_error('创建失败!')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -1,9 +1,8 @@
|
||||||
class PullRequestsController < ApplicationController
|
class PullRequestsController < ApplicationController
|
||||||
before_action :require_login, except: [:index, :show]
|
before_action :require_login, except: [:index, :show, :files, :commits]
|
||||||
before_action :load_repository
|
before_action :load_repository
|
||||||
before_action :set_user, only: [:new, :get_branches]
|
before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits]
|
||||||
before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos]
|
before_action :load_pull_request, only: [:files, :commits]
|
||||||
# before_action :get_relatived, only: [:edit]
|
|
||||||
include TagChosenHelper
|
include TagChosenHelper
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
|
@ -24,11 +23,11 @@ class PullRequestsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@all_branches = PullRequests::BranchesService.new(@user, @project).call
|
@all_branches = Branches::ListService.call(@owner, @project)
|
||||||
@is_fork = @project.forked_from_project_id.present?
|
@is_fork = @project.forked_from_project_id.present?
|
||||||
@projects_names = [{
|
@projects_names = [{
|
||||||
project_user_login: @user.try(:login),
|
project_user_login: @owner.try(:login),
|
||||||
project_name: "#{@user.try(:show_real_name)}/#{@repository.try(:identifier)}",
|
project_name: "#{@owner.try(:show_real_name)}/#{@repository.try(:identifier)}",
|
||||||
project_id: @project.identifier,
|
project_id: @project.identifier,
|
||||||
id: @project.id
|
id: @project.id
|
||||||
}]
|
}]
|
||||||
|
@ -45,66 +44,20 @@ class PullRequestsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_branches
|
def get_branches
|
||||||
branch_result = PullRequests::BranchesService.new(@user, @project).call
|
branch_result = Branches::ListService.call(@owner, @project)
|
||||||
render json: branch_result
|
render json: branch_result
|
||||||
# return json: branch_result
|
# return json: branch_result
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
if params[:title].nil?
|
ActiveRecord::Base.transaction do
|
||||||
normal_status(-1, "名称不能为空")
|
@pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params)
|
||||||
elsif params[:issue_tag_ids].nil?
|
if @gitea_pull_request[:status] == :success
|
||||||
normal_status(-1, "标签不能为空")
|
@pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"])
|
||||||
else
|
render_ok
|
||||||
ActiveRecord::Base.transaction do
|
else
|
||||||
begin
|
render_error("create pull request error: #{@gitea_pull_request[:status]}")
|
||||||
merge_params
|
raise ActiveRecord::Rollback
|
||||||
pull_issue = Issue.new(@issue_params)
|
|
||||||
if pull_issue.save!
|
|
||||||
pr_params = {
|
|
||||||
user_id: current_user.try(:id),
|
|
||||||
project_id: @project.id,
|
|
||||||
issue_id: pull_issue.id,
|
|
||||||
fork_project_id: params[:fork_project_id],
|
|
||||||
is_original: params[:is_original]
|
|
||||||
}
|
|
||||||
local_requests = PullRequest.new(@local_params.merge(pr_params))
|
|
||||||
if local_requests.save
|
|
||||||
remote_pr_params = @local_params
|
|
||||||
remote_pr_params = remote_pr_params.merge(head: "#{params[:merge_user_login]}:#{params[:head]}").compact if local_requests.is_original && params[:merge_user_login]
|
|
||||||
gitea_request = Gitea::PullRequest::CreateService.call(current_user.try(:gitea_token), @project.owner, @repository.try(:identifier), remote_pr_params.except(:milestone))
|
|
||||||
if gitea_request && local_requests.update_attributes(gpid: gitea_request["number"])
|
|
||||||
if params[:issue_tag_ids].present?
|
|
||||||
params[:issue_tag_ids].each do |tag|
|
|
||||||
IssueTagsRelate.create!(issue_id: pull_issue.id, issue_tag_id: tag)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if params[:assigned_to_id].present?
|
|
||||||
Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id,
|
|
||||||
container_id: local_requests.id, container_type: 'PullRequest',
|
|
||||||
parent_container_id: @project.id, parent_container_type: "Project",
|
|
||||||
tiding_type: 'pull_request', status: 0)
|
|
||||||
end
|
|
||||||
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
|
||||||
if params[:title].to_s.include?("WIP:")
|
|
||||||
pull_issue.custom_journal_detail("WIP", "", "这个合并请求被标记为尚未完成的工作。完成后请从标题中移除WIP:前缀。", current_user&.id)
|
|
||||||
end
|
|
||||||
# render :json => { status: 0, message: "PullRequest创建成功", id: pull_issue.id}
|
|
||||||
normal_status(0, "PullRequest创建成功")
|
|
||||||
else
|
|
||||||
normal_status(-1, "PullRequest创建失败")
|
|
||||||
end
|
|
||||||
else
|
|
||||||
normal_status(-1, local_requests.errors.messages.values[0][0])
|
|
||||||
end
|
|
||||||
else
|
|
||||||
normal_status(-1, pull_issue.errors.messages.values[0][0])
|
|
||||||
end
|
|
||||||
rescue => e
|
|
||||||
normal_status(-1, e.message)
|
|
||||||
raise ActiveRecord::Rollback
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -226,11 +179,11 @@ class PullRequestsController < ApplicationController
|
||||||
elsif target_head === target_base && !is_original
|
elsif target_head === target_base && !is_original
|
||||||
normal_status(-2, "分支内容相同,无需创建合并请求")
|
normal_status(-2, "分支内容相同,无需创建合并请求")
|
||||||
else
|
else
|
||||||
can_merge = @project&.pull_requests.where(user_id: current_user&.id, head: target_head, base: target_base, status: 0, is_original: is_original, fork_project_id: params[:fork_project_id])
|
can_merge = @project&.pull_requests.where(head: target_head, base: target_base, status: 0, is_original: is_original, fork_project_id: params[:fork_project_id])
|
||||||
if can_merge.present?
|
if can_merge.present?
|
||||||
render json: {
|
render json: {
|
||||||
status: -2,
|
status: -2,
|
||||||
message: "在这些分支之间的合并请求已存在:<a href='/projects/#{@project.id}/merge/#{can_merge.first.id}/Messagecount''>#{can_merge.first.try(:title)}</a>",
|
message: "在这些分支之间的合并请求已存在:<a href='/projects/#{@owner.login}/#{@project.identifier}/pulls/#{can_merge.first.id}/Messagecount''>#{can_merge.first.try(:title)}</a>",
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
normal_status(0, "可以合并")
|
normal_status(0, "可以合并")
|
||||||
|
@ -239,9 +192,19 @@ class PullRequestsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def files
|
||||||
|
@files_result = Gitea::PullRequest::FilesService.call(@owner.login, @project.identifier, @pull_request.gpid)
|
||||||
|
# render json: @files_result
|
||||||
|
end
|
||||||
|
|
||||||
|
def commits
|
||||||
|
@commits_result = Gitea::PullRequest::CommitsService.call(@owner.login, @project.identifier, @pull_request.gpid)
|
||||||
|
# render json: @commits_result
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def set_user
|
def load_pull_request
|
||||||
@user = @project.owner
|
@pull_request = PullRequest.find params[:id]
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_pull_request
|
def find_pull_request
|
||||||
|
|
|
@ -13,7 +13,7 @@ class RepositoriesController < ApplicationController
|
||||||
def show
|
def show
|
||||||
@user = current_user
|
@user = current_user
|
||||||
@repo = @project.repository
|
@repo = @project.repository
|
||||||
@result = Gitea::Repository::GetService.new(@project.owner, @project.identifier).call
|
@result = @project.forge? ? Gitea::Repository::GetService.new(@owner, @project.identifier).call : nil
|
||||||
@project_fork_id = @project.try(:forked_from_project_id)
|
@project_fork_id = @project.try(:forked_from_project_id)
|
||||||
if @project_fork_id.present?
|
if @project_fork_id.present?
|
||||||
@fork_project = Project.find_by(id: @project_fork_id)
|
@fork_project = Project.find_by(id: @project_fork_id)
|
||||||
|
@ -26,60 +26,85 @@ class RepositoriesController < ApplicationController
|
||||||
|
|
||||||
def entries
|
def entries
|
||||||
@project.increment!(:visits)
|
@project.increment!(:visits)
|
||||||
@project_owner = @project.owner
|
|
||||||
@entries = Gitea::Repository::Entries::ListService.new(@project_owner, @project.identifier, ref: @ref).call
|
if @project.educoder?
|
||||||
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
|
@entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name)
|
||||||
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
else
|
||||||
|
@entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call
|
||||||
|
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
|
||||||
|
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def top_counts
|
def top_counts
|
||||||
@result = Gitea::Repository::GetService.new(@project.owner, @project.identifier).call
|
@result = @project.educoder? ? nil : Gitea::Repository::GetService.new(@project.owner, @project.identifier).call
|
||||||
end
|
end
|
||||||
|
|
||||||
def sub_entries
|
def sub_entries
|
||||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||||
interactor = Repositories::EntriesInteractor.call(@project.owner, @project.identifier, file_path_uri, ref: @ref)
|
|
||||||
if interactor.success?
|
if @project.educoder?
|
||||||
@sub_entries = interactor.result
|
if params[:type] === 'file'
|
||||||
@sub_entries = [] << @sub_entries unless @sub_entries.is_a? Array
|
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
|
||||||
@sub_entries = @sub_entries.sort_by{ |hash| hash['type'] }
|
logger.info "######### sub_entries: #{@sub_entries}"
|
||||||
|
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
|
||||||
|
|
||||||
|
tmp_entries = [{
|
||||||
|
"content" => @sub_entries['data']['content'],
|
||||||
|
"type" => "blob"
|
||||||
|
}]
|
||||||
|
@sub_entries = {
|
||||||
|
"trees"=>tmp_entries,
|
||||||
|
"commits" => [{}]
|
||||||
|
}
|
||||||
|
else
|
||||||
|
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
|
||||||
|
end
|
||||||
else
|
else
|
||||||
render_error(interactor.error)
|
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref)
|
||||||
|
if interactor.success?
|
||||||
|
result = interactor.result
|
||||||
|
@sub_entries = result.is_a?(Array) ? result.sort_by{ |hash| hash['type'] } : result
|
||||||
|
else
|
||||||
|
render_error(interactor.error)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def commits
|
def commits
|
||||||
@project_owner = @project.owner
|
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
|
||||||
@hash_commit = Gitea::Repository::Commits::ListService.new(@project_owner.login, @project.identifier,
|
|
||||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
||||||
end
|
end
|
||||||
|
|
||||||
def commit
|
def commit
|
||||||
@commit = Gitea::Repository::Commits::GetService.new(@repository.user.login, @repository.identifier, params[:sha], current_user.gitea_token).call
|
@sha = params[:sha]
|
||||||
|
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
|
||||||
|
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
|
||||||
end
|
end
|
||||||
|
|
||||||
def tags
|
def tags
|
||||||
@tags = Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier, {page: params[:page], limit: params[:limit]}).call
|
@tags = Gitea::Repository::Tags::ListService.call(current_user&.gitea_token, @owner.login, @project.identifier, {page: params[:page], limit: params[:limit]})
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_file
|
def create_file
|
||||||
interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @project.owner.login, content_params)
|
interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params)
|
||||||
if interactor.success?
|
if interactor.success?
|
||||||
@file = interactor.result
|
@file = interactor.result
|
||||||
create_new_pr(params)
|
# create_new_pr(params)
|
||||||
else
|
else
|
||||||
render_error(interactor.error)
|
render_error(interactor.error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_file
|
def update_file
|
||||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @project.owner.login, params.merge(identifier: @project.identifier))
|
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||||
if interactor.success?
|
if interactor.success?
|
||||||
@file = interactor.result
|
@file = interactor.result
|
||||||
create_new_pr(params)
|
# TODO: 是否创建pr
|
||||||
|
# create_new_pr(params)
|
||||||
render_result(1, "更新成功")
|
render_result(1, "更新成功")
|
||||||
else
|
else
|
||||||
render_error(interactor.error)
|
render_error(interactor.error)
|
||||||
|
@ -87,7 +112,7 @@ class RepositoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_file
|
def delete_file
|
||||||
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @project.owner.login, params.merge(identifier: @project.identifier))
|
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||||
if interactor.success?
|
if interactor.success?
|
||||||
@file = interactor.result
|
@file = interactor.result
|
||||||
render_result(1, "文件删除成功")
|
render_result(1, "文件删除成功")
|
||||||
|
@ -133,8 +158,8 @@ class RepositoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_statistics
|
def get_statistics
|
||||||
@branches_count = Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size
|
@branches_count = @project.educoder? ? 0 : Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size
|
||||||
@tags_count = Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier).call&.size
|
@tags_count = @project.educoder? ? 0 : Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier).call&.size
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_ref
|
def get_ref
|
||||||
|
@ -142,9 +167,9 @@ class RepositoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_latest_commit
|
def get_latest_commit
|
||||||
latest_commit = project_commits
|
latest_commit = @project.educoder? ? nil : project_commits
|
||||||
@latest_commit = latest_commit[:body][0] if latest_commit.present?
|
@latest_commit = latest_commit.present? ? latest_commit[:body][0] : nil
|
||||||
@commits_count = latest_commit[:total_count] if latest_commit.present?
|
@commits_count = latest_commit.present? ? latest_commit[:total_count] : 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def content_params
|
def content_params
|
||||||
|
@ -154,6 +179,10 @@ class RepositoriesController < ApplicationController
|
||||||
new_branch: params[:new_branch],
|
new_branch: params[:new_branch],
|
||||||
content: params[:content],
|
content: params[:content],
|
||||||
message: params[:message],
|
message: params[:message],
|
||||||
|
committer: {
|
||||||
|
email: current_user.mail,
|
||||||
|
name: current_user.login
|
||||||
|
},
|
||||||
identifier: @project.identifier
|
identifier: @project.identifier
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -208,14 +237,14 @@ class RepositoriesController < ApplicationController
|
||||||
issue_type: "1",
|
issue_type: "1",
|
||||||
tracker_id: 2,
|
tracker_id: 2,
|
||||||
status_id: 1,
|
status_id: 1,
|
||||||
priority_id: 1
|
priority_id: params[:priority_id] || "2"
|
||||||
}
|
}
|
||||||
@pull_issue = Issue.new(issue_params)
|
@pull_issue = Issue.new(issue_params)
|
||||||
if @pull_issue.save!
|
if @pull_issue.save!
|
||||||
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
|
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
|
||||||
if local_requests.save
|
if local_requests.save
|
||||||
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @project.owner, @project.try(:identifier), requests_params).call
|
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
|
||||||
if gitea_request && local_requests.update_attributes(gpid: gitea_request["number"])
|
if gitea_request[:status] == :success && local_requests.update_attributes(gpid: gitea_request["body"]["number"])
|
||||||
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
|
include Ci::DbConnectable
|
||||||
|
|
||||||
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users]
|
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users]
|
||||||
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users]
|
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users]
|
||||||
before_action :require_login, only: %i[me list]
|
before_action :require_login, only: %i[me list]
|
||||||
|
before_action :connect_to_ci_database, only: :get_user_info, if: -> { current_user && !current_user.is_a?(AnonymousUser) && current_user.devops_certification? }
|
||||||
|
|
||||||
skip_before_action :check_sign, only: [:attachment_show]
|
skip_before_action :check_sign, only: [:attachment_show]
|
||||||
|
|
||||||
def list
|
def list
|
||||||
|
|
|
@ -139,7 +139,7 @@ class VersionReleasesController < ApplicationController
|
||||||
body: params[:body],
|
body: params[:body],
|
||||||
draft: params[:draft] || false,
|
draft: params[:draft] || false,
|
||||||
name: params[:name],
|
name: params[:name],
|
||||||
prerelease: params[:prerelease],
|
prerelease: params[:prerelease] || false,
|
||||||
tag_name: params[:tag_name],
|
tag_name: params[:tag_name],
|
||||||
target_commitish: params[:target_commitish] || "master" #分支
|
target_commitish: params[:target_commitish] || "master" #分支
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
class Ci::CreateCloudAccountForm
|
||||||
|
include ActiveModel::Model
|
||||||
|
|
||||||
|
attr_accessor :ip_num, :account, :secret
|
||||||
|
|
||||||
|
# validates :project_id, :account, :secret, presence: true
|
||||||
|
validates :account, :secret, presence: true
|
||||||
|
validates :ip_num, presence: true, format: { with: CustomRegexp::IP, multiline: true, message: 'IP 地址格式不对' }
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
class ProtectedBranches::CreateForm < BaseForm
|
||||||
|
attr_accessor :repository, :branch_name, :can_push, :enable_whitelist, :whitelist_user_i_ds,
|
||||||
|
:whitelist_team_i_ds, :enable_merge_whitelist, :whitelist_deploy_keys, :merge_whitelist_user_i_ds,
|
||||||
|
:merge_whitelist_team_i_ds, :enable_status_check, :status_check_contexts, :approvals_whitelist_user_i_ds,
|
||||||
|
:approvals_whitelist_team_i_ds, :required_approvals, :enable_approvals_whitelist, :block_on_rejected_reviews,
|
||||||
|
:dismiss_stale_approvals, :require_signed_commits, :protected_file_patterns, :block_on_outdated_branch
|
||||||
|
|
||||||
|
validates :repo_id, :branch_name, presence: true
|
||||||
|
|
||||||
|
validate do
|
||||||
|
check_branch_name!
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def check_branch_name!
|
||||||
|
protected_branch_exists = repository.protected_branches.exists?(branch_name)
|
||||||
|
raise "Protected branch '#{branch_name}' already exists" if protected_branch_exists
|
||||||
|
end
|
||||||
|
end
|
|
@ -436,4 +436,9 @@ module ApplicationHelper
|
||||||
def find_user_by_login(login)
|
def find_user_by_login(login)
|
||||||
User.find_by_login login
|
User.find_by_login login
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_base64_decoded(str)
|
||||||
|
return nil if str.blank?
|
||||||
|
Base64.decode64 str
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
module Ci::BuildsHelper
|
||||||
|
def format_utc_time(unix_time)
|
||||||
|
return nil if unix_time == 0
|
||||||
|
Time.at(unix_time).strftime("%Y-%m-%d %H:%M")
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_duartion_time(end_time, start_time)
|
||||||
|
return nil if end_time == 0 || start_time == 0
|
||||||
|
game_spend_time(end_time - start_time)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,2 @@
|
||||||
|
module Ci::LanguagesHelper
|
||||||
|
end
|
|
@ -0,0 +1,2 @@
|
||||||
|
module CompareHelper
|
||||||
|
end
|
|
@ -0,0 +1,2 @@
|
||||||
|
module DevOpsHelper
|
||||||
|
end
|
|
@ -1,2 +1,18 @@
|
||||||
module MembersHelper
|
module MembersHelper
|
||||||
|
def get_user_token(user_login,reponame)
|
||||||
|
query_params = {
|
||||||
|
type: "query",
|
||||||
|
chain_params: {
|
||||||
|
reponame: reponame,
|
||||||
|
username: user_login
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response = Gitea::Chain::ChainGetService.new(query_params).call
|
||||||
|
|
||||||
|
if response.status == 200
|
||||||
|
return JSON.parse(response.body)["balance"].to_i
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,8 +28,10 @@ module ProjectsHelper
|
||||||
(User.find_by_login identifier) || (User.find_by_mail identifier)
|
(User.find_by_login identifier) || (User.find_by_mail identifier)
|
||||||
end
|
end
|
||||||
|
|
||||||
def json_response(project)
|
def json_response(project, user)
|
||||||
repo = project.repository
|
# repo = project.repository
|
||||||
|
repo = Repository.includes(:mirror).select(:id, :mirror_url).find_by(project: project)
|
||||||
|
|
||||||
tmp_json = {}
|
tmp_json = {}
|
||||||
unless project.common?
|
unless project.common?
|
||||||
tmp_json = tmp_json.merge({
|
tmp_json = tmp_json.merge({
|
||||||
|
@ -41,16 +43,48 @@ module ProjectsHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
tmp_json = tmp_json.merge({
|
tmp_json = tmp_json.merge({
|
||||||
identifier: project.identifier,
|
identifier: render_identifier(project),
|
||||||
name: project.name,
|
name: project.name,
|
||||||
|
platform: project.platform,
|
||||||
id: project.id,
|
id: project.id,
|
||||||
|
repo_id: repo.id,
|
||||||
|
open_devops: (user.blank? || user.is_a?(AnonymousUser)) ? false : project.open_devops?,
|
||||||
type: project.numerical_for_project_type,
|
type: project.numerical_for_project_type,
|
||||||
author: {
|
author: render_owner(project)
|
||||||
login: project.owner.login,
|
|
||||||
name: project.owner.real_name,
|
|
||||||
image_url: url_to_avatar(project.owner)
|
|
||||||
}
|
|
||||||
}).compact
|
}).compact
|
||||||
|
|
||||||
render json: tmp_json
|
render json: tmp_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_owner(project)
|
||||||
|
if project.educoder?
|
||||||
|
{
|
||||||
|
login: project.project_educoder.owner,
|
||||||
|
name: project.project_educoder.owner,
|
||||||
|
image_url: project.project_educoder.image_url
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
login: @owner.login,
|
||||||
|
name: @owner.real_name,
|
||||||
|
image_url: url_to_avatar(@owner)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_identifier(project)
|
||||||
|
project.educoder? ? project.project_educoder&.repo_name&.split('/')[1] : project.identifier
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_author(project)
|
||||||
|
project.educoder? ? project.project_educoder&.repo_name&.split('/')[0] : project.owner.login
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_educoder_avatar_url(project_educoder)
|
||||||
|
[Rails.application.config_for(:configuration)['educoder']['cdn_url'], project_educoder&.image_url].join('/')
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_avatar_url(owner)
|
||||||
|
['images', url_to_avatar(owner)].join('/')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
module ProtectedBranchesHelper
|
||||||
|
end
|
|
@ -1,11 +1,17 @@
|
||||||
module RepositoriesHelper
|
module RepositoriesHelper
|
||||||
|
def render_permission(user, project)
|
||||||
|
return "Admin" if user&.admin?
|
||||||
|
return "Owner" if user === project.owner
|
||||||
|
project.get_premission(user)
|
||||||
|
end
|
||||||
|
|
||||||
def render_decode64_content(str)
|
def render_decode64_content(str)
|
||||||
return nil if str.blank?
|
return nil if str.blank?
|
||||||
Base64.decode64(str).force_encoding('UTF-8')
|
Base64.decode64(str).force_encoding("UTF-8")
|
||||||
end
|
end
|
||||||
|
|
||||||
def download_type(str)
|
def download_type(str)
|
||||||
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb png jpg gif tif psd svg RData rdata)
|
default_type = %w(xlsx xls ppt pptx pdf zip 7z rar exe pdb obj idb png jpg gif tif psd svg RData rdata doc docx mpp vsdx)
|
||||||
default_type.include?(str&.downcase)
|
default_type.include?(str&.downcase)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -44,7 +50,7 @@ module RepositoriesHelper
|
||||||
end
|
end
|
||||||
if r_content.include?("?")
|
if r_content.include?("?")
|
||||||
new_r_content = r_content + "&raw=true"
|
new_r_content = r_content + "&raw=true"
|
||||||
else
|
else
|
||||||
new_r_content = r_content + "?raw=true"
|
new_r_content = r_content + "?raw=true"
|
||||||
end
|
end
|
||||||
unless r_content.include?("http://") || r_content.include?("https://") || r_content.include?("mailto:")
|
unless r_content.include?("http://") || r_content.include?("https://") || r_content.include?("mailto:")
|
||||||
|
@ -56,4 +62,14 @@ module RepositoriesHelper
|
||||||
|
|
||||||
return content
|
return content
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# unix_time values for example: 1604382982
|
||||||
|
def render_format_time_with_unix(unix_time)
|
||||||
|
Time.at(unix_time).strftime("%Y-%m-%d %H:%M")
|
||||||
|
end
|
||||||
|
|
||||||
|
# date for example: 2020-11-01T19:57:27+08:00
|
||||||
|
def render_format_time_with_date(date)
|
||||||
|
date.to_time.strftime("%Y-%m-%d %H:%M")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,143 @@
|
||||||
module TagChosenHelper
|
module TagChosenHelper
|
||||||
|
def get_associated_data(project)
|
||||||
|
issue_comment_users_array = []
|
||||||
|
cost_time_array = []
|
||||||
|
all_issues = []
|
||||||
|
{
|
||||||
|
"assign_user": render_cache_collaborators(project),
|
||||||
|
"tracker": render_cache_trackers,
|
||||||
|
"issue_status": render_cache_issue_statuses,
|
||||||
|
"priority": render_cache_issue_priorities,
|
||||||
|
"issue_version": render_cache_milestones(project),
|
||||||
|
"start_date": "",
|
||||||
|
"due_date": "",
|
||||||
|
"joins_users": issue_comment_users_array,
|
||||||
|
"cost_time_users": cost_time_array,
|
||||||
|
# "total_cost_time": Time.at(all_cost_time).utc.strftime('%H h %M min %S s'),
|
||||||
|
# "be_depended_issues": be_depended_issues_array,
|
||||||
|
# "depended_issues":depended_issues_array,
|
||||||
|
# "estimated_hours": issue_info[7],
|
||||||
|
"done_ratio": render_complete_percentage,
|
||||||
|
"issue_tag": render_issue_tags(project),
|
||||||
|
"issue_type": render_issue_species,
|
||||||
|
"all_issues": all_issues
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_cache_trackers
|
||||||
|
cache_key = "all_trackers/#{Tracker.maximum('id')}"
|
||||||
|
|
||||||
|
Rails.cache.fetch(cache_key) do
|
||||||
|
Tracker.select(:id, :name, :position).collect do |event|
|
||||||
|
{
|
||||||
|
id: event.id,
|
||||||
|
name: event.name,
|
||||||
|
position: event.position,
|
||||||
|
is_chosen: '0'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_cache_issue_statuses
|
||||||
|
cache_key = "all_issue_statuses/#{IssueStatus.maximum('id')}"
|
||||||
|
|
||||||
|
Rails.cache.fetch(cache_key) do
|
||||||
|
IssueStatus.select(:id, :name, :position).collect do |event|
|
||||||
|
{
|
||||||
|
id: event.id,
|
||||||
|
name: event.name,
|
||||||
|
position: event.position,
|
||||||
|
is_chosen: '0'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_cache_issue_priorities
|
||||||
|
cache_key = "all_issue_priorities/#{IssuePriority.maximum('id')}"
|
||||||
|
|
||||||
|
Rails.cache.fetch(cache_key) do
|
||||||
|
IssuePriority.select(:id, :name, :position).collect do |event|
|
||||||
|
{
|
||||||
|
id: event.id,
|
||||||
|
name: event.name,
|
||||||
|
position: event.position,
|
||||||
|
is_chosen: '0'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_complete_percentage
|
||||||
|
completion_nums = %w(0 10 20 30 40 50 60 70 80 90 100)
|
||||||
|
completion_nums.collect do |event|
|
||||||
|
{
|
||||||
|
id: event.to_i,
|
||||||
|
name: event + "%",
|
||||||
|
is_chosen: '0'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_issue_species
|
||||||
|
species = %W(普通 悬赏)
|
||||||
|
|
||||||
|
species.collect do |event|
|
||||||
|
{
|
||||||
|
id: event.to_i + 1,
|
||||||
|
token: nil,
|
||||||
|
is_chosen: '0'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_issue_tags(project)
|
||||||
|
# project.issue_tags.last&.cache_key
|
||||||
|
cache_key = "all_issue_tags/#{project.issue_tags.maximum('updated_at')}"
|
||||||
|
|
||||||
|
Rails.cache.fetch(cache_key) do
|
||||||
|
project.issue_tags.select(:id, :name, :color).collect do |event|
|
||||||
|
{
|
||||||
|
id: event.id,
|
||||||
|
name: event.name,
|
||||||
|
color: event.color,
|
||||||
|
is_chosen: '0'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_cache_milestones(project)
|
||||||
|
cache_key = "all_milestones/#{project.versions.maximum('updated_on')}"
|
||||||
|
|
||||||
|
Rails.cache.fetch(cache_key) do
|
||||||
|
project.versions.select(:id, :name, :status).collect do |event|
|
||||||
|
{
|
||||||
|
id: event.id,
|
||||||
|
name: event.name,
|
||||||
|
status: event.status,
|
||||||
|
is_chosen: '0'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_cache_collaborators(project)
|
||||||
|
cache_key = "all_collaborators/#{project.members.maximum('created_on')}"
|
||||||
|
|
||||||
|
Rails.cache.fetch(cache_key) do
|
||||||
|
project.members.includes(:user).collect do |event|
|
||||||
|
{
|
||||||
|
id: event.user&.id,
|
||||||
|
name: event.user&.show_real_name,
|
||||||
|
avatar_url: url_to_avatar(event.user),
|
||||||
|
is_chosen: '0'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def issue_left_chosen(project,issue_id)
|
def issue_left_chosen(project,issue_id)
|
||||||
issue_info = Array.new(11)
|
issue_info = Array.new(11)
|
||||||
|
@ -205,4 +344,4 @@ module TagChosenHelper
|
||||||
# be_depended_issues_array
|
# be_depended_issues_array
|
||||||
# end
|
# end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,8 @@ module Gitea
|
||||||
attr_reader :error, :result
|
attr_reader :error, :result
|
||||||
|
|
||||||
def initialize(token, owner, params)
|
def initialize(token, owner, params)
|
||||||
@owner = owner
|
@token = token
|
||||||
|
@owner = owner
|
||||||
@params = params
|
@params = params
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ module Gitea
|
||||||
file_params = file_params.merge(new_branch: @params[:new_branch]) unless @params[:new_branch].blank?
|
file_params = file_params.merge(new_branch: @params[:new_branch]) unless @params[:new_branch].blank?
|
||||||
file_params = file_params.merge(content: Base64.encode64(@params[:content]))
|
file_params = file_params.merge(content: Base64.encode64(@params[:content]))
|
||||||
file_params = file_params.merge(message: @params[:message]) unless @params[:message].blank?
|
file_params = file_params.merge(message: @params[:message]) unless @params[:message].blank?
|
||||||
|
file_params = file_params.merge(committer: @params[:committer])
|
||||||
file_params
|
file_params
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,7 +22,7 @@ module Gitea
|
||||||
|
|
||||||
def run
|
def run
|
||||||
Gitea::UserForm.new(params).validate!
|
Gitea::UserForm.new(params).validate!
|
||||||
response = Gitea::User::RegisterService.new(params).call
|
response = Gitea::User::RegisterService.call(params.merge(token: token))
|
||||||
render_result(response)
|
render_result(response)
|
||||||
rescue Exception => exception
|
rescue Exception => exception
|
||||||
Rails.logger.info "Exception ===========> #{exception.message}"
|
Rails.logger.info "Exception ===========> #{exception.message}"
|
||||||
|
@ -41,5 +41,12 @@ module Gitea
|
||||||
def render_result(response)
|
def render_result(response)
|
||||||
@result = response
|
@result = response
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def token
|
||||||
|
{
|
||||||
|
username: Gitea.gitea_config[:access_key_id],
|
||||||
|
password: Gitea.gitea_config[:access_key_secret]
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
module Repositories::ProtectedBranches
|
||||||
|
class DeleteInteractor
|
||||||
|
def self.call(user, identifier, filepath, **args)
|
||||||
|
interactor = new(user, identifier, filepath, **args)
|
||||||
|
interactor.run
|
||||||
|
interactor
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :error, :result
|
||||||
|
|
||||||
|
def initialize(user, identifier, filepath, **args)
|
||||||
|
@user = user
|
||||||
|
@identifier = identifier
|
||||||
|
@filepath = filepath
|
||||||
|
@args = args
|
||||||
|
end
|
||||||
|
|
||||||
|
def success?
|
||||||
|
@error.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def result
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
|
||||||
|
rescue Exception => exception
|
||||||
|
fail!(exception.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
attr_reader :user, :identifier, :filepath, :args
|
||||||
|
|
||||||
|
def fail!(error)
|
||||||
|
@error = error
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_result(response)
|
||||||
|
@result = response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,24 @@
|
||||||
|
class PostChainJob < ApplicationJob
|
||||||
|
queue_as :default
|
||||||
|
|
||||||
|
def perform(chain_params)
|
||||||
|
status = false
|
||||||
|
chain_type = chain_params[:type].to_s
|
||||||
|
reponame = chain_params[:chain_params][:reponame]
|
||||||
|
5.times do |i|
|
||||||
|
if status
|
||||||
|
break
|
||||||
|
else
|
||||||
|
response = Gitea::Chain::ChainPostService.new(chain_params).call
|
||||||
|
if response.status == 200
|
||||||
|
reponse_body = response&.body
|
||||||
|
messages = reponse_body.present? ? JSON.parse(reponse_body) : "success"
|
||||||
|
status = true
|
||||||
|
Rails.logger.info("################_repository__#{reponame}______create_chain_success_try:_#{i+1}_message__:#{messages}__")
|
||||||
|
else
|
||||||
|
Rails.logger.info("########_repository__#{reponame}______create_chain_failed__try:_#{i+1}_")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,73 @@
|
||||||
|
require 'uri'
|
||||||
|
require 'net/http'
|
||||||
|
|
||||||
|
class SyncEducoderShixunJob < ApplicationJob
|
||||||
|
queue_as :default
|
||||||
|
|
||||||
|
def perform(url, private_token, page, per_page)
|
||||||
|
uri = URI("#{url}?page=#{page}&per_page=#{per_page}&private_token=#{private_token}")
|
||||||
|
puts "-------url: #{uri}"
|
||||||
|
response = Net::HTTP.get_response(uri)
|
||||||
|
|
||||||
|
result = JSON.parse(response.body)
|
||||||
|
|
||||||
|
if result['status'] != 0
|
||||||
|
puts "======= 接口请求失败!"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
result['data']['repositories'].each do |re|
|
||||||
|
next if re['repo_name'].blank?
|
||||||
|
next if ProjectEducoder.exists?(repo_name: re['repo_name'])
|
||||||
|
|
||||||
|
language = ProjectLanguage.find_by_name re['language']
|
||||||
|
language = ProjectLanguage.create!(name: re['language']) if language.blank?
|
||||||
|
|
||||||
|
category = ProjectCategory.find_by_name re['category']
|
||||||
|
category = ProjectCategory.create!(name: re['category']) if category.blank?
|
||||||
|
|
||||||
|
project_params =
|
||||||
|
{
|
||||||
|
name: re['name'],
|
||||||
|
# user_id: params[:user_id],
|
||||||
|
description: re['description'],
|
||||||
|
project_category_id: category.id,
|
||||||
|
project_language_id: language.id,
|
||||||
|
is_public: true,
|
||||||
|
# ignore_id: params[:ignore_id],
|
||||||
|
# license_id: params[:license_id],
|
||||||
|
identifier: re['repo_name'],
|
||||||
|
platform: Project.platforms[:educoder]
|
||||||
|
}
|
||||||
|
|
||||||
|
project = Project.new(project_params)
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
if project.save!
|
||||||
|
repo_params =
|
||||||
|
{
|
||||||
|
hidden: false,
|
||||||
|
project_id: project.id,
|
||||||
|
identifier: re['repo_name']
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectEducoder.create!(
|
||||||
|
project_id: project.id,
|
||||||
|
owner: re['username'],
|
||||||
|
repo_name: re['repo_name'],
|
||||||
|
forked_count: re['forked_count'],
|
||||||
|
commit_count: re['commit_count'],
|
||||||
|
image_url: re['image_url'])
|
||||||
|
|
||||||
|
repo = Repository.new(repo_params)
|
||||||
|
repo.save!
|
||||||
|
|
||||||
|
puts "项目: #{re['name']} 同步成功"
|
||||||
|
else
|
||||||
|
puts "项目: #{re['name']} 同步失败"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -8,7 +8,7 @@ class SyncProjectsJob < ApplicationJob
|
||||||
SyncLog.sync_log("==========begin to sync #{sync_params[:type]} to forge============")
|
SyncLog.sync_log("==========begin to sync #{sync_params[:type]} to forge============")
|
||||||
SyncLog.sync_log("==========sync_params:#{sync_params}============")
|
SyncLog.sync_log("==========sync_params:#{sync_params}============")
|
||||||
|
|
||||||
begin
|
begin
|
||||||
url = "#{gitea_main}/sync_forges" #trustie上的相关路由
|
url = "#{gitea_main}/sync_forges" #trustie上的相关路由
|
||||||
uri = URI.parse(url)
|
uri = URI.parse(url)
|
||||||
http = Net::HTTP.new(uri.hostname, uri.port)
|
http = Net::HTTP.new(uri.hostname, uri.port)
|
||||||
|
@ -85,7 +85,7 @@ class SyncProjectsJob < ApplicationJob
|
||||||
new_target = target_type.constantize.new(re[:target_params].merge(user_id: u_id))
|
new_target = target_type.constantize.new(re[:target_params].merge(user_id: u_id))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !is_exists && new_target.save!
|
if !is_exists && new_target.save!
|
||||||
SyncLog.sync_log("***【#{target_type}】. create_success---------------")
|
SyncLog.sync_log("***【#{target_type}】. create_success---------------")
|
||||||
if re[:journals].present?
|
if re[:journals].present?
|
||||||
|
@ -112,10 +112,8 @@ class SyncProjectsJob < ApplicationJob
|
||||||
SyncLog.sync_log("=========***【#{target_type}】creat_had_erros:#{e}===================")
|
SyncLog.sync_log("=========***【#{target_type}】creat_had_erros:#{e}===================")
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_journals(target_jsons, target_type,issue_id)
|
def create_journals(target_jsons, target_type,issue_id)
|
||||||
|
@ -127,7 +125,7 @@ class SyncProjectsJob < ApplicationJob
|
||||||
if re[:target_params].present?
|
if re[:target_params].present?
|
||||||
u_id = User.select(:id, :login).where(login: re[:user_login]).pluck(:id).first
|
u_id = User.select(:id, :login).where(login: re[:user_login]).pluck(:id).first
|
||||||
is_exists = Journal.exists?(user_id: u_id, journalized_id: re[:target_params][:journalized_id], created_on: re[:target_params][:created_on].to_s.to_time)
|
is_exists = Journal.exists?(user_id: u_id, journalized_id: re[:target_params][:journalized_id], created_on: re[:target_params][:created_on].to_s.to_time)
|
||||||
|
|
||||||
if is_exists
|
if is_exists
|
||||||
SyncLog.sync_log("***00000. Journal:#{re[:target_params][:id]}-is exists--------------")
|
SyncLog.sync_log("***00000. Journal:#{re[:target_params][:id]}-is exists--------------")
|
||||||
else
|
else
|
||||||
|
@ -142,7 +140,7 @@ class SyncProjectsJob < ApplicationJob
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
SyncLog.sync_log("***111222. journal_create failed---------------")
|
SyncLog.sync_log("***111222. journal_create failed---------------")
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -181,4 +179,4 @@ class SyncProjectsJob < ApplicationJob
|
||||||
SyncLog.sync_log("***111222. end_to_create_target---------------")
|
SyncLog.sync_log("***111222. end_to_create_target---------------")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
module Ci
|
||||||
|
class Database < ActiveRecord::Base
|
||||||
|
self.abstract_class = true
|
||||||
|
|
||||||
|
# Dynamically sets the database connection.
|
||||||
|
def self.set_connection(params)
|
||||||
|
puts "[Ci::Database] set db connection params: #{params}"
|
||||||
|
establish_connection(
|
||||||
|
adapter: params[:adapter],
|
||||||
|
database: params[:database],
|
||||||
|
port: params[:port].to_i,
|
||||||
|
host: params[:host],
|
||||||
|
username: params[:username],
|
||||||
|
password: params[:password],
|
||||||
|
encoding: "utf8"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get_connection_params(connect_to)
|
||||||
|
params = Hash.new
|
||||||
|
params[:adapter] = "mysql2"
|
||||||
|
params[:host] = connect_to[:host].to_s
|
||||||
|
params[:username] = connect_to[:username].to_s
|
||||||
|
params[:password] = connect_to[:password].to_s
|
||||||
|
params[:database] = connect_to[:database].to_s
|
||||||
|
params[:port] = connect_to[:port] || "43306"
|
||||||
|
params[:encoding] = "utf8"
|
||||||
|
return params
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,81 @@
|
||||||
|
class Ci::Drone::API < Ci::Drone::Request
|
||||||
|
attr_reader :drone_token, :endpoint, :owner, :repo, :options
|
||||||
|
|
||||||
|
# drone_token:
|
||||||
|
# owner: repo's owner name or login
|
||||||
|
# repo: repo's identifier
|
||||||
|
def initialize(drone_token, endpoint, owner, repo, options={})
|
||||||
|
@drone_token = drone_token
|
||||||
|
@endpoint = endpoint
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
@options = options
|
||||||
|
end
|
||||||
|
|
||||||
|
# Build List
|
||||||
|
# GET api/repos/{owner}/{name}/builds
|
||||||
|
# eq:
|
||||||
|
# Ci::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier)
|
||||||
|
def builds
|
||||||
|
get(endpoint, "api/repos/#{owner}/#{repo}/builds", drone_token: drone_token)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Build Info
|
||||||
|
# GET api/repos/{owner}/{name}/builds/{number}
|
||||||
|
# eq:
|
||||||
|
# Ci::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, project.owner.login, project.identifier, number: number).build
|
||||||
|
def build
|
||||||
|
get(endpoint, "api/repos/#{owner}/#{repo}/builds/#{options[:number]}", drone_token: drone_token)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Update .trustie-pipeline.yml file
|
||||||
|
# PATCH api/repos/{owner}/{name}\
|
||||||
|
# eq:
|
||||||
|
# Ci::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, project.owner.login, project.identifier, config_path: config_path).config_yml
|
||||||
|
def config_yml
|
||||||
|
patch(endpoint, "/api/repos/#{owner}/#{repo}", drone_token: drone_token, config_path: options[:config_path])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Activate user's project with Drone CI
|
||||||
|
# POST api/repos/{owner}/{name}
|
||||||
|
# eq:
|
||||||
|
# Ci::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, project.owner.login, project.identifier).activate
|
||||||
|
def activate
|
||||||
|
post(endpoint, "/api/repos/#{owner}/#{repo}", drone_token: drone_token)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Build Restart
|
||||||
|
# POST api/repos/{owner}/{name}/builds/{number}
|
||||||
|
# Restart the specified build. Please note this api requires read and write access to the repository and the request parameter {build} is not the build id but the build number.
|
||||||
|
# eq:
|
||||||
|
# Ci::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier, number: number).restart
|
||||||
|
def restart
|
||||||
|
post(endpoint, "/api/repos/#{owner}/#{repo}/builds/#{options[:number]}", drone_token: drone_token)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Build Stop
|
||||||
|
# DELETE api/repos/{owner}/{name}/builds/{number}
|
||||||
|
# Stop the specified build. Please note this api requires administrative privileges and the request parameter {build} is not the build id but the build number.
|
||||||
|
# eq:
|
||||||
|
# Ci::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier, number: number).stop
|
||||||
|
def stop
|
||||||
|
delete(endpoint, "/api/repos/#{owner}/#{repo}/builds/#{options[:number]}", drone_token: drone_token)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Build Logs
|
||||||
|
# GET /api/repos/{owner}/{repo}/builds/{build}/logs/{stage}/{step}
|
||||||
|
# Please note this api requires read access to the repository.
|
||||||
|
# eq:
|
||||||
|
# Ci::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier, build: build, stage: stage, step: step).logs
|
||||||
|
def logs
|
||||||
|
get(endpoint, "/api/repos/#{owner}/#{repo}/builds/#{options[:build]}/logs/#{options[:stage]}/#{options[:step]}", drone_token: drone_token)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Synchronize the currently authenticated user’s repository list.
|
||||||
|
# POST /api/user/repos
|
||||||
|
# eq:
|
||||||
|
# Ci::Drone::API.new(drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier, number: number).sync
|
||||||
|
def sync_repos
|
||||||
|
post(endpoint, "/api/users/repos", drone_token: drone_token)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
class Ci::Drone::Ci
|
||||||
|
attr_reader :host, :username, :password, :gitea_username
|
||||||
|
|
||||||
|
# host: drone server's ip
|
||||||
|
# username: drone server's account
|
||||||
|
# password: drone server's password
|
||||||
|
# eq:
|
||||||
|
# DevOps::Drone::Ci.new(@cloud_account.drone_ip, @cloud_account.account, @cloud_account.visible_secret, current_user.login).get_token
|
||||||
|
def initialize(host, username, password, gitea_username)
|
||||||
|
@host = host
|
||||||
|
@username = username
|
||||||
|
@password = password
|
||||||
|
@gitea_username = gitea_username
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_token
|
||||||
|
puts "--------- sshpass -p #{password} ssh -o 'StrictHostKeyChecking no' #{username}@#{host} '#{cmd}'"
|
||||||
|
`sshpass -p #{password} ssh -o "StrictHostKeyChecking no" #{username}@#{host} "#{cmd}"`
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def cmd
|
||||||
|
"cd ..; cd var/lib/drone/; sqlite3 database.sqlite; .dump; select user_hash from users where user_login=#{gitea_username};"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
class Ci::Drone::Client
|
||||||
|
attr_reader :client_id, :drone_ip, :rpc_secret
|
||||||
|
|
||||||
|
# client_id: user's client_id from oauth
|
||||||
|
# drone_ip: 云服务器IP地址, eq: 173.65.32.21
|
||||||
|
# eq:
|
||||||
|
# DevOps::Drone::Client.new(current_user.oauth.client_id, 'drone_ip').generate_cmd
|
||||||
|
def initialize(client_id, drone_ip, rpc_secret)
|
||||||
|
@client_id = client_id
|
||||||
|
@drone_ip = drone_ip
|
||||||
|
@rpc_secret = rpc_secret
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_cmd
|
||||||
|
"docker run -d \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
|
-e DRONE_RPC_HOST=#{drone_ip}:80 \
|
||||||
|
-e DRONE_RPC_SECRET=#{rpc_secret} \
|
||||||
|
-e DRONE_RUNNER_NAME=#{drone_ip} \
|
||||||
|
--restart always \
|
||||||
|
--name drone-agent--#{client_id} \
|
||||||
|
--net='bridge' \
|
||||||
|
drone/drone-runner-docker:1"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,14 @@
|
||||||
|
class Ci::Drone::Error < StandardError
|
||||||
|
attr_reader :code
|
||||||
|
|
||||||
|
def initialize(code, message)
|
||||||
|
super message
|
||||||
|
@code = code
|
||||||
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def parse(result)
|
||||||
|
new(result['errcode'], result['errmsg'])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,108 @@
|
||||||
|
class Ci::Drone::Request
|
||||||
|
# Converts the response body to an ObjectifiedHash.
|
||||||
|
def self.parse(body)
|
||||||
|
body = decode(body)
|
||||||
|
|
||||||
|
if body.is_a? Hash
|
||||||
|
ObjectifiedHash.new body
|
||||||
|
elsif body.is_a? Array
|
||||||
|
body.collect! { |e| ObjectifiedHash.new(e) }
|
||||||
|
elsif body == true
|
||||||
|
body
|
||||||
|
else
|
||||||
|
raise Error::Parsing.new "Couldn't parse a response body"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Decodes a JSON response into Ruby object.
|
||||||
|
def self.decode(response)
|
||||||
|
begin
|
||||||
|
JSON.load response
|
||||||
|
rescue JSON::ParserError
|
||||||
|
raise Error::Parsing.new "The response is not a valid JSON"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(endpoint, path, options={})
|
||||||
|
validate_request_params!(endpoint)
|
||||||
|
request(:get, endpoint, path, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def post(endpoint, path, options={})
|
||||||
|
validate_request_params!(endpoint)
|
||||||
|
request(:post, endpoint, path, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def put(endpoint, path, options={})
|
||||||
|
validate_request_params!(endpoint)
|
||||||
|
request(:put, endpoint, path, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def patch(endpoint, path, options={})
|
||||||
|
validate_request_params!(endpoint)
|
||||||
|
request(:patch, endpoint, path, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(endpoint, path, options={})
|
||||||
|
validate_request_params!(endpoint)
|
||||||
|
request(:delete, endpoint, path, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def request(method, endpoint, path, **params)
|
||||||
|
Rails.logger.info("[drone] request: #{method} #{path} #{params.except(:drone_token).inspect}")
|
||||||
|
|
||||||
|
client ||= begin
|
||||||
|
Faraday.new(url: endpoint) do |req|
|
||||||
|
req.request :url_encoded
|
||||||
|
req.headers['Content-Type'] = 'application/json'
|
||||||
|
req.response :logger # 显示日志
|
||||||
|
req.adapter Faraday.default_adapter
|
||||||
|
req.authorization :Bearer, params[:drone_token]
|
||||||
|
req.headers['Authorization']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
response = client.public_send(method, path) do |req|
|
||||||
|
req.body = params.except(:drone_token).to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
json_response(response)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Checks the response code for common errors.
|
||||||
|
# Returns parsed response for successful requests.
|
||||||
|
def validate(response)
|
||||||
|
# case response.code
|
||||||
|
# when 400; raise Error::BadRequest.new error_message(response)
|
||||||
|
# when 401; raise Error::Unauthorized.new error_message(response)
|
||||||
|
# when 403; raise Error::Forbidden.new error_message(response)
|
||||||
|
# when 404; raise Error::NotFound.new error_message(response)
|
||||||
|
# when 405; raise Error::MethodNotAllowed.new error_message(response)
|
||||||
|
# when 406; raise Error::DataNotAccepted.new error_message(response)
|
||||||
|
# when 409; raise Error::Conflict.new error_message(response)
|
||||||
|
# when 500; raise Error::InternalServerError.new error_message(response)
|
||||||
|
# when 502; raise Error::BadGateway.new error_message(response)
|
||||||
|
# when 503; raise Error::ServiceUnavailable.new error_message(response)
|
||||||
|
# end
|
||||||
|
|
||||||
|
response.parsed_response
|
||||||
|
end
|
||||||
|
|
||||||
|
# Checks a base_uri and params for requests.
|
||||||
|
def validate_request_params!(endpoint)
|
||||||
|
raise "Please set an endpoint to API" unless endpoint
|
||||||
|
end
|
||||||
|
|
||||||
|
def error_message(response)
|
||||||
|
"Server responded with code #{response.code}, message: #{response.parsed_response.message}. " \
|
||||||
|
"Request URI: #{response.request.base_uri}#{response.request.path}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def json_response(response)
|
||||||
|
result = JSON.parse(response.body)
|
||||||
|
status = response.status
|
||||||
|
Rails.logger.info("[drone] response:#{status} #{result.inspect}")
|
||||||
|
|
||||||
|
response.status != 200 ? result.merge!(status: response.status) : result
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,62 @@
|
||||||
|
class Ci::Drone::Server
|
||||||
|
attr_reader :user_login, :client_id, :client_secret, :drone_host, :rpc_secret
|
||||||
|
|
||||||
|
# client_id: user's client_id from oauth
|
||||||
|
# client_secret: user's client_id from oauth
|
||||||
|
# drone_host: 云服务器地址,eq: 173.53.21.31:80
|
||||||
|
# eg:
|
||||||
|
# DevOps::Drone::Server.new(current_user.login, current_user.oauth.client_id, current_user.oauth.client_secret, 'drone_host').generate_cmd
|
||||||
|
def initialize(user_login, client_id, client_secret, drone_host, rpc_secret)
|
||||||
|
@user_login = user_login
|
||||||
|
@client_id = client_id
|
||||||
|
@drone_host = drone_host
|
||||||
|
@rpc_secret = rpc_secret
|
||||||
|
@client_secret = client_secret
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO 一下代码方便测试,正式环境请移除
|
||||||
|
# docker rm -f `docker ps -qa`
|
||||||
|
def generate_cmd
|
||||||
|
"service docker start; docker run \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
|
-e DRONE_DATABASE_DRIVER=mysql \
|
||||||
|
-e DRONE_DATABASE_DATASOURCE=#{database_username}:'#{database_password}'@tcp\\(#{database_host}:#{database_port}\\)/#{user_login}_drone?parseTime=true \
|
||||||
|
-e DRONE_GITEA_SERVER=#{gitea_url} \
|
||||||
|
-e DRONE_GITEA_CLIENT_ID=#{client_id} \
|
||||||
|
-e DRONE_GITEA_CLIENT_SECRET=#{client_secret} \
|
||||||
|
-e DRONE_RPC_SECRET=#{rpc_secret} \
|
||||||
|
-e DRONE_SERVER_HOST=#{drone_host} \
|
||||||
|
-e DRONE_SERVER_PROTO=http \
|
||||||
|
-p '80:80' \
|
||||||
|
--restart=always \
|
||||||
|
--detach=true \
|
||||||
|
--name=drone-server-#{client_id} \
|
||||||
|
--net='bridge' \
|
||||||
|
drone/drone:1"
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def gitea_url
|
||||||
|
Gitea.gitea_config[:domain]
|
||||||
|
end
|
||||||
|
|
||||||
|
def database_username
|
||||||
|
database_config[Rails.env]["ci_server_db"]["username"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def database_password
|
||||||
|
database_config[Rails.env]["ci_server_db"]["password"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def database_host
|
||||||
|
database_config[Rails.env]["ci_server_db"]["host"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def database_port
|
||||||
|
database_config[Rails.env]["ci_server_db"]["port"] || 3306
|
||||||
|
end
|
||||||
|
|
||||||
|
def database_config
|
||||||
|
Rails.configuration.database_configuration
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,22 @@
|
||||||
|
class Ci::Drone::Start
|
||||||
|
attr_reader :drone_username, :drone_password, :drone_host, :drone_server_cmd, :drone_client_cmd
|
||||||
|
|
||||||
|
# drone_username="XXXX" 云服务器登录用户名
|
||||||
|
# drone_password="XXXXX" 云服务器用户密码
|
||||||
|
# drone_host="" 云服务器地址
|
||||||
|
# eq:
|
||||||
|
# drone_server_cmd = DevOps::Drone::Server.new('client_id', 'client_secret', 'drone_url').generate_cmd
|
||||||
|
# drone_client_cmd = DevOps::Drone::Client.new('client_id', 'server_url').generate_cmd
|
||||||
|
# DevOps::Drone::Start.new(drone_username, drone_password, 'drone_host', drone_server_cmd, drone_client_cmd).run
|
||||||
|
def initialize(drone_username, drone_password, drone_host, drone_server_cmd, drone_client_cmd)
|
||||||
|
@drone_username = drone_username
|
||||||
|
@drone_password = drone_password
|
||||||
|
@drone_host = drone_host
|
||||||
|
@drone_server_cmd = drone_server_cmd
|
||||||
|
@drone_client_cmd = drone_client_cmd
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
`sshpass -p #{drone_password} ssh -o "StrictHostKeyChecking no" #{drone_username}@#{drone_host} "#{drone_server_cmd} && #{drone_client_cmd}"`
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,260 @@
|
||||||
|
module Ci::Schema
|
||||||
|
class << self
|
||||||
|
def statement
|
||||||
|
sqls = <<-SQL
|
||||||
|
CREATE TABLE IF NOT EXISTS `repos` (
|
||||||
|
`repo_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`repo_uid` varchar(250) DEFAULT NULL,
|
||||||
|
`repo_user_id` int(11) DEFAULT NULL,
|
||||||
|
`repo_namespace` varchar(250) DEFAULT NULL,
|
||||||
|
`repo_name` varchar(250) DEFAULT NULL,
|
||||||
|
`repo_slug` varchar(250) DEFAULT NULL,
|
||||||
|
`repo_scm` varchar(50) DEFAULT NULL,
|
||||||
|
`repo_clone_url` varchar(2000) DEFAULT NULL,
|
||||||
|
`repo_ssh_url` varchar(2000) DEFAULT NULL,
|
||||||
|
`repo_html_url` varchar(2000) DEFAULT NULL,
|
||||||
|
`repo_active` tinyint(1) DEFAULT NULL,
|
||||||
|
`repo_private` tinyint(1) DEFAULT NULL,
|
||||||
|
`repo_visibility` varchar(50) DEFAULT NULL,
|
||||||
|
`repo_branch` varchar(250) DEFAULT NULL,
|
||||||
|
`repo_counter` int(11) DEFAULT NULL,
|
||||||
|
`repo_config` varchar(500) DEFAULT NULL,
|
||||||
|
`repo_timeout` int(11) DEFAULT NULL,
|
||||||
|
`repo_trusted` tinyint(1) DEFAULT NULL,
|
||||||
|
`repo_protected` tinyint(1) DEFAULT NULL,
|
||||||
|
`repo_synced` int(11) DEFAULT NULL,
|
||||||
|
`repo_created` int(11) DEFAULT NULL,
|
||||||
|
`repo_updated` int(11) DEFAULT NULL,
|
||||||
|
`repo_version` int(11) DEFAULT NULL,
|
||||||
|
`repo_signer` varchar(50) DEFAULT NULL,
|
||||||
|
`repo_secret` varchar(50) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`repo_id`),
|
||||||
|
UNIQUE KEY `repo_slug` (`repo_slug`),
|
||||||
|
UNIQUE KEY `repo_uid` (`repo_uid`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=137 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `builds` (
|
||||||
|
`build_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`build_repo_id` int(11) DEFAULT NULL,
|
||||||
|
`build_config_id` int(11) DEFAULT NULL,
|
||||||
|
`build_trigger` varchar(250) DEFAULT NULL,
|
||||||
|
`build_number` int(11) DEFAULT NULL,
|
||||||
|
`build_parent` int(11) DEFAULT NULL,
|
||||||
|
`build_status` varchar(50) DEFAULT NULL,
|
||||||
|
`build_error` varchar(500) DEFAULT NULL,
|
||||||
|
`build_event` varchar(50) DEFAULT NULL,
|
||||||
|
`build_action` varchar(50) DEFAULT NULL,
|
||||||
|
`build_link` varchar(1000) DEFAULT NULL,
|
||||||
|
`build_timestamp` int(11) DEFAULT NULL,
|
||||||
|
`build_title` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||||
|
`build_message` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||||
|
`build_before` varchar(50) DEFAULT NULL,
|
||||||
|
`build_after` varchar(50) DEFAULT NULL,
|
||||||
|
`build_ref` varchar(500) DEFAULT NULL,
|
||||||
|
`build_source_repo` varchar(250) DEFAULT NULL,
|
||||||
|
`build_source` varchar(500) DEFAULT NULL,
|
||||||
|
`build_target` varchar(500) DEFAULT NULL,
|
||||||
|
`build_author` varchar(500) DEFAULT NULL,
|
||||||
|
`build_author_name` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||||
|
`build_author_email` varchar(500) DEFAULT NULL,
|
||||||
|
`build_author_avatar` varchar(1000) DEFAULT NULL,
|
||||||
|
`build_sender` varchar(500) DEFAULT NULL,
|
||||||
|
`build_deploy` varchar(500) DEFAULT NULL,
|
||||||
|
`build_params` varchar(2000) DEFAULT NULL,
|
||||||
|
`build_started` int(11) DEFAULT NULL,
|
||||||
|
`build_finished` int(11) DEFAULT NULL,
|
||||||
|
`build_created` int(11) DEFAULT NULL,
|
||||||
|
`build_updated` int(11) DEFAULT NULL,
|
||||||
|
`build_version` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`build_id`),
|
||||||
|
UNIQUE KEY `build_repo_id` (`build_repo_id`,`build_number`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `cron` (
|
||||||
|
`cron_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`cron_repo_id` int(11) DEFAULT NULL,
|
||||||
|
`cron_name` varchar(50) DEFAULT NULL,
|
||||||
|
`cron_expr` varchar(50) DEFAULT NULL,
|
||||||
|
`cron_next` int(11) DEFAULT NULL,
|
||||||
|
`cron_prev` int(11) DEFAULT NULL,
|
||||||
|
`cron_event` varchar(50) DEFAULT NULL,
|
||||||
|
`cron_branch` varchar(250) DEFAULT NULL,
|
||||||
|
`cron_target` varchar(250) DEFAULT NULL,
|
||||||
|
`cron_disabled` tinyint(1) DEFAULT NULL,
|
||||||
|
`cron_created` int(11) DEFAULT NULL,
|
||||||
|
`cron_updated` int(11) DEFAULT NULL,
|
||||||
|
`cron_version` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`cron_id`),
|
||||||
|
UNIQUE KEY `cron_repo_id` (`cron_repo_id`,`cron_name`),
|
||||||
|
CONSTRAINT `cron_ibfk_1` FOREIGN KEY (`cron_repo_id`) REFERENCES `repos` (`repo_id`) ON DELETE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `latest` (
|
||||||
|
`latest_repo_id` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`latest_build_id` int(11) DEFAULT NULL,
|
||||||
|
`latest_type` varchar(50) NOT NULL DEFAULT '',
|
||||||
|
`latest_name` varchar(500) NOT NULL DEFAULT '',
|
||||||
|
`latest_created` int(11) DEFAULT NULL,
|
||||||
|
`latest_updated` int(11) DEFAULT NULL,
|
||||||
|
`latest_deleted` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`latest_repo_id`,`latest_type`,`latest_name`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `logs` (
|
||||||
|
`log_id` int(11) NOT NULL,
|
||||||
|
`log_data` mediumblob,
|
||||||
|
PRIMARY KEY (`log_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `migrations` (
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
UNIQUE KEY `name` (`name`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `nodes` (
|
||||||
|
`node_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`node_uid` varchar(500) DEFAULT NULL,
|
||||||
|
`node_provider` varchar(50) DEFAULT NULL,
|
||||||
|
`node_state` varchar(50) DEFAULT NULL,
|
||||||
|
`node_name` varchar(50) DEFAULT NULL,
|
||||||
|
`node_image` varchar(500) DEFAULT NULL,
|
||||||
|
`node_region` varchar(100) DEFAULT NULL,
|
||||||
|
`node_size` varchar(100) DEFAULT NULL,
|
||||||
|
`node_os` varchar(50) DEFAULT NULL,
|
||||||
|
`node_arch` varchar(50) DEFAULT NULL,
|
||||||
|
`node_kernel` varchar(50) DEFAULT NULL,
|
||||||
|
`node_variant` varchar(50) DEFAULT NULL,
|
||||||
|
`node_address` varchar(500) DEFAULT NULL,
|
||||||
|
`node_capacity` int(11) DEFAULT NULL,
|
||||||
|
`node_filter` varchar(2000) DEFAULT NULL,
|
||||||
|
`node_labels` varchar(2000) DEFAULT NULL,
|
||||||
|
`node_error` varchar(2000) DEFAULT NULL,
|
||||||
|
`node_ca_key` blob,
|
||||||
|
`node_ca_cert` blob,
|
||||||
|
`node_tls_key` blob,
|
||||||
|
`node_tls_cert` blob,
|
||||||
|
`node_tls_name` varchar(500) DEFAULT NULL,
|
||||||
|
`node_paused` tinyint(1) DEFAULT NULL,
|
||||||
|
`node_protected` tinyint(1) DEFAULT NULL,
|
||||||
|
`node_created` int(11) DEFAULT NULL,
|
||||||
|
`node_updated` int(11) DEFAULT NULL,
|
||||||
|
`node_pulled` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`node_id`),
|
||||||
|
UNIQUE KEY `node_name` (`node_name`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `orgsecrets` (
|
||||||
|
`secret_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`secret_namespace` varchar(50) DEFAULT NULL,
|
||||||
|
`secret_name` varchar(200) DEFAULT NULL,
|
||||||
|
`secret_type` varchar(50) DEFAULT NULL,
|
||||||
|
`secret_data` blob,
|
||||||
|
`secret_pull_request` tinyint(1) DEFAULT NULL,
|
||||||
|
`secret_pull_request_push` tinyint(1) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`secret_id`),
|
||||||
|
UNIQUE KEY `secret_namespace` (`secret_namespace`,`secret_name`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `perms` (
|
||||||
|
`perm_user_id` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`perm_repo_uid` varchar(250) NOT NULL DEFAULT '',
|
||||||
|
`perm_read` tinyint(1) DEFAULT NULL,
|
||||||
|
`perm_write` tinyint(1) DEFAULT NULL,
|
||||||
|
`perm_admin` tinyint(1) DEFAULT NULL,
|
||||||
|
`perm_synced` int(11) DEFAULT NULL,
|
||||||
|
`perm_created` int(11) DEFAULT NULL,
|
||||||
|
`perm_updated` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`perm_user_id`,`perm_repo_uid`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `secrets` (
|
||||||
|
`secret_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`secret_repo_id` int(11) DEFAULT NULL,
|
||||||
|
`secret_name` varchar(500) DEFAULT NULL,
|
||||||
|
`secret_data` blob,
|
||||||
|
`secret_pull_request` tinyint(1) DEFAULT NULL,
|
||||||
|
`secret_pull_request_push` tinyint(1) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`secret_id`),
|
||||||
|
UNIQUE KEY `secret_repo_id` (`secret_repo_id`,`secret_name`),
|
||||||
|
CONSTRAINT `secrets_ibfk_1` FOREIGN KEY (`secret_repo_id`) REFERENCES `repos` (`repo_id`) ON DELETE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `stages` (
|
||||||
|
`stage_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`stage_repo_id` int(11) DEFAULT NULL,
|
||||||
|
`stage_build_id` int(11) DEFAULT NULL,
|
||||||
|
`stage_number` int(11) DEFAULT NULL,
|
||||||
|
`stage_name` varchar(100) DEFAULT NULL,
|
||||||
|
`stage_kind` varchar(50) DEFAULT NULL,
|
||||||
|
`stage_type` varchar(50) DEFAULT NULL,
|
||||||
|
`stage_status` varchar(50) DEFAULT NULL,
|
||||||
|
`stage_error` varchar(500) DEFAULT NULL,
|
||||||
|
`stage_errignore` tinyint(1) DEFAULT NULL,
|
||||||
|
`stage_exit_code` int(11) DEFAULT NULL,
|
||||||
|
`stage_limit` int(11) DEFAULT NULL,
|
||||||
|
`stage_os` varchar(50) DEFAULT NULL,
|
||||||
|
`stage_arch` varchar(50) DEFAULT NULL,
|
||||||
|
`stage_variant` varchar(10) DEFAULT NULL,
|
||||||
|
`stage_kernel` varchar(50) DEFAULT NULL,
|
||||||
|
`stage_machine` varchar(500) DEFAULT NULL,
|
||||||
|
`stage_started` int(11) DEFAULT NULL,
|
||||||
|
`stage_stopped` int(11) DEFAULT NULL,
|
||||||
|
`stage_created` int(11) DEFAULT NULL,
|
||||||
|
`stage_updated` int(11) DEFAULT NULL,
|
||||||
|
`stage_version` int(11) DEFAULT NULL,
|
||||||
|
`stage_on_success` tinyint(1) DEFAULT NULL,
|
||||||
|
`stage_on_failure` tinyint(1) DEFAULT NULL,
|
||||||
|
`stage_depends_on` text,
|
||||||
|
`stage_labels` text,
|
||||||
|
PRIMARY KEY (`stage_id`),
|
||||||
|
UNIQUE KEY `stage_build_id` (`stage_build_id`,`stage_number`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `stages_unfinished` (
|
||||||
|
`stage_id` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`stage_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `steps` (
|
||||||
|
`step_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`step_stage_id` int(11) DEFAULT NULL,
|
||||||
|
`step_number` int(11) DEFAULT NULL,
|
||||||
|
`step_name` varchar(100) DEFAULT NULL,
|
||||||
|
`step_status` varchar(50) DEFAULT NULL,
|
||||||
|
`step_error` varchar(500) DEFAULT NULL,
|
||||||
|
`step_errignore` tinyint(1) DEFAULT NULL,
|
||||||
|
`step_exit_code` int(11) DEFAULT NULL,
|
||||||
|
`step_started` int(11) DEFAULT NULL,
|
||||||
|
`step_stopped` int(11) DEFAULT NULL,
|
||||||
|
`step_version` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`step_id`),
|
||||||
|
UNIQUE KEY `step_stage_id` (`step_stage_id`,`step_number`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `users` (
|
||||||
|
`user_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`user_login` varchar(250) DEFAULT NULL,
|
||||||
|
`user_email` varchar(500) DEFAULT NULL,
|
||||||
|
`user_admin` tinyint(1) DEFAULT NULL,
|
||||||
|
`user_machine` tinyint(1) DEFAULT NULL,
|
||||||
|
`user_active` tinyint(1) DEFAULT NULL,
|
||||||
|
`user_avatar` varchar(2000) DEFAULT NULL,
|
||||||
|
`user_syncing` tinyint(1) DEFAULT NULL,
|
||||||
|
`user_synced` int(11) DEFAULT NULL,
|
||||||
|
`user_created` int(11) DEFAULT NULL,
|
||||||
|
`user_updated` int(11) DEFAULT NULL,
|
||||||
|
`user_last_login` int(11) DEFAULT NULL,
|
||||||
|
`user_oauth_token` varchar(500) DEFAULT NULL,
|
||||||
|
`user_oauth_refresh` varchar(500) DEFAULT NULL,
|
||||||
|
`user_oauth_expiry` int(11) DEFAULT NULL,
|
||||||
|
`user_hash` varchar(500) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`user_id`),
|
||||||
|
UNIQUE KEY `user_login` (`user_login`),
|
||||||
|
UNIQUE KEY `user_hash` (`user_hash`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||||
|
SQL
|
||||||
|
|
||||||
|
sqls
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,4 +5,5 @@ module CustomRegexp
|
||||||
NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/
|
NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/
|
||||||
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
|
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
|
||||||
URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/
|
URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/
|
||||||
end
|
IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
module Gitea
|
||||||
|
class Database < ActiveRecord::Base
|
||||||
|
self.abstract_class = true
|
||||||
|
|
||||||
|
def self.set_connection
|
||||||
|
gitea_server_config = Rails.configuration.database_configuration[Rails.env]["gitea_server"]
|
||||||
|
raise 'gitea database config missing' if gitea_server_config.blank?
|
||||||
|
|
||||||
|
establish_connection gitea_server_config
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,23 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: applied_messages
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# applied_id :integer
|
||||||
|
# applied_type :string(255)
|
||||||
|
# viewed :integer default("0")
|
||||||
|
# status :integer default("0")
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# name :string(255)
|
||||||
|
# applied_user_id :integer
|
||||||
|
# role :integer
|
||||||
|
# project_id :integer
|
||||||
|
#
|
||||||
|
|
||||||
class AppliedMessage < ApplicationRecord
|
class AppliedMessage < ApplicationRecord
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :applied, polymorphic: true
|
belongs_to :applied, polymorphic: true
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: applied_projects
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# project_id :integer not null
|
||||||
|
# user_id :integer not null
|
||||||
|
# role :integer default("0")
|
||||||
|
# status :integer default("0")
|
||||||
|
#
|
||||||
|
|
||||||
class AppliedProject < ApplicationRecord
|
class AppliedProject < ApplicationRecord
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
|
|
|
@ -1,3 +1,26 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: apply_actions
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# reason :string(255)
|
||||||
|
# container_id :integer
|
||||||
|
# container_type :string(255)
|
||||||
|
# dealer_id :integer
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# status :integer default("0")
|
||||||
|
# apply_reason :text(65535)
|
||||||
|
# noticed :boolean default("0")
|
||||||
|
# ip_addr :string(255)
|
||||||
|
# reject_description :string(255)
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_apply_actions_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
|
||||||
# 申请消息
|
# 申请消息
|
||||||
class ApplyAction < ApplicationRecord
|
class ApplyAction < ApplicationRecord
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
@ -27,4 +50,4 @@ class ApplyAction < ApplicationRecord
|
||||||
belong_container_id: container_id, belong_container_type: belong_container_type)
|
belong_container_id: container_id, belong_container_type: belong_container_type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: apply_user_authentications
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# status :integer
|
||||||
|
# auth_type :integer
|
||||||
|
# remarks :string(255)
|
||||||
|
# dealer :integer
|
||||||
|
# deal_time :datetime
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# is_delete :boolean default("0")
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_apply_user_authentications_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
|
||||||
# status:0 审核中 1 同意 2 拒绝 3 撤销
|
# status:0 审核中 1 同意 2 拒绝 3 撤销
|
||||||
# auth_type:1 实名认证, 2 职业认证
|
# auth_type:1 实名认证, 2 职业认证
|
||||||
class ApplyUserAuthentication < ApplicationRecord
|
class ApplyUserAuthentication < ApplicationRecord
|
||||||
|
|
|
@ -1,3 +1,42 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: attachments
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# container_id :integer
|
||||||
|
# container_type :string(30)
|
||||||
|
# filename :string(255) default(""), not null
|
||||||
|
# disk_filename :string(255) default(""), not null
|
||||||
|
# filesize :integer default("0"), not null
|
||||||
|
# content_type :string(255) default("")
|
||||||
|
# digest :string(60) default(""), not null
|
||||||
|
# downloads :integer default("0"), not null
|
||||||
|
# author_id :integer default("0"), not null
|
||||||
|
# created_on :datetime
|
||||||
|
# description :text(65535)
|
||||||
|
# disk_directory :string(255)
|
||||||
|
# attachtype :integer default("1")
|
||||||
|
# is_public :integer default("1")
|
||||||
|
# copy_from :integer
|
||||||
|
# quotes :integer default("0")
|
||||||
|
# is_publish :integer default("1")
|
||||||
|
# publish_time :datetime
|
||||||
|
# resource_bank_id :integer
|
||||||
|
# unified_setting :boolean default("1")
|
||||||
|
# cloud_url :string(255) default("")
|
||||||
|
# course_second_category_id :integer default("0")
|
||||||
|
# delay_publish :boolean default("0")
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_attachments_on_author_id (author_id)
|
||||||
|
# index_attachments_on_container_id_and_container_type (container_id,container_type)
|
||||||
|
# index_attachments_on_course_second_category_id (course_second_category_id)
|
||||||
|
# index_attachments_on_created_on (created_on)
|
||||||
|
# index_attachments_on_is_public (is_public)
|
||||||
|
# index_attachments_on_quotes (quotes)
|
||||||
|
#
|
||||||
|
|
||||||
class Attachment < ApplicationRecord
|
class Attachment < ApplicationRecord
|
||||||
include BaseModel
|
include BaseModel
|
||||||
include Publicable
|
include Publicable
|
||||||
|
|
|
@ -1,3 +1,22 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: attachment_group_settings
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# attachment_id :integer
|
||||||
|
# course_group_id :integer
|
||||||
|
# course_id :integer
|
||||||
|
# publish_time :datetime
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_attachment_group_settings_on_attachment_id (attachment_id)
|
||||||
|
# index_attachment_group_settings_on_course_group_id (course_group_id)
|
||||||
|
# index_attachment_group_settings_on_course_id (course_id)
|
||||||
|
#
|
||||||
|
|
||||||
class AttachmentGroupSetting < ActiveRecord::Base
|
class AttachmentGroupSetting < ActiveRecord::Base
|
||||||
belongs_to :attachment
|
belongs_to :attachment
|
||||||
# belongs_to :course_group
|
# belongs_to :course_group
|
||||||
|
|
|
@ -1,3 +1,31 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: attachment_histories
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# container_id :integer
|
||||||
|
# container_type :string(255)
|
||||||
|
# filename :string(255) default("")
|
||||||
|
# disk_filename :string(255) default("")
|
||||||
|
# filesize :integer default("0")
|
||||||
|
# content_type :string(255) default("")
|
||||||
|
# digest :string(60) default("")
|
||||||
|
# downloads :integer default("0")
|
||||||
|
# author_id :integer
|
||||||
|
# created_on :datetime
|
||||||
|
# description :text(65535)
|
||||||
|
# disk_directory :string(255)
|
||||||
|
# attachtype :integer
|
||||||
|
# is_public :integer
|
||||||
|
# copy_from :integer
|
||||||
|
# quotes :integer
|
||||||
|
# version :integer
|
||||||
|
# attachment_id :integer
|
||||||
|
# is_publish :integer default("1")
|
||||||
|
# publish_time :date
|
||||||
|
# cloud_url :string(255) default("")
|
||||||
|
#
|
||||||
|
|
||||||
class AttachmentHistory < ApplicationRecord
|
class AttachmentHistory < ApplicationRecord
|
||||||
include Publishable
|
include Publishable
|
||||||
include Publicable
|
include Publicable
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: bidding_users
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# project_package_id :integer
|
||||||
|
# user_id :integer
|
||||||
|
# status :string(255)
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_bidding_users_on_project_package_id (project_package_id)
|
||||||
|
# index_bidding_users_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
|
||||||
class BiddingUser < ApplicationRecord
|
class BiddingUser < ApplicationRecord
|
||||||
include AASM
|
include AASM
|
||||||
|
|
||||||
|
@ -21,4 +38,4 @@ class BiddingUser < ApplicationRecord
|
||||||
def status_text
|
def status_text
|
||||||
I18n.t("bidding_user.status.#{status}")
|
I18n.t("bidding_user.status.#{status}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
module Ci
|
||||||
|
# def self.table_name_prefix
|
||||||
|
# 'ci_'
|
||||||
|
# end
|
||||||
|
end
|
|
@ -0,0 +1,14 @@
|
||||||
|
class Ci::Build < Ci::RemoteBase
|
||||||
|
self.primary_key = 'build_id'
|
||||||
|
|
||||||
|
belongs_to :repo, foreign_key: :build_repo_id
|
||||||
|
has_many :stages, foreign_key: "stage_build_id", dependent: :destroy
|
||||||
|
|
||||||
|
scope :successed, ->{ by_status('success') }
|
||||||
|
scope :failed, -> { by_status('failure') }
|
||||||
|
scope :running, -> { by_status('running') }
|
||||||
|
scope :errored, -> { by_status('error') }
|
||||||
|
scope :pending, -> { by_status('pending') }
|
||||||
|
scope :killed, -> { by_status('killed') }
|
||||||
|
scope :by_status, ->(status) { where(build_status: status) }
|
||||||
|
end
|
|
@ -0,0 +1,47 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: ci_cloud_accounts
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer not null
|
||||||
|
# ip_num :integer
|
||||||
|
# account :string(255)
|
||||||
|
# secret :string(255)
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# ci_user_id :integer
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# dev_ops_cloud_accounts_p_u_ip (user_id,ip_num)
|
||||||
|
#
|
||||||
|
|
||||||
|
class Ci::CloudAccount < Ci::LocalBase
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :ci_user, class_name: 'Ci::User', foreign_key: :ci_user_id, optional: true
|
||||||
|
|
||||||
|
def drone_host
|
||||||
|
[drone_ip, ":80"].join
|
||||||
|
end
|
||||||
|
|
||||||
|
def drone_ip
|
||||||
|
IPAddr.new(self.ip_num, Socket::AF_INET).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def drone_url
|
||||||
|
["http://", self.drone_host].join
|
||||||
|
end
|
||||||
|
|
||||||
|
def visible_secret
|
||||||
|
Base64.decode64(secret)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.encrypted_secret(str)
|
||||||
|
Base64.encode64(str.strip).gsub(/\n/, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_url
|
||||||
|
[drone_url, '/login'].join
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: ci_languages
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# name :string(255) not null
|
||||||
|
# content :text(65535) not null
|
||||||
|
# usage_amount :integer default("0")
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# cover_id :integer
|
||||||
|
#
|
||||||
|
|
||||||
|
class Ci::Language < Ci::LocalBase
|
||||||
|
# before_save :encode_content
|
||||||
|
|
||||||
|
belongs_to :cover, class_name: "Attachment", foreign_key: :cover_id, optional: true
|
||||||
|
|
||||||
|
scope :six_common, -> { limit(6).by_usage_amount_desc }
|
||||||
|
scope :without_content, -> { select(column_names - ['content']) }
|
||||||
|
scope :by_usage_amount_desc, -> { order(usage_amount: :desc) }
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
def encode_content
|
||||||
|
self.content = Base64.encode64 content
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
class Ci::LocalBase < ApplicationRecord
|
||||||
|
self.abstract_class = true
|
||||||
|
|
||||||
|
def self.table_name_prefix
|
||||||
|
"ci_"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class Ci::Log < Ci::RemoteBase
|
||||||
|
self.primary_key = nil
|
||||||
|
|
||||||
|
belongs_to :step, class_name: 'Ci::Step', foreign_key: :log_id
|
||||||
|
end
|
|
@ -0,0 +1,20 @@
|
||||||
|
class Ci::Perm < Ci::RemoteBase
|
||||||
|
self.primary_key = nil
|
||||||
|
|
||||||
|
belongs_to :user, class_name: 'Ci::User', foreign_key: :perm_user_id
|
||||||
|
belongs_to :repo, class_name: 'Ci::Repo', foreign_key: :perm_repo_uid
|
||||||
|
|
||||||
|
def self.auto_create!(user, repo)
|
||||||
|
perm = new(
|
||||||
|
perm_user_id: user.user_id,
|
||||||
|
perm_repo_uid: repo.repo_id,
|
||||||
|
perm_read: true,
|
||||||
|
perm_write: true,
|
||||||
|
perm_admin: true,
|
||||||
|
perm_synced: 0,
|
||||||
|
perm_created: Time.now.to_i,
|
||||||
|
perm_updated: Time.now.to_i
|
||||||
|
)
|
||||||
|
perm.save!
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
class Ci::RemoteBase < Ci::Database
|
||||||
|
self.abstract_class = true
|
||||||
|
|
||||||
|
def generate_code
|
||||||
|
[*'a'..'z',*'0'..'9',*'A'..'Z'].sample(32).join
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,64 @@
|
||||||
|
class Ci::Repo < Ci::RemoteBase
|
||||||
|
self.primary_key = 'repo_id'
|
||||||
|
|
||||||
|
belongs_to :user, foreign_key: :repo_user_id
|
||||||
|
has_one :perm, foreign_key: :perm_repo_uid
|
||||||
|
has_many :builds, foreign_key: :build_repo_id, dependent: :destroy
|
||||||
|
|
||||||
|
def self.find_with_namespace(namespace_path, identifier)
|
||||||
|
logger.info "########namespace_path: #{namespace_path} ########identifier: #{identifier} "
|
||||||
|
|
||||||
|
user = Ci::User.find_by_user_login namespace_path
|
||||||
|
repo = Ci::Repo.where(repo_namespace: namespace_path, repo_name: identifier).first
|
||||||
|
|
||||||
|
[user, repo]
|
||||||
|
end
|
||||||
|
|
||||||
|
def activate!(ci_user_id)
|
||||||
|
update(repo_active: 1,
|
||||||
|
repo_signer: generate_code,
|
||||||
|
repo_secret: generate_code,
|
||||||
|
repo_user_id: ci_user_id,
|
||||||
|
repo_timeout: 60,
|
||||||
|
repo_config: '.trustie-pipeline.yml',
|
||||||
|
repo_updated: Time.now.to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.auto_create!(user, project)
|
||||||
|
repo = new(
|
||||||
|
repo_user_id: user.user_id,
|
||||||
|
repo_namespace: project.owner.login,
|
||||||
|
repo_name: project.identifier,
|
||||||
|
repo_slug: "#{project.owner.login}/#{project.identifier}",
|
||||||
|
repo_scm: "git",
|
||||||
|
repo_ssh_url: "",
|
||||||
|
repo_html_url: "",
|
||||||
|
repo_clone_url: project.repository.url,
|
||||||
|
repo_active: 1,
|
||||||
|
repo_private: true,
|
||||||
|
repo_visibility: 'private',
|
||||||
|
repo_branch: 'master',
|
||||||
|
repo_counter: 0,
|
||||||
|
repo_trusted: false,
|
||||||
|
repo_protected: false,
|
||||||
|
repo_synced: 0,
|
||||||
|
repo_version: 1,
|
||||||
|
repo_timeout: 60,
|
||||||
|
repo_config: '.trustie-pipeline.yml',
|
||||||
|
repo_created: Time.now.to_i,
|
||||||
|
repo_updated: Time.now.to_i
|
||||||
|
)
|
||||||
|
|
||||||
|
repo.repo_signer = repo.generate_code
|
||||||
|
repo.repo_secret = repo.generate_code
|
||||||
|
if repo.save!
|
||||||
|
Ci::Perm.auto_create!(user, repo)
|
||||||
|
repo.update_column(:repo_uid, repo.id)
|
||||||
|
repo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def deactivate!
|
||||||
|
update_column(:repo_active, 0)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,6 @@
|
||||||
|
class Ci::Stage < Ci::RemoteBase
|
||||||
|
self.primary_key = 'stage_id'
|
||||||
|
|
||||||
|
belongs_to :build, foreign_key: :stage_build_id
|
||||||
|
has_many :steps, foreign_key: "step_stage_id", dependent: :destroy
|
||||||
|
end
|
|
@ -0,0 +1,6 @@
|
||||||
|
class Ci::Step < Ci::RemoteBase
|
||||||
|
self.primary_key = 'step_id'
|
||||||
|
|
||||||
|
belongs_to :stage, foreign_key: :step_stage_id
|
||||||
|
has_one :log, class_name: 'Ci::Log', foreign_key: :log_id
|
||||||
|
end
|
|
@ -0,0 +1,68 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: users
|
||||||
|
#
|
||||||
|
# id :integer not null
|
||||||
|
# login :string(255) default(""), not null
|
||||||
|
# hashed_password :string(40) default(""), not null
|
||||||
|
# firstname :string(30) default(""), not null
|
||||||
|
# lastname :string(255) default(""), not null
|
||||||
|
# mail :string(60)
|
||||||
|
# admin :boolean default("0"), not null
|
||||||
|
# status :integer default("1"), not null
|
||||||
|
# last_login_on :datetime
|
||||||
|
# language :string(5) default("")
|
||||||
|
# auth_source_id :integer
|
||||||
|
# created_on :datetime
|
||||||
|
# updated_on :datetime
|
||||||
|
# type :string(255)
|
||||||
|
# identity_url :string(255)
|
||||||
|
# mail_notification :string(255) default(""), not null
|
||||||
|
# salt :string(64)
|
||||||
|
# gid :integer
|
||||||
|
# visits :integer default("0")
|
||||||
|
# excellent_teacher :integer default("0")
|
||||||
|
# excellent_student :integer default("0")
|
||||||
|
# phone :string(255)
|
||||||
|
# authentication :boolean default("0")
|
||||||
|
# grade :integer default("0")
|
||||||
|
# experience :integer default("0")
|
||||||
|
# nickname :string(255)
|
||||||
|
# show_realname :boolean default("1")
|
||||||
|
# professional_certification :boolean default("0")
|
||||||
|
# ID_number :string(255)
|
||||||
|
# certification :integer default("0")
|
||||||
|
# homepage_teacher :boolean default("0")
|
||||||
|
# homepage_engineer :boolean default("0")
|
||||||
|
# is_test :integer default("0")
|
||||||
|
# ecoder_user_id :integer default("0")
|
||||||
|
# business :boolean default("0")
|
||||||
|
# profile_completed :boolean default("0")
|
||||||
|
# laboratory_id :integer
|
||||||
|
# platform :string(255) default("0")
|
||||||
|
# gitea_token :string(255)
|
||||||
|
# gitea_uid :integer
|
||||||
|
# is_shixun_marker :boolean default("0")
|
||||||
|
# is_sync_pwd :boolean default("1")
|
||||||
|
# watchers_count :integer default("0")
|
||||||
|
# devops_step :integer default("0")
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_users_on_ecoder_user_id (ecoder_user_id)
|
||||||
|
# index_users_on_homepage_engineer (homepage_engineer)
|
||||||
|
# index_users_on_homepage_teacher (homepage_teacher)
|
||||||
|
# index_users_on_laboratory_id (laboratory_id)
|
||||||
|
# index_users_on_login (login)
|
||||||
|
# index_users_on_mail (mail)
|
||||||
|
# index_users_on_type (type)
|
||||||
|
#
|
||||||
|
|
||||||
|
class Ci::User < Ci::RemoteBase
|
||||||
|
self.primary_key = 'user_id'
|
||||||
|
|
||||||
|
has_many :repos, foreign_key: :repo_user_id, dependent: :destroy
|
||||||
|
has_many :perms, foreign_key: :perm_user_id, dependent: :delete_all
|
||||||
|
has_one :ci_cloud_account, class_name: 'Ci::CloudAccount', foreign_key: :ci_user_id
|
||||||
|
|
||||||
|
end
|
|
@ -1,3 +1,23 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: composes
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# title :string(255)
|
||||||
|
# description :text(65535)
|
||||||
|
# show_mode :integer default("0")
|
||||||
|
# compose_mode :boolean default("0")
|
||||||
|
# compose_users_count :integer default("0")
|
||||||
|
# compose_projects_count :integer default("0")
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_composes_on_user_id_and_show_mode_and_compose_mode (user_id,show_mode,compose_mode)
|
||||||
|
#
|
||||||
|
|
||||||
class Compose < ApplicationRecord
|
class Compose < ApplicationRecord
|
||||||
#组织
|
#组织
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: compose_projects
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# project_id :integer
|
||||||
|
# compose_id :integer
|
||||||
|
# position :integer default("0")
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_compose_projects_on_user_id_and_project_id_and_compose_id (user_id,project_id,compose_id)
|
||||||
|
#
|
||||||
|
|
||||||
class ComposeProject < ApplicationRecord
|
class ComposeProject < ApplicationRecord
|
||||||
#组织的项目记录表
|
#组织的项目记录表
|
||||||
belongs_to :compose
|
belongs_to :compose
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: compose_users
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# compose_id :integer
|
||||||
|
# is_manager :integer default("0")
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_compose_users_on_user_id_and_compose_id (user_id,compose_id)
|
||||||
|
#
|
||||||
|
|
||||||
class ComposeUser < ApplicationRecord
|
class ComposeUser < ApplicationRecord
|
||||||
belongs_to :compose
|
belongs_to :compose
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
module Droneable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
end
|
||||||
|
|
||||||
|
def devops_uninit?
|
||||||
|
self.devops_step === User::DEVOPS_UNINIT
|
||||||
|
end
|
||||||
|
|
||||||
|
def devops_unverified?
|
||||||
|
self.devops_step === User::DEVOPS_UNVERIFIED
|
||||||
|
end
|
||||||
|
|
||||||
|
def devops_certification?
|
||||||
|
self.devops_step === User::DEVOPS_CERTIFICATION
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_drone_step!(step)
|
||||||
|
self.update_column(:devops_step, step)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ci_certification?
|
||||||
|
return false if self.is_a?(AnonymousUser)
|
||||||
|
devops_certification? && Ci::User.exists?(user_login: self.login)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unbind_account!
|
||||||
|
user_projects = self.projects
|
||||||
|
|
||||||
|
user_projects.update_all(open_devops: false, open_devops_count: 0)
|
||||||
|
set_drone_step!(User::DEVOPS_UNINIT)
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
# 删除用户项目下的与ci相关的所有webhook
|
||||||
|
user_projects.select(:id, :identifier, :gitea_webhook_id).each do |project|
|
||||||
|
if project.gitea_webhook_id
|
||||||
|
result = Gitea::Hooks::DestroyService.call(self.gitea_token, self.login, project.identifier, project.gitea_webhook_id)
|
||||||
|
project.update_column(:gitea_webhook_id, nil) if result.status == 204
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,6 +5,7 @@ module Matchable
|
||||||
scope :with_project_category, ->(category_id) { where(project_category_id: category_id) unless category_id.blank? }
|
scope :with_project_category, ->(category_id) { where(project_category_id: category_id) unless category_id.blank? }
|
||||||
scope :with_project_language, ->(language_id) { where(project_language_id: language_id) unless language_id.blank? }
|
scope :with_project_language, ->(language_id) { where(project_language_id: language_id) unless language_id.blank? }
|
||||||
scope :with_project_type, ->(project_type) { where(project_type: project_type) if Project.project_types.include?(project_type) }
|
scope :with_project_type, ->(project_type) { where(project_type: project_type) if Project.project_types.include?(project_type) }
|
||||||
|
scope :by_name_or_identifier, ->(search) { where("name like :search or identifier LIKE :search", :search => "#{search.split(" ").join('|')}%") unless search.blank? }
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ module ProjectOperable
|
||||||
has_many :managers, -> { joins(:roles).where(roles: { name: 'Manager' }) }, class_name: 'Member'
|
has_many :managers, -> { joins(:roles).where(roles: { name: 'Manager' }) }, class_name: 'Member'
|
||||||
has_many :developers, -> { joins(:roles).where(roles: { name: 'Developer' }) }, class_name: 'Member'
|
has_many :developers, -> { joins(:roles).where(roles: { name: 'Developer' }) }, class_name: 'Member'
|
||||||
has_many :reporters, -> { joins(:roles).where(roles: { name: 'Reporter' }) }, class_name: 'Member'
|
has_many :reporters, -> { joins(:roles).where(roles: { name: 'Reporter' }) }, class_name: 'Member'
|
||||||
|
has_many :writable_members, -> { joins(:roles).where.not(roles: {name: 'Reporter'}) }, class_name: 'Member'
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_member!(user_id, role_name='Developer')
|
def add_member!(user_id, role_name='Developer')
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: coo_imgs
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# src_states :string(255)
|
||||||
|
# url_states :string(255)
|
||||||
|
# img_type :string(255)
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# position :integer
|
||||||
|
#
|
||||||
|
|
||||||
class CooImg < ApplicationRecord
|
class CooImg < ApplicationRecord
|
||||||
extend Enumerize
|
extend Enumerize
|
||||||
|
|
||||||
enumerize :img_type, in: %i[com_coop edu_coop alliance_coop]
|
enumerize :img_type, in: %i[com_coop edu_coop alliance_coop]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: diff_records
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# container_type :string(255)
|
||||||
|
# container_id :integer
|
||||||
|
# column_name :string(255)
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_diff_records_on_container_type_and_container_id (container_type,container_id)
|
||||||
|
# index_diff_records_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
|
||||||
class DiffRecord < ApplicationRecord
|
class DiffRecord < ApplicationRecord
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :container, polymorphic: true
|
belongs_to :container, polymorphic: true
|
||||||
|
@ -5,4 +23,4 @@ class DiffRecord < ApplicationRecord
|
||||||
has_one :diff_record_content, dependent: :destroy
|
has_one :diff_record_content, dependent: :destroy
|
||||||
|
|
||||||
delegate :content, to: :diff_record_content
|
delegate :content, to: :diff_record_content
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: diff_record_contents
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# diff_record_id :integer
|
||||||
|
# content :text(65535)
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_diff_record_contents_on_diff_record_id (diff_record_id)
|
||||||
|
#
|
||||||
|
|
||||||
class DiffRecordContent < ApplicationRecord
|
class DiffRecordContent < ApplicationRecord
|
||||||
belongs_to :diff_record
|
belongs_to :diff_record
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: edu_settings
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# name :string(255)
|
||||||
|
# value :string(255)
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# description :string(255)
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_edu_settings_on_name (name) UNIQUE
|
||||||
|
#
|
||||||
|
|
||||||
class EduSetting < ApplicationRecord
|
class EduSetting < ApplicationRecord
|
||||||
after_commit :expire_value_cache
|
after_commit :expire_value_cache
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,23 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: fork_users
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# project_id :integer
|
||||||
|
# fork_project_id :integer
|
||||||
|
# user_id :integer
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_fork_users_on_project_id (project_id)
|
||||||
|
# index_fork_users_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
|
||||||
class ForkUser < ApplicationRecord
|
class ForkUser < ApplicationRecord
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
belongs_to :fork_project, class_name: 'Project', foreign_key: :fork_project_id
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
class Gitea::Base < Gitea::Database
|
||||||
|
self.abstract_class = true
|
||||||
|
|
||||||
|
end
|
|
@ -1,3 +1,14 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: ignores
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# name :string(255)
|
||||||
|
# content :text(65535)
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
|
||||||
class Ignore < ApplicationRecord
|
class Ignore < ApplicationRecord
|
||||||
include Projectable
|
include Projectable
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,53 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: issues
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# tracker_id :integer not null
|
||||||
|
# project_id :integer not null
|
||||||
|
# subject :string(255) default(""), not null
|
||||||
|
# description :text(4294967295)
|
||||||
|
# due_date :date
|
||||||
|
# category_id :integer
|
||||||
|
# status_id :integer not null
|
||||||
|
# assigned_to_id :integer
|
||||||
|
# priority_id :integer not null
|
||||||
|
# fixed_version_id :integer
|
||||||
|
# author_id :integer not null
|
||||||
|
# created_on :datetime
|
||||||
|
# updated_on :datetime
|
||||||
|
# start_date :date
|
||||||
|
# done_ratio :integer default("0"), not null
|
||||||
|
# estimated_hours :float(24)
|
||||||
|
# parent_id :integer
|
||||||
|
# root_id :integer
|
||||||
|
# lft :integer
|
||||||
|
# rgt :integer
|
||||||
|
# is_private :boolean default("0"), not null
|
||||||
|
# closed_on :datetime
|
||||||
|
# project_issues_index :integer
|
||||||
|
# issue_type :string(255)
|
||||||
|
# token :integer default("0")
|
||||||
|
# issue_tags_value :string(255)
|
||||||
|
# is_lock :boolean default("0")
|
||||||
|
# issue_classify :string(255)
|
||||||
|
# ref_name :string(255)
|
||||||
|
# branch_name :string(255)
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_issues_on_assigned_to_id (assigned_to_id)
|
||||||
|
# index_issues_on_author_id (author_id)
|
||||||
|
# index_issues_on_category_id (category_id)
|
||||||
|
# index_issues_on_created_on (created_on)
|
||||||
|
# index_issues_on_fixed_version_id (fixed_version_id)
|
||||||
|
# index_issues_on_priority_id (priority_id)
|
||||||
|
# index_issues_on_root_id_and_lft_and_rgt (root_id,lft,rgt)
|
||||||
|
# index_issues_on_status_id (status_id)
|
||||||
|
# index_issues_on_tracker_id (tracker_id)
|
||||||
|
# issues_project_id (project_id)
|
||||||
|
#
|
||||||
|
|
||||||
class Issue < ApplicationRecord
|
class Issue < ApplicationRecord
|
||||||
#issue_type 1为普通,2为悬赏
|
#issue_type 1为普通,2为悬赏
|
||||||
include DunCheckAble
|
include DunCheckAble
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: issue_depends
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# issue_id :integer
|
||||||
|
# depend_issue_id :integer
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_issue_depends_on_user_id_and_issue_id_and_depend_issue_id (user_id,issue_id,depend_issue_id)
|
||||||
|
#
|
||||||
|
|
||||||
class IssueDepend < ApplicationRecord
|
class IssueDepend < ApplicationRecord
|
||||||
belongs_to :issue
|
belongs_to :issue
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: issue_priorities
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# name :string(255)
|
||||||
|
# position :integer
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_issue_priorities_on_name (name)
|
||||||
|
#
|
||||||
|
|
||||||
class IssuePriority < ApplicationRecord
|
class IssuePriority < ApplicationRecord
|
||||||
has_many :issues
|
has_many :issues
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,22 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: issue_statuses
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# name :string(30) default(""), not null
|
||||||
|
# is_closed :boolean default("0"), not null
|
||||||
|
# is_default :boolean default("0"), not null
|
||||||
|
# position :integer default("1")
|
||||||
|
# default_done_ratio :integer
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_issue_statuses_on_is_closed (is_closed)
|
||||||
|
# index_issue_statuses_on_is_default (is_default)
|
||||||
|
# index_issue_statuses_on_position (position)
|
||||||
|
#
|
||||||
|
|
||||||
class IssueStatus < ApplicationRecord
|
class IssueStatus < ApplicationRecord
|
||||||
has_many :issues
|
has_many :issues
|
||||||
belongs_to :project, optional: true
|
belongs_to :project, optional: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,24 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: issue_tags
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# name :string(255)
|
||||||
|
# description :string(255)
|
||||||
|
# color :string(255)
|
||||||
|
# user_id :integer
|
||||||
|
# project_id :integer
|
||||||
|
# issues_count :integer default("0")
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# gid :integer
|
||||||
|
# gitea_url :string(255)
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_issue_tags_on_user_id_and_name_and_project_id (user_id,name,project_id)
|
||||||
|
#
|
||||||
|
|
||||||
class IssueTag < ApplicationRecord
|
class IssueTag < ApplicationRecord
|
||||||
|
|
||||||
has_many :issue_tags_relates, dependent: :destroy
|
has_many :issue_tags_relates, dependent: :destroy
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: issue_tags_relates
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# issue_id :integer
|
||||||
|
# issue_tag_id :integer
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_issue_tags_relates_on_issue_id_and_issue_tag_id (issue_id,issue_tag_id)
|
||||||
|
#
|
||||||
|
|
||||||
class IssueTagsRelate < ApplicationRecord
|
class IssueTagsRelate < ApplicationRecord
|
||||||
belongs_to :issue
|
belongs_to :issue
|
||||||
belongs_to :issue_tag, counter_cache: :issues_count
|
belongs_to :issue_tag, counter_cache: :issues_count
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue