diff --git a/CHANGELOG b/CHANGELOG index 0725649306..d3171da81c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,19 +1,29 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.6.0 (unreleased) + - Fix bug where wrong commit ID was being used in a merge request diff to show old image (Stan Hu) + - Add confidential issues - Bump gitlab_git to 9.0.3 (Stan Hu) - Support Golang subpackage fetching (Stan Hu) - Bump Capybara gem to 2.6.2 (Stan Hu) + - New branch button appears on issues where applicable - Contributions to forked projects are included in calendar - Improve the formatting for the user page bio (Connor Shea) + - Easily (un)mark merge request as WIP using link + - Use specialized system notes when MR is (un)marked as WIP - Removed the default password from the initial admin account created during setup. A password can be provided during setup (see installation docs), or GitLab will ask the user to create a new one upon first visit. - Fix issue when pushing to projects ending in .wiki + - Add support for wiki with UTF-8 page names (Hiroyuki Sato) + - Fix wiki search results point to raw source (Hiroyuki Sato) - Don't load all of GitLab in mail_room + - HTTP error pages work independently from location and config (Artem Sidorenko) - Update `omniauth-saml` to 1.5.0 to allow for custom response attributes to be set - Memoize @group in Admin::GroupsController (Yatish Mehta) - Indicate how much an MR diverged from the target branch (Pierre de La Morinerie) + - Added omniauth-auth0 Gem (Daniel Carraro) + - Add label description in tooltip to labels in issue index and sidebar - Strip leading and trailing spaces in URL validator (evuez) - Add "last_sign_in_at" and "confirmed_at" to GET /users/* API endpoints for admins (evuez) - Return empty array instead of 404 when commit has no statuses in commit status API @@ -21,6 +31,7 @@ v 8.6.0 (unreleased) - Rewrite logo to simplify SVG code (Sean Lang) - Allow to use YAML anchors when parsing the `.gitlab-ci.yml` (Pascal Bach) - Ignore jobs that start with `.` (hidden jobs) + - Hide builds from project's settings when the feature is disabled - Allow to pass name of created artifacts archive in `.gitlab-ci.yml` - Refactor and greatly improve search performance - Add support for cross-project label references @@ -32,14 +43,26 @@ v 8.6.0 (unreleased) - Fix bug where Bitbucket `closed` issues were imported as `opened` (Iuri de Silvio) - Don't show Issues/MRs from archived projects in Groups view - Fix wrong "iid of max iid" in Issuable sidebar for some merged MRs + - Fix empty source_sha on Merge Request when there is no diff (Pierre de La Morinerie) - Increase the notes polling timeout over time (Roberto Dip) - Add shortcut to toggle markdown preview (Florent Baldino) - Show labels in dashboard and group milestone views + - Fix an issue when the target branch of a MR had been deleted - Add main language of a project in the list of projects (Tiago Botelho) + - Add #upcoming filter to Milestone filter (Tiago Botelho) - Add ability to show archived projects on dashboard, explore and group pages - Move group activity to separate page - Create external users which are excluded of internal and private projects unless access was explicitly granted - Continue parameters are checked to ensure redirection goes to the same instance + - User deletion is now done in the background so the request can not time out + - Canceled builds are now ignored in compound build status if marked as `allowed to fail` + - Trigger a todo for mentions on commits page + +v 8.5.8 + - Bump Git version requirement to 2.7.4 + +v 8.5.7 + - Bump Git version requirement to 2.7.3 v 8.5.6 - Obtain a lease before querying LDAP @@ -49,7 +72,6 @@ v 8.5.5 - Prevent a 500 error in Todos when author was removed - Fix pagination for filtered dashboard and explore pages - Fix "Show all" link behavior - - Add #upcoming filter to Milestone filter (Tiago Botelho) v 8.5.4 - Do not cache requests for badges (including builds badge) diff --git a/Gemfile b/Gemfile index a0e8e79662..e500bfb788 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,7 @@ gem 'devise', '~> 3.5.4' gem 'devise-async', '~> 0.9.0' gem 'doorkeeper', '~> 2.2.0' gem 'omniauth', '~> 1.3.1' +gem 'omniauth-auth0', '~> 1.4.1' gem 'omniauth-azure-oauth2', '~> 0.0.6' gem 'omniauth-bitbucket', '~> 0.0.2' gem 'omniauth-cas3', '~> 1.1.2' @@ -50,7 +51,7 @@ gem "browser", '~> 1.0.0' # Extracting information from a git repository # Provide access to Gitlab::Git library -gem "gitlab_git", '~> 9.0' +gem "gitlab_git", '~> 10.0' # LDAP Auth # GitLab fork with several improvements to original library. For full list of changes @@ -58,7 +59,9 @@ gem "gitlab_git", '~> 9.0' gem 'gitlab_omniauth-ldap', '~> 1.2.1', require: "omniauth-ldap" # Git Wiki -gem 'gollum-lib', '~> 4.1.0' +# Required manually in config/initializers/gollum.rb to control load order +gem 'gollum-lib', '~> 4.1.0', require: false +gem 'gollum-rugged_adapter', '~> 0.4.2', require: false # Language detection gem "github-linguist", "~> 4.7.0", require: "linguist" diff --git a/Gemfile.lock b/Gemfile.lock index 9c785c903c..e2dba76ce5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -359,11 +359,11 @@ GEM posix-spawn (~> 0.3) gitlab_emoji (0.3.1) gemojione (~> 2.2, >= 2.2.1) - gitlab_git (9.0.3) + gitlab_git (10.0.0) activesupport (~> 4.0) charlock_holmes (~> 0.7.3) github-linguist (~> 4.7.0) - rugged (~> 0.24.0b13) + rugged (~> 0.24.0) gitlab_meta (7.0) gitlab_omniauth-ldap (1.2.1) net-ldap (~> 0.9) @@ -381,6 +381,9 @@ GEM rouge (~> 1.9) sanitize (~> 2.1.0) stringex (~> 2.5.1) + gollum-rugged_adapter (0.4.2) + mime-types (>= 1.15) + rugged (~> 0.24.0, >= 0.21.3) gon (6.0.1) actionpack (>= 3.0) json @@ -495,6 +498,8 @@ GEM omniauth (1.3.1) hashie (>= 1.2, < 4) rack (>= 1.0, < 3) + omniauth-auth0 (1.4.1) + omniauth-oauth2 (~> 1.1) omniauth-azure-oauth2 (0.0.6) jwt (~> 1.0) omniauth (~> 1.0) @@ -703,7 +708,7 @@ GEM rubyntlm (0.5.2) rubypants (0.2.0) rufus-scheduler (3.1.10) - rugged (0.24.0b13) + rugged (0.24.0) safe_yaml (1.0.4) sanitize (2.1.0) nokogiri (>= 1.4.4) @@ -937,10 +942,11 @@ DEPENDENCIES github-markup (~> 1.3.1) gitlab-flowdock-git-hook (~> 1.0.1) gitlab_emoji (~> 0.3.0) - gitlab_git (~> 9.0) + gitlab_git (~> 10.0) gitlab_meta (= 7.0) gitlab_omniauth-ldap (~> 1.2.1) gollum-lib (~> 4.1.0) + gollum-rugged_adapter (~> 0.4.2) gon (~> 6.0.1) grape (~> 0.13.0) grape-entity (~> 0.4.2) @@ -969,6 +975,7 @@ DEPENDENCIES oauth2 (~> 1.0.0) octokit (~> 3.8.0) omniauth (~> 1.3.1) + omniauth-auth0 (~> 1.4.1) omniauth-azure-oauth2 (~> 0.0.6) omniauth-bitbucket (~> 0.0.2) omniauth-cas3 (~> 1.1.2) diff --git a/README.md b/README.md index 3ec1d4a776..afa60116eb 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ GitLab is a Ruby on Rails application that runs on the following software: - Ubuntu/Debian/CentOS/RHEL - Ruby (MRI) 2.1 -- Git 1.7.10+ +- Git 2.7.4+ - Redis 2.8+ - MySQL or PostgreSQL diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 1be86e3b82..f5e1ca9860 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -14,7 +14,6 @@ class Dispatcher path = page.split(':') shortcut_handler = null - switch page when 'projects:issues:index' Issues.init() @@ -25,6 +24,8 @@ class Dispatcher new ZenMode() when 'projects:milestones:show', 'groups:milestones:show', 'dashboard:milestones:show' new Milestone() + when 'dashboard:todos:index' + new Todos() when 'projects:milestones:new', 'projects:milestones:edit' new ZenMode() new DropzoneInput($('.milestone-form')) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 4f03847775..c81e8bf760 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -246,11 +246,15 @@ class GitLabDropdown if oldValue value = "#{oldValue},#{value}" else - @dropdown.find(ACTIVE_CLASS).removeClass ACTIVE_CLASS + @dropdown.find(".#{ACTIVE_CLASS}").removeClass ACTIVE_CLASS # Toggle active class for the tick mark el.toggleClass "is-active" + # Toggle the dropdown label + if @options.toggleLabel + $(@el).find(".dropdown-toggle-text").text @options.toggleLabel(selectedObject) + if value? if !field.length # Create hidden input for form diff --git a/app/assets/javascripts/issuable_form.js.coffee b/app/assets/javascripts/issuable_form.js.coffee index 48c249943f..6c1699c178 100644 --- a/app/assets/javascripts/issuable_form.js.coffee +++ b/app/assets/javascripts/issuable_form.js.coffee @@ -1,4 +1,5 @@ class @IssuableForm + wipRegex: /^\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i constructor: (@form) -> GitLab.GfmAutoComplete.setup() new UsersSelect() @@ -14,6 +15,8 @@ class @IssuableForm @form.on "submit", @resetAutosave @form.on "click", ".btn-cancel", @resetAutosave + @initWip() + initAutosave: -> new Autosave @titleField, [ document.location.pathname, @@ -30,3 +33,41 @@ class @IssuableForm resetAutosave: => @titleField.data("autosave").reset() @descriptionField.data("autosave").reset() + + initWip: -> + @$wipExplanation = @form.find(".js-wip-explanation") + @$noWipExplanation = @form.find(".js-no-wip-explanation") + return unless @$wipExplanation.length and @$noWipExplanation.length + + @form.on "click", ".js-toggle-wip", @toggleWip + + @titleField.on "keyup blur", @renderWipExplanation + + @renderWipExplanation() + + workInProgress: -> + @wipRegex.test @titleField.val() + + renderWipExplanation: => + if @workInProgress() + @$wipExplanation.show() + @$noWipExplanation.hide() + else + @$wipExplanation.hide() + @$noWipExplanation.show() + + toggleWip: (event) => + event.preventDefault() + + if @workInProgress() + @removeWip() + else + @addWip() + + @renderWipExplanation() + + removeWip: -> + @titleField.val @titleField.val().replace(@wipRegex, "") + + addWip: -> + @titleField.val "WIP: #{@titleField.val()}" diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee index d663e34871..f50df1f5ea 100644 --- a/app/assets/javascripts/issue.js.coffee +++ b/app/assets/javascripts/issue.js.coffee @@ -7,6 +7,7 @@ class @Issue # Prevent duplicate event bindings @disableTaskList() @fixAffixScroll() + @initParticipants() if $('a.btn-close').length @initTaskList() @initIssueBtnEventListeners() @@ -84,3 +85,27 @@ class @Issue type: 'PATCH' url: $('form.js-issuable-update').attr('action') data: patchData + + initParticipants: -> + _this = @ + $(document).on "click", ".js-participants-more", @toggleHiddenParticipants + + $(".js-participants-author").each (i) -> + if i >= _this.PARTICIPANTS_ROW_COUNT + $(@) + .addClass "js-participants-hidden" + .hide() + + toggleHiddenParticipants: (e) -> + e.preventDefault() + + currentText = $(this).text().trim() + lessText = $(this).data("less-text") + originalText = $(this).data("original-text") + + if currentText is originalText + $(this).text(lessText) + else + $(this).text(originalText) + + $(".js-participants-hidden").toggle() diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee index a0acf3028b..1127b28926 100644 --- a/app/assets/javascripts/issues.js.coffee +++ b/app/assets/javascripts/issues.js.coffee @@ -41,24 +41,28 @@ @timer = null $("#issue_search").keyup -> clearTimeout(@timer) - @timer = setTimeout(Issues.filterResults, 500) + @timer = setTimeout( -> + Issues.filterResults $("#issue_search_form") + , 500) - filterResults: => - form = $("#issue_search_form") - search = $("#issue_search").val() - $('.issues-holder').css("opacity", '0.5') - issues_url = form.attr('action') + '?' + form.serialize() + filterResults: (form) => + $('.issues-holder, .merge-requests-holder').css("opacity", '0.5') + formAction = form.attr('action') + formData = form.serialize() + issuesUrl = formAction + issuesUrl += ("#{if formAction.indexOf("?") < 0 then '?' else '&'}") + issuesUrl += formData $.ajax type: "GET" - url: form.attr('action') - data: form.serialize() + url: formAction + data: formData complete: -> - $('.issues-holder').css("opacity", '1.0') + $('.issues-holder, .merge-requests-holder').css("opacity", '1.0') success: (data) -> - $('.issues-holder').html(data.html) + $('.issues-holder, .merge-requests-holder').html(data.html) # Change url so if user reload a page - search results are saved - history.replaceState {page: issues_url}, document.title, issues_url + history.replaceState {page: issuesUrl}, document.title, issuesUrl Issues.reload() dataType: "json" diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee index 5ade2cb66c..4a0c18a99a 100644 --- a/app/assets/javascripts/labels_select.js.coffee +++ b/app/assets/javascripts/labels_select.js.coffee @@ -1,30 +1,32 @@ class @LabelsSelect constructor: -> $('.js-label-select').each (i, dropdown) -> - projectId = $(dropdown).data('project-id') - labelUrl = $(dropdown).data("labels") - selectedLabel = $(dropdown).data('selected') + $dropdown = $(dropdown) + projectId = $dropdown.data('project-id') + labelUrl = $dropdown.data('labels') + selectedLabel = $dropdown.data('selected') if selectedLabel - selectedLabel = selectedLabel.split(",") + selectedLabel = selectedLabel.split(',') newLabelField = $('#new_label_name') newColorField = $('#new_label_color') - showNo = $(dropdown).data('show-no') - showAny = $(dropdown).data('show-any') + showNo = $dropdown.data('show-no') + showAny = $dropdown.data('show-any') + defaultLabel = $dropdown.data('default-label') if newLabelField.length - $('.suggest-colors-dropdown a').on "click", (e) -> + $('.suggest-colors-dropdown a').on 'click', (e) -> e.preventDefault() e.stopPropagation() - newColorField.val $(this).data("color") + newColorField.val $(this).data('color') $('.js-dropdown-label-color-preview') - .css 'background-color', $(this).data("color") + .css 'background-color', $(this).data('color') .addClass 'is-active' - $('.js-new-label-btn').on "click", (e) -> + $('.js-new-label-btn').on 'click', (e) -> e.preventDefault() e.stopPropagation() - if newLabelField.val() isnt "" && newColorField.val() isnt "" + if newLabelField.val() isnt '' and newColorField.val() isnt '' $('.js-new-label-btn').disable() # Create new label with API @@ -33,46 +35,38 @@ class @LabelsSelect color: newColorField.val() }, (label) -> $('.js-new-label-btn').enable() - $('.dropdown-menu-back', $(dropdown).parent()).trigger "click" + $('.dropdown-menu-back', $dropdown.parent()).trigger 'click' - $(dropdown).glDropdown( + $dropdown.glDropdown( data: (term, callback) -> - # We have to fetch the JS version of the labels list because there is no - # public facing JSON url for labels $.ajax( url: labelUrl ).done (data) -> - html = $(data) - data = [] - html.find('.label-row a').each -> - data.push( - title: $(@).text().trim() - ) - if showNo data.unshift( - id: "0" - title: 'No label' + id: 0 + title: 'No Label' ) if showAny data.unshift( - title: 'Any label' + isAny: true + title: 'Any Label' ) if data.length > 2 - data.splice 2, 0, "divider" + data.splice 2, 0, 'divider' callback data renderRow: (label) -> if $.isArray(selectedLabel) - selected = "" + selected = '' $.each selectedLabel, (i, selectedLbl) -> selectedLbl = selectedLbl.trim() - if selected is "" && label.title is selectedLbl - selected = "is-active" + if selected is '' and label.title is selectedLbl + selected = 'is-active' else - selected = if label.title is selectedLabel then "is-active" else "" + selected = if label.title is selectedLabel then 'is-active' else '' "
WIP prefix from the title to allow this
- Work In Progress merge request to be merged when it's ready.
- - else
- Start the title with [WIP] or WIP: to prevent a
- Work In Progress merge request from being merged before it's ready.
+ .js-wip-explanation
+ %a.js-toggle-wip{href: ""}
+ Remove the
+ %code WIP:
+ prefix from the title
+ to allow this
+ %strong Work In Progress
+ merge request to be merged when it's ready.
+ .js-no-wip-explanation
+ %a.js-toggle-wip{href: ""}
+ Start the title with
+ %code WIP:
+ to prevent a
+ %strong Work In Progress
+ merge request from being merged before it's ready.
.form-group.detail-page-description
= f.label :description, 'Description', class: 'control-label'
.col-sm-10
@@ -29,6 +38,15 @@
= render 'projects/notes/hints'
.clearfix
.error-alert
+
+- if issuable.is_a?(Issue) && !issuable.project.private?
+ .form-group
+ .col-sm-offset-2.col-sm-10
+ .checkbox
+ = f.label :confidential do
+ = f.check_box :confidential
+ This issue is confidential and should only be visible to team members
+
- if can?(current_user, :"admin_#{issuable.to_ability_name}", issuable.project)
%hr
.form-group
diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml
new file mode 100644
index 0000000000..8761731518
--- /dev/null
+++ b/app/views/shared/issuable/_label_dropdown.html.haml
@@ -0,0 +1,39 @@
+- if params[:label_name]
+ = hidden_field_tag(:label_name, params[:label_name])
+.dropdown
+ %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: @project.try(:id), labels: labels_filter_path, default_label: "Label"}}
+ %span.dropdown-toggle-text
+ = h(params[:label_name].presence || "Label")
+ = icon('chevron-down')
+ .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable
+ .dropdown-page-one
+ = dropdown_title("Filter by label")
+ = dropdown_filter("Search labels")
+ = dropdown_content
+ - if @project
+ = dropdown_footer do
+ %ul.dropdown-footer-list
+ - if can? current_user, :admin_label, @project
+ %li
+ %a.dropdown-toggle-page{href: "#"}
+ Create new
+ %li
+ = link_to namespace_project_labels_path(@project.namespace, @project) do
+ - if can? current_user, :admin_label, @project
+ Manage labels
+ - else
+ View labels
+ - if can? current_user, :admin_label, @project and @project
+ .dropdown-page-two
+ = dropdown_title("Create new label", back: true)
+ = dropdown_content do
+ %input#new_label_color{type: "hidden"}
+ %input#new_label_name.dropdown-input-field{type: "text", placeholder: "Name new label"}
+ .dropdown-label-color-preview.js-dropdown-label-color-preview
+ .suggest-colors.suggest-colors-dropdown
+ - suggested_colors.each do |color|
+ = link_to '#', style: "background-color: #{color}", data: { color: color } do
+  
+ %button.btn.btn-primary.js-new-label-btn{type: "button"}
+ Create
+ = dropdown_loading
diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml
new file mode 100644
index 0000000000..0434506c8d
--- /dev/null
+++ b/app/views/shared/issuable/_milestone_dropdown.html.haml
@@ -0,0 +1,16 @@
+- if params[:milestone_title]
+ = hidden_field_tag(:milestone_title, params[:milestone_title])
+= dropdown_tag(h(params[:milestone_title].presence || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable",
+ placeholder: "Search milestones", footer_content: @project.present?, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: @project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do
+ - if @project
+ %ul.dropdown-footer-list
+ - if can? current_user, :admin_milestone, @project
+ %li
+ = link_to new_namespace_project_milestone_path(@project.namespace, @project), title: "New Milestone" do
+ Create new
+ %li
+ = link_to namespace_project_milestones_path(@project.namespace, @project) do
+ - if can? current_user, :admin_milestone, @project
+ Manage milestones
+ - else
+ View milestones
diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml
index f1d92ef48b..3fb409ff72 100644
--- a/app/views/shared/issuable/_participants.html.haml
+++ b/app/views/shared/issuable/_participants.html.haml
@@ -1,3 +1,6 @@
+- participants_row = 7
+- participants_size = participants.size
+- participants_extra = participants_size - participants_row
.block.participants
.sidebar-collapsed-icon
= icon('users')
@@ -5,6 +8,13 @@
= participants.count
.title.hide-collapsed
= pluralize participants.count, "participant"
- - participants.each do |participant|
- %span.hide-collapsed
- = link_to_member(@project, participant, name: false, size: 24)
+ .hide-collapsed.participants-list
+ - participants.each do |participant|
+ .participants-author.js-participants-author
+ = link_to_member(@project, participant, name: false, size: 24)
+ - if participants_extra > 0
+ %div.participants-more
+ %a.js-participants-more{href: "#", data: {original_text: "+ #{participants_size - 7} more", less_text: "- show less"}}
+ + #{participants_extra} more
+:javascript
+ Issue.prototype.PARTICIPANTS_ROW_COUNT = #{participants_row};
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 23b1ed1e51..2b95b19fac 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -1,13 +1,12 @@
%aside.right-sidebar{ class: sidebar_gutter_collapsed_class }
.issuable-sidebar
- .block
+ .block.issuable-sidebar-header
%span.issuable-count.hide-collapsed.pull-left
= issuable.iid
of
= issuables_count(issuable)
- %span.pull-right
- %a.gutter-toggle.js-sidebar-toggle{href: '#'}
- = sidebar_gutter_toggle_icon
+ %a.gutter-toggle.pull-right.js-sidebar-toggle{href: '#'}
+ = sidebar_gutter_toggle_icon
.issuable-nav.hide-collapsed.pull-right.btn-group{role: 'group', "aria-label" => '...'}
- if prev_issuable = prev_issuable_for(issuable)
= link_to 'Prev', [@project.namespace.becomes(Namespace), @project, prev_issuable], class: 'btn btn-default prev-btn'
@@ -22,20 +21,20 @@
= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
.block.assignee
- .sidebar-collapsed-icon
+ .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: (issuable.assignee.to_reference if issuable.assignee)}
- if issuable.assignee
- = link_to_member_avatar(issuable.assignee, size: 24)
+ = link_to_member(@project, issuable.assignee, size: 24)
- else
= icon('user')
.title.hide-collapsed
- %label
- Assignee
+ Assignee
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
- .pull-right
- = link_to 'Edit', '#', class: 'edit-link'
- .value.hide-collapsed
+ = link_to 'Edit', '#', class: 'edit-link pull-right'
+ .value.bold.hide-collapsed
- if issuable.assignee
- %strong= link_to_member(@project, issuable.assignee, size: 24)
+ = link_to_member(@project, issuable.assignee, size: 32) do
+ %span.username
+ = issuable.assignee.to_reference
- if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee)
%a.pull-right.cannot-be-merged{href: '#', data: {toggle: 'tooltip'}, title: 'Not allowed to merge'}
= icon('exclamation-triangle')
@@ -54,18 +53,13 @@
- else
No
.title.hide-collapsed
- %label
- Milestone
+ Milestone
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
- .pull-right
- = link_to 'Edit', '#', class: 'edit-link'
- .value.hide-collapsed
+ = link_to 'Edit', '#', class: 'edit-link pull-right'
+ .value.bold.hide-collapsed
- if issuable.milestone
- %span.back-to-milestone
- = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do
- %strong
- = icon('clock-o')
- = issuable.milestone.title
+ = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do
+ = issuable.milestone.title
- else
.light None
.selectbox.hide-collapsed
@@ -80,11 +74,10 @@
%span
= issuable.labels.count
.title.hide-collapsed
- %label Labels
+ Labels
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
- .pull-right
- = link_to 'Edit', '#', class: 'edit-link'
- .value.issuable-show-labels.hide-collapsed
+ = link_to 'Edit', '#', class: 'edit-link pull-right'
+ .value.issuable-show-labels.hide-collapsed{class: ("has-labels" if issuable.labels.any?)}
- if issuable.labels.any?
- issuable.labels.each do |label|
= link_to_label(label, type: issuable.to_ability_name)
@@ -95,14 +88,13 @@
{ selected: issuable.label_ids }, multiple: true, class: 'select2 js-select2', data: { placeholder: "Select labels" }
= render "shared/issuable/participants", participants: issuable.participants(current_user)
- %hr
- if current_user
- subscribed = issuable.subscribed?(current_user)
.block.light.subscription{data: {url: toggle_subscription_path(issuable)}}
.sidebar-collapsed-icon
= icon('rss')
.title.hide-collapsed
- %label.light Notifications
+ Notifications
- subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed'
%button.btn.btn-block.btn-gray.subscribe-button.hide-collapsed{:type => 'button'}
%span= subscribed ? 'Unsubscribe' : 'Subscribe'
diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml
index f7c6fc14ad..8588809672 100644
--- a/app/views/shared/milestones/_issuable.html.haml
+++ b/app/views/shared/milestones/_issuable.html.haml
@@ -10,6 +10,8 @@
%strong #{project.name} ·
- elsif show_full_project_name
%strong #{project.name_with_namespace} ·
+ - if issuable.is_a?(Issue)
+ = confidential_icon(issuable)
= link_to_gfm issuable.title, [project.namespace.becomes(Namespace), project, issuable], title: issuable.title
%div{class: 'issuable-detail'}
= link_to [project.namespace.becomes(Namespace), project, issuable] do
diff --git a/app/views/shared/milestones/_labels_tab.html.haml b/app/views/shared/milestones/_labels_tab.html.haml
index ba27bafd1b..868b235700 100644
--- a/app/views/shared/milestones/_labels_tab.html.haml
+++ b/app/views/shared/milestones/_labels_tab.html.haml
@@ -5,7 +5,7 @@
%li
%span.label-row
= link_to milestones_label_path(options) do
- - render_colored_label(label)
+ - render_colored_label(label, tooltip: false)
%span.prepend-left-10
= markdown(label.description, pipeline: :single_line)
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index f01138af3f..6b25745c55 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -6,10 +6,10 @@
.col-sm-6
%strong= link_to_gfm truncate(milestone.title, length: 100), milestone_path
.col-sm-6
- .pull-right.light #{milestone.percent_complete}% complete
+ .pull-right.light #{milestone.percent_complete(current_user)}% complete
.row
.col-sm-6
- = link_to pluralize(milestone.issues.size, 'Issue'), issues_path
+ = link_to pluralize(milestone.issues_visible_to_user(current_user).size, 'Issue'), issues_path
·
= link_to pluralize(milestone.merge_requests.size, 'Merge Request'), merge_requests_path
.col-sm-6= milestone_progress_bar(milestone)
diff --git a/app/views/shared/milestones/_summary.html.haml b/app/views/shared/milestones/_summary.html.haml
index 59d4ae29f7..385c659660 100644
--- a/app/views/shared/milestones/_summary.html.haml
+++ b/app/views/shared/milestones/_summary.html.haml
@@ -3,15 +3,15 @@
.context.prepend-top-default
.milestone-summary
%h4 Progress
- %strong= milestone.issues.size
+ %strong= milestone.issues_visible_to_user(current_user).size
issues:
%span.milestone-stat
- %strong= milestone.issues.opened.size
+ %strong= milestone.issues_visible_to_user(current_user).opened.size
open and
- %strong= milestone.issues.closed.size
+ %strong= milestone.issues_visible_to_user(current_user).closed.size
closed
%span.milestone-stat
- %strong== #{milestone.percent_complete}%
+ %strong== #{milestone.percent_complete(current_user)}%
complete
%span.milestone-stat
diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml
index 57d7ee85a3..2b6ce2d7e7 100644
--- a/app/views/shared/milestones/_tabs.html.haml
+++ b/app/views/shared/milestones/_tabs.html.haml
@@ -2,7 +2,7 @@
%li.active
= link_to '#tab-issues', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do
Issues
- %span.badge= milestone.issues.size
+ %span.badge= milestone.issues_visible_to_user(current_user).size
%li
= link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do
Merge Requests
@@ -21,7 +21,7 @@
.tab-content.milestone-content
.tab-pane.active#tab-issues
- = render 'shared/milestones/issues_tab', issues: milestone.issues, show_project_name: show_project_name, show_full_project_name: show_full_project_name
+ = render 'shared/milestones/issues_tab', issues: milestone.issues_visible_to_user(current_user), show_project_name: show_project_name, show_full_project_name: show_full_project_name
.tab-pane#tab-merge-requests
= render 'shared/milestones/merge_requests_tab', merge_requests: milestone.merge_requests, show_project_name: show_project_name, show_full_project_name: show_full_project_name
.tab-pane#tab-participants
diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml
index 4cf1d948b5..cab8743a07 100644
--- a/app/views/shared/milestones/_top.html.haml
+++ b/app/views/shared/milestones/_top.html.haml
@@ -28,7 +28,7 @@
%h2.title
= markdown escape_once(milestone.title), pipeline: :single_line
-- if milestone.complete? && milestone.active?
+- if milestone.complete?(current_user) && milestone.active?
.alert.alert-success.prepend-top-default
- close_msg = group ? 'You may close the milestone now.' : 'Navigate to the project to close the milestone.'
%span All issues for this milestone are closed. #{close_msg}
@@ -47,7 +47,7 @@
- project_name = group ? ms.project.name : ms.project.name_with_namespace
= link_to project_name, namespace_project_milestone_path(ms.project.namespace, ms.project, ms)
%td
- = ms.issues.opened.count
+ = ms.issues_visible_to_user(current_user).opened.count
%td
- if ms.closed?
Closed
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index 97cfb76cdb..872d2bdf46 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -7,26 +7,11 @@
- show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true && project.commit
- css_class += " no-description" if project.description.blank? && !show_last_commit_as_description
- ci_commit = project.ci_commit(project.commit.sha) if ci && !project.empty_repo? && project.commit
-- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.2']
+- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.3']
- cache_key.push(ci_commit.status) if ci_commit
%li.project-row{ class: css_class }
= cache(cache_key) do
- = link_to project_path(project), class: dom_class(project) do
- - if avatar
- .dash-project-avatar
- - if use_creator_avatar
- = image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:''
- - else
- = project_icon(project, alt: '', class: 'avatar project-avatar s40')
- %span.project-full-name.title
- %span.namespace-name
- - if project.namespace && !skip_namespace
- = project.namespace.human_name
- \/
- %span.project-name.filter-title
- = project.name
-
.controls
- if project.main_language
%span
@@ -45,6 +30,23 @@
%span.visibility-icon.has_tooltip{data: { container: 'body', placement: 'left' },
title: "#{visibility_level_label(project.visibility_level)} - #{project_visibility_level_description(project.visibility_level)}"}
= visibility_level_icon(project.visibility_level, fw: false)
+
+ .title
+ = link_to project_path(project), class: dom_class(project) do
+ - if avatar
+ .dash-project-avatar
+ - if use_creator_avatar
+ = image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:''
+ - else
+ = project_icon(project, alt: '', class: 'avatar project-avatar s40')
+ %span.project-full-name
+ %span.namespace-name
+ - if project.namespace && !skip_namespace
+ = project.namespace.human_name
+ \/
+ %span.project-name.filter-title
+ = project.name
+
- if show_last_commit_as_description
.description
= link_to_gfm project.commit.title, namespace_project_commit_path(project.namespace, project, project.commit),
diff --git a/app/views/shared/snippets/_snippet.html.haml b/app/views/shared/snippets/_snippet.html.haml
index a316a08510..c96dfefe17 100644
--- a/app/views/shared/snippets/_snippet.html.haml
+++ b/app/views/shared/snippets/_snippet.html.haml
@@ -1,8 +1,8 @@
%li.snippet-row
= image_tag avatar_icon(snippet.author_email), class: "avatar s40 hidden-xs", alt: ''
- .snippet-title
- = link_to reliable_snippet_path(snippet), class: 'title' do
+ .title
+ = link_to reliable_snippet_path(snippet) do
= truncate(snippet.title, length: 60)
- if snippet.private?
%span.label.label-gray
diff --git a/app/workers/delete_user_worker.rb b/app/workers/delete_user_worker.rb
new file mode 100644
index 0000000000..6ff361e4d8
--- /dev/null
+++ b/app/workers/delete_user_worker.rb
@@ -0,0 +1,10 @@
+class DeleteUserWorker
+ include Sidekiq::Worker
+
+ def perform(current_user_id, delete_user_id, options = {})
+ delete_user = User.find(delete_user_id)
+ current_user = User.find(current_user_id)
+
+ DeleteUserService.new(current_user).execute(delete_user, options.symbolize_keys)
+ end
+end
diff --git a/app/workers/gitlab_shell_one_shot_worker.rb b/app/workers/gitlab_shell_one_shot_worker.rb
new file mode 100644
index 0000000000..4ddbcf574d
--- /dev/null
+++ b/app/workers/gitlab_shell_one_shot_worker.rb
@@ -0,0 +1,10 @@
+class GitlabShellOneShotWorker
+ include Sidekiq::Worker
+ include Gitlab::ShellAdapter
+
+ sidekiq_options queue: :gitlab_shell, retry: false
+
+ def perform(action, *arg)
+ gitlab_shell.send(action, *arg)
+ end
+end
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 14d7813412..3cc232ef1a 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -1,6 +1,5 @@
class PostReceive
include Sidekiq::Worker
- include Gitlab::Identifier
sidekiq_options queue: :post_receive
@@ -11,51 +10,44 @@ class PostReceive
log("Check gitlab.yml config for correct gitlab_shell.repos_path variable. \"#{Gitlab.config.gitlab_shell.repos_path}\" does not match \"#{repo_path}\"")
end
- repo_path.gsub!(/\.git\z/, "")
- repo_path.gsub!(/\A\//, "")
+ post_received = Gitlab::GitPostReceive.new(repo_path, identifier, changes)
- project = Project.find_with_namespace(repo_path)
-
- if project.nil?
+ if post_received.project.nil?
log("Triggered hook for non-existing project with full path \"#{repo_path} \"")
return false
end
- changes = Base64.decode64(changes) unless changes.include?(" ")
- changes = utf8_encode_changes(changes)
- changes = changes.lines
+ if post_received.wiki?
+ # Nothing defined here yet.
+ elsif post_received.regular_project?
+ process_project_changes(post_received)
+ else
+ log("Triggered hook for unidentifiable repository type with full path \"#{repo_path} \"")
+ false
+ end
+ end
- changes.each do |change|
+ def process_project_changes(post_received)
+ post_received.changes.each do |change|
oldrev, newrev, ref = change.strip.split(' ')
- @user ||= identify(identifier, project, newrev)
+ @user ||= post_received.identify(newrev)
unless @user
- log("Triggered hook for non-existing user \"#{identifier} \"")
+ log("Triggered hook for non-existing user \"#{post_received.identifier} \"")
return false
end
if Gitlab::Git.tag_ref?(ref)
- GitTagPushService.new.execute(project, @user, oldrev, newrev, ref)
+ GitTagPushService.new.execute(post_received.project, @user, oldrev, newrev, ref)
else
- GitPushService.new(project, @user, oldrev: oldrev, newrev: newrev, ref: ref).execute
+ GitPushService.new(post_received.project, @user, oldrev: oldrev, newrev: newrev, ref: ref).execute
end
end
end
- def utf8_encode_changes(changes)
- changes = changes.dup
-
- changes.force_encoding("UTF-8")
- return changes if changes.valid_encoding?
-
- # Convert non-UTF-8 branch/tag names to UTF-8 so they can be dumped as JSON.
- detection = CharlockHolmes::EncodingDetector.detect(changes)
- return changes unless detection && detection[:encoding]
-
- CharlockHolmes::Converter.convert(changes, detection[:encoding], 'UTF-8')
- end
-
+ private
+
def log(message)
Gitlab::GitLogger.error("POST-RECEIVE: #{message}")
end
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 05f127d622..500b745f55 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -357,6 +357,12 @@ production: &base
# crowd_server_url: 'CROWD SERVER URL',
# application_name: 'YOUR_APP_NAME',
# application_password: 'YOUR_APP_PASSWORD' } }
+ #
+ # - { name: 'auth0',
+ # args: {
+ # client_id: 'YOUR_AUTH0_CLIENT_ID',
+ # client_secret: 'YOUR_AUTH0_CLIENT_SECRET',
+ # namespace: 'YOUR_AUTH0_DOMAIN' } }
# SSO maximum session duration in seconds. Defaults to CAS default of 8 hours.
# cas3:
diff --git a/config/initializers/gollum.rb b/config/initializers/gollum.rb
new file mode 100644
index 0000000000..703f24f93b
--- /dev/null
+++ b/config/initializers/gollum.rb
@@ -0,0 +1,13 @@
+module Gollum
+ GIT_ADAPTER = "rugged"
+end
+require "gollum-lib"
+
+module Gollum
+ class Committer
+ # Patch for UTF-8 path
+ def method_missing(name, *args)
+ index.send(name, *args)
+ end
+ end
+end
diff --git a/config/routes.rb b/config/routes.rb
index 2ae282f48a..561987322b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -351,6 +351,8 @@ Rails.application.routes.draw do
get :issues
get :merge_requests
get :activity
+ get :labels
+ get :milestones
scope module: :dashboard do
resources :milestones, only: [:index, :show]
@@ -621,6 +623,7 @@ Rails.application.routes.draw do
post :cancel_merge_when_build_succeeds
get :ci_status
post :toggle_subscription
+ post :remove_wip
end
collection do
diff --git a/db/migrate/20160223192159_add_confidential_to_issues.rb b/db/migrate/20160223192159_add_confidential_to_issues.rb
new file mode 100644
index 0000000000..e9d47fd589
--- /dev/null
+++ b/db/migrate/20160223192159_add_confidential_to_issues.rb
@@ -0,0 +1,6 @@
+class AddConfidentialToIssues < ActiveRecord::Migration
+ def change
+ add_column :issues, :confidential, :boolean, default: false
+ add_index :issues, :confidential
+ end
+end
diff --git a/db/migrate/20160316123110_ci_runners_token_index.rb b/db/migrate/20160316123110_ci_runners_token_index.rb
new file mode 100644
index 0000000000..67bf5b4f97
--- /dev/null
+++ b/db/migrate/20160316123110_ci_runners_token_index.rb
@@ -0,0 +1,13 @@
+class CiRunnersTokenIndex < ActiveRecord::Migration
+ disable_ddl_transaction!
+
+ def change
+ args = [:ci_runners, :token]
+
+ if Gitlab::Database.postgresql?
+ args << { algorithm: :concurrently }
+ end
+
+ add_index(*args)
+ end
+end
diff --git a/db/migrate/20160316192622_change_target_id_to_null_on_todos.rb b/db/migrate/20160316192622_change_target_id_to_null_on_todos.rb
new file mode 100644
index 0000000000..6871b3920d
--- /dev/null
+++ b/db/migrate/20160316192622_change_target_id_to_null_on_todos.rb
@@ -0,0 +1,5 @@
+class ChangeTargetIdToNullOnTodos < ActiveRecord::Migration
+ def change
+ change_column_null :todos, :target_id, true
+ end
+end
diff --git a/db/migrate/20160316204731_add_commit_id_to_todos.rb b/db/migrate/20160316204731_add_commit_id_to_todos.rb
new file mode 100644
index 0000000000..ae19fdd1ab
--- /dev/null
+++ b/db/migrate/20160316204731_add_commit_id_to_todos.rb
@@ -0,0 +1,6 @@
+class AddCommitIdToTodos < ActiveRecord::Migration
+ def change
+ add_column :todos, :commit_id, :string
+ add_index :todos, :commit_id
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f1bccd6274..719fedcdbf 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20160314143402) do
+ActiveRecord::Schema.define(version: 20160316204731) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -261,6 +261,7 @@ ActiveRecord::Schema.define(version: 20160314143402) do
end
add_index "ci_runners", ["description"], name: "index_ci_runners_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"}
+ add_index "ci_runners", ["token"], name: "index_ci_runners_on_token", using: :btree
add_index "ci_runners", ["token"], name: "index_ci_runners_on_token_trigram", using: :gin, opclasses: {"token"=>"gin_trgm_ops"}
create_table "ci_services", force: :cascade do |t|
@@ -416,10 +417,12 @@ ActiveRecord::Schema.define(version: 20160314143402) do
t.string "state"
t.integer "iid"
t.integer "updated_by_id"
+ t.boolean "confidential", default: false
end
add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree
add_index "issues", ["author_id"], name: "index_issues_on_author_id", using: :btree
+ add_index "issues", ["confidential"], name: "index_issues_on_confidential", using: :btree
add_index "issues", ["created_at", "id"], name: "index_issues_on_created_at_and_id", using: :btree
add_index "issues", ["created_at"], name: "index_issues_on_created_at", using: :btree
add_index "issues", ["description"], name: "index_issues_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"}
@@ -866,7 +869,7 @@ ActiveRecord::Schema.define(version: 20160314143402) do
create_table "todos", force: :cascade do |t|
t.integer "user_id", null: false
t.integer "project_id", null: false
- t.integer "target_id", null: false
+ t.integer "target_id"
t.string "target_type", null: false
t.integer "author_id"
t.integer "action", null: false
@@ -874,9 +877,11 @@ ActiveRecord::Schema.define(version: 20160314143402) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "note_id"
+ t.string "commit_id"
end
add_index "todos", ["author_id"], name: "index_todos_on_author_id", using: :btree
+ add_index "todos", ["commit_id"], name: "index_todos_on_commit_id", using: :btree
add_index "todos", ["note_id"], name: "index_todos_on_note_id", using: :btree
add_index "todos", ["project_id"], name: "index_todos_on_project_id", using: :btree
add_index "todos", ["state"], name: "index_todos_on_state", using: :btree
diff --git a/doc/README.md b/doc/README.md
index db19c3de8d..08d0a6a5bf 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -3,6 +3,7 @@
## User documentation
- [API](api/README.md) Automate GitLab via a simple and powerful API.
+- [CI](ci/README.md)
- [GitLab as OAuth2 authentication service provider](integration/oauth_provider.md). It allows you to login to other applications from GitLab.
- [GitLab Basics](gitlab-basics/README.md) Find step by step how to start working on your commandline and on GitLab.
- [Importing to GitLab](workflow/importing/README.md).
@@ -16,42 +17,6 @@
- [Webhooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project.
- [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN.
-## CI User documentation
-
-- [Get started with GitLab CI](ci/quick_start/README.md)
-- [Learn how to enable or disable GitLab CI](ci/enable_or_disable_ci.md)
-- [Learn how `.gitlab-ci.yml` works](ci/yaml/README.md)
-- [Configure a Runner, the application that runs your builds](ci/runners/README.md)
-- [Use Docker images with GitLab Runner](ci/docker/using_docker_images.md)
-- [Use CI to build Docker images](ci/docker/using_docker_build.md)
-- [Use variables in your `.gitlab-ci.yml`](ci/variables/README.md)
-- [Use SSH keys in your build environment](ci/ssh_keys/README.md)
-- [Trigger builds through the API](ci/triggers/README.md)
-- [Build artifacts](ci/build_artifacts/README.md)
-- [User permissions](ci/permissions/README.md)
-- [API](ci/api/README.md)
-
-### CI Examples
-
-- [The .gitlab-ci.yml file for GitLab itself](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml)
-- [Test your PHP applications](ci/examples/php.md)
-- [Test and deploy Ruby applications to Heroku](ci/examples/test-and-deploy-ruby-application-to-heroku.md)
-- [Test and deploy Python applications to Heroku](ci/examples/test-and-deploy-python-application-to-heroku.md)
-- [Test Clojure applications](ci/examples/test-clojure-application.md)
-- [Using `dpl` as deployment tool](ci/deployment/README.md)
-- Help your favorite programming language and GitLab by sending a merge request
- with a guide for that language.
-
-### CI Services
-
-GitLab CI uses the `services` keyword to define what docker containers should
-be linked with your base image. Below is a list of examples you may use:
-
-- [Using MySQL](ci/services/mysql.md)
-- [Using PostgreSQL](ci/services/postgres.md)
-- [Using Redis](ci/services/redis.md)
-- [Using Other Services](ci/docker/using_docker_images.md#how-to-use-other-images-as-services)
-
## Administrator documentation
- [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when webhooks aren't enough.
diff --git a/doc/api/users.md b/doc/api/users.md
index 44a29da5ec..383e7c76ab 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -220,6 +220,7 @@ Parameters:
- `bio` - User's biography
- `admin` (optional) - User is admin - true or false (default)
- `can_create_group` (optional) - User can create groups - true or false
+- `external` (optional) - Flags the user as external - true or false(default)
Note, at the moment this method does only return a 404 error,
even in cases where a 409 (Conflict) would be more appropriate,
diff --git a/doc/ci/deployment/README.md b/doc/ci/deployment/README.md
index ffd841ca9e..7d91ce6710 100644
--- a/doc/ci/deployment/README.md
+++ b/doc/ci/deployment/README.md
@@ -89,7 +89,7 @@ We also use two secure variables:
In GitLab CI 7.12 a new feature was introduced: Secure Variables.
Secure Variables can added by going to `Project > Variables > Add Variable`.
**This feature requires `gitlab-runner` with version equal or greater than 0.4.0.**
-The variables that are defined in the project settings are send along with the build script to the runner.
+The variables that are defined in the project settings are sent along with the build script to the runner.
The secure variables are stored out of the repository. Never store secrets in your projects' .gitlab-ci.yml.
It is also important that secret's value is hidden in the build log.
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 5158e3c387..762b35859b 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -135,6 +135,9 @@ thus allowing to fine tune them.
### cache
+>**Note:**
+Introduced in GitLab Runner v0.7.0.
+
`cache` is used to specify a list of files and directories which should be
cached between builds.
@@ -143,15 +146,55 @@ cached between builds.
If `cache` is defined outside the scope of the jobs, it means it is set
globally and all jobs will use its definition.
-To cache all git untracked files and files in `binaries`:
+Cache all files in `binaries` and `.config`:
+
+```yaml
+rspec:
+ script: test
+ cache:
+ paths:
+ - binaries/
+ - .config
+```
+
+Cache all Git untracked files:
+
+```yaml
+rspec:
+ script: test
+ cache:
+ untracked: true
+```
+
+Cache all Git untracked files and files in `binaries`:
+
+```yaml
+rspec:
+ script: test
+ cache:
+ untracked: true
+ paths:
+ - binaries/
+```
+
+Locally defined cache overwrites globally defined options. This will cache only
+`binaries/`:
```yaml
cache:
- untracked: true
paths:
- - binaries/
+ - my/files
+
+rspec:
+ script: test
+ cache:
+ paths:
+ - binaries/
```
+The cache is provided on best effort basis, so don't expect that cache will be
+always present. For implementation details please check GitLab Runner.
+
#### cache:key
>**Note:**
@@ -236,6 +279,8 @@ job_name:
| Keyword | Required | Description |
|---------------|----------|-------------|
| script | yes | Defines a shell script which is executed by runner |
+| image | no | Use docker image, covered in [Using Docker Images](../docker/using_docker_images.md#define-image-and-services-from-gitlab-ciyml) |
+| services | no | Use docker services, covered in [Using Docker Images](../docker/using_docker_images.md#define-image-and-services-from-gitlab-ciyml) |
| stage | no | Defines a build stage (default: `test`) |
| type | no | Alias for `stage` |
| only | no | Defines a list of git refs for which build is created |
@@ -418,14 +463,14 @@ artifacts:
- .config
```
-Send all git untracked files:
+Send all Git untracked files:
```yaml
artifacts:
untracked: true
```
-Send all git untracked files and files in `binaries`:
+Send all Git untracked files and files in `binaries`:
```yaml
artifacts:
@@ -579,63 +624,6 @@ deploy:
script: make deploy
```
-### cache
-
->**Note:**
-Introduced in GitLab Runner v0.7.0.
-
-`cache` is used to specify list of files and directories which should be cached
-between builds. Below are some examples:
-
-Cache all files in `binaries` and `.config`:
-
-```yaml
-rspec:
- script: test
- cache:
- paths:
- - binaries/
- - .config
-```
-
-Cache all git untracked files:
-
-```yaml
-rspec:
- script: test
- cache:
- untracked: true
-```
-
-Cache all git untracked files and files in `binaries`:
-
-```yaml
-rspec:
- script: test
- cache:
- untracked: true
- paths:
- - binaries/
-```
-
-Locally defined cache overwrites globally defined options. This will cache only
-`binaries/`:
-
-```yaml
-cache:
- paths:
- - my/files
-
-rspec:
- script: test
- cache:
- paths:
- - binaries/
-```
-
-The cache is provided on best effort basis, so don't expect that cache will be
-always present. For implementation details please check GitLab Runner.
-
## Hidden jobs
>**Note:**
diff --git a/doc/hooks/custom_hooks.md b/doc/hooks/custom_hooks.md
index 15051dd76f..dcdf49d337 100644
--- a/doc/hooks/custom_hooks.md
+++ b/doc/hooks/custom_hooks.md
@@ -2,7 +2,7 @@
**Note: Custom git hooks must be configured on the filesystem of the GitLab
server. Only GitLab server administrators will be able to complete these tasks.
-Please explore [webhooks](doc/web_hooks/web_hooks.md) as an option if you do not have filesystem access. For a user configurable Git Hooks interface, please see [GitLab Enterprise Edition Git Hooks](http://doc.gitlab.com/ee/git_hooks/git_hooks.html).**
+Please explore [webhooks](../web_hooks/web_hooks.md) as an option if you do not have filesystem access. For a user configurable Git Hooks interface, please see [GitLab Enterprise Edition Git Hooks](http://doc.gitlab.com/ee/git_hooks/git_hooks.html).**
Git natively supports hooks that are executed on different actions.
Examples of server-side git hooks include pre-receive, post-receive, and update.
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 4f01139726..c567846f62 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -22,7 +22,7 @@ If the highest number stable branch is unclear please check the [GitLab Blog](ht
This guide is long because it covers many cases and includes all commands you need, this is [one of the few installation scripts that actually works out of the box](https://twitter.com/robinvdvleuten/status/424163226532986880).
-This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [doc/install/requirements.md](./requirements.md) for hardware and operating system requirements. If you want to install on RHEL/CentOS we recommend using the [Omnibus packages](https://about.gitlab.com/downloads/).
+This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [requirements.md](requirements.md) for hardware and operating system requirements. If you want to install on RHEL/CentOS we recommend using the [Omnibus packages](https://about.gitlab.com/downloads/).
This is the official installation guide to set up a production server. To set up a **development installation** or for many other installation options please see [the installation section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#installation).
@@ -76,7 +76,7 @@ Make sure you have the right version of Git installed
# Install Git
sudo apt-get install -y git-core
- # Make sure Git is version 1.7.10 or higher, for example 1.7.12 or 2.0.0
+ # Make sure Git is version 2.7.4 or higher
git --version
Is the system packaged Git too old? Remove it and compile from source.
@@ -89,8 +89,9 @@ Is the system packaged Git too old? Remove it and compile from source.
# Download and compile from source
cd /tmp
- curl -L --progress https://www.kernel.org/pub/software/scm/git/git-2.4.3.tar.gz | tar xz
- cd git-2.4.3/
+ curl -O --progress https://www.kernel.org/pub/software/scm/git/git-2.7.4.tar.gz
+ echo '7104c4f5d948a75b499a954524cb281fe30c6649d8abe20982936f75ec1f275b git-2.7.4.tar.gz' | shasum -a256 -c - && tar -xzf git-2.7.4.tar.gz
+ cd git-2.7.4/
./configure
make prefix=/usr/local all
@@ -143,7 +144,7 @@ use 64-bit Linux. You can find downloads for other platforms at the [Go download
page](https://golang.org/dl).
curl -O --progress https://storage.googleapis.com/golang/go1.5.3.linux-amd64.tar.gz
- echo '43afe0c5017e502630b1aea4d44b8a7f059bf60d7f29dfd58db454d4e4e0ae53 go1.5.3.linux-amd64.tar.gz' | shasum -c - && \
+ echo '43afe0c5017e502630b1aea4d44b8a7f059bf60d7f29dfd58db454d4e4e0ae53 go1.5.3.linux-amd64.tar.gz' | shasum -a256 -c - && \
sudo tar -C /usr/local -xzf go1.5.3.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/
rm go1.5.3.linux-amd64.tar.gz
@@ -161,18 +162,11 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
# Install the database packages
sudo apt-get install -y postgresql postgresql-client libpq-dev
- # Login to PostgreSQL
- sudo -u postgres psql -d template1
-
# Create a user for GitLab
- # Do not type the 'template1=#', this is part of the prompt
- template1=# CREATE USER git CREATEDB;
+ sudo -u postgres psql -d template1 -c "CREATE USER git CREATEDB;"
# Create the GitLab production database & grant all privileges on database
- template1=# CREATE DATABASE gitlabhq_production OWNER git;
-
- # Quit the database session
- template1=# \q
+ sudo -u postgres psql -d template1 -c "CREATE DATABASE gitlabhq_production OWNER git;"
# Try connecting to the new database with the new user
sudo -u git -H psql -d gitlabhq_production
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index d59b7f0e84..03cb08dd1f 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -22,7 +22,7 @@ For the installations options please see [the installation page on the GitLab we
- FreeBSD
On the above unsupported distributions is still possible to install GitLab yourself.
-Please see the [installation from source guide](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md) and the [unofficial installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) on the public wiki for more information.
+Please see the [installation from source guide](installation.md) and the [installation guides](https://about.gitlab.com/installation/) for more information.
### Non-Unix operating systems such as Windows
diff --git a/doc/integration/auth0.md b/doc/integration/auth0.md
new file mode 100644
index 0000000000..e5247082a8
--- /dev/null
+++ b/doc/integration/auth0.md
@@ -0,0 +1,89 @@
+# Auth0 OmniAuth Provider
+
+To enable the Auth0 OmniAuth provider, you must create an Auth0 account, and an
+application.
+
+1. Sign in to the [Auth0 Console](https://manage.auth0.com). If you need to
+create an account, you can do so at the same link.
+
+1. Select "New App/API".
+
+1. Provide the Application Name ('GitLab' works fine).
+
+1. Once created, you should see the Quick Start options. Disregard them and
+select 'Settings' above the Quick Start options.
+
+1. At the top of the Settings screen, you should see your Domain, Client ID and
+Client Secret. Take note of these as you'll need to put them in the
+configuration file. For example:
+ - Domain: `test1234.auth0.com`
+ - Client ID: `t6X8L2465bNePWLOvt9yi41i`
+ - Client Secret: `KbveM3nqfjwCbrhaUy_gDu2dss8TIlHIdzlyf33pB7dEK5u_NyQdp65O_o02hXs2`
+
+1. Fill in the Allowed Callback URLs:
+ - http://`YOUR_GITLAB_URL`/users/auth/auth0/callback (or)
+ - https://`YOUR_GITLAB_URL`/users/auth/auth0/callback
+
+1. Fill in the Allowed Origins (CORS):
+ - http://`YOUR_GITLAB_URL` (or)
+ - https://`YOUR_GITLAB_URL`
+
+1. On your GitLab server, open the configuration file.
+
+ For omnibus package:
+
+ ```sh
+ sudo editor /etc/gitlab/gitlab.rb
+ ```
+
+ For installations from source:
+
+ ```sh
+ cd /home/git/gitlab
+ sudo -u git -H editor config/gitlab.yml
+ ```
+
+1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration)
+for initial settings.
+
+1. Add the provider configuration:
+
+ For omnibus package:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ {
+ "name" => "auth0",
+ "args" => { client_id: 'YOUR_AUTH0_CLIENT_ID'',
+ client_secret: 'YOUR_AUTH0_CLIENT_SECRET',
+ namespace: 'YOUR_AUTH0_DOMAIN'
+ }
+ }
+ ]
+ ```
+
+ For installations from source:
+
+ ```yaml
+ - { name: 'auth0',
+ args: {
+ client_id: 'YOUR_AUTH0_CLIENT_ID',
+ client_secret: 'YOUR_AUTH0_CLIENT_SECRET',
+ namespace: 'YOUR_AUTH0_DOMAIN'
+ }
+ }
+ ```
+
+1. Change `YOUR_AUTH0_CLIENT_ID` to the client ID from the Auth0 Console page
+from step 5.
+
+1. Change `YOUR_AUTH0_CLIENT_SECRET` to the client secret from the Auth0 Console
+page from step 5.
+
+1. Save the file and [reconfigure GitLab](../administration/restart_gitlab.md)
+for the changes to take effect.
+
+On the sign in page there should now be an Auth0 icon below the regular sign in
+form. Click the icon to begin the authentication process. Auth0 will ask the
+user to sign in and authorize the GitLab application. If everything goes well
+the user will be returned to GitLab and will be signed in.
diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md
index ba47cb1626..25f3598830 100644
--- a/doc/integration/omniauth.md
+++ b/doc/integration/omniauth.md
@@ -28,6 +28,7 @@ contains some settings that are common for all providers.
- [SAML](saml.md)
- [Crowd](crowd.md)
- [Azure](azure.md)
+- [Auth0](auth0.md)
## Initial OmniAuth Configuration
diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md
index 2dfd08755b..3d375e47c8 100644
--- a/doc/permissions/permissions.md
+++ b/doc/permissions/permissions.md
@@ -74,17 +74,21 @@ Any user can remove themselves from a group, unless they are the last Owner of t
## External Users
-In cases where it is desired that a user has access to some internal or private projects, but others
-should remain hidden from this user, there is the option of creating `External Users`.
-An administrator can flag a user as external through the API or by checking the checkbox on the admin panel.
+In cases where it is desired that a user has access only to some internal or
+private projects, there is the option of creating **External Users**. This
+feature may be useful when for example a contractor is working on a given
+project and should only have access to that project.
-In the case of a new user: navigate to the **Admin** area and click the **New User** button. If you would like to
-edit a user, go to the user list on the **Admin** area and click the **Edit** button.
+External users can only access projects to which they are explicitly granted
+access, thus hiding all other internal or private ones from them. Access can be
+granted by adding the user as member to the project or group.
-External users can only access projects to which they are explicitly granted access, thus hiding all internal projects.
-Access can be granted by adding the users as member to the project or by including this user in a group. External users will, like usual users, receive
-a role in the project or group with all the abilities that are mentioned in the table above.
+They will, like usual users, receive a role in the project or group with all
+the abilities that are mentioned in the table above. They cannot however create
+groups or projects, and they have the same access as logged out users in all
+other cases.
-External users cannot create groups or projects, and have the same access as logged out users in all other cases. This feature may be
-useful when for example a contractor is working on a given project and should only access the given project and public
-projects.
+An administrator can flag a user as external [through the API](../api/users.md)
+or by checking the checkbox on the admin panel. As an administrator, navigate
+to **Admin > Users** to create a new user or edit an existing one. There, you
+will find the option to flag the user as external.
diff --git a/doc/release/security.md b/doc/release/security.md
index b1a62b333e..118c016ba4 100644
--- a/doc/release/security.md
+++ b/doc/release/security.md
@@ -15,7 +15,7 @@ Please report suspected security vulnerabilities in private to Make sure the address is correct and that the page hasn't moved.
diff --git a/public/422.html b/public/422.html index 026997b48e..055b0bde16 100644 --- a/public/422.html +++ b/public/422.html @@ -2,12 +2,51 @@Make sure you have access to the thing you tried to change.
diff --git a/public/500.html b/public/500.html index 08c11bbd05..3d59d1392f 100644 --- a/public/500.html +++ b/public/500.html @@ -2,10 +2,50 @@Try refreshing the page, or going back and attempting the action again.
diff --git a/public/502.html b/public/502.html index 9480a92843..67dfd8a274 100644 --- a/public/502.html +++ b/public/502.html @@ -2,10 +2,50 @@Try refreshing the page, or going back and attempting the action again.
diff --git a/public/deploy.html b/public/deploy.html index 3822ed4b64..48976dacf4 100644 --- a/public/deploy.html +++ b/public/deploy.html @@ -2,12 +2,49 @@