BigW Consortium Gitlab

Commit c71792d9 by Dmitriy Zaporozhets

Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq

parents d0ebdedf 9306d8fc
v 7.5.0 v 7.5.0
- API: Add support for Hipchat (Kevin Houdebert) - API: Add support for Hipchat (Kevin Houdebert)
- Add time zone configuration on gitlab.yml (Sullivan Senechal) - Add time zone configuration on gitlab.yml (Sullivan Senechal)
- Fix LDAP authentication for Git HTTP access
- Fix LDAP config lookup for provider 'ldap'
v 7.4.2
- Fix internal snippet exposing for unauthenticated users
v 7.4.1
- Fix LDAP authentication for Git HTTP access
- Fix LDAP config lookup for provider 'ldap'
- Fix public snippets
- Fix 500 error on projects with nested submodules
v 7.4.0 v 7.4.0
- Refactored membership logic - Refactored membership logic
......
...@@ -31,7 +31,7 @@ gem 'omniauth-shibboleth' ...@@ -31,7 +31,7 @@ gem 'omniauth-shibboleth'
# Extracting information from a git repository # Extracting information from a git repository
# Provide access to Gitlab::Git library # Provide access to Gitlab::Git library
gem "gitlab_git", '7.0.0.rc9' gem "gitlab_git", '7.0.0.rc10'
# Ruby/Rack Git Smart-HTTP Server Handler # Ruby/Rack Git Smart-HTTP Server Handler
gem 'gitlab-grack', '~> 2.0.0.pre', require: 'grack' gem 'gitlab-grack', '~> 2.0.0.pre', require: 'grack'
......
...@@ -179,7 +179,7 @@ GEM ...@@ -179,7 +179,7 @@ GEM
mime-types (~> 1.19) mime-types (~> 1.19)
gitlab_emoji (0.0.1.1) gitlab_emoji (0.0.1.1)
emoji (~> 1.0.1) emoji (~> 1.0.1)
gitlab_git (7.0.0.rc9) gitlab_git (7.0.0.rc10)
activesupport (~> 4.0) activesupport (~> 4.0)
charlock_holmes (~> 0.6) charlock_holmes (~> 0.6)
gitlab-linguist (~> 3.0) gitlab-linguist (~> 3.0)
...@@ -624,7 +624,7 @@ DEPENDENCIES ...@@ -624,7 +624,7 @@ DEPENDENCIES
gitlab-grack (~> 2.0.0.pre) gitlab-grack (~> 2.0.0.pre)
gitlab-linguist (~> 3.0.0) gitlab-linguist (~> 3.0.0)
gitlab_emoji (~> 0.0.1.1) gitlab_emoji (~> 0.0.1.1)
gitlab_git (= 7.0.0.rc9) gitlab_git (= 7.0.0.rc10)
gitlab_meta (= 7.0) gitlab_meta (= 7.0)
gitlab_omniauth-ldap (= 1.1.0) gitlab_omniauth-ldap (= 1.1.0)
gollum-lib (~> 3.0.0) gollum-lib (~> 3.0.0)
......
...@@ -55,14 +55,8 @@ Since a manual installation is a lot of work and error prone we strongly recomme ...@@ -55,14 +55,8 @@ Since a manual installation is a lot of work and error prone we strongly recomme
## Third-party applications ## Third-party applications
Access GitLab from multiple platforms with applications below. There are a lot of applications and API wrappers for GitLab.
These applications are maintained by contributors, GitLab B.V. does not offer support for them. Find them [on our website](https://about.gitlab.com/applications/).
- [iPhone app](http://gitlabcontrol.com/)
- [Android app](https://play.google.com/store/apps/details?id=com.bd.gitlab&hl=en)
- [Chrome app](https://chrome.google.com/webstore/detail/chrome-gitlab-notifier/eageapgbnjicdjjihgclpclilenjbobi)
- [Command line client](https://github.com/drewblessing/gitlab-cli)
- [Ruby API wrapper](https://github.com/NARKOZ/gitlab)
### New versions ### New versions
......
...@@ -63,7 +63,7 @@ window.extractLast = (term) -> ...@@ -63,7 +63,7 @@ window.extractLast = (term) ->
return split( term ).pop() return split( term ).pop()
window.rstrip = (val) -> window.rstrip = (val) ->
return val.replace(/\s+$/, '') return if val then val.replace(/\s+$/, '') else val
# Disable button if text field is empty # Disable button if text field is empty
window.disableButtonIfEmptyField = (field_selector, button_selector) -> window.disableButtonIfEmptyField = (field_selector, button_selector) ->
......
...@@ -58,15 +58,13 @@ class Dispatcher ...@@ -58,15 +58,13 @@ class Dispatcher
when 'groups:show', 'projects:show' when 'groups:show', 'projects:show'
new Activities() new Activities()
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
when 'projects:new'
new Project()
when 'projects:edit'
new Project()
shortcut_handler = new ShortcutsNavigation()
when 'projects:teams:members:index' when 'projects:teams:members:index'
new TeamMembers() new TeamMembers()
when 'groups:members' when 'groups:members'
new GroupMembers() new GroupMembers()
new UsersSelect()
when 'groups:new', 'groups:edit', 'admin:groups:edit'
new GroupAvatar()
when 'projects:tree:show' when 'projects:tree:show'
new TreeView() new TreeView()
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
...@@ -79,13 +77,33 @@ class Dispatcher ...@@ -79,13 +77,33 @@ class Dispatcher
# Ensure we don't create a particular shortcut handler here. This is # Ensure we don't create a particular shortcut handler here. This is
# already created, where the network graph is created. # already created, where the network graph is created.
shortcut_handler = true shortcut_handler = true
when 'users:show'
new User()
switch path.first() switch path.first()
when 'admin' then new Admin() when 'admin'
new Admin()
switch path[1]
when 'groups'
new UsersSelect()
when 'projects'
new NamespaceSelect()
when 'dashboard' when 'dashboard'
shortcut_handler = new ShortcutsDashboardNavigation() shortcut_handler = new ShortcutsDashboardNavigation()
when 'profiles'
new Profile()
when 'projects' when 'projects'
new Project()
switch path[1] switch path[1]
when 'edit'
shortcut_handler = new ShortcutsNavigation()
new ProjectNew()
when 'new'
new ProjectNew()
when 'show'
new ProjectShow()
when 'issues', 'merge_requests'
new ProjectUsersSelect()
when 'wikis' when 'wikis'
new Wikis() new Wikis()
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
...@@ -94,6 +112,7 @@ class Dispatcher ...@@ -94,6 +112,7 @@ class Dispatcher
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
when 'team_members', 'deploy_keys', 'hooks', 'services', 'protected_branches' when 'team_members', 'deploy_keys', 'hooks', 'services', 'protected_branches'
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
new UsersSelect()
# If we haven't installed a custom shortcut handler, install the default one # If we haven't installed a custom shortcut handler, install the default one
......
class @GroupAvatar
constructor: ->
$('.js-choose-group-avatar-button').bind "click", ->
form = $(this).closest("form")
form.find(".js-group-avatar-input").click()
$('.js-group-avatar-input').bind "change", ->
form = $(this).closest("form")
filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find(".js-avatar-filename").text(filename)
...@@ -2,14 +2,3 @@ class @GroupMembers ...@@ -2,14 +2,3 @@ class @GroupMembers
constructor: -> constructor: ->
$('li.group_member').bind 'ajax:success', -> $('li.group_member').bind 'ajax:success', ->
$(this).fadeOut() $(this).fadeOut()
$ ->
# avatar
$('.js-choose-group-avatar-button').bind "click", ->
form = $(this).closest("form")
form.find(".js-group-avatar-input").click()
$('.js-group-avatar-input').bind "change", ->
form = $(this).closest("form")
filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find(".js-avatar-filename").text(filename)
$ -> class @NamespaceSelect
namespaceFormatResult = (namespace) -> constructor: ->
markup = "<div class='namespace-result'>" namespaceFormatResult = (namespace) ->
markup += "<span class='namespace-kind'>" + namespace.kind + "</span>" markup = "<div class='namespace-result'>"
markup += "<span class='namespace-path'>" + namespace.path + "</span>" markup += "<span class='namespace-kind'>" + namespace.kind + "</span>"
markup += "</div>" markup += "<span class='namespace-path'>" + namespace.path + "</span>"
markup markup += "</div>"
markup
formatSelection = (namespace) -> formatSelection = (namespace) ->
namespace.kind + ": " + namespace.path namespace.kind + ": " + namespace.path
$('.ajax-namespace-select').each (i, select) -> $('.ajax-namespace-select').each (i, select) ->
$(select).select2 $(select).select2
placeholder: "Search for namespace" placeholder: "Search for namespace"
multiple: $(select).hasClass('multiselect') multiple: $(select).hasClass('multiselect')
minimumInputLength: 0 minimumInputLength: 0
query: (query) -> query: (query) ->
Api.namespaces query.term, (namespaces) -> Api.namespaces query.term, (namespaces) ->
data = { results: namespaces } data = { results: namespaces }
query.callback(data) query.callback(data)
dropdownCssClass: "ajax-namespace-dropdown" dropdownCssClass: "ajax-namespace-dropdown"
formatResult: namespaceFormatResult formatResult: namespaceFormatResult
formatSelection: formatSelection formatSelection: formatSelection
$ -> class @Profile
$('.edit_user .application-theme input, .edit_user .code-preview-theme input').click -> constructor: ->
# Submit the form $('.edit_user .application-theme input, .edit_user .code-preview-theme input').click ->
$('.edit_user').submit() # Submit the form
$('.edit_user').submit()
new Flash("Appearance settings saved", "notice") new Flash("Appearance settings saved", "notice")
$('.update-username form').on 'ajax:before', -> $('.update-username form').on 'ajax:before', ->
$('.loading-gif').show() $('.loading-gif').show()
$(this).find('.update-success').hide() $(this).find('.update-success').hide()
$(this).find('.update-failed').hide() $(this).find('.update-failed').hide()
$('.update-username form').on 'ajax:complete', -> $('.update-username form').on 'ajax:complete', ->
$(this).find('.btn-save').enableButton() $(this).find('.btn-save').enableButton()
$(this).find('.loading-gif').hide() $(this).find('.loading-gif').hide()
$('.update-notifications').on 'ajax:complete', -> $('.update-notifications').on 'ajax:complete', ->
$(this).find('.btn-save').enableButton() $(this).find('.btn-save').enableButton()
$('.js-choose-user-avatar-button').bind "click", -> $('.js-choose-user-avatar-button').bind "click", ->
form = $(this).closest("form") form = $(this).closest("form")
form.find(".js-user-avatar-input").click() form.find(".js-user-avatar-input").click()
$('.js-user-avatar-input').bind "change", -> $('.js-user-avatar-input').bind "change", ->
form = $(this).closest("form") form = $(this).closest("form")
filename = $(this).val().replace(/^.*[\\\/]/, '') filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find(".js-avatar-filename").text(filename) form.find(".js-avatar-filename").text(filename)
$('.profile-groups-avatars').tooltip("placement": "top")
class @Project class @Project
constructor: -> constructor: ->
$('.project-edit-container').on 'ajax:before', => # Git clone panel switcher
$('.project-edit-container').hide() scope = $ '.git-clone-holder'
$('.save-project-loader').show() if scope.length > 0
$('a, button', scope).click ->
@initEvents() $('a, button', scope).removeClass 'active'
$(@).addClass 'active'
$('#project_clone', scope).val $(@).data 'clone'
initEvents: -> $(".clone").text("").append $(@).data 'clone'
disableButtonIfEmptyField '#project_name', '.project-submit'
# Ref switcher
$('#project_issues_enabled').change -> $('.project-refs-select').on 'change', ->
if ($(this).is(':checked') == true) $(@).parents('form').submit()
$('#project_issues_tracker').removeAttr('disabled')
else $('.hide-no-ssh-message').on 'click', (e) ->
$('#project_issues_tracker').attr('disabled', 'disabled') path = '/'
$.cookie('hide_no_ssh_message', 'false', { path: path })
$('#project_issues_tracker').change() $(@).parents('.no-ssh-key-message').hide()
e.preventDefault()
$('#project_issues_tracker').change ->
if ($(this).val() == gon.default_issues_tracker || $(this).is(':disabled'))
$('#project_issues_tracker_id').attr('disabled', 'disabled')
else
$('#project_issues_tracker_id').removeAttr('disabled')
$ ->
# Git clone panel switcher
scope = $ '.git-clone-holder'
if scope.length > 0
$('a, button', scope).click ->
$('a, button', scope).removeClass 'active'
$(@).addClass 'active'
$('#project_clone', scope).val $(@).data 'clone'
$(".clone").text("").append $(@).data 'clone'
# Ref switcher
$('.project-refs-select').on 'change', ->
$(@).parents('form').submit()
$('.hide-no-ssh-message').on 'click', (e) ->
path = '/'
$.cookie('hide_no_ssh_message', 'false', { path: path })
$(@).parents('.no-ssh-key-message').hide()
e.preventDefault()
$('.project-home-panel .star').on 'ajax:success', (e, data, status, xhr) ->
$(@).toggleClass('on').find('.count').html(data.star_count)
.on 'ajax:error', (e, xhr, status, error) ->
new Flash('Star toggle failed. Try again later.', 'alert')
$("a[data-toggle='tab']").on "shown.bs.tab", (e) ->
$.cookie "default_view", $(e.target).attr("href")
defaultView = $.cookie("default_view")
if defaultView
$("a[href=" + defaultView + "]").tab "show"
else
$("a[data-toggle='tab']:first").tab "show"
class @ProjectNew
constructor: ->
$('.project-edit-container').on 'ajax:before', =>
$('.project-edit-container').hide()
$('.save-project-loader').show()
@initEvents()
initEvents: ->
disableButtonIfEmptyField '#project_name', '.project-submit'
$('#project_issues_enabled').change ->
if ($(this).is(':checked') == true)
$('#project_issues_tracker').removeAttr('disabled')
else
$('#project_issues_tracker').attr('disabled', 'disabled')
$('#project_issues_tracker').change()
$('#project_issues_tracker').change ->
if ($(this).val() == gon.default_issues_tracker || $(this).is(':disabled'))
$('#project_issues_tracker_id').attr('disabled', 'disabled')
else
$('#project_issues_tracker_id').removeAttr('disabled')
class @ProjectShow
constructor: ->
$('.project-home-panel .star').on 'ajax:success', (e, data, status, xhr) ->
$(@).toggleClass('on').find('.count').html(data.star_count)
.on 'ajax:error', (e, xhr, status, error) ->
new Flash('Star toggle failed. Try again later.', 'alert')
$("a[data-toggle='tab']").on "shown.bs.tab", (e) ->
$.cookie "default_view", $(e.target).attr("href")
defaultView = $.cookie("default_view")
if defaultView
$("a[href=" + defaultView + "]").tab "show"
else
$("a[data-toggle='tab']:first").tab "show"
@projectUsersSelect = class @ProjectUsersSelect
init: -> constructor: ->
$('.ajax-project-users-select').each (i, select) -> $('.ajax-project-users-select').each (i, select) =>
project_id = $(select).data('project-id') || $('body').data('project-id') project_id = $(select).data('project-id') || $('body').data('project-id')
$(select).select2 $(select).select2
...@@ -28,14 +28,16 @@ ...@@ -28,14 +28,16 @@
Api.user(id, callback) Api.user(id, callback)
formatResult: projectUsersSelect.projectUserFormatResult formatResult: (args...) =>
formatSelection: projectUsersSelect.projectUserFormatSelection @formatResult(args...)
formatSelection: (args...) =>
@formatSelection(args...)
dropdownCssClass: "ajax-project-users-dropdown" dropdownCssClass: "ajax-project-users-dropdown"
dropdownAutoWidth: true dropdownAutoWidth: true
escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results
m m
projectUserFormatResult: (user) -> formatResult: (user) ->
if user.avatar_url if user.avatar_url
avatar = user.avatar_url avatar = user.avatar_url
else else
...@@ -52,8 +54,5 @@ ...@@ -52,8 +54,5 @@
<div class='user-username'>#{user.username}</div> <div class='user-username'>#{user.username}</div>
</div>" </div>"
projectUserFormatSelection: (user) -> formatSelection: (user) ->
user.name user.name
$ ->
projectUsersSelect.init()
class @User
constructor: ->
$('.profile-groups-avatars').tooltip("placement": "top")
$ -> class @UsersSelect
userFormatResult = (user) -> constructor: ->
$('.ajax-users-select').each (i, select) =>
$(select).select2
placeholder: "Search for a user"
multiple: $(select).hasClass('multiselect')
minimumInputLength: 0
query: (query) ->
Api.users query.term, (users) ->
data = { results: users }
query.callback(data)
initSelection: (element, callback) ->
id = $(element).val()
if id isnt ""
Api.user(id, callback)
formatResult: (args...) =>
@formatResult(args...)
formatSelection: (args...) =>
@formatSelection(args...)
dropdownCssClass: "ajax-users-dropdown"
escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results
m
formatResult: (user) ->
if user.avatar_url if user.avatar_url
avatar = user.avatar_url avatar = user.avatar_url
else else
...@@ -11,27 +36,5 @@ $ -> ...@@ -11,27 +36,5 @@ $ ->
<div class='user-username'>#{user.username}</div> <div class='user-username'>#{user.username}</div>
</div>" </div>"
userFormatSelection = (user) -> formatSelection: (user) ->
user.name user.name
$('.ajax-users-select').each (i, select) ->
$(select).select2
placeholder: "Search for a user"
multiple: $(select).hasClass('multiselect')
minimumInputLength: 0
query: (query) ->
Api.users query.term, (users) ->
data = { results: users }
query.callback(data)
initSelection: (element, callback) ->
id = $(element).val()
if id isnt ""
Api.user(id, callback)
formatResult: userFormatResult
formatSelection: userFormatSelection
dropdownCssClass: "ajax-users-dropdown"
escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results
m
/** Typo **/ /** Typo **/
$monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace; $monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace;
$regular_font: "Helvetica Neue", Helvetica, Arial, sans-serif; $regular_font: "Helvetica Neue", Helvetica, Arial, sans-serif;
class Admin::BackgroundJobsController < Admin::ApplicationController class Admin::BackgroundJobsController < Admin::ApplicationController
def show def show
ps_output, _ = Gitlab::Popen.popen(%W(ps -U #{Settings.gitlab.user} -o pid,pcpu,pmem,stat,start,command)) ps_output, _ = Gitlab::Popen.popen(%W(ps -U #{Gitlab.config.gitlab.user} -o pid,pcpu,pmem,stat,start,command))
@sidekiq_processes = ps_output.split("\n").grep(/sidekiq/) @sidekiq_processes = ps_output.split("\n").grep(/sidekiq/)
end end
end end
...@@ -5,7 +5,6 @@ class ApplicationController < ActionController::Base ...@@ -5,7 +5,6 @@ class ApplicationController < ActionController::Base
before_filter :authenticate_user! before_filter :authenticate_user!
before_filter :reject_blocked! before_filter :reject_blocked!
before_filter :check_password_expiration before_filter :check_password_expiration
before_filter :add_abilities
before_filter :ldap_security_check before_filter :ldap_security_check
before_filter :default_headers before_filter :default_headers
before_filter :add_gon_variables before_filter :add_gon_variables
...@@ -72,7 +71,7 @@ class ApplicationController < ActionController::Base ...@@ -72,7 +71,7 @@ class ApplicationController < ActionController::Base
end end
def abilities def abilities
@abilities ||= Six.new Ability.abilities
end end
def can?(object, action, subject) def can?(object, action, subject)
...@@ -113,10 +112,6 @@ class ApplicationController < ActionController::Base ...@@ -113,10 +112,6 @@ class ApplicationController < ActionController::Base
nil nil
end end
def add_abilities
abilities << Ability
end
def authorize_project!(action) def authorize_project!(action)
return access_denied! unless can?(current_user, action, project) return access_denied! unless can?(current_user, action, project)
end end
......
class Explore::GroupsController < ApplicationController class Explore::GroupsController < ApplicationController
skip_before_filter :authenticate_user!, skip_before_filter :authenticate_user!,
:reject_blocked, :set_current_user_for_observers, :reject_blocked, :set_current_user_for_observers
:add_abilities
layout "explore" layout "explore"
......
class Explore::ProjectsController < ApplicationController class Explore::ProjectsController < ApplicationController
skip_before_filter :authenticate_user!, skip_before_filter :authenticate_user!,
:reject_blocked, :reject_blocked
:add_abilities
layout 'explore' layout 'explore'
......
...@@ -9,7 +9,7 @@ class SnippetsController < ApplicationController ...@@ -9,7 +9,7 @@ class SnippetsController < ApplicationController
before_filter :set_title before_filter :set_title
skip_before_filter :authenticate_user!, only: [:index, :user_index] skip_before_filter :authenticate_user!, only: [:index, :user_index, :show, :raw]
respond_to :html respond_to :html
......
...@@ -48,7 +48,7 @@ class IssuableFinder ...@@ -48,7 +48,7 @@ class IssuableFinder
else else
[] []
end end
elsif current_user && params[:authorized_only].presence elsif current_user && params[:authorized_only].presence && !current_user_related?
klass.of_projects(current_user.authorized_projects).references(:project) klass.of_projects(current_user.authorized_projects).references(:project)
else else
klass.of_projects(ProjectsFinder.new.execute(current_user)).references(:project) klass.of_projects(ProjectsFinder.new.execute(current_user)).references(:project)
...@@ -142,4 +142,8 @@ class IssuableFinder ...@@ -142,4 +142,8 @@ class IssuableFinder
def project def project
Project.where(id: params[:project_id]).first if params[:project_id].present? Project.where(id: params[:project_id]).first if params[:project_id].present?
end end
def current_user_related?
params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me'
end
end end
...@@ -29,6 +29,8 @@ class SnippetsFinder ...@@ -29,6 +29,8 @@ class SnippetsFinder
def by_user(current_user, user, scope) def by_user(current_user, user, scope)
snippets = user.snippets.fresh.non_expired snippets = user.snippets.fresh.non_expired
return snippets.are_public unless current_user
if user == current_user if user == current_user
case scope case scope
when 'are_internal' then when 'are_internal' then
......
...@@ -262,5 +262,13 @@ class Ability ...@@ -262,5 +262,13 @@ class Ability
end end
rules rules
end end
def abilities
@abilities ||= begin
abilities = Six.new
abilities << self
abilities
end
end
end end
end end
...@@ -330,11 +330,7 @@ class User < ActiveRecord::Base ...@@ -330,11 +330,7 @@ class User < ActiveRecord::Base
end end
def abilities def abilities
@abilities ||= begin Ability.abilities
abilities = Six.new
abilities << Ability
abilities
end
end end
def can_select_namespace? def can_select_namespace?
......
...@@ -6,11 +6,7 @@ class BaseService ...@@ -6,11 +6,7 @@ class BaseService
end end
def abilities def abilities
@abilities ||= begin Ability.abilities
abilities = Six.new
abilities << Ability
abilities
end
end end
def can?(object, action, subject) def can?(object, action, subject)
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
- next unless process.match(/(sidekiq \d+\.\d+\.\d+.+$)/) - next unless process.match(/(sidekiq \d+\.\d+\.\d+.+$)/)
- data = process.strip.split(' ') - data = process.strip.split(' ')
%tr %tr
%td= Settings.gitlab.user %td= gitlab_config.user
- 5.times do - 5.times do
%td= data.shift %td= data.shift
%td= data.join(' ') %td= data.join(' ')
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
If '[25 of 25 busy]' is shown, restart GitLab with 'sudo service gitlab reload'. If '[25 of 25 busy]' is shown, restart GitLab with 'sudo service gitlab reload'.
%p %p
%i.fa.fa-exclamation-circle %i.fa.fa-exclamation-circle
If more than one sidekiq process is listed, stop GitLab, kill the remaining sidekiq processes (sudo pkill -u #{Settings.gitlab.user} -f sidekiq) and restart GitLab. If more than one sidekiq process is listed, stop GitLab, kill the remaining sidekiq processes (sudo pkill -u #{gitlab_config.user} -f sidekiq) and restart GitLab.
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= form_tag admin_groups_path, method: :get, class: 'form-inline' do = form_tag admin_groups_path, method: :get, class: 'form-inline' do
.form-group .form-group
= text_field_tag :name, params[:name], class: "form-control input-mn-300" = text_field_tag :name, params[:name], class: "form-control input-mn-300"
= submit_tag "Search", class: "btn submit btn-primary" = button_tag "Search", class: "btn submit btn-primary"
%hr %hr
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
%div.prepend-top-10 %div.prepend-top-10
= select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2" = select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2"
%hr %hr
= submit_tag 'Add users into group', class: "btn btn-create" = button_tag 'Add users into group', class: "btn btn-create"
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
%h3.panel-title %h3.panel-title
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
= label = label
%hr %hr
= hidden_field_tag :sort, params[:sort] = hidden_field_tag :sort, params[:sort]
= submit_tag "Search", class: "btn submit btn-primary" = button_tag "Search", class: "btn submit btn-primary"
= link_to "Reset", admin_projects_path, class: "btn btn-cancel" = link_to "Reset", admin_projects_path, class: "btn btn-cancel"
.col-md-9 .col-md-9
......
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
= text_field_tag :username, nil, {class: "form-control top", placeholder: "LDAP Login", autofocus: "autofocus"} = text_field_tag :username, nil, {class: "form-control top", placeholder: "LDAP Login", autofocus: "autofocus"}
= password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"} = password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"}
%br/ %br/
= submit_tag "LDAP Sign in", class: "btn-save btn" = button_tag "LDAP Sign in", class: "btn-save btn"
...@@ -2,22 +2,22 @@ ...@@ -2,22 +2,22 @@
.login-heading .login-heading
%h3 Sign in %h3 Sign in
.login-body .login-body
- if ldap_enabled? && gitlab_config.signin_enabled - if ldap_enabled?
%ul.nav.nav-tabs %ul.nav.nav-tabs
- @ldap_servers.each_with_index do |server, i| - @ldap_servers.each_with_index do |server, i|
%li{class: (:active if i==0)} %li{class: (:active if i.zero?)}
= link_to server['label'], "#tab-#{server['provider_name']}", 'data-toggle' => 'tab' = link_to server['label'], "#tab-#{server['provider_name']}", 'data-toggle' => 'tab'
%li - if gitlab_config.signin_enabled
= link_to 'Standard', '#tab-signin', 'data-toggle' => 'tab' %li
= link_to 'Standard', '#tab-signin', 'data-toggle' => 'tab'
.tab-content .tab-content
- @ldap_servers.each_with_index do |server,i| - @ldap_servers.each_with_index do |server, i|
%div.tab-pane{id: "tab-#{server['provider_name']}", class: (:active if i==0)} %div.tab-pane{id: "tab-#{server['provider_name']}", class: (:active if i.zero?)}
= render 'devise/sessions/new_ldap', provider: server['provider_name'] = render 'devise/sessions/new_ldap', provider: server['provider_name']
%div#tab-signin.tab-pane - if gitlab_config.signin_enabled
= render 'devise/sessions/new_base' %div#tab-signin.tab-pane
= render 'devise/sessions/new_base'
- elsif ldap_enabled?
= render 'devise/sessions/new_ldap', ldap_servers: @ldap_servers
- elsif gitlab_config.signin_enabled - elsif gitlab_config.signin_enabled
= render 'devise/sessions/new_base' = render 'devise/sessions/new_base'
- else - else
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.form-group .form-group
= search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "groups_search" = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "groups_search"
.form-group .form-group
= submit_tag 'Search', class: "btn btn-primary wide" = button_tag 'Search', class: "btn btn-primary wide"
.pull-right .pull-right
.dropdown.inline .dropdown.inline
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.form-group .form-group
= search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "projects_search" = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "projects_search"
.form-group .form-group
= submit_tag 'Search', class: "btn btn-primary wide" = button_tag 'Search', class: "btn btn-primary wide"
.pull-right .pull-right
.dropdown.inline .dropdown.inline
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
= form_tag members_group_path(@group), method: :get, class: 'form-inline member-search-form' do = form_tag members_group_path(@group), method: :get, class: 'form-inline member-search-form' do
.form-group .form-group
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input input-mn-300' } = search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input input-mn-300' }
= submit_tag 'Search', class: 'btn' = button_tag 'Search', class: 'btn'
- if current_user && current_user.can?(:manage_group, @group) - if current_user && current_user.can?(:manage_group, @group)
.pull-right .pull-right
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
- if @snippet || @snippets - if @snippet || @snippets
= hidden_field_tag :snippets, true = hidden_field_tag :snippets, true
= hidden_field_tag :repository_ref, @ref = hidden_field_tag :repository_ref, @ref
= submit_tag 'Go' if ENV['RAILS_ENV'] == 'test' = button_tag 'Go' if ENV['RAILS_ENV'] == 'test'
.search-autocomplete-opts.hide{:'data-autocomplete-path' => search_autocomplete_path, :'data-autocomplete-project-id' => @project.try(:id), :'data-autocomplete-project-ref' => @ref } .search-autocomplete-opts.hide{:'data-autocomplete-path' => search_autocomplete_path, :'data-autocomplete-project-id' => @project.try(:id), :'data-autocomplete-project-ref' => @ref }
:javascript :javascript
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
.form-group .form-group
.col-sm-2 .col-sm-2
.col-sm-10 .col-sm-10
= submit_tag 'Remove file', class: 'btn btn-remove btn-remove-file' = button_tag 'Remove file', class: 'btn btn-remove btn-remove-file'
= link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal" = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
:javascript :javascript
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
.col-sm-10 .col-sm-10
= text_field_tag :ref, params[:ref], placeholder: 'existing branch name, tag or commit SHA', required: true, tabindex: 2, class: 'form-control' = text_field_tag :ref, params[:ref], placeholder: 'existing branch name, tag or commit SHA', required: true, tabindex: 2, class: 'form-control'
.form-actions .form-actions
= submit_tag 'Create branch', class: 'btn btn-create', tabindex: 3 = button_tag 'Create branch', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel' = link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel'
:javascript :javascript
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
%span.input-group-addon to %span.input-group-addon to
= text_field_tag :to, params[:to], class: "form-control" = text_field_tag :to, params[:to], class: "form-control"
&nbsp; &nbsp;
= submit_tag "Compare", class: "btn btn-create commits-compare-btn" = button_tag "Compare", class: "btn btn-create commits-compare-btn"
- if compare_to_mr_button? - if compare_to_mr_button?
= link_to compare_mr_path, class: 'prepend-left-10 btn' do = link_to compare_mr_path, class: 'prepend-left-10 btn' do
%strong Make a merge request %strong Make a merge request
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
.issue-info .issue-info
- if issue.assignee - if issue.assignee
assigned to #{link_to_member(@project, issue.assignee)} assigned to #{link_to_member(@project, issue.assignee)}
- else
unassigned
- if issue.votes_count > 0 - if issue.votes_count > 0
= render 'votes/votes_inline', votable: issue = render 'votes/votes_inline', votable: issue
- if issue.notes.any? - if issue.notes.any?
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
= hidden_field_tag :issue_context = hidden_field_tag :issue_context
= f.submit class: 'btn' = f.submit class: 'btn'
- elsif issue.milestone - elsif issue.milestone
= link_to issue.milestone.title, project_milestone_path = link_to project_milestone_path(@project, @issue.milestone) do
= @issue.milestone.title
- else - else
None None
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
= text_field_tag :message, nil, placeholder: 'Enter message.', required: false, tabindex: 3, class: 'form-control' = text_field_tag :message, nil, placeholder: 'Enter message.', required: false, tabindex: 3, class: 'form-control'
.light (Optional) Entering a message will create an annotated tag. .light (Optional) Entering a message will create an annotated tag.
.form-actions .form-actions
= submit_tag 'Create tag', class: 'btn btn-create', tabindex: 3 = button_tag 'Create tag', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel' = link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel'
:javascript :javascript
......
...@@ -9,6 +9,6 @@ ...@@ -9,6 +9,6 @@
.col-sm-10= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "select2 lg", required: true) .col-sm-10= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "select2 lg", required: true)
.form-actions .form-actions
= submit_tag 'Import project members', class: "btn btn-create" = button_tag 'Import project members', class: "btn btn-create"
= link_to "Cancel", project_team_index_path(@project), class: "btn btn-cancel" = link_to "Cancel", project_team_index_path(@project), class: "btn btn-cancel"
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
.col-sm-6 .col-sm-6
= search_field_tag :search, params[:search], placeholder: "issue 143", class: "form-control search-text-input", id: "dashboard_search" = search_field_tag :search, params[:search], placeholder: "issue 143", class: "form-control search-text-input", id: "dashboard_search"
.col-sm-4 .col-sm-4
= submit_tag 'Search', class: "btn btn-create" = button_tag 'Search', class: "btn btn-create"
.form-group .form-group
.col-sm-2 .col-sm-2
- unless params[:snippets].eql? 'true' - unless params[:snippets].eql? 'true'
......
- groups.each do |group| - groups.each do |group|
= link_to group, class: 'profile-groups-avatars', :title => group.name do = link_to group, class: 'profile-groups-avatars', :title => group.name do
= image_tag group_icon(group.path) - image_tag group_icon(group.path)
...@@ -13,7 +13,6 @@ module Gitlab ...@@ -13,7 +13,6 @@ module Gitlab
# Custom directories with classes and modules you want to be autoloadable. # Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib config.autoload_paths += %W(#{config.root}/lib
#{config.root}/app/finders
#{config.root}/app/models/hooks #{config.root}/app/models/hooks
#{config.root}/app/models/concerns #{config.root}/app/models/concerns
#{config.root}/app/models/project_services #{config.root}/app/models/project_services
......
...@@ -39,6 +39,8 @@ production: &base ...@@ -39,6 +39,8 @@ production: &base
# time_zone: 'UTC' # time_zone: 'UTC'
## Email settings ## Email settings
# Uncomment and set to false if you need to disable email sending from GitLab (default: true)
# email_enabled: true
# Email address used in the "From" field in mails sent by GitLab # Email address used in the "From" field in mails sent by GitLab
email_from: example@example.com email_from: example@example.com
......
...@@ -95,6 +95,7 @@ Settings.gitlab['https'] = false if Settings.gitlab['https'].nil? ...@@ -95,6 +95,7 @@ Settings.gitlab['https'] = false if Settings.gitlab['https'].nil?
Settings.gitlab['port'] ||= Settings.gitlab.https ? 443 : 80 Settings.gitlab['port'] ||= Settings.gitlab.https ? 443 : 80
Settings.gitlab['relative_url_root'] ||= ENV['RAILS_RELATIVE_URL_ROOT'] || '' Settings.gitlab['relative_url_root'] ||= ENV['RAILS_RELATIVE_URL_ROOT'] || ''
Settings.gitlab['protocol'] ||= Settings.gitlab.https ? "https" : "http" Settings.gitlab['protocol'] ||= Settings.gitlab.https ? "https" : "http"
Settings.gitlab['email_enabled'] ||= true if Settings.gitlab['email_enabled'].nil?
Settings.gitlab['email_from'] ||= "gitlab@#{Settings.gitlab.host}" Settings.gitlab['email_from'] ||= "gitlab@#{Settings.gitlab.host}"
Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url) Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url)
Settings.gitlab['user'] ||= 'git' Settings.gitlab['user'] ||= 'git'
......
# Interceptor in lib/disable_email_interceptor.rb
ActionMailer::Base.register_interceptor(DisableEmailInterceptor) unless Gitlab.config.gitlab.email_enabled
...@@ -21,13 +21,7 @@ ...@@ -21,13 +21,7 @@
## Clients ## Clients
- [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP Find API Clients for GitLab [on our website](https://about.gitlab.com/applications/#api-clients).
- [Laravel API Wrapper for GitLab CE](https://github.com/adamgoose/gitlab) - PHP / [Laravel](http://laravel.com)
- [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby
- [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python
- [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java
- [node-gitlab](https://github.com/moul/node-gitlab) - Node.js
- [NGitLab](https://github.com/Scooletz/NGitLab) - .NET
## Introduction ## Introduction
...@@ -158,7 +152,7 @@ When an attribute is missing, you will get something like: ...@@ -158,7 +152,7 @@ When an attribute is missing, you will get something like:
HTTP/1.1 400 Bad Request HTTP/1.1 400 Bad Request
Content-Type: application/json Content-Type: application/json
{ {
"message":"400 (Bad request) \"title\" not given" "message":"400 (Bad request) \"title\" not given"
} }
...@@ -167,7 +161,7 @@ When a validation error occurs, error messages will be different. They will hold ...@@ -167,7 +161,7 @@ When a validation error occurs, error messages will be different. They will hold
HTTP/1.1 400 Bad Request HTTP/1.1 400 Bad Request
Content-Type: application/json Content-Type: application/json
{ {
"message": { "message": {
"bio": [ "bio": [
......
...@@ -90,7 +90,7 @@ On a very active server (10,000 active users) the Sidekiq process can use 1GB+ o ...@@ -90,7 +90,7 @@ On a very active server (10,000 active users) the Sidekiq process can use 1GB+ o
## Supported web browsers ## Supported web browsers
- Chrome (Latest stable version) - Chrome (Latest stable version)
- Firefox (Latest released version) - Firefox (Latest released version and [latest ESR version](https://www.mozilla.org/en-US/firefox/organizations/))
- Safari 7+ (known problem: required fields in html5 do not work) - Safari 7+ (known problem: required fields in html5 do not work)
- Opera (Latest released version) - Opera (Latest released version)
- IE 10+ - IE 10+
# Import # Import
### Import bare repositories into GitLab project instance ## Import bare repositories into GitLab project instance
Notes: Notes:
* project owner will be a first admin - project owner will be a first admin
* groups will be created as needed - groups will be created as needed
* group owner will be the first admin - group owner will be the first admin
* existing projects will be skipped - existing projects will be skipped
How to use: How to use:
1. copy your bare repos under git repos_path (see `config/gitlab.yml` gitlab_shell -> repos_path) 1. copy your bare repos under git repos_path (see `config/gitlab.yml` gitlab_shell -> repos_path)
2. run the command below 1. run the command below
``` ```
# omnibus-gitlab # omnibus-gitlab
......
...@@ -2,40 +2,42 @@ ...@@ -2,40 +2,42 @@
NOTE: This is a guide for GitLab developers. NOTE: This is a guide for GitLab developers.
# **15th - Code Freeze & Release Manager** # **7 workdays before release - Code Freeze & Release Manager**
### **1. Stop merging in code, except for important bugfixes** ### **1. Stop merging in code, except for important bug fixes**
### **2. Release Manager** ### **2. Release Manager**
A release manager is selected that coordinates the entire release of this version. The release manager has to make sure all the steps below are done and delegated where necessary. This person should also make sure this document is kept up to date and issues are created and updated. A release manager is selected that coordinates the entire release of this version. The release manager has to make sure all the steps below are done and delegated where necessary. This person should also make sure this document is kept up to date and issues are created and updated.
### **3. Create an overall issue** ### **3. Create an overall issue**
Name it "Release x.x.x" for easier searching.
Create issue for GitLab CE project(internal). Name it "Release x.x.x" for easier searching.
Replace the dates with actual dates based on the number of workdays before the release.
``` ```
15th: Xth:
* Update the changelog (#LINK) * Update the changelog (#LINK)
* Triage the omnibus-gitlab milestone * Triage the omnibus-gitlab milestone
16th: Xth:
* Merge CE in to EE (#LINK) * Merge CE in to EE (#LINK)
* Close the omnibus-gitlab milestone * Close the omnibus-gitlab milestone
17th: Xth:
* Create x.x.0.rc1 (#LINK) * Create x.x.0.rc1 (#LINK)
* Build package for GitLab.com (https://dev.gitlab.org/cookbooks/chef-repo/blob/master/doc/administration.md#build-a-package) * Build package for GitLab.com (https://dev.gitlab.org/cookbooks/chef-repo/blob/master/doc/administration.md#build-a-package)
18th: Xth:
* Update GitLab.com with rc1 (#LINK) (https://dev.gitlab.org/cookbooks/chef-repo/blob/master/doc/administration.md#deploy-the-package) * Update GitLab.com with rc1 (#LINK) (https://dev.gitlab.org/cookbooks/chef-repo/blob/master/doc/administration.md#deploy-the-package)
* Regression issue and tweet about rc1 (#LINK) * Regression issue and tweet about rc1 (#LINK)
* Start blog post (#LINK) * Start blog post (#LINK)
21th: Xth:
* Do QA and fix anything coming out of it (#LINK) * Do QA and fix anything coming out of it (#LINK)
...@@ -43,16 +45,13 @@ Name it "Release x.x.x" for easier searching. ...@@ -43,16 +45,13 @@ Name it "Release x.x.x" for easier searching.
* Release CE and EE (#LINK) * Release CE and EE (#LINK)
23rd: Xth:
* Prepare package for GitLab.com release (#LINK)
24th: * * Deploy to GitLab.com (#LINK)
* Deploy to GitLab.com (#LINK)
``` ```
### **4. Update Changelog** ### **4. Update changelog**
Any changes not yet added to the changelog are added by lead developer and in that merge request the complete team is asked if there is anything missing. Any changes not yet added to the changelog are added by lead developer and in that merge request the complete team is asked if there is anything missing.
...@@ -60,26 +59,26 @@ Any changes not yet added to the changelog are added by lead developer and in th ...@@ -60,26 +59,26 @@ Any changes not yet added to the changelog are added by lead developer and in th
Ensure that there is enough time to incorporate the findings of the release candidate, etc. Ensure that there is enough time to incorporate the findings of the release candidate, etc.
# **16th - Merge the CE into EE** # **6 workdays before release- Merge the CE into EE**
Do this via a merge request. Do this via a merge request.
# **17th - Create RC1** # **5 workdays before release - Create RC1**
The RC1 release comes with the task to update the installation and upgrade docs. Be mindful that there might already be merge requests for this on GitLab or GitHub. The RC1 release comes with the task to update the installation and upgrade docs. Be mindful that there might already be merge requests for this on GitLab or GitHub.
### **1. Update the installation guide** ### **1. Update the installation guide**
1. Check if it references the correct branch `x-x-stable` (doesn't exist yet, but that is okay) 1. Check if it references the correct branch `x-x-stable` (doesn't exist yet, but that is okay)
1. Check the [GitLab Shell version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L782) 1. Check the [GitLab Shell version](/lib/tasks/gitlab/check.rake#L782)
1. Check the [Git version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L794) 1. Check the [Git version](/lib/tasks/gitlab/check.rake#L794)
1. There might be other changes. Ask around. 1. There might be other changes. Ask around.
### **2. Create an update guides** ### **2. Create update guides**
1. Create: CE update guide from previous version. Like `from-6-8-to-6.9` 1. Create: CE update guide from previous version. Like `7.3-to-7.4.md`
1. Create: CE to EE update guide in EE repository for latest version. 1. Create: CE to EE update guide in EE repository for latest version.
1. Update: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/6.0-to-6.x.md to latest version. 1. Update: `6.x-or-7.x-to-7.x.md` to latest version.
It's best to copy paste the previous guide and make changes where necessary. It's best to copy paste the previous guide and make changes where necessary.
The typical steps are listed below with any points you should specifically look at. The typical steps are listed below with any points you should specifically look at.
...@@ -98,9 +97,9 @@ List any major changes here, so the user is aware of them before starting to upg ...@@ -98,9 +97,9 @@ List any major changes here, so the user is aware of them before starting to upg
#### 3. Do users need to update dependencies like `git`? #### 3. Do users need to update dependencies like `git`?
- Check if the [GitLab Shell version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L782) changed since the last release. - Check if the [GitLab Shell version](/lib/tasks/gitlab/check.rake#L782) changed since the last release.
- Check if the [Git version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L794) changed since the last release. - Check if the [Git version](/lib/tasks/gitlab/check.rake#L794) changed since the last release.
#### 4. Get latest code #### 4. Get latest code
...@@ -112,19 +111,19 @@ List any major changes here, so the user is aware of them before starting to upg ...@@ -112,19 +111,19 @@ List any major changes here, so the user is aware of them before starting to upg
Check if any of these changed since last release: Check if any of these changed since last release:
- <https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/nginx/gitlab> - [lib/support/nginx/gitlab](/lib/support/nginx/gitlab)
- <https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/nginx/gitlab-ssl> - [lib/support/nginx/gitlab-ssl](/lib/support/nginx/gitlab-ssl)
- <https://gitlab.com/gitlab-org/gitlab-shell/commits/master/config.yml.example> - <https://gitlab.com/gitlab-org/gitlab-shell/commits/master/config.yml.example>
- <https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/gitlab.yml.example> - [config/gitlab.yml.example](/config/gitlab.yml.example)
- <https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/unicorn.rb.example> - [config/unicorn.rb.example](/config/unicorn.rb.example)
- <https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/database.yml.mysql> - [config/database.yml.mysql](/config/database.yml.mysql)
- <https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/database.yml.postgresql> - [config/database.yml.postgresql](/config/database.yml.postgresql)
- <https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/initializers/rack_attack.rb.example> - [config/initializers/rack_attack.rb.example](/config/initializers/rack_attack.rb.example)
- <https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/resque.yml.example> - [config/resque.yml.example](/config/resque.yml.example)
#### 8. Need to update init script? #### 8. Need to update init script?
Check if the `init.d/gitlab` script changed since last release: <https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/init.d/gitlab> Check if the `init.d/gitlab` script changed since last release: [lib/support/init.d/gitlab](/lib/support/init.d/gitlab)
#### 9. Start application #### 9. Start application
...@@ -156,6 +155,12 @@ Create an annotated tag that points to the version change commit: ...@@ -156,6 +155,12 @@ Create an annotated tag that points to the version change commit:
git tag -a vx.x.0.rc1 -m 'Version x.x.0.rc1' git tag -a vx.x.0.rc1 -m 'Version x.x.0.rc1'
``` ```
Tags should be created for both GitLab CE and GitLab EE. Don't forget to push tags to all remotes.
```
git push remote_name vx.x.0.rc1
```
### **6. Create stable branches** ### **6. Create stable branches**
For GitLab EE, append `-ee` to the branch. For GitLab EE, append `-ee` to the branch.
...@@ -173,9 +178,13 @@ Now developers can use master for merging new features. ...@@ -173,9 +178,13 @@ Now developers can use master for merging new features.
So you should use stable branch for future code chages related to release. So you should use stable branch for future code chages related to release.
# **18th - Release RC1** # **4 workdays before release - Release RC1**
### **1. Determine QA person
### **1. Update GitLab.com** Notify person of QA day.
### **2. Update GitLab.com**
Merge the RC1 EE code into GitLab.com. Merge the RC1 EE code into GitLab.com.
Once the build is green, create a package. Once the build is green, create a package.
...@@ -183,19 +192,20 @@ If there are big database migrations consider testing them with the production d ...@@ -183,19 +192,20 @@ If there are big database migrations consider testing them with the production d
Try to deploy in the morning. Try to deploy in the morning.
It is important to do this as soon as possible, so we can catch any errors before we release the full version. It is important to do this as soon as possible, so we can catch any errors before we release the full version.
### **2. Prepare the blog post** ### **3. Prepare the blog post**
- Start with a complete copy of the [release blog template](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/doc/release_blog_template.md) and fill it out. - Start with a complete copy of the [release blog template](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/doc/release_blog_template.md) and fill it out.
- Check the changelog of CE and EE for important changes. - Check the changelog of CE and EE for important changes.
- Create a WIP MR for the blog post - Create a WIP MR for the blog post
- Ask Dmitriy to add screenshots to the WIP MR. - Ask Dmitriy to add screenshots to the WIP MR.
- Decide with team who will be the MVP user. - Decide with team who will be the MVP user.
- Create WIP MR for adding MVP to MVP page on website
- Add a note if there are security fixes: This release fixes an important security issue and we advise everyone to upgrade as soon as possible. - Add a note if there are security fixes: This release fixes an important security issue and we advise everyone to upgrade as soon as possible.
- Create a merge request on [GitLab.com](https://gitlab.com/gitlab-com/www-gitlab-com/tree/master) - Create a merge request on [GitLab.com](https://gitlab.com/gitlab-com/www-gitlab-com/tree/master)
- Assign to one reviewer who will fix spelling issues by editing the branch (can use the online editor) - Assign to one reviewer who will fix spelling issues by editing the branch (can use the online editor)
- After the reviewer is finished the whole team will be mentioned to give their suggestions via line comments - After the reviewer is finished the whole team will be mentioned to give their suggestions via line comments
### **3. Create a regressions issue** ### **4. Create a regressions issue**
On [the GitLab CE issue tracker on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/issues/) create an issue titled "GitLab X.X regressions" add the following text: On [the GitLab CE issue tracker on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/issues/) create an issue titled "GitLab X.X regressions" add the following text:
...@@ -212,7 +222,7 @@ Tweet about the RC release: ...@@ -212,7 +222,7 @@ Tweet about the RC release:
> GitLab x.x.0.rc1 is out. This release candidate is only suitable for testing. Please link regressions issues from LINK_TO_REGRESSION_ISSUE > GitLab x.x.0.rc1 is out. This release candidate is only suitable for testing. Please link regressions issues from LINK_TO_REGRESSION_ISSUE
# **21st - Preparation** # **1 workdays before release - Preparation**
### **1. Pre QA merge** ### **1. Pre QA merge**
...@@ -252,7 +262,7 @@ Note: Merge CE into EE if needed. ...@@ -252,7 +262,7 @@ Note: Merge CE into EE if needed.
### **2. Update installation.md** ### **2. Update installation.md**
Update [installation.md](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md) to the newest version in master. Update [installation.md](/doc/install/installation.md) to the newest version in master.
### **3. Push latest changes from x-x-stable branch to dev.gitlab.org** ### **3. Push latest changes from x-x-stable branch to dev.gitlab.org**
...@@ -304,22 +314,19 @@ List the most important features and link to the blog post. ...@@ -304,22 +314,19 @@ List the most important features and link to the blog post.
Proposed tweet for CE "GitLab X.X is released! It brings *** <link-to-blogpost>" Proposed tweet for CE "GitLab X.X is released! It brings *** <link-to-blogpost>"
### **10. Send out the newsletter** # **1 workday after release - Update GitLab.com**
Send out an email to the 'GitLab Newsletter' mailing list on MailChimp.
Replicate the former release newsletter and modify it accordingly.
**Do not forget to edit `Subject line` and regenerate `Plain-Text Email` from HTML source**
Include a link to the blog post and keep it short.
Proposed email text: Update GitLab.com from RC1 to the released package.
"We have released a new version of GitLab. See our blog post(<link>) for more information."
# **25th - Release GitLab CI**
# **23rd - Optional Patch Release** - Create the update guid `doc/x.x-to-x.x.md`.
- Update CHANGELOG
# **24th - Update GitLab.com** - Bump version
- Create annotated tags `git tag -a vx.x.0 -m 'Version x.x.0' xxxxx`
- Create stable branch `x-x-stable`
- Create GitHub release post
- Post to blog about release
- Post to twitter
Merge the stable release into GitLab.com. Once the build is green deploy the next morning.
# **25th - Release GitLab CI**
...@@ -26,6 +26,6 @@ Otherwise include it in the monthly release and note there was a regression fix ...@@ -26,6 +26,6 @@ Otherwise include it in the monthly release and note there was a regression fix
1. Apply the patch to GitLab Cloud and the private GitLab development server 1. Apply the patch to GitLab Cloud and the private GitLab development server
1. [Build new packages with the latest version](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md) 1. [Build new packages with the latest version](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md)
1. Cherry-pick the changelog update back into master 1. Cherry-pick the changelog update back into master
1. Create blog post
1. Send tweets about the release from `@gitlabhq`, tweet should include the most important feature that the release is addressing as well as the link to the changelog 1. Send tweets about the release from `@gitlabhq`, tweet should include the most important feature that the release is addressing as well as the link to the changelog
1. Note in the 'GitLab X.X regressions' issue that the patch was published (CE only) 1. Note in the 'GitLab X.X regressions' issue that the patch was published (CE only)
1. Send out an email to the 'GitLab Newsletter' mailing list on MailChimp (or the 'Subscribers' list if the patch is EE only)
# From 6.x or 7.x to 7.4 # From 6.x or 7.x to 7.3
This allows you to upgrade any version of GitLab from 6.0 and up (including 7.0 and up) to 7.4. This allows you to upgrade any version of GitLab from 6.0 and up (including 7.0 and up) to 7.3.
## Global issue numbers ## Global issue numbers
...@@ -13,7 +13,11 @@ possible to edit the label text and color. The characters `?`, `&` and `,` are ...@@ -13,7 +13,11 @@ possible to edit the label text and color. The characters `?`, `&` and `,` are
no longer allowed however so those will be removed from your tags during the no longer allowed however so those will be removed from your tags during the
database migrations for GitLab 7.2. database migrations for GitLab 7.2.
## 0. Backup ## 0. Stop server
sudo service gitlab stop
## 1. Backup
It's useful to make a backup just in case things go south: It's useful to make a backup just in case things go south:
(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version) (With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
...@@ -23,10 +27,6 @@ cd /home/git/gitlab ...@@ -23,10 +27,6 @@ cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
``` ```
## 1. Stop server
sudo service gitlab stop
## 2. Update Ruby ## 2. Update Ruby
If you are still using Ruby 1.9.3 or below, you will need to update Ruby. If you are still using Ruby 1.9.3 or below, you will need to update Ruby.
...@@ -70,7 +70,7 @@ sudo -u git -H git checkout -- db/schema.rb # local changes will be restored aut ...@@ -70,7 +70,7 @@ sudo -u git -H git checkout -- db/schema.rb # local changes will be restored aut
For GitLab Community Edition: For GitLab Community Edition:
```bash ```bash
sudo -u git -H git checkout 7-4-stable sudo -u git -H git checkout 7-3-stable
``` ```
OR OR
...@@ -78,7 +78,7 @@ OR ...@@ -78,7 +78,7 @@ OR
For GitLab Enterprise Edition: For GitLab Enterprise Edition:
```bash ```bash
sudo -u git -H git checkout 7-4-stable-ee sudo -u git -H git checkout 7-3-stable-ee
``` ```
## 4. Install additional packages ## 4. Install additional packages
...@@ -99,6 +99,8 @@ sudo apt-get install pkg-config cmake ...@@ -99,6 +99,8 @@ sudo apt-get install pkg-config cmake
sed 's/^port .*/port 0/' /etc/redis/redis.conf.orig | sudo tee /etc/redis/redis.conf sed 's/^port .*/port 0/' /etc/redis/redis.conf.orig | sudo tee /etc/redis/redis.conf
# Enable Redis socket for default Debian / Ubuntu path # Enable Redis socket for default Debian / Ubuntu path
echo 'unixsocket /var/run/redis/redis.sock' | sudo tee -a /etc/redis/redis.conf echo 'unixsocket /var/run/redis/redis.sock' | sudo tee -a /etc/redis/redis.conf
# Be sure redis group can write to the socket, enable only if supported (>= redis 2.4.0).
sudo sed -i '/# unixsocketperm/ s/^# unixsocketperm.*/unixsocketperm 0775/' /etc/redis/redis.conf
# Activate the changes to redis.conf # Activate the changes to redis.conf
sudo service redis-server restart sudo service redis-server restart
# Add git to the redis group # Add git to the redis group
...@@ -152,14 +154,14 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab ...@@ -152,14 +154,14 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
TIP: to see what changed in `gitlab.yml.example` in this release use next command: TIP: to see what changed in `gitlab.yml.example` in this release use next command:
``` ```
git diff 6-0-stable:config/gitlab.yml.example 7-4-stable:config/gitlab.yml.example git diff 6-0-stable:config/gitlab.yml.example 7-3-stable:config/gitlab.yml.example
``` ```
* Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-4-stable/config/gitlab.yml.example but with your settings. * Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-3-stable/config/gitlab.yml.example but with your settings.
* Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-4-stable/config/unicorn.rb.example but with your settings. * Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-3-stable/config/unicorn.rb.example but with your settings.
* Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.0.1/config.yml.example but with your settings. * Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.0.1/config.yml.example but with your settings.
* HTTP setups: Make `/etc/nginx/sites-available/nginx` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-4-stable/lib/support/nginx/gitlab but with your settings. * HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-3-stable/lib/support/nginx/gitlab but with your settings.
* HTTPS setups: Make `/etc/nginx/sites-available/nginx-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-4-stable/lib/support/nginx/gitlab-ssl but with your settings. * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-3-stable/lib/support/nginx/gitlab-ssl but with your settings.
* Copy rack attack middleware config * Copy rack attack middleware config
```bash ```bash
...@@ -196,6 +198,76 @@ When using Google omniauth login, changes of the Google account required. ...@@ -196,6 +198,76 @@ When using Google omniauth login, changes of the Google account required.
Ensure that `Contacts API` and the `Google+ API` are enabled in the [Google Developers Console](https://console.developers.google.com/). Ensure that `Contacts API` and the `Google+ API` are enabled in the [Google Developers Console](https://console.developers.google.com/).
More details can be found at the [integration documentation](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/google.md). More details can be found at the [integration documentation](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/google.md).
## 12. Optional optimizations for GitLab setups with MySQL databases
Only applies if running MySQL database created with GitLab 6.7 or earlier. If you are not experiencing any issues you may not need the following instructions however following them will bring your database in line with the latest recommended installation configuration and help avoid future issues. Be sure to follow these directions exactly. These directions should be safe for any MySQL instance but to be sure make a current MySQL database backup beforehand.
```
# Stop GitLab
sudo service gitlab stop
# Secure your MySQL installation (added in GitLab 6.2)
sudo mysql_secure_installation
# Login to MySQL
mysql -u root -p
# do not type the 'mysql>', this is part of the prompt
# Convert all tables to use the InnoDB storage engine (added in GitLab 6.8)
SELECT CONCAT('ALTER TABLE gitlabhq_production.', table_name, ' ENGINE=InnoDB;') AS 'Copy & run these SQL statements:' FROM information_schema.tables WHERE table_schema = 'gitlabhq_production' AND `ENGINE` <> 'InnoDB' AND `TABLE_TYPE` = 'BASE TABLE';
# If previous query returned results, copy & run all outputed SQL statements
# Convert all tables to correct character set
SET foreign_key_checks = 0;
SELECT CONCAT('ALTER TABLE gitlabhq_production.', table_name, ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') AS 'Copy & run these SQL statements:' FROM information_schema.tables WHERE table_schema = 'gitlabhq_production' AND `TABLE_COLLATION` <> 'utf8_unicode_ci' AND `TABLE_TYPE` = 'BASE TABLE';
# If previous query returned results, copy & run all outputed SQL statements
# turn foreign key checks back on
SET foreign_key_checks = 1;
# Find MySQL users
mysql> SELECT user FROM mysql.user WHERE user LIKE '%git%';
# If git user exists and gitlab user does not exist
# you are done with the database cleanup tasks
mysql> \q
# If both users exist skip to Delete gitlab user
# Create new user for GitLab (changed in GitLab 6.4)
# change $password in the command below to a real password you pick
mysql> CREATE USER 'git'@'localhost' IDENTIFIED BY '$password';
# Grant the git user necessary permissions on the database
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES ON `gitlabhq_production`.* TO 'git'@'localhost';
# Delete the old gitlab user
mysql> DELETE FROM mysql.user WHERE user='gitlab';
# Quit the database session
mysql> \q
# Try connecting to the new database with the new user
sudo -u git -H mysql -u git -p -D gitlabhq_production
# Type the password you replaced $password with earlier
# You should now see a 'mysql>' prompt
# Quit the database session
mysql> \q
# Update database configuration details
# See config/database.yml.mysql for latest recommended configuration details
# Remove the reaping_frequency setting line if it exists (removed in GitLab 6.8)
# Set production -> pool: 10 (updated in GitLab 5.3)
# Set production -> username: git
# Set production -> password: the password your replaced $password with earlier
sudo -u git -H editor /home/git/gitlab/config/database.yml
## Things went south? Revert to previous version (6.0) ## Things went south? Revert to previous version (6.0)
### 1. Revert the code to the previous version ### 1. Revert the code to the previous version
......
# From 7.3 to 7.4 # From 7.3 to 7.4
### 0. Backup ### 0. Stop server
```bash sudo service gitlab stop
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```
### 1. Stop server ### 1. Backup
```bash ```bash
sudo service gitlab stop cd /home/git/gitlab
``` sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
### 2. Get latest code ### 2. Get latest code
```bash ```bash
cd /home/git/gitlab
sudo -u git -H git fetch --all sudo -u git -H git fetch --all
sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
``` ```
...@@ -56,31 +52,7 @@ sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS ...@@ -56,31 +52,7 @@ sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS
sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
``` ```
### 4. Update config files
### 4. Configure Redis to use sockets
# Configure redis to use sockets
sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.orig
# Disable Redis listening on TCP by setting 'port' to 0
sed 's/^port .*/port 0/' /etc/redis/redis.conf.orig | sudo tee /etc/redis/redis.conf
# Enable Redis socket for default Debian / Ubuntu path
echo 'unixsocket /var/run/redis/redis.sock' | sudo tee -a /etc/redis/redis.conf
# Be sure redis group can write to the socket, enable only if supported (>= redis 2.4.0).
sed -i '/# unixsocketperm/ s/^# unixsocketperm.*/unixsocketperm 0775/' /etc/redis/redis.conf
# Activate the changes to redis.conf
sudo service redis-server restart
# Add git to the redis group
sudo usermod -aG redis git
# Configure Redis connection settings
sudo -u git -H cp config/resque.yml.example config/resque.yml
# Change the Redis socket path if you are not using the default Debian / Ubuntu configuration
sudo -u git -H editor config/resque.yml
# Configure gitlab-shell to use Redis sockets
sudo -u git -H sed -i 's|^ # socket.*| socket: /var/run/redis/redis.sock|' /home/git/gitlab-shell/config.yml
### 5. Update config files
#### New configuration options for gitlab.yml #### New configuration options for gitlab.yml
...@@ -93,25 +65,25 @@ git diff origin/7-3-stable:config/gitlab.yml.example origin/7-4-stable:config/gi ...@@ -93,25 +65,25 @@ git diff origin/7-3-stable:config/gitlab.yml.example origin/7-4-stable:config/gi
#### Change timeout for unicorn #### Change timeout for unicorn
``` ```
# config/unicorn.rb # set timeout to 60
timeout 60 sudo -u git -H editor config/unicorn.rb
``` ```
#### Change nginx https settings #### Change nginx https settings
* HTTPS setups: Make `/etc/nginx/sites-available/nginx-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-4-stable/lib/support/nginx/gitlab-ssl but with your setting * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-4-stable/lib/support/nginx/gitlab-ssl but with your setting
#### Update database.yml config file(for mysql only) if needed (basically it is required for old gitlab installations) #### MySQL Databases: Update database.yml config file
* Add `collation: utf8_general_ci` to config/database.yml as seen in [config/database.yml.mysql](config/database.yml.mysql) * Add `collation: utf8_general_ci` to config/database.yml as seen in [config/database.yml.mysql](config/database.yml.mysql)
### 6. Start application ### 5. Start application
sudo service gitlab start sudo service gitlab start
sudo service nginx restart sudo service nginx restart
### 7. Check application status ### 6. Check application status
Check if GitLab and its environment are configured correctly: Check if GitLab and its environment are configured correctly:
...@@ -123,17 +95,15 @@ To make sure you didn't miss anything run a more thorough check with: ...@@ -123,17 +95,15 @@ To make sure you didn't miss anything run a more thorough check with:
If all items are green, then congratulations upgrade is complete! If all items are green, then congratulations upgrade is complete!
### 8. Update OmniAuth configuration
When using Google omniauth login, changes of the Google account required. ### 7. Optional optimizations for GitLab setups with MySQL databases
Ensure that `Contacts API` and the `Google+ API` are enabled in the [Google Developers Console](https://console.developers.google.com/).
More details can be found at the [integration documentation](../integration/google.md).
### 9. Optional optimizations for GitLab setups with MySQL databases
Only applies if running MySQL database created with GitLab 6.7 or earlier. If you are not experiencing any issues you may not need the following instructions however following them will bring your database in line with the latest recommended installation configuration and help avoid future issues. Be sure to follow these directions exactly. These directions should be safe for any MySQL instance but to be sure make a current MySQL database backup beforehand. Only applies if running MySQL database created with GitLab 6.7 or earlier. If you are not experiencing any issues you may not need the following instructions however following them will bring your database in line with the latest recommended installation configuration and help avoid future issues. Be sure to follow these directions exactly. These directions should be safe for any MySQL instance but to be sure make a current MySQL database backup beforehand.
``` ```
# Stop GitLab
sudo service gitlab stop
# Secure your MySQL installation (added in GitLab 6.2) # Secure your MySQL installation (added in GitLab 6.2)
sudo mysql_secure_installation sudo mysql_secure_installation
...@@ -195,6 +165,9 @@ mysql> \q ...@@ -195,6 +165,9 @@ mysql> \q
# Set production -> username: git # Set production -> username: git
# Set production -> password: the password your replaced $password with earlier # Set production -> password: the password your replaced $password with earlier
sudo -u git -H editor /home/git/gitlab/config/database.yml sudo -u git -H editor /home/git/gitlab/config/database.yml
# Run thorough check
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
``` ```
......
Feature: Public snippets
Scenario: Unauthenticated user should see public snippets
Given There is public "Personal snippet one" snippet
And I visit snippet page "Personal snippet one"
Then I should see snippet "Personal snippet one"
Scenario: Unauthenticated user should see raw public snippets
Given There is public "Personal snippet one" snippet
And I visit snippet raw page "Personal snippet one"
Then I should see raw snippet "Personal snippet one"
...@@ -25,4 +25,4 @@ Feature: Snippets ...@@ -25,4 +25,4 @@ Feature: Snippets
Scenario: I destroy "Personal snippet one" Scenario: I destroy "Personal snippet one"
Given I visit snippet page "Personal snippet one" Given I visit snippet page "Personal snippet one"
And I click link "Destroy" And I click link "Destroy"
Then I should not see "Personal snippet one" in snippets Then I should not see "Personal snippet one" in snippets
\ No newline at end of file
...@@ -10,6 +10,7 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps ...@@ -10,6 +10,7 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps
step 'I should see issues authored by me' do step 'I should see issues authored by me' do
should_see(authored_issue) should_see(authored_issue)
should_see(authored_issue_on_public_project)
should_not_see(assigned_issue) should_not_see(assigned_issue)
should_not_see(other_issue) should_not_see(other_issue)
end end
...@@ -22,6 +23,7 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps ...@@ -22,6 +23,7 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps
step 'I have authored issues' do step 'I have authored issues' do
authored_issue authored_issue
authored_issue_on_public_project
end end
step 'I have assigned issues' do step 'I have assigned issues' do
...@@ -64,6 +66,10 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps ...@@ -64,6 +66,10 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps
@other_issue ||= create :issue, project: project @other_issue ||= create :issue, project: project
end end
def authored_issue_on_public_project
@authored_issue_on_public_project ||= create :issue, author: current_user, project: public_project
end
def project def project
@project ||= begin @project ||= begin
project =create :project project =create :project
...@@ -71,4 +77,8 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps ...@@ -71,4 +77,8 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps
project project
end end
end end
def public_project
@public_project ||= create :project, :public
end
end end
...@@ -4,13 +4,17 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps ...@@ -4,13 +4,17 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
step 'I should see merge requests assigned to me' do step 'I should see merge requests assigned to me' do
should_see(assigned_merge_request) should_see(assigned_merge_request)
should_see(assigned_merge_request_from_fork)
should_not_see(authored_merge_request) should_not_see(authored_merge_request)
should_not_see(authored_merge_request_from_fork)
should_not_see(other_merge_request) should_not_see(other_merge_request)
end end
step 'I should see merge requests authored by me' do step 'I should see merge requests authored by me' do
should_see(authored_merge_request) should_see(authored_merge_request)
should_see(authored_merge_request_from_fork)
should_not_see(assigned_merge_request) should_not_see(assigned_merge_request)
should_not_see(assigned_merge_request_from_fork)
should_not_see(other_merge_request) should_not_see(other_merge_request)
end end
...@@ -22,10 +26,12 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps ...@@ -22,10 +26,12 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
step 'I have authored merge requests' do step 'I have authored merge requests' do
authored_merge_request authored_merge_request
authored_merge_request_from_fork
end end
step 'I have assigned merge requests' do step 'I have assigned merge requests' do
assigned_merge_request assigned_merge_request
assigned_merge_request_from_fork
end end
step 'I have other merge requests' do step 'I have other merge requests' do
...@@ -53,15 +59,41 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps ...@@ -53,15 +59,41 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
end end
def assigned_merge_request def assigned_merge_request
@assigned_merge_request ||= create :merge_request, assignee: current_user, target_project: project, source_project: project @assigned_merge_request ||= create :merge_request,
assignee: current_user,
target_project: project,
source_project: project
end end
def authored_merge_request def authored_merge_request
@authored_merge_request ||= create :merge_request, source_branch: 'simple_merge_request', author: current_user, target_project: project, source_project: project @authored_merge_request ||= create :merge_request,
source_branch: 'simple_merge_request',
author: current_user,
target_project: project,
source_project: project
end end
def other_merge_request def other_merge_request
@other_merge_request ||= create :merge_request, source_branch: '2_3_notes_fix', target_project: project, source_project: project @other_merge_request ||= create :merge_request,
source_branch: '2_3_notes_fix',
target_project: project,
source_project: project
end
def authored_merge_request_from_fork
@authored_merge_request_from_fork ||= create :merge_request,
source_branch: 'basic_page',
author: current_user,
target_project: public_project,
source_project: forked_project
end
def assigned_merge_request_from_fork
@assigned_merge_request_from_fork ||= create :merge_request,
source_branch: 'basic_page_fix',
assignee: current_user,
target_project: public_project,
source_project: forked_project
end end
def project def project
...@@ -71,4 +103,12 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps ...@@ -71,4 +103,12 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
project project
end end
end end
def public_project
@public_project ||= create :project, :public
end
def forked_project
@forked_project ||= Projects::ForkService.new(public_project, current_user).execute
end
end end
...@@ -51,4 +51,13 @@ module SharedSnippet ...@@ -51,4 +51,13 @@ module SharedSnippet
visibility_level: Snippet::PUBLIC, visibility_level: Snippet::PUBLIC,
author: current_user) author: current_user)
end end
step 'There is public "Personal snippet one" snippet' do
create(:personal_snippet,
title: "Personal snippet one",
content: "Test content",
file_name: "snippet.rb",
visibility_level: Snippet::PUBLIC,
author: create(:user))
end
end end
class Spinach::Features::PublicSnippets < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedSnippet
step 'I should see snippet "Personal snippet one"' do
page.should have_no_xpath("//i[@class='public-snippet']")
end
step 'I should see raw snippet "Personal snippet one"' do
page.should have_text(snippet.content)
end
step 'I visit snippet page "Personal snippet one"' do
visit snippet_path(snippet)
end
step 'I visit snippet raw page "Personal snippet one"' do
visit raw_snippet_path(snippet)
end
def snippet
@snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one")
end
end
# Read about interceptors in http://guides.rubyonrails.org/action_mailer_basics.html#intercepting-emails
class DisableEmailInterceptor
def self.delivering_email(message)
message.perform_deliveries = false
Rails.logger.info "Emails disabled! Interceptor prevented sending mail #{message.subject}"
end
end
...@@ -42,7 +42,7 @@ module Gitlab ...@@ -42,7 +42,7 @@ module Gitlab
end end
def adapter def adapter
OmniAuth::LDAP::Adaptor.new(config.options) OmniAuth::LDAP::Adaptor.new(config.options.symbolize_keys)
end end
def config def config
...@@ -68,4 +68,4 @@ module Gitlab ...@@ -68,4 +68,4 @@ module Gitlab
end end
end end
end end
end end
\ No newline at end of file
...@@ -16,10 +16,23 @@ module Gitlab ...@@ -16,10 +16,23 @@ module Gitlab
servers.map {|server| server['provider_name'] } servers.map {|server| server['provider_name'] }
end end
def self.valid_provider?(provider)
providers.include?(provider)
end
def self.invalid_provider(provider)
raise "Unknown provider (#{provider}). Available providers: #{providers}"
end
def initialize(provider) def initialize(provider)
@provider = provider if self.class.valid_provider?(provider)
invalid_provider unless valid_provider? @provider = provider
@options = config_for(provider) elsif provider == 'ldap'
@provider = self.class.providers.first
else
self.class.invalid_provider(provider)
end
@options = config_for(@provider) # Use @provider, not provider
end end
def enabled? def enabled?
...@@ -89,14 +102,6 @@ module Gitlab ...@@ -89,14 +102,6 @@ module Gitlab
end end
end end
def valid_provider?
self.class.providers.include?(provider)
end
def invalid_provider
raise "Unknown provider (#{provider}). Available providers: #{self.class.providers}"
end
def auth_options def auth_options
{ {
auth: { auth: {
......
...@@ -202,7 +202,7 @@ module Gitlab ...@@ -202,7 +202,7 @@ module Gitlab
if identifier == "all" if identifier == "all"
link_to("@all", project_url(project), options) link_to("@all", project_url(project), options)
elsif user = User.find_by(username: identifier) elsif User.find_by(username: identifier)
link_to("@#{identifier}", user_url(identifier), options) link_to("@#{identifier}", user_url(identifier), options)
end end
end end
......
...@@ -19,7 +19,7 @@ module Gitlab ...@@ -19,7 +19,7 @@ module Gitlab
issue = Issue.find(id) issue = Issue.find(id)
project_issue_url(id: issue.iid, project_issue_url(id: issue.iid,
project_id: issue.project, project_id: issue.project,
host: Settings.gitlab['url']) host: Gitlab.config.gitlab['url'])
end end
end end
end end
...@@ -60,18 +60,16 @@ server { ...@@ -60,18 +60,16 @@ server {
client_max_body_size 20m; client_max_body_size 20m;
## Strong SSL Security ## Strong SSL Security
## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
ssl on; ssl on;
ssl_certificate /etc/nginx/ssl/gitlab.crt; ssl_certificate /etc/nginx/ssl/gitlab.crt;
ssl_certificate_key /etc/nginx/ssl/gitlab.key; ssl_certificate_key /etc/nginx/ssl/gitlab.key;
# GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs # GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4'; ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on;
ssl_session_cache builtin:1000 shared:SSL:10m; ssl_session_cache shared:SSL:10m;
ssl_prefer_server_ciphers on;
## [WARNING] The following header states that the browser should only communicate ## [WARNING] The following header states that the browser should only communicate
## with your server over a secure connection for the next 24 months. ## with your server over a secure connection for the next 24 months.
...@@ -88,7 +86,7 @@ server { ...@@ -88,7 +86,7 @@ server {
# ssl_stapling_verify on; # ssl_stapling_verify on;
# ssl_trusted_certificate /etc/nginx/ssl/stapling.trusted.crt; # ssl_trusted_certificate /etc/nginx/ssl/stapling.trusted.crt;
# resolver 208.67.222.222 208.67.222.220 valid=300s; # Can change to your DNS resolver if desired # resolver 208.67.222.222 208.67.222.220 valid=300s; # Can change to your DNS resolver if desired
# resolver_timeout 10s; # resolver_timeout 5s;
## [Optional] Generate a stronger DHE parameter: ## [Optional] Generate a stronger DHE parameter:
## sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096 ## sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
......
...@@ -15,26 +15,17 @@ namespace :gitlab do ...@@ -15,26 +15,17 @@ namespace :gitlab do
git_base_path = Gitlab.config.gitlab_shell.repos_path git_base_path = Gitlab.config.gitlab_shell.repos_path
repos_to_import = Dir.glob(git_base_path + '/**/*.git') repos_to_import = Dir.glob(git_base_path + '/**/*.git')
namespaces = Namespace.pluck(:path)
repos_to_import.each do |repo_path| repos_to_import.each do |repo_path|
# strip repo base path # strip repo base path
repo_path[0..git_base_path.length] = '' repo_path[0..git_base_path.length] = ''
path = repo_path.sub(/\.git$/, '') path = repo_path.sub(/\.git$/, '')
name = File.basename path group_name, name = File.split(path)
group_name = File.dirname path
group_name = nil if group_name == '.' group_name = nil if group_name == '.'
# Skip if group or user
if namespaces.include?(name)
puts "Skipping #{project.name} due to namespace conflict with group or user".yellow
next
end
puts "Processing #{repo_path}".yellow puts "Processing #{repo_path}".yellow
if path =~ /.wiki\Z/ if path =~ /\.wiki\Z/
puts " * Skipping wiki repo" puts " * Skipping wiki repo"
next next
end end
...@@ -53,9 +44,9 @@ namespace :gitlab do ...@@ -53,9 +44,9 @@ namespace :gitlab do
# find group namespace # find group namespace
if group_name if group_name
group = Group.find_by(path: group_name) group = Namespace.find_by(path: group_name)
# create group namespace # create group namespace
if !group unless group
group = Group.new(:name => group_name) group = Group.new(:name => group_name)
group.path = group_name group.path = group_name
group.owner = user group.owner = user
......
...@@ -7,9 +7,9 @@ namespace :gitlab do ...@@ -7,9 +7,9 @@ namespace :gitlab do
default_version = File.read(File.join(Rails.root, "GITLAB_SHELL_VERSION")).strip default_version = File.read(File.join(Rails.root, "GITLAB_SHELL_VERSION")).strip
args.with_defaults(tag: 'v' + default_version, repo: "https://gitlab.com/gitlab-org/gitlab-shell.git") args.with_defaults(tag: 'v' + default_version, repo: "https://gitlab.com/gitlab-org/gitlab-shell.git")
user = Settings.gitlab.user user = Gitlab.config.gitlab.user
home_dir = Rails.env.test? ? Rails.root.join('tmp/tests') : Settings.gitlab.user_home home_dir = Rails.env.test? ? Rails.root.join('tmp/tests') : Gitlab.config.gitlab.user_home
gitlab_url = Settings.gitlab.url gitlab_url = Gitlab.config.gitlab.url
# gitlab-shell requires a / at the end of the url # gitlab-shell requires a / at the end of the url
gitlab_url += '/' unless gitlab_url.end_with?('/') gitlab_url += '/' unless gitlab_url.end_with?('/')
repos_path = Gitlab.config.gitlab_shell.repos_path repos_path = Gitlab.config.gitlab_shell.repos_path
...@@ -17,7 +17,7 @@ namespace :gitlab do ...@@ -17,7 +17,7 @@ namespace :gitlab do
# Clone if needed # Clone if needed
unless File.directory?(target_dir) unless File.directory?(target_dir)
sh "git clone '#{args.repo}' '#{target_dir}'" sh(*%W(git clone #{args.repo} #{target_dir}))
end end
# Make sure we're on the right tag # Make sure we're on the right tag
......
...@@ -64,6 +64,13 @@ describe SnippetsFinder do ...@@ -64,6 +64,13 @@ describe SnippetsFinder do
snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user) snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user)
snippets.should include(@snippet1, @snippet2, @snippet3) snippets.should include(@snippet1, @snippet2, @snippet3)
end end
it "returns only public snippets if unauthenticated user" do
snippets = SnippetsFinder.new.execute(nil, filter: :by_user, user: user)
snippets.should include(@snippet3)
snippets.should_not include(@snippet2, @snippet1)
end
end end
context 'by_project filter' do context 'by_project filter' do
......
...@@ -594,7 +594,9 @@ describe GitlabMarkdownHelper do ...@@ -594,7 +594,9 @@ describe GitlabMarkdownHelper do
end end
it "should generate absolute urls for emoji" do it "should generate absolute urls for emoji" do
markdown(":smile:").should include("src=\"http://localhost/assets/emoji/smile.png") markdown(':smile:').should(
include(%(src="#{Gitlab.config.gitlab.url}/assets/emoji/smile.png))
)
end end
it "should generate absolute urls for emoji if relative url is present" do it "should generate absolute urls for emoji if relative url is present" do
......
require 'spec_helper'
describe DisableEmailInterceptor do
before do
ActionMailer::Base.register_interceptor(DisableEmailInterceptor)
end
it 'should not send emails' do
Gitlab.config.gitlab.stub(:email_enabled).and_return(false)
expect {
deliver_mail
}.not_to change(ActionMailer::Base.deliveries, :count)
end
after do
# Removing interceptor from the list because unregister_interceptor is
# implemented in later version of mail gem
# See: https://github.com/mikel/mail/pull/705
Mail.class_variable_set(:@@delivery_interceptors, [])
end
def deliver_mail
key = create :personal_key
Notify.new_ssh_key_email(key.id)
end
end
...@@ -16,5 +16,19 @@ describe Gitlab::LDAP::Config do ...@@ -16,5 +16,19 @@ describe Gitlab::LDAP::Config do
it "raises an error if a unknow provider is used" do it "raises an error if a unknow provider is used" do
expect{ Gitlab::LDAP::Config.new 'unknown' }.to raise_error expect{ Gitlab::LDAP::Config.new 'unknown' }.to raise_error
end end
context "if 'ldap' is the provider name" do
let(:provider) { 'ldap' }
context "and 'ldap' is not in defined as a provider" do
before { Gitlab::LDAP::Config.stub(providers: %w{ldapmain}) }
it "uses the first provider" do
# Fetch the provider_name attribute from 'options' so that we know
# that the 'options' Hash is not empty/nil.
expect(config.options['provider_name']).to eq('ldapmain')
end
end
end
end end
end end
\ No newline at end of file
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