Commit 1bfb586a authored by Kirill Smelkov's avatar Kirill Smelkov

Sync with upstream 8-5-stable

* 8-5-stable:
  Version 8.5.2
  Merge branch 'docs_todos' into 'master'
  Merge branch 'fix/13785-dashboard-projects-display-welcome-after-search' into 'master'
  Merge branch 'fix/13781-delete-tag-without-ajax' into 'master'
  Merge branch 'fix/deprecated-ci-badge-permissions' into 'master'
  Merge branch 'issue_13623' into 'master'
  Merge branch 'fix/12652-omniauth-import-from-gitlab-com-fails' into 'master'
  Merge branch 'shortcuts-help' into 'master'
  Merge branch 'rel-url-fix' into 'master'
  Merge branch 'sidebar-overlap-fix' into 'master'
  Merge branch 'rs-improve-grace-period' into 'master'
  Merge branch 'issue_13648' into 'master'
  Merge branch 'issue_13621' into 'master'
  Merge branch 'issue_13851' into 'master'
  Merge branch 'fix-migration' into 'master'
  Merge branch '11489-branded-appearance-to-ce' into 'master'
  Update Rails to 4.2.5.2
parents 5d6b7eba 3a93df83
...@@ -23,6 +23,7 @@ config/gitlab.yml ...@@ -23,6 +23,7 @@ config/gitlab.yml
config/gitlab_ci.yml config/gitlab_ci.yml
config/initializers/rack_attack.rb config/initializers/rack_attack.rb
config/initializers/smtp_settings.rb config/initializers/smtp_settings.rb
config/initializers/relative_url.rb
config/resque.yml config/resque.yml
config/unicorn.rb config/unicorn.rb
config/secrets.yml config/secrets.yml
......
...@@ -2,7 +2,20 @@ Please view this file on the master branch, on stable branches it's out of date. ...@@ -2,7 +2,20 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.5.2 v 8.5.2
- Fix sidebar overlapping content when screen width was below 1200px - Fix sidebar overlapping content when screen width was below 1200px
- Don't repeat labels listed on Labels tab
- Bring the "branded appearance" feature from EE to CE
- Fix error 500 when commenting on a commit - Fix error 500 when commenting on a commit
- Show days remaining instead of elapsed time for Milestone
- Fix broken icons on installations with relative URL (Artem Sidorenko)
- Fix issue where tag list wasn't refreshed after deleting a tag
- Fix import from gitlab.com (KazSawada)
- Improve implementation to check read access to forks and add pagination
- Don't show any "2FA required" message if it's not actually required
- Fix help keyboard shortcut on relative URL setups (Artem Sidorenko)
- Update Rails to 4.2.5.2
- Fix permissions for deprecated CI build status badge
- Don't show "Welcome to GitLab" when the search didn't return any projects
- Add Todos documentation
v 8.5.1 v 8.5.1
- Fix group projects styles - Fix group projects styles
......
source "https://rubygems.org" source "https://rubygems.org"
gem 'rails', '4.2.5.1' gem 'rails', '4.2.5.2'
gem 'rails-deprecated_sanitizer', '~> 1.0.3' gem 'rails-deprecated_sanitizer', '~> 1.0.3'
# Responders respond_to and respond_with # Responders respond_to and respond_with
......
...@@ -4,41 +4,41 @@ GEM ...@@ -4,41 +4,41 @@ GEM
CFPropertyList (2.3.2) CFPropertyList (2.3.2)
RedCloth (4.2.9) RedCloth (4.2.9)
ace-rails-ap (2.0.1) ace-rails-ap (2.0.1)
actionmailer (4.2.5.1) actionmailer (4.2.5.2)
actionpack (= 4.2.5.1) actionpack (= 4.2.5.2)
actionview (= 4.2.5.1) actionview (= 4.2.5.2)
activejob (= 4.2.5.1) activejob (= 4.2.5.2)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (4.2.5.1) actionpack (4.2.5.2)
actionview (= 4.2.5.1) actionview (= 4.2.5.2)
activesupport (= 4.2.5.1) activesupport (= 4.2.5.2)
rack (~> 1.6) rack (~> 1.6)
rack-test (~> 0.6.2) rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.5.1) actionview (4.2.5.2)
activesupport (= 4.2.5.1) activesupport (= 4.2.5.2)
builder (~> 3.1) builder (~> 3.1)
erubis (~> 2.7.0) erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
activejob (4.2.5.1) activejob (4.2.5.2)
activesupport (= 4.2.5.1) activesupport (= 4.2.5.2)
globalid (>= 0.3.0) globalid (>= 0.3.0)
activemodel (4.2.5.1) activemodel (4.2.5.2)
activesupport (= 4.2.5.1) activesupport (= 4.2.5.2)
builder (~> 3.1) builder (~> 3.1)
activerecord (4.2.5.1) activerecord (4.2.5.2)
activemodel (= 4.2.5.1) activemodel (= 4.2.5.2)
activesupport (= 4.2.5.1) activesupport (= 4.2.5.2)
arel (~> 6.0) arel (~> 6.0)
activerecord-deprecated_finders (1.0.4) activerecord-deprecated_finders (1.0.4)
activerecord-session_store (0.1.2) activerecord-session_store (0.1.2)
actionpack (>= 4.0.0, < 5) actionpack (>= 4.0.0, < 5)
activerecord (>= 4.0.0, < 5) activerecord (>= 4.0.0, < 5)
railties (>= 4.0.0, < 5) railties (>= 4.0.0, < 5)
activesupport (4.2.5.1) activesupport (4.2.5.2)
i18n (~> 0.7) i18n (~> 0.7)
json (~> 1.7, >= 1.7.7) json (~> 1.7, >= 1.7.7)
minitest (~> 5.1) minitest (~> 5.1)
...@@ -586,16 +586,16 @@ GEM ...@@ -586,16 +586,16 @@ GEM
rack rack
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rails (4.2.5.1) rails (4.2.5.2)
actionmailer (= 4.2.5.1) actionmailer (= 4.2.5.2)
actionpack (= 4.2.5.1) actionpack (= 4.2.5.2)
actionview (= 4.2.5.1) actionview (= 4.2.5.2)
activejob (= 4.2.5.1) activejob (= 4.2.5.2)
activemodel (= 4.2.5.1) activemodel (= 4.2.5.2)
activerecord (= 4.2.5.1) activerecord (= 4.2.5.2)
activesupport (= 4.2.5.1) activesupport (= 4.2.5.2)
bundler (>= 1.3.0, < 2.0) bundler (>= 1.3.0, < 2.0)
railties (= 4.2.5.1) railties (= 4.2.5.2)
sprockets-rails sprockets-rails
rails-deprecated_sanitizer (1.0.3) rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha) activesupport (>= 4.2.0.alpha)
...@@ -605,9 +605,9 @@ GEM ...@@ -605,9 +605,9 @@ GEM
rails-deprecated_sanitizer (>= 1.0.1) rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3) rails-html-sanitizer (1.0.3)
loofah (~> 2.0) loofah (~> 2.0)
railties (4.2.5.1) railties (4.2.5.2)
actionpack (= 4.2.5.1) actionpack (= 4.2.5.2)
activesupport (= 4.2.5.1) activesupport (= 4.2.5.2)
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rainbow (2.0.0) rainbow (2.0.0)
...@@ -987,7 +987,7 @@ DEPENDENCIES ...@@ -987,7 +987,7 @@ DEPENDENCIES
rack-attack (~> 4.3.1) rack-attack (~> 4.3.1)
rack-cors (~> 0.4.0) rack-cors (~> 0.4.0)
rack-oauth2 (~> 1.2.1) rack-oauth2 (~> 1.2.1)
rails (= 4.2.5.1) rails (= 4.2.5.2)
rails-deprecated_sanitizer (~> 1.0.3) rails-deprecated_sanitizer (~> 1.0.3)
raphael-rails (~> 2.1.2) raphael-rails (~> 2.1.2)
rblineprof rblineprof
......
...@@ -4,4 +4,7 @@ ...@@ -4,4 +4,7 @@
require File.expand_path('../config/application', __FILE__) require File.expand_path('../config/application', __FILE__)
relative_url_conf = File.expand_path('../config/initializers/relative_url', __FILE__)
require relative_url_conf if File.exist?("#{relative_url_conf}.rb")
Gitlab::Application.load_tasks Gitlab::Application.load_tasks
8.5.1 8.5.2
\ No newline at end of file \ No newline at end of file
...@@ -13,8 +13,10 @@ class @Shortcuts ...@@ -13,8 +13,10 @@ class @Shortcuts
if $('#modal-shortcuts').length > 0 if $('#modal-shortcuts').length > 0
$('#modal-shortcuts').modal('show') $('#modal-shortcuts').modal('show')
else else
url = '/help/shortcuts'
url = gon.relative_url_root + url if gon.relative_url_root?
$.ajax( $.ajax(
url: '/help/shortcuts', url: url,
dataType: 'script', dataType: 'script',
success: (e) -> success: (e) ->
if location and location.length > 0 if location and location.length > 0
......
...@@ -13,6 +13,19 @@ ...@@ -13,6 +13,19 @@
transition-duration: .3s; transition-duration: .3s;
} }
.gitlab-text-container-link {
z-index: 1;
position: absolute;
left: 0px;
}
#logo {
z-index: 2;
position: absolute;
width: 58px;
cursor: pointer;
}
&.right-sidebar-expanded { &.right-sidebar-expanded {
padding-right: $gutter_width; padding-right: $gutter_width;
} }
...@@ -87,7 +100,7 @@ ...@@ -87,7 +100,7 @@
width: 158px; width: 158px;
float: left; float: left;
margin: 0; margin: 0;
margin-left: 14px; margin-left: 50px;
font-size: 19px; font-size: 19px;
line-height: 41px; line-height: 41px;
font-weight: normal; font-weight: normal;
......
.appearance-logo-preview {
max-width: 400px;
margin-bottom: 20px;
}
.appearance-light-logo-preview {
background-color: $background-color;
max-width: 72px;
padding: 10px;
margin-bottom: 10px;
}
...@@ -39,7 +39,7 @@ li.milestone { ...@@ -39,7 +39,7 @@ li.milestone {
margin-right: 10px; margin-right: 10px;
} }
.time-elapsed { .remaining-days {
color: $orange-light; color: $orange-light;
} }
} }
......
class Admin::AppearancesController < Admin::ApplicationController
before_action :set_appearance, except: :create
def show
end
def preview
end
def create
@appearance = Appearance.new(appearance_params)
if @appearance.save
redirect_to admin_appearances_path, notice: 'Appearance was successfully created.'
else
render action: 'show'
end
end
def update
if @appearance.update(appearance_params)
redirect_to admin_appearances_path, notice: 'Appearance was successfully updated.'
else
render action: 'show'
end
end
def logo
@appearance.remove_logo!
@appearance.save
redirect_to admin_appearances_path, notice: 'Logo was succesfully removed.'
end
def header_logos
@appearance.remove_header_logo!
@appearance.save
redirect_to admin_appearances_path, notice: 'Header logo was succesfully removed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appearance
@appearance = Appearance.last || Appearance.new
end
# Only allow a trusted parameter "white list" through.
def appearance_params
params.require(:appearance).permit(
:title, :description, :logo, :logo_cache, :header_logo, :header_logo_cache,
:updated_by
)
end
end
...@@ -3,6 +3,7 @@ module Ci ...@@ -3,6 +3,7 @@ module Ci
before_action :project before_action :project
before_action :authorize_read_project!, except: [:badge] before_action :authorize_read_project!, except: [:badge]
before_action :no_cache, only: [:badge] before_action :no_cache, only: [:badge]
skip_before_action :authenticate_user!, only: [:badge]
protect_from_forgery protect_from_forgery
def show def show
...@@ -18,6 +19,7 @@ module Ci ...@@ -18,6 +19,7 @@ module Ci
# #
def badge def badge
return render_404 unless @project return render_404 unless @project
image = Ci::ImageForBuildService.new.execute(@project, params) image = Ci::ImageForBuildService.new.execute(@project, params)
send_file image.path, filename: image.name, disposition: 'inline', type:"image/svg+xml" send_file image.path, filename: image.name, disposition: 'inline', type:"image/svg+xml"
end end
......
...@@ -6,7 +6,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController ...@@ -6,7 +6,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
@projects = @projects.sort(@sort = params[:sort]) @projects = @projects.sort(@sort = params[:sort])
@projects = @projects.includes(:namespace) @projects = @projects.includes(:namespace)
terms = params['filter_projects'] terms = params[:filter_projects]
if terms.present? if terms.present?
@projects = @projects.search(terms) @projects = @projects.search(terms)
...@@ -35,7 +35,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController ...@@ -35,7 +35,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
@projects = @projects.includes(:namespace, :forked_from_project, :tags) @projects = @projects.includes(:namespace, :forked_from_project, :tags)
@projects = @projects.sort(@sort = params[:sort]) @projects = @projects.sort(@sort = params[:sort])
terms = params['filter_projects'] terms = params[:filter_projects]
if terms.present? if terms.present?
@projects = @projects.search(terms) @projects = @projects.search(terms)
......
...@@ -12,12 +12,14 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController ...@@ -12,12 +12,14 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
current_user.save! if current_user.changed? current_user.save! if current_user.changed?
if two_factor_authentication_required?
if two_factor_grace_period_expired? if two_factor_grace_period_expired?
flash.now[:alert] = 'You must enable Two-factor Authentication for your account.' flash.now[:alert] = 'You must enable Two-factor Authentication for your account.'
else else
grace_period_deadline = current_user.otp_grace_period_started_at + two_factor_grace_period.hours grace_period_deadline = current_user.otp_grace_period_started_at + two_factor_grace_period.hours
flash.now[:alert] = "You must enable Two-factor Authentication for your account before #{l(grace_period_deadline)}." flash.now[:alert] = "You must enable Two-factor Authentication for your account before #{l(grace_period_deadline)}."
end end
end
@qr_code = build_qr_code @qr_code = build_qr_code
end end
......
...@@ -4,12 +4,22 @@ class Projects::ForksController < Projects::ApplicationController ...@@ -4,12 +4,22 @@ class Projects::ForksController < Projects::ApplicationController
before_action :authorize_download_code! before_action :authorize_download_code!
def index def index
@sort = params[:sort] || 'id_desc' base_query = project.forks.includes(:creator)
@all_forks = project.forks.includes(:creator).order_by(@sort)
@public_forks, @protected_forks = @all_forks.partition do |project| @forks = if current_user
can?(current_user, :read_project, project) base_query.where('projects.visibility_level IN (?) OR projects.id IN (?)',
Project.public_and_internal_levels,
current_user.authorized_projects.pluck(:id))
else
base_query.where('projects.visibility_level = ?', Project::PUBLIC)
end end
@total_forks_count = base_query.size
@private_forks_count = @total_forks_count - @forks.size
@public_forks_count = @total_forks_count - @private_forks_count
@sort = params[:sort] || 'id_desc'
@forks = @forks.order_by(@sort).page(params[:page]).per(PER_PAGE)
end end
def new def new
......
...@@ -34,6 +34,11 @@ class Projects::TagsController < Projects::ApplicationController ...@@ -34,6 +34,11 @@ class Projects::TagsController < Projects::ApplicationController
def destroy def destroy
DeleteTagService.new(project, current_user).execute(params[:id]) DeleteTagService.new(project, current_user).execute(params[:id])
respond_to do |format|
format.html do
redirect_to namespace_project_tags_path(@project.namespace, @project) redirect_to namespace_project_tags_path(@project.namespace, @project)
end end
format.js
end
end
end end
...@@ -55,14 +55,15 @@ class UploadsController < ApplicationController ...@@ -55,14 +55,15 @@ class UploadsController < ApplicationController
"user" => User, "user" => User,
"project" => Project, "project" => Project,
"note" => Note, "note" => Note,
"group" => Group "group" => Group,
"appearance" => Appearance
} }
upload_models[params[:model]] upload_models[params[:model]]
end end
def upload_mount def upload_mount
upload_mounts = %w(avatar attachment file) upload_mounts = %w(avatar attachment file logo header_logo)
if upload_mounts.include?(params[:mounted_as]) if upload_mounts.include?(params[:mounted_as])
params[:mounted_as] params[:mounted_as]
......
module AppearancesHelper module AppearancesHelper
def brand_item
nil
end
def brand_title def brand_title
if brand_item && brand_item.title
brand_item.title
else
#'GitLab Community Edition' #'GitLab Community Edition'
'GitLab Nexedi Edition' 'GitLab Nexedi Edition'
end end
end
def brand_image def brand_image
if brand_item.logo?
image_tag brand_item.logo
else
nil nil
end end
end
def brand_text def brand_text
nil markdown(brand_item.description)
end
def brand_item
@appearance ||= Appearance.first
end end
def brand_header_logo def brand_header_logo
if brand_item && brand_item.header_logo?
image_tag brand_item.header_logo
else
render 'shared/logo.svg' render 'shared/logo.svg'
end end
end
end end
...@@ -36,4 +36,14 @@ module MilestonesHelper ...@@ -36,4 +36,14 @@ module MilestonesHelper
options_from_collection_for_select(grouped_milestones, 'name', 'title', params[:milestone_title]) options_from_collection_for_select(grouped_milestones, 'name', 'title', params[:milestone_title])
end end
def milestone_remaining_days(milestone)
if milestone.expired?
content_tag(:strong, 'expired')
elsif milestone.due_date
days = milestone.remaining_days
content = content_tag(:strong, days)
content << " #{'day'.pluralize(days)} remaining"
end
end
end end
class Appearance < ActiveRecord::Base
validates :title, presence: true
validates :description, presence: true
validates :logo, file_size: { maximum: 1.megabyte }
validates :header_logo, file_size: { maximum: 1.megabyte }
mount_uploader :logo, AttachmentUploader
mount_uploader :header_logo, AttachmentUploader
end
...@@ -27,7 +27,7 @@ class Milestone < ActiveRecord::Base ...@@ -27,7 +27,7 @@ class Milestone < ActiveRecord::Base
belongs_to :project belongs_to :project
has_many :issues has_many :issues
has_many :labels, through: :issues has_many :labels, -> { distinct.reorder('labels.title') }, through: :issues
has_many :merge_requests has_many :merge_requests
has_many :participants, through: :issues, source: :assignee has_many :participants, through: :issues, source: :assignee
...@@ -110,17 +110,10 @@ class Milestone < ActiveRecord::Base ...@@ -110,17 +110,10 @@ class Milestone < ActiveRecord::Base
0 0
end end
# Returns the elapsed time (in percent) since the Milestone creation date until today. def remaining_days
# If the Milestone doesn't have a due_date then returns 0 since we can't calculate the elapsed time. return 0 if !due_date || expired?
# If the Milestone is overdue then it returns 100%.
def percent_time_used
return 0 unless due_date
return 100 if expired?
duration = ((created_at - due_date.to_datetime) / 1.day) (due_date - Date.today).to_i
days_elapsed = ((created_at - Time.now) / 1.day)
((days_elapsed.to_f / duration) * 100).floor
end end
def expires_at def expires_at
......
...@@ -358,6 +358,7 @@ class User < ActiveRecord::Base ...@@ -358,6 +358,7 @@ class User < ActiveRecord::Base
encrypted_otp_secret: nil, encrypted_otp_secret: nil,
encrypted_otp_secret_iv: nil, encrypted_otp_secret_iv: nil,
encrypted_otp_secret_salt: nil, encrypted_otp_secret_salt: nil,
otp_grace_period_started_at: nil,
otp_backup_codes: nil otp_backup_codes: nil
) )
end end
......
= form_for @appearance, url: admin_appearances_path, html: { class: 'form-horizontal'} do |f|
- if @appearance.errors.any?
.alert.alert-danger
- @appearance.errors.full_messages.each do |msg|
%p= msg
%fieldset.sign-in
%legend
Sign in/Sign up pages:
.form-group
= f.label :title, class: 'control-label'
.col-sm-10
= f.text_field :title, class: "form-control"
.form-group
= f.label :description, class: 'control-label'
.col-sm-10
= f.text_area :description, class: "form-control", rows: 10
.hint
Description parsed with #{link_to "GitLab Flavored Markdown", help_page_path('markdown', 'markdown'), target: '_blank'}.
.form-group
= f.label :logo, class: 'control-label'
.col-sm-10
- if @appearance.logo?
= image_tag @appearance.logo_url, class: 'appearance-logo-preview'
- if @appearance.persisted?
%br
= link_to 'Remove logo', logo_admin_appearances_path, data: { confirm: "Logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-logo"
%hr
= f.hidden_field :logo_cache
= f.file_field :logo, class: ""
.hint
Maximum file size is 1MB. Pages are optimized for a 640x360 px logo.
%fieldset.app_logo
%legend
Navigation bar:
.form-group
= f.label :header_logo, 'Header logo', class: 'control-label'
.col-sm-10
- if @appearance.header_logo?
= image_tag @appearance.header_logo_url, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
= link_to 'Remove header logo', header_logos_admin_appearances_path, data: { confirm: "Header logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-logo"
%hr
= f.hidden_field :header_logo_cache
= f.file_field :header_logo, class: ""
.hint
Maximum file size is 1MB. Pages are optimized for a 72x72 px header logo
.form-actions
= f.submit 'Save', class: 'btn btn-save'
- if @appearance.persisted?
= link_to 'Preview last save', preview_admin_appearances_path, class: 'btn', target: '_blank'
- if @appearance.updated_at
%span.pull-right
Last edit #{time_ago_with_tooltip(@appearance.updated_at)}
- page_title "Preview | Appearance"
%h3.page-title
Appearance settings - Preview
%hr
.ui-box
.title
Sign-in page
%div
.login-page
.container
.content
.login-title
%h1= brand_title
%hr
.container
.content
.row
.col-sm-7
.brand-image
= brand_image
.brand_text
= brand_text
.col-sm-4
.login-box
%h3.page-title Sign in
= text_field_tag :login, nil, class: "form-control top", placeholder: "Username or Email"
= password_field_tag :password, nil, class: "form-control bottom", placeholder: "Password"
= button_tag "Sign in", class: "btn-create btn"
- page_title "Appearance"
%h3.page-title
Appearance settings
%p.light
You can modify the look and feel of GitLab here
= render 'form'
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
- if @last_push - if @last_push
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
- if @projects.any? - if @projects.any? || params[:filter_projects]
= render 'projects' = render 'projects'
- else - else
= render "zero_authorized_projects" = render "zero_authorized_projects"
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.header-logo .header-logo
%a#logo %a#logo
= brand_header_logo = brand_header_logo
= link_to root_path, class: 'home', title: 'Dashboard', id: 'js-shortcuts-home' do = link_to root_path, class: 'gitlab-text-container-link', title: 'Dashboard', id: 'js-shortcuts-home' do
.gitlab-text-container .gitlab-text-container
%h3 GitLab %h3 GitLab
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.header-logo .header-logo
%a#logo %a#logo
= brand_header_logo = brand_header_logo
= link_to root_path, class: 'home', title: 'Dashboard', id: 'js-shortcuts-home' do = link_to root_path, class: 'gitlab-text-container-link', title: 'Dashboard', id: 'js-shortcuts-home' do
.gitlab-text-container .gitlab-text-container
%h3 GitLab %h3 GitLab
......
...@@ -56,6 +56,11 @@ ...@@ -56,6 +56,11 @@
= icon('cog fw') = icon('cog fw')
%span %span
Background Jobs Background Jobs
= nav_link(controller: :appearances) do
= link_to admin_appearances_path, title: 'Appearances' do
= icon('image')
%span
Appearance
= nav_link(controller: :applications) do = nav_link(controller: :applications) do
= link_to admin_applications_path, title: 'Applications' do = link_to admin_applications_path, title: 'Applications' do
......
.top-area .top-area
.nav-text .nav-text
- public_count = @public_forks.size - full_count_title = "#{@public_forks_count} public and #{@private_forks_count} private"
- protected_count = @protected_forks.size == #{pluralize(@total_forks_count, 'fork')}: #{full_count_title}
- full_count_title = "#{public_count} public and #{protected_count} private"
== #{pluralize(@all_forks.size, 'fork')}: #{full_count_title}
.nav-controls .nav-controls
= search_field_tag :filter_projects, nil, placeholder: 'Search forks', class: 'projects-list-filter project-filter-form-field form-control input-short', = search_field_tag :filter_projects, nil, placeholder: 'Search forks', class: 'projects-list-filter project-filter-form-field form-control input-short',
...@@ -41,17 +39,17 @@ ...@@ -41,17 +39,17 @@
.projects-list-holder .projects-list-holder
- if @public_forks.blank? - if @forks.blank?
%ul.content-list %ul.content-list
%li %li
.nothing-here-block No forks to show .nothing-here-block No forks to show
- else - else
= render 'shared/projects/list', projects: @public_forks, use_creator_avatar: true, = render 'shared/projects/list', projects: @forks, use_creator_avatar: true,
forks: true, show_last_commit_as_description: true forks: true, show_last_commit_as_description: true
- if protected_count > 0 - if @private_forks_count > 0
%ul.projects-list.private-forks-notice %ul.projects-list.private-forks-notice
%li.project-row %li.project-row
= icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon') = icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon')
%strong= pluralize(protected_count, 'private fork') %strong= pluralize(@private_forks_count, 'private fork')
%span you have no access to. %span you have no access to.
...@@ -60,9 +60,7 @@ ...@@ -60,9 +60,7 @@
%strong== #{@milestone.percent_complete}% %strong== #{@milestone.percent_complete}%
complete complete
%span.milestone-stat %span.milestone-stat
%span.time-elapsed %span.remaining-days= milestone_remaining_days(@milestone)
%strong== #{@milestone.percent_time_used}%
time elapsed
%span.pull-right.tab-issues-buttons %span.pull-right.tab-issues-buttons
- if can?(current_user, :create_issue, @project) - if can?(current_user, :create_issue, @project)
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { milestone_id: @milestone.id }), class: "btn btn-grouped", title: "New Issue" do = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { milestone_id: @milestone.id }), class: "btn btn-grouped", title: "New Issue" do
......
$('.js-totaltags-count').html("#{@repository.tags.size}");
- if @repository.tags.empty?
$('.tags').load(document.URL + ' .nothing-here-block').hide().fadeIn(1000)
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
Show all Show all
= paginate projects, theme: "gitlab" if projects.respond_to? :total_pages = paginate projects, theme: "gitlab" if projects.respond_to? :total_pages
- else - else
%h3 No projects found .nothing-here-block No projects found
:javascript :javascript
new ProjectsList(); new ProjectsList();
......
...@@ -54,14 +54,6 @@ module Gitlab ...@@ -54,14 +54,6 @@ module Gitlab
config.action_view.sanitized_allowed_protocols = %w(smb) config.action_view.sanitized_allowed_protocols = %w(smb)
# Relative URL support
# WARNING: We recommend using an FQDN to host GitLab in a root path instead
# of using a relative URL.
# Documentation: http://doc.gitlab.com/ce/install/relative_url.html
# Uncomment and customize the following line to run in a non-root path
#
# config.relative_url_root = "/gitlab"
config.middleware.use Rack::Attack config.middleware.use Rack::Attack
# Allow access to GitLab API from other domains # Allow access to GitLab API from other domains
......
# Relative URL support
# WARNING: We recommend using an FQDN to host GitLab in a root path instead
# of using a relative URL.
# Documentation: http://doc.gitlab.com/ce/install/relative_url.html
# Copy this file to relative_url.rb and customize it to run in a non-root path
#
Rails.application.configure do
config.relative_url_root = "/gitlab"
end
...@@ -154,6 +154,11 @@ Rails.application.routes.draw do ...@@ -154,6 +154,11 @@ Rails.application.routes.draw do
to: "uploads#show", to: "uploads#show",
constraints: { model: /note|user|group|project/, mounted_as: /avatar|attachment/, filename: /[^\/]+/ } constraints: { model: /note|user|group|project/, mounted_as: /avatar|attachment/, filename: /[^\/]+/ }
# Appearance
get ":model/:mounted_as/:id/:filename",
to: "uploads#show",
constraints: { model: /appearance/, mounted_as: /logo|header_logo/, filename: /.+/ }
# Project markdown uploads # Project markdown uploads
get ":namespace_id/:project_id/:secret/:filename", get ":namespace_id/:project_id/:secret/:filename",
to: "projects/uploads#show", to: "projects/uploads#show",
...@@ -251,6 +256,14 @@ Rails.application.routes.draw do ...@@ -251,6 +256,14 @@ Rails.application.routes.draw do
end end
end end
resource :appearances, path: 'appearance' do
member do
get :preview
delete :logo
delete :header_logos
end
end
resource :application_settings, only: [:show, :update] do resource :application_settings, only: [:show, :update] do
resources :services resources :services
put :reset_runners_token put :reset_runners_token
......
class CreateAppearancesCe < ActiveRecord::Migration
def change
unless table_exists?(:appearances)
create_table :appearances do |t|
t.string :title
t.text :description
t.string :header_logo
t.string :logo
t.timestamps null: false
end
end
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160220123949) do ActiveRecord::Schema.define(version: 20160222153918) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -24,6 +24,15 @@ ActiveRecord::Schema.define(version: 20160220123949) do ...@@ -24,6 +24,15 @@ ActiveRecord::Schema.define(version: 20160220123949) do
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "appearances", force: :cascade do |t|
t.string "title"
t.text "description"
t.string "header_logo"
t.string "logo"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "application_settings", force: :cascade do |t| create_table "application_settings", force: :cascade do |t|
t.integer "default_projects_limit" t.integer "default_projects_limit"
t.boolean "signup_enabled" t.boolean "signup_enabled"
......
# Changing the appearance of the login page
GitLab Community Edition offers a way to put your company's identity on the login page of your GitLab server and make it a branded login page.
By default, the page shows the GitLab logo and description.
![default_login_page](branded_login_page/default_login_page.png)
## Changing the appearance of the login page
Navigate to the **Admin** area and go to the **Appearance** page.
Fill in the required details like Title, Description and upload the company logo.
![appearance](branded_login_page/appearance.png)
After saving the page, your GitLab login page will have the details you filled in:
![company_login_page](branded_login_page/custom_sign_in.png)
# Customize the complete sign-in page (GitLab Enterprise Edition only) # Customize the complete sign-in page
Please see [Branded login page](http://doc.gitlab.com/ee/customization/branded_login_page.html) Please see [Branded login page](branded_login_page.md)
# Add a welcome message to the sign-in page (GitLab Community Edition) # Add a welcome message to the sign-in page (GitLab Community Edition)
It is possible to add a markdown-formatted welcome message to your GitLab It is possible to add a markdown-formatted welcome message to your GitLab
sign-in page. Users of GitLab Enterprise Edition should use the [branded login sign-in page. Users of GitLab Enterprise Edition should use the [branded login
page feature](/ee/customization/branded_login_page.html) instead. page feature](branded_login_page.md) instead.
The welcome message (extra_sign_in_text) can now be set/changed in the Admin UI. The welcome message (extra_sign_in_text) can now be set/changed in the Admin UI.
Admin area > Settings Admin area > Settings
...@@ -25,7 +25,7 @@ that points to your GitLab instance. ...@@ -25,7 +25,7 @@ that points to your GitLab instance.
The TL;DR list of configuration files that you need to change in order to The TL;DR list of configuration files that you need to change in order to
serve GitLab under a relative URL is: serve GitLab under a relative URL is:
- `/home/git/gitlab/config/application.rb` - `/home/git/gitlab/config/initializers/relative_url.rb`
- `/home/git/gitlab/config/gitlab.yml` - `/home/git/gitlab/config/gitlab.yml`
- `/home/git/gitlab/config/unicorn.rb` - `/home/git/gitlab/config/unicorn.rb`
- `/home/git/gitlab-shell/config.yml` - `/home/git/gitlab-shell/config.yml`
...@@ -66,8 +66,14 @@ Make sure to follow all steps below: ...@@ -66,8 +66,14 @@ Make sure to follow all steps below:
sudo service gitlab stop sudo service gitlab stop
``` ```
1. Edit `/home/git/gitlab/config/application.rb` and uncomment/change the 1. Create `/home/git/gitlab/config/initializers/relative_url.rb`
following line:
```shell
cp /home/git/gitlab/config/initializers/relative_url.rb.sample \
/home/git/gitlab/config/initializers/relative_url.rb
```
and change the following line:
```ruby ```ruby
config.relative_url_root = "/gitlab" config.relative_url_root = "/gitlab"
...@@ -119,8 +125,12 @@ Make sure to follow all steps below: ...@@ -119,8 +125,12 @@ Make sure to follow all steps below:
### Disable relative URL in GitLab ### Disable relative URL in GitLab
To disable the relative URL, follow the same steps as above and set up the To disable the relative URL:
GitLab URL to one that doesn't contain a relative path.
1. Remove `/home/git/gitlab/config/initializers/relative_url.rb`
1. Follow the same as above starting from 2. and set up the
GitLab URL to one that doesn't contain a relative path.
[omnibus-rel]: http://doc.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to setup relative URL in Omnibus GitLab" [omnibus-rel]: http://doc.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to setup relative URL in Omnibus GitLab"
[restart gitlab]: ../administration/restart_gitlab.md#installations-from-source "How to restart GitLab" [restart gitlab]: ../administration/restart_gitlab.md#installations-from-source "How to restart GitLab"
...@@ -22,3 +22,4 @@ ...@@ -22,3 +22,4 @@
- [Merge When Build Succeeds](merge_when_build_succeeds.md) - [Merge When Build Succeeds](merge_when_build_succeeds.md)
- [Manage large binaries with Git LFS](lfs/manage_large_binaries_with_git_lfs.md) - [Manage large binaries with Git LFS](lfs/manage_large_binaries_with_git_lfs.md)
- [Importing from SVN, GitHub, BitBucket, etc](importing/README.md) - [Importing from SVN, GitHub, BitBucket, etc](importing/README.md)
- [Todos](todos.md)
# GitLab ToDos
>**Note:** This feature was [introduced][ce-2817] in GitLab 8.5.
When you log into GitLab, you normally want to see where you should spend your
time and take some action, or what you need to keep an eye on. All without the
mess of a huge pile of e-mail notifications. GitLab is where you do your work,
so being able to get started quickly is very important.
Todos is a chronological list of to-dos that are waiting for your input, all
in a simple dashboard.
![Todos screenshot showing a list of items to check on](img/todos_index.png)
---
You can access quickly your Todos dashboard by clicking the round gray icon
next to the search bar in the upper right corner.
![Todos icon](img/todos_icon.png)
## What triggers a Todo
A Todo appears in your Todos dashboard when:
- an issue or merge request is assigned to you
- you are `@mentioned` in an issue or merge request, be it the description of
the issue/merge request or in a comment
>**Note:** Commenting on a commit will _not_ trigger a Todo.
## How a Todo is marked as Done
Any action to the corresponding issue or merge request will mark your Todo as
**Done**. This action can include:
- changing the assignee
- changing the milestone
- adding/removing a label
- commenting on the issue
In case where you think no action is needed, you can manually mark the todo as
done by clicking the corresponding **Done** button, and it will disappear from
your Todos list. If you want to mark all your Todos as done, just click on the
**Mark all as done** button.
---
In order for a Todo to be marked as done, the action must be coming from you.
So, if you close the related issue or merge the merge request yourself, and you
had a Todo for that, it will automatically get marked as done. On the other
hand, if someone else closes, merges or takes action on the issue or merge
request, your Todo will remain pending. This makes sense because you may need
to give attention to an issue even if it has been resolved.
There is just one Todo per issue or merge request, so mentioning a user a
hundred times in an issue will only trigger one Todo.
## Filtering your Todos
In general, there are four kinds of filters you can use on your Todos
dashboard:
| Filter | Description |
| ------ | ----------- |
| Project | Filter by project |
| Author | Filter by the author that triggered the Todo |
| Type | Filter by issue or merge request |
| Action | Filter by the action that triggered the Todo (Assigned or Mentioned)|
You can choose more than one filters at the same time.
[ce-2817]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/2817
Feature: Admin Appearance
Scenario: Create new appearance
Given I sign in as an admin
And I visit admin appearance page
When submit form with new appearance
Then I should be redirected to admin appearance page
And I should see newly created appearance
Scenario: Preview appearance
Given application has custom appearance
And I sign in as an admin
When I visit admin appearance page
And I click preview button
Then I should see a customized appearance
Scenario: Custom sign-in page
Given application has custom appearance
When I visit login page
Then I should see a customized appearance
Scenario: Appearance logo
Given application has custom appearance
And I sign in as an admin
And I visit admin appearance page
When I attach a logo
Then I should see a logo
And I remove the logo
Then I should see logo removed
Scenario: Header logos
Given application has custom appearance
And I sign in as an admin
And I visit admin appearance page
When I attach header logos
Then I should see header logos
And I remove the header logos
Then I should see header logos removed
...@@ -13,6 +13,7 @@ Feature: Project Milestone ...@@ -13,6 +13,7 @@ Feature: Project Milestone
Given I visit project "Shop" milestones page Given I visit project "Shop" milestones page
And I click link "v2.2" And I click link "v2.2"
Then I should see the labels "bug", "enhancement" and "feature" Then I should see the labels "bug", "enhancement" and "feature"
And I should see the "bug" label listed only once
@javascript @javascript
Scenario: Listing labels from labels tab Scenario: Listing labels from labels tab
......
class Spinach::Features::AdminAppearance < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
step 'submit form with new appearance' do
fill_in 'appearance_title', with: 'MyCompany'
fill_in 'appearance_description', with: 'dev server'
click_button 'Save'
end
step 'I should be redirected to admin appearance page' do
expect(current_path).to eq admin_appearances_path
expect(page).to have_content 'Appearance settings'
end
step 'I should see newly created appearance' do
expect(page).to have_field('appearance_title', with: 'MyCompany')
expect(page).to have_field('appearance_description', with: 'dev server')
expect(page).to have_content 'Last edit'
end
step 'I click preview button' do
click_link "Preview"
end
step 'application has custom appearance' do
create(:appearance)
end
step 'I should see a customized appearance' do
expect(page).to have_content appearance.title
expect(page).to have_content appearance.description
end
step 'I attach a logo' do
attach_file(:appearance_logo, Rails.root.join('spec', 'fixtures', 'dk.png'))
click_button 'Save'
end
step 'I attach header logos' do
attach_file(:appearance_header_logo, Rails.root.join('spec', 'fixtures', 'dk.png'))
click_button 'Save'
end
step 'I should see a logo' do
expect(page).to have_xpath('//img[@src="/uploads/appearance/logo/1/dk.png"]')
end
step 'I should see header logos' do
expect(page).to have_xpath('//img[@src="/uploads/appearance/header_logo/1/dk.png"]')
end
step 'I remove the logo' do
click_link 'Remove logo'
end
step 'I remove the header logos' do
click_link 'Remove header logo'
end
step 'I should see logo removed' do
expect(page).not_to have_xpath('//img[@src="/uploads/appearance/logo/1/gitlab_logo.png"]')
end
step 'I should see header logos removed' do
expect(page).not_to have_xpath('//img[@src="/uploads/appearance/header_logo/1/header_logo_light.png"]')
end
def appearance
Appearance.last
end
end
...@@ -41,6 +41,12 @@ class Spinach::Features::ProjectMilestone < Spinach::FeatureSteps ...@@ -41,6 +41,12 @@ class Spinach::Features::ProjectMilestone < Spinach::FeatureSteps
end end
end end
step 'I should see the "bug" label listed only once' do
page.within('#tab-labels') do
expect(page).to have_content('bug', count: 1)
end
end
step 'I click link "v2.2"' do step 'I click link "v2.2"' do
click_link "v2.2" click_link "v2.2"
end end
......
...@@ -7,6 +7,10 @@ module SharedPaths ...@@ -7,6 +7,10 @@ module SharedPaths
visit new_project_path visit new_project_path
end end
step 'I visit login page' do
visit new_user_session_path
end
# ---------------------------------------- # ----------------------------------------
# User # User
# ---------------------------------------- # ----------------------------------------
...@@ -187,6 +191,10 @@ module SharedPaths ...@@ -187,6 +191,10 @@ module SharedPaths
visit admin_groups_path visit admin_groups_path
end end
step 'I visit admin appearance page' do
visit admin_appearances_path
end
step 'I visit admin teams page' do step 'I visit admin teams page' do
visit admin_teams_path visit admin_teams_path
end end
......
...@@ -12,7 +12,7 @@ module Gitlab ...@@ -12,7 +12,7 @@ module Gitlab
end end
def execute def execute
project_identifier = CGI.escape(project.import_source, '/') project_identifier = CGI.escape(project.import_source)
#Issues && Comments #Issues && Comments
issues = client.issues(project_identifier) issues = client.issues(project_identifier)
......
require 'spec_helper'
describe Ci::ProjectsController do
let(:visibility) { :public }
let!(:project) { create(:project, visibility, ci_id: 1) }
let(:ci_id) { project.ci_id }
##
# Specs for *deprecated* CI badge
#
describe '#badge' do
shared_examples 'badge provider' do
it 'shows badge' do
expect(response.status).to eq 200
expect(response.headers)
.to include('Content-Type' => 'image/svg+xml')
end
end
context 'user not signed in' do
before { get(:badge, id: ci_id) }
context 'project has no ci_id reference' do
let(:ci_id) { 123 }
it 'returns 404' do
expect(response.status).to eq 404
end
end
context 'project is public' do
let(:visibility) { :public }
it_behaves_like 'badge provider'
end
context 'project is private' do
let(:visibility) { :private }
it_behaves_like 'badge provider'
end
end
context 'user signed in' do
let(:user) { create(:user) }
before { sign_in(user) }
before { get(:badge, id: ci_id) }
context 'private is internal' do
let(:visibility) { :internal }
it_behaves_like 'badge provider'
end
end
end
end
...@@ -32,6 +32,7 @@ FactoryGirl.define do ...@@ -32,6 +32,7 @@ FactoryGirl.define do
before(:create) do |user| before(:create) do |user|
user.two_factor_enabled = true user.two_factor_enabled = true
user.otp_secret = User.generate_otp_secret(32) user.otp_secret = User.generate_otp_secret(32)
user.otp_grace_period_started_at = Time.now
user.generate_otp_backup_codes! user.generate_otp_backup_codes!
end end
end end
......
# Read about factories at https://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :appearance do
title "MepMep"
description "This is my Community Edition instance"
end
end
require 'rails_helper'
RSpec.describe Appearance, type: :model do
subject { create(:appearance) }
it { is_expected.to be_valid }
it { is_expected.to validate_presence_of(:title) }
it { is_expected.to validate_presence_of(:description) }
end
...@@ -256,6 +256,7 @@ describe User, models: true do ...@@ -256,6 +256,7 @@ describe User, models: true do
expect(user).to be_two_factor_enabled expect(user).to be_two_factor_enabled
expect(user.encrypted_otp_secret).not_to be_nil expect(user.encrypted_otp_secret).not_to be_nil
expect(user.otp_backup_codes).not_to be_nil expect(user.otp_backup_codes).not_to be_nil
expect(user.otp_grace_period_started_at).not_to be_nil
user.disable_two_factor! user.disable_two_factor!
...@@ -264,6 +265,7 @@ describe User, models: true do ...@@ -264,6 +265,7 @@ describe User, models: true do
expect(user.encrypted_otp_secret_iv).to be_nil expect(user.encrypted_otp_secret_iv).to be_nil
expect(user.encrypted_otp_secret_salt).to be_nil expect(user.encrypted_otp_secret_salt).to be_nil
expect(user.otp_backup_codes).to be_nil expect(user.otp_backup_codes).to be_nil
expect(user.otp_grace_period_started_at).to be_nil
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment