From a426fb1596978221510c8c78a17703658ad7d161 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 7 Dec 2015 14:11:13 +0100 Subject: Update documentation about automatic issue closing --- config/gitlab.yml.example | 2 +- doc/customization/issue_closing.md | 27 ++++++++++++++------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 1da42ab38f3..db378118f85 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -76,7 +76,7 @@ production: &base # This happens when the commit is pushed or merged into the default branch of a project. # When not specified the default issue_closing_pattern as specified below will be used. # Tip: you can test your closing pattern at http://rubular.com. - # issue_closing_pattern: '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' + # issue_closing_pattern: '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?%{issue_ref}(?:(?:, *| +and +)?))+)' ## Default project features settings default_projects_features: diff --git a/doc/customization/issue_closing.md b/doc/customization/issue_closing.md index 64f128f5a63..00edfc97ed9 100644 --- a/doc/customization/issue_closing.md +++ b/doc/customization/issue_closing.md @@ -1,38 +1,39 @@ # Issue closing pattern -Here's how to close multiple issues in one commit message: +When a commit or merge request resolves one or more issues, it is possible to automatically have these issues closed when the commit or merge request lands in the project's default branch. -If a commit message matches the regular expression below, all issues referenced from -the matched text will be closed. This happens when the commit is pushed or merged -into the default branch of a project. +If a commit message or merge request description contains a sentence matching the regular expression below, all issues referenced from +the matched text will be closed. This happens when the commit is pushed to a project's default branch, or when a commit or merge request is merged into there. -When not specified, the default issue_closing_pattern as shown below will be used: +When not specified, the default `issue_closing_pattern` as shown below will be used: ```bash -((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+) +((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?%{issue_ref}(?:(?:, *| +and +)?))+) ``` +Here, `%{issue_ref}` is a complex regular expression defined inside GitLab, that matches a reference to a local issue (`#123`), cross-project issue (`group/project#123`) or a link to an issue (`https://gitlab.example.com/group/project/issues/123`). + For example: ``` -git commit -m "Awesome commit message (Fix #20, Fixes #21 and Closes #22). This commit is also related to #17 and fixes #18, #19 and #23." +git commit -m "Awesome commit message (Fix #20, Fixes #21 and Closes group/otherproject#2). This commit is also related to #17 and fixes #18, #19 and https://gitlab.example.com/group/otherproject/issues/23." ``` -will close `#20`, `#21`, `#22`, `#18`, `#19` and `#23`, but `#17` won't be closed -as it does not match the pattern. It also works with multiline commit messages. +will close `#18`, `#19`, `#20`, and `#21` in the project this commit is pushed to, as well as `#22` and `#23` in group/otherproject. `#17` won't be closed as it does not match the pattern. It also works with multiline commit messages. Tip: you can test this closing pattern at [http://rubular.com][1]. Use this site to test your own patterns. +Because Rubular doesn't understand `%{issue_ref}`, you can replace this by `#\d+` in testing, which matches only local issue references like `#123`. ## Change the pattern For Omnibus installs you can change the default pattern in `/etc/gitlab/gitlab.rb`: ``` -issue_closing_pattern: '((?:[Cc]los(?:e[sd]|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' +issue_closing_pattern: '((?:[Cc]los(?:e[sd]|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?%{issue_ref}(?:(?:, *| +and +)?))+)' ``` -For manual installs you can customize the pattern in [gitlab.yml][0]. +For manual installs you can customize the pattern in [gitlab.yml][0] using the `issue_closing_pattern` key. -[0]: https://gitlab.com/gitlab-org/gitlab-ce/blob/40c3675372320febf5264061c9bcd63db2dfd13c/config/gitlab.yml.example#L65 -[1]: http://rubular.com/r/Xmbexed1OJ \ No newline at end of file +[0]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/gitlab.yml.example +[1]: http://rubular.com/r/Xmbexed1OJ -- cgit v1.2.1 From a17ba43bfd05cd49bab18d6c7f80226004870bc2 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 13:03:28 +0100 Subject: Move commit builds to partial --- app/controllers/projects/commit_controller.rb | 8 ++-- app/views/projects/commit/_builds.html.haml | 67 ++++++++++++++++++++++++++ app/views/projects/commit/_ci_menu.html.haml | 2 +- app/views/projects/commit/builds.html.haml | 68 +-------------------------- 4 files changed, 73 insertions(+), 72 deletions(-) create mode 100644 app/views/projects/commit/_builds.html.haml diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 3f137440e28..e8af205b788 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -37,7 +37,7 @@ class Projects::CommitController < Projects::ApplicationController def cancel_builds ci_commit.builds.running_or_pending.each(&:cancel) - redirect_to builds_namespace_project_commit_path(project.namespace, project, commit.sha) + redirect_back_or_default default: builds_namespace_project_commit_path(project.namespace, project, commit.sha) end def retry_builds @@ -47,7 +47,7 @@ class Projects::CommitController < Projects::ApplicationController end end - redirect_to builds_namespace_project_commit_path(project.namespace, project, commit.sha) + redirect_back_or_default default: builds_namespace_project_commit_path(project.namespace, project, commit.sha) end def branches @@ -74,8 +74,8 @@ class Projects::CommitController < Projects::ApplicationController end @notes_count = commit.notes.count - - @builds = ci_commit.builds if ci_commit + + @statuses = ci_commit.statuses if ci_commit end def authorize_manage_builds! diff --git a/app/views/projects/commit/_builds.html.haml b/app/views/projects/commit/_builds.html.haml new file mode 100644 index 00000000000..e4d81182c1a --- /dev/null +++ b/app/views/projects/commit/_builds.html.haml @@ -0,0 +1,67 @@ +.gray-content-block.middle-block + .pull-right + - if @ci_project && can?(current_user, :manage_builds, @ci_commit.gl_project) + - if @ci_commit.builds.latest.failed.any?(&:retryable?) + = link_to "Retry failed", retry_builds_namespace_project_commit_path(@ci_commit.gl_project.namespace, @ci_commit.gl_project, @ci_commit.sha), class: 'btn btn-grouped btn-primary', method: :post + + - if @ci_commit.builds.running_or_pending.any? + = link_to "Cancel running", cancel_builds_namespace_project_commit_path(@ci_commit.gl_project.namespace, @ci_commit.gl_project, @ci_commit.sha), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post + + .oneline + = pluralize @statuses.count(:id), "build" + - if defined?(link_to_commit) && link_to_commit + for commit + = link_to @ci_commit.short_sha, namespace_project_commit_path(@ci_commit.gl_project.namespace, @ci_commit.gl_project, @ci_commit.sha), class: "monospace" + - if @ci_commit.duration > 0 + in + = time_interval_in_words @ci_commit.duration + +- if @ci_commit.yaml_errors.present? + .bs-callout.bs-callout-danger + %h4 Found errors in your .gitlab-ci.yml: + %ul + - @ci_commit.yaml_errors.split(",").each do |error| + %li= error + +- if @ci_commit.gl_project.builds_enabled? && !@ci_commit.ci_yaml_file + .bs-callout.bs-callout-warning + \.gitlab-ci.yml not found in this commit + +.table-holder + %table.table.builds + %thead + %tr + %th Status + %th Build ID + %th Ref + %th Stage + %th Name + %th Duration + %th Finished at + - if @ci_project && @ci_project.coverage_enabled? + %th Coverage + %th + - @ci_commit.refs.each do |ref| + = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.statuses.for_ref(ref).latest.ordered, + locals: { coverage: @ci_project.try(:coverage_enabled?), stage: true, allow_retry: true } + +- if @ci_commit.retried.any? + .gray-content-block.second-block + Retried builds + + .table-holder + %table.table.builds + %thead + %tr + %th Status + %th Build ID + %th Ref + %th Stage + %th Name + %th Duration + %th Finished at + - if @ci_project && @ci_project.coverage_enabled? + %th Coverage + %th + = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.retried, + locals: { coverage: @ci_project.try(:coverage_enabled?), stage: true } diff --git a/app/views/projects/commit/_ci_menu.html.haml b/app/views/projects/commit/_ci_menu.html.haml index 76dc87a8824..f74f8b427ec 100644 --- a/app/views/projects/commit/_ci_menu.html.haml +++ b/app/views/projects/commit/_ci_menu.html.haml @@ -6,4 +6,4 @@ = nav_link(path: 'commit#builds') do = link_to builds_namespace_project_commit_path(@project.namespace, @project, @commit.id) do Builds - %span.badge= @builds.count(:id) + %span.badge= @statuses.count diff --git a/app/views/projects/commit/builds.html.haml b/app/views/projects/commit/builds.html.haml index 00cf9c76102..99d62503a94 100644 --- a/app/views/projects/commit/builds.html.haml +++ b/app/views/projects/commit/builds.html.haml @@ -3,70 +3,4 @@ = render "commit_box" = render "ci_menu" - -- if @ci_commit.yaml_errors.present? - .bs-callout.bs-callout-danger - %h4 Found errors in your .gitlab-ci.yml: - %ul - - @ci_commit.yaml_errors.split(",").each do |error| - %li= error - -- unless @ci_commit.ci_yaml_file - .bs-callout.bs-callout-warning - \.gitlab-ci.yml not found in this commit - -.gray-content-block.second-block - Latest builds - - .pull-right - - if @ci_commit.duration > 0 - %i.fa.fa-time - #{time_interval_in_words @ci_commit.duration} - -   - - - if @ci_project && current_user && can?(current_user, :manage_builds, @project) - - if @ci_commit.builds.latest.failed.any?(&:retryable?) - = link_to "Retry failed", retry_builds_namespace_project_commit_path(@project.namespace, @project, @commit.sha), class: 'btn btn-xs btn-primary', method: :post - - - if @ci_commit.builds.running_or_pending.any? - = link_to "Cancel running", cancel_builds_namespace_project_commit_path(@project.namespace, @project, @commit.sha), class: 'btn btn-xs btn-danger', method: :post - -.table-holder - %table.table.builds - %thead - %tr - %th Status - %th Build ID - %th Ref - %th Stage - %th Name - %th Duration - %th Finished at - - if @ci_project && @ci_project.coverage_enabled? - %th Coverage - %th - - @ci_commit.refs.each do |ref| - = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.statuses.for_ref(ref).latest.ordered, - locals: { coverage: @ci_project.try(:coverage_enabled?), stage: true, allow_retry: true } - -- if @ci_commit.retried.any? - .gray-content-block.second-block - Retried builds - - .table-holder - %table.table.builds - %thead - %tr - %th Status - %th Build ID - %th Ref - %th Stage - %th Name - %th Duration - %th Finished at - - if @ci_project && @ci_project.coverage_enabled? - %th Coverage - %th - = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.retried, - locals: { coverage: @ci_project.try(:coverage_enabled?), stage: true } += render "builds" -- cgit v1.2.1 From 1567572e79bbeace4a68f00c01e64ed0dad9106a Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 13:04:24 +0100 Subject: Add Builds tab to MR detail page --- .../javascripts/merge_request_tabs.js.coffee | 22 +++++++++++- .../projects/merge_requests_controller.rb | 41 +++++++++++++++------- .../projects/merge_requests/_new_submit.html.haml | 8 +++++ app/views/projects/merge_requests/_show.html.haml | 10 ++++-- .../projects/merge_requests/show/_builds.html.haml | 1 + .../merge_requests/widget/_heading.html.haml | 2 +- config/routes.rb | 1 + 7 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 app/views/projects/merge_requests/show/_builds.html.haml diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee index 593a8f42130..69a12fdd045 100644 --- a/app/assets/javascripts/merge_request_tabs.js.coffee +++ b/app/assets/javascripts/merge_request_tabs.js.coffee @@ -43,6 +43,7 @@ # class @MergeRequestTabs diffsLoaded: false + buildsLoaded: false commitsLoaded: false constructor: (@opts = {}) -> @@ -54,6 +55,12 @@ class @MergeRequestTabs bindEvents: -> $(document).on 'shown.bs.tab', '.merge-request-tabs a[data-toggle="tab"]', @tabShown + $(document).on 'click', '.js-show-tab', @showTab + + showTab: (event) => + event.preventDefault() + + @activateTab $(event.target).data('action') tabShown: (event) => $target = $(event.target) @@ -61,6 +68,8 @@ class @MergeRequestTabs if action == 'commits' @loadCommits($target.attr('href')) + else if action == 'builds' + @loadBuilds($target.attr('href')) else if action == 'diffs' @loadDiff($target.attr('href')) @@ -101,7 +110,7 @@ class @MergeRequestTabs action = 'notes' if action == 'show' # Remove a trailing '/commits' or '/diffs' - new_state = @_location.pathname.replace(/\/(commits|diffs)(\.html)?\/?$/, '') + new_state = @_location.pathname.replace(/\/(commits|builds|diffs)(\.html)?\/?$/, '') # Append the new action if we're on a tab other than 'notes' unless action == 'notes' @@ -129,6 +138,17 @@ class @MergeRequestTabs @commitsLoaded = true @scrollToElement("#commits") + loadBuilds: (source) -> + return if @buildsLoaded + + @_get + url: "#{source}.json" + success: (data) => + document.getElementById('builds').innerHTML = data.html + $('.js-timeago').timeago() + @buildsLoaded = true + @scrollToElement("#builds") + loadDiff: (source) -> return if @diffsLoaded diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 3f47f2ddb2c..04642294cd3 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -1,13 +1,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController before_action :module_enabled before_action :merge_request, only: [ - :edit, :update, :show, :diffs, :commits, :merge, :merge_check, + :edit, :update, :show, :diffs, :commits, :builds, :merge, :merge_check, :ci_status, :toggle_subscription ] - before_action :closes_issues, only: [:edit, :update, :show, :diffs, :commits] - before_action :validates_merge_request, only: [:show, :diffs, :commits] - before_action :define_show_vars, only: [:show, :diffs, :commits] - before_action :ensure_ref_fetched, only: [:show, :commits, :diffs] + before_action :closes_issues, only: [:edit, :update, :show, :diffs, :commits, :builds] + before_action :validates_merge_request, only: [:show, :diffs, :commits, :builds] + before_action :define_show_vars, only: [:show, :diffs, :commits, :builds] + before_action :ensure_ref_fetched, only: [:show, :diffs, :commits, :builds] # Allow read any merge_request before_action :authorize_read_merge_request! @@ -79,6 +79,15 @@ class Projects::MergeRequestsController < Projects::ApplicationController end end + def builds + @ci_project = @merge_request.source_project.gitlab_ci_project + + respond_to do |format| + format.html { render 'show' } + format.json { render json: { html: view_to_html_string('projects/merge_requests/show/_builds') } } + end + end + def new params[:merge_request] ||= ActionController::Parameters.new(source_project: @project) @merge_request = MergeRequests::BuildService.new(project, current_user, merge_request_params).execute @@ -91,20 +100,19 @@ class Projects::MergeRequestsController < Projects::ApplicationController @target_project = merge_request.target_project @source_project = merge_request.source_project - @commits = @merge_request.compare_commits + @commits = @merge_request.compare_commits.reverse @commit = @merge_request.last_commit @first_commit = @merge_request.first_commit @diffs = @merge_request.compare_diffs + + @ci_project = @source_project.gitlab_ci_project + @ci_commit = @merge_request.ci_commit + @statuses = @ci_commit.statuses if @ci_commit + @note_counts = Note.where(commit_id: @commits.map(&:id)). group(:commit_id).count end - def edit - @source_project = @merge_request.source_project - @target_project = @merge_request.target_project - @target_branches = @merge_request.target_project.repository.branch_names - end - def create @target_branches ||= [] @merge_request = MergeRequests::CreateService.new(project, current_user, merge_request_params).execute @@ -118,6 +126,12 @@ class Projects::MergeRequestsController < Projects::ApplicationController end end + def edit + @source_project = @merge_request.source_project + @target_project = @merge_request.target_project + @target_branches = @merge_request.target_project.repository.branch_names + end + def update @merge_request = MergeRequests::UpdateService.new(project, current_user, merge_request_params).execute(@merge_request) @@ -264,6 +278,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController @merge_request_diff = @merge_request.merge_request_diff + @ci_commit = @merge_request.ci_commit + @statuses = @ci_commit.statuses if @ci_commit + if @merge_request.locked_long_ago? @merge_request.unlock_mr @merge_request.close diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index 156922cea41..f0a821d2d9f 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -23,6 +23,11 @@ = link_to url_for(params), data: {target: '#commits', action: 'commits', toggle: 'tab'} do Commits %span.badge= @commits.size + - if @ci_commit + %li.builds-tab.active + = link_to url_for(params), data: {target: '#builds', action: 'builds', toggle: 'tab'} do + Builds + %span.badge= @statuses.size %li.diffs-tab.active = link_to url_for(params), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do Changes @@ -31,6 +36,9 @@ .tab-content #commits.commits.tab-pane = render "projects/merge_requests/show/commits" + - if @ci_commit + #builds.builds.tab-pane + = render "projects/merge_requests/show/builds" #diffs.diffs.tab-pane.active - if @diffs.present? = render "projects/diffs/diffs", diffs: @diffs, project: @project diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index f5aff0877e7..79d71a784c1 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -26,8 +26,7 @@ %li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff) .normal %span Request to merge - %span.label-branch - = source_branch_with_namespace(@merge_request) + %span.label-branch= source_branch_with_namespace(@merge_request) %span into = link_to namespace_project_commits_path(@project.namespace, @project, @merge_request.target_branch), class: "label-branch" do = @merge_request.target_branch @@ -51,6 +50,11 @@ = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#commits', action: 'commits', toggle: 'tab'} do Commits %span.badge= @commits.size + - if @ci_commit + %li.builds-tab + = link_to builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#builds', action: 'builds', toggle: 'tab'} do + Builds + %span.badge= @statuses.size %li.diffs-tab = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do Changes @@ -61,6 +65,8 @@ = render "projects/merge_requests/discussion" #commits.commits.tab-pane - # This tab is always loaded via AJAX + #builds.builds.tab-pane + - # This tab is always loaded via AJAX #diffs.diffs.tab-pane - # This tab is always loaded via AJAX diff --git a/app/views/projects/merge_requests/show/_builds.html.haml b/app/views/projects/merge_requests/show/_builds.html.haml new file mode 100644 index 00000000000..307a75d02ca --- /dev/null +++ b/app/views/projects/merge_requests/show/_builds.html.haml @@ -0,0 +1 @@ += render "projects/commit/builds", link_to_commit: true diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml index ba5ad22bca7..f277014f840 100644 --- a/app/views/projects/merge_requests/widget/_heading.html.haml +++ b/app/views/projects/merge_requests/widget/_heading.html.haml @@ -7,7 +7,7 @@ %span CI build #{status} for #{@merge_request.last_commit_short_sha}. %span.ci-coverage - = link_to "View build details", ci_status_path(ci_commit) + = link_to "View build details", builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: "js-show-tab", data: {action: 'builds'} - elsif @merge_request.has_ci? - # Compatibility with old CI integrations (ex jenkins) when you request status from CI server via AJAX diff --git a/config/routes.rb b/config/routes.rb index 3b151891a6b..38f0b16a412 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -570,6 +570,7 @@ Rails.application.routes.draw do resources :merge_requests, constraints: { id: /\d+/ }, except: [:destroy] do member do get :diffs + get :builds get :commits post :merge get :merge_check -- cgit v1.2.1 From c767d0e6bd95e73217a92040d568b34e14b65949 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 13:04:47 +0100 Subject: Change text of MR widget heading --- app/assets/stylesheets/pages/merge_requests.scss | 4 ++++ .../projects/merge_requests/widget/_heading.html.haml | 15 ++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index f21ad694d06..ab7df978768 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -81,6 +81,10 @@ &.ci-error { color: $gl-danger; } + + a.monospace { + color: inherit; + } } .mr-widget-body, diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml index f277014f840..e94b07eaeaa 100644 --- a/app/views/projects/merge_requests/widget/_heading.html.haml +++ b/app/views/projects/merge_requests/widget/_heading.html.haml @@ -4,10 +4,12 @@ .mr-widget-heading .ci_widget{class: "ci-#{status}"} = ci_status_icon(ci_commit) - %span CI build #{status} - for #{@merge_request.last_commit_short_sha}. + %span Build #{status} + for + = succeed "." do + = link_to @ci_commit.short_sha, namespace_project_commit_path(@merge_request.source_project.namespace, @merge_request.source_project, @ci_commit.sha), class: "monospace" %span.ci-coverage - = link_to "View build details", builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: "js-show-tab", data: {action: 'builds'} + = link_to "View details", builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: "js-show-tab", data: {action: 'builds'} - elsif @merge_request.has_ci? - # Compatibility with old CI integrations (ex jenkins) when you request status from CI server via AJAX @@ -21,10 +23,13 @@ - else = icon("circle") %span CI build #{status} - for #{@merge_request.last_commit_short_sha}. + for + - commit = @merge_request.last_commit + = succeed "." do + = link_to commit.short_id, namespace_project_commit_path(@merge_request.source_project.namespace, @merge_request.source_project, commit), class: "monospace" %span.ci-coverage - if ci_build_details_path(@merge_request) - = link_to "View build details", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" + = link_to "View details", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" .ci_widget = icon("spinner spin") -- cgit v1.2.1 From af6b5437421106caf34719e37d359808b88eb45c Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 13:04:59 +0100 Subject: Make commit and MR ref filters aware of /builds path --- lib/gitlab/markdown/commit_reference_filter.rb | 11 +++++++++++ lib/gitlab/markdown/merge_request_reference_filter.rb | 8 +++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/markdown/commit_reference_filter.rb b/lib/gitlab/markdown/commit_reference_filter.rb index b4036578e60..e3066a89b04 100644 --- a/lib/gitlab/markdown/commit_reference_filter.rb +++ b/lib/gitlab/markdown/commit_reference_filter.rb @@ -47,6 +47,17 @@ module Gitlab def object_link_title(commit) commit.link_title end + + def object_link_text_extras(object, matches) + extras = super + + path = matches[:path] if matches.names.include?("path") + if path == '/builds' + extras.unshift "builds" + end + + extras + end end end end diff --git a/lib/gitlab/markdown/merge_request_reference_filter.rb b/lib/gitlab/markdown/merge_request_reference_filter.rb index de71fc76a9b..79d67870b14 100644 --- a/lib/gitlab/markdown/merge_request_reference_filter.rb +++ b/lib/gitlab/markdown/merge_request_reference_filter.rb @@ -24,8 +24,14 @@ module Gitlab def object_link_text_extras(object, matches) extras = super - if matches.names.include?("path") && matches[:path] && matches[:path] == '/diffs' + path = matches[:path] if matches.names.include?("path") + case path + when '/diffs' extras.unshift "diffs" + when '/builds' + extras.unshift "builds" + when '/commits' + extras.unshift "commits" end extras -- cgit v1.2.1 From 5beacba038c097e513b46f24ee26d5065ad419c9 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 14:13:57 +0100 Subject: Fix spec --- features/steps/project/commits/commits.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index e5b3f27135d..0d6a9a8fc66 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -118,6 +118,6 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps step 'I see builds list' do expect(page).to have_content "build: pending" - expect(page).to have_content "Latest builds" + expect(page).to have_content "1 build" end end -- cgit v1.2.1 From df6750d3d6b562c8a6a0a57c12dfd694da38a0e8 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 16:42:10 +0100 Subject: Default target branch to patch-n when editing file in protected branch --- app/controllers/projects/blob_controller.rb | 12 ++++++++++-- app/helpers/branches_helper.rb | 2 +- app/helpers/tree_helper.rb | 13 ++++++++++--- app/models/repository.rb | 11 +++++++++++ app/views/shared/_new_commit_form.html.haml | 2 +- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 31a33bfd237..62163682936 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -162,12 +162,20 @@ class Projects::BlobController < Projects::ApplicationController end def sanitized_new_branch_name - @new_branch ||= sanitize(strip_tags(params[:new_branch])) + sanitize(strip_tags(params[:new_branch])) end def editor_variables @current_branch = @ref - @new_branch = params[:new_branch].present? ? sanitized_new_branch_name : @ref + + @new_branch = + if params[:new_branch].present? + sanitized_new_branch_name + elsif ::Gitlab::GitAccess.new(current_user, @project).can_push_to_branch?(@ref) + @ref + else + @repository.next_patch_branch + end @file_path = if action_name.to_s == 'create' diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb index d6eaa7d57bc..e39548e17e1 100644 --- a/app/helpers/branches_helper.rb +++ b/app/helpers/branches_helper.rb @@ -11,7 +11,7 @@ module BranchesHelper def can_push_branch?(project, branch_name) return false unless project.repository.branch_names.include?(branch_name) - + ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(branch_name) end end diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index 6afa1aacc5b..ac75c9a14b7 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -48,10 +48,17 @@ module TreeHelper def allowed_tree_edit?(project = nil, ref = nil) project ||= @project - ref ||= @ref - return false unless project.repository.branch_names.include?(ref) + can?(current_user, :push_code, project) + end - ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref) + def tree_edit_branch(project = @project, ref = @ref) + if allowed_tree_edit? + if can_push_branch?(project, ref) + ref + else + project.repository.next_patch_branch + end + end end def can_delete_or_replace?(blob) diff --git a/app/models/repository.rb b/app/models/repository.rb index 1d43307e1e7..1edec52c09e 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -329,6 +329,17 @@ class Repository commit(sha) end + def next_patch_branch + patch_branch_ids = self.branch_names.map do |n| + result = n.match(/\Apatch-([0-9]+)\z/) + result[1].to_i if result + end.compact + + highest_patch_branch_id = patch_branch_ids.max || 0 + + "patch-#{highest_patch_branch_id + 1}" + end + # Remove archives older than 2 hours def branches_sorted_by(value) case value diff --git a/app/views/shared/_new_commit_form.html.haml b/app/views/shared/_new_commit_form.html.haml index 31b02ed93d0..074080e44c9 100644 --- a/app/views/shared/_new_commit_form.html.haml +++ b/app/views/shared/_new_commit_form.html.haml @@ -4,7 +4,7 @@ .form-group.branch = label_tag 'new_branch', 'Target branch', class: 'control-label' .col-sm-10 - = text_field_tag 'new_branch', @new_branch || @ref, required: true, class: "form-control js-new-branch" + = text_field_tag 'new_branch', @new_branch || tree_edit_branch, required: true, class: "form-control js-new-branch" .form-group.js-create-merge-request-form-group .col-sm-offset-2.col-sm-10 -- cgit v1.2.1 From 82ddd738b672afd4ed28f12fb58f512fa117d2be Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 17:10:07 +0100 Subject: Show tooltip when trying to edit file when not on branch --- app/helpers/blob_helper.rb | 38 ++++++++++++-------------- app/helpers/tree_helper.rb | 13 +++++---- app/services/files/base_service.rb | 2 +- app/views/projects/blob/_actions.html.haml | 14 ++++++---- app/views/projects/blob/show.html.haml | 2 +- app/views/projects/tree/_tree_header.html.haml | 4 +++ 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 4a3d971f7c6..65bd543bf1a 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -30,26 +30,24 @@ module BlobHelper nil end - if blob_viewable?(blob) - text = 'Edit' - after = options[:after] || '' - from_mr = options[:from_merge_request_id] - link_opts = {} - link_opts[:from_merge_request_id] = from_mr if from_mr - cls = 'btn btn-small' - if allowed_tree_edit?(project, ref) - link_to(text, - namespace_project_edit_blob_path(project.namespace, project, - tree_join(ref, path), - link_opts), - class: cls - ) - else - content_tag :span, text, class: cls + ' disabled' - end + after.html_safe - else - '' - end + return unless blob && blob_editable?(blob) + + text = 'Edit' + after = options[:after] || '' + from_mr = options[:from_merge_request_id] + link_opts = {} + link_opts[:from_merge_request_id] = from_mr if from_mr + cls = 'btn btn-small' + link_to(text, + namespace_project_edit_blob_path(project.namespace, project, + tree_join(ref, path), + link_opts), + class: cls + ) + after.html_safe + end + + def blob_editable?(blob, project = @project, ref = @ref) + allowed_tree_edit?(project, ref) && !blob.lfs_pointer? end def leave_edit_message diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index ac75c9a14b7..886a1e734b5 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -46,13 +46,20 @@ module TreeHelper File.join(*args) end + def on_top_of_branch?(project = @project, ref = @ref) + project.repository.branch_names.include?(ref) + end + def allowed_tree_edit?(project = nil, ref = nil) project ||= @project + ref ||= @ref + return false unless on_top_of_branch?(project, ref) + can?(current_user, :push_code, project) end def tree_edit_branch(project = @project, ref = @ref) - if allowed_tree_edit? + if allowed_tree_edit?(project, ref) if can_push_branch?(project, ref) ref else @@ -61,10 +68,6 @@ module TreeHelper end end - def can_delete_or_replace?(blob) - allowed_tree_edit? && !blob.lfs_pointer? - end - def tree_breadcrumbs(tree, max_links = 2) if @path.present? part_path = "" diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb index f50aaf2eb52..309abcd6d0b 100644 --- a/app/services/files/base_service.rb +++ b/app/services/files/base_service.rb @@ -53,7 +53,7 @@ module Files unless project.empty_repo? unless repository.branch_names.include?(@current_branch) - raise_error("You can only create files if you are on top of a branch") + raise_error("You can only create or edit files when you are on top of a branch") end if @current_branch != @target_branch diff --git a/app/views/projects/blob/_actions.html.haml b/app/views/projects/blob/_actions.html.haml index 0e54e59e953..41d8765623e 100644 --- a/app/views/projects/blob/_actions.html.haml +++ b/app/views/projects/blob/_actions.html.haml @@ -1,5 +1,4 @@ .btn-group.tree-btn-group - = edit_blob_link(@project, @ref, @path) = link_to 'Raw', namespace_project_raw_path(@project.namespace, @project, @id), class: 'btn btn-sm', target: '_blank' -# only show normal/blame view links for text files @@ -12,11 +11,16 @@ class: 'btn btn-sm' unless @blob.empty? = link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), class: 'btn btn-sm' - - if @ref != @commit.sha - = link_to 'Permalink', namespace_project_blob_path(@project.namespace, @project, - tree_join(@commit.sha, @path)), class: 'btn btn-sm' + = link_to 'Permalink', namespace_project_blob_path(@project.namespace, @project, + tree_join(@commit.sha, @path)), class: 'btn btn-sm' -- if can_delete_or_replace?(@blob) +- if blob_editable?(@blob) .btn-group{ role: "group" } + = edit_blob_link(@project, @ref, @path) %button.btn.btn-default{ 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } Replace %button.btn.btn-remove{ 'data-target' => '#modal-remove-blob', 'data-toggle' => 'modal' } Delete +- elsif !on_top_of_branch? + .btn-group{ role: "group" } + %button.btn.btn-default.disabled.has_tooltip{title: "You can only edit files when you are on top of a branch.", data: {container: 'body'}} Edit + %button.btn.btn-default.disabled.has_tooltip{title: "You can only replace files when you are on top of a branch.", data: {container: 'body'}} Replace + %button.btn.btn-remove.disabled.has_tooltip{title: "You can only delete files when you are on top of a branch.", data: {container: 'body'}} Delete diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml index 09d6fc18e3e..3f8d11ed8c8 100644 --- a/app/views/projects/blob/show.html.haml +++ b/app/views/projects/blob/show.html.haml @@ -6,7 +6,7 @@ %div#tree-holder.tree-holder = render 'blob', blob: @blob -- if can_delete_or_replace?(@blob) +- if blob_editable?(@blob) = render 'projects/blob/remove' - title = "Replace #{@blob.name}" diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml index 1115ca6b4ca..4767f824ac1 100644 --- a/app/views/projects/tree/_tree_header.html.haml +++ b/app/views/projects/tree/_tree_header.html.haml @@ -30,3 +30,7 @@ = link_to '#modal-create-new-dir', { 'data-target' => '#modal-create-new-dir', 'data-toggle' => 'modal'} do = icon('folder fw') New directory + - elsif !on_top_of_branch? + %li + %span.btn.add-to-tree.disabled.has_tooltip{href: '#', title: "You can only add files when you are on top of a branch.", data: {container: 'body'}} + = icon('plus') -- cgit v1.2.1 From 7aeb7077cb906933c59e5b890fd4027005e34d3d Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 17:11:23 +0100 Subject: Only show Edit button for text blobs. --- app/helpers/blob_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 65bd543bf1a..68e5d5be600 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -30,7 +30,7 @@ module BlobHelper nil end - return unless blob && blob_editable?(blob) + return unless blob && blob.text? && blob_editable?(blob) text = 'Edit' after = options[:after] || '' @@ -47,7 +47,7 @@ module BlobHelper end def blob_editable?(blob, project = @project, ref = @ref) - allowed_tree_edit?(project, ref) && !blob.lfs_pointer? + !blob.lfs_pointer? && allowed_tree_edit?(project, ref) end def leave_edit_message -- cgit v1.2.1 From 23b6a98de00b966728f6b5ed3747b0d2e078165f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 22:28:28 +0100 Subject: Move Builds tab to the end --- .../javascripts/merge_request_tabs.js.coffee | 26 +++++++++++----------- .../projects/merge_requests/_new_submit.html.haml | 16 ++++++------- app/views/projects/merge_requests/_show.html.haml | 12 +++++----- config/routes.rb | 2 +- .../markdown/merge_request_reference_filter.rb | 4 ++-- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee index 69a12fdd045..b0eeb1db536 100644 --- a/app/assets/javascripts/merge_request_tabs.js.coffee +++ b/app/assets/javascripts/merge_request_tabs.js.coffee @@ -68,10 +68,10 @@ class @MergeRequestTabs if action == 'commits' @loadCommits($target.attr('href')) - else if action == 'builds' - @loadBuilds($target.attr('href')) else if action == 'diffs' @loadDiff($target.attr('href')) + else if action == 'builds' + @loadBuilds($target.attr('href')) @setCurrentAction(action) @@ -110,7 +110,7 @@ class @MergeRequestTabs action = 'notes' if action == 'show' # Remove a trailing '/commits' or '/diffs' - new_state = @_location.pathname.replace(/\/(commits|builds|diffs)(\.html)?\/?$/, '') + new_state = @_location.pathname.replace(/\/(commits|diffs|builds)(\.html)?\/?$/, '') # Append the new action if we're on a tab other than 'notes' unless action == 'notes' @@ -138,6 +138,16 @@ class @MergeRequestTabs @commitsLoaded = true @scrollToElement("#commits") + loadDiff: (source) -> + return if @diffsLoaded + + @_get + url: "#{source}.json" + @_location.search + success: (data) => + document.getElementById('diffs').innerHTML = data.html + @diffsLoaded = true + @scrollToElement("#diffs") + loadBuilds: (source) -> return if @buildsLoaded @@ -149,16 +159,6 @@ class @MergeRequestTabs @buildsLoaded = true @scrollToElement("#builds") - loadDiff: (source) -> - return if @diffsLoaded - - @_get - url: "#{source}.json" + @_location.search - success: (data) => - document.getElementById('diffs').innerHTML = data.html - @diffsLoaded = true - @scrollToElement("#diffs") - # Show or hide the loading spinner # # status - Boolean, true to show, false to hide diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index 3f6e421fcd7..4172d5a4e88 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -23,22 +23,19 @@ = link_to url_for(params), data: {target: 'div#commits', action: 'commits', toggle: 'tab'} do Commits %span.badge= @commits.size - - if @ci_commit - %li.builds-tab.active - = link_to url_for(params), data: {target: '#builds', action: 'builds', toggle: 'tab'} do - Builds - %span.badge= @statuses.size %li.diffs-tab.active = link_to url_for(params), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do Changes %span.badge= @diffs.size + - if @ci_commit + %li.builds-tab.active + = link_to url_for(params), data: {target: 'div#builds', action: 'builds', toggle: 'tab'} do + Builds + %span.badge= @statuses.size .tab-content #commits.commits.tab-pane = render "projects/merge_requests/show/commits" - - if @ci_commit - #builds.builds.tab-pane - = render "projects/merge_requests/show/builds" #diffs.diffs.tab-pane.active - if @diffs.present? = render "projects/diffs/diffs", diffs: @diffs, project: @project @@ -50,6 +47,9 @@ .alert.alert-danger %h4 This comparison includes a huge diff. %p To preserve performance the line changes are not shown. + - if @ci_commit + #builds.builds.tab-pane + = render "projects/merge_requests/show/builds" :javascript $('.assign-to-me-link').on('click', function(e){ diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 686a9a2c758..960d1561e73 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -50,25 +50,25 @@ = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#commits', action: 'commits', toggle: 'tab'} do Commits %span.badge= @commits.size + %li.diffs-tab + = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do + Changes + %span.badge= @merge_request.diffs.size - if @ci_commit %li.builds-tab = link_to builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#builds', action: 'builds', toggle: 'tab'} do Builds %span.badge= @statuses.size - %li.diffs-tab - = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do - Changes - %span.badge= @merge_request.diffs.size .tab-content #notes.notes.tab-pane.voting_notes = render "projects/merge_requests/discussion" #commits.commits.tab-pane - # This tab is always loaded via AJAX - #builds.builds.tab-pane - - # This tab is always loaded via AJAX #diffs.diffs.tab-pane - # This tab is always loaded via AJAX + #builds.builds.tab-pane + - # This tab is always loaded via AJAX .mr-loading-status = spinner diff --git a/config/routes.rb b/config/routes.rb index 359cd08e134..046e1800235 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -570,9 +570,9 @@ Rails.application.routes.draw do resources :merge_requests, constraints: { id: /\d+/ }, except: [:destroy] do member do + get :commits get :diffs get :builds - get :commits post :merge get :merge_check get :ci_status diff --git a/lib/gitlab/markdown/merge_request_reference_filter.rb b/lib/gitlab/markdown/merge_request_reference_filter.rb index 79d67870b14..2eb77c46da7 100644 --- a/lib/gitlab/markdown/merge_request_reference_filter.rb +++ b/lib/gitlab/markdown/merge_request_reference_filter.rb @@ -28,10 +28,10 @@ module Gitlab case path when '/diffs' extras.unshift "diffs" - when '/builds' - extras.unshift "builds" when '/commits' extras.unshift "commits" + when '/builds' + extras.unshift "builds" end extras -- cgit v1.2.1 From 57d71520bdc2ba79ba8182802cd944d4fb42a192 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 22:30:40 +0100 Subject: Make tooltip less confusing --- app/controllers/projects/application_controller.rb | 2 +- app/services/files/base_service.rb | 2 +- app/views/projects/blob/_actions.html.haml | 6 +++--- app/views/projects/tree/_tree_header.html.haml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index d3f926b62bc..eea41dbeeb1 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -21,7 +21,7 @@ class Projects::ApplicationController < ApplicationController unless @repository.branch_names.include?(@ref) redirect_to( namespace_project_tree_path(@project.namespace, @project, @ref), - notice: "This action is not allowed unless you are on top of a branch" + notice: "This action is not allowed unless you are on a branch" ) end end diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb index 309abcd6d0b..9a67b160940 100644 --- a/app/services/files/base_service.rb +++ b/app/services/files/base_service.rb @@ -53,7 +53,7 @@ module Files unless project.empty_repo? unless repository.branch_names.include?(@current_branch) - raise_error("You can only create or edit files when you are on top of a branch") + raise_error("You can only create or edit files when you are on a branch") end if @current_branch != @target_branch diff --git a/app/views/projects/blob/_actions.html.haml b/app/views/projects/blob/_actions.html.haml index 41d8765623e..b1df8d19938 100644 --- a/app/views/projects/blob/_actions.html.haml +++ b/app/views/projects/blob/_actions.html.haml @@ -21,6 +21,6 @@ %button.btn.btn-remove{ 'data-target' => '#modal-remove-blob', 'data-toggle' => 'modal' } Delete - elsif !on_top_of_branch? .btn-group{ role: "group" } - %button.btn.btn-default.disabled.has_tooltip{title: "You can only edit files when you are on top of a branch.", data: {container: 'body'}} Edit - %button.btn.btn-default.disabled.has_tooltip{title: "You can only replace files when you are on top of a branch.", data: {container: 'body'}} Replace - %button.btn.btn-remove.disabled.has_tooltip{title: "You can only delete files when you are on top of a branch.", data: {container: 'body'}} Delete + %button.btn.btn-default.disabled.has_tooltip{title: "You can only edit files when you are on a branch.", data: {container: 'body'}} Edit + %button.btn.btn-default.disabled.has_tooltip{title: "You can only replace files when you are on a branch.", data: {container: 'body'}} Replace + %button.btn.btn-remove.disabled.has_tooltip{title: "You can only delete files when you are on a branch.", data: {container: 'body'}} Delete diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml index 4767f824ac1..2baa5ecd974 100644 --- a/app/views/projects/tree/_tree_header.html.haml +++ b/app/views/projects/tree/_tree_header.html.haml @@ -32,5 +32,5 @@ New directory - elsif !on_top_of_branch? %li - %span.btn.add-to-tree.disabled.has_tooltip{href: '#', title: "You can only add files when you are on top of a branch.", data: {container: 'body'}} + %span.btn.add-to-tree.disabled.has_tooltip{title: "You can only add files when you are on a branch.", data: {container: 'body'}} = icon('plus') -- cgit v1.2.1 From 0f89e6905db6fe821332013e8ddb2707079e0ba4 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 22:31:40 +0100 Subject: Fix spec --- features/project/source/browse_files.feature | 6 ------ features/steps/project/source/browse_files.rb | 4 ---- 2 files changed, 10 deletions(-) diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature index 37f99b37619..439787f2641 100644 --- a/features/project/source/browse_files.feature +++ b/features/project/source/browse_files.feature @@ -110,12 +110,6 @@ Feature: Project Source Browse Files Given I visit a binary file in the repo Then I cannot see the edit button - Scenario: If I don't have edit permission the edit link is disabled - Given public project "Community" - And I visit project "Community" source page - And I click on ".gitignore" file in repo - Then The edit button is disabled - @javascript Scenario: I can edit and commit file Given I click on ".gitignore" file in repo diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 2792174cc93..f2b95764267 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -53,10 +53,6 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps expect(page).not_to have_link 'edit' end - step 'The edit button is disabled' do - expect(page).to have_css '.disabled', text: 'Edit' - end - step 'I can edit code' do set_new_content expect(evaluate_script('blob.editor.getValue()')).to eq new_gitignore_content -- cgit v1.2.1 From 56f25c3e615752817446d5aedb7d66d25d815641 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Mon, 7 Dec 2015 13:37:01 +0100 Subject: Improve text indication visibility on snippets --- CHANGELOG | 1 + app/helpers/visibility_level_helper.rb | 26 ++++--- .../admin/application_settings/_form.html.haml | 4 +- app/views/shared/snippets/_header.html.haml | 2 +- spec/helpers/visibility_level_helper_spec.rb | 85 +++++++++------------- 5 files changed, 53 insertions(+), 65 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 67f70e676c2..c291d4b6dec 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -24,6 +24,7 @@ v 8.3.0 (unreleased) - Fix bug when simultaneously accepting multiple MRs results in MRs that are of "merged" status, but not merged to the target branch - Add languages page to graphs - Block LDAP user when they are no longer found in the LDAP server + - Improve wording on project visibility levels (Zeger-Jan van de Weg) v 8.2.3 - Fix application settings cache not expiring after changes (Stan Hu) diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb index 72c65030f94..2e69ce923a2 100644 --- a/app/helpers/visibility_level_helper.rb +++ b/app/helpers/visibility_level_helper.rb @@ -12,22 +12,22 @@ module VisibilityLevelHelper # Return the description for the +level+ argument. # - # +level+ One of the Gitlab::VisibilityLevel constants - # +form_model+ Either a model object (Project, Snippet, etc.) or the name of - # a Project or Snippet class. + # +level+ One of the Gitlab::VisibilityLevel constants + # +form_model+ Either a model object (Project, Snippet, etc.) or the name of + # a Project or Snippet class. def visibility_level_description(level, form_model) - case form_model.is_a?(String) ? form_model : form_model.class.name - when 'PersonalSnippet', 'ProjectSnippet', 'Snippet' - snippet_visibility_level_description(level) - when 'Project' + case form_model + when Project project_visibility_level_description(level) + when Snippet + snippet_visibility_level_description(level, form_model) end end def project_visibility_level_description(level) case level when Gitlab::VisibilityLevel::PRIVATE - "Project access must be granted explicitly for each user." + "Project access must be granted explicitly to each user." when Gitlab::VisibilityLevel::INTERNAL "The project can be cloned by any logged in user." when Gitlab::VisibilityLevel::PUBLIC @@ -35,12 +35,16 @@ module VisibilityLevelHelper end end - def snippet_visibility_level_description(level) + def snippet_visibility_level_description(level, snippet = nil) case level when Gitlab::VisibilityLevel::PRIVATE - "The snippet is visible only for me." + if snippet.is_a? ProjectSnippet + "The snippet is visible only to project members." + else + "The snippet is visible only to me." + end when Gitlab::VisibilityLevel::INTERNAL - "The snippet is visible for any logged in user." + "The snippet is visible to any logged in user." when Gitlab::VisibilityLevel::PUBLIC "The snippet can be accessed without any authentication." end diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index ddaf0e0e8ff..6c355366948 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -14,11 +14,11 @@ .form-group.project-visibility-level-holder = f.label :default_project_visibility, class: 'control-label col-sm-2' .col-sm-10 - = render('shared/visibility_radios', model_method: :default_project_visibility, form: f, selected_level: @application_setting.default_project_visibility, form_model: 'Project') + = render('shared/visibility_radios', model_method: :default_project_visibility, form: f, selected_level: @application_setting.default_project_visibility, form_model: Project) .form-group.project-visibility-level-holder = f.label :default_snippet_visibility, class: 'control-label col-sm-2' .col-sm-10 - = render('shared/visibility_radios', model_method: :default_snippet_visibility, form: f, selected_level: @application_setting.default_snippet_visibility, form_model: 'Snippet') + = render('shared/visibility_radios', model_method: :default_snippet_visibility, form: f, selected_level: @application_setting.default_snippet_visibility, form_model: PersonalSnippet) .form-group = f.label :restricted_visibility_levels, class: 'control-label col-sm-2' .col-sm-10 diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml index 89c1d7122b0..eb0fd21c2d4 100644 --- a/app/views/shared/snippets/_header.html.haml +++ b/app/views/shared/snippets/_header.html.haml @@ -1,6 +1,6 @@ .issuable-details .page-title - .snippet-box.has_tooltip{class: visibility_level_color(@snippet.visibility_level), title: snippet_visibility_level_description(@snippet.visibility_level), data: { container: 'body' }} + .snippet-box.has_tooltip{class: visibility_level_color(@snippet.visibility_level), title: snippet_visibility_level_description(@snippet.visibility_level, @snippet), data: { container: 'body' }} = visibility_level_icon(@snippet.visibility_level, fw: false) = visibility_level_label(@snippet.visibility_level) Snippet ##{@snippet.id} diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb index c4f7693329c..aafc24397a9 100644 --- a/spec/helpers/visibility_level_helper_spec.rb +++ b/spec/helpers/visibility_level_helper_spec.rb @@ -7,69 +7,52 @@ describe VisibilityLevelHelper do init_haml_helpers end - let(:project) { create(:project) } + let(:project) { build(:project) } + let(:personal_snippet) { build(:personal_snippet) } + let(:project_snippet) { build(:project_snippet) } describe 'visibility_level_description' do - shared_examples 'a visibility level description' do - let(:desc) do - visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, - form_model) - end - - let(:expected_class) do - class_name = case form_model.class.name - when 'String' - form_model - else - form_model.class.name - end - - class_name.match(/(project|snippet)$/i)[0] - end - - it 'should refer to the correct class' do - expect(desc).to match(/#{expected_class}/i) + context 'used with a Project' do + it 'delegates projects to #project_visibility_level_description' do + expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)) + .to match /project/i end end - context 'form_model argument is a String' do - context 'model object is a personal snippet' do - it_behaves_like 'a visibility level description' do - let(:form_model) { 'PersonalSnippet' } - end + context 'called with a Snippet' do + it 'delegates snippets to #snippet_visibility_level_description' do + expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)) + .to match /snippet/i end + end + end - context 'model object is a project snippet' do - it_behaves_like 'a visibility level description' do - let(:form_model) { 'ProjectSnippet' } - end - end + describe "#project_visibility_level_description" do + it "describes private projects" do + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) + .to eq "Project access must be granted explicitly to each user." + end - context 'model object is a project' do - it_behaves_like 'a visibility level description' do - let(:form_model) { 'Project' } - end - end + it "describes public projects" do + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC)) + .to eq "The project can be cloned without any authentication." end + end - context 'form_model argument is a model object' do - context 'model object is a personal snippet' do - it_behaves_like 'a visibility level description' do - let(:form_model) { create(:personal_snippet) } - end - end + describe "#snippet_visibility_level_description" do + it 'describes visibility only for me' do + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)) + .to eq "The snippet is visible only to me." + end - context 'model object is a project snippet' do - it_behaves_like 'a visibility level description' do - let(:form_model) { create(:project_snippet, project: project) } - end - end + it 'describes visibility for project members' do + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)) + .to eq "The snippet is visible only to project members." + end - context 'model object is a project' do - it_behaves_like 'a visibility level description' do - let(:form_model) { project } - end - end + it 'defaults to personal snippet' do + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) + .to eq "The snippet is visible only to me." end end -- cgit v1.2.1 From 9dd26749634648e2cd27b223eea5d291c0a78f37 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 9 Dec 2015 01:43:57 +0100 Subject: Fix only 20 group members showing on project member page Signed-off-by: Dmitriy Zaporozhets --- app/controllers/projects/project_members_controller.rb | 2 +- app/views/projects/project_members/_group_members.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index 07eb94e4f48..8364fc293b7 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -23,7 +23,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController @group_members = @group_members.where(user_id: users) end - @group_members = @group_members.order('access_level DESC').limit(20) + @group_members = @group_members.order('access_level DESC') end @project_member = @project.project_members.new diff --git a/app/views/projects/project_members/_group_members.html.haml b/app/views/projects/project_members/_group_members.html.haml index d2810f9707a..1c2458fa144 100644 --- a/app/views/projects/project_members/_group_members.html.haml +++ b/app/views/projects/project_members/_group_members.html.haml @@ -10,7 +10,7 @@ = icon('pencil-square-o') Manage group members %ul.content-list - - members.each do |member| + - members.limit(20).each do |member| = render 'groups/group_members/group_member', member: member, show_controls: false - if members.count > 20 %li -- cgit v1.2.1 From 9dbc768db8304004c08957710d423c0b2b54510a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 8 Dec 2015 21:00:01 -0800 Subject: Update annotations --- app/models/lfs_object.rb | 12 ++++++++++++ app/models/lfs_objects_project.rb | 11 +++++++++++ app/models/note.rb | 1 + app/models/project.rb | 1 + app/models/user.rb | 1 + spec/factories/lfs_objects.rb | 12 ++++++++++++ spec/factories/lfs_objects_projects.rb | 11 +++++++++++ spec/factories/notes.rb | 1 + spec/factories/projects.rb | 1 + spec/models/note_spec.rb | 1 + spec/models/project_spec.rb | 1 + spec/models/user_spec.rb | 1 + 12 files changed, 54 insertions(+) diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index 18657c3e1c8..86b1b7e2f99 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -1,3 +1,15 @@ +# == Schema Information +# +# Table name: lfs_objects +# +# id :integer not null, primary key +# oid :string(255) not null +# size :integer not null +# created_at :datetime +# updated_at :datetime +# file :string(255) +# + class LfsObject < ActiveRecord::Base has_many :lfs_objects_projects, dependent: :destroy has_many :projects, through: :lfs_objects_projects diff --git a/app/models/lfs_objects_project.rb b/app/models/lfs_objects_project.rb index 0fd5f089db9..890736bfc80 100644 --- a/app/models/lfs_objects_project.rb +++ b/app/models/lfs_objects_project.rb @@ -1,3 +1,14 @@ +# == Schema Information +# +# Table name: lfs_objects_projects +# +# id :integer not null, primary key +# lfs_object_id :integer not null +# project_id :integer not null +# created_at :datetime +# updated_at :datetime +# + class LfsObjectsProject < ActiveRecord::Base belongs_to :project belongs_to :lfs_object diff --git a/app/models/note.rb b/app/models/note.rb index 8d433c57ceb..98c29ddc4cd 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -16,6 +16,7 @@ # system :boolean default(FALSE), not null # st_diff :text # updated_by_id :integer +# is_award :boolean default(FALSE), not null # require 'carrierwave/orm/activerecord' diff --git a/app/models/project.rb b/app/models/project.rb index af034a6692b..cb965ce1b9e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -28,6 +28,7 @@ # import_type :string(255) # import_source :string(255) # commit_count :integer default(0) +# import_error :text # require 'carrierwave/orm/activerecord' diff --git a/app/models/user.rb b/app/models/user.rb index cfed797e725..7155dd2bea7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -56,6 +56,7 @@ # project_view :integer default(0) # consumed_timestep :integer # layout :integer default(0) +# hide_project_limit :boolean default(FALSE) # require 'carrierwave/orm/activerecord' diff --git a/spec/factories/lfs_objects.rb b/spec/factories/lfs_objects.rb index 7fb2d77ca32..2da107ba24b 100644 --- a/spec/factories/lfs_objects.rb +++ b/spec/factories/lfs_objects.rb @@ -1,3 +1,15 @@ +# == Schema Information +# +# Table name: lfs_objects +# +# id :integer not null, primary key +# oid :string(255) not null +# size :integer not null +# created_at :datetime +# updated_at :datetime +# file :string(255) +# + # Read about factories at https://github.com/thoughtbot/factory_girl FactoryGirl.define do diff --git a/spec/factories/lfs_objects_projects.rb b/spec/factories/lfs_objects_projects.rb index 93de6607df8..3772236a77a 100644 --- a/spec/factories/lfs_objects_projects.rb +++ b/spec/factories/lfs_objects_projects.rb @@ -1,3 +1,14 @@ +# == Schema Information +# +# Table name: lfs_objects_projects +# +# id :integer not null, primary key +# lfs_object_id :integer not null +# project_id :integer not null +# created_at :datetime +# updated_at :datetime +# + # Read about factories at https://github.com/thoughtbot/factory_girl FactoryGirl.define do diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb index 9d777ddfccd..35a20adeef3 100644 --- a/spec/factories/notes.rb +++ b/spec/factories/notes.rb @@ -16,6 +16,7 @@ # system :boolean default(FALSE), not null # st_diff :text # updated_by_id :integer +# is_award :boolean default(FALSE), not null # require_relative '../support/repo_helpers' diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 1d500a11ad7..112213377ff 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -28,6 +28,7 @@ # import_type :string(255) # import_source :string(255) # commit_count :integer default(0) +# import_error :text # FactoryGirl.define do diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index f347f537550..e7e8887baf2 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -16,6 +16,7 @@ # system :boolean default(FALSE), not null # st_diff :text # updated_by_id :integer +# is_award :boolean default(FALSE), not null # require 'spec_helper' diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 06a02c13bf1..dc703d8095c 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -28,6 +28,7 @@ # import_type :string(255) # import_source :string(255) # commit_count :integer default(0) +# import_error :text # require 'spec_helper' diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a0f78d3b336..1aad37fa02e 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -56,6 +56,7 @@ # project_view :integer default(0) # consumed_timestep :integer # layout :integer default(0) +# hide_project_limit :boolean default(FALSE) # require 'spec_helper' -- cgit v1.2.1