Merge branch 'master' into ci-and-ce-sitting-in-a-tree-k-i-s-s-i-n-g
This commit is contained in:
commit
843694f902
|
@ -21,7 +21,6 @@ config/aws.yml
|
|||
config/database.yml
|
||||
config/gitlab.yml
|
||||
config/gitlab_ci.yml
|
||||
config/initializers/omniauth.rb
|
||||
config/initializers/rack_attack.rb
|
||||
config/initializers/smtp_settings.rb
|
||||
config/resque.yml
|
||||
|
|
16
CHANGELOG
16
CHANGELOG
|
@ -1,7 +1,9 @@
|
|||
Please view this file on the master branch, on stable branches it's out of date.
|
||||
|
||||
v 8.0.0 (unreleased)
|
||||
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu)
|
||||
- Prevent too many redirects upon login when home page URL is set to external_url (Stan Hu)
|
||||
- Improve dropdown positioning on the project home page (Hannes Rosenögger)
|
||||
- Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibilty mode (Stan Hu)
|
||||
- Remove user OAuth tokens from the database and request new tokens each session (Stan Hu)
|
||||
- Only show recent push event if the branch still exists or a recent merge request has not been created (Stan Hu)
|
||||
- Remove satellites
|
||||
|
@ -13,6 +15,17 @@ v 8.0.0 (unreleased)
|
|||
- Search for comments should be case insensetive
|
||||
- Create cross-reference for closing references on commits pushed to non-default branches (Maël Valais)
|
||||
- Ability to search milestones
|
||||
- Gracefully handle SMTP user input errors (e.g. incorrect email addresses) to prevent Sidekiq retries (Stan Hu)
|
||||
- Move dashboard activity to separate page
|
||||
- Improve performance of git blame
|
||||
- Limit content width to 1200px for most of pages to improve readability on big screens
|
||||
|
||||
v 7.14.1
|
||||
- Improve abuse reports management from admin area
|
||||
- Fix "Reload with full diff" URL button in compare branch view (Stan Hu)
|
||||
- Only include base URL in OmniAuth full_host parameter (Stan Hu)
|
||||
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu)
|
||||
- Ability to enable SSL verification for Webhooks
|
||||
|
||||
v 7.14.0
|
||||
- Fix bug where non-project members of the target project could set labels on new merge requests.
|
||||
|
@ -298,6 +311,7 @@ v 7.11.0
|
|||
- Protect OmniAuth request phase against CSRF.
|
||||
- Don't send notifications to mentioned users that don't have access to the project in question.
|
||||
- Add search issues/MR by number
|
||||
- Change plots to bar graphs in commit statistics screen
|
||||
- Move snippets UI to fluid layout
|
||||
- Improve UI for sidebar. Increase separation between navigation and content
|
||||
- Improve new project command options (Ben Bodenmiller)
|
||||
|
|
4
Gemfile
4
Gemfile
|
@ -42,7 +42,7 @@ gem 'rqrcode-rails3', '~> 0.1.7'
|
|||
gem 'attr_encrypted', '~> 1.3.4'
|
||||
|
||||
# Browser detection
|
||||
gem "browser", '~> 0.8.0'
|
||||
gem "browser", '~> 1.0.0'
|
||||
|
||||
# Extracting information from a git repository
|
||||
# Provide access to Gitlab::Git library
|
||||
|
@ -285,7 +285,7 @@ gem "newrelic_rpm", '~> 3.9.4.245'
|
|||
|
||||
gem 'octokit', '~> 3.7.0'
|
||||
|
||||
gem "mail_room", "~> 0.4.0"
|
||||
gem "mail_room", "~> 0.4.1"
|
||||
|
||||
gem 'email_reply_parser', '~> 0.5.8'
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ GEM
|
|||
ruby_parser (~> 3.7.0)
|
||||
sass (~> 3.0)
|
||||
terminal-table (~> 1.4)
|
||||
browser (0.8.0)
|
||||
browser (1.0.0)
|
||||
builder (3.2.2)
|
||||
byebug (6.0.2)
|
||||
cal-heatmap-rails (0.0.1)
|
||||
|
@ -388,7 +388,7 @@ GEM
|
|||
systemu (~> 2.6.2)
|
||||
mail (2.6.3)
|
||||
mime-types (>= 1.16, < 3)
|
||||
mail_room (0.4.0)
|
||||
mail_room (0.4.1)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mimemagic (0.3.0)
|
||||
|
@ -790,7 +790,7 @@ DEPENDENCIES
|
|||
binding_of_caller (~> 0.7.2)
|
||||
bootstrap-sass (~> 3.0)
|
||||
brakeman
|
||||
browser (~> 0.8.0)
|
||||
browser (~> 1.0.0)
|
||||
byebug
|
||||
cal-heatmap-rails (~> 0.0.1)
|
||||
capybara (~> 2.4.0)
|
||||
|
@ -846,7 +846,7 @@ DEPENDENCIES
|
|||
jquery-ui-rails (~> 4.2.1)
|
||||
kaminari (~> 0.15.1)
|
||||
letter_opener (~> 1.1.2)
|
||||
mail_room (~> 0.4.0)
|
||||
mail_room (~> 0.4.1)
|
||||
minitest (~> 5.7.0)
|
||||
mousetrap-rails (~> 1.4.6)
|
||||
mysql2 (~> 0.3.16)
|
||||
|
|
|
@ -116,6 +116,12 @@ $ ->
|
|||
$('.remove-row').bind 'ajax:success', ->
|
||||
$(this).closest('li').fadeOut()
|
||||
|
||||
$('.js-remove-tr').bind 'ajax:before', ->
|
||||
$(this).hide()
|
||||
|
||||
$('.js-remove-tr').bind 'ajax:success', ->
|
||||
$(this).closest('tr').fadeOut()
|
||||
|
||||
# Initialize select2 selects
|
||||
$('select.select2').select2(width: 'resolve', dropdownAutoWidth: true)
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ class Dispatcher
|
|||
MergeRequests.init()
|
||||
when 'dashboard:show', 'root:show'
|
||||
new Dashboard()
|
||||
when 'dashboard:activity'
|
||||
new Activities()
|
||||
when 'dashboard:projects:starred'
|
||||
new Activities()
|
||||
|
|
|
@ -8,7 +8,7 @@ class @ProjectsList
|
|||
|
||||
$(".projects-list-filter").keyup ->
|
||||
terms = $(this).val()
|
||||
uiBox = $(this).closest('.panel')
|
||||
uiBox = $(this).closest('.projects-list-holder')
|
||||
if terms == "" || terms == undefined
|
||||
uiBox.find(".projects-list li").show()
|
||||
else
|
||||
|
|
|
@ -20,3 +20,8 @@ html {
|
|||
.navless-container {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
|
||||
.container-limited {
|
||||
max-width: $fixed-layout-width;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ $code_line_height: 1.5;
|
|||
$border-color: #E5E5E5;
|
||||
$background-color: #f5f5f5;
|
||||
$header-height: 50px;
|
||||
$readable-width: 1100px;
|
||||
$fixed-layout-width: 1200px;
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -20,16 +20,16 @@ header {
|
|||
}
|
||||
|
||||
&.navbar-gitlab {
|
||||
padding: 0 20px;
|
||||
z-index: 100;
|
||||
margin-bottom: 0;
|
||||
min-height: $header-height;
|
||||
border: none;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #EEE;
|
||||
|
||||
.container {
|
||||
.container-fluid {
|
||||
background: #FFF;
|
||||
width: 100% !important;
|
||||
padding: 0;
|
||||
filter: none;
|
||||
|
||||
.nav > li > a {
|
||||
|
@ -64,55 +64,11 @@ header {
|
|||
}
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
border-bottom: 1px solid transparent;
|
||||
float: left;
|
||||
height: $header-height;
|
||||
width: $sidebar_width;
|
||||
overflow: hidden;
|
||||
transition-duration: .3s;
|
||||
|
||||
a {
|
||||
float: left;
|
||||
height: $header-height;
|
||||
width: 100%;
|
||||
padding: ($header-height - 36 ) / 2 8px;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.gitlab-text-container {
|
||||
width: 230px;
|
||||
|
||||
h3 {
|
||||
width: 158px;
|
||||
float: left;
|
||||
margin: 0;
|
||||
margin-left: 14px;
|
||||
font-size: 18px;
|
||||
line-height: $header-height - 14;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #EEE;
|
||||
}
|
||||
}
|
||||
|
||||
.header-content {
|
||||
border-bottom: 1px solid #EEE;
|
||||
padding-right: 35px;
|
||||
height: $header-height;
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
padding: 0 15px 0 35px;
|
||||
overflow: hidden;
|
||||
font-size: 18px;
|
||||
line-height: $header-height;
|
||||
|
@ -168,15 +124,7 @@ header {
|
|||
}
|
||||
|
||||
@mixin collapsed-header {
|
||||
.header-logo {
|
||||
width: $sidebar_collapsed_width;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
.title {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
margin-left: $sidebar_collapsed_width;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-md-max) {
|
||||
|
@ -191,16 +139,14 @@ header {
|
|||
}
|
||||
|
||||
.header-expanded {
|
||||
margin-left: $sidebar_width;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
header .container {
|
||||
header .container-fluid {
|
||||
font-size: 18px;
|
||||
|
||||
.title {
|
||||
}
|
||||
|
||||
.navbar-nav {
|
||||
margin: 0px;
|
||||
float: none !important;
|
||||
|
|
|
@ -188,3 +188,46 @@
|
|||
width: $sidebar_width - 2 * 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-wrapper {
|
||||
.header-logo {
|
||||
border-bottom: 1px solid transparent;
|
||||
float: left;
|
||||
height: $header-height;
|
||||
width: $sidebar_width;
|
||||
overflow: hidden;
|
||||
transition-duration: .3s;
|
||||
|
||||
a {
|
||||
float: left;
|
||||
height: $header-height;
|
||||
width: 100%;
|
||||
padding: ($header-height - 36 ) / 2 8px;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.gitlab-text-container {
|
||||
width: 230px;
|
||||
|
||||
h3 {
|
||||
width: 158px;
|
||||
float: left;
|
||||
margin: 0;
|
||||
margin-left: 14px;
|
||||
font-size: 18px;
|
||||
line-height: $header-height - 14;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #EEE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,41 +23,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.project-row, .group-row {
|
||||
padding: 0 !important;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 8px 15px;
|
||||
}
|
||||
|
||||
.project-name, .group-name {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
float: right;
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.last-activity {
|
||||
float: right;
|
||||
font-size: 12px;
|
||||
color: #AAA;
|
||||
display: block;
|
||||
.date {
|
||||
color: #777;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.project-description {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.project-access-icon {
|
||||
margin-left: 10px;
|
||||
float: left;
|
||||
|
@ -73,10 +38,9 @@
|
|||
float: left;
|
||||
|
||||
.avatar {
|
||||
margin-top: -8px;
|
||||
margin-left: -15px;
|
||||
@include border-radius(0px);
|
||||
}
|
||||
|
||||
.identicon {
|
||||
line-height: 40px;
|
||||
}
|
||||
|
|
|
@ -45,9 +45,3 @@
|
|||
|
||||
.btn { font-size: 13px; }
|
||||
}
|
||||
|
||||
.issuable-details {
|
||||
.description {
|
||||
max-width: $readable-width;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,14 +30,21 @@
|
|||
}
|
||||
}
|
||||
|
||||
.project-home-dropdown {
|
||||
margin: 11px 3px 0;
|
||||
}
|
||||
|
||||
.project-home-desc {
|
||||
h1 {
|
||||
margin: 0;
|
||||
margin-bottom: 10px;
|
||||
font-size: 26px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 18px;
|
||||
color: #666;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
@ -316,3 +323,34 @@ table.table.protected-branches-list tr.no-border {
|
|||
pre.light-well {
|
||||
border-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.projects-search-form {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 20px;
|
||||
|
||||
input {
|
||||
border-color: #BBB;
|
||||
}
|
||||
}
|
||||
|
||||
.project-row {
|
||||
.project-full-name {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.project-description {
|
||||
color: #888;
|
||||
font-size: 13px;
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.my-projects .project-row {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
|
|
@ -117,7 +117,6 @@
|
|||
|
||||
.readme-holder {
|
||||
margin: 0 auto;
|
||||
max-width: $readable-width;
|
||||
|
||||
.readme-file-title {
|
||||
font-size: 14px;
|
||||
|
|
|
@ -7,27 +7,23 @@
|
|||
* $color-dark -
|
||||
*/
|
||||
@mixin gitlab-theme($color-light, $color, $color-darker, $color-dark) {
|
||||
header {
|
||||
&.navbar-gitlab {
|
||||
.header-logo {
|
||||
background-color: $color-darker;
|
||||
border-color: $color-darker;
|
||||
.page-with-sidebar {
|
||||
.header-logo {
|
||||
background-color: $color-darker;
|
||||
border-color: $color-darker;
|
||||
|
||||
a {
|
||||
color: $color-light;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-dark;
|
||||
a {
|
||||
color: $color-light;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-dark;
|
||||
a {
|
||||
color: #FFF;
|
||||
}
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-with-sidebar {
|
||||
.collapse-nav a {
|
||||
color: #FFF;
|
||||
background: $color;
|
||||
|
|
|
@ -4,8 +4,13 @@ class Admin::AbuseReportsController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
AbuseReport.find(params[:id]).destroy
|
||||
abuse_report = AbuseReport.find(params[:id])
|
||||
|
||||
redirect_to admin_abuse_reports_path, notice: 'Report was removed'
|
||||
if params[:remove_user]
|
||||
abuse_report.user.destroy
|
||||
end
|
||||
|
||||
abuse_report.destroy
|
||||
render nothing: true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,6 +39,6 @@ class Admin::HooksController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def hook_params
|
||||
params.require(:hook).permit(:url)
|
||||
params.require(:hook).permit(:url, :enable_ssl_verification)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -59,7 +59,9 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def authenticate_user!(*args)
|
||||
# If user is not signed-in and tries to access root_path - redirect him to landing page
|
||||
if current_application_settings.home_page_url.present?
|
||||
# Don't redirect to the default URL to prevent endless redirections
|
||||
if current_application_settings.home_page_url.present? &&
|
||||
current_application_settings.home_page_url.chomp('/') != Gitlab.config.gitlab['url'].chomp('/')
|
||||
if current_user.nil? && root_path == request.path
|
||||
redirect_to current_application_settings.home_page_url and return
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class DashboardController < Dashboard::ApplicationController
|
||||
before_action :load_projects
|
||||
before_action :event_filter, only: :show
|
||||
before_action :event_filter, only: :activity
|
||||
|
||||
respond_to :html
|
||||
|
||||
|
@ -10,13 +10,8 @@ class DashboardController < Dashboard::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
||||
format.json do
|
||||
load_events
|
||||
pager_json("events/_events", @events.count)
|
||||
end
|
||||
|
||||
format.atom do
|
||||
event_filter
|
||||
load_events
|
||||
render layout: false
|
||||
end
|
||||
|
@ -40,6 +35,19 @@ class DashboardController < Dashboard::ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def activity
|
||||
@last_push = current_user.recent_push
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
||||
format.json do
|
||||
load_events
|
||||
pager_json("events/_events", @events.count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def load_projects
|
||||
|
|
|
@ -53,6 +53,7 @@ class Projects::HooksController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def hook_params
|
||||
params.require(:hook).permit(:url, :push_events, :issues_events, :merge_requests_events, :tag_push_events, :note_events)
|
||||
params.require(:hook).permit(:url, :push_events, :issues_events,
|
||||
:merge_requests_events, :tag_push_events, :note_events, :enable_ssl_verification)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ class Projects::ServicesController < Projects::ApplicationController
|
|||
:push_events, :issues_events, :merge_requests_events, :tag_push_events,
|
||||
:note_events, :send_from_committer_email, :disable_diffs, :external_wiki_url,
|
||||
:notify, :color,
|
||||
:server_host, :server_port, :default_irc_uri]
|
||||
:server_host, :server_port, :default_irc_uri, :enable_ssl_verification]
|
||||
# Authorize
|
||||
before_action :authorize_admin_project!
|
||||
before_action :service, only: [:edit, :update, :test]
|
||||
|
|
|
@ -24,5 +24,14 @@ module Gitlab
|
|||
@sidebar
|
||||
end
|
||||
end
|
||||
|
||||
def fluid_layout(enabled = false)
|
||||
if @fluid_layout.nil?
|
||||
@fluid_layout = enabled
|
||||
else
|
||||
@fluid_layout
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
module PageLayoutHelper
|
||||
def page_title(*titles)
|
||||
@page_title ||= []
|
||||
|
||||
@page_title.push(*titles.compact) if titles.any?
|
||||
|
||||
@page_title.join(" | ")
|
||||
end
|
||||
|
||||
def header_title(title = nil, title_url = nil)
|
||||
if title
|
||||
@header_title = title
|
||||
@header_title_url = title_url
|
||||
else
|
||||
@header_title_url ? link_to(@header_title, @header_title_url) : @header_title
|
||||
end
|
||||
end
|
||||
|
||||
def sidebar(name = nil)
|
||||
if name
|
||||
@sidebar = name
|
||||
else
|
||||
@sidebar
|
||||
end
|
||||
end
|
||||
|
||||
def fluid_layout(enabled = false)
|
||||
if @fluid_layout.nil?
|
||||
@fluid_layout = enabled
|
||||
else
|
||||
@fluid_layout
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,6 +3,8 @@ class EmailRejectionMailer < BaseMailer
|
|||
@reason = reason
|
||||
@original_message = Mail::Message.new(original_raw)
|
||||
|
||||
return unless @original_message.from
|
||||
|
||||
headers = {
|
||||
to: @original_message.from,
|
||||
subject: "[Rejected] #{@original_message.subject}"
|
||||
|
|
|
@ -25,6 +25,7 @@ class WebHook < ActiveRecord::Base
|
|||
default_value_for :note_events, false
|
||||
default_value_for :merge_requests_events, false
|
||||
default_value_for :tag_push_events, false
|
||||
default_value_for :enable_ssl_verification, false
|
||||
|
||||
# HTTParty timeout
|
||||
default_timeout Gitlab.config.gitlab.webhook_timeout
|
||||
|
@ -41,7 +42,7 @@ class WebHook < ActiveRecord::Base
|
|||
"Content-Type" => "application/json",
|
||||
"X-Gitlab-Event" => hook_name.singularize.titleize
|
||||
},
|
||||
verify: false)
|
||||
verify: enable_ssl_verification)
|
||||
else
|
||||
post_url = url.gsub("#{parsed_url.userinfo}@", "")
|
||||
auth = {
|
||||
|
@ -54,7 +55,7 @@ class WebHook < ActiveRecord::Base
|
|||
"Content-Type" => "application/json",
|
||||
"X-Gitlab-Event" => hook_name.singularize.titleize
|
||||
},
|
||||
verify: false,
|
||||
verify: enable_ssl_verification,
|
||||
basic_auth: auth)
|
||||
end
|
||||
rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e
|
||||
|
|
|
@ -23,7 +23,7 @@ require "addressable/uri"
|
|||
class BuildkiteService < CiService
|
||||
ENDPOINT = "https://buildkite.com"
|
||||
|
||||
prop_accessor :project_url, :token
|
||||
prop_accessor :project_url, :token, :enable_ssl_verification
|
||||
|
||||
validates :project_url, presence: true, if: :activated?
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
@ -37,6 +37,7 @@ class BuildkiteService < CiService
|
|||
def compose_service_hook
|
||||
hook = service_hook || build_service_hook
|
||||
hook.url = webhook_url
|
||||
hook.enable_ssl_verification = enable_ssl_verification
|
||||
hook.save
|
||||
end
|
||||
|
||||
|
@ -96,7 +97,11 @@ class BuildkiteService < CiService
|
|||
|
||||
{ type: 'text',
|
||||
name: 'project_url',
|
||||
placeholder: "#{ENDPOINT}/example/project" }
|
||||
placeholder: "#{ENDPOINT}/example/project" },
|
||||
|
||||
{ type: 'checkbox',
|
||||
name: 'enable_ssl_verification',
|
||||
title: "Enable SSL verification" }
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
class GitlabCiService < CiService
|
||||
API_PREFIX = "api/v1"
|
||||
|
||||
prop_accessor :project_url, :token
|
||||
prop_accessor :project_url, :token, :enable_ssl_verification
|
||||
validates :project_url,
|
||||
presence: true,
|
||||
format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated?
|
||||
|
@ -34,6 +34,7 @@ class GitlabCiService < CiService
|
|||
def compose_service_hook
|
||||
hook = service_hook || build_service_hook
|
||||
hook.url = [project_url, "/build", "?token=#{token}"].join("")
|
||||
hook.enable_ssl_verification = enable_ssl_verification
|
||||
hook.save
|
||||
end
|
||||
|
||||
|
@ -136,7 +137,8 @@ class GitlabCiService < CiService
|
|||
def fields
|
||||
[
|
||||
{ type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' },
|
||||
{ type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' }
|
||||
{ type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' },
|
||||
{ type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
%tr
|
||||
%td
|
||||
- if reporter
|
||||
= link_to reporter.name, [:admin, reporter]
|
||||
= link_to reporter.name, reporter
|
||||
- else
|
||||
(removed)
|
||||
%td
|
||||
|
@ -12,12 +12,15 @@
|
|||
= abuse_report.message
|
||||
%td
|
||||
- if user
|
||||
= link_to user.name, [:admin, user]
|
||||
= link_to user.name, user
|
||||
- else
|
||||
(removed)
|
||||
%td
|
||||
- if user
|
||||
= link_to 'Block', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs btn-warning"
|
||||
= link_to 'Remove user', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, method: :delete, class: "btn btn-xs btn-remove"
|
||||
= link_to 'Remove user & report', admin_abuse_report_path(abuse_report, remove_user: true),
|
||||
data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, remote: true, method: :delete, class: "btn btn-xs btn-remove js-remove-tr"
|
||||
|
||||
%td
|
||||
= link_to 'Remove report', [:admin, abuse_report], method: :delete, class: "btn btn-xs btn-close"
|
||||
- if user
|
||||
= link_to 'Block user', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs"
|
||||
= link_to 'Remove report', [:admin, abuse_report], remote: true, method: :delete, class: "btn btn-xs btn-close js-remove-tr"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
%th Reported at
|
||||
%th Message
|
||||
%th User
|
||||
%th
|
||||
%th Primary action
|
||||
%th
|
||||
= render @abuse_reports
|
||||
= paginate @abuse_reports
|
||||
|
|
|
@ -18,6 +18,13 @@
|
|||
= f.label :url, "URL:", class: 'control-label'
|
||||
.col-sm-10
|
||||
= f.text_field :url, class: "form-control"
|
||||
.form-group
|
||||
= f.label :enable_ssl_verification, "SSL verification", class: 'control-label checkbox'
|
||||
.col-sm-10
|
||||
.checkbox
|
||||
= f.label :enable_ssl_verification do
|
||||
= f.check_box :enable_ssl_verification
|
||||
%strong Enable SSL verification
|
||||
.form-actions
|
||||
= f.submit "Add System Hook", class: "btn btn-create"
|
||||
%hr
|
||||
|
@ -32,6 +39,7 @@
|
|||
.list-item-name
|
||||
= link_to admin_hook_path(hook) do
|
||||
%strong= hook.url
|
||||
%p SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"}
|
||||
|
||||
.pull-right
|
||||
= link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.panel.panel-default
|
||||
.panel-heading.clearfix
|
||||
.projects-list-holder
|
||||
.projects-search-form
|
||||
.input-group
|
||||
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
|
||||
- if current_user.can_create_project?
|
||||
|
@ -7,4 +7,7 @@
|
|||
= link_to new_project_path, class: 'btn btn-success' do
|
||||
New project
|
||||
|
||||
= render 'shared/projects_list', projects: @projects, projects_limit: 20
|
||||
%ul.projects-list.bordered-list.my-projects
|
||||
- @projects.each do |project|
|
||||
%li.project-row
|
||||
= render partial: 'shared/project', locals: { project: project, avatar: true, stars: true }
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
= content_for :meta_tags do
|
||||
- if current_user
|
||||
= auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity")
|
||||
|
||||
%section.activities
|
||||
= render 'activities'
|
|
@ -5,10 +5,10 @@
|
|||
= render 'shared/show_aside'
|
||||
|
||||
.dashboard.row
|
||||
%section.activities.col-md-8
|
||||
%section.activities.col-md-7
|
||||
= render 'dashboard/activities'
|
||||
%aside.col-md-4
|
||||
.panel.panel-default
|
||||
%aside.col-md-5
|
||||
.panel.panel-default.projects-list-holder
|
||||
.panel-heading.clearfix
|
||||
.input-group
|
||||
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
|
||||
|
|
|
@ -4,14 +4,10 @@
|
|||
|
||||
= render 'dashboard/projects_head'
|
||||
|
||||
- if @last_push
|
||||
= render "events/event_last_push", event: @last_push
|
||||
|
||||
- if @projects.any?
|
||||
= render 'shared/show_aside'
|
||||
|
||||
.dashboard.row
|
||||
%section.activities.col-md-8
|
||||
= render 'activities'
|
||||
%aside.col-md-4
|
||||
= render 'sidebar'
|
||||
|
||||
= render 'projects'
|
||||
- else
|
||||
= render "zero_authorized_projects"
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
#{time_ago_with_tooltip(event.created_at)}
|
||||
|
||||
.pull-right
|
||||
= link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-sm" do
|
||||
= link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-info btn-sm" do
|
||||
Create Merge Request
|
||||
%hr
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
%li
|
||||
%h4.project-title
|
||||
.project-access-icon
|
||||
= visibility_level_icon(project.visibility_level)
|
||||
= link_to project.name_with_namespace, [project.namespace.becomes(Namespace), project]
|
||||
%span.pull-right
|
||||
%i.fa.fa-star
|
||||
= project.star_count
|
||||
|
||||
.project-info
|
||||
- if project.description.present?
|
||||
.project-description.str-truncated
|
||||
= markdown(project.description, pipeline: :description)
|
||||
|
||||
.repo-info
|
||||
- unless project.empty_repo?
|
||||
= link_to pluralize(round_commit_count(project), 'commit'), namespace_project_commits_path(project.namespace, project, project.default_branch)
|
||||
·
|
||||
= link_to pluralize(project.repository.branch_names.count, 'branch'), namespace_project_branches_path(project.namespace, project)
|
||||
·
|
||||
= link_to pluralize(project.repository.tag_names.count, 'tag'), namespace_project_tags_path(project.namespace, project)
|
||||
- else
|
||||
%i.fa.fa-exclamation-triangle
|
||||
Empty repository
|
|
@ -0,0 +1,6 @@
|
|||
%ul.projects-list.bordered-list.my-projects.public-projects
|
||||
- projects.each do |project|
|
||||
%li.project-row
|
||||
= render partial: 'shared/project', locals: { project: project, avatar: true, stars: true }
|
||||
- unless projects.present?
|
||||
.nothing-here-block No such projects
|
|
@ -4,10 +4,5 @@
|
|||
.clearfix
|
||||
= render 'filter'
|
||||
%br
|
||||
.public-projects
|
||||
%ul.bordered-list.top-list
|
||||
= render @projects
|
||||
- unless @projects.present?
|
||||
.nothing-here-block No public projects
|
||||
|
||||
= paginate @projects, theme: "gitlab"
|
||||
= render 'projects', projects: @projects
|
||||
= paginate @projects, theme: "gitlab"
|
||||
|
|
|
@ -7,8 +7,5 @@
|
|||
See most starred projects
|
||||
.pull-right
|
||||
= render 'explore/projects/dropdown'
|
||||
.public-projects
|
||||
%ul.bordered-list
|
||||
= render @starred_projects
|
||||
|
||||
= render 'projects', projects: @starred_projects
|
||||
= paginate @starred_projects, theme: 'gitlab'
|
||||
|
|
|
@ -13,6 +13,4 @@
|
|||
See most discussed projects for last month
|
||||
.pull-right
|
||||
= render 'explore/projects/dropdown'
|
||||
.public-projects
|
||||
%ul.bordered-list
|
||||
= render @trending_projects
|
||||
= render 'projects', projects: @trending_projects
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.panel.panel-default
|
||||
.panel.panel-default.projects-list-holder
|
||||
.panel-heading.clearfix
|
||||
.input-group
|
||||
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
= render 'shared/show_aside'
|
||||
|
||||
.row
|
||||
%section.activities.col-md-8
|
||||
%section.activities.col-md-7
|
||||
.hidden-xs
|
||||
- if current_user
|
||||
= render "events/event_last_push", event: @last_push
|
||||
|
@ -33,5 +33,5 @@
|
|||
|
||||
.content_list
|
||||
= spinner
|
||||
%aside.side.col-md-4
|
||||
%aside.side.col-md-5
|
||||
= render "projects", projects: @projects
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
.page-with-sidebar{ class: nav_sidebar_class }
|
||||
= render "layouts/broadcast"
|
||||
.sidebar-wrapper.nicescroll
|
||||
.header-logo
|
||||
= link_to root_path, class: 'home', title: 'Dashboard', id: 'js-shortcuts-home', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
= brand_header_logo
|
||||
.gitlab-text-container
|
||||
%h3 GitLab
|
||||
- if defined?(sidebar) && sidebar
|
||||
= render "layouts/nav/#{sidebar}"
|
||||
- elsif current_user
|
||||
|
@ -13,7 +18,7 @@
|
|||
.username
|
||||
= current_user.username
|
||||
.content-wrapper
|
||||
.container-fluid
|
||||
%div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" }
|
||||
.content
|
||||
= render "layouts/flash"
|
||||
.clearfix
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
%header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class }
|
||||
.container
|
||||
.header-logo
|
||||
= link_to root_path, class: 'home', title: 'Dashboard', id: 'js-shortcuts-home', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
= brand_header_logo
|
||||
.gitlab-text-container
|
||||
%h3 GitLab
|
||||
%div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" }
|
||||
.header-content
|
||||
%button.navbar-toggle{type: 'button'}
|
||||
%span.sr-only Toggle navigation
|
||||
|
@ -17,15 +12,6 @@
|
|||
%li.visible-sm.visible-xs
|
||||
= link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
= icon('search')
|
||||
-#%li.hidden-xs
|
||||
= link_to help_path, title: 'Help', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
= icon('question-circle fw')
|
||||
-#%li
|
||||
= link_to explore_root_path, title: 'Explore', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
= icon('globe fw')
|
||||
-#%li
|
||||
= link_to user_snippets_path(current_user), title: 'Your snippets', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
= icon('clipboard fw')
|
||||
- if current_user.is_admin?
|
||||
%li
|
||||
= link_to admin_root_path, title: 'Admin area', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
|
@ -34,9 +20,6 @@
|
|||
%li.hidden-xs
|
||||
= link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
= icon('plus fw')
|
||||
-#%li
|
||||
= link_to profile_path, title: 'Profile settings', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
= icon('cog fw')
|
||||
%li
|
||||
= link_to destroy_user_session_path, class: 'logout', method: :delete, title: 'Sign out', data: {toggle: 'tooltip', placement: 'bottom'} do
|
||||
= icon('sign-out')
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
%header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class }
|
||||
.container
|
||||
.header-logo
|
||||
= link_to explore_root_path, class: "home" do
|
||||
= brand_header_logo
|
||||
.gitlab-text-container
|
||||
%h3 GitLab
|
||||
%div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" }
|
||||
.header-content
|
||||
- unless current_controller?('sessions')
|
||||
.pull-right
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
%ul.nav.nav-sidebar
|
||||
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
|
||||
= link_to (current_user ? root_path : explore_root_path), title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do
|
||||
= icon('dashboard fw')
|
||||
= icon('home fw')
|
||||
%span
|
||||
Projects
|
||||
= nav_link(path: 'dashboard#activity') do
|
||||
= link_to activity_dashboard_path, title: 'Activity', data: {placement: 'right'} do
|
||||
= icon('dashboard fw')
|
||||
%span
|
||||
Activity
|
||||
= nav_link(controller: :groups) do
|
||||
= link_to (current_user ? dashboard_groups_path : explore_groups_path), title: 'Groups', data: {placement: 'right'} do
|
||||
= icon('group fw')
|
||||
|
@ -29,7 +34,7 @@
|
|||
%span.count= current_user.assigned_merge_requests.opened.count
|
||||
= nav_link(controller: :snippets) do
|
||||
= link_to (current_user ? user_snippets_path(current_user) : snippets_path), title: 'Your snippets', data: {placement: 'right'} do
|
||||
= icon('dashboard fw')
|
||||
= icon('clipboard fw')
|
||||
%span
|
||||
Snippets
|
||||
- if current_user
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
.project-home-panel.clearfix{:class => ("empty-project" if empty_repo)}
|
||||
.project-identicon-holder
|
||||
= project_icon(@project, alt: '', class: 'project-avatar avatar s90')
|
||||
.project-home-desc.lead
|
||||
.project-home-desc
|
||||
%h1= @project.name
|
||||
- if @project.description.present?
|
||||
= markdown(@project.description, pipeline: :description)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
.light
|
||||
= commit_author_link(commit, avatar: false)
|
||||
authored
|
||||
#{time_ago_with_tooltip(commit.committed_date)}
|
||||
#{time_ago_with_tooltip(commit.committed_date, skip_js: true)}
|
||||
%td.lines.blame-numbers
|
||||
%pre
|
||||
- line_count = blame_group[:lines].count
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
%span.dropdown
|
||||
%a.dropdown-toggle.btn.btn-new{href: '#', "data-toggle" => "dropdown"}
|
||||
= icon('plus')
|
||||
%ul.dropdown-menu
|
||||
%ul.dropdown-menu.dropdown-menu-right.project-home-dropdown
|
||||
- if can?(current_user, :create_issue, @project)
|
||||
%li
|
||||
= link_to url_for_new_issue do
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
- page_title "Deploy Keys"
|
||||
|
||||
%h3.page-title
|
||||
Deploy keys allow read-only access to the repository
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
- if params[:view] == 'parallel'
|
||||
- fluid_layout true
|
||||
|
||||
.prepend-top-20.append-bottom-20
|
||||
.pull-right
|
||||
.btn-group
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Too many changes to show.
|
||||
.pull-right
|
||||
- unless diff_hard_limit_enabled?
|
||||
= link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: :html)), class: "btn btn-sm btn-warning"
|
||||
= link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: nil)), class: "btn btn-sm btn-warning"
|
||||
|
||||
- if current_controller?(:commit) or current_controller?(:merge_requests)
|
||||
- if current_controller?(:commit)
|
||||
|
|
|
@ -50,39 +50,42 @@
|
|||
datasets : [{
|
||||
fillColor : "rgba(220,220,220,0.5)",
|
||||
strokeColor : "rgba(220,220,220,1)",
|
||||
pointColor : "rgba(220,220,220,1)",
|
||||
pointStrokeColor : "#EEE",
|
||||
barStrokeWidth: 1,
|
||||
barValueSpacing: 1,
|
||||
barDatasetSpacing: 1,
|
||||
data : #{@commits_per_time.values.to_json}
|
||||
}]
|
||||
}
|
||||
|
||||
ctx = $("#hour-chart").get(0).getContext("2d");
|
||||
new Chart(ctx).Line(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2})
|
||||
new Chart(ctx).Bar(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2})
|
||||
|
||||
data = {
|
||||
labels : #{@commits_per_week_days.keys.to_json},
|
||||
datasets : [{
|
||||
fillColor : "rgba(220,220,220,0.5)",
|
||||
strokeColor : "rgba(220,220,220,1)",
|
||||
pointColor : "rgba(220,220,220,1)",
|
||||
pointStrokeColor : "#EEE",
|
||||
barStrokeWidth: 1,
|
||||
barValueSpacing: 1,
|
||||
barDatasetSpacing: 1,
|
||||
data : #{@commits_per_week_days.values.to_json}
|
||||
}]
|
||||
}
|
||||
|
||||
ctx = $("#weekday-chart").get(0).getContext("2d");
|
||||
new Chart(ctx).Line(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2})
|
||||
new Chart(ctx).Bar(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2})
|
||||
|
||||
data = {
|
||||
labels : #{@commits_per_month.keys.to_json},
|
||||
datasets : [{
|
||||
fillColor : "rgba(220,220,220,0.5)",
|
||||
strokeColor : "rgba(220,220,220,1)",
|
||||
pointColor : "rgba(220,220,220,1)",
|
||||
pointStrokeColor : "#EEE",
|
||||
barStrokeWidth: 1,
|
||||
barValueSpacing: 1,
|
||||
barDatasetSpacing: 1,
|
||||
data : #{@commits_per_month.values.to_json}
|
||||
}]
|
||||
}
|
||||
|
||||
ctx = $("#month-chart").get(0).getContext("2d");
|
||||
new Chart(ctx).Line(data, {"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2})
|
||||
new Chart(ctx).Bar(data, {"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2})
|
||||
|
|
|
@ -55,6 +55,13 @@
|
|||
%strong Merge Request events
|
||||
%p.light
|
||||
This url will be triggered when a merge request is created
|
||||
.form-group
|
||||
= f.label :enable_ssl_verification, "SSL verification", class: 'control-label checkbox'
|
||||
.col-sm-10
|
||||
.checkbox
|
||||
= f.label :enable_ssl_verification do
|
||||
= f.check_box :enable_ssl_verification
|
||||
%strong Enable SSL verification
|
||||
.form-actions
|
||||
= f.submit "Add Web Hook", class: "btn btn-create"
|
||||
|
||||
|
@ -74,3 +81,4 @@
|
|||
- %w(push_events tag_push_events issues_events note_events merge_requests_events).each do |trigger|
|
||||
- if hook.send(trigger)
|
||||
%span.label.label-gray= trigger.titleize
|
||||
SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
- page_title "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests"
|
||||
- if params[:view] == 'parallel'
|
||||
- fluid_layout true
|
||||
|
||||
.merge-request{'data-url' => merge_request_path(@merge_request)}
|
||||
.merge-request-details.issuable-details
|
||||
= render "projects/merge_requests/show/mr_title"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
- if avatar
|
||||
.dash-project-avatar
|
||||
= project_icon(project, alt: '', class: 'avatar project-avatar s40')
|
||||
%span.str-truncated
|
||||
%span.str-truncated.project-full-name
|
||||
%span.namespace-name
|
||||
- if project.namespace
|
||||
= project.namespace.human_name
|
||||
|
@ -14,3 +14,7 @@
|
|||
%span.pull-right.light
|
||||
%i.fa.fa-star
|
||||
= project.star_count
|
||||
- if project.description.present?
|
||||
.project-description
|
||||
.str-truncated
|
||||
= markdown(project.description, pipeline: :description)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
= render 'shared/show_aside'
|
||||
|
||||
.row
|
||||
%section.col-md-8
|
||||
%section.col-md-7
|
||||
.header-with-avatar
|
||||
= link_to avatar_icon(@user.email, 400), target: '_blank' do
|
||||
= image_tag avatar_icon(@user.email, 90), class: "avatar avatar-tile s90", alt: ''
|
||||
|
@ -59,7 +59,7 @@
|
|||
|
||||
.content_list
|
||||
= spinner
|
||||
%aside.col-md-4
|
||||
%aside.col-md-5
|
||||
= render 'profile', user: @user
|
||||
= render 'projects', projects: @projects, contributed_projects: @contributed_projects
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ class EmailReceiverWorker
|
|||
def handle_failure(raw, e)
|
||||
Rails.logger.warn("Email can not be processed: #{e}\n\n#{raw}")
|
||||
|
||||
return unless raw.present?
|
||||
|
||||
can_retry = false
|
||||
reason = nil
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ class EmailsOnPushWorker
|
|||
def perform(project_id, recipients, push_data, options = {})
|
||||
options.symbolize_keys!
|
||||
options.reverse_merge!(
|
||||
send_from_committer_email: false,
|
||||
send_from_committer_email: false,
|
||||
disable_diffs: false
|
||||
)
|
||||
send_from_committer_email = options[:send_from_committer_email]
|
||||
|
@ -16,9 +16,9 @@ class EmailsOnPushWorker
|
|||
ref = push_data["ref"]
|
||||
author_id = push_data["user_id"]
|
||||
|
||||
action =
|
||||
action =
|
||||
if Gitlab::Git.blank_ref?(before_sha)
|
||||
:create
|
||||
:create
|
||||
elsif Gitlab::Git.blank_ref?(after_sha)
|
||||
:delete
|
||||
else
|
||||
|
@ -42,17 +42,22 @@ class EmailsOnPushWorker
|
|||
end
|
||||
|
||||
recipients.split(" ").each do |recipient|
|
||||
Notify.repository_push_email(
|
||||
project_id,
|
||||
recipient,
|
||||
author_id: author_id,
|
||||
ref: ref,
|
||||
action: action,
|
||||
compare: compare,
|
||||
reverse_compare: reverse_compare,
|
||||
send_from_committer_email: send_from_committer_email,
|
||||
disable_diffs: disable_diffs
|
||||
).deliver
|
||||
begin
|
||||
Notify.repository_push_email(
|
||||
project_id,
|
||||
recipient,
|
||||
author_id: author_id,
|
||||
ref: ref,
|
||||
action: action,
|
||||
compare: compare,
|
||||
reverse_compare: reverse_compare,
|
||||
send_from_committer_email: send_from_committer_email,
|
||||
disable_diffs: disable_diffs
|
||||
).deliver
|
||||
# These are input errors and won't be corrected even if Sidekiq retries
|
||||
rescue Net::SMTPFatalError, Net::SMTPSyntaxError => e
|
||||
logger.info("Failed to send e-mail for project '#{project.name_with_namespace}' to #{recipient}: #{e}")
|
||||
end
|
||||
end
|
||||
ensure
|
||||
compare = nil
|
||||
|
|
|
@ -8,7 +8,7 @@ class Settings < Settingslogic
|
|||
def gitlab_on_standard_port?
|
||||
gitlab.port.to_i == (gitlab.https ? 443 : 80)
|
||||
end
|
||||
|
||||
|
||||
# get host without www, thanks to http://stackoverflow.com/a/6674363/1233435
|
||||
def get_host_without_www(url)
|
||||
url = URI.encode(url)
|
||||
|
@ -32,14 +32,12 @@ class Settings < Settingslogic
|
|||
end
|
||||
end
|
||||
|
||||
def build_base_gitlab_url
|
||||
base_gitlab_url.join('')
|
||||
end
|
||||
|
||||
def build_gitlab_url
|
||||
custom_port = gitlab_on_standard_port? ? nil : ":#{gitlab.port}"
|
||||
[ gitlab.protocol,
|
||||
"://",
|
||||
gitlab.host,
|
||||
custom_port,
|
||||
gitlab.relative_url_root
|
||||
].join('')
|
||||
(base_gitlab_url + [gitlab.relative_url_root]).join('')
|
||||
end
|
||||
|
||||
# check that values in `current` (string or integer) is a contant in `modul`.
|
||||
|
@ -64,6 +62,17 @@ class Settings < Settingslogic
|
|||
end
|
||||
value
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def base_gitlab_url
|
||||
custom_port = gitlab_on_standard_port? ? nil : ":#{gitlab.port}"
|
||||
[ gitlab.protocol,
|
||||
"://",
|
||||
gitlab.host,
|
||||
custom_port
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -123,6 +132,7 @@ Settings.gitlab['email_enabled'] ||= true if Settings.gitlab['email_enabled'].ni
|
|||
Settings.gitlab['email_from'] ||= "gitlab@#{Settings.gitlab.host}"
|
||||
Settings.gitlab['email_display_name'] ||= "GitLab"
|
||||
Settings.gitlab['email_reply_to'] ||= "noreply@#{Settings.gitlab.host}"
|
||||
Settings.gitlab['base_url'] ||= Settings.send(:build_base_gitlab_url)
|
||||
Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url)
|
||||
Settings.gitlab['user'] ||= 'git'
|
||||
Settings.gitlab['user_home'] ||= begin
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
if Gitlab::LDAP::Config.enabled?
|
||||
module OmniAuth::Strategies
|
||||
server = Gitlab.config.ldap.servers.values.first
|
||||
klass = server['provider_class']
|
||||
const_set(klass, Class.new(LDAP)) unless klass == 'LDAP'
|
||||
end
|
||||
|
||||
OmniauthCallbacksController.class_eval do
|
||||
server = Gitlab.config.ldap.servers.values.first
|
||||
alias_method server['provider_name'], :ldap
|
||||
end
|
||||
end
|
||||
|
||||
OmniAuth.config.full_host = Settings.gitlab['base_url']
|
||||
OmniAuth.config.allowed_request_methods = [:post]
|
||||
#In case of auto sign-in, the GET method is used (users don't get to click on a button)
|
||||
OmniAuth.config.allowed_request_methods << :get if Gitlab.config.omniauth.auto_sign_in_with_provider.present?
|
||||
OmniAuth.config.before_request_phase do |env|
|
||||
OmniAuth::RequestForgeryProtection.new(env).call
|
||||
end
|
||||
|
||||
if Gitlab.config.omniauth.enabled
|
||||
Gitlab.config.omniauth.providers.each do |provider|
|
||||
if provider['name'] == 'kerberos'
|
||||
require 'omniauth-kerberos'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -14,6 +14,8 @@
|
|||
# :name: "inbox"
|
||||
# # Always "sidekiq".
|
||||
# :delivery_method: sidekiq
|
||||
# # Always true.
|
||||
# :delete_after_delivery: true
|
||||
# :delivery_options:
|
||||
# # The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
|
||||
# :redis_url: redis://localhost:6379
|
||||
|
|
|
@ -360,6 +360,7 @@ Gitlab::Application.routes.draw do
|
|||
member do
|
||||
get :issues
|
||||
get :merge_requests
|
||||
get :activity
|
||||
end
|
||||
|
||||
scope module: :dashboard do
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddEnableSslVerification < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :web_hooks, :enable_ssl_verification, :boolean, default: false
|
||||
end
|
||||
end
|
14
db/schema.rb
14
db/schema.rb
|
@ -821,14 +821,14 @@ ActiveRecord::Schema.define(version: 20150826001931) do
|
|||
t.integer "project_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "type", default: "ProjectHook"
|
||||
t.string "type", default: "ProjectHook"
|
||||
t.integer "service_id"
|
||||
t.boolean "push_events", default: true, null: false
|
||||
t.boolean "issues_events", default: false, null: false
|
||||
t.boolean "merge_requests_events", default: false, null: false
|
||||
t.boolean "tag_push_events", default: false
|
||||
t.integer "group_id"
|
||||
t.boolean "note_events", default: false, null: false
|
||||
t.boolean "push_events", default: true, null: false
|
||||
t.boolean "issues_events", default: false, null: false
|
||||
t.boolean "merge_requests_events", default: false, null: false
|
||||
t.boolean "tag_push_events", default: false
|
||||
t.boolean "note_events", default: false, null: false
|
||||
t.boolean "enable_ssl_verification", default: false
|
||||
end
|
||||
|
||||
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
|
||||
|
|
|
@ -59,6 +59,8 @@ In this example, we'll use the Gmail address `gitlab-replies@gmail.com`. If you'
|
|||
:name: "inbox"
|
||||
# Always "sidekiq".
|
||||
:delivery_method: sidekiq
|
||||
# Always true.
|
||||
:delete_after_delivery: true
|
||||
:delivery_options:
|
||||
# The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
|
||||
:redis_url: redis://localhost:6379
|
||||
|
@ -144,6 +146,8 @@ TODO
|
|||
:name: "inbox"
|
||||
# Always "sidekiq".
|
||||
:delivery_method: sidekiq
|
||||
# Always true.
|
||||
:delete_after_delivery: true
|
||||
:delivery_options:
|
||||
# The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
|
||||
:redis_url: redis://localhost:6379
|
||||
|
|
|
@ -8,5 +8,5 @@
|
|||
### Note
|
||||
* If you'd like to migrate from a self-hosted GitLab instance to GitLab.com, you can copy your repos by changing the remote and pushing to the new server; but issues and merge requests can't be imported.
|
||||
|
||||
* Repositories are imported to GitLab via HTTP.
|
||||
If the repository is too large, it can timeout. We have a soft limit of 10GB.
|
||||
* You can import any Git repository via HTTP from the New Project page.
|
||||
If the repository is too large, it can timeout.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
@admin
|
||||
Feature: Admin Hooks
|
||||
Background:
|
||||
Given I sign in as an admin
|
||||
|
||||
Scenario: On Admin Hooks
|
||||
Given I visit admin hooks page
|
||||
Then I submit the form with enabled SSL verification
|
||||
And I see new hook with enabled SSL verification
|
|
@ -10,6 +10,10 @@ Feature: Dashboard
|
|||
Scenario: I should see projects list
|
||||
Then I should see "New Project" link
|
||||
Then I should see "Shop" project link
|
||||
|
||||
@javascript
|
||||
Scenario: I should see activity list
|
||||
And I visit dashboard activity page
|
||||
Then I should see project "Shop" activity feed
|
||||
|
||||
Scenario: I should see groups list
|
||||
|
@ -26,12 +30,12 @@ Feature: Dashboard
|
|||
@javascript
|
||||
Scenario: I should see User joined Project event
|
||||
Given user with name "John Doe" joined project "Shop"
|
||||
When I visit dashboard page
|
||||
When I visit dashboard activity page
|
||||
Then I should see "John Doe joined project Shop" event
|
||||
|
||||
@javascript
|
||||
Scenario: I should see User left Project event
|
||||
Given user with name "John Doe" joined project "Shop"
|
||||
And user with name "John Doe" left project "Shop"
|
||||
When I visit dashboard page
|
||||
When I visit dashboard activity page
|
||||
Then I should see "John Doe left project Shop" event
|
||||
|
|
|
@ -6,7 +6,7 @@ Feature: Event Filters
|
|||
And this project has push event
|
||||
And this project has new member event
|
||||
And this project has merge request event
|
||||
And I visit dashboard page
|
||||
And I visit dashboard activity page
|
||||
|
||||
@javascript
|
||||
Scenario: I should see all events
|
||||
|
@ -16,7 +16,7 @@ Feature: Event Filters
|
|||
|
||||
@javascript
|
||||
Scenario: I should see only pushed events
|
||||
When I click "push" event filter
|
||||
When I click "push" event filter
|
||||
Then I should see push event
|
||||
And I should not see new member event
|
||||
And I should not see merge request event
|
||||
|
@ -38,11 +38,11 @@ Feature: Event Filters
|
|||
@javascript
|
||||
Scenario: I should see only selected events while page reloaded
|
||||
When I click "push" event filter
|
||||
And I visit dashboard page
|
||||
And I visit dashboard activity page
|
||||
Then I should see push event
|
||||
And I should not see new member event
|
||||
When I click "team" event filter
|
||||
And I visit dashboard page
|
||||
And I visit dashboard activity page
|
||||
Then I should see push event
|
||||
And I should see new member event
|
||||
And I should not see merge request event
|
||||
|
|
|
@ -41,6 +41,7 @@ Feature: Project Commits
|
|||
Scenario: I browse big commit
|
||||
Given I visit big commit page
|
||||
Then I see big commit warning
|
||||
And I see "Reload with full diff" link
|
||||
|
||||
Scenario: I browse a commit with an image
|
||||
Given I visit a commit with an image that changed
|
||||
|
|
|
@ -13,6 +13,11 @@ Feature: Project Hooks
|
|||
When I submit new hook
|
||||
Then I should see newly created hook
|
||||
|
||||
Scenario: I add new hook with SSL verification enabled
|
||||
Given I visit project hooks page
|
||||
When I submit new hook with SSL verification enabled
|
||||
Then I should see newly created hook with SSL verification enabled
|
||||
|
||||
Scenario: I test hook
|
||||
Given project has hook
|
||||
And I visit project hooks page
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
class Spinach::Features::AdminHooks < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedPaths
|
||||
include SharedAdmin
|
||||
|
||||
step "I submit the form with enabled SSL verification" do
|
||||
fill_in 'hook_url', with: 'http://google.com'
|
||||
check "Enable SSL verification"
|
||||
click_on "Add System Hook"
|
||||
end
|
||||
|
||||
step "I see new hook with enabled SSL verification" do
|
||||
expect(page).to have_content "SSL Verification: enabled"
|
||||
end
|
||||
end
|
|
@ -79,6 +79,12 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps
|
|||
expect(page).to have_content "Too many changes"
|
||||
end
|
||||
|
||||
step 'I see "Reload with full diff" link' do
|
||||
link = find_link('Reload with full diff')
|
||||
expect(link[:href]).to end_with('?force_show_diff=true')
|
||||
expect(link[:href]).not_to include('.html')
|
||||
end
|
||||
|
||||
step 'I visit a commit with an image that changed' do
|
||||
visit namespace_project_commit_path(@project.namespace, @project, sample_image_commit.id)
|
||||
end
|
||||
|
|
|
@ -28,11 +28,24 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps
|
|||
expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1)
|
||||
end
|
||||
|
||||
step 'I submit new hook with SSL verification enabled' do
|
||||
@url = FFaker::Internet.uri("http")
|
||||
fill_in "hook_url", with: @url
|
||||
check "hook_enable_ssl_verification"
|
||||
expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1)
|
||||
end
|
||||
|
||||
step 'I should see newly created hook' do
|
||||
expect(current_path).to eq namespace_project_hooks_path(current_project.namespace, current_project)
|
||||
expect(page).to have_content(@url)
|
||||
end
|
||||
|
||||
step 'I should see newly created hook with SSL verification enabled' do
|
||||
expect(current_path).to eq namespace_project_hooks_path(current_project.namespace, current_project)
|
||||
expect(page).to have_content(@url)
|
||||
expect(page).to have_content("SSL Verification: enabled")
|
||||
end
|
||||
|
||||
step 'I click test hook button' do
|
||||
stub_request(:post, @hook.url).to_return(status: 200)
|
||||
click_link 'Test Hook'
|
||||
|
|
|
@ -71,6 +71,10 @@ module SharedPaths
|
|||
visit dashboard_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard activity page' do
|
||||
visit activity_dashboard_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard projects page' do
|
||||
visit projects_dashboard_path
|
||||
end
|
||||
|
|
|
@ -288,7 +288,7 @@ print_status() {
|
|||
fi
|
||||
if [ "$mail_room_enabled" = true ]; then
|
||||
if [ "$mail_room_status" = "0" ]; then
|
||||
echo "The GitLab MailRoom email processor with pid $spid is running."
|
||||
echo "The GitLab MailRoom email processor with pid $mpid is running."
|
||||
else
|
||||
printf "The GitLab MailRoom email processor is \033[31mnot running\033[0m.\n"
|
||||
fi
|
||||
|
|
|
@ -121,7 +121,6 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
skip "TODO (rspeicher): Re-enable when usernames can't end in periods."
|
||||
doc = filter("Mention me (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{reference}<\/a>\.\)/)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe EmailsOnPushWorker do
|
||||
include RepoHelpers
|
||||
|
||||
let(:project) { create(:project) }
|
||||
let(:user) { create(:user) }
|
||||
let(:data) { Gitlab::PushDataBuilder.build_sample(project, user) }
|
||||
|
||||
subject { EmailsOnPushWorker.new }
|
||||
|
||||
before do
|
||||
allow(Project).to receive(:find).and_return(project)
|
||||
end
|
||||
|
||||
describe "#perform" do
|
||||
it "sends mail" do
|
||||
subject.perform(project.id, user.email, data.stringify_keys)
|
||||
|
||||
email = ActionMailer::Base.deliveries.last
|
||||
expect(email.subject).to include('Change some files')
|
||||
expect(email.to).to eq([user.email])
|
||||
end
|
||||
|
||||
it "gracefully handles an input SMTP error" do
|
||||
ActionMailer::Base.deliveries.clear
|
||||
allow(Notify).to receive(:repository_push_email).and_raise(Net::SMTPFatalError)
|
||||
|
||||
subject.perform(project.id, user.email, data.stringify_keys)
|
||||
|
||||
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue