Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce
This commit is contained in:
commit
abb5b9f6e5
50 changed files with 335 additions and 282 deletions
11
CHANGELOG
11
CHANGELOG
|
@ -1,9 +1,9 @@
|
|||
Please view this file on the master branch, on stable branches it's out of date.
|
||||
|
||||
v 8.0.0 (unreleased)
|
||||
- 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)
|
||||
- Fix "Reload with full diff" URL button in compare branch view (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
|
||||
|
@ -16,14 +16,19 @@ v 8.0.0 (unreleased)
|
|||
- 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)
|
||||
- Improve abuse reports management from admin area
|
||||
- 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
|
||||
- Fix 500 error when submit project snippet without body
|
||||
- Improve search page usability
|
||||
- Bring more UI consistency in way how projects, snippets and groups lists are rendered
|
||||
|
||||
v 7.14.1 (unreleased)
|
||||
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.
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -273,6 +273,6 @@ gem "newrelic_rpm"
|
|||
|
||||
gem 'octokit', '3.7.0'
|
||||
|
||||
gem "mail_room", "~> 0.4.0"
|
||||
gem "mail_room", "~> 0.4.1"
|
||||
|
||||
gem 'email_reply_parser'
|
||||
|
|
|
@ -372,7 +372,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)
|
||||
|
@ -808,7 +808,7 @@ DEPENDENCIES
|
|||
jquery-ui-rails
|
||||
kaminari (~> 0.15.1)
|
||||
letter_opener
|
||||
mail_room (~> 0.4.0)
|
||||
mail_room (~> 0.4.1)
|
||||
minitest (~> 5.3.0)
|
||||
mousetrap-rails
|
||||
mysql2
|
||||
|
|
|
@ -55,7 +55,6 @@ class Dispatcher
|
|||
new Activities()
|
||||
when 'dashboard:projects:starred'
|
||||
new Activities()
|
||||
new ProjectsList()
|
||||
when 'projects:commit:show'
|
||||
new Commit()
|
||||
new Diff()
|
||||
|
@ -70,7 +69,6 @@ class Dispatcher
|
|||
when 'groups:show'
|
||||
new Activities()
|
||||
shortcut_handler = new ShortcutsNavigation()
|
||||
new ProjectsList()
|
||||
when 'groups:group_members:index'
|
||||
new GroupMembers()
|
||||
new UsersSelect()
|
||||
|
@ -96,8 +94,6 @@ class Dispatcher
|
|||
when 'users:show'
|
||||
new User()
|
||||
new Activities()
|
||||
when 'admin:users:show'
|
||||
new ProjectsList()
|
||||
|
||||
switch path.first()
|
||||
when 'admin'
|
||||
|
|
|
@ -157,3 +157,41 @@
|
|||
white-space: nowrap;
|
||||
max-width: $max_width;
|
||||
}
|
||||
|
||||
/*
|
||||
* Base mixin for lists in GitLab
|
||||
*/
|
||||
@mixin basic-list {
|
||||
margin: 5px 0px;
|
||||
padding: 0px;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #EEE;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
margin: 0px;
|
||||
|
||||
&:last-child {
|
||||
border:none
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: #f9f9f9;
|
||||
a {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
&.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.light {
|
||||
a {
|
||||
color: #777;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -375,9 +375,9 @@ table {
|
|||
}
|
||||
|
||||
.center-top-menu {
|
||||
border-bottom: 1px solid #EEE;
|
||||
list-style: none;
|
||||
text-align: center;
|
||||
margin-top: 5px;
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
|
@ -385,7 +385,7 @@ table {
|
|||
display: inline-block;
|
||||
|
||||
a {
|
||||
padding: 10px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
&.active a {
|
||||
|
|
|
@ -93,28 +93,12 @@ ol, ul {
|
|||
|
||||
/** light list with border-bottom between li **/
|
||||
ul.bordered-list {
|
||||
margin: 5px 0px;
|
||||
padding: 0px;
|
||||
li {
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid #EEE;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
margin: 0px;
|
||||
&:last-child { border:none }
|
||||
&.active {
|
||||
background: #f9f9f9;
|
||||
a { font-weight: bold; }
|
||||
}
|
||||
|
||||
&.light {
|
||||
a { color: #777; }
|
||||
}
|
||||
}
|
||||
@include basic-list;
|
||||
|
||||
&.top-list {
|
||||
li:first-child {
|
||||
padding-top: 0;
|
||||
|
||||
h4, h5 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
|
|
@ -162,78 +162,6 @@ ul.nav.nav-projects-tabs {
|
|||
margin: 0px;
|
||||
}
|
||||
|
||||
.my-projects,
|
||||
.public-projects {
|
||||
li {
|
||||
.project-info {
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.access-icon {
|
||||
color: #AAA;
|
||||
margin-left: 10px;
|
||||
i {
|
||||
color: #AAA;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.public-clone {
|
||||
background: #EEE;
|
||||
color: #777;
|
||||
padding: 6px 10px;
|
||||
margin: 1px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.public-projects .repo-info {
|
||||
color: #777;
|
||||
|
||||
a {
|
||||
color: #777;
|
||||
}
|
||||
}
|
||||
|
||||
.project-side {
|
||||
.project-fork-icon {
|
||||
float: left;
|
||||
font-size: 26px;
|
||||
margin-right: 10px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.panel {
|
||||
@include border-radius(3px);
|
||||
|
||||
.panel-heading, .panel-footer {
|
||||
font-weight: normal;
|
||||
background-color: transparent;
|
||||
color: #666;
|
||||
border-color: #EEE;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.nav-pills a {
|
||||
padding: 10px;
|
||||
font-weight: bold;
|
||||
color: $gl-link-color;
|
||||
}
|
||||
|
||||
.nav {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.ci-status-image {
|
||||
max-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.transfer-project .select2-container {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
@ -334,23 +262,32 @@ pre.light-well {
|
|||
}
|
||||
}
|
||||
|
||||
.project-row {
|
||||
.project-full-name {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
/*
|
||||
* Projects list rendered on dashboard and user page
|
||||
*/
|
||||
.projects-list {
|
||||
@include basic-list;
|
||||
|
||||
.project-description {
|
||||
color: #888;
|
||||
font-size: 13px;
|
||||
.project-row {
|
||||
.project-full-name {
|
||||
@include str-truncated;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
.project-description {
|
||||
color: #888;
|
||||
font-size: 13px;
|
||||
|
||||
p {
|
||||
@include str-truncated;
|
||||
margin-bottom: 0;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.my-projects .project-row {
|
||||
padding: 10px 0;
|
||||
.panel .projects-list li {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,19 @@
|
|||
.search-results {
|
||||
.search-result-row {
|
||||
border-bottom: 1px solid #EEE;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-holder {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 20px;
|
||||
|
||||
input {
|
||||
border-color: #BBB;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,3 +6,27 @@
|
|||
.snippet-form-holder .file-holder .file-title {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
|
||||
.snippet-row {
|
||||
.snippet-title {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
line-height: 20px;
|
||||
margin-bottom: 2px;
|
||||
|
||||
.monospace {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.snippet-info {
|
||||
color: #888;
|
||||
font-size: 13px;
|
||||
line-height: 24px;
|
||||
|
||||
a {
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -55,7 +55,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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -30,9 +30,14 @@ class Projects::SnippetsController < Projects::ApplicationController
|
|||
def create
|
||||
@snippet = CreateSnippetService.new(@project, current_user,
|
||||
snippet_params).execute
|
||||
respond_with(@snippet,
|
||||
location: namespace_project_snippet_path(@project.namespace,
|
||||
@project, @snippet))
|
||||
|
||||
if @snippet.valid?
|
||||
respond_with(@snippet,
|
||||
location: namespace_project_snippet_path(@project.namespace,
|
||||
@project, @snippet))
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
|
|
|
@ -2,13 +2,21 @@ class TrendingProjectsFinder
|
|||
def execute(current_user, start_date = nil)
|
||||
start_date ||= Date.today - 1.month
|
||||
|
||||
projects = projects_for(current_user)
|
||||
|
||||
# Determine trending projects based on comments count
|
||||
# for period of time - ex. month
|
||||
projects.joins(:notes).where('notes.created_at > ?', start_date).
|
||||
select("projects.*, count(notes.id) as ncount").
|
||||
group("projects.id").reorder("ncount DESC")
|
||||
trending_project_ids = Note.
|
||||
select("notes.project_id, count(notes.project_id) as pcount").
|
||||
where('notes.created_at > ?', start_date).
|
||||
group("project_id").
|
||||
reorder("pcount DESC").
|
||||
map(&:project_id)
|
||||
|
||||
sql_order_ids = trending_project_ids.reverse.
|
||||
map { |project_id| "id = #{project_id}" }.join(", ")
|
||||
|
||||
# Get list of projects that user allowed to see
|
||||
projects = projects_for(current_user)
|
||||
projects.where(id: trending_project_ids).reorder(sql_order_ids)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -7,7 +7,4 @@
|
|||
= link_to new_project_path, class: 'btn btn-success' do
|
||||
New project
|
||||
|
||||
%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 }
|
||||
= render 'shared/projects/list', projects: @projects
|
||||
|
|
|
@ -8,32 +8,9 @@
|
|||
= link_to new_group_path, class: "btn btn-new btn-sm" do
|
||||
%i.fa.fa-plus
|
||||
New Group
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
%strong Groups
|
||||
(#{@group_members.count})
|
||||
%ul.well-list
|
||||
- @group_members.each do |group_member|
|
||||
- group = group_member.group
|
||||
%li
|
||||
.pull-right.hidden-xs
|
||||
- if can?(current_user, :admin_group, group)
|
||||
= link_to edit_group_path(group), class: "btn-sm btn btn-grouped" do
|
||||
%i.fa.fa-cogs
|
||||
Settings
|
||||
|
||||
= link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do
|
||||
%i.fa.fa-sign-out
|
||||
Leave
|
||||
|
||||
= image_tag group_icon(group), class: "avatar s40 avatar-tile hidden-xs"
|
||||
= link_to group, class: 'group-name' do
|
||||
%strong= group.name
|
||||
|
||||
as
|
||||
%strong #{group_member.human_access}
|
||||
|
||||
%div.light
|
||||
#{pluralize(group.projects.count, "project")}, #{pluralize(group.users.count, "user")}
|
||||
%ul.bordered-list
|
||||
- @group_members.each do |group_member|
|
||||
- group = group_member.group
|
||||
= render 'shared/groups/group', group: group, group_member: group_member
|
||||
|
||||
= paginate @group_members
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
= link_to new_project_path, class: 'btn btn-success' do
|
||||
New project
|
||||
|
||||
= render 'shared/projects_list', projects: @projects,
|
||||
projects_limit: 20, stars: true, avatar: false
|
||||
= render 'shared/projects/list', projects: @projects, projects_limit: 20
|
||||
|
||||
- else
|
||||
%h3 You don't have starred projects yet
|
||||
|
|
|
@ -32,17 +32,7 @@
|
|||
|
||||
%ul.bordered-list
|
||||
- @groups.each do |group|
|
||||
%li
|
||||
.clearfix
|
||||
%h4
|
||||
= link_to group_path(id: group.path) do
|
||||
= group.name
|
||||
.clearfix
|
||||
%p
|
||||
= truncate group.description, length: 150
|
||||
.clearfix
|
||||
%p.light
|
||||
#{pluralize(group.members.size, 'member')}, #{pluralize(group.projects.count, 'project')}
|
||||
= render 'shared/groups/group', group: group
|
||||
- unless @groups.present?
|
||||
.nothing-here-block No public groups
|
||||
|
||||
|
|
|
@ -1,6 +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
|
||||
- if projects.any?
|
||||
.public-projects
|
||||
= render 'shared/projects/list', projects: projects
|
||||
- else
|
||||
.nothing-here-block
|
||||
No such projects
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
= link_to new_project_path(namespace_id: @group.id), class: 'btn btn-success' do
|
||||
New project
|
||||
|
||||
= render 'shared/projects_list', projects: @projects, projects_limit: 20
|
||||
= render 'shared/projects/list', projects: @projects, projects_limit: 20
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
- if project_nav_tab? :snippets
|
||||
= nav_link(controller: :snippets) do
|
||||
= link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets', data: {placement: 'right'} do
|
||||
= icon('file-text-o fw')
|
||||
= icon('clipboard fw')
|
||||
%span
|
||||
Snippets
|
||||
|
||||
|
|
|
@ -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,15 +0,0 @@
|
|||
%li
|
||||
%h4.snippet-title
|
||||
= link_to reliable_snippet_path(snippet) do
|
||||
= truncate(snippet.title, length: 60)
|
||||
%span.cgray.monospace.tiny.pull-right
|
||||
= snippet.file_name
|
||||
|
||||
.snippet-info
|
||||
= "##{snippet.id}"
|
||||
%span
|
||||
by
|
||||
= image_tag avatar_icon(snippet.author_email), class: "avatar avatar-inline s16"
|
||||
= snippet.author_name
|
||||
%span.light
|
||||
#{time_ago_with_tooltip(snippet.created_at)}
|
|
@ -8,9 +8,8 @@
|
|||
%p.light
|
||||
Share code pastes with others out of git repository
|
||||
|
||||
%hr
|
||||
%ul.bordered-list
|
||||
= render partial: "projects/snippets/snippet", collection: @snippets
|
||||
= render partial: "shared/snippets/snippet", collection: @snippets
|
||||
- if @snippets.empty?
|
||||
%li
|
||||
.nothing-here-block Nothing here.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%ul.nav.nav-pills.search-filter
|
||||
%ul.nav.nav-tabs.search-filter
|
||||
- if @project
|
||||
%li{class: ("active" if @scope == 'blobs')}
|
||||
= link_to search_filter_path(scope: 'blobs') do
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
.dropdown.inline
|
||||
%button.dropdown-toggle.btn.btn{type: 'button', 'data-toggle' => 'dropdown'}
|
||||
%i.fa.fa-tags
|
||||
%button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'}
|
||||
%span.light Group:
|
||||
- if @group.present?
|
||||
%strong= @group.name
|
||||
|
@ -17,8 +16,7 @@
|
|||
= group.name
|
||||
|
||||
.dropdown.inline.prepend-left-10.project-filter
|
||||
%button.dropdown-toggle.btn.btn{type: 'button', 'data-toggle' => 'dropdown'}
|
||||
%i.fa.fa-tags
|
||||
%button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'}
|
||||
%span.light Project:
|
||||
- if @project.present?
|
||||
%strong= @project.name_with_namespace
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
= form_tag search_path, method: :get, class: 'form-inline' do |f|
|
||||
= form_tag search_path, method: :get do |f|
|
||||
= hidden_field_tag :project_id, params[:project_id]
|
||||
= hidden_field_tag :group_id, params[:group_id]
|
||||
= hidden_field_tag :snippets, params[:snippets]
|
||||
= hidden_field_tag :scope, params[:scope]
|
||||
|
||||
.search-holder.clearfix
|
||||
.form-group
|
||||
.input-group
|
||||
= search_field_tag :search, params[:search], placeholder: "Search for projects, issues etc", class: "form-control search-text-input", id: "dashboard_search", autofocus: true
|
||||
= button_tag 'Search', class: "btn btn-primary"
|
||||
%span.input-group-btn
|
||||
= button_tag 'Search', class: "btn btn-primary"
|
||||
- unless params[:snippets].eql? 'true'
|
||||
.pull-right
|
||||
= render 'filter'
|
||||
%br
|
||||
= render 'filter'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- if @search_results.empty?
|
||||
= render partial: "search/results/empty"
|
||||
- else
|
||||
.light
|
||||
%p.light
|
||||
Search results for
|
||||
%code
|
||||
= @search_term
|
||||
|
@ -11,10 +11,13 @@
|
|||
- elsif @group
|
||||
in group #{link_to @group.name, @group}
|
||||
|
||||
%br
|
||||
.results.prepend-top-10
|
||||
.search-results
|
||||
= render partial: "search/results/#{@scope.singularize}", collection: @objects
|
||||
- if @scope == 'projects'
|
||||
.term
|
||||
= render 'shared/projects/list', projects: @objects
|
||||
- else
|
||||
= render partial: "search/results/#{@scope.singularize}", collection: @objects
|
||||
= paginate @objects, theme: 'gitlab'
|
||||
|
||||
:javascript
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
.search-result-row
|
||||
%h4
|
||||
= link_to [project.namespace.becomes(Namespace), project] do
|
||||
%span.term= project.name_with_namespace
|
||||
- if project.description.present?
|
||||
%span.light.term= project.description
|
|
@ -1,7 +1,5 @@
|
|||
- page_title @search_term
|
||||
= render 'search/form'
|
||||
%hr
|
||||
- if @search_term
|
||||
= render 'search/category'
|
||||
%hr
|
||||
= render 'search/results'
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
= cache [project.namespace, project, controller.controller_name, controller.action_name] do
|
||||
= link_to project_path(project), class: dom_class(project) do
|
||||
- if avatar
|
||||
.dash-project-avatar
|
||||
= project_icon(project, alt: '', class: 'avatar project-avatar s40')
|
||||
%span.str-truncated.project-full-name
|
||||
%span.namespace-name
|
||||
- if project.namespace
|
||||
= project.namespace.human_name
|
||||
\/
|
||||
%span.project-name.filter-title
|
||||
= project.name
|
||||
- if stars
|
||||
%span.pull-right.light
|
||||
%i.fa.fa-star
|
||||
= project.star_count
|
||||
- if project.description.present?
|
||||
.project-description
|
||||
.str-truncated
|
||||
= markdown(project.description, pipeline: :description)
|
|
@ -1,17 +0,0 @@
|
|||
- projects_limit = 20 unless local_assigns[:projects_limit]
|
||||
- avatar = true unless local_assigns[:avatar] == false
|
||||
- stars = false unless local_assigns[:stars] == true
|
||||
%ul.well-list.projects-list
|
||||
- projects.each_with_index do |project, i|
|
||||
%li{class: (i >= projects_limit) ? 'project-row hide' : 'project-row'}
|
||||
= render "shared/project", project: project, avatar: avatar, stars: stars
|
||||
- if projects.blank?
|
||||
%li
|
||||
.nothing-here-block There are no projects here.
|
||||
- if projects.count > projects_limit
|
||||
%li.bottom
|
||||
%span.light
|
||||
#{projects_limit} of #{pluralize(projects.count, 'project')} displayed.
|
||||
%span
|
||||
= link_to '#', class: 'js-expand' do
|
||||
Show all
|
24
app/views/shared/groups/_group.html.haml
Normal file
24
app/views/shared/groups/_group.html.haml
Normal file
|
@ -0,0 +1,24 @@
|
|||
- group_member = local_assigns[:group_member]
|
||||
%li
|
||||
- if group_member
|
||||
.pull-right.hidden-xs
|
||||
- if can?(current_user, :admin_group, group)
|
||||
= link_to edit_group_path(group), class: "btn-sm btn btn-grouped" do
|
||||
%i.fa.fa-cogs
|
||||
Settings
|
||||
|
||||
= link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do
|
||||
%i.fa.fa-sign-out
|
||||
Leave
|
||||
|
||||
= image_tag group_icon(group), class: "avatar s40 avatar-tile hidden-xs"
|
||||
= link_to group, class: 'group-name' do
|
||||
%strong= group.name
|
||||
|
||||
- if group_member
|
||||
as
|
||||
%strong #{group_member.human_access}
|
||||
|
||||
%div.light
|
||||
#{pluralize(group.projects.count, "project")}, #{pluralize(group.users.count, "user")}
|
||||
|
19
app/views/shared/projects/_list.html.haml
Normal file
19
app/views/shared/projects/_list.html.haml
Normal file
|
@ -0,0 +1,19 @@
|
|||
- projects_limit = 20 unless local_assigns[:projects_limit]
|
||||
- avatar = true unless local_assigns[:avatar] == false
|
||||
- stars = true unless local_assigns[:stars] == false
|
||||
|
||||
%ul.projects-list
|
||||
- projects.each_with_index do |project, i|
|
||||
- css_class = (i >= projects_limit) ? 'hide' : nil
|
||||
= render "shared/projects/project", project: project,
|
||||
avatar: avatar, stars: stars, css_class: css_class
|
||||
|
||||
- if projects.count > projects_limit
|
||||
%li.bottom.center
|
||||
.light
|
||||
#{projects_limit} of #{pluralize(projects.count, 'project')} displayed.
|
||||
= link_to '#', class: 'js-expand' do
|
||||
Show all
|
||||
|
||||
:coffeescript
|
||||
new ProjectsList()
|
23
app/views/shared/projects/_project.html.haml
Normal file
23
app/views/shared/projects/_project.html.haml
Normal file
|
@ -0,0 +1,23 @@
|
|||
- avatar = true unless local_assigns[:avatar] == false
|
||||
- stars = true unless local_assigns[:stars] == false
|
||||
- css_class = nil unless local_assigns[:css_class]
|
||||
%li.project-row{ class: css_class }
|
||||
= cache [project.namespace, project, controller.controller_name, controller.action_name, 'v2'] do
|
||||
= link_to project_path(project), class: dom_class(project) do
|
||||
- if avatar
|
||||
.dash-project-avatar
|
||||
= project_icon(project, alt: '', class: 'avatar project-avatar s40')
|
||||
%span.project-full-name
|
||||
%span.namespace-name
|
||||
- if project.namespace
|
||||
= project.namespace.human_name
|
||||
\/
|
||||
%span.project-name.filter-title
|
||||
= project.name
|
||||
- if stars
|
||||
%span.pull-right.light
|
||||
%i.fa.fa-star
|
||||
= project.star_count
|
||||
- if project.description.present?
|
||||
.project-description
|
||||
= markdown(project.description, pipeline: :description)
|
|
@ -1,12 +1,12 @@
|
|||
%li
|
||||
%h4.snippet-title
|
||||
%li.snippet-row
|
||||
.snippet-title
|
||||
= link_to reliable_snippet_path(snippet) do
|
||||
= truncate(snippet.title, length: 60)
|
||||
- if snippet.private?
|
||||
%span.label.label-gray
|
||||
%i.fa.fa-lock
|
||||
private
|
||||
%span.cgray.monospace.tiny.pull-right
|
||||
%span.monospace.pull-right
|
||||
= snippet.file_name
|
||||
|
||||
%small.pull-right.cgray
|
||||
|
@ -14,10 +14,8 @@
|
|||
= link_to snippet.project.name_with_namespace, namespace_project_path(snippet.project.namespace, snippet.project)
|
||||
|
||||
.snippet-info
|
||||
= "##{snippet.id}"
|
||||
%span
|
||||
by
|
||||
= link_to user_snippets_path(snippet.author) do
|
||||
= image_tag avatar_icon(snippet.author_email), class: "avatar avatar-inline s16", alt: ''
|
||||
= snippet.author_name
|
||||
%span.light #{time_ago_with_tooltip(snippet.created_at)}
|
||||
= link_to user_snippets_path(snippet.author) do
|
||||
= image_tag avatar_icon(snippet.author_email), class: "avatar s24", alt: ''
|
||||
= snippet.author_name
|
||||
authored #{time_ago_with_tooltip(snippet.created_at)}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
%ul.bordered-list
|
||||
= render partial: 'snippet', collection: @snippets
|
||||
= render partial: 'shared/snippets/snippet', collection: @snippets
|
||||
- if @snippets.empty?
|
||||
%li
|
||||
.nothing-here-block Nothing here.
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
- if local_assigns.has_key?(:contributed_projects) && contributed_projects.present?
|
||||
.panel.panel-default.contributed-projects
|
||||
.panel-heading Projects contributed to
|
||||
= render 'shared/projects_list',
|
||||
= render 'shared/projects/list',
|
||||
projects: contributed_projects.sort_by(&:star_count).reverse,
|
||||
projects_limit: 5, stars: true, avatar: false
|
||||
|
||||
- if local_assigns.has_key?(:projects) && projects.present?
|
||||
.panel.panel-default
|
||||
.panel-heading Personal projects
|
||||
= render 'shared/projects_list',
|
||||
= render 'shared/projects/list',
|
||||
projects: projects.sort_by(&:star_count).reverse,
|
||||
projects_limit: 10, stars: true, avatar: false
|
||||
|
|
5
db/migrate/20150824002011_add_enable_ssl_verification.rb
Normal file
5
db/migrate/20150824002011_add_enable_ssl_verification.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddEnableSslVerification < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :web_hooks, :enable_ssl_verification, :boolean, default: false
|
||||
end
|
||||
end
|
15
db/schema.rb
15
db/schema.rb
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150818213832) do
|
||||
ActiveRecord::Schema.define(version: 20150824002011) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -566,13 +566,14 @@ ActiveRecord::Schema.define(version: 20150818213832) 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.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
|
||||
|
|
9
features/admin/hooks.feature
Normal file
9
features/admin/hooks.feature
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
15
features/steps/admin/hooks.rb
Normal file
15
features/steps/admin/hooks.rb
Normal file
|
@ -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
|
|
@ -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'
|
||||
|
|
Loading…
Reference in a new issue