From 6daa97f47212d89bfa0dcbb7f549ecb68d1b3783 Mon Sep 17 00:00:00 2001 From: Nilton Moura Date: Thu, 26 Dec 2013 17:13:25 -0200 Subject: Changed sudo by su -c The sudo command needs a tty to run. If you put this file on a CentOS 6, for example, it will not run in the host startup process. Instead, the 'su -c' runs the command apart if it has or not a tty. I tested this change in a fresh install of gitlab on a CentOS 6.5 with successful. --- lib/support/init.d/gitlab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index f1b94087b6a..42bd4785d56 100755 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -41,7 +41,7 @@ test -f /etc/default/gitlab && . /etc/default/gitlab # Switch to the app_user if it is not he/she who is running the script. if [ "$USER" != "$app_user" ]; then - sudo -u "$app_user" -H -i $0 "$@"; exit; + eval su - "$app_user" -c $(echo \")$0 "$@"$(echo \"); exit; fi # Switch to the gitlab path, exit on failure. -- cgit v1.2.3 From c2ed468d803f37e29636d234d6c5db4e7e220880 Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Thu, 20 Feb 2014 10:59:03 +0100 Subject: Also expose username for the /discover endpoint Fixes #6328 --- lib/api/entities.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 8557fa074d4..9c9c7fcd6ea 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -15,7 +15,7 @@ module API end class UserSafe < Grape::Entity - expose :name + expose :name, :username end class UserBasic < Grape::Entity -- cgit v1.2.3 From ec225ae1cbbdd413749dc43545ada4662cb1aa3f Mon Sep 17 00:00:00 2001 From: Andrew Kumanyaev Date: Fri, 21 Feb 2014 20:25:29 +0300 Subject: Update merge_request_observer_spec.rb --- spec/observers/merge_request_observer_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/observers/merge_request_observer_spec.rb b/spec/observers/merge_request_observer_spec.rb index 6ad7c4d81da..18df8b78513 100644 --- a/spec/observers/merge_request_observer_spec.rb +++ b/spec/observers/merge_request_observer_spec.rb @@ -120,7 +120,7 @@ describe MergeRequestObserver do end before do - @merge_request = create(:merge_request, source_project: project, source_project: project) + @merge_request = create(:merge_request, source_project: project, target_project: project) @event = Event.last end -- cgit v1.2.3 From 2d554f42f07a9bebcb6d43ace2cdeedcc54e8de9 Mon Sep 17 00:00:00 2001 From: Jacob Carlborg Date: Thu, 9 Jan 2014 17:50:27 +0100 Subject: Add button for toggling inline comments in diff view. This is useful when there are many comments and they're becoming a distraction when trying to read the diff. --- app/assets/stylesheets/sections/commits.scss | 3 + app/assets/stylesheets/sections/notes.scss | 29 ++++++++- app/views/projects/commits/_diffs.html.haml | 10 +++- .../notes/_diff_notes_with_reply.html.haml | 2 +- .../_diff_notes_with_reply_parallel.html.haml | 2 +- features/project/merge_requests.feature | 44 ++++++++++++++ features/steps/project/project_merge_requests.rb | 68 ++++++++++++++++++++++ 7 files changed, 154 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss index ff293bc4a00..537ce921d9c 100644 --- a/app/assets/stylesheets/sections/commits.scss +++ b/app/assets/stylesheets/sections/commits.scss @@ -60,6 +60,9 @@ } table { + &.text-file { + border-collapse: separate; + } width: 100%; font-family: $monospace_font; border: none; diff --git a/app/assets/stylesheets/sections/notes.scss b/app/assets/stylesheets/sections/notes.scss index 9f5f1579fbd..52c778aaa85 100644 --- a/app/assets/stylesheets/sections/notes.scss +++ b/app/assets/stylesheets/sections/notes.scss @@ -184,13 +184,40 @@ ul.notes { } } } + +.file { + .discussion-actions { + margin-right: 5px; + margin-top: 3px; + + .turn-off { + display: inherit; + } + .turn-on { + display: none; + } + } + + &.open .discussion-actions { + .turn-off { + display: none; + } + .turn-on { + display: inherit; + } + } + + &[id^="diff"] .content { + display: block; + } +} + .file .note .note-actions { right: 0; top: 0; } - /** * Line note button on the side of diffs */ diff --git a/app/views/projects/commits/_diffs.html.haml b/app/views/projects/commits/_diffs.html.haml index a41a89bb972..6713fa20dd9 100644 --- a/app/views/projects/commits/_diffs.html.haml +++ b/app/views/projects/commits/_diffs.html.haml @@ -44,7 +44,7 @@ - file = project.repository.blob_at(@commit.id, diff.new_path) - file = project.repository.blob_at(@commit.parent_id, diff.old_path) unless file - next unless file - .file{id: "diff-#{i}"} + .file.js-details-container.js-toggle-container.open{id: "diff-#{i}"} .header - if diff.deleted_file %span= diff.old_path @@ -62,6 +62,14 @@ View file @ %span.commit-short-id= @commit.short_id(6) + .discussion-actions.pull-right + = link_to "javascript:;", class: "js-details-target js-toggle-button turn-on" do + %i.icon-eye-close + Hide inline discussion + = link_to "javascript:;", class: "js-details-target js-toggle-button turn-off" do + %i.icon-eye-open + Show inline discussion + .content -# Skipp all non non-supported blobs - next unless file.respond_to?('text?') diff --git a/app/views/projects/notes/_diff_notes_with_reply.html.haml b/app/views/projects/notes/_diff_notes_with_reply.html.haml index 9537ab18caa..9acadc6a14e 100644 --- a/app/views/projects/notes/_diff_notes_with_reply.html.haml +++ b/app/views/projects/notes/_diff_notes_with_reply.html.haml @@ -1,7 +1,7 @@ - note = notes.first # example note -# Check if line want not changed since comment was left - if !defined?(line) || line == note.diff_line - %tr.notes_holder + %tr.notes_holder.js-toggle-content %td.notes_line{ colspan: 2 } %span.btn.disabled %i.icon-comment diff --git a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml index 936dbb354cd..2012aa021b9 100644 --- a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml +++ b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml @@ -1,6 +1,6 @@ - note1 = notes1.first # example note - note2 = notes2.first # example note -%tr.notes_holder +%tr.notes_holder.js-toggle-content -# Check if line want not changed since comment was left /- if !defined?(line1) || line1 == note1.diff_line - if note1 diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature index 556b96338d6..9eba427c3e3 100644 --- a/features/project/merge_requests.feature +++ b/features/project/merge_requests.feature @@ -88,3 +88,47 @@ Feature: Project Merge Requests Given I visit merge request page "Bug NS-04" And I leave a comment with a header containing "Comment with a header" Then The comment with the header should not have an ID + + # Toggling inline comments + + @javascript + Scenario: I hide comments on a merge request diff with comments in a single file + Given project "Shop" have "Bug NS-05" open merge request with diffs inside + And I visit merge request page "Bug NS-05" + And I switch to the diff tab + And I leave a comment like "Line is wrong" on line 39 of the second file + And I click link "Hide inline discussion" of the second file + Then I should not see a comment like "Line is wrong" in the second file + + @javascript + Scenario: I show comments on a merge request diff with comments in a single file + Given project "Shop" have "Bug NS-05" open merge request with diffs inside + And I visit merge request page "Bug NS-05" + And I switch to the diff tab + And I leave a comment like "Line is wrong" on line 39 of the second file + And I click link "Hide inline discussion" of the second file + And I click link "Show inline discussion" of the second file + Then I should see a comment like "Line is wrong" in the second file + + @javascript + Scenario: I hide comments on a merge request diff with comments in multiple files + Given project "Shop" have "Bug NS-05" open merge request with diffs inside + And I visit merge request page "Bug NS-05" + And I switch to the diff tab + And I leave a comment like "Line is correct" on line 12 of the first file + And I leave a comment like "Line is wrong" on line 39 of the second file + And I click link "Hide inline discussion" of the second file + Then I should not see a comment like "Line is wrong" in the second file + And I should still see a comment like "Line is correct" in the first file + + @javascript + Scenario: I show comments on a merge request diff with comments in multiple files + Given project "Shop" have "Bug NS-05" open merge request with diffs inside + And I visit merge request page "Bug NS-05" + And I switch to the diff tab + And I leave a comment like "Line is correct" on line 12 of the first file + And I leave a comment like "Line is wrong" on line 39 of the second file + And I click link "Hide inline discussion" of the second file + And I click link "Show inline discussion" of the second file + Then I should see a comment like "Line is wrong" in the second file + And I should still see a comment like "Line is correct" in the first file diff --git a/features/steps/project/project_merge_requests.rb b/features/steps/project/project_merge_requests.rb index adf9e77e136..d4ce432834e 100644 --- a/features/steps/project/project_merge_requests.rb +++ b/features/steps/project/project_merge_requests.rb @@ -170,6 +170,62 @@ class ProjectMergeRequests < Spinach::FeatureSteps end end + step 'I click link "Hide inline discussion" of the second file' do + within '.files [id^=diff]:nth-child(2)' do + click_link "Hide inline discussion" + end + end + + step 'I click link "Show inline discussion" of the second file' do + within '.files [id^=diff]:nth-child(2)' do + click_link "Show inline discussion" + end + end + + step 'I should not see a comment like "Line is wrong" in the second file' do + within '.files [id^=diff]:nth-child(2)' do + page.should_not have_visible_content "Line is wrong" + end + end + + step 'I should see a comment like "Line is wrong" in the second file' do + within '.files [id^=diff]:nth-child(2) .note-text' do + page.should have_visible_content "Line is wrong" + end + end + + step 'I leave a comment like "Line is correct" on line 12 of the first file' do + init_diff_note_first_file + + within(".js-discussion-note-form") do + fill_in "note_note", with: "Line is correct" + click_button "Add Comment" + end + + within ".files [id^=diff]:nth-child(1) .note-text" do + page.should have_content "Line is correct" + end + end + + step 'I leave a comment like "Line is wrong" on line 39 of the second file' do + init_diff_note_second_file + + within(".js-discussion-note-form") do + fill_in "note_note", with: "Line is wrong" + click_button "Add Comment" + end + + within ".files [id^=diff]:nth-child(2) .note-text" do + page.should have_content "Line is wrong" + end + end + + step 'I should still see a comment like "Line is correct" in the first file' do + within '.files [id^=diff]:nth-child(1) .note-text' do + page.should have_visible_content "Line is correct" + end + end + def project @project ||= Project.find_by!(name: "Shop") end @@ -192,4 +248,16 @@ class ProjectMergeRequests < Spinach::FeatureSteps page.should have_content message end end + + def init_diff_note_first_file + find('a[data-line-code="a5cc2925ca8258af241be7e5b0381edf30266302_12_12"]').click + end + + def init_diff_note_second_file + find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_28_39"]').click + end + + def have_visible_content (text) + have_css("*", text: text, visible: true) + end end -- cgit v1.2.3 From 170340e6b15f91e79cf683c892ec887c3115b317 Mon Sep 17 00:00:00 2001 From: Ciro Santillli Date: Sun, 23 Feb 2014 10:04:56 +0100 Subject: Remove dir prefix and suffix from tests inside dir. --- features/project/archived.feature | 39 ++++ features/project/archived_projects.feature | 39 ---- features/project/commits/comments.feature | 48 +++++ features/project/commits/commit_comments.feature | 48 ----- .../project/commits/commit_diff_comments.feature | 85 --------- .../project/commits/commits_user_lookup.feature | 14 -- features/project/commits/diff_comments.feature | 85 +++++++++ features/project/commits/user_lookup.feature | 14 ++ features/project/create.feature | 22 +++ features/project/create_project.feature | 22 --- features/project/fork.feature | 14 ++ features/project/fork_project.feature | 14 -- features/project/public.feature | 8 + features/project/public_projects.feature | 8 - features/public/projects.feature | 101 ++++++++++ features/public/public_projects.feature | 101 ---------- features/snippets/discover.feature | 10 + features/snippets/discover_snippets.feature | 10 - features/snippets/user.feature | 22 +++ features/snippets/user_snippets.feature | 22 --- features/steps/admin/active_tab.rb | 37 ++++ features/steps/admin/admin_active_tab.rb | 37 ---- features/steps/admin/admin_broadcast_messages.rb | 41 ---- features/steps/admin/admin_groups.rb | 66 ------- features/steps/admin/admin_logs.rb | 11 -- features/steps/admin/admin_projects.rb | 22 --- features/steps/admin/admin_users.rb | 34 ---- features/steps/admin/broadcast_messages.rb | 41 ++++ features/steps/admin/groups.rb | 66 +++++++ features/steps/admin/logs.rb | 11 ++ features/steps/admin/projects.rb | 22 +++ features/steps/admin/users.rb | 34 ++++ features/steps/dashboard/active_tab.rb | 21 +++ features/steps/dashboard/dashboard_active_tab.rb | 21 --- .../steps/dashboard/dashboard_event_filters.rb | 87 --------- features/steps/dashboard/dashboard_issues.rb | 74 -------- .../steps/dashboard/dashboard_merge_requests.rb | 74 -------- features/steps/dashboard/dashboard_projects.rb | 11 -- features/steps/dashboard/dashboard_search.rb | 19 -- .../dashboard/dashboard_with_archived_projects.rb | 22 --- features/steps/dashboard/event_filters.rb | 87 +++++++++ features/steps/dashboard/issues.rb | 74 ++++++++ features/steps/dashboard/merge_requests.rb | 74 ++++++++ features/steps/dashboard/projects.rb | 11 ++ features/steps/dashboard/search.rb | 19 ++ features/steps/dashboard/with_archived_projects.rb | 22 +++ features/steps/profile/active_tab.rb | 25 +++ features/steps/profile/emails.rb | 48 +++++ features/steps/profile/notifications.rb | 12 ++ features/steps/profile/profile_active_tab.rb | 25 --- features/steps/profile/profile_emails.rb | 48 ----- features/steps/profile/profile_notifications.rb | 12 -- features/steps/profile/profile_ssh_keys.rb | 48 ----- features/steps/profile/ssh_keys.rb | 48 +++++ features/steps/project/active_tab.rb | 140 ++++++++++++++ features/steps/project/archived.rb | 37 ++++ features/steps/project/browse_branches.rb | 35 ++++ features/steps/project/browse_commits.rb | 104 +++++++++++ .../steps/project/browse_commits_user_lookup.rb | 35 ++++ features/steps/project/browse_files.rb | 53 ++++++ features/steps/project/browse_git_repo.rb | 19 ++ features/steps/project/browse_tags.rb | 10 + features/steps/project/create.rb | 42 +++++ features/steps/project/create_project.rb | 42 ----- features/steps/project/filter_labels.rb | 70 +++++++ features/steps/project/fork.rb | 36 ++++ features/steps/project/forked_merge_requests.rb | 183 ++++++++++++++++++ features/steps/project/graph.rb | 13 ++ features/steps/project/hooks.rb | 38 ++++ features/steps/project/issue_tracker.rb | 31 +++ features/steps/project/issues.rb | 145 +++++++++++++++ features/steps/project/labels.rb | 24 +++ features/steps/project/markdown_render.rb | 207 +++++++++++++++++++++ features/steps/project/merge_requests.rb | 195 +++++++++++++++++++ features/steps/project/milestones.rb | 59 ++++++ features/steps/project/multiselect_blob.rb | 58 ++++++ features/steps/project/network_graph.rb | 93 +++++++++ features/steps/project/project_active_tab.rb | 140 -------------- features/steps/project/project_archived.rb | 37 ---- features/steps/project/project_browse_branches.rb | 35 ---- features/steps/project/project_browse_commits.rb | 104 ----------- .../project/project_browse_commits_user_lookup.rb | 35 ---- features/steps/project/project_browse_files.rb | 53 ------ features/steps/project/project_browse_git_repo.rb | 19 -- features/steps/project/project_browse_tags.rb | 10 - features/steps/project/project_filter_labels.rb | 70 ------- features/steps/project/project_fork.rb | 36 ---- .../steps/project/project_forked_merge_requests.rb | 183 ------------------ features/steps/project/project_graph.rb | 13 -- features/steps/project/project_hooks.rb | 38 ---- features/steps/project/project_issue_tracker.rb | 31 --- features/steps/project/project_issues.rb | 145 --------------- features/steps/project/project_labels.rb | 24 --- features/steps/project/project_markdown_render.rb | 207 --------------------- features/steps/project/project_merge_requests.rb | 195 ------------------- features/steps/project/project_milestones.rb | 59 ------ features/steps/project/project_multiselect_blob.rb | 58 ------ features/steps/project/project_network_graph.rb | 93 --------- features/steps/project/project_search_code.rb | 17 -- features/steps/project/project_services.rb | 103 ---------- features/steps/project/project_snippets.rb | 99 ---------- features/steps/project/project_team_management.rb | 107 ----------- features/steps/project/project_wall.rb | 18 -- features/steps/project/project_wiki.rb | 92 --------- features/steps/project/public.rb | 9 + features/steps/project/public_projects.rb | 9 - features/steps/project/search_code.rb | 17 ++ features/steps/project/services.rb | 103 ++++++++++ features/steps/project/snippets.rb | 99 ++++++++++ features/steps/project/team_management.rb | 107 +++++++++++ features/steps/project/wall.rb | 18 ++ features/steps/project/wiki.rb | 92 +++++++++ features/steps/public/projects.rb | 172 +++++++++++++++++ features/steps/public/projects_feature.rb | 172 ----------------- features/steps/snippets/discover.rb | 17 ++ features/steps/snippets/discover_snippets.rb | 17 -- features/steps/snippets/user.rb | 41 ++++ features/steps/snippets/user_snippets.rb | 41 ---- 118 files changed, 3317 insertions(+), 3317 deletions(-) create mode 100644 features/project/archived.feature delete mode 100644 features/project/archived_projects.feature create mode 100644 features/project/commits/comments.feature delete mode 100644 features/project/commits/commit_comments.feature delete mode 100644 features/project/commits/commit_diff_comments.feature delete mode 100644 features/project/commits/commits_user_lookup.feature create mode 100644 features/project/commits/diff_comments.feature create mode 100644 features/project/commits/user_lookup.feature create mode 100644 features/project/create.feature delete mode 100644 features/project/create_project.feature create mode 100644 features/project/fork.feature delete mode 100644 features/project/fork_project.feature create mode 100644 features/project/public.feature delete mode 100644 features/project/public_projects.feature create mode 100644 features/public/projects.feature delete mode 100644 features/public/public_projects.feature create mode 100644 features/snippets/discover.feature delete mode 100644 features/snippets/discover_snippets.feature create mode 100644 features/snippets/user.feature delete mode 100644 features/snippets/user_snippets.feature create mode 100644 features/steps/admin/active_tab.rb delete mode 100644 features/steps/admin/admin_active_tab.rb delete mode 100644 features/steps/admin/admin_broadcast_messages.rb delete mode 100644 features/steps/admin/admin_groups.rb delete mode 100644 features/steps/admin/admin_logs.rb delete mode 100644 features/steps/admin/admin_projects.rb delete mode 100644 features/steps/admin/admin_users.rb create mode 100644 features/steps/admin/broadcast_messages.rb create mode 100644 features/steps/admin/groups.rb create mode 100644 features/steps/admin/logs.rb create mode 100644 features/steps/admin/projects.rb create mode 100644 features/steps/admin/users.rb create mode 100644 features/steps/dashboard/active_tab.rb delete mode 100644 features/steps/dashboard/dashboard_active_tab.rb delete mode 100644 features/steps/dashboard/dashboard_event_filters.rb delete mode 100644 features/steps/dashboard/dashboard_issues.rb delete mode 100644 features/steps/dashboard/dashboard_merge_requests.rb delete mode 100644 features/steps/dashboard/dashboard_projects.rb delete mode 100644 features/steps/dashboard/dashboard_search.rb delete mode 100644 features/steps/dashboard/dashboard_with_archived_projects.rb create mode 100644 features/steps/dashboard/event_filters.rb create mode 100644 features/steps/dashboard/issues.rb create mode 100644 features/steps/dashboard/merge_requests.rb create mode 100644 features/steps/dashboard/projects.rb create mode 100644 features/steps/dashboard/search.rb create mode 100644 features/steps/dashboard/with_archived_projects.rb create mode 100644 features/steps/profile/active_tab.rb create mode 100644 features/steps/profile/emails.rb create mode 100644 features/steps/profile/notifications.rb delete mode 100644 features/steps/profile/profile_active_tab.rb delete mode 100644 features/steps/profile/profile_emails.rb delete mode 100644 features/steps/profile/profile_notifications.rb delete mode 100644 features/steps/profile/profile_ssh_keys.rb create mode 100644 features/steps/profile/ssh_keys.rb create mode 100644 features/steps/project/active_tab.rb create mode 100644 features/steps/project/archived.rb create mode 100644 features/steps/project/browse_branches.rb create mode 100644 features/steps/project/browse_commits.rb create mode 100644 features/steps/project/browse_commits_user_lookup.rb create mode 100644 features/steps/project/browse_files.rb create mode 100644 features/steps/project/browse_git_repo.rb create mode 100644 features/steps/project/browse_tags.rb create mode 100644 features/steps/project/create.rb delete mode 100644 features/steps/project/create_project.rb create mode 100644 features/steps/project/filter_labels.rb create mode 100644 features/steps/project/fork.rb create mode 100644 features/steps/project/forked_merge_requests.rb create mode 100644 features/steps/project/graph.rb create mode 100644 features/steps/project/hooks.rb create mode 100644 features/steps/project/issue_tracker.rb create mode 100644 features/steps/project/issues.rb create mode 100644 features/steps/project/labels.rb create mode 100644 features/steps/project/markdown_render.rb create mode 100644 features/steps/project/merge_requests.rb create mode 100644 features/steps/project/milestones.rb create mode 100644 features/steps/project/multiselect_blob.rb create mode 100644 features/steps/project/network_graph.rb delete mode 100644 features/steps/project/project_active_tab.rb delete mode 100644 features/steps/project/project_archived.rb delete mode 100644 features/steps/project/project_browse_branches.rb delete mode 100644 features/steps/project/project_browse_commits.rb delete mode 100644 features/steps/project/project_browse_commits_user_lookup.rb delete mode 100644 features/steps/project/project_browse_files.rb delete mode 100644 features/steps/project/project_browse_git_repo.rb delete mode 100644 features/steps/project/project_browse_tags.rb delete mode 100644 features/steps/project/project_filter_labels.rb delete mode 100644 features/steps/project/project_fork.rb delete mode 100644 features/steps/project/project_forked_merge_requests.rb delete mode 100644 features/steps/project/project_graph.rb delete mode 100644 features/steps/project/project_hooks.rb delete mode 100644 features/steps/project/project_issue_tracker.rb delete mode 100644 features/steps/project/project_issues.rb delete mode 100644 features/steps/project/project_labels.rb delete mode 100644 features/steps/project/project_markdown_render.rb delete mode 100644 features/steps/project/project_merge_requests.rb delete mode 100644 features/steps/project/project_milestones.rb delete mode 100644 features/steps/project/project_multiselect_blob.rb delete mode 100644 features/steps/project/project_network_graph.rb delete mode 100644 features/steps/project/project_search_code.rb delete mode 100644 features/steps/project/project_services.rb delete mode 100644 features/steps/project/project_snippets.rb delete mode 100644 features/steps/project/project_team_management.rb delete mode 100644 features/steps/project/project_wall.rb delete mode 100644 features/steps/project/project_wiki.rb create mode 100644 features/steps/project/public.rb delete mode 100644 features/steps/project/public_projects.rb create mode 100644 features/steps/project/search_code.rb create mode 100644 features/steps/project/services.rb create mode 100644 features/steps/project/snippets.rb create mode 100644 features/steps/project/team_management.rb create mode 100644 features/steps/project/wall.rb create mode 100644 features/steps/project/wiki.rb create mode 100644 features/steps/public/projects.rb delete mode 100644 features/steps/public/projects_feature.rb create mode 100644 features/steps/snippets/discover.rb delete mode 100644 features/steps/snippets/discover_snippets.rb create mode 100644 features/steps/snippets/user.rb delete mode 100644 features/steps/snippets/user_snippets.rb diff --git a/features/project/archived.feature b/features/project/archived.feature new file mode 100644 index 00000000000..9aac29384ba --- /dev/null +++ b/features/project/archived.feature @@ -0,0 +1,39 @@ +Feature: Project Archived + Background: + Given I sign in as a user + And I own project "Shop" + And I own project "Forum" + + Scenario: I should not see archived on project page of not-archive project + And project "Forum" is archived + And I visit project "Shop" page + Then I should not see "Archived" + + Scenario: I should see archived on project page of archive project + And project "Forum" is archived + And I visit project "Forum" page + Then I should see "Archived" + + Scenario: I should not see archived on projects page with no archived projects + And I visit dashboard projects page + Then I should not see "Archived" + + Scenario: I should see archived on projects page with archived projects + And project "Forum" is archived + And I visit dashboard projects page + Then I should see "Archived" + + Scenario: I archive project + When project "Shop" has push event + And I visit project "Shop" page + And I visit edit project "Shop" page + And I set project archived + Then I should see "Archived" + + Scenario: I unarchive project + When project "Shop" has push event + And project "Shop" is archived + And I visit project "Shop" page + And I visit edit project "Shop" page + And I set project unarchived + Then I should not see "Archived" diff --git a/features/project/archived_projects.feature b/features/project/archived_projects.feature deleted file mode 100644 index 9aac29384ba..00000000000 --- a/features/project/archived_projects.feature +++ /dev/null @@ -1,39 +0,0 @@ -Feature: Project Archived - Background: - Given I sign in as a user - And I own project "Shop" - And I own project "Forum" - - Scenario: I should not see archived on project page of not-archive project - And project "Forum" is archived - And I visit project "Shop" page - Then I should not see "Archived" - - Scenario: I should see archived on project page of archive project - And project "Forum" is archived - And I visit project "Forum" page - Then I should see "Archived" - - Scenario: I should not see archived on projects page with no archived projects - And I visit dashboard projects page - Then I should not see "Archived" - - Scenario: I should see archived on projects page with archived projects - And project "Forum" is archived - And I visit dashboard projects page - Then I should see "Archived" - - Scenario: I archive project - When project "Shop" has push event - And I visit project "Shop" page - And I visit edit project "Shop" page - And I set project archived - Then I should see "Archived" - - Scenario: I unarchive project - When project "Shop" has push event - And project "Shop" is archived - And I visit project "Shop" page - And I visit edit project "Shop" page - And I set project unarchived - Then I should not see "Archived" diff --git a/features/project/commits/comments.feature b/features/project/commits/comments.feature new file mode 100644 index 00000000000..a1aa745a681 --- /dev/null +++ b/features/project/commits/comments.feature @@ -0,0 +1,48 @@ +Feature: Comments on commits + Background: + Given I sign in as a user + And I own project "Shop" + And I visit project commit page + + @javascript + Scenario: I can comment on a commit + Given I leave a comment like "XML attached" + Then I should see a comment saying "XML attached" + + @javascript + Scenario: I can't cancel the main form + Then I should not see the cancel comment button + + @javascript + Scenario: I can't preview without text + Given I haven't written any comment text + Then I should not see the comment preview button + + @javascript + Scenario: I can preview with text + Given I write a comment like "Nice" + Then I should see the comment preview button + + @javascript + Scenario: I preview a comment + Given I preview a comment text like "Bug fixed :smile:" + Then I should see the comment preview + And I should not see the comment text field + + @javascript + Scenario: I can edit after preview + Given I preview a comment text like "Bug fixed :smile:" + Then I should see the comment edit button + + @javascript + Scenario: I have a reset form after posting from preview + Given I preview a comment text like "Bug fixed :smile:" + And I submit the comment + Then I should see an empty comment text field + And I should not see the comment preview + + @javascript + Scenario: I can delete a comment + Given I leave a comment like "XML attached" + And I delete a comment + Then I should not see a comment saying "XML attached" diff --git a/features/project/commits/commit_comments.feature b/features/project/commits/commit_comments.feature deleted file mode 100644 index a1aa745a681..00000000000 --- a/features/project/commits/commit_comments.feature +++ /dev/null @@ -1,48 +0,0 @@ -Feature: Comments on commits - Background: - Given I sign in as a user - And I own project "Shop" - And I visit project commit page - - @javascript - Scenario: I can comment on a commit - Given I leave a comment like "XML attached" - Then I should see a comment saying "XML attached" - - @javascript - Scenario: I can't cancel the main form - Then I should not see the cancel comment button - - @javascript - Scenario: I can't preview without text - Given I haven't written any comment text - Then I should not see the comment preview button - - @javascript - Scenario: I can preview with text - Given I write a comment like "Nice" - Then I should see the comment preview button - - @javascript - Scenario: I preview a comment - Given I preview a comment text like "Bug fixed :smile:" - Then I should see the comment preview - And I should not see the comment text field - - @javascript - Scenario: I can edit after preview - Given I preview a comment text like "Bug fixed :smile:" - Then I should see the comment edit button - - @javascript - Scenario: I have a reset form after posting from preview - Given I preview a comment text like "Bug fixed :smile:" - And I submit the comment - Then I should see an empty comment text field - And I should not see the comment preview - - @javascript - Scenario: I can delete a comment - Given I leave a comment like "XML attached" - And I delete a comment - Then I should not see a comment saying "XML attached" diff --git a/features/project/commits/commit_diff_comments.feature b/features/project/commits/commit_diff_comments.feature deleted file mode 100644 index b26019f832f..00000000000 --- a/features/project/commits/commit_diff_comments.feature +++ /dev/null @@ -1,85 +0,0 @@ -Feature: Comments on commit diffs - Background: - Given I sign in as a user - And I own project "Shop" - And I visit project commit page - - @javascript - Scenario: I can access add diff comment buttons - Then I should see add a diff comment button - - @javascript - Scenario: I can comment on a commit diff - Given I leave a diff comment like "Typo, please fix" - Then I should see a diff comment saying "Typo, please fix" - - @javascript - Scenario: I get a temporary form for the first comment on a diff line - Given I open a diff comment form - Then I should see a temporary diff comment form - - @javascript - Scenario: I have a cancel button on the diff form - Given I open a diff comment form - Then I should see the cancel comment button - - @javascript - Scenario: I can cancel a diff form - Given I open a diff comment form - And I cancel the diff comment - Then I should not see the diff comment form - - @javascript - Scenario: I can't open a second form for a diff line - Given I open a diff comment form - And I open a diff comment form - Then I should only see one diff form - - @javascript - Scenario: I can have multiple forms - Given I open a diff comment form - And I write a diff comment like ":-1: I don't like this" - And I open another diff comment form - Then I should see a diff comment form with ":-1: I don't like this" - And I should see an empty diff comment form - - @javascript - Scenario: I can preview multiple forms separately - Given I preview a diff comment text like "Should fix it :smile:" - And I preview another diff comment text like "DRY this up" - Then I should see two separate previews - - @javascript - Scenario: I have a reply button in discussions - Given I leave a diff comment like "Typo, please fix" - Then I should see a discussion reply button - - @javascript - Scenario: I can't preview without text - Given I open a diff comment form - And I haven't written any diff comment text - Then I should not see the diff comment preview button - - @javascript - Scenario: I can preview with text - Given I open a diff comment form - And I write a diff comment like ":-1: I don't like this" - Then I should see the diff comment preview button - - @javascript - Scenario: I preview a diff comment - Given I preview a diff comment text like "Should fix it :smile:" - Then I should see the diff comment preview - And I should not see the diff comment text field - - @javascript - Scenario: I can edit after preview - Given I preview a diff comment text like "Should fix it :smile:" - Then I should see the diff comment edit button - - @javascript - Scenario: The form gets removed after posting - Given I preview a diff comment text like "Should fix it :smile:" - And I submit the diff comment - Then I should not see the diff comment form - And I should see a discussion reply button diff --git a/features/project/commits/commits_user_lookup.feature b/features/project/commits/commits_user_lookup.feature deleted file mode 100644 index f3864c0ab38..00000000000 --- a/features/project/commits/commits_user_lookup.feature +++ /dev/null @@ -1,14 +0,0 @@ -Feature: Project Browse Commits User Lookup - Background: - Given I sign in as a user - And I own a project - And I have the user that authored the commits - And I visit my project's commits page - - Scenario: I browse commit from list - Given I click on commit link - Then I see commit info - - Scenario: I browse another commit from list - Given I click on another commit link - Then I see other commit info \ No newline at end of file diff --git a/features/project/commits/diff_comments.feature b/features/project/commits/diff_comments.feature new file mode 100644 index 00000000000..b26019f832f --- /dev/null +++ b/features/project/commits/diff_comments.feature @@ -0,0 +1,85 @@ +Feature: Comments on commit diffs + Background: + Given I sign in as a user + And I own project "Shop" + And I visit project commit page + + @javascript + Scenario: I can access add diff comment buttons + Then I should see add a diff comment button + + @javascript + Scenario: I can comment on a commit diff + Given I leave a diff comment like "Typo, please fix" + Then I should see a diff comment saying "Typo, please fix" + + @javascript + Scenario: I get a temporary form for the first comment on a diff line + Given I open a diff comment form + Then I should see a temporary diff comment form + + @javascript + Scenario: I have a cancel button on the diff form + Given I open a diff comment form + Then I should see the cancel comment button + + @javascript + Scenario: I can cancel a diff form + Given I open a diff comment form + And I cancel the diff comment + Then I should not see the diff comment form + + @javascript + Scenario: I can't open a second form for a diff line + Given I open a diff comment form + And I open a diff comment form + Then I should only see one diff form + + @javascript + Scenario: I can have multiple forms + Given I open a diff comment form + And I write a diff comment like ":-1: I don't like this" + And I open another diff comment form + Then I should see a diff comment form with ":-1: I don't like this" + And I should see an empty diff comment form + + @javascript + Scenario: I can preview multiple forms separately + Given I preview a diff comment text like "Should fix it :smile:" + And I preview another diff comment text like "DRY this up" + Then I should see two separate previews + + @javascript + Scenario: I have a reply button in discussions + Given I leave a diff comment like "Typo, please fix" + Then I should see a discussion reply button + + @javascript + Scenario: I can't preview without text + Given I open a diff comment form + And I haven't written any diff comment text + Then I should not see the diff comment preview button + + @javascript + Scenario: I can preview with text + Given I open a diff comment form + And I write a diff comment like ":-1: I don't like this" + Then I should see the diff comment preview button + + @javascript + Scenario: I preview a diff comment + Given I preview a diff comment text like "Should fix it :smile:" + Then I should see the diff comment preview + And I should not see the diff comment text field + + @javascript + Scenario: I can edit after preview + Given I preview a diff comment text like "Should fix it :smile:" + Then I should see the diff comment edit button + + @javascript + Scenario: The form gets removed after posting + Given I preview a diff comment text like "Should fix it :smile:" + And I submit the diff comment + Then I should not see the diff comment form + And I should see a discussion reply button diff --git a/features/project/commits/user_lookup.feature b/features/project/commits/user_lookup.feature new file mode 100644 index 00000000000..f3864c0ab38 --- /dev/null +++ b/features/project/commits/user_lookup.feature @@ -0,0 +1,14 @@ +Feature: Project Browse Commits User Lookup + Background: + Given I sign in as a user + And I own a project + And I have the user that authored the commits + And I visit my project's commits page + + Scenario: I browse commit from list + Given I click on commit link + Then I see commit info + + Scenario: I browse another commit from list + Given I click on another commit link + Then I see other commit info \ No newline at end of file diff --git a/features/project/create.feature b/features/project/create.feature new file mode 100644 index 00000000000..395a3218b2b --- /dev/null +++ b/features/project/create.feature @@ -0,0 +1,22 @@ +Feature: Create Project + In order to get access to project sections + A user with ability to create a project + Should be able to create a new one + + Scenario: User create a project + Given I sign in as a user + When I visit new project page + And fill project form with valid data + Then I should see project page + And I should see empty project instuctions + + @javascript + Scenario: Empty project instructions + Given I sign in as a user + When I visit new project page + And fill project form with valid data + Then I see empty project instuctions + And I click on HTTP + Then Remote url should update to http link + And If I click on SSH + Then Remote url should update to ssh link \ No newline at end of file diff --git a/features/project/create_project.feature b/features/project/create_project.feature deleted file mode 100644 index 395a3218b2b..00000000000 --- a/features/project/create_project.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: Create Project - In order to get access to project sections - A user with ability to create a project - Should be able to create a new one - - Scenario: User create a project - Given I sign in as a user - When I visit new project page - And fill project form with valid data - Then I should see project page - And I should see empty project instuctions - - @javascript - Scenario: Empty project instructions - Given I sign in as a user - When I visit new project page - And fill project form with valid data - Then I see empty project instuctions - And I click on HTTP - Then Remote url should update to http link - And If I click on SSH - Then Remote url should update to ssh link \ No newline at end of file diff --git a/features/project/fork.feature b/features/project/fork.feature new file mode 100644 index 00000000000..dc477ca3bf3 --- /dev/null +++ b/features/project/fork.feature @@ -0,0 +1,14 @@ +Feature: Fork Project + Background: + Given I sign in as a user + And I am a member of project "Shop" + When I visit project "Shop" page + + Scenario: User fork a project + Given I click link "Fork" + Then I should see the forked project page + + Scenario: User already has forked the project + Given I already have a project named "Shop" in my namespace + And I click link "Fork" + Then I should see a "Name has already been taken" warning diff --git a/features/project/fork_project.feature b/features/project/fork_project.feature deleted file mode 100644 index dc477ca3bf3..00000000000 --- a/features/project/fork_project.feature +++ /dev/null @@ -1,14 +0,0 @@ -Feature: Fork Project - Background: - Given I sign in as a user - And I am a member of project "Shop" - When I visit project "Shop" page - - Scenario: User fork a project - Given I click link "Fork" - Then I should see the forked project page - - Scenario: User already has forked the project - Given I already have a project named "Shop" in my namespace - And I click link "Fork" - Then I should see a "Name has already been taken" warning diff --git a/features/project/public.feature b/features/project/public.feature new file mode 100644 index 00000000000..c5a9da14c54 --- /dev/null +++ b/features/project/public.feature @@ -0,0 +1,8 @@ +Feature: Public Projects + Background: + Given I sign in as a user + + Scenario: I should see the list of public projects + When I visit the public projects area + Then I should see the list of public projects + diff --git a/features/project/public_projects.feature b/features/project/public_projects.feature deleted file mode 100644 index c5a9da14c54..00000000000 --- a/features/project/public_projects.feature +++ /dev/null @@ -1,8 +0,0 @@ -Feature: Public Projects - Background: - Given I sign in as a user - - Scenario: I should see the list of public projects - When I visit the public projects area - Then I should see the list of public projects - diff --git a/features/public/projects.feature b/features/public/projects.feature new file mode 100644 index 00000000000..57fe834b4bf --- /dev/null +++ b/features/public/projects.feature @@ -0,0 +1,101 @@ +Feature: Public Projects Feature + Background: + Given public project "Community" + And internal project "Internal" + And private project "Enterprise" + + Scenario: I visit public area + When I visit the public projects area + Then I should see project "Community" + And I should not see project "Internal" + And I should not see project "Enterprise" + + Scenario: I visit public project page + When I visit project "Community" page + Then I should see project "Community" home page + + Scenario: I visit internal project page + When I visit project "Internal" page + Then I should be redirected to sign in page + + Scenario: I visit private project page + When I visit project "Enterprise" page + Then I should be redirected to sign in page + + Scenario: I visit an empty public project page + Given public empty project "Empty Public Project" + When I visit empty project page + Then I should see empty public project details + And I should see empty public project details with http clone info + + Scenario: I visit an empty public project page as user + Given I sign in as a user + And public empty project "Empty Public Project" + When I visit empty project page + Then I should see empty public project details + And I should see empty public project details with ssh clone info + + Scenario: I visit public area as user + Given I sign in as a user + When I visit the public projects area + Then I should see project "Community" + And I should see project "Internal" + And I should not see project "Enterprise" + + Scenario: I visit internal project page as user + Given I sign in as a user + When I visit project "Internal" page + Then I should see project "Internal" home page + + Scenario: I visit public project page + When I visit project "Community" page + Then I should see project "Community" home page + And I should see an http link to the repository + + Scenario: I visit public project page as user + Given I sign in as a user + When I visit project "Community" page + Then I should see project "Community" home page + And I should see an ssh link to the repository + + Scenario: I visit an empty public project page + Given public empty project "Empty Public Project" + When I visit empty project page + Then I should see empty public project details + + Scenario: I visit public project issues page as a non authorized user + Given I visit project "Community" page + And I visit "Community" issues page + Then I should see list of issues for "Community" project + + Scenario: I visit public project issues page as authorized user + Given I sign in as a user + Given I visit project "Community" page + And I visit "Community" issues page + Then I should see list of issues for "Community" project + + Scenario: I visit internal project issues page as authorized user + Given I sign in as a user + Given I visit project "Internal" page + And I visit "Internal" issues page + Then I should see list of issues for "Internal" project + + Scenario: I visit public project merge requests page as an authorized user + Given I sign in as a user + Given I visit project "Community" page + And I visit "Community" merge requests page + And project "Community" has "Bug fix" open merge request + Then I should see list of merge requests for "Community" project + + Scenario: I visit public project merge requests page as a non authorized user + Given I visit project "Community" page + And I visit "Community" merge requests page + And project "Community" has "Bug fix" open merge request + Then I should see list of merge requests for "Community" project + + Scenario: I visit internal project merge requests page as an authorized user + Given I sign in as a user + Given I visit project "Internal" page + And I visit "Internal" merge requests page + And project "Internal" has "Feature implemented" open merge request + Then I should see list of merge requests for "Internal" project diff --git a/features/public/public_projects.feature b/features/public/public_projects.feature deleted file mode 100644 index 57fe834b4bf..00000000000 --- a/features/public/public_projects.feature +++ /dev/null @@ -1,101 +0,0 @@ -Feature: Public Projects Feature - Background: - Given public project "Community" - And internal project "Internal" - And private project "Enterprise" - - Scenario: I visit public area - When I visit the public projects area - Then I should see project "Community" - And I should not see project "Internal" - And I should not see project "Enterprise" - - Scenario: I visit public project page - When I visit project "Community" page - Then I should see project "Community" home page - - Scenario: I visit internal project page - When I visit project "Internal" page - Then I should be redirected to sign in page - - Scenario: I visit private project page - When I visit project "Enterprise" page - Then I should be redirected to sign in page - - Scenario: I visit an empty public project page - Given public empty project "Empty Public Project" - When I visit empty project page - Then I should see empty public project details - And I should see empty public project details with http clone info - - Scenario: I visit an empty public project page as user - Given I sign in as a user - And public empty project "Empty Public Project" - When I visit empty project page - Then I should see empty public project details - And I should see empty public project details with ssh clone info - - Scenario: I visit public area as user - Given I sign in as a user - When I visit the public projects area - Then I should see project "Community" - And I should see project "Internal" - And I should not see project "Enterprise" - - Scenario: I visit internal project page as user - Given I sign in as a user - When I visit project "Internal" page - Then I should see project "Internal" home page - - Scenario: I visit public project page - When I visit project "Community" page - Then I should see project "Community" home page - And I should see an http link to the repository - - Scenario: I visit public project page as user - Given I sign in as a user - When I visit project "Community" page - Then I should see project "Community" home page - And I should see an ssh link to the repository - - Scenario: I visit an empty public project page - Given public empty project "Empty Public Project" - When I visit empty project page - Then I should see empty public project details - - Scenario: I visit public project issues page as a non authorized user - Given I visit project "Community" page - And I visit "Community" issues page - Then I should see list of issues for "Community" project - - Scenario: I visit public project issues page as authorized user - Given I sign in as a user - Given I visit project "Community" page - And I visit "Community" issues page - Then I should see list of issues for "Community" project - - Scenario: I visit internal project issues page as authorized user - Given I sign in as a user - Given I visit project "Internal" page - And I visit "Internal" issues page - Then I should see list of issues for "Internal" project - - Scenario: I visit public project merge requests page as an authorized user - Given I sign in as a user - Given I visit project "Community" page - And I visit "Community" merge requests page - And project "Community" has "Bug fix" open merge request - Then I should see list of merge requests for "Community" project - - Scenario: I visit public project merge requests page as a non authorized user - Given I visit project "Community" page - And I visit "Community" merge requests page - And project "Community" has "Bug fix" open merge request - Then I should see list of merge requests for "Community" project - - Scenario: I visit internal project merge requests page as an authorized user - Given I sign in as a user - Given I visit project "Internal" page - And I visit "Internal" merge requests page - And project "Internal" has "Feature implemented" open merge request - Then I should see list of merge requests for "Internal" project diff --git a/features/snippets/discover.feature b/features/snippets/discover.feature new file mode 100644 index 00000000000..d6fd2cd7808 --- /dev/null +++ b/features/snippets/discover.feature @@ -0,0 +1,10 @@ +Feature: Discover Snippets + Background: + Given I sign in as a user + And I have public "Personal snippet one" snippet + And I have private "Personal snippet private" snippet + + Scenario: I should see snippets + Given I visit snippets page + Then I should see "Personal snippet one" in snippets + And I should not see "Personal snippet private" in snippets diff --git a/features/snippets/discover_snippets.feature b/features/snippets/discover_snippets.feature deleted file mode 100644 index d6fd2cd7808..00000000000 --- a/features/snippets/discover_snippets.feature +++ /dev/null @@ -1,10 +0,0 @@ -Feature: Discover Snippets - Background: - Given I sign in as a user - And I have public "Personal snippet one" snippet - And I have private "Personal snippet private" snippet - - Scenario: I should see snippets - Given I visit snippets page - Then I should see "Personal snippet one" in snippets - And I should not see "Personal snippet private" in snippets diff --git a/features/snippets/user.feature b/features/snippets/user.feature new file mode 100644 index 00000000000..4c8a91501c4 --- /dev/null +++ b/features/snippets/user.feature @@ -0,0 +1,22 @@ +Feature: User Snippets + Background: + Given I sign in as a user + And I have public "Personal snippet one" snippet + And I have private "Personal snippet private" snippet + + Scenario: I should see all my snippets + Given I visit my snippets page + Then I should see "Personal snippet one" in snippets + And I should see "Personal snippet private" in snippets + + Scenario: I can see only my private snippets + Given I visit my snippets page + And I click "Private" filter + Then I should not see "Personal snippet one" in snippets + And I should see "Personal snippet private" in snippets + + Scenario: I can see only my public snippets + Given I visit my snippets page + And I click "Public" filter + Then I should see "Personal snippet one" in snippets + And I should not see "Personal snippet private" in snippets diff --git a/features/snippets/user_snippets.feature b/features/snippets/user_snippets.feature deleted file mode 100644 index 4c8a91501c4..00000000000 --- a/features/snippets/user_snippets.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: User Snippets - Background: - Given I sign in as a user - And I have public "Personal snippet one" snippet - And I have private "Personal snippet private" snippet - - Scenario: I should see all my snippets - Given I visit my snippets page - Then I should see "Personal snippet one" in snippets - And I should see "Personal snippet private" in snippets - - Scenario: I can see only my private snippets - Given I visit my snippets page - And I click "Private" filter - Then I should not see "Personal snippet one" in snippets - And I should see "Personal snippet private" in snippets - - Scenario: I can see only my public snippets - Given I visit my snippets page - And I click "Public" filter - Then I should see "Personal snippet one" in snippets - And I should not see "Personal snippet private" in snippets diff --git a/features/steps/admin/active_tab.rb b/features/steps/admin/active_tab.rb new file mode 100644 index 00000000000..ccafe09c18f --- /dev/null +++ b/features/steps/admin/active_tab.rb @@ -0,0 +1,37 @@ +class AdminActiveTab < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedActiveTab + + Then 'the active main tab should be Home' do + ensure_active_main_tab('Home') + end + + Then 'the active main tab should be Projects' do + ensure_active_main_tab('Projects') + end + + Then 'the active main tab should be Groups' do + ensure_active_main_tab('Groups') + end + + Then 'the active main tab should be Users' do + ensure_active_main_tab('Users') + end + + Then 'the active main tab should be Logs' do + ensure_active_main_tab('Logs') + end + + Then 'the active main tab should be Hooks' do + ensure_active_main_tab('Hooks') + end + + Then 'the active main tab should be Resque' do + ensure_active_main_tab('Background Jobs') + end + + Then 'the active main tab should be Messages' do + ensure_active_main_tab('Messages') + end +end diff --git a/features/steps/admin/admin_active_tab.rb b/features/steps/admin/admin_active_tab.rb deleted file mode 100644 index ccafe09c18f..00000000000 --- a/features/steps/admin/admin_active_tab.rb +++ /dev/null @@ -1,37 +0,0 @@ -class AdminActiveTab < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedActiveTab - - Then 'the active main tab should be Home' do - ensure_active_main_tab('Home') - end - - Then 'the active main tab should be Projects' do - ensure_active_main_tab('Projects') - end - - Then 'the active main tab should be Groups' do - ensure_active_main_tab('Groups') - end - - Then 'the active main tab should be Users' do - ensure_active_main_tab('Users') - end - - Then 'the active main tab should be Logs' do - ensure_active_main_tab('Logs') - end - - Then 'the active main tab should be Hooks' do - ensure_active_main_tab('Hooks') - end - - Then 'the active main tab should be Resque' do - ensure_active_main_tab('Background Jobs') - end - - Then 'the active main tab should be Messages' do - ensure_active_main_tab('Messages') - end -end diff --git a/features/steps/admin/admin_broadcast_messages.rb b/features/steps/admin/admin_broadcast_messages.rb deleted file mode 100644 index a35fa34a3a2..00000000000 --- a/features/steps/admin/admin_broadcast_messages.rb +++ /dev/null @@ -1,41 +0,0 @@ -class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - step 'application already has admin messages' do - FactoryGirl.create(:broadcast_message, message: "Migration to new server") - end - - step 'I should be all broadcast messages' do - page.should have_content "Migration to new server" - end - - step 'submit form with new broadcast message' do - fill_in 'broadcast_message_message', with: 'Application update from 4:00 CST to 5:00 CST' - select '2018', from: "broadcast_message_ends_at_1i" - click_button "Add broadcast message" - end - - step 'I should be redirected to admin messages page' do - current_path.should == admin_broadcast_messages_path - end - - step 'I should see newly created broadcast message' do - page.should have_content 'Application update from 4:00 CST to 5:00 CST' - end - - step 'submit form with new customized broadcast message' do - fill_in 'broadcast_message_message', with: 'Application update from 4:00 CST to 5:00 CST' - click_link "Customize colors" - fill_in 'broadcast_message_color', with: '#f2dede' - fill_in 'broadcast_message_font', with: '#b94a48' - select '2018', from: "broadcast_message_ends_at_1i" - click_button "Add broadcast message" - end - - step 'I should see a customized broadcast message' do - page.should have_content 'Application update from 4:00 CST to 5:00 CST' - page.should have_selector %(div[style="background-color:#f2dede;color:#b94a48"]) - end -end diff --git a/features/steps/admin/admin_groups.rb b/features/steps/admin/admin_groups.rb deleted file mode 100644 index 9c1bcfefb9c..00000000000 --- a/features/steps/admin/admin_groups.rb +++ /dev/null @@ -1,66 +0,0 @@ -class AdminGroups < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedUser - include SharedActiveTab - include Select2Helper - - When 'I visit admin group page' do - visit admin_group_path(current_group) - end - - When 'I click new group link' do - click_link "New Group" - end - - And 'I have group with projects' do - @group = create(:group) - @project = create(:project, group: @group) - @event = create(:closed_issue_event, project: @project) - - @project.team << [current_user, :master] - end - - And 'submit form with new group info' do - fill_in 'group_name', with: 'gitlab' - fill_in 'group_description', with: 'Group description' - click_button "Create group" - end - - Then 'I should see newly created group' do - page.should have_content "Group: gitlab" - page.should have_content "Group description" - end - - Then 'I should be redirected to group page' do - current_path.should == admin_group_path(Group.last) - end - - When 'I select user "John Doe" from user list as "Reporter"' do - user = User.find_by(name: "John Doe") - select2(user.id, from: "#user_ids", multiple: true) - within "#new_team_member" do - select "Reporter", from: "group_access" - end - click_button "Add users into group" - end - - Then 'I should see "John Doe" in team list in every project as "Reporter"' do - within ".group-users-list" do - page.should have_content "John Doe" - page.should have_content "Reporter" - end - end - - step 'I should be all groups' do - Group.all.each do |group| - page.should have_content group.name - end - end - - protected - - def current_group - @group ||= Group.first - end -end diff --git a/features/steps/admin/admin_logs.rb b/features/steps/admin/admin_logs.rb deleted file mode 100644 index 83958545c4d..00000000000 --- a/features/steps/admin/admin_logs.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AdminLogs < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - Then 'I should see tabs with available logs' do - page.should have_content 'production.log' - page.should have_content 'githost.log' - page.should have_content 'application.log' - end -end diff --git a/features/steps/admin/admin_projects.rb b/features/steps/admin/admin_projects.rb deleted file mode 100644 index b410b23851b..00000000000 --- a/features/steps/admin/admin_projects.rb +++ /dev/null @@ -1,22 +0,0 @@ -class AdminProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - And 'I should see all projects' do - Project.all.each do |p| - page.should have_content p.name_with_namespace - end - end - - And 'I click on first project' do - click_link Project.first.name_with_namespace - end - - Then 'I should see project details' do - project = Project.first - current_path.should == admin_project_path(project) - page.should have_content(project.name_with_namespace) - page.should have_content(project.creator.name) - end -end diff --git a/features/steps/admin/admin_users.rb b/features/steps/admin/admin_users.rb deleted file mode 100644 index 33c1344eaeb..00000000000 --- a/features/steps/admin/admin_users.rb +++ /dev/null @@ -1,34 +0,0 @@ -class AdminUsers < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - Then 'I should see all users' do - User.all.each do |user| - page.should have_content user.name - end - end - - And 'Click edit' do - @user = User.first - find("#edit_user_#{@user.id}").click - end - - And 'Input non ascii char in username' do - fill_in 'user_username', with: "\u3042\u3044" - end - - And 'Click save' do - click_button("Save") - end - - Then 'See username error message' do - within "#error_explanation" do - page.should have_content "Username" - end - end - - And 'Not changed form action url' do - page.should have_selector %(form[action="/admin/users/#{@user.username}"]) - end -end diff --git a/features/steps/admin/broadcast_messages.rb b/features/steps/admin/broadcast_messages.rb new file mode 100644 index 00000000000..a35fa34a3a2 --- /dev/null +++ b/features/steps/admin/broadcast_messages.rb @@ -0,0 +1,41 @@ +class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedAdmin + + step 'application already has admin messages' do + FactoryGirl.create(:broadcast_message, message: "Migration to new server") + end + + step 'I should be all broadcast messages' do + page.should have_content "Migration to new server" + end + + step 'submit form with new broadcast message' do + fill_in 'broadcast_message_message', with: 'Application update from 4:00 CST to 5:00 CST' + select '2018', from: "broadcast_message_ends_at_1i" + click_button "Add broadcast message" + end + + step 'I should be redirected to admin messages page' do + current_path.should == admin_broadcast_messages_path + end + + step 'I should see newly created broadcast message' do + page.should have_content 'Application update from 4:00 CST to 5:00 CST' + end + + step 'submit form with new customized broadcast message' do + fill_in 'broadcast_message_message', with: 'Application update from 4:00 CST to 5:00 CST' + click_link "Customize colors" + fill_in 'broadcast_message_color', with: '#f2dede' + fill_in 'broadcast_message_font', with: '#b94a48' + select '2018', from: "broadcast_message_ends_at_1i" + click_button "Add broadcast message" + end + + step 'I should see a customized broadcast message' do + page.should have_content 'Application update from 4:00 CST to 5:00 CST' + page.should have_selector %(div[style="background-color:#f2dede;color:#b94a48"]) + end +end diff --git a/features/steps/admin/groups.rb b/features/steps/admin/groups.rb new file mode 100644 index 00000000000..9c1bcfefb9c --- /dev/null +++ b/features/steps/admin/groups.rb @@ -0,0 +1,66 @@ +class AdminGroups < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedUser + include SharedActiveTab + include Select2Helper + + When 'I visit admin group page' do + visit admin_group_path(current_group) + end + + When 'I click new group link' do + click_link "New Group" + end + + And 'I have group with projects' do + @group = create(:group) + @project = create(:project, group: @group) + @event = create(:closed_issue_event, project: @project) + + @project.team << [current_user, :master] + end + + And 'submit form with new group info' do + fill_in 'group_name', with: 'gitlab' + fill_in 'group_description', with: 'Group description' + click_button "Create group" + end + + Then 'I should see newly created group' do + page.should have_content "Group: gitlab" + page.should have_content "Group description" + end + + Then 'I should be redirected to group page' do + current_path.should == admin_group_path(Group.last) + end + + When 'I select user "John Doe" from user list as "Reporter"' do + user = User.find_by(name: "John Doe") + select2(user.id, from: "#user_ids", multiple: true) + within "#new_team_member" do + select "Reporter", from: "group_access" + end + click_button "Add users into group" + end + + Then 'I should see "John Doe" in team list in every project as "Reporter"' do + within ".group-users-list" do + page.should have_content "John Doe" + page.should have_content "Reporter" + end + end + + step 'I should be all groups' do + Group.all.each do |group| + page.should have_content group.name + end + end + + protected + + def current_group + @group ||= Group.first + end +end diff --git a/features/steps/admin/logs.rb b/features/steps/admin/logs.rb new file mode 100644 index 00000000000..83958545c4d --- /dev/null +++ b/features/steps/admin/logs.rb @@ -0,0 +1,11 @@ +class AdminLogs < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedAdmin + + Then 'I should see tabs with available logs' do + page.should have_content 'production.log' + page.should have_content 'githost.log' + page.should have_content 'application.log' + end +end diff --git a/features/steps/admin/projects.rb b/features/steps/admin/projects.rb new file mode 100644 index 00000000000..b410b23851b --- /dev/null +++ b/features/steps/admin/projects.rb @@ -0,0 +1,22 @@ +class AdminProjects < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedAdmin + + And 'I should see all projects' do + Project.all.each do |p| + page.should have_content p.name_with_namespace + end + end + + And 'I click on first project' do + click_link Project.first.name_with_namespace + end + + Then 'I should see project details' do + project = Project.first + current_path.should == admin_project_path(project) + page.should have_content(project.name_with_namespace) + page.should have_content(project.creator.name) + end +end diff --git a/features/steps/admin/users.rb b/features/steps/admin/users.rb new file mode 100644 index 00000000000..33c1344eaeb --- /dev/null +++ b/features/steps/admin/users.rb @@ -0,0 +1,34 @@ +class AdminUsers < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedAdmin + + Then 'I should see all users' do + User.all.each do |user| + page.should have_content user.name + end + end + + And 'Click edit' do + @user = User.first + find("#edit_user_#{@user.id}").click + end + + And 'Input non ascii char in username' do + fill_in 'user_username', with: "\u3042\u3044" + end + + And 'Click save' do + click_button("Save") + end + + Then 'See username error message' do + within "#error_explanation" do + page.should have_content "Username" + end + end + + And 'Not changed form action url' do + page.should have_selector %(form[action="/admin/users/#{@user.username}"]) + end +end diff --git a/features/steps/dashboard/active_tab.rb b/features/steps/dashboard/active_tab.rb new file mode 100644 index 00000000000..8f5f0eed816 --- /dev/null +++ b/features/steps/dashboard/active_tab.rb @@ -0,0 +1,21 @@ +class DashboardActiveTab < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedActiveTab + + Then 'the active main tab should be Home' do + ensure_active_main_tab('Home') + end + + Then 'the active main tab should be Issues' do + ensure_active_main_tab('Issues') + end + + Then 'the active main tab should be Merge Requests' do + ensure_active_main_tab('Merge Requests') + end + + Then 'the active main tab should be Help' do + ensure_active_main_tab('Help') + end +end diff --git a/features/steps/dashboard/dashboard_active_tab.rb b/features/steps/dashboard/dashboard_active_tab.rb deleted file mode 100644 index 8f5f0eed816..00000000000 --- a/features/steps/dashboard/dashboard_active_tab.rb +++ /dev/null @@ -1,21 +0,0 @@ -class DashboardActiveTab < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedActiveTab - - Then 'the active main tab should be Home' do - ensure_active_main_tab('Home') - end - - Then 'the active main tab should be Issues' do - ensure_active_main_tab('Issues') - end - - Then 'the active main tab should be Merge Requests' do - ensure_active_main_tab('Merge Requests') - end - - Then 'the active main tab should be Help' do - ensure_active_main_tab('Help') - end -end diff --git a/features/steps/dashboard/dashboard_event_filters.rb b/features/steps/dashboard/dashboard_event_filters.rb deleted file mode 100644 index d0fe5c9b64b..00000000000 --- a/features/steps/dashboard/dashboard_event_filters.rb +++ /dev/null @@ -1,87 +0,0 @@ -class EventFilters < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - Then 'I should see push event' do - page.should have_selector('span.pushed') - end - - Then 'I should not see push event' do - page.should_not have_selector('span.pushed') - end - - Then 'I should see new member event' do - page.should have_selector('span.joined') - end - - And 'I should not see new member event' do - page.should_not have_selector('span.joined') - end - - Then 'I should see merge request event' do - page.should have_selector('span.accepted') - end - - And 'I should not see merge request event' do - page.should_not have_selector('span.accepted') - end - - And 'this project has push event' do - data = { - before: "0000000000000000000000000000000000000000", - after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e", - ref: "refs/heads/new_design", - user_id: @user.id, - user_name: @user.name, - repository: { - name: @project.name, - url: "localhost/rubinius", - description: "", - homepage: "localhost/rubinius", - private: true - } - } - - @event = Event.create( - project: @project, - action: Event::PUSHED, - data: data, - author_id: @user.id - ) - end - - And 'this project has new member event' do - user = create(:user, {name: "John Doe"}) - Event.create( - project: @project, - author_id: user.id, - action: Event::JOINED - ) - end - - And 'this project has merge request event' do - merge_request = create :merge_request, author: @user, source_project: @project, target_project: @project - Event.create( - project: @project, - action: Event::MERGED, - target_id: merge_request.id, - target_type: "MergeRequest", - author_id: @user.id - ) - end - - When 'I click "push" event filter' do - click_link("push_event_filter") - end - - When 'I click "team" event filter' do - click_link("team_event_filter") - end - - When 'I click "merge" event filter' do - click_link("merged_event_filter") - end - -end - diff --git a/features/steps/dashboard/dashboard_issues.rb b/features/steps/dashboard/dashboard_issues.rb deleted file mode 100644 index 1344edfa80b..00000000000 --- a/features/steps/dashboard/dashboard_issues.rb +++ /dev/null @@ -1,74 +0,0 @@ -class DashboardIssues < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - - step 'I should see issues assigned to me' do - should_see(assigned_issue) - should_not_see(authored_issue) - should_not_see(other_issue) - end - - step 'I should see issues authored by me' do - should_see(authored_issue) - should_not_see(assigned_issue) - should_not_see(other_issue) - end - - step 'I should see all issues' do - should_see(authored_issue) - should_see(assigned_issue) - should_see(other_issue) - end - - step 'I have authored issues' do - authored_issue - end - - step 'I have assigned issues' do - assigned_issue - end - - step 'I have other issues' do - other_issue - end - - step 'I click "Authored by me" link' do - within ".scope-filter" do - click_link 'Created by me' - end - end - - step 'I click "All" link' do - within ".scope-filter" do - click_link "Everyone's" - end - end - - def should_see(issue) - page.should have_content(issue.title[0..10]) - end - - def should_not_see(issue) - page.should_not have_content(issue.title[0..10]) - end - - def assigned_issue - @assigned_issue ||= create :issue, assignee: current_user, project: project - end - - def authored_issue - @authored_issue ||= create :issue, author: current_user, project: project - end - - def other_issue - @other_issue ||= create :issue, project: project - end - - def project - @project ||= begin - project =create :project - project.team << [current_user, :master] - project - end - end -end diff --git a/features/steps/dashboard/dashboard_merge_requests.rb b/features/steps/dashboard/dashboard_merge_requests.rb deleted file mode 100644 index 62d84506c49..00000000000 --- a/features/steps/dashboard/dashboard_merge_requests.rb +++ /dev/null @@ -1,74 +0,0 @@ -class DashboardMergeRequests < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - - step 'I should see merge requests assigned to me' do - should_see(assigned_merge_request) - should_not_see(authored_merge_request) - should_not_see(other_merge_request) - end - - step 'I should see merge requests authored by me' do - should_see(authored_merge_request) - should_not_see(assigned_merge_request) - should_not_see(other_merge_request) - end - - step 'I should see all merge requests' do - should_see(authored_merge_request) - should_see(assigned_merge_request) - should_see(other_merge_request) - end - - step 'I have authored merge requests' do - authored_merge_request - end - - step 'I have assigned merge requests' do - assigned_merge_request - end - - step 'I have other merge requests' do - other_merge_request - end - - step 'I click "Authored by me" link' do - within ".scope-filter" do - click_link 'Created by me' - end - end - - step 'I click "All" link' do - within ".scope-filter" do - click_link "Everyone's" - end - end - - def should_see(merge_request) - page.should have_content(merge_request.title[0..10]) - end - - def should_not_see(merge_request) - page.should_not have_content(merge_request.title[0..10]) - end - - def assigned_merge_request - @assigned_merge_request ||= create :merge_request, assignee: current_user, target_project: project - end - - def authored_merge_request - @authored_merge_request ||= create :merge_request, author: current_user, target_project: project - end - - def other_merge_request - @other_merge_request ||= create :merge_request, target_project: project - end - - def project - @project ||= begin - project =create :project - project.team << [current_user, :master] - project - end - end -end diff --git a/features/steps/dashboard/dashboard_projects.rb b/features/steps/dashboard/dashboard_projects.rb deleted file mode 100644 index 85251565446..00000000000 --- a/features/steps/dashboard/dashboard_projects.rb +++ /dev/null @@ -1,11 +0,0 @@ -class DashboardProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - Then 'I should see projects list' do - @user.authorized_projects.all.each do |project| - page.should have_link project.name_with_namespace - end - end -end diff --git a/features/steps/dashboard/dashboard_search.rb b/features/steps/dashboard/dashboard_search.rb deleted file mode 100644 index 32966a8617a..00000000000 --- a/features/steps/dashboard/dashboard_search.rb +++ /dev/null @@ -1,19 +0,0 @@ -class DashboardSearch < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - Given 'I search for "Sho"' do - fill_in "dashboard_search", with: "Sho" - click_button "Search" - end - - Then 'I should see "Shop" project link' do - page.should have_link "Shop" - end - - Given 'I search for "Contibuting"' do - fill_in "dashboard_search", with: "Contibuting" - click_button "Search" - end -end diff --git a/features/steps/dashboard/dashboard_with_archived_projects.rb b/features/steps/dashboard/dashboard_with_archived_projects.rb deleted file mode 100644 index 1bc69555b56..00000000000 --- a/features/steps/dashboard/dashboard_with_archived_projects.rb +++ /dev/null @@ -1,22 +0,0 @@ -class DashboardWithArchivedProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - When 'project "Forum" is archived' do - project = Project.find_by(name: "Forum") - project.update_attribute(:archived, true) - end - - Then 'I should see "Shop" project link' do - page.should have_link "Shop" - end - - Then 'I should not see "Forum" project link' do - page.should_not have_link "Forum" - end - - Then 'I should see "Forum" project link' do - page.should have_link "Forum" - end -end diff --git a/features/steps/dashboard/event_filters.rb b/features/steps/dashboard/event_filters.rb new file mode 100644 index 00000000000..d0fe5c9b64b --- /dev/null +++ b/features/steps/dashboard/event_filters.rb @@ -0,0 +1,87 @@ +class EventFilters < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + Then 'I should see push event' do + page.should have_selector('span.pushed') + end + + Then 'I should not see push event' do + page.should_not have_selector('span.pushed') + end + + Then 'I should see new member event' do + page.should have_selector('span.joined') + end + + And 'I should not see new member event' do + page.should_not have_selector('span.joined') + end + + Then 'I should see merge request event' do + page.should have_selector('span.accepted') + end + + And 'I should not see merge request event' do + page.should_not have_selector('span.accepted') + end + + And 'this project has push event' do + data = { + before: "0000000000000000000000000000000000000000", + after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e", + ref: "refs/heads/new_design", + user_id: @user.id, + user_name: @user.name, + repository: { + name: @project.name, + url: "localhost/rubinius", + description: "", + homepage: "localhost/rubinius", + private: true + } + } + + @event = Event.create( + project: @project, + action: Event::PUSHED, + data: data, + author_id: @user.id + ) + end + + And 'this project has new member event' do + user = create(:user, {name: "John Doe"}) + Event.create( + project: @project, + author_id: user.id, + action: Event::JOINED + ) + end + + And 'this project has merge request event' do + merge_request = create :merge_request, author: @user, source_project: @project, target_project: @project + Event.create( + project: @project, + action: Event::MERGED, + target_id: merge_request.id, + target_type: "MergeRequest", + author_id: @user.id + ) + end + + When 'I click "push" event filter' do + click_link("push_event_filter") + end + + When 'I click "team" event filter' do + click_link("team_event_filter") + end + + When 'I click "merge" event filter' do + click_link("merged_event_filter") + end + +end + diff --git a/features/steps/dashboard/issues.rb b/features/steps/dashboard/issues.rb new file mode 100644 index 00000000000..1344edfa80b --- /dev/null +++ b/features/steps/dashboard/issues.rb @@ -0,0 +1,74 @@ +class DashboardIssues < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + + step 'I should see issues assigned to me' do + should_see(assigned_issue) + should_not_see(authored_issue) + should_not_see(other_issue) + end + + step 'I should see issues authored by me' do + should_see(authored_issue) + should_not_see(assigned_issue) + should_not_see(other_issue) + end + + step 'I should see all issues' do + should_see(authored_issue) + should_see(assigned_issue) + should_see(other_issue) + end + + step 'I have authored issues' do + authored_issue + end + + step 'I have assigned issues' do + assigned_issue + end + + step 'I have other issues' do + other_issue + end + + step 'I click "Authored by me" link' do + within ".scope-filter" do + click_link 'Created by me' + end + end + + step 'I click "All" link' do + within ".scope-filter" do + click_link "Everyone's" + end + end + + def should_see(issue) + page.should have_content(issue.title[0..10]) + end + + def should_not_see(issue) + page.should_not have_content(issue.title[0..10]) + end + + def assigned_issue + @assigned_issue ||= create :issue, assignee: current_user, project: project + end + + def authored_issue + @authored_issue ||= create :issue, author: current_user, project: project + end + + def other_issue + @other_issue ||= create :issue, project: project + end + + def project + @project ||= begin + project =create :project + project.team << [current_user, :master] + project + end + end +end diff --git a/features/steps/dashboard/merge_requests.rb b/features/steps/dashboard/merge_requests.rb new file mode 100644 index 00000000000..62d84506c49 --- /dev/null +++ b/features/steps/dashboard/merge_requests.rb @@ -0,0 +1,74 @@ +class DashboardMergeRequests < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + + step 'I should see merge requests assigned to me' do + should_see(assigned_merge_request) + should_not_see(authored_merge_request) + should_not_see(other_merge_request) + end + + step 'I should see merge requests authored by me' do + should_see(authored_merge_request) + should_not_see(assigned_merge_request) + should_not_see(other_merge_request) + end + + step 'I should see all merge requests' do + should_see(authored_merge_request) + should_see(assigned_merge_request) + should_see(other_merge_request) + end + + step 'I have authored merge requests' do + authored_merge_request + end + + step 'I have assigned merge requests' do + assigned_merge_request + end + + step 'I have other merge requests' do + other_merge_request + end + + step 'I click "Authored by me" link' do + within ".scope-filter" do + click_link 'Created by me' + end + end + + step 'I click "All" link' do + within ".scope-filter" do + click_link "Everyone's" + end + end + + def should_see(merge_request) + page.should have_content(merge_request.title[0..10]) + end + + def should_not_see(merge_request) + page.should_not have_content(merge_request.title[0..10]) + end + + def assigned_merge_request + @assigned_merge_request ||= create :merge_request, assignee: current_user, target_project: project + end + + def authored_merge_request + @authored_merge_request ||= create :merge_request, author: current_user, target_project: project + end + + def other_merge_request + @other_merge_request ||= create :merge_request, target_project: project + end + + def project + @project ||= begin + project =create :project + project.team << [current_user, :master] + project + end + end +end diff --git a/features/steps/dashboard/projects.rb b/features/steps/dashboard/projects.rb new file mode 100644 index 00000000000..85251565446 --- /dev/null +++ b/features/steps/dashboard/projects.rb @@ -0,0 +1,11 @@ +class DashboardProjects < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + Then 'I should see projects list' do + @user.authorized_projects.all.each do |project| + page.should have_link project.name_with_namespace + end + end +end diff --git a/features/steps/dashboard/search.rb b/features/steps/dashboard/search.rb new file mode 100644 index 00000000000..32966a8617a --- /dev/null +++ b/features/steps/dashboard/search.rb @@ -0,0 +1,19 @@ +class DashboardSearch < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + Given 'I search for "Sho"' do + fill_in "dashboard_search", with: "Sho" + click_button "Search" + end + + Then 'I should see "Shop" project link' do + page.should have_link "Shop" + end + + Given 'I search for "Contibuting"' do + fill_in "dashboard_search", with: "Contibuting" + click_button "Search" + end +end diff --git a/features/steps/dashboard/with_archived_projects.rb b/features/steps/dashboard/with_archived_projects.rb new file mode 100644 index 00000000000..1bc69555b56 --- /dev/null +++ b/features/steps/dashboard/with_archived_projects.rb @@ -0,0 +1,22 @@ +class DashboardWithArchivedProjects < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + When 'project "Forum" is archived' do + project = Project.find_by(name: "Forum") + project.update_attribute(:archived, true) + end + + Then 'I should see "Shop" project link' do + page.should have_link "Shop" + end + + Then 'I should not see "Forum" project link' do + page.should_not have_link "Forum" + end + + Then 'I should see "Forum" project link' do + page.should have_link "Forum" + end +end diff --git a/features/steps/profile/active_tab.rb b/features/steps/profile/active_tab.rb new file mode 100644 index 00000000000..ee9f5f201cf --- /dev/null +++ b/features/steps/profile/active_tab.rb @@ -0,0 +1,25 @@ +class ProfileActiveTab < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedActiveTab + + Then 'the active main tab should be Home' do + ensure_active_main_tab('Home') + end + + Then 'the active main tab should be Account' do + ensure_active_main_tab('Account') + end + + Then 'the active main tab should be SSH Keys' do + ensure_active_main_tab('SSH Keys') + end + + Then 'the active main tab should be Design' do + ensure_active_main_tab('Design') + end + + Then 'the active main tab should be History' do + ensure_active_main_tab('History') + end +end diff --git a/features/steps/profile/emails.rb b/features/steps/profile/emails.rb new file mode 100644 index 00000000000..99588c85991 --- /dev/null +++ b/features/steps/profile/emails.rb @@ -0,0 +1,48 @@ +class ProfileEmails < Spinach::FeatureSteps + include SharedAuthentication + + Then 'I visit profile emails page' do + visit profile_emails_path + end + + Then 'I should see my emails' do + page.should have_content(@user.email) + @user.emails.each do |email| + page.should have_content(email.email) + end + end + + And 'I submit new email "my@email.com"' do + fill_in "email_email", with: "my@email.com" + click_button "Add" + end + + Then 'I should see new email "my@email.com"' do + email = @user.emails.find_by(email: "my@email.com") + email.should_not be_nil + page.should have_content("my@email.com") + end + + Then 'I should not see email "my@email.com"' do + email = @user.emails.find_by(email: "my@email.com") + email.should be_nil + page.should_not have_content("my@email.com") + end + + Then 'I click link "Remove" for "my@email.com"' do + # there should only be one remove button at this time + click_link "Remove" + # force these to reload as they have been cached + @user.emails.reload + end + + And 'I submit duplicate email @user.email' do + fill_in "email_email", with: @user.email + click_button "Add" + end + + Then 'I should not have @user.email added' do + email = @user.emails.find_by(email: @user.email) + email.should be_nil + end +end diff --git a/features/steps/profile/notifications.rb b/features/steps/profile/notifications.rb new file mode 100644 index 00000000000..e884df3098e --- /dev/null +++ b/features/steps/profile/notifications.rb @@ -0,0 +1,12 @@ +class ProfileNotifications < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + + step 'I visit profile notifications page' do + visit profile_notifications_path + end + + step 'I should see global notifications settings' do + page.should have_content "Notifications settings" + end +end diff --git a/features/steps/profile/profile_active_tab.rb b/features/steps/profile/profile_active_tab.rb deleted file mode 100644 index ee9f5f201cf..00000000000 --- a/features/steps/profile/profile_active_tab.rb +++ /dev/null @@ -1,25 +0,0 @@ -class ProfileActiveTab < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedActiveTab - - Then 'the active main tab should be Home' do - ensure_active_main_tab('Home') - end - - Then 'the active main tab should be Account' do - ensure_active_main_tab('Account') - end - - Then 'the active main tab should be SSH Keys' do - ensure_active_main_tab('SSH Keys') - end - - Then 'the active main tab should be Design' do - ensure_active_main_tab('Design') - end - - Then 'the active main tab should be History' do - ensure_active_main_tab('History') - end -end diff --git a/features/steps/profile/profile_emails.rb b/features/steps/profile/profile_emails.rb deleted file mode 100644 index 99588c85991..00000000000 --- a/features/steps/profile/profile_emails.rb +++ /dev/null @@ -1,48 +0,0 @@ -class ProfileEmails < Spinach::FeatureSteps - include SharedAuthentication - - Then 'I visit profile emails page' do - visit profile_emails_path - end - - Then 'I should see my emails' do - page.should have_content(@user.email) - @user.emails.each do |email| - page.should have_content(email.email) - end - end - - And 'I submit new email "my@email.com"' do - fill_in "email_email", with: "my@email.com" - click_button "Add" - end - - Then 'I should see new email "my@email.com"' do - email = @user.emails.find_by(email: "my@email.com") - email.should_not be_nil - page.should have_content("my@email.com") - end - - Then 'I should not see email "my@email.com"' do - email = @user.emails.find_by(email: "my@email.com") - email.should be_nil - page.should_not have_content("my@email.com") - end - - Then 'I click link "Remove" for "my@email.com"' do - # there should only be one remove button at this time - click_link "Remove" - # force these to reload as they have been cached - @user.emails.reload - end - - And 'I submit duplicate email @user.email' do - fill_in "email_email", with: @user.email - click_button "Add" - end - - Then 'I should not have @user.email added' do - email = @user.emails.find_by(email: @user.email) - email.should be_nil - end -end diff --git a/features/steps/profile/profile_notifications.rb b/features/steps/profile/profile_notifications.rb deleted file mode 100644 index e884df3098e..00000000000 --- a/features/steps/profile/profile_notifications.rb +++ /dev/null @@ -1,12 +0,0 @@ -class ProfileNotifications < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - - step 'I visit profile notifications page' do - visit profile_notifications_path - end - - step 'I should see global notifications settings' do - page.should have_content "Notifications settings" - end -end diff --git a/features/steps/profile/profile_ssh_keys.rb b/features/steps/profile/profile_ssh_keys.rb deleted file mode 100644 index 65ca824bb5b..00000000000 --- a/features/steps/profile/profile_ssh_keys.rb +++ /dev/null @@ -1,48 +0,0 @@ -class ProfileSshKeys < Spinach::FeatureSteps - include SharedAuthentication - - Then 'I should see my ssh keys' do - @user.keys.each do |key| - page.should have_content(key.title) - end - end - - Given 'I click link "Add new"' do - click_link "Add SSH Key" - end - - And 'I submit new ssh key "Laptop"' do - fill_in "key_title", with: "Laptop" - fill_in "key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop" - click_button "Add key" - end - - Then 'I should see new ssh key "Laptop"' do - key = Key.find_by(title: "Laptop") - page.should have_content(key.title) - page.should have_content(key.key) - current_path.should == profile_key_path(key) - end - - Given 'I click link "Work"' do - click_link "Work" - end - - And 'I click link "Remove"' do - click_link "Remove" - end - - Then 'I visit profile keys page' do - visit profile_keys_path - end - - And 'I should not see "Work" ssh key' do - within "#keys-table" do - page.should_not have_content "Work" - end - end - - And 'I have ssh key "ssh-rsa Work"' do - create(:key, user: @user, title: "ssh-rsa Work", key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+L3TbFegm3k8QjejSwemk4HhlRh+DuN679Pc5ckqE/MPhVtE/+kZQDYCTB284GiT2aIoGzmZ8ee9TkaoejAsBwlA+Wz2Q3vhz65X6sMgalRwpdJx8kSEUYV8ZPV3MZvPo8KdNg993o4jL6G36GDW4BPIyO6FPZhfsawdf6liVD0Xo5kibIK7B9VoE178cdLQtLpS2YolRwf5yy6XR6hbbBGQR+6xrGOdP16eGZDb1CE2bMvvJijjloFqPscGktWOqW+nfh5txwFfBzlfARDTBsS8WZtg3Yoj1kn33kPsWRlgHfNutFRAIynDuDdQzQq8tTtVwm+Yi75RfcPHW8y3P Work") - end -end diff --git a/features/steps/profile/ssh_keys.rb b/features/steps/profile/ssh_keys.rb new file mode 100644 index 00000000000..65ca824bb5b --- /dev/null +++ b/features/steps/profile/ssh_keys.rb @@ -0,0 +1,48 @@ +class ProfileSshKeys < Spinach::FeatureSteps + include SharedAuthentication + + Then 'I should see my ssh keys' do + @user.keys.each do |key| + page.should have_content(key.title) + end + end + + Given 'I click link "Add new"' do + click_link "Add SSH Key" + end + + And 'I submit new ssh key "Laptop"' do + fill_in "key_title", with: "Laptop" + fill_in "key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop" + click_button "Add key" + end + + Then 'I should see new ssh key "Laptop"' do + key = Key.find_by(title: "Laptop") + page.should have_content(key.title) + page.should have_content(key.key) + current_path.should == profile_key_path(key) + end + + Given 'I click link "Work"' do + click_link "Work" + end + + And 'I click link "Remove"' do + click_link "Remove" + end + + Then 'I visit profile keys page' do + visit profile_keys_path + end + + And 'I should not see "Work" ssh key' do + within "#keys-table" do + page.should_not have_content "Work" + end + end + + And 'I have ssh key "ssh-rsa Work"' do + create(:key, user: @user, title: "ssh-rsa Work", key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+L3TbFegm3k8QjejSwemk4HhlRh+DuN679Pc5ckqE/MPhVtE/+kZQDYCTB284GiT2aIoGzmZ8ee9TkaoejAsBwlA+Wz2Q3vhz65X6sMgalRwpdJx8kSEUYV8ZPV3MZvPo8KdNg993o4jL6G36GDW4BPIyO6FPZhfsawdf6liVD0Xo5kibIK7B9VoE178cdLQtLpS2YolRwf5yy6XR6hbbBGQR+6xrGOdP16eGZDb1CE2bMvvJijjloFqPscGktWOqW+nfh5txwFfBzlfARDTBsS8WZtg3Yoj1kn33kPsWRlgHfNutFRAIynDuDdQzQq8tTtVwm+Yi75RfcPHW8y3P Work") + end +end diff --git a/features/steps/project/active_tab.rb b/features/steps/project/active_tab.rb new file mode 100644 index 00000000000..dcc252f4765 --- /dev/null +++ b/features/steps/project/active_tab.rb @@ -0,0 +1,140 @@ +class ProjectActiveTab < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + include SharedActiveTab + + # Main Tabs + + Then 'the active main tab should be Home' do + ensure_active_main_tab('Home') + end + + Then 'the active main tab should be Settings' do + ensure_active_main_tab('Settings') + end + + Then 'the active main tab should be Files' do + ensure_active_main_tab('Files') + end + + Then 'the active main tab should be Commits' do + ensure_active_main_tab('Commits') + end + + Then 'the active main tab should be Network' do + ensure_active_main_tab('Network') + end + + Then 'the active main tab should be Issues' do + ensure_active_main_tab('Issues') + end + + Then 'the active main tab should be Merge Requests' do + ensure_active_main_tab('Merge Requests') + end + + Then 'the active main tab should be Wall' do + ensure_active_main_tab('Wall') + end + + Then 'the active main tab should be Wiki' do + ensure_active_main_tab('Wiki') + end + + # Sub Tabs: Home + + Given 'I click the "Team" tab' do + click_link('Members') + end + + Given 'I click the "Attachments" tab' do + click_link('Attachments') + end + + Given 'I click the "Snippets" tab' do + click_link('Snippets') + end + + Given 'I click the "Edit" tab' do + within '.project-settings-nav' do + click_link('Project') + end + end + + Given 'I click the "Hooks" tab' do + click_link('Web Hooks') + end + + Given 'I click the "Deploy Keys" tab' do + click_link('Deploy Keys') + end + + Then 'the active sub nav should be Team' do + ensure_active_sub_nav('Members') + end + + Then 'the active sub nav should be Edit' do + ensure_active_sub_nav('Project') + end + + Then 'the active sub nav should be Hooks' do + ensure_active_sub_nav('Web Hooks') + end + + Then 'the active sub nav should be Deploy Keys' do + ensure_active_sub_nav('Deploy Keys') + end + + # Sub Tabs: Commits + + Given 'I click the "Compare" tab' do + click_link('Compare') + end + + Given 'I click the "Branches" tab' do + click_link('Branches') + end + + Given 'I click the "Tags" tab' do + click_link('Tags') + end + + Then 'the active sub tab should be Commits' do + ensure_active_sub_tab('Commits') + end + + Then 'the active sub tab should be Compare' do + ensure_active_sub_tab('Compare') + end + + Then 'the active sub tab should be Branches' do + ensure_active_sub_tab('Branches') + end + + Then 'the active sub tab should be Tags' do + ensure_active_sub_tab('Tags') + end + + # Sub Tabs: Issues + + Given 'I click the "Milestones" tab' do + click_link('Milestones') + end + + Given 'I click the "Labels" tab' do + click_link('Labels') + end + + Then 'the active sub tab should be Browse Issues' do + ensure_active_sub_tab('Browse Issues') + end + + Then 'the active sub tab should be Milestones' do + ensure_active_sub_tab('Milestones') + end + + Then 'the active sub tab should be Labels' do + ensure_active_sub_tab('Labels') + end +end diff --git a/features/steps/project/archived.rb b/features/steps/project/archived.rb new file mode 100644 index 00000000000..dfbe762c438 --- /dev/null +++ b/features/steps/project/archived.rb @@ -0,0 +1,37 @@ +class ProjectArchived < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + When 'project "Forum" is archived' do + project = Project.find_by(name: "Forum") + project.update_attribute(:archived, true) + end + + When 'project "Shop" is archived' do + project = Project.find_by(name: "Shop") + project.update_attribute(:archived, true) + end + + When 'I visit project "Forum" page' do + project = Project.find_by(name: "Forum") + visit project_path(project) + end + + Then 'I should not see "Archived"' do + page.should_not have_content "Archived" + end + + Then 'I should see "Archived"' do + page.should have_content "Archived" + end + + When 'I set project archived' do + click_link "Archive" + end + + When 'I set project unarchived' do + click_link "Unarchive" + end + +end \ No newline at end of file diff --git a/features/steps/project/browse_branches.rb b/features/steps/project/browse_branches.rb new file mode 100644 index 00000000000..ef29cc67a4e --- /dev/null +++ b/features/steps/project/browse_branches.rb @@ -0,0 +1,35 @@ +class ProjectBrowseBranches < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + Then 'I should see "Shop" recent branches list' do + page.should have_content "Branches" + page.should have_content "master" + end + + Given 'I click link "All"' do + click_link "All" + end + + Then 'I should see "Shop" all branches list' do + page.should have_content "Branches" + page.should have_content "master" + end + + Given 'I click link "Protected"' do + click_link "Protected" + end + + Then 'I should see "Shop" protected branches list' do + within ".protected-branches-list" do + page.should have_content "stable" + page.should_not have_content "master" + end + end + + And 'project "Shop" has protected branches' do + project = Project.find_by(name: "Shop") + project.protected_branches.create(name: "stable") + end +end diff --git a/features/steps/project/browse_commits.rb b/features/steps/project/browse_commits.rb new file mode 100644 index 00000000000..d667b58240f --- /dev/null +++ b/features/steps/project/browse_commits.rb @@ -0,0 +1,104 @@ +class ProjectBrowseCommits < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + Then 'I see project commits' do + commit = @project.repository.commit + page.should have_content(@project.name) + page.should have_content(commit.message) + page.should have_content(commit.id.to_s[0..5]) + end + + Given 'I click atom feed link' do + click_link "Feed" + end + + Then 'I see commits atom feed' do + commit = @project.repository.commit + page.response_headers['Content-Type'].should have_content("application/atom+xml") + page.body.should have_selector("title", text: "Recent commits to #{@project.name}") + page.body.should have_selector("author email", text: commit.author_email) + page.body.should have_selector("entry summary", text: commit.description) + end + + Given 'I click on commit link' do + visit project_commit_path(@project, ValidCommit::ID) + end + + Then 'I see commit info' do + page.should have_content ValidCommit::MESSAGE + page.should have_content "Showing 1 changed file" + end + + And 'I fill compare fields with refs' do + fill_in "from", with: "8716fc78f3c65bbf7bcf7b574febd583bc5d2812" + fill_in "to", with: "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" + click_button "Compare" + end + + Then 'I see compared refs' do + page.should have_content "Compare View" + page.should have_content "Commits (1)" + page.should have_content "Showing 2 changed files" + end + + Then 'I see breadcrumb links' do + page.should have_selector('ul.breadcrumb') + page.should have_selector('ul.breadcrumb span.divider', count: 3) + page.should have_selector('ul.breadcrumb a', count: 4) + + find('ul.breadcrumb li:nth-child(2) a')['href'].should match(/#{@project.path_with_namespace}\/commits\/master\z/) + find('ul.breadcrumb li:last a')['href'].should match(%r{master/app/models/project\.rb\z}) + end + + Then 'I see commits stats' do + page.should have_content 'Top 50 Committers' + page.should have_content 'Committers' + page.should have_content 'Total commits' + page.should have_content 'Authors' + end + + Given 'I visit big commit page' do + visit project_commit_path(@project, BigCommits::BIG_COMMIT_ID) + end + + Then 'I see big commit warning' do + page.should have_content BigCommits::BIG_COMMIT_MESSAGE + page.should have_content "Warning! This is a large diff" + page.should have_content "If you still want to see the diff" + end + + Given 'I visit huge commit page' do + visit project_commit_path(@project, BigCommits::HUGE_COMMIT_ID) + end + + Then 'I see huge commit message' do + page.should have_content BigCommits::HUGE_COMMIT_MESSAGE + page.should have_content "Warning! This is a large diff" + page.should_not have_content "If you still want to see the diff" + end + + Given 'I visit a commit with an image that changed' do + visit project_commit_path(@project, 'cc1ba255d6c5ffdce87a357ba7ccc397a4f4026b') + end + + Then 'The diff links to both the previous and current image' do + links = page.all('.two-up span div a') + links[0]['href'].should =~ %r{blob/bc3735004cb45cec5e0e4fa92710897a910a5957} + links[1]['href'].should =~ %r{blob/cc1ba255d6c5ffdce87a357ba7ccc397a4f4026b} + end + + Given 'I click side-by-side diff button' do + click_link "Side-by-side Diff" + end + + Then 'I see side-by-side diff button' do + page.should have_content "Side-by-side Diff" + end + + Then 'I see inline diff button' do + page.should have_content "Inline Diff" + end + +end diff --git a/features/steps/project/browse_commits_user_lookup.rb b/features/steps/project/browse_commits_user_lookup.rb new file mode 100644 index 00000000000..328be373553 --- /dev/null +++ b/features/steps/project/browse_commits_user_lookup.rb @@ -0,0 +1,35 @@ +class ProjectBrowseCommitsUserLookup < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + Given 'I have the user that authored the commits' do + @user = create(:user, email: 'dmitriy.zaporozhets@gmail.com') + create(:email, { user: @user, email: 'dzaporozhets@sphereconsultinginc.com' }) + end + + Given 'I click on commit link' do + visit project_commit_path(@project, ValidCommit::ID) + end + + Given 'I click on another commit link' do + visit project_commit_path(@project, ValidCommitWithAltEmail::ID) + end + + Then 'I see commit info' do + page.should have_content ValidCommit::MESSAGE + check_author_link(ValidCommit::AUTHOR_EMAIL) + end + + Then 'I see other commit info' do + page.should have_content ValidCommitWithAltEmail::MESSAGE + check_author_link(ValidCommitWithAltEmail::AUTHOR_EMAIL) + end + + def check_author_link(email) + author_link = find('.commit-author-link') + author_link['href'].should == user_path(@user) + author_link['data-original-title'].should == email + find('.commit-author-name').text.should == @user.name + end +end diff --git a/features/steps/project/browse_files.rb b/features/steps/project/browse_files.rb new file mode 100644 index 00000000000..069086d5eac --- /dev/null +++ b/features/steps/project/browse_files.rb @@ -0,0 +1,53 @@ +class ProjectBrowseFiles < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I should see files from repository' do + page.should have_content "app" + page.should have_content "history" + page.should have_content "Gemfile" + end + + step 'I should see files from repository for "8470d70"' do + current_path.should == project_tree_path(@project, "8470d70") + page.should have_content "app" + page.should have_content "history" + page.should have_content "Gemfile" + end + + step 'I click on "Gemfile.lock" file in repo' do + click_link "Gemfile.lock" + end + + step 'I should see it content' do + page.should have_content "DEPENDENCIES" + end + + step 'I click link "raw"' do + click_link "raw" + end + + step 'I should see raw file content' do + page.source.should == ValidCommit::BLOB_FILE + end + + step 'I click button "edit"' do + click_link 'edit' + end + + step 'I can edit code' do + page.execute_script('editor.setValue("GitlabFileEditor")') + page.evaluate_script('editor.getValue()').should == "GitlabFileEditor" + end + + step 'I click on "new file" link in repo' do + click_link 'new-file-link' + end + + step 'I can see new file page' do + page.should have_content "New file" + page.should have_content "File name" + page.should have_content "Commit message" + end +end diff --git a/features/steps/project/browse_git_repo.rb b/features/steps/project/browse_git_repo.rb new file mode 100644 index 00000000000..cd9a60f49cb --- /dev/null +++ b/features/steps/project/browse_git_repo.rb @@ -0,0 +1,19 @@ +class ProjectBrowseGitRepo < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + Given 'I click on "Gemfile.lock" file in repo' do + click_link "Gemfile.lock" + end + + And 'I click blame button' do + click_link "blame" + end + + Then 'I should see git file blame' do + page.should have_content "DEPENDENCIES" + page.should have_content "Dmitriy Zaporozhets" + page.should have_content "Moving to rails 3.2" + end +end diff --git a/features/steps/project/browse_tags.rb b/features/steps/project/browse_tags.rb new file mode 100644 index 00000000000..0cbfa0d80aa --- /dev/null +++ b/features/steps/project/browse_tags.rb @@ -0,0 +1,10 @@ +class ProjectBrowseTags < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + Then 'I should see "Shop" all tags list' do + page.should have_content "Tags" + page.should have_content "v1.2.1" + end +end diff --git a/features/steps/project/create.rb b/features/steps/project/create.rb new file mode 100644 index 00000000000..b59345e7078 --- /dev/null +++ b/features/steps/project/create.rb @@ -0,0 +1,42 @@ +class CreateProject < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + + And 'fill project form with valid data' do + fill_in 'project_name', with: 'Empty' + click_button "Create project" + end + + Then 'I should see project page' do + current_path.should == project_path(Project.last) + page.should have_content "Empty" + end + + And 'I should see empty project instuctions' do + page.should have_content "git init" + page.should have_content "git remote" + page.should have_content Project.last.url_to_repo + end + + Then 'I see empty project instuctions' do + page.should have_content "git init" + page.should have_content "git remote" + page.should have_content Project.last.url_to_repo + end + + And 'I click on HTTP' do + click_button 'HTTP' + end + + Then 'Remote url should update to http link' do + page.should have_content "git remote add origin #{Project.last.http_url_to_repo}" + end + + And 'If I click on SSH' do + click_button 'SSH' + end + + Then 'Remote url should update to ssh link' do + page.should have_content "git remote add origin #{Project.last.url_to_repo}" + end +end diff --git a/features/steps/project/create_project.rb b/features/steps/project/create_project.rb deleted file mode 100644 index b59345e7078..00000000000 --- a/features/steps/project/create_project.rb +++ /dev/null @@ -1,42 +0,0 @@ -class CreateProject < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - - And 'fill project form with valid data' do - fill_in 'project_name', with: 'Empty' - click_button "Create project" - end - - Then 'I should see project page' do - current_path.should == project_path(Project.last) - page.should have_content "Empty" - end - - And 'I should see empty project instuctions' do - page.should have_content "git init" - page.should have_content "git remote" - page.should have_content Project.last.url_to_repo - end - - Then 'I see empty project instuctions' do - page.should have_content "git init" - page.should have_content "git remote" - page.should have_content Project.last.url_to_repo - end - - And 'I click on HTTP' do - click_button 'HTTP' - end - - Then 'Remote url should update to http link' do - page.should have_content "git remote add origin #{Project.last.http_url_to_repo}" - end - - And 'If I click on SSH' do - click_button 'SSH' - end - - Then 'Remote url should update to ssh link' do - page.should have_content "git remote add origin #{Project.last.url_to_repo}" - end -end diff --git a/features/steps/project/filter_labels.rb b/features/steps/project/filter_labels.rb new file mode 100644 index 00000000000..5926d69d6c7 --- /dev/null +++ b/features/steps/project/filter_labels.rb @@ -0,0 +1,70 @@ +class ProjectFilterLabels < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + Then 'I should see "bug" in labels filter' do + within ".labels-filter" do + page.should have_content "bug" + end + end + + And 'I should see "feature" in labels filter' do + within ".labels-filter" do + page.should have_content "feature" + end + end + + And 'I should see "enhancement" in labels filter' do + within ".labels-filter" do + page.should have_content "enhancement" + end + end + + Then 'I should see "Bugfix1" in issues list' do + within ".issues-list" do + page.should have_content "Bugfix1" + end + end + + And 'I should see "Bugfix2" in issues list' do + within ".issues-list" do + page.should have_content "Bugfix2" + end + end + + And 'I should not see "Bugfix2" in issues list' do + within ".issues-list" do + page.should_not have_content "Bugfix2" + end + end + + And 'I should not see "Feature1" in issues list' do + within ".issues-list" do + page.should_not have_content "Feature1" + end + end + + Given 'I click link "bug"' do + click_link "bug" + end + + Given 'I click link "feature"' do + click_link "feature" + end + + And 'project "Shop" has issue "Bugfix1" with tags: "bug", "feature"' do + project = Project.find_by(name: "Shop") + create(:issue, title: "Bugfix1", project: project, label_list: ['bug', 'feature']) + end + + And 'project "Shop" has issue "Bugfix2" with tags: "bug", "enhancement"' do + project = Project.find_by(name: "Shop") + create(:issue, title: "Bugfix2", project: project, label_list: ['bug', 'enhancement']) + end + + And 'project "Shop" has issue "Feature1" with tags: "feature"' do + project = Project.find_by(name: "Shop") + create(:issue, title: "Feature1", project: project, label_list: 'feature') + end +end diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb new file mode 100644 index 00000000000..c00d9014b1d --- /dev/null +++ b/features/steps/project/fork.rb @@ -0,0 +1,36 @@ +class ForkProject < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + step 'I click link "Fork"' do + page.should have_content "Shop" + page.should have_content "Fork" + Gitlab::Shell.any_instance.stub(:fork_repository).and_return(true) + click_link "Fork" + end + + step 'I am a member of project "Shop"' do + @project = Project.find_by(name: "Shop") + @project ||= create(:project, name: "Shop", group: create(:group)) + @project.team << [@user, :reporter] + end + + step 'I should see the forked project page' do + page.should have_content "Project was successfully forked." + current_path.should include current_user.namespace.path + @forked_project = Project.find_by(namespace_id: current_user.namespace.path) + end + + step 'I already have a project named "Shop" in my namespace' do + current_user.namespace ||= create(:namespace) + current_user.namespace.should_not be_nil + current_user.namespace.path.should_not be_nil + @my_project = create(:project, name: "Shop", namespace: current_user.namespace) + end + + step 'I should see a "Name has already been taken" warning' do + page.should have_content "Name has already been taken" + end + +end diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb new file mode 100644 index 00000000000..4cc99f8af55 --- /dev/null +++ b/features/steps/project/forked_merge_requests.rb @@ -0,0 +1,183 @@ +class ProjectForkedMergeRequests < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedNote + include SharedPaths + include Select2Helper + + step 'I am a member of project "Shop"' do + @project = Project.find_by(name: "Shop") + @project ||= create(:project, name: "Shop") + @project.team << [@user, :reporter] + end + + step 'I have a project forked off of "Shop" called "Forked Shop"' do + @forking_user = @user + forked_project_link = build(:forked_project_link) + @forked_project = Project.find_by(name: "Forked Shop") + @forked_project ||= create(:project, name: "Forked Shop", forked_project_link: forked_project_link, creator_id: @forking_user.id , namespace: @forking_user.namespace) + + forked_project_link.forked_from_project = @project + forked_project_link.forked_to_project = @forked_project + @forked_project.team << [@forking_user , :master] + forked_project_link.save! + end + + step 'I click link "New Merge Request"' do + click_link "New Merge Request" + end + + step 'I should see merge request "Merge Request On Forked Project"' do + @project.merge_requests.size.should >= 1 + @merge_request = @project.merge_requests.last + current_path.should == project_merge_request_path(@project, @merge_request) + @merge_request.title.should == "Merge Request On Forked Project" + @merge_request.source_project.should == @forked_project + @merge_request.source_branch.should == "master" + @merge_request.target_branch.should == "stable" + page.should have_content @forked_project.path_with_namespace + page.should have_content @project.path_with_namespace + page.should have_content @merge_request.source_branch + page.should have_content @merge_request.target_branch + end + + step 'I fill out a "Merge Request On Forked Project" merge request' do + select2 @forked_project.id, from: "#merge_request_source_project_id" + select2 @project.id, from: "#merge_request_target_project_id" + + find(:select, "merge_request_source_project_id", {}).value.should == @forked_project.id.to_s + find(:select, "merge_request_target_project_id", {}).value.should == @project.id.to_s + + select2 "master", from: "#merge_request_source_branch" + select2 "stable", from: "#merge_request_target_branch" + + find(:select, "merge_request_source_branch", {}).value.should == 'master' + find(:select, "merge_request_target_branch", {}).value.should == 'stable' + + fill_in "merge_request_title", with: "Merge Request On Forked Project" + end + + step 'I submit the merge request' do + click_button "Submit merge request" + end + + step 'I follow the target commit link' do + commit = @project.repository.commit + click_link commit.short_id(8) + end + + step 'I should see the commit under the forked from project' do + commit = @project.repository.commit + page.should have_content(commit.message) + end + + step 'I click "Create Merge Request on fork" link' do + click_link "Create Merge Request on fork" + end + + step 'I see prefilled new Merge Request page for the forked project' do + current_path.should == new_project_merge_request_path(@forked_project) + find("#merge_request_source_project_id").value.should == @forked_project.id.to_s + find("#merge_request_target_project_id").value.should == @project.id.to_s + find("#merge_request_source_branch").value.should have_content "new_design" + find("#merge_request_target_branch").value.should have_content "master" + find("#merge_request_title").value.should == "New Design" + verify_commit_link(".mr_target_commit",@project) + verify_commit_link(".mr_source_commit",@forked_project) + end + + step 'I update the merge request title' do + fill_in "merge_request_title", with: "An Edited Forked Merge Request" + end + + step 'I save the merge request' do + click_button "Save changes" + end + + step 'I should see the edited merge request' do + page.should have_content "An Edited Forked Merge Request" + @project.merge_requests.size.should >= 1 + @merge_request = @project.merge_requests.last + current_path.should == project_merge_request_path(@project, @merge_request) + @merge_request.source_project.should == @forked_project + @merge_request.source_branch.should == "master" + @merge_request.target_branch.should == "stable" + page.should have_content @forked_project.path_with_namespace + page.should have_content @project.path_with_namespace + page.should have_content @merge_request.source_branch + page.should have_content @merge_request.target_branch + end + + step 'I should see last push widget' do + page.should have_content "You pushed to new_design" + page.should have_link "Create Merge Request" + end + + step 'project "Forked Shop" has push event' do + @forked_project = Project.find_by(name: "Forked Shop") + + data = { + before: "0000000000000000000000000000000000000000", + after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e", + ref: "refs/heads/new_design", + user_id: @user.id, + user_name: @user.name, + repository: { + name: @forked_project.name, + url: "localhost/rubinius", + description: "", + homepage: "localhost/rubinius", + private: true + } + } + + @event = Event.create( + project: @forked_project, + action: Event::PUSHED, + data: data, + author_id: @user.id + ) + end + + + step 'I click link edit "Merge Request On Forked Project"' do + find("#edit_merge_request").click + end + + step 'I see the edit page prefilled for "Merge Request On Forked Project"' do + current_path.should == edit_project_merge_request_path(@project, @merge_request) + page.should have_content "Edit merge request ##{@merge_request.id}" + find("#merge_request_title").value.should == "Merge Request On Forked Project" + find("#merge_request_source_project_id").value.should == @forked_project.id.to_s + find("#merge_request_target_project_id").value.should == @project.id.to_s + find("#merge_request_source_branch").value.should have_content "master" + verify_commit_link(".mr_source_commit",@forked_project) + find("#merge_request_target_branch").value.should have_content "stable" + verify_commit_link(".mr_target_commit",@project) + end + + step 'I fill out an invalid "Merge Request On Forked Project" merge request' do + #If this isn't filled in the rest of the validations won't be triggered + fill_in "merge_request_title", with: "Merge Request On Forked Project" + find(:select, "merge_request_source_project_id", {}).value.should == @forked_project.id.to_s + find(:select, "merge_request_target_project_id", {}).value.should == @forked_project.id.to_s + find(:select, "merge_request_source_branch", {}).value.should == "" + find(:select, "merge_request_target_branch", {}).value.should == "" + end + + step 'I should see validation errors' do + page.should have_content "Source branch can't be blank" + page.should have_content "Target branch can't be blank" + page.should have_content "Branch conflict You can not use same project/branch for source and target" + end + + def project + @project ||= Project.find_by!(name: "Shop") + end + + # Verify a link is generated against the correct project + def verify_commit_link(container_div, container_project) + # This should force a wait for the javascript to execute + find(:div,container_div).find(".commit_short_id")['href'].should have_content "#{container_project.path_with_namespace}/commit" + end +end diff --git a/features/steps/project/graph.rb b/features/steps/project/graph.rb new file mode 100644 index 00000000000..89fe5fdeadf --- /dev/null +++ b/features/steps/project/graph.rb @@ -0,0 +1,13 @@ +class ProjectGraph < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + + Then 'page should have graphs' do + page.should have_selector ".stat-graph" + end + + When 'I visit project "Shop" graph page' do + project = Project.find_by(name: "Shop") + visit project_graph_path(project, "master") + end +end diff --git a/features/steps/project/hooks.rb b/features/steps/project/hooks.rb new file mode 100644 index 00000000000..19ff3244543 --- /dev/null +++ b/features/steps/project/hooks.rb @@ -0,0 +1,38 @@ +require 'webmock' + +class ProjectHooks < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + include RSpec::Matchers + include RSpec::Mocks::ExampleMethods + include WebMock::API + + Given 'project has hook' do + @hook = create(:project_hook, project: current_project) + end + + Then 'I should see project hook' do + page.should have_content @hook.url + end + + When 'I submit new hook' do + @url = Faker::Internet.uri("http") + fill_in "hook_url", with: @url + expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1) + end + + Then 'I should see newly created hook' do + page.current_path.should == project_hooks_path(current_project) + page.should have_content(@url) + end + + When 'I click test hook button' do + stub_request(:post, @hook.url).to_return(status: 200) + click_link 'Test Hook' + end + + Then 'hook should be triggered' do + page.current_path.should == project_hooks_path(current_project) + end +end diff --git a/features/steps/project/issue_tracker.rb b/features/steps/project/issue_tracker.rb new file mode 100644 index 00000000000..c2fd4e15c9e --- /dev/null +++ b/features/steps/project/issue_tracker.rb @@ -0,0 +1,31 @@ +class ProjectIssueTracker < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'project "Shop" has issues enabled' do + @project = Project.find_by(name: "Shop") + @project ||= create(:project, name: "Shop", namespace: @user.namespace) + @project.issues_enabled = true + end + + step 'change the issue tracker to "GitLab"' do + select 'GitLab', from: 'project_issues_tracker' + end + + step 'I the project should have "GitLab" as issue tracker' do + find_field('project_issues_tracker').value.should == 'gitlab' + end + + step 'change the issue tracker to "Redmine"' do + select 'Redmine', from: 'project_issues_tracker' + end + + step 'I the project should have "Redmine" as issue tracker' do + find_field('project_issues_tracker').value.should == 'redmine' + end + + And 'I save project' do + click_button 'Save changes' + end +end diff --git a/features/steps/project/issues.rb b/features/steps/project/issues.rb new file mode 100644 index 00000000000..a92fd50584d --- /dev/null +++ b/features/steps/project/issues.rb @@ -0,0 +1,145 @@ +class ProjectIssues < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedNote + include SharedPaths + include SharedMarkdown + + Given 'I should see "Release 0.4" in issues' do + page.should have_content "Release 0.4" + end + + And 'I should not see "Release 0.3" in issues' do + page.should_not have_content "Release 0.3" + end + + And 'I should not see "Tweet control" in issues' do + page.should_not have_content "Tweet control" + end + + Given 'I click link "Closed"' do + click_link "Closed" + end + + Then 'I should see "Release 0.3" in issues' do + page.should have_content "Release 0.3" + end + + And 'I should not see "Release 0.4" in issues' do + page.should_not have_content "Release 0.4" + end + + Given 'I click link "All"' do + click_link "All" + end + + Given 'I click link "Release 0.4"' do + click_link "Release 0.4" + end + + Then 'I should see issue "Release 0.4"' do + page.should have_content "Release 0.4" + end + + Given 'I click link "New Issue"' do + click_link "New Issue" + end + + And 'I submit new issue "500 error on profile"' do + fill_in "issue_title", with: "500 error on profile" + click_button "Submit new issue" + end + + Given 'I click link "500 error on profile"' do + click_link "500 error on profile" + end + + Then 'I should see issue "500 error on profile"' do + issue = Issue.find_by(title: "500 error on profile") + page.should have_content issue.title + page.should have_content issue.author_name + page.should have_content issue.project.name + end + + Given 'I fill in issue search with "Re"' do + fill_in 'issue_search', with: "Re" + end + + Given 'I fill in issue search with "Bu"' do + fill_in 'issue_search', with: "Bu" + end + + And 'I fill in issue search with ".3"' do + fill_in 'issue_search', with: ".3" + end + + And 'I fill in issue search with "Something"' do + fill_in 'issue_search', with: "Something" + end + + And 'I fill in issue search with ""' do + fill_in 'issue_search', with: "" + end + + Given 'project "Shop" has milestone "v2.2"' do + project = Project.find_by(name: "Shop") + milestone = create(:milestone, title: "v2.2", project: project) + + 3.times { create(:issue, project: project, milestone: milestone) } + end + + And 'project "Shop" has milestone "v3.0"' do + project = Project.find_by(name: "Shop") + milestone = create(:milestone, title: "v3.0", project: project) + + 3.times { create(:issue, project: project, milestone: milestone) } + end + + When 'I select milestone "v3.0"' do + select "v3.0", from: "milestone_id" + end + + Then 'I should see selected milestone with title "v3.0"' do + issues_milestone_selector = "#issue_milestone_id_chzn > a" + page.find(issues_milestone_selector).should have_content("v3.0") + end + + When 'I select first assignee from "Shop" project' do + project = Project.find_by(name: "Shop") + first_assignee = project.users.first + select first_assignee.name, from: "assignee_id" + end + + Then 'I should see first assignee from "Shop" as selected assignee' do + issues_assignee_selector = "#issue_assignee_id_chzn > a" + project = Project.find_by(name: "Shop") + assignee_name = project.users.first.name + page.find(issues_assignee_selector).should have_content(assignee_name) + end + + And 'project "Shop" have "Release 0.4" open issue' do + project = Project.find_by(name: "Shop") + create(:issue, + title: "Release 0.4", + project: project, + author: project.users.first, + description: "# Description header" + ) + end + + And 'project "Shop" have "Tweet control" open issue' do + project = Project.find_by(name: "Shop") + create(:issue, + title: "Tweet control", + project: project, + author: project.users.first) + end + + And 'project "Shop" have "Release 0.3" closed issue' do + project = Project.find_by(name: "Shop") + create(:closed_issue, + title: "Release 0.3", + project: project, + author: project.users.first) + end +end diff --git a/features/steps/project/labels.rb b/features/steps/project/labels.rb new file mode 100644 index 00000000000..0907cdb526f --- /dev/null +++ b/features/steps/project/labels.rb @@ -0,0 +1,24 @@ +class ProjectLabels < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + Then 'I should see label "bug"' do + within ".labels-table" do + page.should have_content "bug" + end + end + + And 'I should see label "feature"' do + within ".labels-table" do + page.should have_content "feature" + end + end + + And 'project "Shop" have issues tags: "bug", "feature"' do + project = Project.find_by(name: "Shop") + ['bug', 'feature'].each do |label| + create(:issue, project: project, label_list: label) + end + end +end diff --git a/features/steps/project/markdown_render.rb b/features/steps/project/markdown_render.rb new file mode 100644 index 00000000000..89fbb7408c2 --- /dev/null +++ b/features/steps/project/markdown_render.rb @@ -0,0 +1,207 @@ +class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedMarkdown + + And 'I own project "Delta"' do + @project = Project.find_by(name: "Delta") + @project ||= create(:project, name: "Delta", namespace: @user.namespace) + @project.team << [@user, :master] + end + + Then 'I should see files from repository in master' do + current_path.should == project_tree_path(@project, "master") + page.should have_content "Gemfile" + page.should have_content "app" + page.should have_content "README" + end + + And 'I should see rendered README which contains correct links' do + page.should have_content "Welcome to GitLab GitLab is a free project and repository management application" + page.should have_link "GitLab API doc" + page.should have_link "GitLab API website" + page.should have_link "Rake tasks" + page.should have_link "backup and restore procedure" + page.should have_link "GitLab API doc directory" + page.should have_link "Maintenance" + end + + And 'I click on Gitlab API in README' do + click_link "GitLab API doc" + end + + Then 'I should see correct document rendered' do + current_path.should == project_blob_path(@project, "master/doc/api/README.md") + page.should have_content "All API requests require authentication" + end + + And 'I click on Rake tasks in README' do + click_link "Rake tasks" + end + + Then 'I should see correct directory rendered' do + current_path.should == project_tree_path(@project, "master/doc/raketasks") + page.should have_content "backup_restore.md" + page.should have_content "maintenance.md" + end + + And 'I click on GitLab API doc directory in README' do + click_link "GitLab API doc directory" + end + + Then 'I should see correct doc/api directory rendered' do + current_path.should == project_tree_path(@project, "master/doc/api/") + page.should have_content "README.md" + page.should have_content "users.md" + end + + And 'I click on Maintenance in README' do + click_link "Maintenance" + end + + Then 'I should see correct maintenance file rendered' do + current_path.should == project_blob_path(@project, "master/doc/raketasks/maintenance.md") + page.should have_content "bundle exec rake gitlab:env:info RAILS_ENV=production" + end + + And 'I navigate to the doc/api/README' do + click_link "doc" + click_link "api" + click_link "README.md" + end + + And 'I see correct file rendered' do + current_path.should == project_blob_path(@project, "master/doc/api/README.md") + page.should have_content "Contents" + page.should have_link "Users" + page.should have_link "Rake tasks" + end + + And 'I click on users in doc/api/README' do + click_link "Users" + end + + Then 'I should see the correct document file' do + current_path.should == project_blob_path(@project, "master/doc/api/users.md") + page.should have_content "Get a list of users." + end + + And 'I click on raketasks in doc/api/README' do + click_link "Rake tasks" + end + + When 'I visit markdown branch' do + visit project_tree_path(@project, "markdown") + end + + Then 'I should see files from repository in markdown branch' do + current_path.should == project_tree_path(@project, "markdown") + page.should have_content "Gemfile" + page.should have_content "app" + page.should have_content "README" + end + + And 'I see correct file rendered in markdown branch' do + current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") + page.should have_content "Contents" + page.should have_link "Users" + page.should have_link "Rake tasks" + end + + Then 'I should see correct document rendered for markdown branch' do + current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") + page.should have_content "All API requests require authentication" + end + + Then 'I should see correct directory rendered for markdown branch' do + current_path.should == project_tree_path(@project, "markdown/doc/raketasks") + page.should have_content "backup_restore.md" + page.should have_content "maintenance.md" + end + + Then 'I should see the users document file in markdown branch' do + current_path.should == project_blob_path(@project, "markdown/doc/api/users.md") + page.should have_content "Get a list of users." + end + + Given 'I go to wiki page' do + click_link "Wiki" + current_path.should == project_wiki_path(@project, "home") + end + + And 'I add various links to the wiki page' do + fill_in "wiki[content]", with: "[test](test)\n[GitLab API doc](doc/api/README.md)\n[Rake tasks](doc/raketasks)\n" + fill_in "wiki[message]", with: "Adding links to wiki" + click_button "Create page" + end + + Then 'Wiki page should have added links' do + current_path.should == project_wiki_path(@project, "home") + page.should have_content "test GitLab API doc Rake tasks" + end + + step 'I add a header to the wiki page' do + fill_in "wiki[content]", with: "# Wiki header\n" + fill_in "wiki[message]", with: "Add header to wiki" + click_button "Create page" + end + + step 'Wiki header should have correct id and link' do + header_should_have_correct_id_and_link(1, 'Wiki header', 'wiki-header') + end + + And 'I click on test link' do + click_link "test" + end + + Then 'I see new wiki page named test' do + current_path.should == project_wiki_path(@project, "test") + page.should have_content "Editing" + end + + When 'I go back to wiki page home' do + visit project_wiki_path(@project, "home") + current_path.should == project_wiki_path(@project, "home") + end + + And 'I click on GitLab API doc link' do + click_link "GitLab API" + end + + Then 'I see Gitlab API document' do + current_path.should == project_blob_path(@project, "master/doc/api/README.md") + page.should have_content "Status codes" + end + + And 'I click on Rake tasks link' do + click_link "Rake tasks" + end + + Then 'I see Rake tasks directory' do + current_path.should == project_tree_path(@project, "master/doc/raketasks") + page.should have_content "backup_restore.md" + page.should have_content "maintenance.md" + end + + Given 'I go directory which contains README file' do + visit project_tree_path(@project, "master/doc/api") + current_path.should == project_tree_path(@project, "master/doc/api") + end + + And 'I click on a relative link in README' do + click_link "Users" + end + + Then 'I should see the correct markdown' do + current_path.should == project_blob_path(@project, "master/doc/api/users.md") + page.should have_content "List users" + end + + step 'Header "Application details" should have correct id and link' do + header_should_have_correct_id_and_link(2, 'Application details', 'application-details') + end + + step 'Header "GitLab API" should have correct id and link' do + header_should_have_correct_id_and_link(1, 'GitLab API', 'gitlab-api') + end +end diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb new file mode 100644 index 00000000000..adf9e77e136 --- /dev/null +++ b/features/steps/project/merge_requests.rb @@ -0,0 +1,195 @@ +class ProjectMergeRequests < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedNote + include SharedPaths + include SharedMarkdown + + step 'I click link "New Merge Request"' do + click_link "New Merge Request" + end + + step 'I click link "Bug NS-04"' do + click_link "Bug NS-04" + end + + step 'I click link "All"' do + click_link "All" + end + + step 'I click link "Closed"' do + click_link "Closed" + end + + step 'I should see merge request "Wiki Feature"' do + within '.merge-request' do + page.should have_content "Wiki Feature" + end + end + + step 'I should see closed merge request "Bug NS-04"' do + merge_request = MergeRequest.find_by!(title: "Bug NS-04") + merge_request.closed?.should be_true + page.should have_content "Closed by" + end + + step 'I should see merge request "Bug NS-04"' do + page.should have_content "Bug NS-04" + end + + step 'I should see "Bug NS-04" in merge requests' do + page.should have_content "Bug NS-04" + end + + step 'I should see "Feature NS-03" in merge requests' do + page.should have_content "Feature NS-03" + end + + step 'I should not see "Feature NS-03" in merge requests' do + page.should_not have_content "Feature NS-03" + end + + + step 'I should not see "Bug NS-04" in merge requests' do + page.should_not have_content "Bug NS-04" + end + + step 'I click link "Close"' do + within '.page-title' do + click_link "Close" + end + end + + step 'I submit new merge request "Wiki Feature"' do + fill_in "merge_request_title", with: "Wiki Feature" + select "master", from: "merge_request_source_branch" + select "notes_refactoring", from: "merge_request_target_branch" + click_button "Submit merge request" + end + + step 'project "Shop" have "Bug NS-04" open merge request' do + create(:merge_request, + title: "Bug NS-04", + source_project: project, + target_project: project, + source_branch: 'stable', + target_branch: 'master', + author: project.users.first, + description: "# Description header" + ) + end + + step 'project "Shop" have "Bug NS-05" open merge request with diffs inside' do + create(:merge_request_with_diffs, + title: "Bug NS-05", + source_project: project, + target_project: project, + author: project.users.first) + end + + step 'project "Shop" have "Feature NS-03" closed merge request' do + create(:closed_merge_request, + title: "Feature NS-03", + source_project: project, + target_project: project, + author: project.users.first) + end + + step 'I switch to the diff tab' do + visit diffs_project_merge_request_path(project, merge_request) + end + + step 'I switch to the merge request\'s comments tab' do + visit project_merge_request_path(project, merge_request) + end + + step 'I click on the first commit in the merge request' do + within '.first-commits' do + click_link merge_request.commits.first.short_id(8) + end + end + + step 'I leave a comment on the diff page' do + init_diff_note + leave_comment "One comment to rule them all" + end + + step 'I leave a comment on the diff page in commit' do + find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click + leave_comment "One comment to rule them all" + end + + step 'I leave a comment like "Line is wrong" on line 185 of the first file' do + init_diff_note + leave_comment "Line is wrong" + end + + step 'I leave a comment like "Line is wrong" on line 185 of the first file in commit' do + find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click + leave_comment "Line is wrong" + end + + step 'I should see a discussion has started on line 185' do + page.should have_content "#{current_user.name} started a discussion on this merge request diff" + page.should have_content "app/assets/stylesheets/tree.scss:L185" + page.should have_content "Line is wrong" + end + + step 'I should see a discussion has started on commit b1e6a9dbf1:L185' do + page.should have_content "#{current_user.name} started a discussion on commit" + page.should have_content "app/assets/stylesheets/tree.scss:L185" + page.should have_content "Line is wrong" + end + + step 'I should see a discussion has started on commit b1e6a9dbf1' do + page.should have_content "#{current_user.name} started a discussion on commit" + page.should have_content "One comment to rule them all" + page.should have_content "app/assets/stylesheets/tree.scss:L185" + end + + step 'merge request is mergeable' do + page.should have_content 'You can accept this request automatically' + end + + step 'I modify merge commit message' do + find('.modify-merge-commit-link').click + fill_in 'merge_commit_message', with: "wow such merge" + end + + step 'merge request "Bug NS-05" is mergeable' do + merge_request.mark_as_mergeable + end + + step 'I accept this merge request' do + click_button "Accept Merge Request" + end + + step 'I should see merged request' do + within '.issue-box' do + page.should have_content "Merged" + end + end + + def project + @project ||= Project.find_by!(name: "Shop") + end + + def merge_request + @merge_request ||= MergeRequest.find_by!(title: "Bug NS-05") + end + + def init_diff_note + find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185"]').click + end + + def leave_comment(message) + within(".js-discussion-note-form") do + fill_in "note_note", with: message + click_button "Add Comment" + end + + within ".note-text" do + page.should have_content message + end + end +end diff --git a/features/steps/project/milestones.rb b/features/steps/project/milestones.rb new file mode 100644 index 00000000000..9ce18fbaabd --- /dev/null +++ b/features/steps/project/milestones.rb @@ -0,0 +1,59 @@ +class ProjectMilestones < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + include SharedMarkdown + + Then 'I should see milestone "v2.2"' do + milestone = @project.milestones.find_by(title: "v2.2") + page.should have_content(milestone.title[0..10]) + page.should have_content(milestone.expires_at) + page.should have_content("Browse Issues") + end + + Given 'I click link "v2.2"' do + click_link "v2.2" + end + + Given 'I click link "New Milestone"' do + click_link "New Milestone" + end + + And 'I submit new milestone "v2.3"' do + fill_in "milestone_title", with: "v2.3" + click_button "Create milestone" + end + + Then 'I should see milestone "v2.3"' do + milestone = @project.milestones.find_by(title: "v2.3") + page.should have_content(milestone.title[0..10]) + page.should have_content(milestone.expires_at) + page.should have_content("Browse Issues") + end + + And 'project "Shop" has milestone "v2.2"' do + project = Project.find_by(name: "Shop") + milestone = create(:milestone, + title: "v2.2", + project: project, + description: "# Description header" + ) + 3.times { create(:issue, project: project, milestone: milestone) } + end + + Given 'the milestone has open and closed issues' do + project = Project.find_by(name: "Shop") + milestone = project.milestones.find_by(title: 'v2.2') + + # 3 Open issues created above; create one closed issue + create(:closed_issue, project: project, milestone: milestone) + end + + When 'I click link "All Issues"' do + click_link 'All Issues' + end + + Then "I should see 3 issues" do + page.should have_selector('#tab-issues li', count: 4) + end +end diff --git a/features/steps/project/multiselect_blob.rb b/features/steps/project/multiselect_blob.rb new file mode 100644 index 00000000000..3d330e837c1 --- /dev/null +++ b/features/steps/project/multiselect_blob.rb @@ -0,0 +1,58 @@ +class ProjectMultiselectBlob < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + class << self + def click_line_steps(*line_numbers) + line_numbers.each do |line_number| + step "I click line #{line_number} in file" do + find("#L#{line_number}").click + end + + step "I shift-click line #{line_number} in file" do + script = "$('#L#{line_number}').trigger($.Event('click', { shiftKey: true }));" + page.evaluate_script(script) + end + end + end + + def check_state_steps(*ranges) + ranges.each do |range| + fragment = range.kind_of?(Array) ? "L#{range.first}-#{range.last}" : "L#{range}" + pluralization = range.kind_of?(Array) ? "s" : "" + + step "I should see \"#{fragment}\" as URI fragment" do + URI.parse(current_url).fragment.should == fragment + end + + step "I should see line#{pluralization} #{fragment[1..-1]} highlighted" do + ids = Array(range).map { |n| "LC#{n}" } + extra = false + + highlighted = all("#tree-content-holder .highlight .line.hll") + highlighted.each do |element| + extra ||= ids.delete(element[:id]).nil? + end + + extra.should be_false and ids.should be_empty + end + end + end + end + + click_line_steps *Array(1..5) + check_state_steps *Array(1..5), Array(1..2), Array(1..3), Array(1..4), Array(1..5), Array(3..5) + + step 'I go back in history' do + page.evaluate_script("window.history.back()") + end + + step 'I go forward in history' do + page.evaluate_script("window.history.forward()") + end + + step 'I click on "Gemfile.lock" file in repo' do + click_link "Gemfile.lock" + end +end \ No newline at end of file diff --git a/features/steps/project/network_graph.rb b/features/steps/project/network_graph.rb new file mode 100644 index 00000000000..1c5cfcc6c68 --- /dev/null +++ b/features/steps/project/network_graph.rb @@ -0,0 +1,93 @@ +class ProjectNetworkGraph < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + Then 'page should have network graph' do + page.should have_selector ".network-graph" + end + + When 'I visit project "Shop" network page' do + # Stub Graph max_size to speed up test (10 commits vs. 650) + Network::Graph.stub(max_count: 10) + + project = Project.find_by(name: "Shop") + visit project_network_path(project, "master") + end + + And 'page should select "master" in select box' do + page.should have_selector '.select2-chosen', text: "master" + end + + And 'page should select "v2.1.0" in select box' do + page.should have_selector '.select2-chosen', text: "v2.1.0" + end + + And 'page should have "master" on graph' do + within '.network-graph' do + page.should have_content 'master' + end + end + + When 'I switch ref to "stable"' do + page.select 'stable', from: 'ref' + sleep 2 + end + + When 'I switch ref to "v2.1.0"' do + page.select 'v2.1.0', from: 'ref' + sleep 2 + end + + When 'click "Show only selected branch" checkbox' do + find('#filter_ref').click + sleep 2 + end + + Then 'page should have content not containing "v2.1.0"' do + within '.network-graph' do + page.should have_content 'cleaning' + end + end + + Then 'page should not have content not containing "v2.1.0"' do + within '.network-graph' do + page.should_not have_content 'cleaning' + end + end + + And 'page should select "stable" in select box' do + page.should have_selector '.select2-chosen', text: "stable" + end + + And 'page should select "v2.1.0" in select box' do + page.should have_selector '.select2-chosen', text: "v2.1.0" + end + + And 'page should have "stable" on graph' do + within '.network-graph' do + page.should have_content 'stable' + end + end + + When 'I looking for a commit by SHA of "v2.1.0"' do + within ".network-form" do + fill_in 'extended_sha1', with: '98d6492' + find('button').click + end + sleep 2 + end + + And 'page should have "v2.1.0" on graph' do + within '.network-graph' do + page.should have_content 'v2.1.0' + end + end + + When 'I look for a commit by ";"' do + within ".network-form" do + fill_in 'extended_sha1', with: ';' + find('button').click + end + end +end diff --git a/features/steps/project/project_active_tab.rb b/features/steps/project/project_active_tab.rb deleted file mode 100644 index dcc252f4765..00000000000 --- a/features/steps/project/project_active_tab.rb +++ /dev/null @@ -1,140 +0,0 @@ -class ProjectActiveTab < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - include SharedActiveTab - - # Main Tabs - - Then 'the active main tab should be Home' do - ensure_active_main_tab('Home') - end - - Then 'the active main tab should be Settings' do - ensure_active_main_tab('Settings') - end - - Then 'the active main tab should be Files' do - ensure_active_main_tab('Files') - end - - Then 'the active main tab should be Commits' do - ensure_active_main_tab('Commits') - end - - Then 'the active main tab should be Network' do - ensure_active_main_tab('Network') - end - - Then 'the active main tab should be Issues' do - ensure_active_main_tab('Issues') - end - - Then 'the active main tab should be Merge Requests' do - ensure_active_main_tab('Merge Requests') - end - - Then 'the active main tab should be Wall' do - ensure_active_main_tab('Wall') - end - - Then 'the active main tab should be Wiki' do - ensure_active_main_tab('Wiki') - end - - # Sub Tabs: Home - - Given 'I click the "Team" tab' do - click_link('Members') - end - - Given 'I click the "Attachments" tab' do - click_link('Attachments') - end - - Given 'I click the "Snippets" tab' do - click_link('Snippets') - end - - Given 'I click the "Edit" tab' do - within '.project-settings-nav' do - click_link('Project') - end - end - - Given 'I click the "Hooks" tab' do - click_link('Web Hooks') - end - - Given 'I click the "Deploy Keys" tab' do - click_link('Deploy Keys') - end - - Then 'the active sub nav should be Team' do - ensure_active_sub_nav('Members') - end - - Then 'the active sub nav should be Edit' do - ensure_active_sub_nav('Project') - end - - Then 'the active sub nav should be Hooks' do - ensure_active_sub_nav('Web Hooks') - end - - Then 'the active sub nav should be Deploy Keys' do - ensure_active_sub_nav('Deploy Keys') - end - - # Sub Tabs: Commits - - Given 'I click the "Compare" tab' do - click_link('Compare') - end - - Given 'I click the "Branches" tab' do - click_link('Branches') - end - - Given 'I click the "Tags" tab' do - click_link('Tags') - end - - Then 'the active sub tab should be Commits' do - ensure_active_sub_tab('Commits') - end - - Then 'the active sub tab should be Compare' do - ensure_active_sub_tab('Compare') - end - - Then 'the active sub tab should be Branches' do - ensure_active_sub_tab('Branches') - end - - Then 'the active sub tab should be Tags' do - ensure_active_sub_tab('Tags') - end - - # Sub Tabs: Issues - - Given 'I click the "Milestones" tab' do - click_link('Milestones') - end - - Given 'I click the "Labels" tab' do - click_link('Labels') - end - - Then 'the active sub tab should be Browse Issues' do - ensure_active_sub_tab('Browse Issues') - end - - Then 'the active sub tab should be Milestones' do - ensure_active_sub_tab('Milestones') - end - - Then 'the active sub tab should be Labels' do - ensure_active_sub_tab('Labels') - end -end diff --git a/features/steps/project/project_archived.rb b/features/steps/project/project_archived.rb deleted file mode 100644 index dfbe762c438..00000000000 --- a/features/steps/project/project_archived.rb +++ /dev/null @@ -1,37 +0,0 @@ -class ProjectArchived < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - When 'project "Forum" is archived' do - project = Project.find_by(name: "Forum") - project.update_attribute(:archived, true) - end - - When 'project "Shop" is archived' do - project = Project.find_by(name: "Shop") - project.update_attribute(:archived, true) - end - - When 'I visit project "Forum" page' do - project = Project.find_by(name: "Forum") - visit project_path(project) - end - - Then 'I should not see "Archived"' do - page.should_not have_content "Archived" - end - - Then 'I should see "Archived"' do - page.should have_content "Archived" - end - - When 'I set project archived' do - click_link "Archive" - end - - When 'I set project unarchived' do - click_link "Unarchive" - end - -end \ No newline at end of file diff --git a/features/steps/project/project_browse_branches.rb b/features/steps/project/project_browse_branches.rb deleted file mode 100644 index ef29cc67a4e..00000000000 --- a/features/steps/project/project_browse_branches.rb +++ /dev/null @@ -1,35 +0,0 @@ -class ProjectBrowseBranches < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - Then 'I should see "Shop" recent branches list' do - page.should have_content "Branches" - page.should have_content "master" - end - - Given 'I click link "All"' do - click_link "All" - end - - Then 'I should see "Shop" all branches list' do - page.should have_content "Branches" - page.should have_content "master" - end - - Given 'I click link "Protected"' do - click_link "Protected" - end - - Then 'I should see "Shop" protected branches list' do - within ".protected-branches-list" do - page.should have_content "stable" - page.should_not have_content "master" - end - end - - And 'project "Shop" has protected branches' do - project = Project.find_by(name: "Shop") - project.protected_branches.create(name: "stable") - end -end diff --git a/features/steps/project/project_browse_commits.rb b/features/steps/project/project_browse_commits.rb deleted file mode 100644 index d667b58240f..00000000000 --- a/features/steps/project/project_browse_commits.rb +++ /dev/null @@ -1,104 +0,0 @@ -class ProjectBrowseCommits < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - Then 'I see project commits' do - commit = @project.repository.commit - page.should have_content(@project.name) - page.should have_content(commit.message) - page.should have_content(commit.id.to_s[0..5]) - end - - Given 'I click atom feed link' do - click_link "Feed" - end - - Then 'I see commits atom feed' do - commit = @project.repository.commit - page.response_headers['Content-Type'].should have_content("application/atom+xml") - page.body.should have_selector("title", text: "Recent commits to #{@project.name}") - page.body.should have_selector("author email", text: commit.author_email) - page.body.should have_selector("entry summary", text: commit.description) - end - - Given 'I click on commit link' do - visit project_commit_path(@project, ValidCommit::ID) - end - - Then 'I see commit info' do - page.should have_content ValidCommit::MESSAGE - page.should have_content "Showing 1 changed file" - end - - And 'I fill compare fields with refs' do - fill_in "from", with: "8716fc78f3c65bbf7bcf7b574febd583bc5d2812" - fill_in "to", with: "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" - click_button "Compare" - end - - Then 'I see compared refs' do - page.should have_content "Compare View" - page.should have_content "Commits (1)" - page.should have_content "Showing 2 changed files" - end - - Then 'I see breadcrumb links' do - page.should have_selector('ul.breadcrumb') - page.should have_selector('ul.breadcrumb span.divider', count: 3) - page.should have_selector('ul.breadcrumb a', count: 4) - - find('ul.breadcrumb li:nth-child(2) a')['href'].should match(/#{@project.path_with_namespace}\/commits\/master\z/) - find('ul.breadcrumb li:last a')['href'].should match(%r{master/app/models/project\.rb\z}) - end - - Then 'I see commits stats' do - page.should have_content 'Top 50 Committers' - page.should have_content 'Committers' - page.should have_content 'Total commits' - page.should have_content 'Authors' - end - - Given 'I visit big commit page' do - visit project_commit_path(@project, BigCommits::BIG_COMMIT_ID) - end - - Then 'I see big commit warning' do - page.should have_content BigCommits::BIG_COMMIT_MESSAGE - page.should have_content "Warning! This is a large diff" - page.should have_content "If you still want to see the diff" - end - - Given 'I visit huge commit page' do - visit project_commit_path(@project, BigCommits::HUGE_COMMIT_ID) - end - - Then 'I see huge commit message' do - page.should have_content BigCommits::HUGE_COMMIT_MESSAGE - page.should have_content "Warning! This is a large diff" - page.should_not have_content "If you still want to see the diff" - end - - Given 'I visit a commit with an image that changed' do - visit project_commit_path(@project, 'cc1ba255d6c5ffdce87a357ba7ccc397a4f4026b') - end - - Then 'The diff links to both the previous and current image' do - links = page.all('.two-up span div a') - links[0]['href'].should =~ %r{blob/bc3735004cb45cec5e0e4fa92710897a910a5957} - links[1]['href'].should =~ %r{blob/cc1ba255d6c5ffdce87a357ba7ccc397a4f4026b} - end - - Given 'I click side-by-side diff button' do - click_link "Side-by-side Diff" - end - - Then 'I see side-by-side diff button' do - page.should have_content "Side-by-side Diff" - end - - Then 'I see inline diff button' do - page.should have_content "Inline Diff" - end - -end diff --git a/features/steps/project/project_browse_commits_user_lookup.rb b/features/steps/project/project_browse_commits_user_lookup.rb deleted file mode 100644 index 328be373553..00000000000 --- a/features/steps/project/project_browse_commits_user_lookup.rb +++ /dev/null @@ -1,35 +0,0 @@ -class ProjectBrowseCommitsUserLookup < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - Given 'I have the user that authored the commits' do - @user = create(:user, email: 'dmitriy.zaporozhets@gmail.com') - create(:email, { user: @user, email: 'dzaporozhets@sphereconsultinginc.com' }) - end - - Given 'I click on commit link' do - visit project_commit_path(@project, ValidCommit::ID) - end - - Given 'I click on another commit link' do - visit project_commit_path(@project, ValidCommitWithAltEmail::ID) - end - - Then 'I see commit info' do - page.should have_content ValidCommit::MESSAGE - check_author_link(ValidCommit::AUTHOR_EMAIL) - end - - Then 'I see other commit info' do - page.should have_content ValidCommitWithAltEmail::MESSAGE - check_author_link(ValidCommitWithAltEmail::AUTHOR_EMAIL) - end - - def check_author_link(email) - author_link = find('.commit-author-link') - author_link['href'].should == user_path(@user) - author_link['data-original-title'].should == email - find('.commit-author-name').text.should == @user.name - end -end diff --git a/features/steps/project/project_browse_files.rb b/features/steps/project/project_browse_files.rb deleted file mode 100644 index 069086d5eac..00000000000 --- a/features/steps/project/project_browse_files.rb +++ /dev/null @@ -1,53 +0,0 @@ -class ProjectBrowseFiles < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I should see files from repository' do - page.should have_content "app" - page.should have_content "history" - page.should have_content "Gemfile" - end - - step 'I should see files from repository for "8470d70"' do - current_path.should == project_tree_path(@project, "8470d70") - page.should have_content "app" - page.should have_content "history" - page.should have_content "Gemfile" - end - - step 'I click on "Gemfile.lock" file in repo' do - click_link "Gemfile.lock" - end - - step 'I should see it content' do - page.should have_content "DEPENDENCIES" - end - - step 'I click link "raw"' do - click_link "raw" - end - - step 'I should see raw file content' do - page.source.should == ValidCommit::BLOB_FILE - end - - step 'I click button "edit"' do - click_link 'edit' - end - - step 'I can edit code' do - page.execute_script('editor.setValue("GitlabFileEditor")') - page.evaluate_script('editor.getValue()').should == "GitlabFileEditor" - end - - step 'I click on "new file" link in repo' do - click_link 'new-file-link' - end - - step 'I can see new file page' do - page.should have_content "New file" - page.should have_content "File name" - page.should have_content "Commit message" - end -end diff --git a/features/steps/project/project_browse_git_repo.rb b/features/steps/project/project_browse_git_repo.rb deleted file mode 100644 index cd9a60f49cb..00000000000 --- a/features/steps/project/project_browse_git_repo.rb +++ /dev/null @@ -1,19 +0,0 @@ -class ProjectBrowseGitRepo < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - Given 'I click on "Gemfile.lock" file in repo' do - click_link "Gemfile.lock" - end - - And 'I click blame button' do - click_link "blame" - end - - Then 'I should see git file blame' do - page.should have_content "DEPENDENCIES" - page.should have_content "Dmitriy Zaporozhets" - page.should have_content "Moving to rails 3.2" - end -end diff --git a/features/steps/project/project_browse_tags.rb b/features/steps/project/project_browse_tags.rb deleted file mode 100644 index 0cbfa0d80aa..00000000000 --- a/features/steps/project/project_browse_tags.rb +++ /dev/null @@ -1,10 +0,0 @@ -class ProjectBrowseTags < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - Then 'I should see "Shop" all tags list' do - page.should have_content "Tags" - page.should have_content "v1.2.1" - end -end diff --git a/features/steps/project/project_filter_labels.rb b/features/steps/project/project_filter_labels.rb deleted file mode 100644 index 5926d69d6c7..00000000000 --- a/features/steps/project/project_filter_labels.rb +++ /dev/null @@ -1,70 +0,0 @@ -class ProjectFilterLabels < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - Then 'I should see "bug" in labels filter' do - within ".labels-filter" do - page.should have_content "bug" - end - end - - And 'I should see "feature" in labels filter' do - within ".labels-filter" do - page.should have_content "feature" - end - end - - And 'I should see "enhancement" in labels filter' do - within ".labels-filter" do - page.should have_content "enhancement" - end - end - - Then 'I should see "Bugfix1" in issues list' do - within ".issues-list" do - page.should have_content "Bugfix1" - end - end - - And 'I should see "Bugfix2" in issues list' do - within ".issues-list" do - page.should have_content "Bugfix2" - end - end - - And 'I should not see "Bugfix2" in issues list' do - within ".issues-list" do - page.should_not have_content "Bugfix2" - end - end - - And 'I should not see "Feature1" in issues list' do - within ".issues-list" do - page.should_not have_content "Feature1" - end - end - - Given 'I click link "bug"' do - click_link "bug" - end - - Given 'I click link "feature"' do - click_link "feature" - end - - And 'project "Shop" has issue "Bugfix1" with tags: "bug", "feature"' do - project = Project.find_by(name: "Shop") - create(:issue, title: "Bugfix1", project: project, label_list: ['bug', 'feature']) - end - - And 'project "Shop" has issue "Bugfix2" with tags: "bug", "enhancement"' do - project = Project.find_by(name: "Shop") - create(:issue, title: "Bugfix2", project: project, label_list: ['bug', 'enhancement']) - end - - And 'project "Shop" has issue "Feature1" with tags: "feature"' do - project = Project.find_by(name: "Shop") - create(:issue, title: "Feature1", project: project, label_list: 'feature') - end -end diff --git a/features/steps/project/project_fork.rb b/features/steps/project/project_fork.rb deleted file mode 100644 index c00d9014b1d..00000000000 --- a/features/steps/project/project_fork.rb +++ /dev/null @@ -1,36 +0,0 @@ -class ForkProject < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I click link "Fork"' do - page.should have_content "Shop" - page.should have_content "Fork" - Gitlab::Shell.any_instance.stub(:fork_repository).and_return(true) - click_link "Fork" - end - - step 'I am a member of project "Shop"' do - @project = Project.find_by(name: "Shop") - @project ||= create(:project, name: "Shop", group: create(:group)) - @project.team << [@user, :reporter] - end - - step 'I should see the forked project page' do - page.should have_content "Project was successfully forked." - current_path.should include current_user.namespace.path - @forked_project = Project.find_by(namespace_id: current_user.namespace.path) - end - - step 'I already have a project named "Shop" in my namespace' do - current_user.namespace ||= create(:namespace) - current_user.namespace.should_not be_nil - current_user.namespace.path.should_not be_nil - @my_project = create(:project, name: "Shop", namespace: current_user.namespace) - end - - step 'I should see a "Name has already been taken" warning' do - page.should have_content "Name has already been taken" - end - -end diff --git a/features/steps/project/project_forked_merge_requests.rb b/features/steps/project/project_forked_merge_requests.rb deleted file mode 100644 index 4cc99f8af55..00000000000 --- a/features/steps/project/project_forked_merge_requests.rb +++ /dev/null @@ -1,183 +0,0 @@ -class ProjectForkedMergeRequests < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - include Select2Helper - - step 'I am a member of project "Shop"' do - @project = Project.find_by(name: "Shop") - @project ||= create(:project, name: "Shop") - @project.team << [@user, :reporter] - end - - step 'I have a project forked off of "Shop" called "Forked Shop"' do - @forking_user = @user - forked_project_link = build(:forked_project_link) - @forked_project = Project.find_by(name: "Forked Shop") - @forked_project ||= create(:project, name: "Forked Shop", forked_project_link: forked_project_link, creator_id: @forking_user.id , namespace: @forking_user.namespace) - - forked_project_link.forked_from_project = @project - forked_project_link.forked_to_project = @forked_project - @forked_project.team << [@forking_user , :master] - forked_project_link.save! - end - - step 'I click link "New Merge Request"' do - click_link "New Merge Request" - end - - step 'I should see merge request "Merge Request On Forked Project"' do - @project.merge_requests.size.should >= 1 - @merge_request = @project.merge_requests.last - current_path.should == project_merge_request_path(@project, @merge_request) - @merge_request.title.should == "Merge Request On Forked Project" - @merge_request.source_project.should == @forked_project - @merge_request.source_branch.should == "master" - @merge_request.target_branch.should == "stable" - page.should have_content @forked_project.path_with_namespace - page.should have_content @project.path_with_namespace - page.should have_content @merge_request.source_branch - page.should have_content @merge_request.target_branch - end - - step 'I fill out a "Merge Request On Forked Project" merge request' do - select2 @forked_project.id, from: "#merge_request_source_project_id" - select2 @project.id, from: "#merge_request_target_project_id" - - find(:select, "merge_request_source_project_id", {}).value.should == @forked_project.id.to_s - find(:select, "merge_request_target_project_id", {}).value.should == @project.id.to_s - - select2 "master", from: "#merge_request_source_branch" - select2 "stable", from: "#merge_request_target_branch" - - find(:select, "merge_request_source_branch", {}).value.should == 'master' - find(:select, "merge_request_target_branch", {}).value.should == 'stable' - - fill_in "merge_request_title", with: "Merge Request On Forked Project" - end - - step 'I submit the merge request' do - click_button "Submit merge request" - end - - step 'I follow the target commit link' do - commit = @project.repository.commit - click_link commit.short_id(8) - end - - step 'I should see the commit under the forked from project' do - commit = @project.repository.commit - page.should have_content(commit.message) - end - - step 'I click "Create Merge Request on fork" link' do - click_link "Create Merge Request on fork" - end - - step 'I see prefilled new Merge Request page for the forked project' do - current_path.should == new_project_merge_request_path(@forked_project) - find("#merge_request_source_project_id").value.should == @forked_project.id.to_s - find("#merge_request_target_project_id").value.should == @project.id.to_s - find("#merge_request_source_branch").value.should have_content "new_design" - find("#merge_request_target_branch").value.should have_content "master" - find("#merge_request_title").value.should == "New Design" - verify_commit_link(".mr_target_commit",@project) - verify_commit_link(".mr_source_commit",@forked_project) - end - - step 'I update the merge request title' do - fill_in "merge_request_title", with: "An Edited Forked Merge Request" - end - - step 'I save the merge request' do - click_button "Save changes" - end - - step 'I should see the edited merge request' do - page.should have_content "An Edited Forked Merge Request" - @project.merge_requests.size.should >= 1 - @merge_request = @project.merge_requests.last - current_path.should == project_merge_request_path(@project, @merge_request) - @merge_request.source_project.should == @forked_project - @merge_request.source_branch.should == "master" - @merge_request.target_branch.should == "stable" - page.should have_content @forked_project.path_with_namespace - page.should have_content @project.path_with_namespace - page.should have_content @merge_request.source_branch - page.should have_content @merge_request.target_branch - end - - step 'I should see last push widget' do - page.should have_content "You pushed to new_design" - page.should have_link "Create Merge Request" - end - - step 'project "Forked Shop" has push event' do - @forked_project = Project.find_by(name: "Forked Shop") - - data = { - before: "0000000000000000000000000000000000000000", - after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e", - ref: "refs/heads/new_design", - user_id: @user.id, - user_name: @user.name, - repository: { - name: @forked_project.name, - url: "localhost/rubinius", - description: "", - homepage: "localhost/rubinius", - private: true - } - } - - @event = Event.create( - project: @forked_project, - action: Event::PUSHED, - data: data, - author_id: @user.id - ) - end - - - step 'I click link edit "Merge Request On Forked Project"' do - find("#edit_merge_request").click - end - - step 'I see the edit page prefilled for "Merge Request On Forked Project"' do - current_path.should == edit_project_merge_request_path(@project, @merge_request) - page.should have_content "Edit merge request ##{@merge_request.id}" - find("#merge_request_title").value.should == "Merge Request On Forked Project" - find("#merge_request_source_project_id").value.should == @forked_project.id.to_s - find("#merge_request_target_project_id").value.should == @project.id.to_s - find("#merge_request_source_branch").value.should have_content "master" - verify_commit_link(".mr_source_commit",@forked_project) - find("#merge_request_target_branch").value.should have_content "stable" - verify_commit_link(".mr_target_commit",@project) - end - - step 'I fill out an invalid "Merge Request On Forked Project" merge request' do - #If this isn't filled in the rest of the validations won't be triggered - fill_in "merge_request_title", with: "Merge Request On Forked Project" - find(:select, "merge_request_source_project_id", {}).value.should == @forked_project.id.to_s - find(:select, "merge_request_target_project_id", {}).value.should == @forked_project.id.to_s - find(:select, "merge_request_source_branch", {}).value.should == "" - find(:select, "merge_request_target_branch", {}).value.should == "" - end - - step 'I should see validation errors' do - page.should have_content "Source branch can't be blank" - page.should have_content "Target branch can't be blank" - page.should have_content "Branch conflict You can not use same project/branch for source and target" - end - - def project - @project ||= Project.find_by!(name: "Shop") - end - - # Verify a link is generated against the correct project - def verify_commit_link(container_div, container_project) - # This should force a wait for the javascript to execute - find(:div,container_div).find(".commit_short_id")['href'].should have_content "#{container_project.path_with_namespace}/commit" - end -end diff --git a/features/steps/project/project_graph.rb b/features/steps/project/project_graph.rb deleted file mode 100644 index 89fe5fdeadf..00000000000 --- a/features/steps/project/project_graph.rb +++ /dev/null @@ -1,13 +0,0 @@ -class ProjectGraph < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - - Then 'page should have graphs' do - page.should have_selector ".stat-graph" - end - - When 'I visit project "Shop" graph page' do - project = Project.find_by(name: "Shop") - visit project_graph_path(project, "master") - end -end diff --git a/features/steps/project/project_hooks.rb b/features/steps/project/project_hooks.rb deleted file mode 100644 index 19ff3244543..00000000000 --- a/features/steps/project/project_hooks.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'webmock' - -class ProjectHooks < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include RSpec::Matchers - include RSpec::Mocks::ExampleMethods - include WebMock::API - - Given 'project has hook' do - @hook = create(:project_hook, project: current_project) - end - - Then 'I should see project hook' do - page.should have_content @hook.url - end - - When 'I submit new hook' do - @url = Faker::Internet.uri("http") - fill_in "hook_url", with: @url - expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1) - end - - Then 'I should see newly created hook' do - page.current_path.should == project_hooks_path(current_project) - page.should have_content(@url) - end - - When 'I click test hook button' do - stub_request(:post, @hook.url).to_return(status: 200) - click_link 'Test Hook' - end - - Then 'hook should be triggered' do - page.current_path.should == project_hooks_path(current_project) - end -end diff --git a/features/steps/project/project_issue_tracker.rb b/features/steps/project/project_issue_tracker.rb deleted file mode 100644 index c2fd4e15c9e..00000000000 --- a/features/steps/project/project_issue_tracker.rb +++ /dev/null @@ -1,31 +0,0 @@ -class ProjectIssueTracker < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'project "Shop" has issues enabled' do - @project = Project.find_by(name: "Shop") - @project ||= create(:project, name: "Shop", namespace: @user.namespace) - @project.issues_enabled = true - end - - step 'change the issue tracker to "GitLab"' do - select 'GitLab', from: 'project_issues_tracker' - end - - step 'I the project should have "GitLab" as issue tracker' do - find_field('project_issues_tracker').value.should == 'gitlab' - end - - step 'change the issue tracker to "Redmine"' do - select 'Redmine', from: 'project_issues_tracker' - end - - step 'I the project should have "Redmine" as issue tracker' do - find_field('project_issues_tracker').value.should == 'redmine' - end - - And 'I save project' do - click_button 'Save changes' - end -end diff --git a/features/steps/project/project_issues.rb b/features/steps/project/project_issues.rb deleted file mode 100644 index a92fd50584d..00000000000 --- a/features/steps/project/project_issues.rb +++ /dev/null @@ -1,145 +0,0 @@ -class ProjectIssues < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - include SharedMarkdown - - Given 'I should see "Release 0.4" in issues' do - page.should have_content "Release 0.4" - end - - And 'I should not see "Release 0.3" in issues' do - page.should_not have_content "Release 0.3" - end - - And 'I should not see "Tweet control" in issues' do - page.should_not have_content "Tweet control" - end - - Given 'I click link "Closed"' do - click_link "Closed" - end - - Then 'I should see "Release 0.3" in issues' do - page.should have_content "Release 0.3" - end - - And 'I should not see "Release 0.4" in issues' do - page.should_not have_content "Release 0.4" - end - - Given 'I click link "All"' do - click_link "All" - end - - Given 'I click link "Release 0.4"' do - click_link "Release 0.4" - end - - Then 'I should see issue "Release 0.4"' do - page.should have_content "Release 0.4" - end - - Given 'I click link "New Issue"' do - click_link "New Issue" - end - - And 'I submit new issue "500 error on profile"' do - fill_in "issue_title", with: "500 error on profile" - click_button "Submit new issue" - end - - Given 'I click link "500 error on profile"' do - click_link "500 error on profile" - end - - Then 'I should see issue "500 error on profile"' do - issue = Issue.find_by(title: "500 error on profile") - page.should have_content issue.title - page.should have_content issue.author_name - page.should have_content issue.project.name - end - - Given 'I fill in issue search with "Re"' do - fill_in 'issue_search', with: "Re" - end - - Given 'I fill in issue search with "Bu"' do - fill_in 'issue_search', with: "Bu" - end - - And 'I fill in issue search with ".3"' do - fill_in 'issue_search', with: ".3" - end - - And 'I fill in issue search with "Something"' do - fill_in 'issue_search', with: "Something" - end - - And 'I fill in issue search with ""' do - fill_in 'issue_search', with: "" - end - - Given 'project "Shop" has milestone "v2.2"' do - project = Project.find_by(name: "Shop") - milestone = create(:milestone, title: "v2.2", project: project) - - 3.times { create(:issue, project: project, milestone: milestone) } - end - - And 'project "Shop" has milestone "v3.0"' do - project = Project.find_by(name: "Shop") - milestone = create(:milestone, title: "v3.0", project: project) - - 3.times { create(:issue, project: project, milestone: milestone) } - end - - When 'I select milestone "v3.0"' do - select "v3.0", from: "milestone_id" - end - - Then 'I should see selected milestone with title "v3.0"' do - issues_milestone_selector = "#issue_milestone_id_chzn > a" - page.find(issues_milestone_selector).should have_content("v3.0") - end - - When 'I select first assignee from "Shop" project' do - project = Project.find_by(name: "Shop") - first_assignee = project.users.first - select first_assignee.name, from: "assignee_id" - end - - Then 'I should see first assignee from "Shop" as selected assignee' do - issues_assignee_selector = "#issue_assignee_id_chzn > a" - project = Project.find_by(name: "Shop") - assignee_name = project.users.first.name - page.find(issues_assignee_selector).should have_content(assignee_name) - end - - And 'project "Shop" have "Release 0.4" open issue' do - project = Project.find_by(name: "Shop") - create(:issue, - title: "Release 0.4", - project: project, - author: project.users.first, - description: "# Description header" - ) - end - - And 'project "Shop" have "Tweet control" open issue' do - project = Project.find_by(name: "Shop") - create(:issue, - title: "Tweet control", - project: project, - author: project.users.first) - end - - And 'project "Shop" have "Release 0.3" closed issue' do - project = Project.find_by(name: "Shop") - create(:closed_issue, - title: "Release 0.3", - project: project, - author: project.users.first) - end -end diff --git a/features/steps/project/project_labels.rb b/features/steps/project/project_labels.rb deleted file mode 100644 index 0907cdb526f..00000000000 --- a/features/steps/project/project_labels.rb +++ /dev/null @@ -1,24 +0,0 @@ -class ProjectLabels < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - Then 'I should see label "bug"' do - within ".labels-table" do - page.should have_content "bug" - end - end - - And 'I should see label "feature"' do - within ".labels-table" do - page.should have_content "feature" - end - end - - And 'project "Shop" have issues tags: "bug", "feature"' do - project = Project.find_by(name: "Shop") - ['bug', 'feature'].each do |label| - create(:issue, project: project, label_list: label) - end - end -end diff --git a/features/steps/project/project_markdown_render.rb b/features/steps/project/project_markdown_render.rb deleted file mode 100644 index 89fbb7408c2..00000000000 --- a/features/steps/project/project_markdown_render.rb +++ /dev/null @@ -1,207 +0,0 @@ -class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedMarkdown - - And 'I own project "Delta"' do - @project = Project.find_by(name: "Delta") - @project ||= create(:project, name: "Delta", namespace: @user.namespace) - @project.team << [@user, :master] - end - - Then 'I should see files from repository in master' do - current_path.should == project_tree_path(@project, "master") - page.should have_content "Gemfile" - page.should have_content "app" - page.should have_content "README" - end - - And 'I should see rendered README which contains correct links' do - page.should have_content "Welcome to GitLab GitLab is a free project and repository management application" - page.should have_link "GitLab API doc" - page.should have_link "GitLab API website" - page.should have_link "Rake tasks" - page.should have_link "backup and restore procedure" - page.should have_link "GitLab API doc directory" - page.should have_link "Maintenance" - end - - And 'I click on Gitlab API in README' do - click_link "GitLab API doc" - end - - Then 'I should see correct document rendered' do - current_path.should == project_blob_path(@project, "master/doc/api/README.md") - page.should have_content "All API requests require authentication" - end - - And 'I click on Rake tasks in README' do - click_link "Rake tasks" - end - - Then 'I should see correct directory rendered' do - current_path.should == project_tree_path(@project, "master/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" - end - - And 'I click on GitLab API doc directory in README' do - click_link "GitLab API doc directory" - end - - Then 'I should see correct doc/api directory rendered' do - current_path.should == project_tree_path(@project, "master/doc/api/") - page.should have_content "README.md" - page.should have_content "users.md" - end - - And 'I click on Maintenance in README' do - click_link "Maintenance" - end - - Then 'I should see correct maintenance file rendered' do - current_path.should == project_blob_path(@project, "master/doc/raketasks/maintenance.md") - page.should have_content "bundle exec rake gitlab:env:info RAILS_ENV=production" - end - - And 'I navigate to the doc/api/README' do - click_link "doc" - click_link "api" - click_link "README.md" - end - - And 'I see correct file rendered' do - current_path.should == project_blob_path(@project, "master/doc/api/README.md") - page.should have_content "Contents" - page.should have_link "Users" - page.should have_link "Rake tasks" - end - - And 'I click on users in doc/api/README' do - click_link "Users" - end - - Then 'I should see the correct document file' do - current_path.should == project_blob_path(@project, "master/doc/api/users.md") - page.should have_content "Get a list of users." - end - - And 'I click on raketasks in doc/api/README' do - click_link "Rake tasks" - end - - When 'I visit markdown branch' do - visit project_tree_path(@project, "markdown") - end - - Then 'I should see files from repository in markdown branch' do - current_path.should == project_tree_path(@project, "markdown") - page.should have_content "Gemfile" - page.should have_content "app" - page.should have_content "README" - end - - And 'I see correct file rendered in markdown branch' do - current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") - page.should have_content "Contents" - page.should have_link "Users" - page.should have_link "Rake tasks" - end - - Then 'I should see correct document rendered for markdown branch' do - current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") - page.should have_content "All API requests require authentication" - end - - Then 'I should see correct directory rendered for markdown branch' do - current_path.should == project_tree_path(@project, "markdown/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" - end - - Then 'I should see the users document file in markdown branch' do - current_path.should == project_blob_path(@project, "markdown/doc/api/users.md") - page.should have_content "Get a list of users." - end - - Given 'I go to wiki page' do - click_link "Wiki" - current_path.should == project_wiki_path(@project, "home") - end - - And 'I add various links to the wiki page' do - fill_in "wiki[content]", with: "[test](test)\n[GitLab API doc](doc/api/README.md)\n[Rake tasks](doc/raketasks)\n" - fill_in "wiki[message]", with: "Adding links to wiki" - click_button "Create page" - end - - Then 'Wiki page should have added links' do - current_path.should == project_wiki_path(@project, "home") - page.should have_content "test GitLab API doc Rake tasks" - end - - step 'I add a header to the wiki page' do - fill_in "wiki[content]", with: "# Wiki header\n" - fill_in "wiki[message]", with: "Add header to wiki" - click_button "Create page" - end - - step 'Wiki header should have correct id and link' do - header_should_have_correct_id_and_link(1, 'Wiki header', 'wiki-header') - end - - And 'I click on test link' do - click_link "test" - end - - Then 'I see new wiki page named test' do - current_path.should == project_wiki_path(@project, "test") - page.should have_content "Editing" - end - - When 'I go back to wiki page home' do - visit project_wiki_path(@project, "home") - current_path.should == project_wiki_path(@project, "home") - end - - And 'I click on GitLab API doc link' do - click_link "GitLab API" - end - - Then 'I see Gitlab API document' do - current_path.should == project_blob_path(@project, "master/doc/api/README.md") - page.should have_content "Status codes" - end - - And 'I click on Rake tasks link' do - click_link "Rake tasks" - end - - Then 'I see Rake tasks directory' do - current_path.should == project_tree_path(@project, "master/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" - end - - Given 'I go directory which contains README file' do - visit project_tree_path(@project, "master/doc/api") - current_path.should == project_tree_path(@project, "master/doc/api") - end - - And 'I click on a relative link in README' do - click_link "Users" - end - - Then 'I should see the correct markdown' do - current_path.should == project_blob_path(@project, "master/doc/api/users.md") - page.should have_content "List users" - end - - step 'Header "Application details" should have correct id and link' do - header_should_have_correct_id_and_link(2, 'Application details', 'application-details') - end - - step 'Header "GitLab API" should have correct id and link' do - header_should_have_correct_id_and_link(1, 'GitLab API', 'gitlab-api') - end -end diff --git a/features/steps/project/project_merge_requests.rb b/features/steps/project/project_merge_requests.rb deleted file mode 100644 index adf9e77e136..00000000000 --- a/features/steps/project/project_merge_requests.rb +++ /dev/null @@ -1,195 +0,0 @@ -class ProjectMergeRequests < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - include SharedMarkdown - - step 'I click link "New Merge Request"' do - click_link "New Merge Request" - end - - step 'I click link "Bug NS-04"' do - click_link "Bug NS-04" - end - - step 'I click link "All"' do - click_link "All" - end - - step 'I click link "Closed"' do - click_link "Closed" - end - - step 'I should see merge request "Wiki Feature"' do - within '.merge-request' do - page.should have_content "Wiki Feature" - end - end - - step 'I should see closed merge request "Bug NS-04"' do - merge_request = MergeRequest.find_by!(title: "Bug NS-04") - merge_request.closed?.should be_true - page.should have_content "Closed by" - end - - step 'I should see merge request "Bug NS-04"' do - page.should have_content "Bug NS-04" - end - - step 'I should see "Bug NS-04" in merge requests' do - page.should have_content "Bug NS-04" - end - - step 'I should see "Feature NS-03" in merge requests' do - page.should have_content "Feature NS-03" - end - - step 'I should not see "Feature NS-03" in merge requests' do - page.should_not have_content "Feature NS-03" - end - - - step 'I should not see "Bug NS-04" in merge requests' do - page.should_not have_content "Bug NS-04" - end - - step 'I click link "Close"' do - within '.page-title' do - click_link "Close" - end - end - - step 'I submit new merge request "Wiki Feature"' do - fill_in "merge_request_title", with: "Wiki Feature" - select "master", from: "merge_request_source_branch" - select "notes_refactoring", from: "merge_request_target_branch" - click_button "Submit merge request" - end - - step 'project "Shop" have "Bug NS-04" open merge request' do - create(:merge_request, - title: "Bug NS-04", - source_project: project, - target_project: project, - source_branch: 'stable', - target_branch: 'master', - author: project.users.first, - description: "# Description header" - ) - end - - step 'project "Shop" have "Bug NS-05" open merge request with diffs inside' do - create(:merge_request_with_diffs, - title: "Bug NS-05", - source_project: project, - target_project: project, - author: project.users.first) - end - - step 'project "Shop" have "Feature NS-03" closed merge request' do - create(:closed_merge_request, - title: "Feature NS-03", - source_project: project, - target_project: project, - author: project.users.first) - end - - step 'I switch to the diff tab' do - visit diffs_project_merge_request_path(project, merge_request) - end - - step 'I switch to the merge request\'s comments tab' do - visit project_merge_request_path(project, merge_request) - end - - step 'I click on the first commit in the merge request' do - within '.first-commits' do - click_link merge_request.commits.first.short_id(8) - end - end - - step 'I leave a comment on the diff page' do - init_diff_note - leave_comment "One comment to rule them all" - end - - step 'I leave a comment on the diff page in commit' do - find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click - leave_comment "One comment to rule them all" - end - - step 'I leave a comment like "Line is wrong" on line 185 of the first file' do - init_diff_note - leave_comment "Line is wrong" - end - - step 'I leave a comment like "Line is wrong" on line 185 of the first file in commit' do - find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click - leave_comment "Line is wrong" - end - - step 'I should see a discussion has started on line 185' do - page.should have_content "#{current_user.name} started a discussion on this merge request diff" - page.should have_content "app/assets/stylesheets/tree.scss:L185" - page.should have_content "Line is wrong" - end - - step 'I should see a discussion has started on commit b1e6a9dbf1:L185' do - page.should have_content "#{current_user.name} started a discussion on commit" - page.should have_content "app/assets/stylesheets/tree.scss:L185" - page.should have_content "Line is wrong" - end - - step 'I should see a discussion has started on commit b1e6a9dbf1' do - page.should have_content "#{current_user.name} started a discussion on commit" - page.should have_content "One comment to rule them all" - page.should have_content "app/assets/stylesheets/tree.scss:L185" - end - - step 'merge request is mergeable' do - page.should have_content 'You can accept this request automatically' - end - - step 'I modify merge commit message' do - find('.modify-merge-commit-link').click - fill_in 'merge_commit_message', with: "wow such merge" - end - - step 'merge request "Bug NS-05" is mergeable' do - merge_request.mark_as_mergeable - end - - step 'I accept this merge request' do - click_button "Accept Merge Request" - end - - step 'I should see merged request' do - within '.issue-box' do - page.should have_content "Merged" - end - end - - def project - @project ||= Project.find_by!(name: "Shop") - end - - def merge_request - @merge_request ||= MergeRequest.find_by!(title: "Bug NS-05") - end - - def init_diff_note - find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185"]').click - end - - def leave_comment(message) - within(".js-discussion-note-form") do - fill_in "note_note", with: message - click_button "Add Comment" - end - - within ".note-text" do - page.should have_content message - end - end -end diff --git a/features/steps/project/project_milestones.rb b/features/steps/project/project_milestones.rb deleted file mode 100644 index 9ce18fbaabd..00000000000 --- a/features/steps/project/project_milestones.rb +++ /dev/null @@ -1,59 +0,0 @@ -class ProjectMilestones < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include SharedMarkdown - - Then 'I should see milestone "v2.2"' do - milestone = @project.milestones.find_by(title: "v2.2") - page.should have_content(milestone.title[0..10]) - page.should have_content(milestone.expires_at) - page.should have_content("Browse Issues") - end - - Given 'I click link "v2.2"' do - click_link "v2.2" - end - - Given 'I click link "New Milestone"' do - click_link "New Milestone" - end - - And 'I submit new milestone "v2.3"' do - fill_in "milestone_title", with: "v2.3" - click_button "Create milestone" - end - - Then 'I should see milestone "v2.3"' do - milestone = @project.milestones.find_by(title: "v2.3") - page.should have_content(milestone.title[0..10]) - page.should have_content(milestone.expires_at) - page.should have_content("Browse Issues") - end - - And 'project "Shop" has milestone "v2.2"' do - project = Project.find_by(name: "Shop") - milestone = create(:milestone, - title: "v2.2", - project: project, - description: "# Description header" - ) - 3.times { create(:issue, project: project, milestone: milestone) } - end - - Given 'the milestone has open and closed issues' do - project = Project.find_by(name: "Shop") - milestone = project.milestones.find_by(title: 'v2.2') - - # 3 Open issues created above; create one closed issue - create(:closed_issue, project: project, milestone: milestone) - end - - When 'I click link "All Issues"' do - click_link 'All Issues' - end - - Then "I should see 3 issues" do - page.should have_selector('#tab-issues li', count: 4) - end -end diff --git a/features/steps/project/project_multiselect_blob.rb b/features/steps/project/project_multiselect_blob.rb deleted file mode 100644 index 3d330e837c1..00000000000 --- a/features/steps/project/project_multiselect_blob.rb +++ /dev/null @@ -1,58 +0,0 @@ -class ProjectMultiselectBlob < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - class << self - def click_line_steps(*line_numbers) - line_numbers.each do |line_number| - step "I click line #{line_number} in file" do - find("#L#{line_number}").click - end - - step "I shift-click line #{line_number} in file" do - script = "$('#L#{line_number}').trigger($.Event('click', { shiftKey: true }));" - page.evaluate_script(script) - end - end - end - - def check_state_steps(*ranges) - ranges.each do |range| - fragment = range.kind_of?(Array) ? "L#{range.first}-#{range.last}" : "L#{range}" - pluralization = range.kind_of?(Array) ? "s" : "" - - step "I should see \"#{fragment}\" as URI fragment" do - URI.parse(current_url).fragment.should == fragment - end - - step "I should see line#{pluralization} #{fragment[1..-1]} highlighted" do - ids = Array(range).map { |n| "LC#{n}" } - extra = false - - highlighted = all("#tree-content-holder .highlight .line.hll") - highlighted.each do |element| - extra ||= ids.delete(element[:id]).nil? - end - - extra.should be_false and ids.should be_empty - end - end - end - end - - click_line_steps *Array(1..5) - check_state_steps *Array(1..5), Array(1..2), Array(1..3), Array(1..4), Array(1..5), Array(3..5) - - step 'I go back in history' do - page.evaluate_script("window.history.back()") - end - - step 'I go forward in history' do - page.evaluate_script("window.history.forward()") - end - - step 'I click on "Gemfile.lock" file in repo' do - click_link "Gemfile.lock" - end -end \ No newline at end of file diff --git a/features/steps/project/project_network_graph.rb b/features/steps/project/project_network_graph.rb deleted file mode 100644 index 1c5cfcc6c68..00000000000 --- a/features/steps/project/project_network_graph.rb +++ /dev/null @@ -1,93 +0,0 @@ -class ProjectNetworkGraph < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - Then 'page should have network graph' do - page.should have_selector ".network-graph" - end - - When 'I visit project "Shop" network page' do - # Stub Graph max_size to speed up test (10 commits vs. 650) - Network::Graph.stub(max_count: 10) - - project = Project.find_by(name: "Shop") - visit project_network_path(project, "master") - end - - And 'page should select "master" in select box' do - page.should have_selector '.select2-chosen', text: "master" - end - - And 'page should select "v2.1.0" in select box' do - page.should have_selector '.select2-chosen', text: "v2.1.0" - end - - And 'page should have "master" on graph' do - within '.network-graph' do - page.should have_content 'master' - end - end - - When 'I switch ref to "stable"' do - page.select 'stable', from: 'ref' - sleep 2 - end - - When 'I switch ref to "v2.1.0"' do - page.select 'v2.1.0', from: 'ref' - sleep 2 - end - - When 'click "Show only selected branch" checkbox' do - find('#filter_ref').click - sleep 2 - end - - Then 'page should have content not containing "v2.1.0"' do - within '.network-graph' do - page.should have_content 'cleaning' - end - end - - Then 'page should not have content not containing "v2.1.0"' do - within '.network-graph' do - page.should_not have_content 'cleaning' - end - end - - And 'page should select "stable" in select box' do - page.should have_selector '.select2-chosen', text: "stable" - end - - And 'page should select "v2.1.0" in select box' do - page.should have_selector '.select2-chosen', text: "v2.1.0" - end - - And 'page should have "stable" on graph' do - within '.network-graph' do - page.should have_content 'stable' - end - end - - When 'I looking for a commit by SHA of "v2.1.0"' do - within ".network-form" do - fill_in 'extended_sha1', with: '98d6492' - find('button').click - end - sleep 2 - end - - And 'page should have "v2.1.0" on graph' do - within '.network-graph' do - page.should have_content 'v2.1.0' - end - end - - When 'I look for a commit by ";"' do - within ".network-form" do - fill_in 'extended_sha1', with: ';' - find('button').click - end - end -end diff --git a/features/steps/project/project_search_code.rb b/features/steps/project/project_search_code.rb deleted file mode 100644 index d117b019a15..00000000000 --- a/features/steps/project/project_search_code.rb +++ /dev/null @@ -1,17 +0,0 @@ -class ProjectSearchCode < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - When 'I search for term "Welcome to GitLab"' do - fill_in "search", with: "Welcome to GitLab" - click_button "Go" - click_link 'Repository Code' - end - - Then 'I should see files from repository containing "Welcome to GitLab"' do - page.should have_content "Welcome to GitLab" - page.should have_content "GitLab is a free project and repository management application" - end - -end diff --git a/features/steps/project/project_services.rb b/features/steps/project/project_services.rb deleted file mode 100644 index 54b3f18e084..00000000000 --- a/features/steps/project/project_services.rb +++ /dev/null @@ -1,103 +0,0 @@ -class ProjectServices < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I visit project "Shop" services page' do - visit project_services_path(@project) - end - - step 'I should see list of available services' do - page.should have_content 'Project services' - page.should have_content 'Campfire' - page.should have_content 'Hipchat' - page.should have_content 'GitLab CI' - page.should have_content 'Assembla' - end - - step 'I click gitlab-ci service link' do - click_link 'GitLab CI' - end - - step 'I fill gitlab-ci settings' do - check 'Active' - fill_in 'Project url', with: 'http://ci.gitlab.org/projects/3' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see service settings saved' do - find_field('Project url').value.should == 'http://ci.gitlab.org/projects/3' - end - - step 'I click hipchat service link' do - click_link 'Hipchat' - end - - step 'I fill hipchat settings' do - check 'Active' - fill_in 'Room', with: 'gitlab' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see hipchat service settings saved' do - find_field('Room').value.should == 'gitlab' - end - - - step 'I click pivotaltracker service link' do - click_link 'PivotalTracker' - end - - step 'I fill pivotaltracker settings' do - check 'Active' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see pivotaltracker service settings saved' do - find_field('Token').value.should == 'verySecret' - end - - step 'I click Flowdock service link' do - click_link 'Flowdock' - end - - step 'I fill Flowdock settings' do - check 'Active' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see Flowdock service settings saved' do - find_field('Token').value.should == 'verySecret' - end - - step 'I click Assembla service link' do - click_link 'Assembla' - end - - step 'I fill Assembla settings' do - check 'Active' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see Assembla service settings saved' do - find_field('Token').value.should == 'verySecret' - end - - step 'I click email on push service link' do - click_link 'Emails on push' - end - - step 'I fill email on push settings' do - fill_in 'Recipients', with: 'qa@company.name' - click_button 'Save' - end - - step 'I should see email on push service settings saved' do - find_field('Recipients').value.should == 'qa@company.name' - end -end diff --git a/features/steps/project/project_snippets.rb b/features/steps/project/project_snippets.rb deleted file mode 100644 index c3a76bea269..00000000000 --- a/features/steps/project/project_snippets.rb +++ /dev/null @@ -1,99 +0,0 @@ -class ProjectSnippets < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - - And 'project "Shop" have "Snippet one" snippet' do - create(:project_snippet, - title: "Snippet one", - content: "Test content", - file_name: "snippet.rb", - project: project, - author: project.users.first) - end - - And 'project "Shop" have no "Snippet two" snippet' do - create(:snippet, - title: "Snippet two", - content: "Test content", - file_name: "snippet.rb", - author: project.users.first) - end - - Given 'I click link "New Snippet"' do - click_link "Add new snippet" - end - - Given 'I click link "Snippet one"' do - click_link "Snippet one" - end - - Then 'I should see "Snippet one" in snippets' do - page.should have_content "Snippet one" - end - - And 'I should not see "Snippet two" in snippets' do - page.should_not have_content "Snippet two" - end - - And 'I should not see "Snippet one" in snippets' do - page.should_not have_content "Snippet one" - end - - And 'I click link "Edit"' do - within ".file-title" do - click_link "Edit" - end - end - - And 'I click link "Remove Snippet"' do - click_link "Remove snippet" - end - - And 'I submit new snippet "Snippet three"' do - fill_in "project_snippet_title", :with => "Snippet three" - fill_in "project_snippet_file_name", :with => "my_snippet.rb" - within('.file-editor') do - find(:xpath, "//input[@id='project_snippet_content']").set 'Content of snippet three' - end - click_button "Create snippet" - end - - Then 'I should see snippet "Snippet three"' do - page.should have_content "Snippet three" - page.should have_content "Content of snippet three" - end - - And 'I submit new title "Snippet new title"' do - fill_in "project_snippet_title", :with => "Snippet new title" - click_button "Save" - end - - Then 'I should see "Snippet new title"' do - page.should have_content "Snippet new title" - end - - And 'I leave a comment like "Good snippet!"' do - within('.js-main-target-form') do - fill_in "note_note", with: "Good snippet!" - click_button "Add Comment" - end - end - - Then 'I should see comment "Good snippet!"' do - page.should have_content "Good snippet!" - end - - And 'I visit snippet page "Snippet one"' do - visit project_snippet_path(project, project_snippet) - end - - def project - @project ||= Project.find_by!(name: "Shop") - end - - def project_snippet - @project_snippet ||= ProjectSnippet.find_by!(title: "Snippet one") - end -end diff --git a/features/steps/project/project_team_management.rb b/features/steps/project/project_team_management.rb deleted file mode 100644 index ffc5016529f..00000000000 --- a/features/steps/project/project_team_management.rb +++ /dev/null @@ -1,107 +0,0 @@ -class ProjectTeamManagement < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include Select2Helper - - Then 'I should be able to see myself in team' do - page.should have_content(@user.name) - page.should have_content(@user.username) - end - - And 'I should see "Sam" in team list' do - user = User.find_by(name: "Sam") - page.should have_content(user.name) - page.should have_content(user.username) - end - - Given 'I click link "New Team Member"' do - click_link "New project member" - end - - And 'I select "Mike" as "Reporter"' do - user = User.find_by(name: "Mike") - - select2(user.id, from: "#user_ids", multiple: true) - within "#new_team_member" do - select "Reporter", from: "project_access" - end - click_button "Add users" - end - - Then 'I should see "Mike" in team list as "Reporter"' do - within ".access-reporter" do - page.should have_content('Mike') - end - end - - Given 'I should see "Sam" in team list as "Developer"' do - within ".access-developer" do - page.should have_content('Sam') - end - end - - And 'I change "Sam" role to "Reporter"' do - user = User.find_by(name: "Sam") - within "#user_#{user.id}" do - select "Reporter", from: "team_member_project_access" - end - end - - And 'I should see "Sam" in team list as "Reporter"' do - within ".access-reporter" do - page.should have_content('Sam') - end - end - - And 'I click link "Remove from team"' do - click_link "Remove from team" - end - - And 'I should not see "Sam" in team list' do - user = User.find_by(name: "Sam") - page.should_not have_content(user.name) - page.should_not have_content(user.username) - end - - And 'gitlab user "Mike"' do - create(:user, name: "Mike") - end - - And 'gitlab user "Sam"' do - create(:user, name: "Sam") - end - - And '"Sam" is "Shop" developer' do - user = User.find_by(name: "Sam") - project = Project.find_by(name: "Shop") - project.team << [user, :developer] - end - - Given 'I own project "Website"' do - @project = create(:empty_project, name: "Website", namespace: @user.namespace) - @project.team << [@user, :master] - end - - And '"Mike" is "Website" reporter' do - user = User.find_by(name: "Mike") - project = Project.find_by(name: "Website") - project.team << [user, :reporter] - end - - And 'I click link "Import team from another project"' do - click_link "Import members from another project" - end - - When 'I submit "Website" project for import team' do - project = Project.find_by(name: "Website") - select project.name_with_namespace, from: 'source_project_id' - click_button 'Import' - end - - step 'I click cancel link for "Sam"' do - within "#user_#{User.find_by(name: 'Sam').id}" do - click_link('Remove user from team') - end - end -end diff --git a/features/steps/project/project_wall.rb b/features/steps/project/project_wall.rb deleted file mode 100644 index 7c61580eb2c..00000000000 --- a/features/steps/project/project_wall.rb +++ /dev/null @@ -1,18 +0,0 @@ -class ProjectWall < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - - - Given 'I write new comment "my special test message"' do - within(".wall-note-form") do - fill_in "note[note]", with: "my special test message" - click_button "Add Comment" - end - end - - Then 'I should see project wall note "my special test message"' do - page.should have_content "my special test message" - end -end diff --git a/features/steps/project/project_wiki.rb b/features/steps/project/project_wiki.rb deleted file mode 100644 index 6146599cc4a..00000000000 --- a/features/steps/project/project_wiki.rb +++ /dev/null @@ -1,92 +0,0 @@ -class ProjectWiki < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - - Given 'I click on the Cancel button' do - within(:css, ".form-actions") do - click_on "Cancel" - end - end - - Then 'I should be redirected back to the Edit Home Wiki page' do - url = URI.parse(current_url) - url.path.should == project_wiki_path(project, :home) - end - - Given 'I create the Wiki Home page' do - fill_in "Content", with: '[link test](test)' - click_on "Create page" - end - - Then 'I should see the newly created wiki page' do - page.should have_content "Home" - page.should have_content "link test" - - click_link "link test" - page.should have_content "Editing" - end - - Given 'I have an existing Wiki page' do - wiki.create_page("existing", "content", :markdown, "first commit") - @page = wiki.find_page("existing") - end - - And 'I browse to that Wiki page' do - visit project_wiki_path(project, @page) - end - - And 'I click on the Edit button' do - click_on "Edit" - end - - And 'I change the content' do - fill_in "Content", with: 'Updated Wiki Content' - click_on "Save changes" - end - - Then 'I should see the updated content' do - page.should have_content "Updated Wiki Content" - end - - Then 'I should be redirected back to that Wiki page' do - url = URI.parse(current_url) - url.path.should == project_wiki_path(project, @page) - end - - And 'That page has two revisions' do - @page.update("new content", :markdown, "second commit") - end - - And 'I click the History button' do - click_on "History" - end - - Then 'I should see both revisions' do - page.should have_content current_user.name - page.should have_content "first commit" - page.should have_content "second commit" - end - - And 'I click on the "Delete this page" button' do - click_on "Delete this page" - end - - Then 'The page should be deleted' do - page.should have_content "Page was successfully deleted" - end - - And 'I click on the "Pages" button' do - click_on "Pages" - end - - Then 'I should see the existing page in the pages list' do - page.should have_content current_user.name - page.should have_content @page.title.titleize - end - - def wiki - @gollum_wiki = GollumWiki.new(project, current_user) - end -end diff --git a/features/steps/project/public.rb b/features/steps/project/public.rb new file mode 100644 index 00000000000..7063e7d56ae --- /dev/null +++ b/features/steps/project/public.rb @@ -0,0 +1,9 @@ +class PublicProjects < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + Then 'I should see the list of public projects' do + page.should have_content "Public Projects" + end +end diff --git a/features/steps/project/public_projects.rb b/features/steps/project/public_projects.rb deleted file mode 100644 index 7063e7d56ae..00000000000 --- a/features/steps/project/public_projects.rb +++ /dev/null @@ -1,9 +0,0 @@ -class PublicProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - Then 'I should see the list of public projects' do - page.should have_content "Public Projects" - end -end diff --git a/features/steps/project/search_code.rb b/features/steps/project/search_code.rb new file mode 100644 index 00000000000..d117b019a15 --- /dev/null +++ b/features/steps/project/search_code.rb @@ -0,0 +1,17 @@ +class ProjectSearchCode < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + When 'I search for term "Welcome to GitLab"' do + fill_in "search", with: "Welcome to GitLab" + click_button "Go" + click_link 'Repository Code' + end + + Then 'I should see files from repository containing "Welcome to GitLab"' do + page.should have_content "Welcome to GitLab" + page.should have_content "GitLab is a free project and repository management application" + end + +end diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb new file mode 100644 index 00000000000..54b3f18e084 --- /dev/null +++ b/features/steps/project/services.rb @@ -0,0 +1,103 @@ +class ProjectServices < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I visit project "Shop" services page' do + visit project_services_path(@project) + end + + step 'I should see list of available services' do + page.should have_content 'Project services' + page.should have_content 'Campfire' + page.should have_content 'Hipchat' + page.should have_content 'GitLab CI' + page.should have_content 'Assembla' + end + + step 'I click gitlab-ci service link' do + click_link 'GitLab CI' + end + + step 'I fill gitlab-ci settings' do + check 'Active' + fill_in 'Project url', with: 'http://ci.gitlab.org/projects/3' + fill_in 'Token', with: 'verySecret' + click_button 'Save' + end + + step 'I should see service settings saved' do + find_field('Project url').value.should == 'http://ci.gitlab.org/projects/3' + end + + step 'I click hipchat service link' do + click_link 'Hipchat' + end + + step 'I fill hipchat settings' do + check 'Active' + fill_in 'Room', with: 'gitlab' + fill_in 'Token', with: 'verySecret' + click_button 'Save' + end + + step 'I should see hipchat service settings saved' do + find_field('Room').value.should == 'gitlab' + end + + + step 'I click pivotaltracker service link' do + click_link 'PivotalTracker' + end + + step 'I fill pivotaltracker settings' do + check 'Active' + fill_in 'Token', with: 'verySecret' + click_button 'Save' + end + + step 'I should see pivotaltracker service settings saved' do + find_field('Token').value.should == 'verySecret' + end + + step 'I click Flowdock service link' do + click_link 'Flowdock' + end + + step 'I fill Flowdock settings' do + check 'Active' + fill_in 'Token', with: 'verySecret' + click_button 'Save' + end + + step 'I should see Flowdock service settings saved' do + find_field('Token').value.should == 'verySecret' + end + + step 'I click Assembla service link' do + click_link 'Assembla' + end + + step 'I fill Assembla settings' do + check 'Active' + fill_in 'Token', with: 'verySecret' + click_button 'Save' + end + + step 'I should see Assembla service settings saved' do + find_field('Token').value.should == 'verySecret' + end + + step 'I click email on push service link' do + click_link 'Emails on push' + end + + step 'I fill email on push settings' do + fill_in 'Recipients', with: 'qa@company.name' + click_button 'Save' + end + + step 'I should see email on push service settings saved' do + find_field('Recipients').value.should == 'qa@company.name' + end +end diff --git a/features/steps/project/snippets.rb b/features/steps/project/snippets.rb new file mode 100644 index 00000000000..c3a76bea269 --- /dev/null +++ b/features/steps/project/snippets.rb @@ -0,0 +1,99 @@ +class ProjectSnippets < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedNote + include SharedPaths + + And 'project "Shop" have "Snippet one" snippet' do + create(:project_snippet, + title: "Snippet one", + content: "Test content", + file_name: "snippet.rb", + project: project, + author: project.users.first) + end + + And 'project "Shop" have no "Snippet two" snippet' do + create(:snippet, + title: "Snippet two", + content: "Test content", + file_name: "snippet.rb", + author: project.users.first) + end + + Given 'I click link "New Snippet"' do + click_link "Add new snippet" + end + + Given 'I click link "Snippet one"' do + click_link "Snippet one" + end + + Then 'I should see "Snippet one" in snippets' do + page.should have_content "Snippet one" + end + + And 'I should not see "Snippet two" in snippets' do + page.should_not have_content "Snippet two" + end + + And 'I should not see "Snippet one" in snippets' do + page.should_not have_content "Snippet one" + end + + And 'I click link "Edit"' do + within ".file-title" do + click_link "Edit" + end + end + + And 'I click link "Remove Snippet"' do + click_link "Remove snippet" + end + + And 'I submit new snippet "Snippet three"' do + fill_in "project_snippet_title", :with => "Snippet three" + fill_in "project_snippet_file_name", :with => "my_snippet.rb" + within('.file-editor') do + find(:xpath, "//input[@id='project_snippet_content']").set 'Content of snippet three' + end + click_button "Create snippet" + end + + Then 'I should see snippet "Snippet three"' do + page.should have_content "Snippet three" + page.should have_content "Content of snippet three" + end + + And 'I submit new title "Snippet new title"' do + fill_in "project_snippet_title", :with => "Snippet new title" + click_button "Save" + end + + Then 'I should see "Snippet new title"' do + page.should have_content "Snippet new title" + end + + And 'I leave a comment like "Good snippet!"' do + within('.js-main-target-form') do + fill_in "note_note", with: "Good snippet!" + click_button "Add Comment" + end + end + + Then 'I should see comment "Good snippet!"' do + page.should have_content "Good snippet!" + end + + And 'I visit snippet page "Snippet one"' do + visit project_snippet_path(project, project_snippet) + end + + def project + @project ||= Project.find_by!(name: "Shop") + end + + def project_snippet + @project_snippet ||= ProjectSnippet.find_by!(title: "Snippet one") + end +end diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb new file mode 100644 index 00000000000..ffc5016529f --- /dev/null +++ b/features/steps/project/team_management.rb @@ -0,0 +1,107 @@ +class ProjectTeamManagement < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + include Select2Helper + + Then 'I should be able to see myself in team' do + page.should have_content(@user.name) + page.should have_content(@user.username) + end + + And 'I should see "Sam" in team list' do + user = User.find_by(name: "Sam") + page.should have_content(user.name) + page.should have_content(user.username) + end + + Given 'I click link "New Team Member"' do + click_link "New project member" + end + + And 'I select "Mike" as "Reporter"' do + user = User.find_by(name: "Mike") + + select2(user.id, from: "#user_ids", multiple: true) + within "#new_team_member" do + select "Reporter", from: "project_access" + end + click_button "Add users" + end + + Then 'I should see "Mike" in team list as "Reporter"' do + within ".access-reporter" do + page.should have_content('Mike') + end + end + + Given 'I should see "Sam" in team list as "Developer"' do + within ".access-developer" do + page.should have_content('Sam') + end + end + + And 'I change "Sam" role to "Reporter"' do + user = User.find_by(name: "Sam") + within "#user_#{user.id}" do + select "Reporter", from: "team_member_project_access" + end + end + + And 'I should see "Sam" in team list as "Reporter"' do + within ".access-reporter" do + page.should have_content('Sam') + end + end + + And 'I click link "Remove from team"' do + click_link "Remove from team" + end + + And 'I should not see "Sam" in team list' do + user = User.find_by(name: "Sam") + page.should_not have_content(user.name) + page.should_not have_content(user.username) + end + + And 'gitlab user "Mike"' do + create(:user, name: "Mike") + end + + And 'gitlab user "Sam"' do + create(:user, name: "Sam") + end + + And '"Sam" is "Shop" developer' do + user = User.find_by(name: "Sam") + project = Project.find_by(name: "Shop") + project.team << [user, :developer] + end + + Given 'I own project "Website"' do + @project = create(:empty_project, name: "Website", namespace: @user.namespace) + @project.team << [@user, :master] + end + + And '"Mike" is "Website" reporter' do + user = User.find_by(name: "Mike") + project = Project.find_by(name: "Website") + project.team << [user, :reporter] + end + + And 'I click link "Import team from another project"' do + click_link "Import members from another project" + end + + When 'I submit "Website" project for import team' do + project = Project.find_by(name: "Website") + select project.name_with_namespace, from: 'source_project_id' + click_button 'Import' + end + + step 'I click cancel link for "Sam"' do + within "#user_#{User.find_by(name: 'Sam').id}" do + click_link('Remove user from team') + end + end +end diff --git a/features/steps/project/wall.rb b/features/steps/project/wall.rb new file mode 100644 index 00000000000..7c61580eb2c --- /dev/null +++ b/features/steps/project/wall.rb @@ -0,0 +1,18 @@ +class ProjectWall < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedNote + include SharedPaths + + + Given 'I write new comment "my special test message"' do + within(".wall-note-form") do + fill_in "note[note]", with: "my special test message" + click_button "Add Comment" + end + end + + Then 'I should see project wall note "my special test message"' do + page.should have_content "my special test message" + end +end diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb new file mode 100644 index 00000000000..6146599cc4a --- /dev/null +++ b/features/steps/project/wiki.rb @@ -0,0 +1,92 @@ +class ProjectWiki < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedNote + include SharedPaths + + Given 'I click on the Cancel button' do + within(:css, ".form-actions") do + click_on "Cancel" + end + end + + Then 'I should be redirected back to the Edit Home Wiki page' do + url = URI.parse(current_url) + url.path.should == project_wiki_path(project, :home) + end + + Given 'I create the Wiki Home page' do + fill_in "Content", with: '[link test](test)' + click_on "Create page" + end + + Then 'I should see the newly created wiki page' do + page.should have_content "Home" + page.should have_content "link test" + + click_link "link test" + page.should have_content "Editing" + end + + Given 'I have an existing Wiki page' do + wiki.create_page("existing", "content", :markdown, "first commit") + @page = wiki.find_page("existing") + end + + And 'I browse to that Wiki page' do + visit project_wiki_path(project, @page) + end + + And 'I click on the Edit button' do + click_on "Edit" + end + + And 'I change the content' do + fill_in "Content", with: 'Updated Wiki Content' + click_on "Save changes" + end + + Then 'I should see the updated content' do + page.should have_content "Updated Wiki Content" + end + + Then 'I should be redirected back to that Wiki page' do + url = URI.parse(current_url) + url.path.should == project_wiki_path(project, @page) + end + + And 'That page has two revisions' do + @page.update("new content", :markdown, "second commit") + end + + And 'I click the History button' do + click_on "History" + end + + Then 'I should see both revisions' do + page.should have_content current_user.name + page.should have_content "first commit" + page.should have_content "second commit" + end + + And 'I click on the "Delete this page" button' do + click_on "Delete this page" + end + + Then 'The page should be deleted' do + page.should have_content "Page was successfully deleted" + end + + And 'I click on the "Pages" button' do + click_on "Pages" + end + + Then 'I should see the existing page in the pages list' do + page.should have_content current_user.name + page.should have_content @page.title.titleize + end + + def wiki + @gollum_wiki = GollumWiki.new(project, current_user) + end +end diff --git a/features/steps/public/projects.rb b/features/steps/public/projects.rb new file mode 100644 index 00000000000..eb1d235f435 --- /dev/null +++ b/features/steps/public/projects.rb @@ -0,0 +1,172 @@ +class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + step 'public empty project "Empty Public Project"' do + create :empty_project, name: 'Empty Public Project', visibility_level: Gitlab::VisibilityLevel::PUBLIC + end + + step 'I should see project "Empty Public Project"' do + page.should have_content "Empty Public Project" + end + + step 'I should see public project details' do + page.should have_content '32 branches' + page.should have_content '16 tags' + end + + step 'I should see project readme' do + page.should have_content 'README.md' + end + + step 'I visit empty project page' do + project = Project.find_by(name: 'Empty Public Project') + visit project_path(project) + end + + step 'I visit project "Community" page' do + project = Project.find_by(name: 'Community') + visit project_path(project) + end + + step 'I should see empty public project details' do + page.should have_content 'Git global setup' + end + + step 'I should see empty public project details with http clone info' do + project = Project.find_by(name: 'Empty Public Project') + page.all(:css, '.git-empty .clone').each do |element| + element.text.should include(project.http_url_to_repo) + end + end + + step 'I should see empty public project details with ssh clone info' do + project = Project.find_by(name: 'Empty Public Project') + page.all(:css, '.git-empty .clone').each do |element| + element.text.should include(project.url_to_repo) + end + end + + step 'I visit project "Enterprise" page' do + project = Project.find_by(name: 'Enterprise') + visit project_path(project) + end + + step 'I should see project "Community" home page' do + within '.project-home-title' do + page.should have_content 'Community' + end + end + + step 'I visit project "Internal" page' do + project = Project.find_by(name: 'Internal') + visit project_path(project) + end + + step 'I should see project "Internal" home page' do + within '.project-home-title' do + page.should have_content 'Internal' + end + end + + step 'I should see an http link to the repository' do + project = Project.find_by(name: 'Community') + page.should have_field('project_clone', with: project.http_url_to_repo) + end + + step 'I should see an ssh link to the repository' do + project = Project.find_by(name: 'Community') + page.should have_field('project_clone', with: project.url_to_repo) + end + + step 'I visit "Community" issues page' do + create(:issue, + title: "Bug", + project: public_project + ) + create(:issue, + title: "New feature", + project: public_project + ) + visit project_issues_path(public_project) + end + + + step 'I should see list of issues for "Community" project' do + page.should have_content "Bug" + page.should have_content public_project.name + page.should have_content "New feature" + end + + step 'I visit "Internal" issues page' do + create(:issue, + title: "Internal Bug", + project: internal_project + ) + create(:issue, + title: "New internal feature", + project: internal_project + ) + visit project_issues_path(internal_project) + end + + + step 'I should see list of issues for "Internal" project' do + page.should have_content "Internal Bug" + page.should have_content internal_project.name + page.should have_content "New internal feature" + end + + step 'I visit "Community" merge requests page' do + visit project_merge_requests_path(public_project) + end + + step 'project "Community" has "Bug fix" open merge request' do + create(:merge_request, + title: "Bug fix for public project", + source_project: public_project, + target_project: public_project, + ) + end + + step 'I should see list of merge requests for "Community" project' do + page.should have_content public_project.name + page.should have_content public_merge_request.source_project.name + end + + step 'I visit "Internal" merge requests page' do + visit project_merge_requests_path(internal_project) + end + + step 'project "Internal" has "Feature implemented" open merge request' do + create(:merge_request, + title: "Feature implemented", + source_project: internal_project, + target_project: internal_project + ) + end + + step 'I should see list of merge requests for "Internal" project' do + page.should have_content internal_project.name + page.should have_content internal_merge_request.source_project.name + end + + def internal_project + @internal_project ||= Project.find_by!(name: 'Internal') + end + + def public_project + @public_project ||= Project.find_by!(name: 'Community') + end + + + def internal_merge_request + @internal_merge_request ||= MergeRequest.find_by!(title: 'Feature implemented') + end + + def public_merge_request + @public_merge_request ||= MergeRequest.find_by!(title: 'Bug fix for public project') + end +end + diff --git a/features/steps/public/projects_feature.rb b/features/steps/public/projects_feature.rb deleted file mode 100644 index eb1d235f435..00000000000 --- a/features/steps/public/projects_feature.rb +++ /dev/null @@ -1,172 +0,0 @@ -class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'public empty project "Empty Public Project"' do - create :empty_project, name: 'Empty Public Project', visibility_level: Gitlab::VisibilityLevel::PUBLIC - end - - step 'I should see project "Empty Public Project"' do - page.should have_content "Empty Public Project" - end - - step 'I should see public project details' do - page.should have_content '32 branches' - page.should have_content '16 tags' - end - - step 'I should see project readme' do - page.should have_content 'README.md' - end - - step 'I visit empty project page' do - project = Project.find_by(name: 'Empty Public Project') - visit project_path(project) - end - - step 'I visit project "Community" page' do - project = Project.find_by(name: 'Community') - visit project_path(project) - end - - step 'I should see empty public project details' do - page.should have_content 'Git global setup' - end - - step 'I should see empty public project details with http clone info' do - project = Project.find_by(name: 'Empty Public Project') - page.all(:css, '.git-empty .clone').each do |element| - element.text.should include(project.http_url_to_repo) - end - end - - step 'I should see empty public project details with ssh clone info' do - project = Project.find_by(name: 'Empty Public Project') - page.all(:css, '.git-empty .clone').each do |element| - element.text.should include(project.url_to_repo) - end - end - - step 'I visit project "Enterprise" page' do - project = Project.find_by(name: 'Enterprise') - visit project_path(project) - end - - step 'I should see project "Community" home page' do - within '.project-home-title' do - page.should have_content 'Community' - end - end - - step 'I visit project "Internal" page' do - project = Project.find_by(name: 'Internal') - visit project_path(project) - end - - step 'I should see project "Internal" home page' do - within '.project-home-title' do - page.should have_content 'Internal' - end - end - - step 'I should see an http link to the repository' do - project = Project.find_by(name: 'Community') - page.should have_field('project_clone', with: project.http_url_to_repo) - end - - step 'I should see an ssh link to the repository' do - project = Project.find_by(name: 'Community') - page.should have_field('project_clone', with: project.url_to_repo) - end - - step 'I visit "Community" issues page' do - create(:issue, - title: "Bug", - project: public_project - ) - create(:issue, - title: "New feature", - project: public_project - ) - visit project_issues_path(public_project) - end - - - step 'I should see list of issues for "Community" project' do - page.should have_content "Bug" - page.should have_content public_project.name - page.should have_content "New feature" - end - - step 'I visit "Internal" issues page' do - create(:issue, - title: "Internal Bug", - project: internal_project - ) - create(:issue, - title: "New internal feature", - project: internal_project - ) - visit project_issues_path(internal_project) - end - - - step 'I should see list of issues for "Internal" project' do - page.should have_content "Internal Bug" - page.should have_content internal_project.name - page.should have_content "New internal feature" - end - - step 'I visit "Community" merge requests page' do - visit project_merge_requests_path(public_project) - end - - step 'project "Community" has "Bug fix" open merge request' do - create(:merge_request, - title: "Bug fix for public project", - source_project: public_project, - target_project: public_project, - ) - end - - step 'I should see list of merge requests for "Community" project' do - page.should have_content public_project.name - page.should have_content public_merge_request.source_project.name - end - - step 'I visit "Internal" merge requests page' do - visit project_merge_requests_path(internal_project) - end - - step 'project "Internal" has "Feature implemented" open merge request' do - create(:merge_request, - title: "Feature implemented", - source_project: internal_project, - target_project: internal_project - ) - end - - step 'I should see list of merge requests for "Internal" project' do - page.should have_content internal_project.name - page.should have_content internal_merge_request.source_project.name - end - - def internal_project - @internal_project ||= Project.find_by!(name: 'Internal') - end - - def public_project - @public_project ||= Project.find_by!(name: 'Community') - end - - - def internal_merge_request - @internal_merge_request ||= MergeRequest.find_by!(title: 'Feature implemented') - end - - def public_merge_request - @public_merge_request ||= MergeRequest.find_by!(title: 'Bug fix for public project') - end -end - diff --git a/features/steps/snippets/discover.rb b/features/steps/snippets/discover.rb new file mode 100644 index 00000000000..09337937002 --- /dev/null +++ b/features/steps/snippets/discover.rb @@ -0,0 +1,17 @@ +class DiscoverSnippets < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedSnippet + + Then 'I should see "Personal snippet one" in snippets' do + page.should have_content "Personal snippet one" + end + + And 'I should not see "Personal snippet private" in snippets' do + page.should_not have_content "Personal snippet private" + end + + def snippet + @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") + end +end diff --git a/features/steps/snippets/discover_snippets.rb b/features/steps/snippets/discover_snippets.rb deleted file mode 100644 index 09337937002..00000000000 --- a/features/steps/snippets/discover_snippets.rb +++ /dev/null @@ -1,17 +0,0 @@ -class DiscoverSnippets < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedSnippet - - Then 'I should see "Personal snippet one" in snippets' do - page.should have_content "Personal snippet one" - end - - And 'I should not see "Personal snippet private" in snippets' do - page.should_not have_content "Personal snippet private" - end - - def snippet - @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") - end -end diff --git a/features/steps/snippets/user.rb b/features/steps/snippets/user.rb new file mode 100644 index 00000000000..2d7ffc866e7 --- /dev/null +++ b/features/steps/snippets/user.rb @@ -0,0 +1,41 @@ +class UserSnippets < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedSnippet + + Given 'I visit my snippets page' do + visit user_snippets_path(current_user) + end + + Then 'I should see "Personal snippet one" in snippets' do + page.should have_content "Personal snippet one" + end + + And 'I should see "Personal snippet private" in snippets' do + page.should have_content "Personal snippet private" + end + + Then 'I should not see "Personal snippet one" in snippets' do + page.should_not have_content "Personal snippet one" + end + + And 'I should not see "Personal snippet private" in snippets' do + page.should_not have_content "Personal snippet private" + end + + Given 'I click "Public" filter' do + within('.nav-stacked') do + click_link "Public" + end + end + + Given 'I click "Private" filter' do + within('.nav-stacked') do + click_link "Private" + end + end + + def snippet + @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") + end +end diff --git a/features/steps/snippets/user_snippets.rb b/features/steps/snippets/user_snippets.rb deleted file mode 100644 index 2d7ffc866e7..00000000000 --- a/features/steps/snippets/user_snippets.rb +++ /dev/null @@ -1,41 +0,0 @@ -class UserSnippets < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedSnippet - - Given 'I visit my snippets page' do - visit user_snippets_path(current_user) - end - - Then 'I should see "Personal snippet one" in snippets' do - page.should have_content "Personal snippet one" - end - - And 'I should see "Personal snippet private" in snippets' do - page.should have_content "Personal snippet private" - end - - Then 'I should not see "Personal snippet one" in snippets' do - page.should_not have_content "Personal snippet one" - end - - And 'I should not see "Personal snippet private" in snippets' do - page.should_not have_content "Personal snippet private" - end - - Given 'I click "Public" filter' do - within('.nav-stacked') do - click_link "Public" - end - end - - Given 'I click "Private" filter' do - within('.nav-stacked') do - click_link "Private" - end - end - - def snippet - @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") - end -end -- cgit v1.2.3 From 5818cf063bda5f6a96ccefe086b64a3699dd2c67 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 24 Feb 2014 15:31:58 +0100 Subject: Don't send an email for "mentioned in" notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, an email is sent every time a mentionable is referenced by an issue, a commit or a merge request: if I comment "This MR is related to #5", watchers get one email for the comment, and another one stating "Issue #5 was mentioned by issue #13". This is annoying — but the biggest issue is when pushing an existing branch. Every issue referenced by commit messages in this branch will get a new mention (which is fine), and dozens of emails will be sent for all these new mentions (which is not). This commit fixes the spam by avoiding to send an email when a new mention is created. In most cases the email notification for the mentioner is enough. --- app/services/notification_service.rb | 1 + spec/services/notification_service_spec.rb | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 9d7bb9639ac..ee867a1da0c 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -111,6 +111,7 @@ class NotificationService # ignore gitlab service messages return true if note.note =~ /\A_Status changed to closed_/ + return true if note.note =~ /\A_mentioned in / && note.system == true opts = { noteable_type: note.noteable_type, project_id: note.project_id } diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index e378be04255..0869ebc9e0f 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -32,6 +32,7 @@ describe NotificationService do describe 'Notes' do context 'issue note' do let(:issue) { create(:issue, assignee: create(:user)) } + let(:mentioned_issue) { create(:issue, assignee: issue.assignee) } let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@mention referenced') } before do @@ -50,6 +51,13 @@ describe NotificationService do notification.new_note(note) end + it 'filters out "mentioned in" notes' do + mentioned_note = Note.create_cross_reference_note(mentioned_issue, issue, issue.author, issue.project) + + Notify.should_not_receive(:note_issue_email) + notification.new_note(mentioned_note) + end + def should_email(user_id) Notify.should_receive(:note_issue_email).with(user_id, note.id) end -- cgit v1.2.3 From 324749486f8d712c48e77a04a482b734c3d54b41 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 24 Feb 2014 13:04:05 +0100 Subject: Use tags to do minor updates of GitLab --- doc/update/patch_versions.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md index b284ff48365..0dbb3e5db15 100644 --- a/doc/update/patch_versions.md +++ b/doc/update/patch_versions.md @@ -18,10 +18,11 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git pull origin STABLE_BRANCH +sudo -u git -H git fetch --all +sudo -u git -H git checkout LATEST_TAG ``` -Replace STABLE_BRANCH with the minor version you want to upgrade to, for example `6-3-stable`. +Replace LATEST_TAG with the latest GitLab tag you want to upgrade to, for example `v6.6.3`. ### 3. Update gitlab-shell if it is not the latest version -- cgit v1.2.3 From fdd8b9e32a2a394c7dcd71e64e6bca8c25eda730 Mon Sep 17 00:00:00 2001 From: Ben Tomasik Date: Fri, 28 Feb 2014 00:10:17 -0600 Subject: Update user_management.md Believe the intention was to say 'groups' instead of 'projects' here. --- doc/raketasks/user_management.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/raketasks/user_management.md b/doc/raketasks/user_management.md index 38474104852..e8232082916 100644 --- a/doc/raketasks/user_management.md +++ b/doc/raketasks/user_management.md @@ -15,7 +15,7 @@ Notes: bundle exec rake gitlab:import:all_users_to_all_projects ``` -### Add user as a developer to all projects +### Add user as a developer to all groups ``` bundle exec rake gitlab:import:user_to_groups[username@domain.tld] -- cgit v1.2.3 From 39bb54feb3685d74f57109553e032b041644dc43 Mon Sep 17 00:00:00 2001 From: lol768 Date: Sun, 2 Mar 2014 18:45:38 +0000 Subject: Fix registration error info typo --- app/models/user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/user.rb b/app/models/user.rb index 855fe58ffe8..0ed3ab4521e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -249,7 +249,7 @@ class User < ActiveRecord::Base def namespace_uniq namespace_name = self.username if Namespace.find_by(path: namespace_name) - self.errors.add :username, "already exist" + self.errors.add :username, "already exists" end end -- cgit v1.2.3 From 7ba0b502d3e6fdc5efc5619d803a1b9fcf9db791 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 18 Feb 2014 11:12:01 +0100 Subject: Add a "View in GitLab" link in notification emails When an email notification concerns a specific object (issue, note, merge request, etc.), add a link to the footer of the email that opens the item's page in a web browser. Rationale: * The link is predictable: always the same text, always at the same location, like any reliable tool. * It allows to remove the inline-title in many emails, and leave only the actual content of the message. --- app/mailers/emails/groups.rb | 2 +- app/mailers/emails/issues.rb | 4 ++++ app/mailers/emails/merge_requests.rb | 4 ++++ app/mailers/emails/notes.rb | 4 ++++ app/mailers/emails/profile.rb | 2 ++ app/mailers/emails/projects.rb | 7 +++++++ app/views/layouts/notify.html.haml | 3 +++ spec/mailers/notify_spec.rb | 6 ++++++ 8 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/mailers/emails/groups.rb b/app/mailers/emails/groups.rb index 1c8ae122c46..1654fc55bca 100644 --- a/app/mailers/emails/groups.rb +++ b/app/mailers/emails/groups.rb @@ -3,7 +3,7 @@ module Emails def group_access_granted_email(user_group_id) @membership = UsersGroup.find(user_group_id) @group = @membership.group - + @target_url = group_url(@group) mail(to: @membership.user.email, subject: subject("Access to group was granted")) end diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb index 3adb47dc5b1..d684e354452 100644 --- a/app/mailers/emails/issues.rb +++ b/app/mailers/emails/issues.rb @@ -3,6 +3,7 @@ module Emails def new_issue_email(recipient_id, issue_id) @issue = Issue.find(issue_id) @project = @issue.project + @target_url = project_issue_url(@project, @issue) mail(from: sender(@issue.author_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) @@ -12,6 +13,7 @@ module Emails @issue = Issue.find(issue_id) @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id @project = @issue.project + @target_url = project_issue_url(@project, @issue) mail(from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) @@ -21,6 +23,7 @@ module Emails @issue = Issue.find issue_id @project = @issue.project @updated_by = User.find updated_by_user_id + @target_url = project_issue_url(@project, @issue) mail(from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) @@ -31,6 +34,7 @@ module Emails @issue_status = status @project = @issue.project @updated_by = User.find updated_by_user_id + @target_url = project_issue_url(@project, @issue) mail(from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb index 0845e14edc7..5e1b8faf13e 100644 --- a/app/mailers/emails/merge_requests.rb +++ b/app/mailers/emails/merge_requests.rb @@ -3,6 +3,7 @@ module Emails def new_merge_request_email(recipient_id, merge_request_id) @merge_request = MergeRequest.find(merge_request_id) @project = @merge_request.project + @target_url = project_merge_request_url(@project, @merge_request) mail(from: sender(@merge_request.author_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) @@ -12,6 +13,7 @@ module Emails @merge_request = MergeRequest.find(merge_request_id) @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id @project = @merge_request.project + @target_url = project_merge_request_url(@project, @merge_request) mail(from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) @@ -21,6 +23,7 @@ module Emails @merge_request = MergeRequest.find(merge_request_id) @updated_by = User.find updated_by_user_id @project = @merge_request.project + @target_url = project_merge_request_url(@project, @merge_request) mail(from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) @@ -29,6 +32,7 @@ module Emails def merged_merge_request_email(recipient_id, merge_request_id) @merge_request = MergeRequest.find(merge_request_id) @project = @merge_request.project + @target_url = project_merge_request_url(@project, @merge_request) mail(from: sender(@merge_request.author_id_of_changes), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb index 00b127da429..22c4ededf5f 100644 --- a/app/mailers/emails/notes.rb +++ b/app/mailers/emails/notes.rb @@ -4,6 +4,7 @@ module Emails @note = Note.find(note_id) @commit = @note.noteable @project = @note.project + @target_url = project_commit_url(@project, @commit, anchor: "note_#{@note.id}") mail(from: sender(@note.author_id), to: recipient(recipient_id), subject: subject("#{@commit.title} (#{@commit.short_id})")) @@ -13,6 +14,7 @@ module Emails @note = Note.find(note_id) @issue = @note.noteable @project = @note.project + @target_url = project_issue_url(@project, @issue) mail(from: sender(@note.author_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) @@ -22,6 +24,7 @@ module Emails @note = Note.find(note_id) @merge_request = @note.noteable @project = @note.project + @target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{@note.id}") mail(from: sender(@note.author_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) @@ -30,6 +33,7 @@ module Emails def note_wall_email(recipient_id, note_id) @note = Note.find(note_id) @project = @note.project + @target_url = project_wall_url(@note.project, anchor: "note_#{@note.id}") mail(from: sender(@note.author_id), to: recipient(recipient_id), subject: subject("Note on wall")) diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb index c91660a02b5..f02d95fd557 100644 --- a/app/mailers/emails/profile.rb +++ b/app/mailers/emails/profile.rb @@ -3,6 +3,7 @@ module Emails def new_user_email(user_id, password) @user = User.find(user_id) @password = password + @target_url = user_url(@user) mail(to: @user.email, subject: subject("Account was created for you")) end @@ -15,6 +16,7 @@ module Emails def new_ssh_key_email(key_id) @key = Key.find(key_id) @user = @key.user + @target_url = user_url(@user) mail(to: @user.email, subject: subject("SSH key was added to your account")) end end diff --git a/app/mailers/emails/projects.rb b/app/mailers/emails/projects.rb index 46f24e9fb7c..46aa34d13da 100644 --- a/app/mailers/emails/projects.rb +++ b/app/mailers/emails/projects.rb @@ -3,6 +3,7 @@ module Emails def project_access_granted_email(user_project_id) @users_project = UsersProject.find user_project_id @project = @users_project.project + @target_url = project_url(@project) mail(to: @users_project.user.email, subject: subject("Access to project was granted")) end @@ -10,6 +11,7 @@ module Emails def project_was_moved_email(project_id, user_id) @user = User.find user_id @project = Project.find project_id + @target_url = project_url(@project) mail(to: @user.email, subject: subject("Project was moved")) end @@ -21,6 +23,11 @@ module Emails @commits = Commit.decorate(compare.commits) @diffs = compare.diffs @branch = branch + if @commits.length > 1 + @target_url = project_compare_url(@project, from: @commits.first, to: @commits.last) + else + @target_url = project_commit_url(@project, @compare.commit) + end mail(from: sender(author_id), to: recipient, diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index f88abeca887..2a167105248 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -20,3 +20,6 @@ %p{style: "font-size:small;color:#777"} - if @project You're receiving this notification because you are a member of the #{@project.name_with_namespace} project team. + %br + - if @target_url + #{link_to "View in GitLab", @target_url} diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 6ba4d97ad4a..6b8d7a6f047 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -468,6 +468,8 @@ describe Notify do let(:example_site_path) { root_path } let(:user) { create(:user) } let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, 'cd5c4bac', 'b1e6a9db') } + let(:commits) { Commit.decorate(compare.commits) } + let(:diff_path) { project_compare_path(project, from: commits.first, to: commits.last) } subject { Notify.repository_push_email(project.id, 'devs@company.name', user.id, 'master', compare) } @@ -492,5 +494,9 @@ describe Notify do it 'includes diffs' do should have_body_text /Checkout wiki pages for installation information/ end + + it 'contains a link to the diff' do + should have_body_text /#{diff_path}/ + end end end -- cgit v1.2.3 From edd6028bdb1f0e8ba6744540e9d3f324ab40126d Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 18 Feb 2014 11:46:01 +0100 Subject: Remove custom link to target in notification emails Every email has a different way of showing a link to the discussion on the website. We don't need this anymore, as we now have a standard "View in GitLab" link in the footer of every email. --- app/mailers/emails/notes.rb | 2 +- app/views/notify/closed_issue_email.html.haml | 3 --- app/views/notify/closed_merge_request_email.html.haml | 2 -- app/views/notify/group_access_granted_email.html.haml | 3 --- app/views/notify/issue_status_changed_email.html.haml | 3 --- app/views/notify/merged_merge_request_email.html.haml | 2 -- app/views/notify/new_issue_email.html.haml | 3 --- app/views/notify/new_merge_request_email.html.haml | 2 -- app/views/notify/note_commit_email.html.haml | 3 --- app/views/notify/note_issue_email.html.haml | 3 --- app/views/notify/note_merge_request_email.html.haml | 1 - app/views/notify/note_wall_email.html.haml | 4 ---- app/views/notify/reassigned_issue_email.html.haml | 3 --- app/views/notify/reassigned_merge_request_email.html.haml | 3 --- 14 files changed, 1 insertion(+), 36 deletions(-) diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb index 22c4ededf5f..ccbdadf010f 100644 --- a/app/mailers/emails/notes.rb +++ b/app/mailers/emails/notes.rb @@ -14,7 +14,7 @@ module Emails @note = Note.find(note_id) @issue = @note.noteable @project = @note.project - @target_url = project_issue_url(@project, @issue) + @target_url = project_issue_url(@project, @issue, anchor: "note_#{@note.id}") mail(from: sender(@note.author_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) diff --git a/app/views/notify/closed_issue_email.html.haml b/app/views/notify/closed_issue_email.html.haml index 325cd44eb4b..56c18cd83cd 100644 --- a/app/views/notify/closed_issue_email.html.haml +++ b/app/views/notify/closed_issue_email.html.haml @@ -1,5 +1,2 @@ %p = "Issue was closed by #{@updated_by.name}" -%p - = "Issue ##{@issue.iid}" - = link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title diff --git a/app/views/notify/closed_merge_request_email.html.haml b/app/views/notify/closed_merge_request_email.html.haml index 45770cc85de..3157f59b2b6 100644 --- a/app/views/notify/closed_merge_request_email.html.haml +++ b/app/views/notify/closed_merge_request_email.html.haml @@ -1,7 +1,5 @@ %p = "Merge Request #{@merge_request.iid} was closed by #{@updated_by.name}" -%p - = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request) %p != merge_path_description(@merge_request, '→') %p diff --git a/app/views/notify/group_access_granted_email.html.haml b/app/views/notify/group_access_granted_email.html.haml index 5023ec737a5..0092a947eee 100644 --- a/app/views/notify/group_access_granted_email.html.haml +++ b/app/views/notify/group_access_granted_email.html.haml @@ -1,5 +1,2 @@ %p = "You have been granted #{@membership.human_access} access to group" -%p - = link_to group_url(@group) do - = @group.name diff --git a/app/views/notify/issue_status_changed_email.html.haml b/app/views/notify/issue_status_changed_email.html.haml index 7706b3f7516..482c884a9db 100644 --- a/app/views/notify/issue_status_changed_email.html.haml +++ b/app/views/notify/issue_status_changed_email.html.haml @@ -1,5 +1,2 @@ %p = "Issue was #{@issue_status} by #{@updated_by.name}" -%p - = "Issue ##{@issue.iid}" - = link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title diff --git a/app/views/notify/merged_merge_request_email.html.haml b/app/views/notify/merged_merge_request_email.html.haml index e2bc9cf5c04..e3a5239fe05 100644 --- a/app/views/notify/merged_merge_request_email.html.haml +++ b/app/views/notify/merged_merge_request_email.html.haml @@ -1,7 +1,5 @@ %p = "Merge Request #{@merge_request.iid} was merged" -%p - = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request) %p != merge_path_description(@merge_request, '→') %p diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml index 3b3c148517a..05a91424713 100644 --- a/app/views/notify/new_issue_email.html.haml +++ b/app/views/notify/new_issue_email.html.haml @@ -1,8 +1,5 @@ %p New Issue was created. -%p - = "Issue ##{@issue.iid}" - = link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title %p Author: #{@issue.author_name} %p diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml index 321f9418ded..bc52824c44f 100644 --- a/app/views/notify/new_merge_request_email.html.haml +++ b/app/views/notify/new_merge_request_email.html.haml @@ -1,7 +1,5 @@ %p = "New Merge Request ##{@merge_request.iid}" -%p - = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request) %p != merge_path_description(@merge_request, '→') %p diff --git a/app/views/notify/note_commit_email.html.haml b/app/views/notify/note_commit_email.html.haml index 620b258fc15..1d961e4424c 100644 --- a/app/views/notify/note_commit_email.html.haml +++ b/app/views/notify/note_commit_email.html.haml @@ -1,5 +1,2 @@ -%p - = "New comment for Commit #{@commit.short_id}" - = link_to_gfm truncate(@commit.title, length: 16), project_commit_url(@note.project, id: @commit.id, anchor: "note_#{@note.id}") = render 'note_message' diff --git a/app/views/notify/note_issue_email.html.haml b/app/views/notify/note_issue_email.html.haml index b3230953e7d..2fa2f784661 100644 --- a/app/views/notify/note_issue_email.html.haml +++ b/app/views/notify/note_issue_email.html.haml @@ -1,4 +1 @@ -%p - = "New comment for Issue ##{@issue.iid}" - = link_to_gfm truncate(@issue.title, length: 35), project_issue_url(@issue.project, @issue, anchor: "note_#{@note.id}") = render 'note_message' diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml index d587b068486..83d07aa0c92 100644 --- a/app/views/notify/note_merge_request_email.html.haml +++ b/app/views/notify/note_merge_request_email.html.haml @@ -4,5 +4,4 @@ - else = link_to "New comment", project_merge_request_url(@merge_request.target_project, @merge_request, anchor: "note_#{@note.id}") for Merge Request ##{@merge_request.iid} - %cite "#{truncate(@merge_request.title, length: 20)}" = render 'note_message' diff --git a/app/views/notify/note_wall_email.html.haml b/app/views/notify/note_wall_email.html.haml index 92200e83efa..2fa2f784661 100644 --- a/app/views/notify/note_wall_email.html.haml +++ b/app/views/notify/note_wall_email.html.haml @@ -1,5 +1 @@ -%p - New message on - = link_to "Project Wall", project_wall_url(@note.project, anchor: "note_#{@note.id}") - = render 'note_message' diff --git a/app/views/notify/reassigned_issue_email.html.haml b/app/views/notify/reassigned_issue_email.html.haml index b0edff44ce6..07227a3e68c 100644 --- a/app/views/notify/reassigned_issue_email.html.haml +++ b/app/views/notify/reassigned_issue_email.html.haml @@ -1,6 +1,3 @@ -%p - = "Reassigned Issue ##{@issue.iid}" - = link_to_gfm truncate(@issue.title, length: 30), project_issue_url(@issue.project, @issue) %p Assignee changed - if @previous_assignee diff --git a/app/views/notify/reassigned_merge_request_email.html.haml b/app/views/notify/reassigned_merge_request_email.html.haml index d2d82d36c48..00aee6bc952 100644 --- a/app/views/notify/reassigned_merge_request_email.html.haml +++ b/app/views/notify/reassigned_merge_request_email.html.haml @@ -1,6 +1,3 @@ -%p - = "Reassigned Merge Request ##{@merge_request.iid}" - = link_to_gfm truncate(@merge_request.title, length: 30), project_merge_request_url(@merge_request.target_project, @merge_request) %p Assignee changed - if @previous_assignee -- cgit v1.2.3 From b59d105c0e541520073761b15ce575be3518cef2 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 18 Feb 2014 11:13:16 +0100 Subject: Linkify the reference to the project in the notification emails footer Rationale: * Consistency: the link is always at the same place. * Streamlining: it allows to remove the header banner, now that the project url can be accessed from another place. --- app/views/layouts/notify.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index 2a167105248..9aceb58e8d1 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -19,7 +19,7 @@ %td{align: "left", style: "margin: 0; padding: 10px;"} %p{style: "font-size:small;color:#777"} - if @project - You're receiving this notification because you are a member of the #{@project.name_with_namespace} project team. + You're receiving this notification because you are a member of the #{link_to @project.name_with_namespace, project_url(@project)} project team. %br - if @target_url #{link_to "View in GitLab", @target_url} -- cgit v1.2.3 From 8e421d2bcb8088fa065b9bd8a6e1776c5140f4cd Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 18 Feb 2014 14:44:00 +0100 Subject: Add the description to the "new issue" and "new merge request" emails Previously the content of the issue or merge request was missing from the email. --- app/views/notify/new_issue_email.html.haml | 12 ++++++------ app/views/notify/new_merge_request_email.html.haml | 8 ++++++-- spec/mailers/notify_spec.rb | 20 +++++++++++++++++++- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml index 05a91424713..f2f8eee18c4 100644 --- a/app/views/notify/new_issue_email.html.haml +++ b/app/views/notify/new_issue_email.html.haml @@ -1,6 +1,6 @@ -%p - New Issue was created. -%p - Author: #{@issue.author_name} -%p - Assignee: #{@issue.assignee_name} +-if @issue.description + = markdown(@issue.description) + +- if @issue.assignee_id.present? + %p + Assignee: #{@issue.assignee_name} diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml index bc52824c44f..2c012c4b215 100644 --- a/app/views/notify/new_merge_request_email.html.haml +++ b/app/views/notify/new_merge_request_email.html.haml @@ -2,6 +2,10 @@ = "New Merge Request ##{@merge_request.iid}" %p != merge_path_description(@merge_request, '→') -%p - Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name} +- if @merge_request.assignee_id.present? + %p + Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name} + +-if @merge_request.description + = markdown(@merge_request.description) diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 6b8d7a6f047..bc375622b32 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -146,7 +146,8 @@ describe Notify do end context 'for issues' do - let(:issue) { create(:issue, author: current_user, assignee: assignee, project: project ) } + let(:issue) { create(:issue, author: current_user, assignee: assignee, project: project) } + let(:issue_with_description) { create(:issue, author: current_user, assignee: assignee, project: project, description: Faker::Lorem.sentence) } describe 'that are new' do subject { Notify.new_issue_email(issue.assignee_id, issue.id) } @@ -162,6 +163,14 @@ describe Notify do end end + describe 'that are new with a description' do + subject { Notify.new_issue_email(issue_with_description.assignee_id, issue_with_description.id) } + + it 'contains the description' do + should have_body_text /#{issue_with_description.description}/ + end + end + describe 'that have been reassigned' do subject { Notify.reassigned_issue_email(recipient.id, issue.id, previous_assignee.id, current_user) } @@ -221,6 +230,7 @@ describe Notify do context 'for merge requests' do let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) } + let(:merge_request_with_description) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project, description: Faker::Lorem.sentence) } describe 'that are new' do subject { Notify.new_merge_request_email(merge_request.assignee_id, merge_request.id) } @@ -244,6 +254,14 @@ describe Notify do end end + describe 'that are new with a description' do + subject { Notify.new_merge_request_email(merge_request_with_description.assignee_id, merge_request_with_description.id) } + + it 'contains the description' do + should have_body_text /#{merge_request_with_description.description}/ + end + end + describe 'that are reassigned' do subject { Notify.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) } -- cgit v1.2.3 From eeb011e34a2ccc3ff8a37bd91d8cb7b5cc033228 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 18 Feb 2014 11:14:04 +0100 Subject: Remove the author name from issue notes emails Rationale: the author name is now displayed in the email "From" field; this information is no longer needed. --- app/views/notify/_note_message.html.haml | 4 ---- spec/mailers/notify_spec.rb | 4 ---- 2 files changed, 8 deletions(-) diff --git a/app/views/notify/_note_message.html.haml b/app/views/notify/_note_message.html.haml index 9e329af2d47..ba2ed5697ba 100644 --- a/app/views/notify/_note_message.html.haml +++ b/app/views/notify/_note_message.html.haml @@ -1,6 +1,2 @@ -%p - %strong #{@note.author_name} - wrote: - %cite{style: 'color: #666'} = markdown(@note.note) diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index bc375622b32..f990ed659b8 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -353,10 +353,6 @@ describe Notify do should deliver_to recipient.email end - it 'contains the name of the note\'s author' do - should have_body_text /#{note_author.name}/ - end - it 'contains the message from the note' do should have_body_text /#{note.note}/ end -- cgit v1.2.3 From ec196fbbf2cb1849631d921015296806d0563da6 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 18 Feb 2014 12:19:08 +0100 Subject: Remove the quote-style around message in notification emails Rationale: * In this notification email, the message is the most important content. It should not be dimmed or smaller than the rest of the text. * Now that all UI elements are removed, the message *is* the email. It should be written as a standard email message, without styling. --- app/views/notify/_note_message.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/notify/_note_message.html.haml b/app/views/notify/_note_message.html.haml index ba2ed5697ba..5272dfa0ede 100644 --- a/app/views/notify/_note_message.html.haml +++ b/app/views/notify/_note_message.html.haml @@ -1,2 +1,2 @@ -%cite{style: 'color: #666'} +%div = markdown(@note.note) -- cgit v1.2.3 From 7959455f4d5dc25963176b9f83981b17b415996e Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 18 Feb 2014 12:14:27 +0100 Subject: Remove the header banner in notification emails Rationale: * The link to the project is already displayed in the message footer. * Streamlining: the content of the message is better emphasized. --- app/views/layouts/notify.html.haml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index 9aceb58e8d1..c632fdeb3e2 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -5,16 +5,10 @@ GitLab %body - %h1{style: "background: #EEE; border-bottom: 1px solid #DDD; color: #474D57; font: normal 20px Helvetica, Arial, sans-serif; margin: 0; padding: 5px 10px; line-height: 32px; font-size: 16px;"} - GitLab - - if @project - \| - = link_to @project.name_with_namespace, project_url(@project), style: 'color: #29B; text-decoration: none' %table{align: "left", border: "0", cellpadding: "0", cellspacing: "0", style: "padding: 10px 0;", width: "100%"} %tr %td{align: "left", style: "margin: 0; padding: 10px;"} = yield - %br %tr %td{align: "left", style: "margin: 0; padding: 10px;"} %p{style: "font-size:small;color:#777"} -- cgit v1.2.3 From 306744bbb0a5e1fc6253ec9512cbae87df2a94c7 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 18 Feb 2014 14:27:39 +0100 Subject: Simplify the default layout of notification emails * Less margin: the content appears as the text of the message. * Streamlined footer: everything on one line, with a small separator. * Zimbra (www.zimbra.com) chokes on HTML tables, and doesn't display the content of the message. Switching to a simpler layout fixes the issue. --- app/views/layouts/notify.html.haml | 31 +++++++++++++--------- app/views/notify/new_merge_request_email.html.haml | 4 +-- .../notify/note_merge_request_email.html.haml | 2 +- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index c632fdeb3e2..09d84a3eb9f 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -3,17 +3,24 @@ %meta{content: "text/html; charset=utf-8", "http-equiv" => "Content-Type"} %title GitLab + :css + p.details { + font-style:italic; + color:#777 + } + .footer p { + font-size:small; + color:#777 + } %body - %table{align: "left", border: "0", cellpadding: "0", cellspacing: "0", style: "padding: 10px 0;", width: "100%"} - %tr - %td{align: "left", style: "margin: 0; padding: 10px;"} - = yield - %tr - %td{align: "left", style: "margin: 0; padding: 10px;"} - %p{style: "font-size:small;color:#777"} - - if @project - You're receiving this notification because you are a member of the #{link_to @project.name_with_namespace, project_url(@project)} project team. - %br - - if @target_url - #{link_to "View in GitLab", @target_url} + %div.content + = yield + %div.footer{style: "margin-top: 10px;"} + %p + \— + %br + - if @project + You're receiving this notification because you are a member of the #{link_to @project.name_with_namespace, project_url(@project)} project team. + - if @target_url + #{link_to "View in GitLab", @target_url} diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml index 2c012c4b215..f02d5111b22 100644 --- a/app/views/notify/new_merge_request_email.html.haml +++ b/app/views/notify/new_merge_request_email.html.haml @@ -1,6 +1,4 @@ -%p - = "New Merge Request ##{@merge_request.iid}" -%p +%p.details != merge_path_description(@merge_request, '→') - if @merge_request.assignee_id.present? diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml index 83d07aa0c92..f5287176fbc 100644 --- a/app/views/notify/note_merge_request_email.html.haml +++ b/app/views/notify/note_merge_request_email.html.haml @@ -1,4 +1,4 @@ -%p +%p.details - if @note.for_diff_line? = link_to "New comment on diff", diffs_project_merge_request_url(@merge_request.target_project, @merge_request, anchor: "note_#{@note.id}") - else -- cgit v1.2.3 From ad278c4e7468cc7aac8af27199bc6851853cf779 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 18 Feb 2014 17:32:12 +0100 Subject: Make the merge request notification emails more readable Emphasize the meaningful informations, and remove the less needed ones: * Use "!" to identify a merge request * Write the name of the commented file for diff notes * Don't show the assignee in the "merged merge request" email --- app/views/notify/closed_merge_request_email.html.haml | 7 +------ app/views/notify/merged_merge_request_email.html.haml | 7 +------ app/views/notify/note_merge_request_email.html.haml | 12 ++++++------ 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/app/views/notify/closed_merge_request_email.html.haml b/app/views/notify/closed_merge_request_email.html.haml index 3157f59b2b6..809d46f31be 100644 --- a/app/views/notify/closed_merge_request_email.html.haml +++ b/app/views/notify/closed_merge_request_email.html.haml @@ -1,7 +1,2 @@ %p - = "Merge Request #{@merge_request.iid} was closed by #{@updated_by.name}" -%p - != merge_path_description(@merge_request, '→') -%p - Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name} - + = "Merge Request !#{@merge_request.iid} was closed by #{@updated_by.name}" diff --git a/app/views/notify/merged_merge_request_email.html.haml b/app/views/notify/merged_merge_request_email.html.haml index e3a5239fe05..0c62d439aed 100644 --- a/app/views/notify/merged_merge_request_email.html.haml +++ b/app/views/notify/merged_merge_request_email.html.haml @@ -1,7 +1,2 @@ %p - = "Merge Request #{@merge_request.iid} was merged" -%p - != merge_path_description(@merge_request, '→') -%p - Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name} - + = "Merge Request !#{@merge_request.iid} was merged" diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml index f5287176fbc..65f0e4c4068 100644 --- a/app/views/notify/note_merge_request_email.html.haml +++ b/app/views/notify/note_merge_request_email.html.haml @@ -1,7 +1,7 @@ -%p.details - - if @note.for_diff_line? - = link_to "New comment on diff", diffs_project_merge_request_url(@merge_request.target_project, @merge_request, anchor: "note_#{@note.id}") - - else - = link_to "New comment", project_merge_request_url(@merge_request.target_project, @merge_request, anchor: "note_#{@note.id}") - for Merge Request ##{@merge_request.iid} +- if @note.diff_file_name + %p.details + New comment on diff for + = link_to @note.diff_file_name, @target_url + \: + = render 'note_message' -- cgit v1.2.3 From 7e14f86c71b8b2f94ad65cae6118f752c8f31610 Mon Sep 17 00:00:00 2001 From: Greg Messner Date: Mon, 3 Mar 2014 23:08:39 -0800 Subject: Added description parameter support to Create and Update MR API endpoints (issue-110). --- CHANGELOG | 1 + lib/api/merge_requests.rb | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ab420399263..315513030f7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,7 @@ v 6.7.0 - Show contribution guide link for new issue form (Jeroen van Baarsen) - Fix CI status for merge requests from fork - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) + - Create and Update MR calls now support the description parameter (Greg Messner) v 6.6.2 - Fix 500 error on branch/tag create or remove via UI diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 58d2f79faff..e2458198411 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -64,6 +64,7 @@ module API # target_project - The target project of the merge request defaults to the :id of the project # assignee_id - Assignee user ID # title (required) - Title of MR + # description - Description of MR # # Example: # POST /projects/:id/merge_requests @@ -72,7 +73,7 @@ module API set_current_user_for_thread do authorize! :write_merge_request, user_project required_attributes! [:source_branch, :target_branch, :title] - attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id] + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description] merge_request = user_project.merge_requests.new(attrs) merge_request.author = current_user merge_request.source_project = user_project @@ -105,12 +106,13 @@ module API # assignee_id - Assignee user ID # title - Title of MR # state_event - Status of MR. (close|reopen|merge) + # description - Description of MR # Example: # PUT /projects/:id/merge_request/:merge_request_id # put ":id/merge_request/:merge_request_id" do set_current_user_for_thread do - attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event] + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event, :description] merge_request = user_project.merge_requests.find(params[:merge_request_id]) authorize! :modify_merge_request, merge_request -- cgit v1.2.3 From 4239e457ac1a5293c260b0102e1ae9538544d839 Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Tue, 4 Mar 2014 16:08:48 -0700 Subject: Add .adoc file extension for AsciiDoc Add .adoc file extension for AsciiDoc as it's a very popular extension to use and the one recommended by the Asciidoctor project. --- app/helpers/tree_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index 2dbc1cffb16..50501dffefb 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -40,7 +40,7 @@ module TreeHelper # Returns boolean def markup?(filename) filename.downcase.end_with?(*%w(.textile .rdoc .org .creole - .mediawiki .rst .asciidoc .pod)) + .mediawiki .rst .adoc .asciidoc .pod)) end def gitlab_markdown?(filename) -- cgit v1.2.3 From 9a676ccc0a8dd26eb1ebd5042acbf31cfb906f91 Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Wed, 5 Mar 2014 20:44:01 +0100 Subject: Added tag_push_events to the web_hooks * Added a scope to the web_hooks model * Added extra checkbooks in de hooks overview window --- app/models/project_hook.rb | 3 +- app/views/projects/hooks/index.html.haml | 9 +- ...305193308_add_tag_push_hooks_to_project_hook.rb | 5 ++ db/schema.rb | 98 +++++++++++----------- spec/models/project_hook_spec.rb | 19 +++++ 5 files changed, 85 insertions(+), 49 deletions(-) create mode 100644 db/migrate/20140305193308_add_tag_push_hooks_to_project_hook.rb create mode 100644 spec/models/project_hook_spec.rb diff --git a/app/models/project_hook.rb b/app/models/project_hook.rb index e1c9ed01bc5..4e9b22532cb 100644 --- a/app/models/project_hook.rb +++ b/app/models/project_hook.rb @@ -17,9 +17,10 @@ class ProjectHook < WebHook belongs_to :project - attr_accessible :push_events, :issues_events, :merge_requests_events + attr_accessible :push_events, :issues_events, :merge_requests_events, :tag_push_events scope :push_hooks, -> { where(push_events: true) } + scope :tag_push_hooks, -> { where(tag_push_events: true) } scope :issue_hooks, -> { where(issues_events: true) } scope :merge_request_hooks, -> { where(merge_requests_events: true) } end diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml index 00e5ae27779..866fd6f6066 100644 --- a/app/views/projects/hooks/index.html.haml +++ b/app/views/projects/hooks/index.html.haml @@ -26,6 +26,13 @@ %strong Push events %p.light This url will be triggered by a push to the repository + %div + = f.check_box :tag_push_events, class: 'pull-left' + .prepend-left-20 + = f.label :tag_push_events, class: 'list-label' do + %strong Tag push events + %p.light + This url will be triggered when a new tag is pushed to the repository %div = f.check_box :issues_events, class: 'pull-left' .prepend-left-20 @@ -56,6 +63,6 @@ .clearfix %span.monospace= hook.url %p - - %w(push_events issues_events merge_requests_events).each do |trigger| + - %w(push_events tag_push_events issues_events merge_requests_events).each do |trigger| - if hook.send(trigger) %span.label.label-gray= trigger.titleize diff --git a/db/migrate/20140305193308_add_tag_push_hooks_to_project_hook.rb b/db/migrate/20140305193308_add_tag_push_hooks_to_project_hook.rb new file mode 100644 index 00000000000..7017148702a --- /dev/null +++ b/db/migrate/20140305193308_add_tag_push_hooks_to_project_hook.rb @@ -0,0 +1,5 @@ +class AddTagPushHooksToProjectHook < ActiveRecord::Migration + def change + add_column :web_hooks, :tag_push_events, :boolean, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 9f1de4d2120..73abb1450b5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,15 +11,18 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140304005354) do +ActiveRecord::Schema.define(version: 20140305193308) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" create_table "broadcast_messages", force: true do |t| t.text "message", null: false t.datetime "starts_at" t.datetime "ends_at" t.integer "alert_type" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "color" t.string "font" end @@ -27,8 +30,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "deploy_keys_projects", force: true do |t| t.integer "deploy_key_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "deploy_keys_projects", ["project_id"], name: "index_deploy_keys_projects_on_project_id", using: :btree @@ -49,8 +52,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "title" t.text "data" t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "action" t.integer "author_id" end @@ -65,8 +68,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "forked_project_links", force: true do |t| t.integer "forked_to_project_id", null: false t.integer "forked_from_project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree @@ -76,8 +79,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.integer "assignee_id" t.integer "author_id" t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "position", default: 0 t.string "branch_name" t.text "description" @@ -95,8 +98,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "keys", force: true do |t| t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.text "key" t.string "title" t.string "type" @@ -106,10 +109,10 @@ ActiveRecord::Schema.define(version: 20140304005354) do add_index "keys", ["user_id"], name: "index_keys_on_user_id", using: :btree create_table "merge_request_diffs", force: true do |t| - t.string "state", default: "collected", null: false - t.text "st_commits", limit: 2147483647 - t.text "st_diffs", limit: 2147483647 - t.integer "merge_request_id", null: false + t.string "state", default: "collected", null: false + t.text "st_commits" + t.text "st_diffs" + t.integer "merge_request_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -123,8 +126,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.integer "author_id" t.integer "assignee_id" t.string "title" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "milestone_id" t.string "state" t.string "merge_status" @@ -138,7 +141,7 @@ ActiveRecord::Schema.define(version: 20140304005354) do add_index "merge_requests", ["created_at"], name: "index_merge_requests_on_created_at", using: :btree add_index "merge_requests", ["milestone_id"], name: "index_merge_requests_on_milestone_id", using: :btree add_index "merge_requests", ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree - add_index "merge_requests", ["source_project_id"], name: "index_merge_requests_on_project_id", using: :btree + add_index "merge_requests", ["source_project_id"], name: "index_merge_requests_on_source_project_id", using: :btree add_index "merge_requests", ["target_branch"], name: "index_merge_requests_on_target_branch", using: :btree add_index "merge_requests", ["title"], name: "index_merge_requests_on_title", using: :btree @@ -147,8 +150,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.integer "project_id", null: false t.text "description" t.date "due_date" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "state" t.integer "iid" end @@ -160,8 +163,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "name", null: false t.string "path", null: false t.integer "owner_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "type" t.string "description", default: "", null: false t.string "avatar" @@ -176,15 +179,15 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.text "note" t.string "noteable_type" t.integer "author_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "project_id" t.string "attachment" t.string "line_code" t.string "commit_id" t.integer "noteable_id" - t.text "st_diff" t.boolean "system", default: false, null: false + t.text "st_diff" end add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree @@ -199,8 +202,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "name" t.string "path" t.text "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "creator_id" t.boolean "issues_enabled", default: true, null: false t.boolean "wall_enabled", default: true, null: false @@ -217,15 +220,15 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.boolean "archived", default: false, null: false end - add_index "projects", ["creator_id"], name: "index_projects_on_owner_id", using: :btree + add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree add_index "projects", ["last_activity_at"], name: "index_projects_on_last_activity_at", using: :btree add_index "projects", ["namespace_id"], name: "index_projects_on_namespace_id", using: :btree create_table "protected_branches", force: true do |t| t.integer "project_id", null: false t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "protected_branches", ["project_id"], name: "index_protected_branches_on_project_id", using: :btree @@ -235,8 +238,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "title" t.string "token" t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "active", default: false, null: false t.string "project_url" t.string "subdomain" @@ -249,14 +252,14 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "snippets", force: true do |t| t.string "title" - t.text "content", limit: 2147483647 - t.integer "author_id", null: false + t.text "content" + t.integer "author_id", null: false t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "file_name" t.datetime "expires_at" - t.boolean "private", default: true, null: false + t.boolean "private", default: true, null: false t.string "type" end @@ -293,8 +296,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "name" t.boolean "admin", default: false, null: false t.integer "projects_limit", default: 10 @@ -338,8 +341,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.integer "group_access", null: false t.integer "group_id", null: false t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "notification_level", default: 3, null: false end @@ -348,8 +351,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "users_projects", force: true do |t| t.integer "user_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "project_access", default: 0, null: false t.integer "notification_level", default: 3, null: false end @@ -361,13 +364,14 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "web_hooks", force: true do |t| t.string "url" t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "type", default: "ProjectHook" t.integer "service_id" t.boolean "push_events", default: true, null: false t.boolean "issues_events", default: false, null: false t.boolean "merge_requests_events", default: false, null: false + t.boolean "tag_push_events", default: false end add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree diff --git a/spec/models/project_hook_spec.rb b/spec/models/project_hook_spec.rb new file mode 100644 index 00000000000..7bd7c431bcd --- /dev/null +++ b/spec/models/project_hook_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe ProjectHook do + describe '.push_hooks' do + it 'should return hooks for push events only' do + hook = create(:project_hook, push_events: true) + hook2 = create(:project_hook, push_events: false) + expect(ProjectHook.push_hooks).to eq([hook]) + end + end + + describe '.tag_push_hooks' do + it 'should return hooks for tag push events only' do + hook = create(:project_hook, tag_push_events: true) + hook2 = create(:project_hook, tag_push_events: false) + expect(ProjectHook.tag_push_hooks).to eq([hook]) + end + end +end -- cgit v1.2.3 From 13d2bcc3b4d6141643fe31dc4d7212ebca0612a5 Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Wed, 5 Mar 2014 21:23:49 +0100 Subject: Created a basic Git Tag Push service This is the first version, and only has the most basic information about the tag that is created. --- app/services/git_tag_push_service.rb | 25 +++++++++++++++++ spec/services/git_tag_push_service_spec.rb | 43 ++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 app/services/git_tag_push_service.rb create mode 100644 spec/services/git_tag_push_service_spec.rb diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb new file mode 100644 index 00000000000..21db5fcfa58 --- /dev/null +++ b/app/services/git_tag_push_service.rb @@ -0,0 +1,25 @@ +class GitTagPushService + attr_accessor :project, :user, :push_data + def execute(project, user, ref) + @project, @user = project, user + @push_data = create_push_data(ref) + project.execute_hooks(@push_data.dup, :tag_push_hooks) + end + + private + + def create_push_data(ref) + data = { + ref: ref, + user_id: user.id, + user_name: user.name, + project_id: project.id, + repository: { + name: project.name, + url: project.url_to_repo, + description: project.description, + homepage: project.web_url + } + } + end +end diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb new file mode 100644 index 00000000000..aabb9f8f38d --- /dev/null +++ b/spec/services/git_tag_push_service_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +describe GitTagPushService do + let (:user) { create :user } + let (:project) { create :project } + let (:service) { GitTagPushService.new } + + before do + @ref = 'refs/tags/super-tag' + end + + describe 'Git Tag Push Data' do + before do + service.execute(project, user, @ref) + @push_data = service.push_data + end + + subject { @push_data } + + it { should include(ref: @ref) } + it { should include(user_id: user.id) } + it { should include(user_name: user.name) } + it { should include(project_id: project.id) } + + context 'With repository data' do + subject { @push_data[:repository] } + + it { should include(name: project.name) } + it { should include(url: project.url_to_repo) } + it { should include(description: project.description) } + it { should include(homepage: project.web_url) } + end + end + + describe "Web Hooks" do + context "execute web hooks" do + it "when pushing tags" do + project.should_receive(:execute_hooks) + service.execute(project, user, 'refs/tags/v1.0.0') + end + end + end +end -- cgit v1.2.3 From f096bd61bda605f2e3631bcd4663ab68c7396989 Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Wed, 5 Mar 2014 22:10:35 +0100 Subject: Post-receive hook can also fire TagPushService --- app/workers/post_receive.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index 6416aa608ec..80e6368ad2d 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -29,10 +29,20 @@ class PostReceive return false end - GitPushService.new.execute(project, user, oldrev, newrev, ref) + if tag?(ref) + GitTagPushService.new.execute(project, user, ref) + else + GitPushService.new.execute(project, user, oldrev, newrev, ref) + end end def log(message) Gitlab::GitLogger.error("POST-RECEIVE: #{message}") end + + private + + def tag?(ref) + !!(/refs\/tags\/(.*)/.match(ref)) + end end -- cgit v1.2.3 From 61a72bc2e22548e7c216cf4499ced0841ff521cf Mon Sep 17 00:00:00 2001 From: mk Date: Thu, 6 Mar 2014 14:08:40 +0100 Subject: Allow underscore as the first char for project names. Not sure if the default_regex really has to be expanded for this special use case. We tried to extend only the project_name_regex first, but that didn't help. --- lib/gitlab/regex.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index d18fc8bf2ce..e932b64f4f0 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -7,7 +7,7 @@ module Gitlab end def project_name_regex - /\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z/ + /\A[a-zA-Z0-9_][a-zA-Z0-9_\-\. ]*\z/ end def name_regex @@ -49,7 +49,7 @@ module Gitlab protected def default_regex - /\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(? Date: Thu, 6 Mar 2014 16:08:51 +0100 Subject: Added newrev and oldrev to the hook data --- app/services/git_tag_push_service.rb | 8 +++++--- app/workers/post_receive.rb | 2 +- spec/services/git_tag_push_service_spec.rb | 8 ++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb index 21db5fcfa58..84fb371fee5 100644 --- a/app/services/git_tag_push_service.rb +++ b/app/services/git_tag_push_service.rb @@ -1,16 +1,18 @@ class GitTagPushService attr_accessor :project, :user, :push_data - def execute(project, user, ref) + def execute(project, user, oldrev, newrev, ref) @project, @user = project, user - @push_data = create_push_data(ref) + @push_data = create_push_data(oldrev, newrev, ref) project.execute_hooks(@push_data.dup, :tag_push_hooks) end private - def create_push_data(ref) + def create_push_data(oldrev, newrev, ref) data = { ref: ref, + oldrev: oldrev, + newrev: newrev, user_id: user.id, user_name: user.name, project_id: project.id, diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index 80e6368ad2d..3b0cf77d42e 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -30,7 +30,7 @@ class PostReceive end if tag?(ref) - GitTagPushService.new.execute(project, user, ref) + GitTagPushService.new.execute(project, user, oldrev, newrev, ref) else GitPushService.new.execute(project, user, oldrev, newrev, ref) end diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb index aabb9f8f38d..d3f7ca30748 100644 --- a/spec/services/git_tag_push_service_spec.rb +++ b/spec/services/git_tag_push_service_spec.rb @@ -7,17 +7,21 @@ describe GitTagPushService do before do @ref = 'refs/tags/super-tag' + @oldrev = 'b98a310def241a6fd9c9a9a3e7934c48e498fe81' + @newrev = 'b19a04f53caeebf4fe5ec2327cb83e9253dc91bb' end describe 'Git Tag Push Data' do before do - service.execute(project, user, @ref) + service.execute(project, user, @oldrev, @newrev, @ref) @push_data = service.push_data end subject { @push_data } it { should include(ref: @ref) } + it { should include(oldrev: @oldrev) } + it { should include(newrev: @newrev) } it { should include(user_id: user.id) } it { should include(user_name: user.name) } it { should include(project_id: project.id) } @@ -36,7 +40,7 @@ describe GitTagPushService do context "execute web hooks" do it "when pushing tags" do project.should_receive(:execute_hooks) - service.execute(project, user, 'refs/tags/v1.0.0') + service.execute(project, user, 'oldrev', 'newrev', 'refs/tags/v1.0.0') end end end -- cgit v1.2.3 From e6ceec9d60b9fe5eaec8faf777307f39bd4b1fa3 Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Thu, 6 Mar 2014 16:15:19 +0100 Subject: Renamed oldrev/newrev to before/after --- app/services/git_tag_push_service.rb | 4 ++-- spec/services/git_tag_push_service_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb index 84fb371fee5..3504479f33a 100644 --- a/app/services/git_tag_push_service.rb +++ b/app/services/git_tag_push_service.rb @@ -11,8 +11,8 @@ class GitTagPushService def create_push_data(oldrev, newrev, ref) data = { ref: ref, - oldrev: oldrev, - newrev: newrev, + before: oldrev, + after: newrev, user_id: user.id, user_name: user.name, project_id: project.id, diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb index d3f7ca30748..e65a8204c54 100644 --- a/spec/services/git_tag_push_service_spec.rb +++ b/spec/services/git_tag_push_service_spec.rb @@ -20,8 +20,8 @@ describe GitTagPushService do subject { @push_data } it { should include(ref: @ref) } - it { should include(oldrev: @oldrev) } - it { should include(newrev: @newrev) } + it { should include(before: @oldrev) } + it { should include(after: @newrev) } it { should include(user_id: user.id) } it { should include(user_name: user.name) } it { should include(project_id: project.id) } -- cgit v1.2.3 From 9818775cad7eec3bdc11a958a876f5fff1f991fb Mon Sep 17 00:00:00 2001 From: Jason Hollingsworth Date: Thu, 6 Mar 2014 21:07:02 -0600 Subject: Check if any social providers are enabled. --- app/helpers/profile_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb index dd9e03d95a8..297ae83d895 100644 --- a/app/helpers/profile_helper.rb +++ b/app/helpers/profile_helper.rb @@ -10,7 +10,7 @@ module ProfileHelper end def show_profile_social_tab? - Gitlab.config.omniauth.enabled && !current_user.ldap_user? + enabled_social_providers.any? && !current_user.ldap_user? end def show_profile_remove_tab? -- cgit v1.2.3 From daa7f077db81f3ecc3417419b7f74b157bb3fda3 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 10 Mar 2014 14:48:08 +0200 Subject: Port LDAP code from EE Signed-off-by: Dmitriy Zaporozhets --- lib/gitlab/ldap/access.rb | 17 ++++++++++ lib/gitlab/ldap/adapter.rb | 78 ++++++++++++++++++++++++++++++++++++++++++++++ lib/gitlab/ldap/person.rb | 54 ++++++++++++++++++++++++++++++++ lib/gitlab/ldap/user.rb | 32 +++++++++++-------- 4 files changed, 168 insertions(+), 13 deletions(-) create mode 100644 lib/gitlab/ldap/access.rb create mode 100644 lib/gitlab/ldap/adapter.rb create mode 100644 lib/gitlab/ldap/person.rb diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb new file mode 100644 index 00000000000..5ca240257bc --- /dev/null +++ b/lib/gitlab/ldap/access.rb @@ -0,0 +1,17 @@ +#------------------------------------------------------------------- +# +# Copyright (C) 2013 GitLab.com - Distributed under the MIT Expat License +# +#------------------------------------------------------------------- + +module Gitlab + module LDAP + class Access + def allowed?(user) + !!Gitlab::LDAP::Person.find_by_dn(user.extern_uid) + rescue + false + end + end + end +end diff --git a/lib/gitlab/ldap/adapter.rb b/lib/gitlab/ldap/adapter.rb new file mode 100644 index 00000000000..c0ad1f90f38 --- /dev/null +++ b/lib/gitlab/ldap/adapter.rb @@ -0,0 +1,78 @@ +#------------------------------------------------------------------- +# +# Copyright (C) 2013 GitLab.com - Distributed under the MIT Expat License +# +#------------------------------------------------------------------- + +module Gitlab + module LDAP + class Adapter + attr_reader :ldap + + def initialize + encryption = config['method'].to_s == 'ssl' ? :simple_tls : nil + + options = { + host: config['host'], + port: config['port'], + encryption: encryption + } + + auth_options = { + auth: { + method: :simple, + username: config['bind_dn'], + password: config['password'] + } + } + + if config['password'] || config['bind_dn'] + options.merge!(auth_options) + end + + @ldap = Net::LDAP.new(options) + end + + def users(field, value) + if field.to_sym == :dn + options = { + base: value + } + else + options = { + base: config['base'], + filter: Net::LDAP::Filter.eq(field, value) + } + end + + if config['user_filter'].present? + user_filter = Net::LDAP::Filter.construct(config['user_filter']) + + options[:filter] = if options[:filter] + Net::LDAP::Filter.join(options[:filter], user_filter) + else + user_filter + end + end + + entries = ldap.search(options).select do |entry| + entry.respond_to? config.uid + end + + entries.map do |entry| + Gitlab::LDAP::Person.new(entry) + end + end + + def user(*args) + users(*args).first + end + + private + + def config + @config ||= Gitlab.config.ldap + end + end + end +end diff --git a/lib/gitlab/ldap/person.rb b/lib/gitlab/ldap/person.rb new file mode 100644 index 00000000000..339e6f37e2c --- /dev/null +++ b/lib/gitlab/ldap/person.rb @@ -0,0 +1,54 @@ +#------------------------------------------------------------------- +# +# Copyright (C) 2013 GitLab.com - Distributed under the MIT Expat License +# +#------------------------------------------------------------------- + +module Gitlab + module LDAP + class Person + def self.find_by_uid(uid) + Gitlab::LDAP::Adapter.new.user(config.uid, uid) + end + + def self.find_by_dn(dn) + Gitlab::LDAP::Adapter.new.user('dn', dn) + end + + def initialize(entry) + Rails.logger.debug { "Instantiating #{self.class.name} with LDIF:\n#{entry.to_ldif}" } + @entry = entry + end + + def name + entry.cn.first + end + + def uid + entry.send(config.uid).first + end + + def username + uid + end + + def dn + entry.dn + end + + private + + def entry + @entry + end + + def adapter + @adapter ||= Gitlab::LDAP::Adapter.new + end + + def config + @config ||= Gitlab.config.ldap + end + end + end +end diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index fd36dda7d22..456a61b9e43 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -13,8 +13,8 @@ module Gitlab def find_or_create(auth) @auth = auth - if uid.blank? || email.blank? - raise_error("Account must provide an uid and email address") + if uid.blank? || email.blank? || username.blank? + raise_error("Account must provide a dn, uid and email address") end user = find(auth) @@ -62,8 +62,16 @@ module Gitlab return nil unless ldap_conf.enabled && login.present? && password.present? ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf) + filter = Net::LDAP::Filter.eq(ldap.uid, login) + + # Apply LDAP user filter if present + if ldap_conf['user_filter'].present? + user_filter = Net::LDAP::Filter.construct(ldap_conf['user_filter']) + filter = Net::LDAP::Filter.join(filter, user_filter) + end + ldap_user = ldap.bind_as( - filter: Net::LDAP::Filter.eq(ldap.uid, login), + filter: filter, size: 1, password: password ) @@ -71,22 +79,20 @@ module Gitlab find_by_uid(ldap_user.dn) if ldap_user end - # Check LDAP user existance by dn. User in git over ssh check - # - # It covers 2 cases: - # * when ldap account was removed - # * when ldap account was deactivated by change of OU membership in 'dn' - def blocked?(dn) - ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf) - ldap.connection.search(base: dn, scope: Net::LDAP::SearchScope_BaseObject, size: 1).blank? - end - private def find_by_uid(uid) model.where(provider: provider, extern_uid: uid).last end + def username + (auth.info.nickname || samaccountname).to_s.force_encoding("utf-8") + end + + def samaccountname + (auth.extra[:raw_info][:samaccountname] || []).first + end + def provider 'ldap' end -- cgit v1.2.3 From 0fdab6a7478a6bc57c05485a246be318063e4e22 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 10 Mar 2014 17:09:45 +0200 Subject: Remove copyright Signed-off-by: Dmitriy Zaporozhets --- lib/gitlab/ldap/access.rb | 6 ------ lib/gitlab/ldap/adapter.rb | 6 ------ lib/gitlab/ldap/person.rb | 6 ------ 3 files changed, 18 deletions(-) diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb index 5ca240257bc..2a636244473 100644 --- a/lib/gitlab/ldap/access.rb +++ b/lib/gitlab/ldap/access.rb @@ -1,9 +1,3 @@ -#------------------------------------------------------------------- -# -# Copyright (C) 2013 GitLab.com - Distributed under the MIT Expat License -# -#------------------------------------------------------------------- - module Gitlab module LDAP class Access diff --git a/lib/gitlab/ldap/adapter.rb b/lib/gitlab/ldap/adapter.rb index c0ad1f90f38..a7b5bcb207c 100644 --- a/lib/gitlab/ldap/adapter.rb +++ b/lib/gitlab/ldap/adapter.rb @@ -1,9 +1,3 @@ -#------------------------------------------------------------------- -# -# Copyright (C) 2013 GitLab.com - Distributed under the MIT Expat License -# -#------------------------------------------------------------------- - module Gitlab module LDAP class Adapter diff --git a/lib/gitlab/ldap/person.rb b/lib/gitlab/ldap/person.rb index 339e6f37e2c..5ee383dfa03 100644 --- a/lib/gitlab/ldap/person.rb +++ b/lib/gitlab/ldap/person.rb @@ -1,9 +1,3 @@ -#------------------------------------------------------------------- -# -# Copyright (C) 2013 GitLab.com - Distributed under the MIT Expat License -# -#------------------------------------------------------------------- - module Gitlab module LDAP class Person -- cgit v1.2.3 From b1ff8e31b1717c1abbaa3db88da77aef48b51c4e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 10 Mar 2014 17:10:23 +0200 Subject: Add ldap check in application_controller and internal api Signed-off-by: Dmitriy Zaporozhets --- app/controllers/application_controller.rb | 19 +++++++++++++++++++ config/gitlab.yml.example | 15 ++++++++++++++- lib/api/internal.rb | 8 +++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9ed46c23942..af1a80ff799 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,6 +6,7 @@ class ApplicationController < ActionController::Base before_filter :check_password_expiration around_filter :set_current_user_for_thread before_filter :add_abilities + before_filter :ldap_security_check before_filter :dev_tools if Rails.env == 'development' before_filter :default_headers before_filter :add_gon_variables @@ -179,11 +180,29 @@ class ApplicationController < ActionController::Base end end + def ldap_security_check + if current_user && current_user.ldap_user? && current_user.requires_ldap_check? + if gitlab_ldap_access.allowed?(current_user) + gitlab_ldap_access.update_permissions(current_user) + current_user.last_credential_check_at = Time.now + current_user.save + else + sign_out current_user + flash[:alert] = "Access denied for your LDAP account." + redirect_to new_user_session_path + end + end + end + def event_filter filters = cookies['event_filter'].split(',') if cookies['event_filter'].present? @event_filter ||= EventFilter.new(filters) end + def gitlab_ldap_access + Gitlab::LDAP::Access.new + end + # JSON for infinite scroll via Pager object def pager_json(partial, count) html = render_to_string( diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index a40ce7212fe..9364181eaa4 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -121,7 +121,6 @@ production: &base ldap: enabled: false host: '_your_ldap_server' - base: '_the_base_where_you_search_for_users' port: 636 uid: 'sAMAccountName' method: 'ssl' # "tls" or "ssl" or "plain" @@ -138,6 +137,20 @@ production: &base # disable this setting, because the userPrincipalName contains an '@'. allow_username_or_email_login: true + # Base where we can search for users + # + # Ex. ou=People,dc=gitlab,dc=example + # + base: '' + + # Filter LDAP users + # + # Format: RFC 4515 + # Ex. (employeeType=developer) + # + user_filter: '' + + ## OmniAuth settings omniauth: # Allow login via Twitter, Google, etc. using OmniAuth providers diff --git a/lib/api/internal.rb b/lib/api/internal.rb index ebc9fef07b4..69aad3748b3 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -35,8 +35,14 @@ module API user = key.user return false if user.blocked? + if Gitlab.config.ldap.enabled - return false if user.ldap_user? && Gitlab::LDAP::User.blocked?(user.extern_uid) + if user.ldap_user? + # Check if LDAP user exists and match LDAP user_filter + unless Gitlab::LDAP::Access.new.allowed?(user) + return false + end + end end action = case git_cmd -- cgit v1.2.3 From 509c45163a69b608a65f11e3383f565c13d643c4 Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 10 Mar 2014 17:40:40 +0100 Subject: Update references to gitlab dot com. --- PROCESS.md | 6 +++--- README.md | 17 +++-------------- doc/development/architecture.md | 2 +- doc/install/installation.md | 2 +- doc/release/security.md | 2 +- 5 files changed, 9 insertions(+), 20 deletions(-) diff --git a/PROCESS.md b/PROCESS.md index bf757025c40..c582dc6fd0d 100644 --- a/PROCESS.md +++ b/PROCESS.md @@ -12,7 +12,7 @@ Below we describe the contributing process to GitLab for two reasons. So that co - Closes invalid issues and merge requests with a comment (duplicates, [feature requests](#feature-requests), [fixed in newer version](#issue-fixed-in-newer-version), [issue report for old version](#issue-report-for-old-version), not a problem in GitLab, etc.) - Assigns appropriate [labels](#how-we-handle-issues) - Asks for feedback from issue reporter/merge request initiator ([invalid issue reports](#improperly-formatted-issue), [format code](#code-format), etc.) -- Asks for feedback from the relevant developer(s) based on the [list of members and their specialities](http://gitlab.org/team/) +- Asks for feedback from the relevant developer(s) based on the [list of members and their specialities](https://www.gitlab.com/core-team/) - Monitors all issues/merge requests for feedback (but especially ones commented on since automatically watching them): - Closes issues with no feedback from the reporter for two weeks - Closes stale merge requests @@ -37,7 +37,7 @@ Below we describe the contributing process to GitLab for two reasons. So that co ## Mentioning people -The most important thing is making sure valid issues receive feedback from the development team. Therefore the priority is mentioning developers that can help on those issue. Please select someone with relevant experience from [GitLab core team](http://gitlab.org/team/). If there is nobody mentioned with that expertise look in the commit history for the affected files to find someone. Avoid mentioning the lead developer, this is the person that is least likely to give a timely response. If the involvement of the lead developer is needed the other core team members will mention this person. +The most important thing is making sure valid issues receive feedback from the development team. Therefore the priority is mentioning developers that can help on those issue. Please select someone with relevant experience from [GitLab core team](https://www.gitlab.com/core-team/). If there is nobody mentioned with that expertise look in the commit history for the affected files to find someone. Avoid mentioning the lead developer, this is the person that is least likely to give a timely response. If the involvement of the lead developer is needed the other core team members will mention this person. ## Workflow labels @@ -89,7 +89,7 @@ Please use ``` to format console output, logs, and code as it's very hard to rea ### Issue fixed in newer version -Thanks for the issue report. This issue has already been fixed in newer versions of GitLab. Due to the size of this project and our limited resources we are only able to support the latest stable release as outlined in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker). In order to get this bug fix and enjoy many new features please \[upgrade\]\(http://blog.gitlab.org/). If you still experience issues at that time please open a new issue following our issue tracker guidelines found in the \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). +Thanks for the issue report. This issue has already been fixed in newer versions of GitLab. Due to the size of this project and our limited resources we are only able to support the latest stable release as outlined in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker). In order to get this bug fix and enjoy many new features please \[upgrade\]\(https://github.com/gitlabhq/gitlabhq/tree/master/doc/update). If you still experience issues at that time please open a new issue following our issue tracker guidelines found in the \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). ### Improperly formatted merge request diff --git a/README.md b/README.md index 3bffdbe1f3a..b23c0bb14f9 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,11 @@ ### Resources -* GitLab.org community site: [Homepage](http://gitlab.org) | [Screenshots](http://gitlab.org/screenshots/) | [Blog](http://blog.gitlab.org/) | [Demo](http://demo.gitlabhq.com/users/sign_in) +* [GitLab.com](https://www.gitlab.com/) includes information about [subscriptions](https://www.gitlab.com/subscription/), [consultancy](https://www.gitlab.com/consultancy/), the [community](https://www.gitlab.com/community/) and the [hosted GitLab Cloud](https://www.gitlab.com/cloud/). -* GitLab.com commercial services: [Homepage](http://www.gitlab.com/) | [Subscription](http://www.gitlab.com/subscription/) | [Consultancy](http://www.gitlab.com/consultancy/) | [GitLab Cloud](http://www.gitlab.com/cloud/) | [Blog](http://blog.gitlab.com/) +* [GitLab Enterprise Edition](https://www.gitlab.com/gitlab-ce/) offers additional features that are useful for larger organizations (100+ users). -* [GitLab Enterprise Edition](https://www.gitlab.com/features/) offers additional features that are useful for larger organizations (100+ users). - -* [GitLab CI](https://gitlab.com/gitlab-org/gitlab-ci/blob/master/README.md) is a continuous integration (CI) server that is easy to integrate with GitLab. +* [GitLab CI](https://www.gitlab.com/gitlab-ci/) is a continuous integration (CI) server that is easy to integrate with GitLab. * Unofficial third-party [iPhone app](http://gitlabcontrol.com/) and [Android app](https://play.google.com/store/apps/details?id=com.bd.gitlab&hl=en) for GitLab @@ -155,12 +153,3 @@ or start each component separately * [Book](http://www.packtpub.com/gitlab-repository-management/book) written by GitLab enthusiast Jonathan M. Hethey is unofficial but it offers a good overview. * [Gitter chat room](https://gitter.im/gitlabhq/gitlabhq#) here you can ask questions when you need help. - - -### Getting in touch - -* [Core team](http://gitlab.org/team/) - -* [Contributors](http://contributors.gitlab.org/) - -* [Community](http://gitlab.org/community/) diff --git a/doc/development/architecture.md b/doc/development/architecture.md index 8a772344b79..ab74af4faf9 100644 --- a/doc/development/architecture.md +++ b/doc/development/architecture.md @@ -3,7 +3,7 @@ # Software delivery -There are two editions of GitLab: [Enterprise Edition](https://www.gitlab.com/features/) (EE) and [Community Edition](http://gitlab.org/gitlab-ce/) (CE). +There are two editions of GitLab: [Enterprise Edition](https://www.gitlab.com/gitlab-ee/) (EE) and [Community Edition](https://www.gitlab.com/gitlab-ce/) (CE). GitLab CE is delivered via git from the [gitlabhq repository](https://gitlab.com/gitlab-org/gitlab-ce/tree/master). New versions of GitLab are released in stable branches and the master branch is for bleeding edge development. diff --git a/doc/install/installation.md b/doc/install/installation.md index d6e0a8a0012..16f029dc10f 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -4,7 +4,7 @@ this should be the highest numbered stable branch (example shown below). ![capture](http://i.imgur.com/d2AlIVj.png) -If this is unclear check the [GitLab Blog](http://blog.gitlab.org/) for installation guide links by version. +If this is unclear check the [GitLab Blog](https://www.gitlab.com/blog/) for installation guide links by version. # Important notes diff --git a/doc/release/security.md b/doc/release/security.md index 7ec3991de85..8e5a7e32099 100644 --- a/doc/release/security.md +++ b/doc/release/security.md @@ -15,7 +15,7 @@ Please report suspected security vulnerabilities in private to support@gitlab.co 1. Acknowledge the issue to the researcher that disclosed it 1. Fix the issue on a feature branch, do this on the private GitLab development server and update the VERSION and CHANGELOG in this branch 1. Consider creating and testing workarounds -1. Create feature branches for the blog posts on GitLab.org and GitLab.com and link them from the code branch +1. Create feature branches for the blog post on GitLab.com and link them from the code branch 1. Merge the code feature branch into master 1. Cherry-pick the code into the latest stable branch 1. Create a git tag vX.X.X for CE and another patch release for EE -- cgit v1.2.3 From ad71eca8bbaeccc6e67d977c8d7c2deb324f123d Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 10 Mar 2014 18:14:59 +0100 Subject: Catch missing commands in rake tasks with '' --- lib/tasks/gitlab/task_helpers.rake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/tasks/gitlab/task_helpers.rake b/lib/tasks/gitlab/task_helpers.rake index d36b9682850..da61c6e007f 100644 --- a/lib/tasks/gitlab/task_helpers.rake +++ b/lib/tasks/gitlab/task_helpers.rake @@ -82,6 +82,8 @@ namespace :gitlab do def run(command) output, _ = Gitlab::Popen.popen(command) output + rescue Errno::ENOENT + '' # if the command does not exist, return an empty string end def uid_for(user_name) -- cgit v1.2.3 From 3e864036e73f537a37e601716f0835fbee4593c7 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 10 Mar 2014 19:16:43 +0200 Subject: Fix ldap_user_auth_spec Signed-off-by: Dmitriy Zaporozhets --- spec/lib/gitlab/ldap/ldap_user_auth_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb b/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb index a0e74c49631..501642dca79 100644 --- a/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb +++ b/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb @@ -9,7 +9,8 @@ describe Gitlab::LDAP do @info = double( uid: '12djsak321', name: 'John', - email: 'john@mail.com' + email: 'john@mail.com', + nickname: 'john' ) end -- cgit v1.2.3 From f84d84622393223e40dd9533f86266d5f377f881 Mon Sep 17 00:00:00 2001 From: Greg Messner Date: Mon, 10 Mar 2014 12:39:29 -0700 Subject: Added tests of Create and Update MR description. --- spec/requests/api/merge_requests_spec.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 412b6c95ffa..1a9e4809e7d 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -92,9 +92,10 @@ describe API::API do it "should return merge_request" do post api("/projects/#{fork_project.id}/merge_requests", user2), - title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user2, target_project_id: project.id + title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user2, target_project_id: project.id, description: 'Test description for Test merge_request' response.status.should == 201 json_response['title'].should == 'Test merge_request' + json_response['description'].should == 'Test description for Test merge_request' end it "should not return 422 when source_branch equals target_branch" do @@ -168,6 +169,12 @@ describe API::API do json_response['title'].should == 'New title' end + it "should return merge_request" do + put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), description: "New description" + response.status.should == 200 + json_response['description'].should == 'New description' + end + it "should return 422 when source_branch and target_branch are renamed the same" do put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), source_branch: "master", target_branch: "master" -- cgit v1.2.3 From 5d6d795d60050c2c5db95501b6de38e458fd41b6 Mon Sep 17 00:00:00 2001 From: Matt DeTullio Date: Sun, 9 Mar 2014 23:28:49 -0400 Subject: Fixes a bug with group member administration Group owners were not able to remove any users from their group if they were the only owner. --- app/models/ability.rb | 1 + features/group.feature | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 69ada753d02..1afe8a4638f 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -240,6 +240,7 @@ class Ability can_manage = group_abilities(user, group).include?(:manage_group) if can_manage && (user != target_user) rules << :modify + rules << :destroy end if !group.last_owner?(user) && (can_manage || (user == target_user)) rules << :destroy diff --git a/features/group.feature b/features/group.feature index 71282fb75ba..4e11bcba939 100644 --- a/features/group.feature +++ b/features/group.feature @@ -74,7 +74,7 @@ Feature: Groups When I visit group "Owned" members page Then I should see user "John Doe" in team list Then I should see user "Mary Jane" in team list - Then I should not see the "Remove User From Group" button for "Mary Jane" + Then I should not see the "Remove User From Group" button for "John Doe" @javascript Scenario: Guest should be able to remove himself from group -- cgit v1.2.3 From e57e1e04e3d4b930e60a87643f09c908b3bfb90b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 11 Mar 2014 09:15:04 +0200 Subject: Remove non-exist method from ldap security check Signed-off-by: Dmitriy Zaporozhets --- app/controllers/application_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index af1a80ff799..9b05bc479ff 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -183,7 +183,6 @@ class ApplicationController < ActionController::Base def ldap_security_check if current_user && current_user.ldap_user? && current_user.requires_ldap_check? if gitlab_ldap_access.allowed?(current_user) - gitlab_ldap_access.update_permissions(current_user) current_user.last_credential_check_at = Time.now current_user.save else -- cgit v1.2.3 From cf890b227a277086dd1b5cfee356027f1a77a424 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 11 Mar 2014 10:07:22 +0200 Subject: Add User#last_credential_check_at Signed-off-by: Dmitriy Zaporozhets --- .../20130809124851_add_permission_check_to_user.rb | 5 ++ db/schema.rb | 73 +++++++++++----------- 2 files changed, 40 insertions(+), 38 deletions(-) create mode 100644 db/migrate/20130809124851_add_permission_check_to_user.rb diff --git a/db/migrate/20130809124851_add_permission_check_to_user.rb b/db/migrate/20130809124851_add_permission_check_to_user.rb new file mode 100644 index 00000000000..c26157904c7 --- /dev/null +++ b/db/migrate/20130809124851_add_permission_check_to_user.rb @@ -0,0 +1,5 @@ +class AddPermissionCheckToUser < ActiveRecord::Migration + def change + add_column :users, :last_credential_check_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 9f1de4d2120..ec6673b6d37 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -76,8 +76,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.integer "assignee_id" t.integer "author_id" t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "position", default: 0 t.string "branch_name" t.text "description" @@ -95,8 +95,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "keys", force: true do |t| t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.text "key" t.string "title" t.string "type" @@ -123,8 +123,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.integer "author_id" t.integer "assignee_id" t.string "title" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "milestone_id" t.string "state" t.string "merge_status" @@ -176,8 +176,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.text "note" t.string "noteable_type" t.integer "author_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "project_id" t.string "attachment" t.string "line_code" @@ -199,8 +199,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "name" t.string "path" t.text "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "creator_id" t.boolean "issues_enabled", default: true, null: false t.boolean "wall_enabled", default: true, null: false @@ -252,8 +252,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.text "content", limit: 2147483647 t.integer "author_id", null: false t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "file_name" t.datetime "expires_at" t.boolean "private", default: true, null: false @@ -275,45 +275,42 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.datetime "created_at" end - add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id", using: :btree - add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree - create_table "tags", force: true do |t| t.string "name" end create_table "users", force: true do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false + t.string "email", default: "", null: false + t.string "encrypted_password", limit: 128, default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "name" - t.boolean "admin", default: false, null: false - t.integer "projects_limit", default: 10 - t.string "skype", default: "", null: false - t.string "linkedin", default: "", null: false - t.string "twitter", default: "", null: false + t.boolean "admin", default: false, null: false + t.integer "projects_limit", default: 10 + t.string "skype", default: "", null: false + t.string "linkedin", default: "", null: false + t.string "twitter", default: "", null: false t.string "authentication_token" - t.integer "theme_id", default: 1, null: false + t.integer "theme_id", default: 1, null: false t.string "bio" - t.integer "failed_attempts", default: 0 + t.integer "failed_attempts", default: 0 t.datetime "locked_at" t.string "extern_uid" t.string "provider" t.string "username" - t.boolean "can_create_group", default: true, null: false - t.boolean "can_create_team", default: true, null: false + t.boolean "can_create_group", default: true, null: false + t.boolean "can_create_team", default: true, null: false t.string "state" - t.integer "color_scheme_id", default: 1, null: false - t.integer "notification_level", default: 1, null: false + t.integer "color_scheme_id", default: 1, null: false + t.integer "notification_level", default: 1, null: false t.datetime "password_expires_at" t.integer "created_by_id" t.string "avatar" @@ -321,15 +318,15 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" - t.boolean "hide_no_ssh_key", default: false - t.string "website_url", default: "", null: false + t.boolean "hide_no_ssh_key", default: false + t.string "website_url", default: "", null: false + t.datetime "last_credential_check_at" end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree add_index "users", ["authentication_token"], name: "index_users_on_authentication_token", unique: true, using: :btree add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree - add_index "users", ["extern_uid", "provider"], name: "index_users_on_extern_uid_and_provider", unique: true, using: :btree add_index "users", ["name"], name: "index_users_on_name", using: :btree add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree add_index "users", ["username"], name: "index_users_on_username", using: :btree @@ -348,8 +345,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "users_projects", force: true do |t| t.integer "user_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "project_access", default: 0, null: false t.integer "notification_level", default: 3, null: false end @@ -361,8 +358,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "web_hooks", force: true do |t| t.string "url" t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "type", default: "ProjectHook" t.integer "service_id" t.boolean "push_events", default: true, null: false -- cgit v1.2.3 From c6d39a14d6b15f457bfc050f54e256cd5da64cc9 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 11 Mar 2014 10:24:07 +0200 Subject: Add User#requires_ldap_check? method Signed-off-by: Dmitriy Zaporozhets --- app/controllers/application_controller.rb | 2 +- app/models/user.rb | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9b05bc479ff..9a0c9f60b05 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -181,7 +181,7 @@ class ApplicationController < ActionController::Base end def ldap_security_check - if current_user && current_user.ldap_user? && current_user.requires_ldap_check? + if current_user && current_user.requires_ldap_check? if gitlab_ldap_access.allowed?(current_user) current_user.last_credential_check_at = Time.now current_user.save diff --git a/app/models/user.rb b/app/models/user.rb index 855fe58ffe8..a9ee471ad61 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -185,7 +185,7 @@ class User < ActiveRecord::Base where(conditions).first end end - + def find_for_commit(email, name) # Prefer email match over name match User.where(email: email).first || @@ -275,7 +275,9 @@ class User < ActiveRecord::Base # Projects user has access to def authorized_projects @authorized_projects ||= begin - project_ids = (personal_projects.pluck(:id) + groups_projects.pluck(:id) + projects.pluck(:id)).uniq + project_ids = personal_projects.pluck(:id) + project_ids += groups_projects.pluck(:id) + project_ids += projects.pluck(:id).uniq Project.where(id: project_ids).joins(:namespace).order('namespaces.name ASC') end end @@ -406,6 +408,14 @@ class User < ActiveRecord::Base end end + def requires_ldap_check? + if ldap_user? + !last_credential_check_at || (last_credential_check_at + 1.hour) < Time.now + else + false + end + end + def solo_owned_groups @solo_owned_groups ||= owned_groups.select do |group| group.owners == [self] -- cgit v1.2.3 From dcda7516d6657e1372137e5549e3af4400e0ad5f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 11 Mar 2014 12:18:14 +0200 Subject: Use username instead of wierd email for first login Signed-off-by: Dmitriy Zaporozhets --- doc/install/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/install/installation.md b/doc/install/installation.md index 16f029dc10f..c7495b8cbbb 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -351,7 +351,7 @@ If all items are green, then congratulations on successfully installing GitLab! Visit YOUR_SERVER in your web browser for your first GitLab login. The setup has created an admin account for you. You can use it to log in: - admin@local.host + root 5iveL!fe **Important Note:** -- cgit v1.2.3 From 0c3aa2e844f56bc1372742e57939ab6b708761c4 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 11 Mar 2014 13:18:10 +0200 Subject: More entries to CHANGELOG Signed-off-by: Dmitriy Zaporozhets --- CHANGELOG | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index c8bbce73f5a..f24cc8b5092 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,11 @@ v 6.7.0 - Fix CI status for merge requests from fork - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) - Converted all the help sections into markdown + - LDAP user filters + - Streamline the content of notification emails (Pierre de La Morinerie) + - Fixes a bug with group member administration (Matt DeTullio) + - Sort tag names using VersionSorter (Robert Speicher) + - Add GFM autocompletion for MergeRequests (Robert Speicher) v 6.6.2 - Fix 500 error on branch/tag create or remove via UI -- cgit v1.2.3 From 9f405068cdfeb185cd3762f0ae5df6d87f6e31ba Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 11 Mar 2014 13:33:47 +0200 Subject: SHow group name in access granted email Signed-off-by: Dmitriy Zaporozhets --- app/views/notify/group_access_granted_email.html.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/notify/group_access_granted_email.html.haml b/app/views/notify/group_access_granted_email.html.haml index 0092a947eee..823ebf77347 100644 --- a/app/views/notify/group_access_granted_email.html.haml +++ b/app/views/notify/group_access_granted_email.html.haml @@ -1,2 +1,4 @@ %p = "You have been granted #{@membership.human_access} access to group" + = link_to group_url(@group) do + = @group.name -- cgit v1.2.3 From 7157f79caa88689f1b8989d183ef20fbc942bd0f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 11 Mar 2014 15:15:08 +0200 Subject: Refactor js behaviours helpers Signed-off-by: Dmitriy Zaporozhets --- .../javascripts/behaviors/details_behavior.coffee | 12 +- .../javascripts/behaviors/toggler_behavior.coffee | 15 +- app/assets/javascripts/main.js.coffee | 9 -- app/assets/stylesheets/generic/common.scss | 4 - app/views/groups/members.html.haml | 6 +- app/views/projects/commit/_commit_box.html.haml | 2 +- app/views/projects/edit.html.haml | 173 +++++++++++---------- .../merge_requests/show/_mr_accept.html.haml | 23 +-- app/views/projects/new.html.haml | 58 ++++--- 9 files changed, 155 insertions(+), 147 deletions(-) diff --git a/app/assets/javascripts/behaviors/details_behavior.coffee b/app/assets/javascripts/behaviors/details_behavior.coffee index 7ad5c818946..decab3e1bed 100644 --- a/app/assets/javascripts/behaviors/details_behavior.coffee +++ b/app/assets/javascripts/behaviors/details_behavior.coffee @@ -1,5 +1,15 @@ $ -> $("body").on "click", ".js-details-target", -> container = $(@).closest(".js-details-container") - container.toggleClass("open") + + # Show details content. Hides link after click. + # + # %div + # %a.js-details-expand + # %div.js-details-content + # + $("body").on "click", ".js-details-expand", (e) -> + $(@).next('.js-details-content').removeClass("hide") + $(@).hide() + e.preventDefault() diff --git a/app/assets/javascripts/behaviors/toggler_behavior.coffee b/app/assets/javascripts/behaviors/toggler_behavior.coffee index 5afb656e696..d06cb116dfe 100644 --- a/app/assets/javascripts/behaviors/toggler_behavior.coffee +++ b/app/assets/javascripts/behaviors/toggler_behavior.coffee @@ -1,17 +1,18 @@ $ -> $("body").on "click", ".js-toggler-target", -> container = $(@).closest(".js-toggler-container") - container.toggleClass("on") - $("body").on "click", ".js-toggle-visibility-link", (e) -> + # Toggle button. Show/hide content inside parent container. + # Button does not change visibility. If button has icon - it changes chevron style. + # + # %div.js-toggle-container + # %a.js-toggle-button + # %div.js-toggle-content + # + $("body").on "click", ".js-toggle-button", (e) -> $(@).find('i'). toggleClass('icon-chevron-down'). toggleClass('icon-chevron-up') - container = $(".js-toggle-visibility-container") - container.toggleClass("hide") - e.preventDefault() - - $("body").on "click", ".js-toggle-button", (e) -> $(@).closest(".js-toggle-container").find(".js-toggle-content").toggle() e.preventDefault() diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee index 69c731ff1a1..70e8972d24d 100644 --- a/app/assets/javascripts/main.js.coffee +++ b/app/assets/javascripts/main.js.coffee @@ -62,11 +62,6 @@ $ -> $('.remove-row').bind 'ajax:success', -> $(this).closest('li').fadeOut() - # Click a .appear-link, appear-data fadeout - $(".appear-link").on 'click', (e) -> - $('.appear-data').fadeIn() - e.preventDefault() - # Initialize select2 selects $('select.select2').select2(width: 'resolve', dropdownAutoWidth: true) @@ -121,10 +116,6 @@ $ -> $(@).next('table').show() $(@).remove() - $(".diff-content").on "click", ".js-details-expand", -> - $(@).next('.js-details-contain').removeClass("hide") - $(@).remove() - (($) -> # Disable an element and add the 'disabled' Bootstrap class $.fn.extend disable: -> diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index 6183cefa594..b5ccaed0401 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -298,10 +298,6 @@ img.emoji { width: 20px; } -.appear-data { - display: none; -} - .chart { overflow: hidden; height: 220px; diff --git a/app/views/groups/members.html.haml b/app/views/groups/members.html.haml index 0c972622f88..2d0605b18ad 100644 --- a/app/views/groups/members.html.haml +++ b/app/views/groups/members.html.haml @@ -9,7 +9,7 @@ %hr -.clearfix +.clearfix.js-toggle-container = form_tag members_group_path(@group), method: :get, class: 'form-inline member-search-form' do .form-group = search_field_tag :search, params[:search], { placeholder: 'Find member by name', class: 'form-control search-text-input input-mn-300' } @@ -17,11 +17,11 @@ - if current_user && current_user.can?(:manage_group, @group) .pull-right - = link_to '#', class: 'btn btn-new js-toggle-visibility-link' do + = link_to '#', class: 'btn btn-new js-toggle-button' do Add members %i.icon-chevron-down - .js-toggle-visibility-container.hide.new-group-member-holder + .js-toggle-content.hide.new-group-member-holder = render "new_group_member" .ui-box.prepend-top-20 diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index df44c30c005..e61d9a2ac47 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -47,7 +47,7 @@ - if @branches.any? and in = link_to("#{pluralize(@branches.count, "other branch")}", "#", class: "js-details-expand") - %span.js-details-contain.hide + %span.js-details-content.hide = commit_branches_links(@project, @branches) .commit-box diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 005d994806e..10674ccae46 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -93,100 +93,101 @@ - .centered-light-block - %h3 - %i.icon-warning-sign - Dangerous settings - - %p Project settings below may result in data loss! - = link_to '#', class: 'btn js-toggle-visibility-link' do - Show it to me - %i.icon-chevron-down - - .js-toggle-visibility-container.hide - - if can? current_user, :archive_project, @project - .ui-box.ui-box-danger - .title - - if @project.archived? - Unarchive project - - else - Archive project - .body - - if @project.archived? - %p - Unarchiving the project will mark its repository as active. - %br - The project can be committed to. - %br - %strong Once active this project shows up in the search and on the dashboard. - = link_to 'Unarchive', unarchive_project_path(@project), - data: { confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be comitted to again." }, - method: :post, class: "btn btn-remove" - - else - %p - Archiving the project will mark its repository as read-only. - %br - It is hidden from the dashboard and doesn't show up in searches. - %br - %strong Archived projects cannot be committed to! - = link_to 'Archive', archive_project_path(@project), - data: { confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to." }, - method: :post, class: "btn btn-remove" - - else - .nothing-here-block Only the project owner can archive a project - - - if can?(current_user, :change_namespace, @project) + .danger-settings.js-toggle-container + .centered-light-block + %h3 + %i.icon-warning-sign + Dangerous settings + + %p Project settings below may result in data loss! + = link_to '#', class: 'btn js-toggle-button' do + Show it to me + %i.icon-chevron-down + + .js-toggle-content.hide + - if can? current_user, :archive_project, @project + .ui-box.ui-box-danger + .title + - if @project.archived? + Unarchive project + - else + Archive project + .body + - if @project.archived? + %p + Unarchiving the project will mark its repository as active. + %br + The project can be committed to. + %br + %strong Once active this project shows up in the search and on the dashboard. + = link_to 'Unarchive', unarchive_project_path(@project), + data: { confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be comitted to again." }, + method: :post, class: "btn btn-remove" + - else + %p + Archiving the project will mark its repository as read-only. + %br + It is hidden from the dashboard and doesn't show up in searches. + %br + %strong Archived projects cannot be committed to! + = link_to 'Archive', archive_project_path(@project), + data: { confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to." }, + method: :post, class: "btn btn-remove" + - else + .nothing-here-block Only the project owner can archive a project + + - if can?(current_user, :change_namespace, @project) + .ui-box.ui-box-danger + .title Transfer project + .errors-holder + .form-holder + = form_for(@project, url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'transfer-project form-horizontal' }) do |f| + .form-group + = f.label :namespace_id, class: 'control-label' do + %span Namespace + .col-sm-10 + .form-group + = f.select :namespace_id, namespaces_options(@project.namespace_id), { prompt: 'Choose a project namespace' }, { class: 'select2' } + %ul + %li Be careful. Changing the project's namespace can have unintended side effects. + %li You can only transfer the project to namespaces you manage. + %li You will need to update your local repositories to point to the new location. + .form-actions + = f.submit 'Transfer', class: "btn btn-remove" + - else + .nothing-here-block Only the project owner can transfer a project + .ui-box.ui-box-danger - .title Transfer project + .title Rename repository .errors-holder .form-holder - = form_for(@project, url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'transfer-project form-horizontal' }) do |f| + = form_for(@project, html: { class: 'form-horizontal' }) do |f| .form-group - = f.label :namespace_id, class: 'control-label' do - %span Namespace - .col-sm-10 + = f.label :path, class: 'control-label' do + %span Path + .col-sm-9 .form-group - = f.select :namespace_id, namespaces_options(@project.namespace_id), { prompt: 'Choose a project namespace' }, { class: 'select2' } + .input-group + = f.text_field :path, class: 'form-control' + %span.input-group-addon .git %ul - %li Be careful. Changing the project's namespace can have unintended side effects. - %li You can only transfer the project to namespaces you manage. + %li Be careful. Renaming a project's repository can have unintended side effects. %li You will need to update your local repositories to point to the new location. .form-actions - = f.submit 'Transfer', class: "btn btn-remove" - - else - .nothing-here-block Only the project owner can transfer a project - - .ui-box.ui-box-danger - .title Rename repository - .errors-holder - .form-holder - = form_for(@project, html: { class: 'form-horizontal' }) do |f| - .form-group - = f.label :path, class: 'control-label' do - %span Path - .col-sm-9 - .form-group - .input-group - = f.text_field :path, class: 'form-control' - %span.input-group-addon .git - %ul - %li Be careful. Renaming a project's repository can have unintended side effects. - %li You will need to update your local repositories to point to the new location. - .form-actions - = f.submit 'Rename', class: "btn btn-remove" - - - if can?(current_user, :remove_project, @project) - .ui-box.ui-box-danger - .title Remove project - .body - %p - Removing the project will delete its repository and all related resources including issues, merge requests etc. - %br - %strong Removed projects cannot be restored! - - = link_to 'Remove project', @project, data: { confirm: remove_project_message(@project) }, method: :delete, class: "btn btn-remove" - - else - .nothing-here-block Only project owner can remove a project + = f.submit 'Rename', class: "btn btn-remove" + + - if can?(current_user, :remove_project, @project) + .ui-box.ui-box-danger + .title Remove project + .body + %p + Removing the project will delete its repository and all related resources including issues, merge requests etc. + %br + %strong Removed projects cannot be restored! + + = link_to 'Remove project', @project, data: { confirm: remove_project_message(@project) }, method: :delete, class: "btn btn-remove" + - else + .nothing-here-block Only project owner can remove a project .save-project-loader.hide %center diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml index a9cbe43fb16..97706a5a4b0 100644 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml @@ -15,18 +15,19 @@ = link_to "click here", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" for instructions. - %br - If you want to modify merge commit message - - %strong - = link_to "click here", "#", class: "modify-merge-commit-link js-toggle-visibility-link", title: "Modify merge commit message" - .js-toggle-visibility-container.hide - .form-group - = label_tag :merge_commit_message, "Commit message", class: 'control-label' - .col-sm-10 - = text_area_tag :merge_commit_message, @merge_request.merge_commit_message, class: "form-control js-gfm-input", rows: 14, required: true - %p.hint - The recommended maximum line length is 52 characters for the first line and 72 characters for all following lines. + .js-toggle-container + %p + If you want to modify merge commit message - + %strong + = link_to "click here", "#", class: "modify-merge-commit-link js-toggle-button", title: "Modify merge commit message" + .js-toggle-content.hide + .form-group + = label_tag :merge_commit_message, "Commit message", class: 'control-label' + .col-sm-10 + = text_area_tag :merge_commit_message, @merge_request.merge_commit_message, class: "form-control js-gfm-input", rows: 14, required: true + %p.hint + The recommended maximum line length is 52 characters for the first line and 72 characters for all following lines. .accept-group .pull-left diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 9ee54fef062..9cc28c7f535 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -9,18 +9,6 @@ %strong Project name .col-sm-10 = f.text_field :name, placeholder: "Example Project", class: "form-control", tabindex: 1, autofocus: true - .help-inline - = link_to "#", class: 'js-toggle-visibility-link' do - %span Customize repository name? - - .form-group.js-toggle-visibility-container.hide - = f.label :path, class: 'control-label' do - %span Repository name - .col-sm-10 - .input-group - = f.text_field :path, class: 'form-control' - %span.input-group-addon .git - - if current_user.can_select_namespace? .form-group @@ -29,19 +17,39 @@ .col-sm-10 = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2} - .form-group - .col-sm-2 - .col-sm-10 - = link_to "#", class: 'appear-link' do - %i.icon-upload-alt - %span Import existing repository? - .form-group.appear-data.import-url-data - = f.label :import_url, class: 'control-label' do - %span Import existing repo - .col-sm-10 - = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' - .light - URL must be cloneable + %hr + .js-toggle-container + .form-group + .col-sm-2 + .col-sm-10 + = link_to "#", class: 'js-toggle-button' do + %span Customize repository name? + .js-toggle-content.hide + .form-group + = f.label :path, class: 'control-label' do + %span Repository name + .col-sm-10 + .input-group + = f.text_field :path, class: 'form-control' + %span.input-group-addon .git + + .js-toggle-container + .form-group + .col-sm-2 + .col-sm-10 + = link_to "#", class: 'js-toggle-button' do + %i.icon-upload-alt + %span Import existing repository? + .js-toggle-content.hide + .form-group.import-url-data + = f.label :import_url, class: 'control-label' do + %span Import existing repo + .col-sm-10 + = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' + .light + URL must be cloneable + %hr + .form-group = f.label :description, class: 'control-label' do Description -- cgit v1.2.3 From a6eb28abc5e4d90780f63e30fbcb7857989ef7ac Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 11 Mar 2014 18:23:03 +0200 Subject: Better explanation for import url Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/new.html.haml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 9cc28c7f535..83bbbb058f0 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -23,6 +23,7 @@ .col-sm-2 .col-sm-10 = link_to "#", class: 'js-toggle-button' do + %i.icon-edit %span Customize repository name? .js-toggle-content.hide .form-group @@ -46,8 +47,10 @@ %span Import existing repo .col-sm-10 = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' - .light - URL must be cloneable + %p.help-block + This url must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git. + %br + Import timeout is 2 minutes. For big repositories use clone/push combination. %hr .form-group -- cgit v1.2.3 From dff9221c407bdb277db14b3daef6fc230f38ac7c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 11 Mar 2014 18:34:43 +0200 Subject: Show import notice in callout block Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/new.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 83bbbb058f0..3f9d05cff2d 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -47,7 +47,7 @@ %span Import existing repo .col-sm-10 = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' - %p.help-block + .bs-callout.bs-callout-info This url must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git. %br Import timeout is 2 minutes. For big repositories use clone/push combination. -- cgit v1.2.3 From 71b1030bf7cb85e5fc9efb40951e9613dbbc5ada Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Tue, 11 Mar 2014 19:20:15 +0100 Subject: Added rake task to add limits back in mysql --- lib/tasks/migrate/add_limits_mysql.rake | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 lib/tasks/migrate/add_limits_mysql.rake diff --git a/lib/tasks/migrate/add_limits_mysql.rake b/lib/tasks/migrate/add_limits_mysql.rake new file mode 100644 index 00000000000..7dadfe6164d --- /dev/null +++ b/lib/tasks/migrate/add_limits_mysql.rake @@ -0,0 +1,13 @@ +desc "GITLAB | Add limits to strings in mysql database" +task add_limits_mysql: :environment do + puts "Adding limits to schema.rb for mysql" + LimitsToMysql.new.up +end + +class LimitsToMysql < ActiveRecord::Migration + def up + change_column :merge_request_diffs, :st_commits, :text, limit: 65535 + change_column :merge_request_diffs, :st_diffs, :text, limit: 65535 + change_column :snippets, :content, :text, limit: 65535 + end +end -- cgit v1.2.3 From 55fbe71ad11640347be8128d3c26a33b934e30a8 Mon Sep 17 00:00:00 2001 From: Daniel Cestari Date: Tue, 11 Mar 2014 17:20:02 -0430 Subject: Fix error with reopened merge request not properly reloading If you reopen a Merge Request and then try to update the source branch it won't properly reload the code since the "reload_code" method still checks if the MR is "opened" and not just "open" (which includes reopened) --- app/models/merge_request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 4774cbcf3aa..7c2648d8c7a 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -133,7 +133,7 @@ class MergeRequest < ActiveRecord::Base end def reload_code - if merge_request_diff && opened? + if merge_request_diff && open? merge_request_diff.reload_content end end -- cgit v1.2.3 From f9c4bb56388daf0747b8b90a28e0f97acfbb92f8 Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Wed, 12 Mar 2014 08:13:27 +0100 Subject: Changed limits to a higher order --- lib/tasks/migrate/add_limits_mysql.rake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/tasks/migrate/add_limits_mysql.rake b/lib/tasks/migrate/add_limits_mysql.rake index 7dadfe6164d..163d6377cfb 100644 --- a/lib/tasks/migrate/add_limits_mysql.rake +++ b/lib/tasks/migrate/add_limits_mysql.rake @@ -6,8 +6,8 @@ end class LimitsToMysql < ActiveRecord::Migration def up - change_column :merge_request_diffs, :st_commits, :text, limit: 65535 - change_column :merge_request_diffs, :st_diffs, :text, limit: 65535 - change_column :snippets, :content, :text, limit: 65535 + change_column :merge_request_diffs, :st_commits, :text, limit: 2147483647 + change_column :merge_request_diffs, :st_diffs, :text, limit: 2147483647 + change_column :snippets, :content, :text, limit: 2147483647 end end -- cgit v1.2.3 From 75c9c68c18f287473e49b1f8e9282c1062d48897 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 12 Mar 2014 09:55:08 +0200 Subject: Rebuild schame from migrations Signed-off-by: Dmitriy Zaporozhets --- db/schema.rb | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 725174f2fd1..e07fd3deaca 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -278,17 +278,20 @@ ActiveRecord::Schema.define(version: 20140305193308) do t.datetime "created_at" end + add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id", using: :btree + add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree + create_table "tags", force: true do |t| t.string "name" end create_table "users", force: true do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", limit: 128, default: "", null: false + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" @@ -296,40 +299,41 @@ ActiveRecord::Schema.define(version: 20140305193308) do t.datetime "created_at" t.datetime "updated_at" t.string "name" - t.boolean "admin", default: false, null: false - t.integer "projects_limit", default: 10 - t.string "skype", default: "", null: false - t.string "linkedin", default: "", null: false - t.string "twitter", default: "", null: false + t.boolean "admin", default: false, null: false + t.integer "projects_limit", default: 10 + t.string "skype", default: "", null: false + t.string "linkedin", default: "", null: false + t.string "twitter", default: "", null: false t.string "authentication_token" - t.integer "theme_id", default: 1, null: false + t.integer "theme_id", default: 1, null: false t.string "bio" - t.integer "failed_attempts", default: 0 + t.integer "failed_attempts", default: 0 t.datetime "locked_at" t.string "extern_uid" t.string "provider" t.string "username" - t.boolean "can_create_group", default: true, null: false - t.boolean "can_create_team", default: true, null: false + t.boolean "can_create_group", default: true, null: false + t.boolean "can_create_team", default: true, null: false t.string "state" - t.integer "color_scheme_id", default: 1, null: false - t.integer "notification_level", default: 1, null: false + t.integer "color_scheme_id", default: 1, null: false + t.integer "notification_level", default: 1, null: false t.datetime "password_expires_at" t.integer "created_by_id" + t.datetime "last_credential_check_at" t.string "avatar" t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" - t.boolean "hide_no_ssh_key", default: false - t.string "website_url", default: "", null: false - t.datetime "last_credential_check_at" + t.boolean "hide_no_ssh_key", default: false + t.string "website_url", default: "", null: false end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree add_index "users", ["authentication_token"], name: "index_users_on_authentication_token", unique: true, using: :btree add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree + add_index "users", ["extern_uid", "provider"], name: "index_users_on_extern_uid_and_provider", unique: true, using: :btree add_index "users", ["name"], name: "index_users_on_name", using: :btree add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree add_index "users", ["username"], name: "index_users_on_username", using: :btree -- cgit v1.2.3 From 1c23f2b2594a1326a21a3ecd0856fa9b57eca059 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 12 Mar 2014 10:08:58 +0200 Subject: Correct image path to social icons Signed-off-by: Dmitriy Zaporozhets --- app/helpers/application_helper.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 90b05027155..faecde299c1 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -146,8 +146,7 @@ module ApplicationHelper def authbutton(provider, size = 64) file_name = "#{provider.to_s.split('_').first}_#{size}.png" - image_tag("authbuttons/#{file_name}", - alt: "Sign in with #{provider.to_s.titleize}") + image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}") end def simple_sanitize(str) -- cgit v1.2.3 From ae4ae2b225ffa5883a45d1de4cc79bdc96550cdf Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 12 Mar 2014 10:19:24 +0200 Subject: Move images from vendor to app so they are compiled by rails Signed-off-by: Dmitriy Zaporozhets --- app/assets/images/authbuttons/github_32.png | Bin 0 -> 1902 bytes app/assets/images/authbuttons/github_64.png | Bin 0 -> 4444 bytes app/assets/images/authbuttons/google_32.png | Bin 0 -> 1611 bytes app/assets/images/authbuttons/google_64.png | Bin 0 -> 3437 bytes app/assets/images/authbuttons/twitter_32.png | Bin 0 -> 1417 bytes app/assets/images/authbuttons/twitter_64.png | Bin 0 -> 3328 bytes app/assets/images/bg_fallback.png | Bin 0 -> 2976 bytes app/assets/images/icon_sprite.png | Bin 0 -> 2782 bytes app/assets/images/progress_bar.gif | Bin 0 -> 494 bytes app/assets/images/slider_handles.png | Bin 0 -> 4122 bytes app/assets/images/ui-icons_222222_256x240.png | Bin 0 -> 4193 bytes app/assets/images/ui-icons_454545_256x240.png | Bin 0 -> 4193 bytes vendor/assets/images/authbuttons/github_32.png | Bin 1902 -> 0 bytes vendor/assets/images/authbuttons/github_64.png | Bin 4444 -> 0 bytes vendor/assets/images/authbuttons/google_32.png | Bin 1611 -> 0 bytes vendor/assets/images/authbuttons/google_64.png | Bin 3437 -> 0 bytes vendor/assets/images/authbuttons/twitter_32.png | Bin 1417 -> 0 bytes vendor/assets/images/authbuttons/twitter_64.png | Bin 3328 -> 0 bytes vendor/assets/images/bg_fallback.png | Bin 2976 -> 0 bytes vendor/assets/images/icon_sprite.png | Bin 2782 -> 0 bytes vendor/assets/images/progress_bar.gif | Bin 494 -> 0 bytes vendor/assets/images/slider_handles.png | Bin 4122 -> 0 bytes vendor/assets/images/ui-icons_222222_256x240.png | Bin 4193 -> 0 bytes vendor/assets/images/ui-icons_454545_256x240.png | Bin 4193 -> 0 bytes 24 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 app/assets/images/authbuttons/github_32.png create mode 100644 app/assets/images/authbuttons/github_64.png create mode 100644 app/assets/images/authbuttons/google_32.png create mode 100644 app/assets/images/authbuttons/google_64.png create mode 100644 app/assets/images/authbuttons/twitter_32.png create mode 100644 app/assets/images/authbuttons/twitter_64.png create mode 100644 app/assets/images/bg_fallback.png create mode 100644 app/assets/images/icon_sprite.png create mode 100644 app/assets/images/progress_bar.gif create mode 100644 app/assets/images/slider_handles.png create mode 100644 app/assets/images/ui-icons_222222_256x240.png create mode 100644 app/assets/images/ui-icons_454545_256x240.png delete mode 100644 vendor/assets/images/authbuttons/github_32.png delete mode 100644 vendor/assets/images/authbuttons/github_64.png delete mode 100644 vendor/assets/images/authbuttons/google_32.png delete mode 100644 vendor/assets/images/authbuttons/google_64.png delete mode 100644 vendor/assets/images/authbuttons/twitter_32.png delete mode 100644 vendor/assets/images/authbuttons/twitter_64.png delete mode 100644 vendor/assets/images/bg_fallback.png delete mode 100644 vendor/assets/images/icon_sprite.png delete mode 100644 vendor/assets/images/progress_bar.gif delete mode 100644 vendor/assets/images/slider_handles.png delete mode 100644 vendor/assets/images/ui-icons_222222_256x240.png delete mode 100644 vendor/assets/images/ui-icons_454545_256x240.png diff --git a/app/assets/images/authbuttons/github_32.png b/app/assets/images/authbuttons/github_32.png new file mode 100644 index 00000000000..c56eef05eb9 Binary files /dev/null and b/app/assets/images/authbuttons/github_32.png differ diff --git a/app/assets/images/authbuttons/github_64.png b/app/assets/images/authbuttons/github_64.png new file mode 100644 index 00000000000..39de55bc796 Binary files /dev/null and b/app/assets/images/authbuttons/github_64.png differ diff --git a/app/assets/images/authbuttons/google_32.png b/app/assets/images/authbuttons/google_32.png new file mode 100644 index 00000000000..6225cc9c2d7 Binary files /dev/null and b/app/assets/images/authbuttons/google_32.png differ diff --git a/app/assets/images/authbuttons/google_64.png b/app/assets/images/authbuttons/google_64.png new file mode 100644 index 00000000000..4d608f71008 Binary files /dev/null and b/app/assets/images/authbuttons/google_64.png differ diff --git a/app/assets/images/authbuttons/twitter_32.png b/app/assets/images/authbuttons/twitter_32.png new file mode 100644 index 00000000000..696eb02484d Binary files /dev/null and b/app/assets/images/authbuttons/twitter_32.png differ diff --git a/app/assets/images/authbuttons/twitter_64.png b/app/assets/images/authbuttons/twitter_64.png new file mode 100644 index 00000000000..2893274766f Binary files /dev/null and b/app/assets/images/authbuttons/twitter_64.png differ diff --git a/app/assets/images/bg_fallback.png b/app/assets/images/bg_fallback.png new file mode 100644 index 00000000000..d9066ad7d7b Binary files /dev/null and b/app/assets/images/bg_fallback.png differ diff --git a/app/assets/images/icon_sprite.png b/app/assets/images/icon_sprite.png new file mode 100644 index 00000000000..9ad65fc443b Binary files /dev/null and b/app/assets/images/icon_sprite.png differ diff --git a/app/assets/images/progress_bar.gif b/app/assets/images/progress_bar.gif new file mode 100644 index 00000000000..c3d43fa40b2 Binary files /dev/null and b/app/assets/images/progress_bar.gif differ diff --git a/app/assets/images/slider_handles.png b/app/assets/images/slider_handles.png new file mode 100644 index 00000000000..a6d477033fa Binary files /dev/null and b/app/assets/images/slider_handles.png differ diff --git a/app/assets/images/ui-icons_222222_256x240.png b/app/assets/images/ui-icons_222222_256x240.png new file mode 100644 index 00000000000..8bc06cbf03b Binary files /dev/null and b/app/assets/images/ui-icons_222222_256x240.png differ diff --git a/app/assets/images/ui-icons_454545_256x240.png b/app/assets/images/ui-icons_454545_256x240.png new file mode 100644 index 00000000000..cfd1eaffaae Binary files /dev/null and b/app/assets/images/ui-icons_454545_256x240.png differ diff --git a/vendor/assets/images/authbuttons/github_32.png b/vendor/assets/images/authbuttons/github_32.png deleted file mode 100644 index c56eef05eb9..00000000000 Binary files a/vendor/assets/images/authbuttons/github_32.png and /dev/null differ diff --git a/vendor/assets/images/authbuttons/github_64.png b/vendor/assets/images/authbuttons/github_64.png deleted file mode 100644 index 39de55bc796..00000000000 Binary files a/vendor/assets/images/authbuttons/github_64.png and /dev/null differ diff --git a/vendor/assets/images/authbuttons/google_32.png b/vendor/assets/images/authbuttons/google_32.png deleted file mode 100644 index 6225cc9c2d7..00000000000 Binary files a/vendor/assets/images/authbuttons/google_32.png and /dev/null differ diff --git a/vendor/assets/images/authbuttons/google_64.png b/vendor/assets/images/authbuttons/google_64.png deleted file mode 100644 index 4d608f71008..00000000000 Binary files a/vendor/assets/images/authbuttons/google_64.png and /dev/null differ diff --git a/vendor/assets/images/authbuttons/twitter_32.png b/vendor/assets/images/authbuttons/twitter_32.png deleted file mode 100644 index 696eb02484d..00000000000 Binary files a/vendor/assets/images/authbuttons/twitter_32.png and /dev/null differ diff --git a/vendor/assets/images/authbuttons/twitter_64.png b/vendor/assets/images/authbuttons/twitter_64.png deleted file mode 100644 index 2893274766f..00000000000 Binary files a/vendor/assets/images/authbuttons/twitter_64.png and /dev/null differ diff --git a/vendor/assets/images/bg_fallback.png b/vendor/assets/images/bg_fallback.png deleted file mode 100644 index d9066ad7d7b..00000000000 Binary files a/vendor/assets/images/bg_fallback.png and /dev/null differ diff --git a/vendor/assets/images/icon_sprite.png b/vendor/assets/images/icon_sprite.png deleted file mode 100644 index 9ad65fc443b..00000000000 Binary files a/vendor/assets/images/icon_sprite.png and /dev/null differ diff --git a/vendor/assets/images/progress_bar.gif b/vendor/assets/images/progress_bar.gif deleted file mode 100644 index c3d43fa40b2..00000000000 Binary files a/vendor/assets/images/progress_bar.gif and /dev/null differ diff --git a/vendor/assets/images/slider_handles.png b/vendor/assets/images/slider_handles.png deleted file mode 100644 index a6d477033fa..00000000000 Binary files a/vendor/assets/images/slider_handles.png and /dev/null differ diff --git a/vendor/assets/images/ui-icons_222222_256x240.png b/vendor/assets/images/ui-icons_222222_256x240.png deleted file mode 100644 index 8bc06cbf03b..00000000000 Binary files a/vendor/assets/images/ui-icons_222222_256x240.png and /dev/null differ diff --git a/vendor/assets/images/ui-icons_454545_256x240.png b/vendor/assets/images/ui-icons_454545_256x240.png deleted file mode 100644 index cfd1eaffaae..00000000000 Binary files a/vendor/assets/images/ui-icons_454545_256x240.png and /dev/null differ -- cgit v1.2.3 From 42f25e75f84622f57073e4ba64f292eac2dac78d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 12 Mar 2014 10:25:37 +0200 Subject: Improve import notice Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/new.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 3f9d05cff2d..5d5637c1588 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -50,7 +50,7 @@ .bs-callout.bs-callout-info This url must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git. %br - Import timeout is 2 minutes. For big repositories use clone/push combination. + The import will time out after 2 minutes. For big repositories, use a clone/push combination. %hr .form-group -- cgit v1.2.3 From c22646d2a4f5fd50997cd95d89b35b27df65721f Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Wed, 12 Mar 2014 14:04:24 +0100 Subject: Logrotate daily, keeping 90 days of old logs Also remove the 'delaycompress' option which is not needed because we use 'copytruncate'. --- lib/support/logrotate/gitlab | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/support/logrotate/gitlab b/lib/support/logrotate/gitlab index df9398d0795..d9b07b61ec3 100644 --- a/lib/support/logrotate/gitlab +++ b/lib/support/logrotate/gitlab @@ -2,21 +2,19 @@ # based on: http://stackoverflow.com/a/4883967 /home/git/gitlab/log/*.log { - weekly + daily missingok - rotate 52 + rotate 90 compress - delaycompress notifempty copytruncate } /home/git/gitlab-shell/gitlab-shell.log { - weekly + daily missingok - rotate 52 + rotate 90 compress - delaycompress notifempty copytruncate } -- cgit v1.2.3 From 3e6fe8bff04f7ab72119cdfc04d7c752c58a3d40 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Wed, 12 Mar 2014 16:01:10 +0100 Subject: Add 6.6-to-6.7.md update guide --- doc/update/6.6-to-6.7.md | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 doc/update/6.6-to-6.7.md diff --git a/doc/update/6.6-to-6.7.md b/doc/update/6.6-to-6.7.md new file mode 100644 index 00000000000..7b2fc673628 --- /dev/null +++ b/doc/update/6.6-to-6.7.md @@ -0,0 +1,95 @@ +# From 6.6 to 6.7 + +### 0. Backup + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production +``` + +### 1. Stop server + + sudo service gitlab stop + +### 2. Get latest code + +```bash +cd /home/git/gitlab +sudo -u git -H git fetch --all +``` + +For Gitlab Community Edition: + +```bash +sudo -u git -H git checkout 6-7-stable +``` + +OR + +For GitLab Enterprise Edition: + +```bash +sudo -u git -H git checkout 6-7-stable-ee +``` + +### 3. Update gitlab-shell (and its config) + +```bash +cd /home/git/gitlab-shell +sudo -u git -H git fetch +sudo -u git -H git checkout v1.8.0 +``` + +### 4. Install libs, migrations, etc. + +```bash +cd /home/git/gitlab + +# MySQL installations (note: the line below states '--without ... postgres') +sudo -u git -H bundle install --without development test postgres --deployment + +# PostgreSQL installations (note: the line below states '--without ... mysql') +sudo -u git -H bundle install --without development test mysql --deployment + + +# Run database migrations +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production + +# Clean up assets and cache +sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production + +# Update init.d script +sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab +``` + + +### 5. Start application + + sudo service gitlab start + sudo service nginx restart + +### 6. Check application status + +Check if GitLab and its environment are configured correctly: + + sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production + +To make sure you didn't miss anything run a more thorough check with: + + sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production + +If all items are green, then congratulations upgrade is complete! + +## Things went south? Revert to previous version (6.6) + +### 1. Revert the code to the previous version +Follow the [`upgrade guide from 6.5 to 6.6`](6.5-to-6.6.md), except for the database migration +(The backup is already migrated to the previous version) + +### 2. Restore from the backup: + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production +``` +If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. -- cgit v1.2.3 From 85a4d1ec6c0288d960c5c51d2d6e6b4ce55e2e35 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Wed, 12 Mar 2014 16:01:34 +0100 Subject: Update the logrotate configuration in 6.7 --- doc/update/6.6-to-6.7.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/update/6.6-to-6.7.md b/doc/update/6.6-to-6.7.md index 7b2fc673628..e4a0cafa911 100644 --- a/doc/update/6.6-to-6.7.md +++ b/doc/update/6.6-to-6.7.md @@ -60,6 +60,9 @@ sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS # Update init.d script sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab + +# Update the logrotate configuration (keep logs for 90 days instead of 52 weeks) +sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab ``` -- cgit v1.2.3 From e603da7360dd8141a00b8096cb67acda0e039940 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 12 Mar 2014 17:14:28 +0200 Subject: Add Project#import_status field Signed-off-by: Dmitriy Zaporozhets --- .../20140312145357_add_import_status_to_project.rb | 5 + db/schema.rb | 101 +++++++++++---------- 2 files changed, 60 insertions(+), 46 deletions(-) create mode 100644 db/migrate/20140312145357_add_import_status_to_project.rb diff --git a/db/migrate/20140312145357_add_import_status_to_project.rb b/db/migrate/20140312145357_add_import_status_to_project.rb new file mode 100644 index 00000000000..ef972e8342a --- /dev/null +++ b/db/migrate/20140312145357_add_import_status_to_project.rb @@ -0,0 +1,5 @@ +class AddImportStatusToProject < ActiveRecord::Migration + def change + add_column :projects, :import_status, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index ec6673b6d37..00627c945a7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,15 +11,18 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140304005354) do +ActiveRecord::Schema.define(version: 20140312145357) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" create_table "broadcast_messages", force: true do |t| t.text "message", null: false t.datetime "starts_at" t.datetime "ends_at" t.integer "alert_type" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "color" t.string "font" end @@ -27,8 +30,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "deploy_keys_projects", force: true do |t| t.integer "deploy_key_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "deploy_keys_projects", ["project_id"], name: "index_deploy_keys_projects_on_project_id", using: :btree @@ -49,8 +52,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "title" t.text "data" t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "action" t.integer "author_id" end @@ -65,8 +68,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "forked_project_links", force: true do |t| t.integer "forked_to_project_id", null: false t.integer "forked_from_project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree @@ -106,10 +109,10 @@ ActiveRecord::Schema.define(version: 20140304005354) do add_index "keys", ["user_id"], name: "index_keys_on_user_id", using: :btree create_table "merge_request_diffs", force: true do |t| - t.string "state", default: "collected", null: false - t.text "st_commits", limit: 2147483647 - t.text "st_diffs", limit: 2147483647 - t.integer "merge_request_id", null: false + t.string "state", default: "collected", null: false + t.text "st_commits" + t.text "st_diffs" + t.integer "merge_request_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -138,7 +141,7 @@ ActiveRecord::Schema.define(version: 20140304005354) do add_index "merge_requests", ["created_at"], name: "index_merge_requests_on_created_at", using: :btree add_index "merge_requests", ["milestone_id"], name: "index_merge_requests_on_milestone_id", using: :btree add_index "merge_requests", ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree - add_index "merge_requests", ["source_project_id"], name: "index_merge_requests_on_project_id", using: :btree + add_index "merge_requests", ["source_project_id"], name: "index_merge_requests_on_source_project_id", using: :btree add_index "merge_requests", ["target_branch"], name: "index_merge_requests_on_target_branch", using: :btree add_index "merge_requests", ["title"], name: "index_merge_requests_on_title", using: :btree @@ -147,8 +150,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.integer "project_id", null: false t.text "description" t.date "due_date" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "state" t.integer "iid" end @@ -160,8 +163,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "name", null: false t.string "path", null: false t.integer "owner_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "type" t.string "description", default: "", null: false t.string "avatar" @@ -183,8 +186,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "line_code" t.string "commit_id" t.integer "noteable_id" - t.text "st_diff" t.boolean "system", default: false, null: false + t.text "st_diff" end add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree @@ -215,17 +218,18 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "import_url" t.integer "visibility_level", default: 0, null: false t.boolean "archived", default: false, null: false + t.string "import_status" end - add_index "projects", ["creator_id"], name: "index_projects_on_owner_id", using: :btree + add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree add_index "projects", ["last_activity_at"], name: "index_projects_on_last_activity_at", using: :btree add_index "projects", ["namespace_id"], name: "index_projects_on_namespace_id", using: :btree create_table "protected_branches", force: true do |t| t.integer "project_id", null: false t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "protected_branches", ["project_id"], name: "index_protected_branches_on_project_id", using: :btree @@ -235,8 +239,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.string "title" t.string "token" t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "active", default: false, null: false t.string "project_url" t.string "subdomain" @@ -249,14 +253,14 @@ ActiveRecord::Schema.define(version: 20140304005354) do create_table "snippets", force: true do |t| t.string "title" - t.text "content", limit: 2147483647 - t.integer "author_id", null: false + t.text "content" + t.integer "author_id", null: false t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" t.string "file_name" t.datetime "expires_at" - t.boolean "private", default: true, null: false + t.boolean "private", default: true, null: false t.string "type" end @@ -275,17 +279,20 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.datetime "created_at" end + add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id", using: :btree + add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree + create_table "tags", force: true do |t| t.string "name" end create_table "users", force: true do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", limit: 128, default: "", null: false + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" @@ -293,40 +300,41 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.datetime "created_at" t.datetime "updated_at" t.string "name" - t.boolean "admin", default: false, null: false - t.integer "projects_limit", default: 10 - t.string "skype", default: "", null: false - t.string "linkedin", default: "", null: false - t.string "twitter", default: "", null: false + t.boolean "admin", default: false, null: false + t.integer "projects_limit", default: 10 + t.string "skype", default: "", null: false + t.string "linkedin", default: "", null: false + t.string "twitter", default: "", null: false t.string "authentication_token" - t.integer "theme_id", default: 1, null: false + t.integer "theme_id", default: 1, null: false t.string "bio" - t.integer "failed_attempts", default: 0 + t.integer "failed_attempts", default: 0 t.datetime "locked_at" t.string "extern_uid" t.string "provider" t.string "username" - t.boolean "can_create_group", default: true, null: false - t.boolean "can_create_team", default: true, null: false + t.boolean "can_create_group", default: true, null: false + t.boolean "can_create_team", default: true, null: false t.string "state" - t.integer "color_scheme_id", default: 1, null: false - t.integer "notification_level", default: 1, null: false + t.integer "color_scheme_id", default: 1, null: false + t.integer "notification_level", default: 1, null: false t.datetime "password_expires_at" t.integer "created_by_id" + t.datetime "last_credential_check_at" t.string "avatar" t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" - t.boolean "hide_no_ssh_key", default: false - t.string "website_url", default: "", null: false - t.datetime "last_credential_check_at" + t.boolean "hide_no_ssh_key", default: false + t.string "website_url", default: "", null: false end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree add_index "users", ["authentication_token"], name: "index_users_on_authentication_token", unique: true, using: :btree add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree + add_index "users", ["extern_uid", "provider"], name: "index_users_on_extern_uid_and_provider", unique: true, using: :btree add_index "users", ["name"], name: "index_users_on_name", using: :btree add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree add_index "users", ["username"], name: "index_users_on_username", using: :btree @@ -335,8 +343,8 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.integer "group_access", null: false t.integer "group_id", null: false t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "notification_level", default: 3, null: false end @@ -365,6 +373,7 @@ ActiveRecord::Schema.define(version: 20140304005354) do t.boolean "push_events", default: true, null: false t.boolean "issues_events", default: false, null: false t.boolean "merge_requests_events", default: false, null: false + t.boolean "tag_push_events", default: false end add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree -- cgit v1.2.3 From 7f50c7f62c083ef5599b2ffe24723683c246bfb0 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 12 Mar 2014 17:14:48 +0200 Subject: Move project creation to service Signed-off-by: Dmitriy Zaporozhets --- app/observers/project_observer.rb | 26 +------------------------- app/services/projects/create_service.rb | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/app/observers/project_observer.rb b/app/observers/project_observer.rb index 4e3deec01bf..ad41ddad58f 100644 --- a/app/observers/project_observer.rb +++ b/app/observers/project_observer.rb @@ -1,30 +1,6 @@ class ProjectObserver < BaseObserver def after_create(project) - project.update_column(:last_activity_at, project.created_at) - - return true if project.forked? - - if project.import? - RepositoryImportWorker.perform_in(5.seconds, project.id) - else - GitlabShellWorker.perform_async( - :add_repository, - project.path_with_namespace - ) - - log_info("#{project.owner.name} created a new project \"#{project.name_with_namespace}\"") - end - - if project.wiki_enabled? - begin - # force the creation of a wiki, - GollumWiki.new(project, project.owner).wiki - rescue GollumWiki::CouldNotCreateWikiError => ex - # Prevent project observer crash - # if failed to create wiki - nil - end - end + log_info("#{project.owner.name} created a new project \"#{project.name_with_namespace}\"") end def after_update(project) diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index ba131d8ffbe..b3f97a7c9c1 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -58,6 +58,29 @@ module Projects user: current_user ) end + + @project.update_column(:last_activity_at, @project.created_at) + + if @project.import? + RepositoryImportWorker.perform_in(5.seconds, @project.id) + else + GitlabShellWorker.perform_async( + :add_repository, + @project.path_with_namespace + ) + + end + + if @project.wiki_enabled? + begin + # force the creation of a wiki, + GollumWiki.new(@project, @project.owner).wiki + rescue GollumWiki::CouldNotCreateWikiError => ex + # Prevent project observer crash + # if failed to create wiki + nil + end + end end @project -- cgit v1.2.3 From 1436433c7b982fbe17b10f744f2f65f208305d3c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 12 Mar 2014 17:15:03 +0200 Subject: Add project import state machine Signed-off-by: Dmitriy Zaporozhets --- app/models/project.rb | 28 ++++++++++++++++++---------- app/workers/repository_import_worker.rb | 6 ++++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 47dc8a1fdb0..90c33822568 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -59,13 +59,10 @@ class Project < ActiveRecord::Base has_one :gemnasium_service, dependent: :destroy has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" has_one :forked_from_project, through: :forked_project_link - # Merge Requests for target project should be removed with it has_many :merge_requests, dependent: :destroy, foreign_key: "target_project_id" - # Merge requests from source project should be kept when source project was removed has_many :fork_merge_requests, foreign_key: "source_project_id", class_name: MergeRequest - has_many :issues, -> { order "state DESC, created_at DESC" }, dependent: :destroy has_many :services, dependent: :destroy has_many :events, dependent: :destroy @@ -74,10 +71,8 @@ class Project < ActiveRecord::Base has_many :snippets, dependent: :destroy, class_name: "ProjectSnippet" has_many :hooks, dependent: :destroy, class_name: "ProjectHook" has_many :protected_branches, dependent: :destroy - has_many :users_projects, dependent: :destroy has_many :users, through: :users_projects - has_many :deploy_keys_projects, dependent: :destroy has_many :deploy_keys, through: :deploy_keys_projects @@ -97,15 +92,12 @@ class Project < ActiveRecord::Base validates :issues_enabled, :wall_enabled, :merge_requests_enabled, :wiki_enabled, inclusion: { in: [true, false] } validates :issues_tracker_id, length: { maximum: 255 }, allow_blank: true - validates :namespace, presence: true validates_uniqueness_of :name, scope: :namespace_id validates_uniqueness_of :path, scope: :namespace_id - validates :import_url, format: { with: URI::regexp(%w(git http https)), message: "should be a valid url" }, if: :import? - validate :check_limit, on: :create # Scopes @@ -118,14 +110,30 @@ class Project < ActiveRecord::Base scope :sorted_by_activity, -> { reorder("projects.last_activity_at DESC") } scope :personal, ->(user) { where(namespace_id: user.namespace_id) } scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) } - scope :public_only, -> { where(visibility_level: Project::PUBLIC) } scope :public_and_internal_only, -> { where(visibility_level: Project.public_and_internal_levels) } - scope :non_archived, -> { where(archived: false) } enumerize :issues_tracker, in: (Gitlab.config.issues_tracker.keys).append(:gitlab), default: :gitlab + state_machine :import_status, initial: :none do + event :import_start do + transition :none => :started + end + + event :import_finish do + transition :started => :finished + end + + event :import_fail do + transition :started => :timeout + end + + state :started + state :finished + state :timeout + end + class << self def public_and_internal_levels [Project::PUBLIC, Project::INTERNAL] diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb index 95b80bca7c0..c577cb0273f 100644 --- a/app/workers/repository_import_worker.rb +++ b/app/workers/repository_import_worker.rb @@ -6,16 +6,18 @@ class RepositoryImportWorker def perform(project_id) project = Project.find(project_id) + project.import_start + result = gitlab_shell.send(:import_repository, project.path_with_namespace, project.import_url) if result - project.imported = true + project.import_finish project.save project.satellite.create unless project.satellite.exists? else - project.imported = false + project.import_fail end end end -- cgit v1.2.3 From 37db76a31b8d9676aeadcaf6e2e175ead0f68d74 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 12 Mar 2014 19:25:48 +0200 Subject: Project import and retry import scaffold Signed-off-by: Dmitriy Zaporozhets --- app/controllers/projects_controller.rb | 37 ++++++++++++------ app/views/projects/create.js.haml | 8 +++- app/views/projects/empty.html.haml | 70 ++++++++++++++-------------------- app/views/projects/import.html.haml | 29 ++++++++++++++ 4 files changed, 89 insertions(+), 55 deletions(-) create mode 100644 app/views/projects/import.html.haml diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index f1c0336e6ea..f4087b884c8 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -5,7 +5,7 @@ class ProjectsController < ApplicationController # Authorize before_filter :authorize_read_project!, except: [:index, :new, :create] - before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive] + before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive, :retry_import] before_filter :require_non_empty_project, only: [:blob, :tree, :graph] layout 'navless', only: [:new, :create, :fork] @@ -21,16 +21,9 @@ class ProjectsController < ApplicationController def create @project = ::Projects::CreateService.new(current_user, params[:project]).execute + flash[:notice] = 'Project was successfully created.' if @project.saved? respond_to do |format| - flash[:notice] = 'Project was successfully created.' if @project.saved? - format.html do - if @project.saved? - redirect_to @project - else - render "new" - end - end format.js end end @@ -67,9 +60,7 @@ class ProjectsController < ApplicationController if @project.empty_repo? render "projects/empty", layout: user_layout else - if current_user - @last_push = current_user.recent_push(@project.id) - end + @last_push = current_user.recent_push(@project.id) if current_user render :show, layout: user_layout end end @@ -77,6 +68,28 @@ class ProjectsController < ApplicationController end end + def import + if project.import_finished? + redirect_to @project + return + end + end + + def retry_import + unless @project.import_failed? + redirect_to import_project_path(@project) + end + + @project.import_url = params[:project][:import_url] + + if @project.save + @project.reload + @project.import_retry + end + + redirect_to import_project_path(@project) + end + def destroy return access_denied! unless can?(current_user, :remove_project, project) diff --git a/app/views/projects/create.js.haml b/app/views/projects/create.js.haml index a444b8b59a6..89710d3a09a 100644 --- a/app/views/projects/create.js.haml +++ b/app/views/projects/create.js.haml @@ -1,6 +1,10 @@ - if @project.saved? - :plain - location.href = "#{project_path(@project)}"; + - if @project.import? + :plain + location.href = "#{import_project_path(@project)}"; + - else + :plain + location.href = "#{project_path(@project)}"; - else :plain $(".project-edit-errors").html("#{escape_javascript(render('errors'))}"); diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index 489b9b0e951..97dc73bce14 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -1,46 +1,34 @@ = render "home_panel" -- if @project.import? && !@project.imported - .save-project-loader - %center - %h2 - %i.icon-spinner.icon-spin - Importing repository. - %p.monospace git clone --bare #{@project.import_url} - %p Please wait while we import the repository for you. Refresh at will. - :javascript - new ProjectImport(); +%div.git-empty + %fieldset + %legend Git global setup: + %pre.dark + :preserve + git config --global user.name "#{git_user_name}" + git config --global user.email "#{git_user_email}" -- else - %div.git-empty - %fieldset - %legend Git global setup: - %pre.dark - :preserve - git config --global user.name "#{git_user_name}" - git config --global user.email "#{git_user_email}" + %fieldset + %legend Create Repository + %pre.dark + :preserve + mkdir #{@project.path} + cd #{@project.path} + git init + touch README + git add README + git commit -m 'first commit' + git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'clone')} + git push -u origin master - %fieldset - %legend Create Repository - %pre.dark - :preserve - mkdir #{@project.path} - cd #{@project.path} - git init - touch README - git add README - git commit -m 'first commit' - git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'clone')} - git push -u origin master + %fieldset + %legend Existing Git Repo? + %pre.dark + :preserve + cd existing_git_repo + git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'clone')} + git push -u origin master - %fieldset - %legend Existing Git Repo? - %pre.dark - :preserve - cd existing_git_repo - git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'clone')} - git push -u origin master - - - if can? current_user, :remove_project, @project - .prepend-top-20 - = link_to 'Remove project', @project, data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-remove pull-right" +- if can? current_user, :remove_project, @project + .prepend-top-20 + = link_to 'Remove project', @project, data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-remove pull-right" diff --git a/app/views/projects/import.html.haml b/app/views/projects/import.html.haml new file mode 100644 index 00000000000..c9fb6c5c6ab --- /dev/null +++ b/app/views/projects/import.html.haml @@ -0,0 +1,29 @@ +- if @project.import_in_progress? + .save-project-loader + %center + %h2 + %i.icon-spinner.icon-spin + Import in progress. + %p.monospace git clone --bare #{@project.import_url} + %p Please wait while we import the repository for you. Refresh at will. + :javascript + new ProjectImport(); + +- elsif @project.import_failed? + .save-project-loader + %center + %h2 + Import failed. Retry? + %hr + = form_for @project, url: retry_import_project_path(@project), method: :put, html: { class: 'form-horizontal' } do |f| + .form-group.import-url-data + = f.label :import_url, class: 'control-label' do + %span Import existing repo + .col-sm-10 + = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' + .bs-callout.bs-callout-info + This url must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git. + %br + The import will time out after 2 minutes. For big repositories, use a clone/push combination. + .form-actions + = f.submit 'Retry import', class: "btn btn-create", tabindex: 4 -- cgit v1.2.3 From b47646ef13597836cad342a4d9372316289f0155 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 12 Mar 2014 19:26:09 +0200 Subject: Add retry feature to project import Signed-off-by: Dmitriy Zaporozhets --- app/models/project.rb | 28 +++++++++++++++++++++++++--- app/services/projects/create_service.rb | 2 +- app/workers/repository_import_worker.rb | 2 -- config/routes.rb | 2 ++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 90c33822568..c2ba21ac7e9 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -126,12 +126,18 @@ class Project < ActiveRecord::Base end event :import_fail do - transition :started => :timeout + transition :started => :failed + end + + event :import_retry do + transition :failed => :started end state :started state :finished - state :timeout + state :failed + + after_transition any => :started, :do => :add_import_job end class << self @@ -210,12 +216,28 @@ class Project < ActiveRecord::Base id && persisted? end + def add_import_job + RepositoryImportWorker.perform_in(2.seconds, id) + end + def import? import_url.present? end def imported? - imported + import_finished? + end + + def import_in_progress? + import? && import_status == 'started' + end + + def import_failed? + import_status == 'failed' + end + + def import_finished? + import_status == 'finished' end def check_limit diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index b3f97a7c9c1..4d3d518a509 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -62,7 +62,7 @@ module Projects @project.update_column(:last_activity_at, @project.created_at) if @project.import? - RepositoryImportWorker.perform_in(5.seconds, @project.id) + @project.import_start else GitlabShellWorker.perform_async( :add_repository, diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb index c577cb0273f..e66df8c4db1 100644 --- a/app/workers/repository_import_worker.rb +++ b/app/workers/repository_import_worker.rb @@ -6,8 +6,6 @@ class RepositoryImportWorker def perform(project_id) project = Project.find(project_id) - project.import_start - result = gitlab_shell.send(:import_repository, project.path_with_namespace, project.import_url) diff --git a/config/routes.rb b/config/routes.rb index fdca1e62661..628d1f631bc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -179,6 +179,8 @@ Gitlab::Application.routes.draw do post :archive post :unarchive get :autocomplete_sources + get :import + put :retry_import end scope module: :projects do -- cgit v1.2.3 From aaff356655e47d78d1da6adca314ccf11f02268c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 10:27:05 +0200 Subject: Redirect to import page from show when import in progress Signed-off-by: Dmitriy Zaporozhets --- app/controllers/projects_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index f4087b884c8..8d24052f724 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -48,6 +48,11 @@ class ProjectsController < ApplicationController end def show + if @project.import_in_progress? + redirect_to import_project_path(@project) + return + end + return authenticate_user! unless @project.public? || current_user limit = (params[:limit] || 20).to_i -- cgit v1.2.3 From 44c940391701c8ac6715a90a707db0c255e016d9 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 10:27:20 +0200 Subject: Hide retry import form for non masters Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/import.html.haml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/app/views/projects/import.html.haml b/app/views/projects/import.html.haml index c9fb6c5c6ab..d11372be61b 100644 --- a/app/views/projects/import.html.haml +++ b/app/views/projects/import.html.haml @@ -15,15 +15,16 @@ %h2 Import failed. Retry? %hr - = form_for @project, url: retry_import_project_path(@project), method: :put, html: { class: 'form-horizontal' } do |f| - .form-group.import-url-data - = f.label :import_url, class: 'control-label' do - %span Import existing repo - .col-sm-10 - = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' - .bs-callout.bs-callout-info - This url must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git. - %br - The import will time out after 2 minutes. For big repositories, use a clone/push combination. - .form-actions - = f.submit 'Retry import', class: "btn btn-create", tabindex: 4 + - if can?(current_user, :admin_project, @project) + = form_for @project, url: retry_import_project_path(@project), method: :put, html: { class: 'form-horizontal' } do |f| + .form-group.import-url-data + = f.label :import_url, class: 'control-label' do + %span Import existing repo + .col-sm-10 + = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' + .bs-callout.bs-callout-info + This url must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git. + %br + The import will time out after 2 minutes. For big repositories, use a clone/push combination. + .form-actions + = f.submit 'Retry import', class: "btn btn-create", tabindex: 4 -- cgit v1.2.3 From c4263dfbaff03711b7f18343d8e8bdc380242501 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 10:39:41 +0200 Subject: Fix BackgroundJobs page Signed-off-by: Dmitriy Zaporozhets --- app/views/admin/background_jobs/show.html.haml | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/app/views/admin/background_jobs/show.html.haml b/app/views/admin/background_jobs/show.html.haml index e5af56ffc5c..32f77cc1a70 100644 --- a/app/views/admin/background_jobs/show.html.haml +++ b/app/views/admin/background_jobs/show.html.haml @@ -14,27 +14,21 @@ %table.table %thead %th USER - %th %th PID - %th %th CPU - %th %th MEM - %th %th STATE - %th %th START - %th %th COMMAND - %th - - @sidekiq_processes.split("\n").each do |process| + %tbody + - @sidekiq_processes.each do |process| - next unless process.match(/(sidekiq \d+\.\d+\.\d+.+$)/) - - data = process.gsub!(/\s+/m, '|').strip.split('|') + - data = process.strip.split(' ') %tr - - 6.times do + %td= Settings.gitlab.user + - 5.times do %td= data.shift - %td - %td= data.join(" ") + %td= data.join(' ') .clearfix %p -- cgit v1.2.3 From 46cc3b22c9fbe89b9fadc9c7488ec4e353b4970e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 10:47:53 +0200 Subject: Add mysql limits to db during setup Signed-off-by: Dmitriy Zaporozhets --- lib/tasks/gitlab/setup.rake | 8 ++++++++ lib/tasks/migrate/add_limits_mysql.rake | 1 + 2 files changed, 9 insertions(+) diff --git a/lib/tasks/gitlab/setup.rake b/lib/tasks/gitlab/setup.rake index 2b730774e06..853994dd67d 100644 --- a/lib/tasks/gitlab/setup.rake +++ b/lib/tasks/gitlab/setup.rake @@ -15,6 +15,14 @@ namespace :gitlab do end Rake::Task["db:setup"].invoke + + config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env] + success = case config["adapter"] + when /^mysql/ then + Rake::Task["add_limits_mysql"].invoke + when "postgresql" then + end + Rake::Task["db:seed_fu"].invoke rescue Gitlab::TaskAbortedByUserError puts "Quitting...".red diff --git a/lib/tasks/migrate/add_limits_mysql.rake b/lib/tasks/migrate/add_limits_mysql.rake index 163d6377cfb..46b6451752b 100644 --- a/lib/tasks/migrate/add_limits_mysql.rake +++ b/lib/tasks/migrate/add_limits_mysql.rake @@ -9,5 +9,6 @@ class LimitsToMysql < ActiveRecord::Migration change_column :merge_request_diffs, :st_commits, :text, limit: 2147483647 change_column :merge_request_diffs, :st_diffs, :text, limit: 2147483647 change_column :snippets, :content, :text, limit: 2147483647 + change_column :notes, :st_diff, :text, limit: 2147483647 end end -- cgit v1.2.3 From 10c0cb8ca763861b8c636ccece7278407650f1c8 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 11:28:41 +0200 Subject: Add migration for already imported projects Signed-off-by: Dmitriy Zaporozhets --- ...0313092127_migrate_already_imported_projects.rb | 12 ++++ db/schema.rb | 83 +++++++++++----------- 2 files changed, 53 insertions(+), 42 deletions(-) create mode 100644 db/migrate/20140313092127_migrate_already_imported_projects.rb diff --git a/db/migrate/20140313092127_migrate_already_imported_projects.rb b/db/migrate/20140313092127_migrate_already_imported_projects.rb new file mode 100644 index 00000000000..f4392c0f05e --- /dev/null +++ b/db/migrate/20140313092127_migrate_already_imported_projects.rb @@ -0,0 +1,12 @@ +class MigrateAlreadyImportedProjects < ActiveRecord::Migration + def up + Project.where(imported: true).update_all(import_status: "finished") + Project.where(imported: false).update_all(import_status: "none") + remove_column :projects, :imported + end + + def down + add_column :projects, :imported, :boolean, default: false + Project.where(import_status: 'finished').update_all(imported: true) + end +end diff --git a/db/schema.rb b/db/schema.rb index 00627c945a7..2c5f46b2e97 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: 20140312145357) do +ActiveRecord::Schema.define(version: 20140313092127) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -21,8 +21,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.datetime "starts_at" t.datetime "ends_at" t.integer "alert_type" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "color" t.string "font" end @@ -30,8 +30,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do create_table "deploy_keys_projects", force: true do |t| t.integer "deploy_key_id", null: false t.integer "project_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "deploy_keys_projects", ["project_id"], name: "index_deploy_keys_projects_on_project_id", using: :btree @@ -52,8 +52,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.string "title" t.text "data" t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "action" t.integer "author_id" end @@ -68,8 +68,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do create_table "forked_project_links", force: true do |t| t.integer "forked_to_project_id", null: false t.integer "forked_from_project_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree @@ -79,8 +79,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.integer "assignee_id" t.integer "author_id" t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "position", default: 0 t.string "branch_name" t.text "description" @@ -98,8 +98,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do create_table "keys", force: true do |t| t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.text "key" t.string "title" t.string "type" @@ -126,8 +126,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.integer "author_id" t.integer "assignee_id" t.string "title" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "milestone_id" t.string "state" t.string "merge_status" @@ -141,7 +141,7 @@ ActiveRecord::Schema.define(version: 20140312145357) do add_index "merge_requests", ["created_at"], name: "index_merge_requests_on_created_at", using: :btree add_index "merge_requests", ["milestone_id"], name: "index_merge_requests_on_milestone_id", using: :btree add_index "merge_requests", ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree - add_index "merge_requests", ["source_project_id"], name: "index_merge_requests_on_source_project_id", using: :btree + add_index "merge_requests", ["source_project_id"], name: "index_merge_requests_on_project_id", using: :btree add_index "merge_requests", ["target_branch"], name: "index_merge_requests_on_target_branch", using: :btree add_index "merge_requests", ["title"], name: "index_merge_requests_on_title", using: :btree @@ -150,8 +150,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.integer "project_id", null: false t.text "description" t.date "due_date" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "state" t.integer "iid" end @@ -163,8 +163,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.string "name", null: false t.string "path", null: false t.integer "owner_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "type" t.string "description", default: "", null: false t.string "avatar" @@ -179,15 +179,15 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.text "note" t.string "noteable_type" t.integer "author_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "project_id" t.string "attachment" t.string "line_code" t.string "commit_id" t.integer "noteable_id" - t.boolean "system", default: false, null: false t.text "st_diff" + t.boolean "system", default: false, null: false end add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree @@ -202,8 +202,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.string "name" t.string "path" t.text "description" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "creator_id" t.boolean "issues_enabled", default: true, null: false t.boolean "wall_enabled", default: true, null: false @@ -214,22 +214,21 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.string "issues_tracker_id" t.boolean "snippets_enabled", default: true, null: false t.datetime "last_activity_at" - t.boolean "imported", default: false, null: false t.string "import_url" t.integer "visibility_level", default: 0, null: false t.boolean "archived", default: false, null: false t.string "import_status" end - add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree + add_index "projects", ["creator_id"], name: "index_projects_on_owner_id", using: :btree add_index "projects", ["last_activity_at"], name: "index_projects_on_last_activity_at", using: :btree add_index "projects", ["namespace_id"], name: "index_projects_on_namespace_id", using: :btree create_table "protected_branches", force: true do |t| t.integer "project_id", null: false t.string "name", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "protected_branches", ["project_id"], name: "index_protected_branches_on_project_id", using: :btree @@ -239,8 +238,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.string "title" t.string "token" t.integer "project_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "active", default: false, null: false t.string "project_url" t.string "subdomain" @@ -256,8 +255,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.text "content" t.integer "author_id", null: false t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "file_name" t.datetime "expires_at" t.boolean "private", default: true, null: false @@ -297,8 +296,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "name" t.boolean "admin", default: false, null: false t.integer "projects_limit", default: 10 @@ -320,7 +319,6 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.integer "notification_level", default: 1, null: false t.datetime "password_expires_at" t.integer "created_by_id" - t.datetime "last_credential_check_at" t.string "avatar" t.string "confirmation_token" t.datetime "confirmed_at" @@ -328,6 +326,7 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.string "unconfirmed_email" t.boolean "hide_no_ssh_key", default: false t.string "website_url", default: "", null: false + t.datetime "last_credential_check_at" end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree @@ -343,8 +342,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do t.integer "group_access", null: false t.integer "group_id", null: false t.integer "user_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "notification_level", default: 3, null: false end @@ -353,8 +352,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do create_table "users_projects", force: true do |t| t.integer "user_id", null: false t.integer "project_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "project_access", default: 0, null: false t.integer "notification_level", default: 3, null: false end @@ -366,8 +365,8 @@ ActiveRecord::Schema.define(version: 20140312145357) do create_table "web_hooks", force: true do |t| t.string "url" t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "type", default: "ProjectHook" t.integer "service_id" t.boolean "push_events", default: true, null: false -- cgit v1.2.3 From b0a86cb3ba649ea959d05a972f6cd1d6798f86c9 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 11:33:33 +0200 Subject: Use gitlab:setup inside gitlab:test Signed-off-by: Dmitriy Zaporozhets --- lib/tasks/gitlab/test.rake | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/tasks/gitlab/test.rake b/lib/tasks/gitlab/test.rake index f52af0c3ded..83e794189d2 100644 --- a/lib/tasks/gitlab/test.rake +++ b/lib/tasks/gitlab/test.rake @@ -2,15 +2,14 @@ namespace :gitlab do desc "GITLAB | Run all tests" task :test do cmds = [ - %W(rake db:setup), - %W(rake db:seed_fu), + %W(rake gitlab:setup), %W(rake spinach), %W(rake spec), %W(rake jasmine:ci) ] cmds.each do |cmd| - system({'RAILS_ENV' => 'test'}, *cmd) + system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) raise "#{cmd} failed!" unless $?.exitstatus.zero? end -- cgit v1.2.3 From 5be424565ebe71b6c4d93adfecea9d7b057ae086 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 11:37:13 +0200 Subject: Create event and clear cache on new trag push Signed-off-by: Dmitriy Zaporozhets --- app/services/git_tag_push_service.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb index 3504479f33a..62eaf9b4f51 100644 --- a/app/services/git_tag_push_service.rb +++ b/app/services/git_tag_push_service.rb @@ -1,8 +1,12 @@ class GitTagPushService attr_accessor :project, :user, :push_data + def execute(project, user, oldrev, newrev, ref) @project, @user = project, user @push_data = create_push_data(oldrev, newrev, ref) + + create_push_event + project.repository.expire_cache project.execute_hooks(@push_data.dup, :tag_push_hooks) end @@ -24,4 +28,13 @@ class GitTagPushService } } end + + def create_push_event + Event.create!( + project: project, + action: Event::PUSHED, + data: push_data, + author_id: push_data[:user_id] + ) + end end -- cgit v1.2.3 From b4edf4f996d1bad2d893a404f5d1b8a08c3c3e0d Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Thu, 13 Mar 2014 12:04:33 +0100 Subject: Added entry for the new webhook --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index f24cc8b5092..9d5c8684d33 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,7 @@ v 6.7.0 - Fixes a bug with group member administration (Matt DeTullio) - Sort tag names using VersionSorter (Robert Speicher) - Add GFM autocompletion for MergeRequests (Robert Speicher) + - Add webhook when a new tag is pushed (Jeroen van Baarsen) v 6.6.2 - Fix 500 error on branch/tag create or remove via UI -- cgit v1.2.3 From 494dc8ca8b13471aa40c9e614c594fb6ccf810c0 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 20:29:03 +0200 Subject: Update httparty Signed-off-by: Dmitriy Zaporozhets --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 709f5711916..615ad62112a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -235,7 +235,7 @@ GEM httparty httparty http_parser.rb (0.5.3) - httparty (0.12.0) + httparty (0.13.0) json (~> 1.8) multi_xml (>= 0.5.2) httpauth (0.2.0) -- cgit v1.2.3 From d1bee5e374595231327525472fab391bc078fa81 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 20:35:11 +0200 Subject: Remove default value for Project#imported Signed-off-by: Dmitriy Zaporozhets --- app/models/project.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index c2ba21ac7e9..392c38cc5d9 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -28,7 +28,6 @@ class Project < ActiveRecord::Base include Gitlab::VisibilityLevel extend Enumerize - default_value_for :imported, false default_value_for :archived, false ActsAsTaggableOn.strict_case_match = true -- cgit v1.2.3 From 9064fba071d06439ead76890015c3d38ffa63375 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 21:15:18 +0200 Subject: Mention retry feature for repository import in CHANGELOG Signed-off-by: Dmitriy Zaporozhets --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index f24cc8b5092..bcacc162b87 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,7 @@ v 6.7.0 - Fixes a bug with group member administration (Matt DeTullio) - Sort tag names using VersionSorter (Robert Speicher) - Add GFM autocompletion for MergeRequests (Robert Speicher) + - Add retry feature for repository import v 6.6.2 - Fix 500 error on branch/tag create or remove via UI -- cgit v1.2.3 From 599ee9670d9757436aee8db5c7c16d44c5ef3f99 Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Thu, 13 Mar 2014 22:04:36 +0100 Subject: Fixed error on mysql install link Fixed error on install guide to mysql conf page. --- doc/install/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/install/installation.md b/doc/install/installation.md index c7495b8cbbb..a0eac76ab5b 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -144,7 +144,7 @@ GitLab Shell is an ssh access and repository management software developed speci # 5. Database -We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](doc/install/database_mysql.md). +We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](database_mysql.md). # Install the database packages sudo apt-get install -y postgresql-9.1 postgresql-client libpq-dev -- cgit v1.2.3 From 65cb88f3ba48d0f446df167c2f707e9b464f2036 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 23:15:33 +0200 Subject: Correct BackgroundJobs page for both OSX and linux Signed-off-by: Dmitriy Zaporozhets --- app/controllers/admin/background_jobs_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/background_jobs_controller.rb b/app/controllers/admin/background_jobs_controller.rb index f2b8277efea..4c1d0df4110 100644 --- a/app/controllers/admin/background_jobs_controller.rb +++ b/app/controllers/admin/background_jobs_controller.rb @@ -1,6 +1,6 @@ class Admin::BackgroundJobsController < Admin::ApplicationController def show - ps_output, _ = Gitlab::Popen.popen(%W(ps -U #{Settings.gitlab.user} -o euser,pid,pcpu,pmem,stat,start,command)) + ps_output, _ = Gitlab::Popen.popen(%W(ps -U #{Settings.gitlab.user} -o pid,pcpu,pmem,stat,start,command)) @sidekiq_processes = ps_output.split("\n").grep(/sidekiq/) end end -- cgit v1.2.3 From 632fe8fbe1af9653fec6ecbb5c3e5c66d738641c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Mar 2014 23:19:50 +0200 Subject: Update changelog Signed-off-by: Dmitriy Zaporozhets --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 9d5c8684d33..201990669a2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,7 @@ v 6.7.0 - Sort tag names using VersionSorter (Robert Speicher) - Add GFM autocompletion for MergeRequests (Robert Speicher) - Add webhook when a new tag is pushed (Jeroen van Baarsen) + - Add button for toggling inline comments in diff view v 6.6.2 - Fix 500 error on branch/tag create or remove via UI -- cgit v1.2.3 From 0983438037a13606ff6cbd281a7892295bfd7dd2 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 13 Mar 2014 17:25:55 -0400 Subject: TestEnv.reset_satellite_dir should run 'git clean' quietly Removes the "Removing gitlabhq" messages cluttering spec output --- spec/support/test_env.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index 77a669c0cc1..e2c3f648ccf 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -106,7 +106,7 @@ module TestEnv setup_stubs [ %W(git reset --hard --quiet), - %W(git clean -fx), + %W(git clean -fx --quiet), %W(git checkout --quiet origin/master) ].each do |git_cmd| system(*git_cmd, chdir: seed_satellite_path) -- cgit v1.2.3 From 5a616649b549eafc082ad876ac086da8945217f2 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 14 Mar 2014 08:52:57 +0100 Subject: Allow passing an adapter to Gitlab::LDAP::Person --- lib/gitlab/ldap/person.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/gitlab/ldap/person.rb b/lib/gitlab/ldap/person.rb index 5ee383dfa03..06b17c58f8c 100644 --- a/lib/gitlab/ldap/person.rb +++ b/lib/gitlab/ldap/person.rb @@ -1,12 +1,14 @@ module Gitlab module LDAP class Person - def self.find_by_uid(uid) - Gitlab::LDAP::Adapter.new.user(config.uid, uid) + def self.find_by_uid(uid, adapter=nil) + adapter ||= Gitlab::LDAP::Adapter.new + adapter.user(config.uid, uid) end - def self.find_by_dn(dn) - Gitlab::LDAP::Adapter.new.user('dn', dn) + def self.find_by_dn(dn, adapter=nil) + adapter ||= Gitlab::LDAP::Adapter.new + adapter.user('dn', dn) end def initialize(entry) -- cgit v1.2.3 From af53aa9072ae355b6de167b0d20f9b87195131ec Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 14 Mar 2014 08:53:46 +0100 Subject: Add Gitlab::LDAP::Adapter.open This new method is based on Net::LDAP.open, which reuses a single LDAP connection. --- lib/gitlab/ldap/adapter.rb | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/ldap/adapter.rb b/lib/gitlab/ldap/adapter.rb index a7b5bcb207c..983a2956a35 100644 --- a/lib/gitlab/ldap/adapter.rb +++ b/lib/gitlab/ldap/adapter.rb @@ -3,7 +3,17 @@ module Gitlab class Adapter attr_reader :ldap - def initialize + def self.open(&block) + Net::LDAP.open(adapter_options) do |ldap| + block.call(self.new(ldap)) + end + end + + def self.config + Gitlab.config.ldap + end + + def self.adapter_options encryption = config['method'].to_s == 'ssl' ? :simple_tls : nil options = { @@ -23,8 +33,12 @@ module Gitlab if config['password'] || config['bind_dn'] options.merge!(auth_options) end + options + end + - @ldap = Net::LDAP.new(options) + def initialize(ldap=nil) + @ldap = ldap || Net::LDAP.new(self.class.adapter_options) end def users(field, value) @@ -65,7 +79,7 @@ module Gitlab private def config - @config ||= Gitlab.config.ldap + @config ||= self.class.config end end end -- cgit v1.2.3 From 56df3dbff2e07f6c4402ff7410412238d643ce0f Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 14 Mar 2014 08:55:50 +0100 Subject: Add Gitlab::LDAP::Access.open This new method wraps Gitlab::LDAP::Adapter.open to enable connection reuse. --- lib/gitlab/ldap/access.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb index 2a636244473..8f492e5c012 100644 --- a/lib/gitlab/ldap/access.rb +++ b/lib/gitlab/ldap/access.rb @@ -1,8 +1,20 @@ module Gitlab module LDAP class Access + attr_reader :adapter + + def self.open(&block) + Gitlab::LDAP::Adapter.open do |adapter| + block.call(self.new(adapter)) + end + end + + def initialize(adapter=nil) + @adapter = adapter + end + def allowed?(user) - !!Gitlab::LDAP::Person.find_by_dn(user.extern_uid) + !!Gitlab::LDAP::Person.find_by_dn(user.extern_uid, adapter) rescue false end -- cgit v1.2.3 From 48e9054056db7f14bdef0d2d5c859f357110ed95 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 14 Mar 2014 08:57:39 +0100 Subject: Open/close LDAP in ApplicationController By opening the LDAP connection at the controller level we can reuse it for all LDAP queries during the request. --- CHANGELOG | 1 + app/controllers/application_controller.rb | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 201990669a2..5a7263a9358 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,7 @@ v 6.7.0 - Add GFM autocompletion for MergeRequests (Robert Speicher) - Add webhook when a new tag is pushed (Jeroen van Baarsen) - Add button for toggling inline comments in diff view + - Reuse the GitLab LDAP connection within each request v 6.6.2 - Fix 500 error on branch/tag create or remove via UI diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9a0c9f60b05..5f8b2da06f8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -182,13 +182,15 @@ class ApplicationController < ActionController::Base def ldap_security_check if current_user && current_user.requires_ldap_check? - if gitlab_ldap_access.allowed?(current_user) - current_user.last_credential_check_at = Time.now - current_user.save - else - sign_out current_user - flash[:alert] = "Access denied for your LDAP account." - redirect_to new_user_session_path + gitlab_ldap_access do |access| + if access.allowed?(current_user) + current_user.last_credential_check_at = Time.now + current_user.save + else + sign_out current_user + flash[:alert] = "Access denied for your LDAP account." + redirect_to new_user_session_path + end end end end @@ -198,8 +200,8 @@ class ApplicationController < ActionController::Base @event_filter ||= EventFilter.new(filters) end - def gitlab_ldap_access - Gitlab::LDAP::Access.new + def gitlab_ldap_access(&block) + Gitlab::LDAP::Access.open { |access| block.call(access) } end # JSON for infinite scroll via Pager object -- cgit v1.2.3 From f6f80659ec23ffc7ad4847b13ac78047862f0d91 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 10:44:16 +0200 Subject: Override rake spec and rake spinach tasks Signed-off-by: Dmitriy Zaporozhets --- .travis.yml | 2 -- lib/tasks/gitlab/test.rake | 1 - lib/tasks/spec.rake | 14 ++++++++++++++ lib/tasks/spinach.rake | 14 ++++++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 lib/tasks/spec.rake create mode 100644 lib/tasks/spinach.rake diff --git a/.travis.yml b/.travis.yml index 6bff3752b2a..07f8146f3de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,6 @@ services: before_script: - "cp config/database.yml.$DB config/database.yml" - "cp config/gitlab.yml.example config/gitlab.yml" - - "bundle exec rake db:setup" - - "bundle exec rake db:seed_fu" script: "bundle exec rake $TASK --trace" notifications: email: false diff --git a/lib/tasks/gitlab/test.rake b/lib/tasks/gitlab/test.rake index 83e794189d2..2c9b9978933 100644 --- a/lib/tasks/gitlab/test.rake +++ b/lib/tasks/gitlab/test.rake @@ -2,7 +2,6 @@ namespace :gitlab do desc "GITLAB | Run all tests" task :test do cmds = [ - %W(rake gitlab:setup), %W(rake spinach), %W(rake spec), %W(rake jasmine:ci) diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake new file mode 100644 index 00000000000..4e562459e15 --- /dev/null +++ b/lib/tasks/spec.rake @@ -0,0 +1,14 @@ +Rake::Task["spec"].clear + +desc "GITLAB | Run specs" +task :spec do + cmds = [ + %W(rake gitlab:setup), + %W(rspec spec), + ] + + cmds.each do |cmd| + system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) + raise "#{cmd} failed!" unless $?.exitstatus.zero? + end +end diff --git a/lib/tasks/spinach.rake b/lib/tasks/spinach.rake new file mode 100644 index 00000000000..60d4d6343b7 --- /dev/null +++ b/lib/tasks/spinach.rake @@ -0,0 +1,14 @@ +Rake::Task["spinach"].clear + +desc "GITLAB | Run spinach" +task :spinach do + cmds = [ + %W(rake gitlab:setup), + %W(spinach), + ] + + cmds.each do |cmd| + system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) + raise "#{cmd} failed!" unless $?.exitstatus.zero? + end +end -- cgit v1.2.3 From 8839339ee36a27693b68a2779b485b0acc932173 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 11:06:10 +0200 Subject: Override rake test Signed-off-by: Dmitriy Zaporozhets --- lib/tasks/test.rake | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 lib/tasks/test.rake diff --git a/lib/tasks/test.rake b/lib/tasks/test.rake new file mode 100644 index 00000000000..24d55b9455a --- /dev/null +++ b/lib/tasks/test.rake @@ -0,0 +1,7 @@ +Rake::Task["test"].clear + +desc "GITLAB | Run all tests" +task :test do + Rake::Task["gitlab:test"].invoke +end + -- cgit v1.2.3 From b007cadf5534e4202a955825770019787a37f7d6 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 12:19:02 +0200 Subject: Fix project creation test Signed-off-by: Dmitriy Zaporozhets --- features/project/create.feature | 3 ++- features/steps/project/create.rb | 2 +- lib/tasks/test.rake | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/project/create.feature b/features/project/create.feature index 395a3218b2b..bb8e3a368ed 100644 --- a/features/project/create.feature +++ b/features/project/create.feature @@ -3,6 +3,7 @@ Feature: Create Project A user with ability to create a project Should be able to create a new one + @javascript Scenario: User create a project Given I sign in as a user When I visit new project page @@ -19,4 +20,4 @@ Feature: Create Project And I click on HTTP Then Remote url should update to http link And If I click on SSH - Then Remote url should update to ssh link \ No newline at end of file + Then Remote url should update to ssh link diff --git a/features/steps/project/create.rb b/features/steps/project/create.rb index b59345e7078..b42e5bd3623 100644 --- a/features/steps/project/create.rb +++ b/features/steps/project/create.rb @@ -8,8 +8,8 @@ class CreateProject < Spinach::FeatureSteps end Then 'I should see project page' do - current_path.should == project_path(Project.last) page.should have_content "Empty" + current_path.should == project_path(Project.last) end And 'I should see empty project instuctions' do diff --git a/lib/tasks/test.rake b/lib/tasks/test.rake index 24d55b9455a..f19da1bb437 100644 --- a/lib/tasks/test.rake +++ b/lib/tasks/test.rake @@ -4,4 +4,3 @@ desc "GITLAB | Run all tests" task :test do Rake::Task["gitlab:test"].invoke end - -- cgit v1.2.3 From ac6b9fafdc78a3c5d7fc5c5903e7d28d2f626d41 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 12:53:05 +0200 Subject: Fix specs Signed-off-by: Dmitriy Zaporozhets --- spec/observers/users_project_observer_spec.rb | 24 ------------------------ spec/services/projects_create_service_spec.rb | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/spec/observers/users_project_observer_spec.rb b/spec/observers/users_project_observer_spec.rb index dea90b2bfa7..be277b4dbd2 100644 --- a/spec/observers/users_project_observer_spec.rb +++ b/spec/observers/users_project_observer_spec.rb @@ -47,30 +47,6 @@ describe UsersProjectObserver do end describe "#after_create" do - context 'wiki_enabled creates repository directory' do - context 'wiki_enabled true creates wiki repository directory' do - before do - @project = create(:project, wiki_enabled: true) - @path = GollumWiki.new(@project, user).send(:path_to_repo) - end - - after do - FileUtils.rm_rf(@path) - end - - it { File.exists?(@path).should be_true } - end - - context 'wiki_enabled false does not create wiki repository directory' do - before do - @project = create(:project, wiki_enabled: false) - @path = GollumWiki.new(@project, user).send(:path_to_repo) - end - - it { File.exists?(@path).should be_false } - end - end - it "should send email to user" do subject.should_receive(:notification) Event.stub(create: true) diff --git a/spec/services/projects_create_service_spec.rb b/spec/services/projects_create_service_spec.rb index 0a41832a211..f2a784df103 100644 --- a/spec/services/projects_create_service_spec.rb +++ b/spec/services/projects_create_service_spec.rb @@ -38,6 +38,27 @@ describe Projects::CreateService do it { @project.namespace.should == @group } end + context 'wiki_enabled creates repository directory' do + context 'wiki_enabled true creates wiki repository directory' do + before do + @project = create_project(@user, @opts) + @path = GollumWiki.new(@project, @user).send(:path_to_repo) + end + + it { File.exists?(@path).should be_true } + end + + context 'wiki_enabled false does not create wiki repository directory' do + before do + @opts.merge!(wiki_enabled: false) + @project = create_project(@user, @opts) + @path = GollumWiki.new(@project, @user).send(:path_to_repo) + end + + it { File.exists?(@path).should be_false } + end + end + context 'respect configured visibility setting' do before(:each) do @settings = double("settings") -- cgit v1.2.3 From bce8edbbcc03bd29230124f9d7871dabbc79d38f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 12:57:26 +0200 Subject: Require gitlab-shell v1.8.4 Signed-off-by: Dmitriy Zaporozhets --- lib/tasks/gitlab/check.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 767674e1e84..2b158fe14ee 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -727,7 +727,7 @@ namespace :gitlab do end def check_gitlab_shell - required_version = Gitlab::VersionInfo.new(1, 7, 9) + required_version = Gitlab::VersionInfo.new(1, 8, 4) current_version = Gitlab::VersionInfo.parse(gitlab_shell_version) print "GitLab Shell version >= #{required_version} ? ... " -- cgit v1.2.3 From b5d81174fb12296ade36ec1f52546b8527bbdcf1 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 13:02:55 +0200 Subject: Fix mr process order on push. First close merge requests that being merged. Then update code of open mr. This fixes bug when MR merged via command line lose their diff because code reload was before MR close. Signed-off-by: Dmitriy Zaporozhets --- app/models/project.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 392c38cc5d9..6425940b21d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -390,18 +390,17 @@ class Project < ActiveRecord::Base branch_name = ref.gsub("refs/heads/", "") c_ids = self.repository.commits_between(oldrev, newrev).map(&:id) + # Close merge requests + mrs = self.merge_requests.opened.where(target_branch: branch_name).to_a + mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) } + mrs.each { |merge_request| MergeRequests::MergeService.new.execute(merge_request, user, nil) } + # Update code for merge requests into project between project branches mrs = self.merge_requests.opened.by_branch(branch_name).to_a # Update code for merge requests between project and project fork mrs += self.fork_merge_requests.opened.by_branch(branch_name).to_a - mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked } - # Close merge requests - mrs = self.merge_requests.opened.where(target_branch: branch_name).to_a - mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) } - mrs.each { |merge_request| MergeRequests::MergeService.new.execute(merge_request, user, nil) } - true end -- cgit v1.2.3 From f3ceebad42f56619aad1aa793735e47cd7da7aec Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 14 Mar 2014 12:33:03 +0100 Subject: Ignore newlines per md standard. --- app/helpers/gitlab_markdown_helper.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index 6cad5e4658e..7f72ab54838 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -35,7 +35,6 @@ module GitlabMarkdownHelper # see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch- filter_html: true, with_toc_data: true, - hard_wrap: true, safe_links_only: true }.merge(options)) @markdown = Redcarpet::Markdown.new(gitlab_renderer, @@ -45,7 +44,7 @@ module GitlabMarkdownHelper fenced_code_blocks: true, autolink: true, strikethrough: true, - lax_html_blocks: true, + lax_spacing: true, space_after_headers: true, superscript: true) end -- cgit v1.2.3 From ccc14fa21c227228dffcf87c7ae683965f0f451e Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 14 Mar 2014 12:33:22 +0100 Subject: Add to changelog changes for markdown. --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index f93668289ce..6c8b4e6cd80 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,8 @@ v 6.7.0 - Add button for toggling inline comments in diff view - Add retry feature for repository import - Reuse the GitLab LDAP connection within each request + - Changed markdown new line behaviour to conform to markdown standards + v 6.6.2 - Fix 500 error on branch/tag create or remove via UI -- cgit v1.2.3 From fa3c087a4cad7a62b2aec9df88d379c1822e0d0c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 14:23:28 +0200 Subject: Clear rake task only if defined Signed-off-by: Dmitriy Zaporozhets --- lib/tasks/spec.rake | 2 +- lib/tasks/spinach.rake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake index 4e562459e15..90a1809914b 100644 --- a/lib/tasks/spec.rake +++ b/lib/tasks/spec.rake @@ -1,4 +1,4 @@ -Rake::Task["spec"].clear +Rake::Task["spec"].clear if Rake::Task.task_defined?('spec') desc "GITLAB | Run specs" task :spec do diff --git a/lib/tasks/spinach.rake b/lib/tasks/spinach.rake index 60d4d6343b7..c23d0e0e188 100644 --- a/lib/tasks/spinach.rake +++ b/lib/tasks/spinach.rake @@ -1,4 +1,4 @@ -Rake::Task["spinach"].clear +Rake::Task["spinach"].clear if Rake::Task.task_defined?('spinach') desc "GITLAB | Run spinach" task :spinach do -- cgit v1.2.3 From e07b2f527fcaff6f2a998b0a74b0669389fbbbe6 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 14:41:28 +0200 Subject: Fix global search Signed-off-by: Dmitriy Zaporozhets --- CHANGELOG | 1 + app/controllers/search_controller.rb | 1 + app/services/search/global_service.rb | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 6c8b4e6cd80..50cfc95ef33 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -20,6 +20,7 @@ v 6.7.0 - Add retry feature for repository import - Reuse the GitLab LDAP connection within each request - Changed markdown new line behaviour to conform to markdown standards + - Fix global search v 6.6.2 diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index c1648d6c387..8df84e9884a 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -7,6 +7,7 @@ class SearchController < ApplicationController if @project return access_denied! unless can?(current_user, :download_code, @project) + @search_results = Search::ProjectService.new(@project, current_user, params).execute else @search_results = Search::GlobalService.new(current_user, params).execute diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb index 09c7cb25dd5..372d1bf7129 100644 --- a/app/services/search/global_service.rb +++ b/app/services/search/global_service.rb @@ -14,9 +14,10 @@ module Search group = Group.find_by(id: params[:group_id]) if params[:group_id].present? projects = Project.accessible_to(current_user) projects = projects.where(namespace_id: group.id) if group - projects = projects.search(query) project_ids = projects.pluck(:id) + projects = projects.search(query) + result[:projects] = projects.limit(20) result[:merge_requests] = MergeRequest.in_projects(project_ids).search(query).order('updated_at DESC').limit(20) result[:issues] = Issue.where(project_id: project_ids).search(query).order('updated_at DESC').limit(20) -- cgit v1.2.3 From 17a9ecf8cf6724613b38c08040bdb786ffe30718 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 14:43:50 +0200 Subject: Remove confusing code Signed-off-by: Dmitriy Zaporozhets --- app/services/search/global_service.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb index 372d1bf7129..8a1fce17ce7 100644 --- a/app/services/search/global_service.rb +++ b/app/services/search/global_service.rb @@ -16,9 +16,7 @@ module Search projects = projects.where(namespace_id: group.id) if group project_ids = projects.pluck(:id) - projects = projects.search(query) - - result[:projects] = projects.limit(20) + result[:projects] = projects.search(query).limit(20) result[:merge_requests] = MergeRequest.in_projects(project_ids).search(query).order('updated_at DESC').limit(20) result[:issues] = Issue.where(project_id: project_ids).search(query).order('updated_at DESC').limit(20) result[:total_results] = %w(projects issues merge_requests).sum { |items| result[items.to_sym].size } -- cgit v1.2.3 From a39eeba1dc631508ef4af7f26f4ba2e8cdea8bfe Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 15:55:41 +0200 Subject: Render 404 instead of 500 if trying to see snippets of unexisting user Signed-off-by: Dmitriy Zaporozhets --- app/controllers/snippets_controller.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index e54a968326f..0dd941a48e2 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -19,6 +19,9 @@ class SnippetsController < ApplicationController def user_index @user = User.find_by(username: params[:username]) + + render_404 and return unless @user + @snippets = @user.snippets.fresh.non_expired if @user == current_user -- cgit v1.2.3 From 25f68a71d6a176c35e3817cf98d4668a7a303f74 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 15:58:10 +0200 Subject: Project must have namespace for Project#find_with_namespace Signed-off-by: Dmitriy Zaporozhets --- app/models/project.rb | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 6425940b21d..7d7edc45739 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -177,15 +177,13 @@ class Project < ActiveRecord::Base end def find_with_namespace(id) - if id.include?("/") - id = id.split("/") - namespace = Namespace.find_by(path: id.first) - return nil unless namespace - - where(namespace_id: namespace.id).find_by(path: id.second) - else - where(path: id, namespace_id: nil).last - end + return nil unless id.include?("/") + + id = id.split("/") + namespace = Namespace.find_by(path: id.first) + return nil unless namespace + + where(namespace_id: namespace.id).find_by(path: id.second) end def visibility_levels -- cgit v1.2.3 From a9f2903e8642bc15da5a0b53f71b65ec1f25fc6e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 15:58:52 +0200 Subject: Change project lookup order for api Signed-off-by: Dmitriy Zaporozhets --- lib/api/helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index f8c48e2f3b2..fc309f65a56 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -47,7 +47,7 @@ module API end def find_project(id) - project = Project.find_by(id: id) || Project.find_with_namespace(id) + project = Project.find_with_namespace(id) || Project.find_by(id: id) if project && can?(current_user, :read_project, project) project -- cgit v1.2.3 From 779fa4a7b7f2eef7910509df1787412844a3b3b8 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 13 Mar 2014 18:32:30 +0100 Subject: Use batch_add_keys in `rake gitlab:shell:setup` --- CHANGELOG | 2 +- lib/gitlab/backend/shell.rb | 16 ++++++++++++++++ lib/tasks/gitlab/shell.rake | 12 ++++++++---- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 50cfc95ef33..8fd88bf1542 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -21,7 +21,7 @@ v 6.7.0 - Reuse the GitLab LDAP connection within each request - Changed markdown new line behaviour to conform to markdown standards - Fix global search - + - Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.4) v 6.6.2 - Fix 500 error on branch/tag create or remove via UI diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb index 7121c8e40d2..b93800e235f 100644 --- a/lib/gitlab/backend/shell.rb +++ b/lib/gitlab/backend/shell.rb @@ -2,6 +2,12 @@ module Gitlab class Shell class AccessDenied < StandardError; end + class KeyAdder < Struct.new(:io) + def add_key(id, key) + io.puts("#{id}\t#{key.strip}") + end + end + # Init new repository # # name - project path with namespace @@ -130,6 +136,16 @@ module Gitlab system "#{gitlab_shell_path}/bin/gitlab-keys", "add-key", key_id, key_content end + # Batch-add keys to authorized_keys + # + # Ex. + # batch_add_keys { |adder| adder.add_key("key-42", "sha-rsa ...") } + def batch_add_keys(&block) + IO.popen(%W(#{gitlab_shell_path}/bin/gitlab-keys batch-add-keys), 'w') do |io| + block.call(KeyAdder.new(io)) + end + end + # Remove ssh key from gitlab shell # # Ex. diff --git a/lib/tasks/gitlab/shell.rake b/lib/tasks/gitlab/shell.rake index 0d7a390bc92..08de0f2dd5d 100644 --- a/lib/tasks/gitlab/shell.rake +++ b/lib/tasks/gitlab/shell.rake @@ -34,14 +34,18 @@ namespace :gitlab do Gitlab::Shell.new.remove_all_keys - Key.find_each(batch_size: 1000) do |key| - if Gitlab::Shell.new.add_key(key.shell_id, key.key) + Gitlab::Shell.new.batch_add_keys do |adder| + Key.find_each(batch_size: 1000) do |key| + adder.add_key(key.shell_id, key.key) print '.' - else - print 'F' end end + unless $?.success? + puts "Failed to add keys...".red + exit 1 + end + rescue Gitlab::TaskAbortedByUserError puts "Quitting...".red exit 1 -- cgit v1.2.3 From 090ed21e6f53ade25716fb0b406f25b93b6a7690 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 14 Mar 2014 15:57:52 +0100 Subject: Batch key import requires gitlab-shell 1.8.5 --- CHANGELOG | 2 +- lib/tasks/gitlab/check.rake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8fd88bf1542..785a4bb6713 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -21,7 +21,7 @@ v 6.7.0 - Reuse the GitLab LDAP connection within each request - Changed markdown new line behaviour to conform to markdown standards - Fix global search - - Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.4) + - Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.5) v 6.6.2 - Fix 500 error on branch/tag create or remove via UI diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 2b158fe14ee..c2e6cd1be78 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -727,7 +727,7 @@ namespace :gitlab do end def check_gitlab_shell - required_version = Gitlab::VersionInfo.new(1, 8, 4) + required_version = Gitlab::VersionInfo.new(1, 8, 5) current_version = Gitlab::VersionInfo.parse(gitlab_shell_version) print "GitLab Shell version >= #{required_version} ? ... " -- cgit v1.2.3 From 4aa3ce75342f26be3c87ac8c84f24658b9ef22a4 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 14 Mar 2014 17:25:11 +0100 Subject: Add check for orphaned UsersGroups --- lib/tasks/gitlab/check.rake | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 2b158fe14ee..467a91fbe86 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -17,6 +17,7 @@ namespace :gitlab do check_database_config_exists check_database_is_not_sqlite check_migrations_are_up + check_orphaned_users_groups check_gitlab_config_exists check_gitlab_config_not_outdated check_log_writable @@ -181,6 +182,15 @@ namespace :gitlab do end end + def check_orphaned_users_groups + print "Database contains orphaned UsersGroups? ... " + if UsersGroup.where("user_id not in (select id from users)").count > 0 + puts "yes".red + else + puts "no".green + end + end + def check_satellites_exist print "Projects have satellites? ... " -- cgit v1.2.3 From 686128cd68cfb6fc90ee32848c00826a7abe6280 Mon Sep 17 00:00:00 2001 From: Daniel Lorch Date: Fri, 14 Mar 2014 18:06:01 +0100 Subject: JIRA project identifiers may also contain dashes '-' --- lib/gitlab/markdown.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index dc9c0e0ab2c..e72f4f5d0ce 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -98,7 +98,7 @@ module Gitlab (?\W)? # Prefix ( # Reference @(?[a-zA-Z][a-zA-Z0-9_\-\.]*) # User name - |\#(?([a-zA-Z]+-)?\d+) # Issue ID + |\#(?([a-zA-Z\-]+-)?\d+) # Issue ID |!(?\d+) # MR ID |\$(?\d+) # Snippet ID |(?[\h]{6,40}) # Commit ID -- cgit v1.2.3 From 901976d9729fe5fb91929c463b0ad3a68e457c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ho=CC=88ltje?= Date: Fri, 14 Mar 2014 14:53:43 -0400 Subject: Switched line endings to LF for system_hooks.md It was checked in with Windows style line endings. --- doc/api/system_hooks.md | 140 ++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/doc/api/system_hooks.md b/doc/api/system_hooks.md index 355ce31c126..2e87ada1d70 100644 --- a/doc/api/system_hooks.md +++ b/doc/api/system_hooks.md @@ -1,70 +1,70 @@ -All methods require admin authorization. - -The url endpoint of the system hooks can be configured in [the admin area under hooks](/admin/hooks). - -## List system hooks - -Get list of system hooks - -``` -GET /hooks -``` - -Parameters: - -+ **none** - -```json -[ - { - "id":3, - "url":"http://example.com/hook", - "created_at":"2013-10-02T10:15:31Z" - } -] -``` - -## Add new system hook hook - -``` -POST /hooks -``` - -Parameters: - -+ `url` (required) - The hook URL - - -## Test system hook - -``` -GET /hooks/:id -``` - -Parameters: - -+ `id` (required) - The ID of hook - -```json -{ - "event_name":"project_create", - "name":"Ruby", - "path":"ruby", - "project_id":1, - "owner_name":"Someone", - "owner_email":"example@gitlabhq.com" -} -``` - -## Delete system hook - -Deletes a system hook. This is an idempotent API function and returns `200 Ok` even if the hook -is not available. If the hook is deleted it is also returned as JSON. - -``` -DELETE /hooks/:id -``` - -Parameters: - -+ `id` (required) - The ID of hook +All methods require admin authorization. + +The url endpoint of the system hooks can be configured in [the admin area under hooks](/admin/hooks). + +## List system hooks + +Get list of system hooks + +``` +GET /hooks +``` + +Parameters: + ++ **none** + +```json +[ + { + "id":3, + "url":"http://example.com/hook", + "created_at":"2013-10-02T10:15:31Z" + } +] +``` + +## Add new system hook hook + +``` +POST /hooks +``` + +Parameters: + ++ `url` (required) - The hook URL + + +## Test system hook + +``` +GET /hooks/:id +``` + +Parameters: + ++ `id` (required) - The ID of hook + +```json +{ + "event_name":"project_create", + "name":"Ruby", + "path":"ruby", + "project_id":1, + "owner_name":"Someone", + "owner_email":"example@gitlabhq.com" +} +``` + +## Delete system hook + +Deletes a system hook. This is an idempotent API function and returns `200 Ok` even if the hook +is not available. If the hook is deleted it is also returned as JSON. + +``` +DELETE /hooks/:id +``` + +Parameters: + ++ `id` (required) - The ID of hook -- cgit v1.2.3 From f84d015fa95448c6ee6a256cbea6c2ed011a289d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 14 Mar 2014 23:09:43 +0200 Subject: Fix commit comment count css Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/commit/_commit_box.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index e61d9a2ac47..f2b0699f136 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -1,7 +1,7 @@ .pull-right %div - if @notes_count > 0 - %span.btn.disabled.grouped + %span.btn.disabled.btn-grouped %i.icon-comment = @notes_count .pull-left.btn-group -- cgit v1.2.3 From 6e73b208a9f69c68bf8575d902d6662eb3db0662 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sat, 15 Mar 2014 10:23:48 +0200 Subject: Add comments fixtures for development Signed-off-by: Dmitriy Zaporozhets --- db/fixtures/development/13_comments.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 db/fixtures/development/13_comments.rb diff --git a/db/fixtures/development/13_comments.rb b/db/fixtures/development/13_comments.rb new file mode 100644 index 00000000000..b133ec3146d --- /dev/null +++ b/db/fixtures/development/13_comments.rb @@ -0,0 +1,13 @@ +ActiveRecord::Base.observers.disable :all + +Issue.all.limit(10).each_with_index do |issue, i| + 5.times do + Note.seed(:id, [{ + project_id: issue.project.id, + author_id: issue.project.team.users.sample.id, + note: Faker::Lorem.sentence, + noteable_id: issue.id, + noteable_type: 'Issue' + }]) + end +end -- cgit v1.2.3 From 39f80884db394decdb4b4a21a30bc1ecb3203944 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sat, 15 Mar 2014 11:39:35 +0200 Subject: Improve developer seeds Return execution of observers in seeds. Mute email sending to letter opening in you browser. Added `rake dev` task to reset db and add seeds. Signed-off-by: Dmitriy Zaporozhets --- db/fixtures/development/01_admin.rb | 5 +- db/fixtures/development/04_project.rb | 104 ++++++++++++++------------- db/fixtures/development/05_users.rb | 1 + db/fixtures/development/06_teams.rb | 2 - db/fixtures/development/09_issues.rb | 8 +-- db/fixtures/development/10_merge_requests.rb | 7 +- db/fixtures/development/11_keys.rb | 2 - db/fixtures/development/12_snippets.rb | 2 - db/fixtures/development/13_comments.rb | 26 ++++--- lib/gitlab/seeder.rb | 19 +++++ lib/tasks/dev.rake | 6 +- 11 files changed, 96 insertions(+), 86 deletions(-) diff --git a/db/fixtures/development/01_admin.rb b/db/fixtures/development/01_admin.rb index 3e76d76e838..42d18435340 100644 --- a/db/fixtures/development/01_admin.rb +++ b/db/fixtures/development/01_admin.rb @@ -8,8 +8,7 @@ User.seed(:id, [ password_confirmation: "5iveL!fe", admin: true, projects_limit: 100, - theme_id: Gitlab::Theme::MARS + theme_id: Gitlab::Theme::MARS, + confirmed_at: DateTime.now } ]) - -User.find(1).confirm! diff --git a/db/fixtures/development/04_project.rb b/db/fixtures/development/04_project.rb index d0d0774e0c8..9303ab93300 100644 --- a/db/fixtures/development/04_project.rb +++ b/db/fixtures/development/04_project.rb @@ -1,53 +1,55 @@ -project_urls = [ - 'https://github.com/documentcloud/underscore.git', - 'https://github.com/diaspora/diaspora.git', - 'https://github.com/diaspora/diaspora-project-site.git', - 'https://github.com/diaspora/diaspora-client.git', - 'https://github.com/brightbox/brightbox-cli.git', - 'https://github.com/brightbox/puppet.git', - 'https://github.com/gitlabhq/gitlabhq.git', - 'https://github.com/gitlabhq/gitlab-ci.git', - 'https://github.com/gitlabhq/gitlab-recipes.git', - 'https://github.com/gitlabhq/gitlab-shell.git', - 'https://github.com/gitlabhq/grack.git', - 'https://github.com/gitlabhq/testme.git', - 'https://github.com/twitter/flight.git', - 'https://github.com/twitter/typeahead.js.git', - 'https://github.com/h5bp/html5-boilerplate.git', - 'https://github.com/h5bp/mobile-boilerplate.git', -] - -project_urls.each_with_index do |url, i| - group_path, project_path = url.split('/')[-2..-1] - - group = Group.find_by(path: group_path) - - unless group - group = Group.new( - name: group_path.titleize, - path: group_path - ) - group.description = Faker::Lorem.sentence - group.save - - group.add_owner(User.first) - end - - project_path.gsub!(".git", "") - - params = { - import_url: url, - namespace_id: group.id, - name: project_path.titleize, - description: Faker::Lorem.sentence - } - - project = Projects::CreateService.new(User.first, params).execute - - if project.valid? - print '.' - else - puts project.errors.full_messages - print 'F' +Gitlab::Seeder.quiet do + project_urls = [ + 'https://github.com/documentcloud/underscore.git', + 'https://github.com/diaspora/diaspora.git', + 'https://github.com/diaspora/diaspora-project-site.git', + 'https://github.com/diaspora/diaspora-client.git', + 'https://github.com/brightbox/brightbox-cli.git', + 'https://github.com/brightbox/puppet.git', + 'https://github.com/gitlabhq/gitlabhq.git', + 'https://github.com/gitlabhq/gitlab-ci.git', + 'https://github.com/gitlabhq/gitlab-recipes.git', + 'https://github.com/gitlabhq/gitlab-shell.git', + 'https://github.com/gitlabhq/grack.git', + 'https://github.com/gitlabhq/testme.git', + 'https://github.com/twitter/flight.git', + 'https://github.com/twitter/typeahead.js.git', + 'https://github.com/h5bp/html5-boilerplate.git', + 'https://github.com/h5bp/mobile-boilerplate.git', + ] + + project_urls.each_with_index do |url, i| + group_path, project_path = url.split('/')[-2..-1] + + group = Group.find_by(path: group_path) + + unless group + group = Group.new( + name: group_path.titleize, + path: group_path + ) + group.description = Faker::Lorem.sentence + group.save + + group.add_owner(User.first) + end + + project_path.gsub!(".git", "") + + params = { + import_url: url, + namespace_id: group.id, + name: project_path.titleize, + description: Faker::Lorem.sentence + } + + project = Projects::CreateService.new(User.first, params).execute + + if project.valid? + print '.' + else + puts project.errors.full_messages + print 'F' + end end end diff --git a/db/fixtures/development/05_users.rb b/db/fixtures/development/05_users.rb index 3440a645408..d736408dbf5 100644 --- a/db/fixtures/development/05_users.rb +++ b/db/fixtures/development/05_users.rb @@ -6,6 +6,7 @@ Gitlab::Seeder.quiet do username: Faker::Internet.user_name, name: Faker::Name.name, email: Faker::Internet.email, + confirmed_at: DateTime.now }]) print '.' rescue ActiveRecord::RecordNotSaved diff --git a/db/fixtures/development/06_teams.rb b/db/fixtures/development/06_teams.rb index a1e01879db5..dfbe75fd20e 100644 --- a/db/fixtures/development/06_teams.rb +++ b/db/fixtures/development/06_teams.rb @@ -1,5 +1,3 @@ -ActiveRecord::Base.observers.disable :all - Gitlab::Seeder.quiet do Group.all.each do |group| User.all.sample(4).each do |user| diff --git a/db/fixtures/development/09_issues.rb b/db/fixtures/development/09_issues.rb index 2b81d7a2597..635878622d0 100644 --- a/db/fixtures/development/09_issues.rb +++ b/db/fixtures/development/09_issues.rb @@ -1,5 +1,3 @@ -ActiveRecord::Base.observers.disable :all - Gitlab::Seeder.quiet do (1..300).each do |i| # Random Project @@ -12,9 +10,7 @@ Gitlab::Seeder.quiet do user_id = user.id - begin - Thread.current[:current_user] = user - + Gitlab::Seeder.by_user(user) do Issue.seed(:id, [{ id: i, project_id: project.id, @@ -25,8 +21,6 @@ Gitlab::Seeder.quiet do title: Faker::Lorem.sentence(6), description: Faker::Lorem.sentence }]) - ensure - Thread.current[:current_user] = nil end print('.') end diff --git a/db/fixtures/development/10_merge_requests.rb b/db/fixtures/development/10_merge_requests.rb index 2b1f4160211..cb08a7c2537 100644 --- a/db/fixtures/development/10_merge_requests.rb +++ b/db/fixtures/development/10_merge_requests.rb @@ -1,5 +1,3 @@ -ActiveRecord::Base.observers.disable :all - Gitlab::Seeder.quiet do (1..100).each do |i| # Random Project @@ -17,9 +15,8 @@ Gitlab::Seeder.quiet do next if branches.uniq.size < 2 user_id = user.id - begin - Thread.current[:current_user] = user + Gitlab::Seeder.by_user(user) do MergeRequest.seed(:id, [{ id: i, source_branch: branches.first, @@ -31,8 +28,6 @@ Gitlab::Seeder.quiet do milestone: project.milestones.sample, title: Faker::Lorem.sentence(6) }]) - ensure - Thread.current[:current_user] = nil end print('.') end diff --git a/db/fixtures/development/11_keys.rb b/db/fixtures/development/11_keys.rb index 4b53ff411f2..42171393d1b 100644 --- a/db/fixtures/development/11_keys.rb +++ b/db/fixtures/development/11_keys.rb @@ -1,5 +1,3 @@ -ActiveRecord::Base.observers.enable :all - Gitlab::Seeder.quiet do User.first(30).each_with_index do |user, i| Key.seed(:id, [ diff --git a/db/fixtures/development/12_snippets.rb b/db/fixtures/development/12_snippets.rb index 4ca8afe294e..dced2706264 100644 --- a/db/fixtures/development/12_snippets.rb +++ b/db/fixtures/development/12_snippets.rb @@ -1,5 +1,3 @@ -ActiveRecord::Base.observers.disable :all - Gitlab::Seeder.quiet do contents = [ `curl https://gist.github.com/randx/4275756/raw/da2f262920c96d1a970d48bf2e99147954b1f4bd/glus1204.sh`, diff --git a/db/fixtures/development/13_comments.rb b/db/fixtures/development/13_comments.rb index b133ec3146d..626aba200d1 100644 --- a/db/fixtures/development/13_comments.rb +++ b/db/fixtures/development/13_comments.rb @@ -1,13 +1,19 @@ -ActiveRecord::Base.observers.disable :all +Gitlab::Seeder.quiet do + Issue.all.limit(10).each_with_index do |issue, i| + 5.times do + user = issue.project.team.users.sample -Issue.all.limit(10).each_with_index do |issue, i| - 5.times do - Note.seed(:id, [{ - project_id: issue.project.id, - author_id: issue.project.team.users.sample.id, - note: Faker::Lorem.sentence, - noteable_id: issue.id, - noteable_type: 'Issue' - }]) + Gitlab::Seeder.by_user(user) do + Note.seed(:id, [{ + project_id: issue.project.id, + author_id: user.id, + note: Faker::Lorem.sentence, + noteable_id: issue.id, + noteable_type: 'Issue' + }]) + + print '.' + end + end end end diff --git a/lib/gitlab/seeder.rb b/lib/gitlab/seeder.rb index 3aa3b2ba1e9..39de1223b18 100644 --- a/lib/gitlab/seeder.rb +++ b/lib/gitlab/seeder.rb @@ -1,10 +1,29 @@ module Gitlab class Seeder def self.quiet + mute_mailer SeedFu.quiet = true yield SeedFu.quiet = false puts "\nOK".green end + + def self.by_user(user) + begin + Thread.current[:current_user] = user + yield + ensure + Thread.current[:current_user] = nil + end + end + + def self.mute_mailer + code = <<-eos +def Notify.delay + self +end + eos + eval(code) + end end end diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake index 7d3602211c1..058c7417040 100644 --- a/lib/tasks/dev.rake +++ b/lib/tasks/dev.rake @@ -1,10 +1,10 @@ +task dev: ["dev:setup"] + namespace :dev do desc "GITLAB | Setup developer environment (db, fixtures)" task :setup => :environment do ENV['force'] = 'yes' - Rake::Task["db:setup"].invoke - Rake::Task["db:seed_fu"].invoke + Rake::Task["gitlab:setup"].invoke Rake::Task["gitlab:shell:setup"].invoke end end - -- cgit v1.2.3 From ac09f6deb9ced5f5db6dc21b9cf9c153953d175f Mon Sep 17 00:00:00 2001 From: Kei Date: Fri, 14 Mar 2014 12:49:50 +0800 Subject: Fixed some minor typos. --- doc/system_hooks/system_hooks.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md index fe32ca1a9fa..76ca2a59911 100644 --- a/doc/system_hooks/system_hooks.md +++ b/doc/system_hooks/system_hooks.md @@ -11,8 +11,8 @@ System hooks can be used, e.g. for logging or changing information in a LDAP ser "created_at": "2012-07-21T07:30:54Z", "event_name": "project_create", "name": "StoreCloud", - "owner_email": "johnsmith@gmail.com" - "owner_name": "John Smit", + "owner_email": "johnsmith@gmail.com", + "owner_name": "John Smith", "path": "stormcloud", "path_with_namespace": "jsmith/stormcloud", "project_id": 74, @@ -26,7 +26,7 @@ System hooks can be used, e.g. for logging or changing information in a LDAP ser "created_at": "2012-07-21T07:30:58Z", "event_name": "project_destroy", "name": "Underscore", - "owner_email": "johnsmith@gmail.com" + "owner_email": "johnsmith@gmail.com", "owner_name": "John Smith", "path": "underscore", "path_with_namespace": "jsmith/underscore", @@ -36,7 +36,7 @@ System hooks can be used, e.g. for logging or changing information in a LDAP ser **New Team Member:** -```ruby +```json { "created_at": "2012-07-21T07:30:56Z", "event_name": "user_add_to_team", -- cgit v1.2.3 From cfabaa8bd59adc13f7545e1523ecfd986339a77b Mon Sep 17 00:00:00 2001 From: Arif Ali Date: Mon, 17 Mar 2014 00:01:14 +0000 Subject: update changelog, add remainder 6.6.X changlog entries --- CHANGELOG | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 88b096628c0..dc49e759415 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -24,6 +24,18 @@ v 6.7.0 - Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.5) - Create and Update MR calls now support the description parameter (Greg Messner) +v 6.6.5 + - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) + - Hide mr close button for comment form if merge request was closed or inline comment + - Adds ability to reopen closed merge request + +v 6.6.4 + - Add missing html escape for highlighted code blocks in comments, issues + +v 6.6.3 + - Fix 500 error when edit yourself from admin area + - Hide private groups for public profiles + v 6.6.2 - Fix 500 error on branch/tag create or remove via UI -- cgit v1.2.3 From c0d2b976caa8bacd3a1fb90337eb2ddcbee93c8e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 17 Mar 2014 13:29:51 +0200 Subject: Restore old travis.yml Signed-off-by: Dmitriy Zaporozhets --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 07f8146f3de..d7c65286cfe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,8 @@ rvm: services: - redis-server before_script: + - "bundle exec rake db:setup" + - "bundle exec rake db:seed_fu" - "cp config/database.yml.$DB config/database.yml" - "cp config/gitlab.yml.example config/gitlab.yml" script: "bundle exec rake $TASK --trace" -- cgit v1.2.3 From 7c60713e82982066e187b8c16ce327978b451b0a Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 17 Mar 2014 13:44:54 +0200 Subject: Move project members api to separate file Signed-off-by: Dmitriy Zaporozhets --- lib/api/api.rb | 1 + lib/api/project_hooks.rb | 9 -- lib/api/project_members.rb | 114 ++++++++++++++++++++++ lib/api/projects.rb | 105 -------------------- spec/requests/api/project_members_spec.rb | 156 ++++++++++++++++++++++++++++++ spec/requests/api/projects_spec.rb | 142 --------------------------- 6 files changed, 271 insertions(+), 256 deletions(-) create mode 100644 lib/api/project_members.rb create mode 100644 spec/requests/api/project_members_spec.rb diff --git a/lib/api/api.rb b/lib/api/api.rb index 6bec8368b12..7c4cdad7f0d 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -38,6 +38,7 @@ module API mount Internal mount SystemHooks mount ProjectSnippets + mount ProjectMembers mount DeployKeys mount ProjectHooks mount Services diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index c271dd8b61b..79c3d122d32 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -5,15 +5,6 @@ module API before { authorize_admin_project } resource :projects do - helpers do - def handle_project_member_errors(errors) - if errors[:project_access].any? - error!(errors[:project_access], 422) - end - not_found! - end - end - # Get project hooks # # Parameters: diff --git a/lib/api/project_members.rb b/lib/api/project_members.rb new file mode 100644 index 00000000000..47c4ddce163 --- /dev/null +++ b/lib/api/project_members.rb @@ -0,0 +1,114 @@ +module API + # Projects members API + class ProjectMembers < Grape::API + before { authenticate! } + + resource :projects do + helpers do + def handle_project_member_errors(errors) + if errors[:project_access].any? + error!(errors[:project_access], 422) + end + not_found! + end + end + + # Get a project team members + # + # Parameters: + # id (required) - The ID of a project + # query - Query string + # Example Request: + # GET /projects/:id/members + get ":id/members" do + if params[:query].present? + @members = paginate user_project.users.where("username LIKE ?", "%#{params[:query]}%") + else + @members = paginate user_project.users + end + present @members, with: Entities::ProjectMember, project: user_project + end + + # Get a project team members + # + # Parameters: + # id (required) - The ID of a project + # user_id (required) - The ID of a user + # Example Request: + # GET /projects/:id/members/:user_id + get ":id/members/:user_id" do + @member = user_project.users.find params[:user_id] + present @member, with: Entities::ProjectMember, project: user_project + end + + # Add a new project team member + # + # Parameters: + # id (required) - The ID of a project + # user_id (required) - The ID of a user + # access_level (required) - Project access level + # Example Request: + # POST /projects/:id/members + post ":id/members" do + authorize! :admin_project, user_project + required_attributes! [:user_id, :access_level] + + # either the user is already a team member or a new one + team_member = user_project.team_member_by_id(params[:user_id]) + if team_member.nil? + team_member = user_project.users_projects.new( + user_id: params[:user_id], + project_access: params[:access_level] + ) + end + + if team_member.save + @member = team_member.user + present @member, with: Entities::ProjectMember, project: user_project + else + handle_project_member_errors team_member.errors + end + end + + # Update project team member + # + # Parameters: + # id (required) - The ID of a project + # user_id (required) - The ID of a team member + # access_level (required) - Project access level + # Example Request: + # PUT /projects/:id/members/:user_id + put ":id/members/:user_id" do + authorize! :admin_project, user_project + required_attributes! [:access_level] + + team_member = user_project.users_projects.find_by(user_id: params[:user_id]) + not_found!("User can not be found") if team_member.nil? + + if team_member.update_attributes(project_access: params[:access_level]) + @member = team_member.user + present @member, with: Entities::ProjectMember, project: user_project + else + handle_project_member_errors team_member.errors + end + end + + # Remove a team member from project + # + # Parameters: + # id (required) - The ID of a project + # user_id (required) - The ID of a team member + # Example Request: + # DELETE /projects/:id/members/:user_id + delete ":id/members/:user_id" do + authorize! :admin_project, user_project + team_member = user_project.users_projects.find_by(user_id: params[:user_id]) + unless team_member.nil? + team_member.destroy + else + {message: "Access revoked", id: params[:user_id].to_i} + end + end + end + end +end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index bcca69ff49a..618a582a451 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -5,13 +5,6 @@ module API resource :projects do helpers do - def handle_project_member_errors(errors) - if errors[:project_access].any? - error!(errors[:project_access], 422) - end - not_found! - end - def map_public_to_visibility_level(attrs) publik = attrs.delete(:public) publik = [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(publik) @@ -196,104 +189,6 @@ module API user_project.forked_project_link.destroy end end - - # Get a project team members - # - # Parameters: - # id (required) - The ID of a project - # query - Query string - # Example Request: - # GET /projects/:id/members - get ":id/members" do - if params[:query].present? - @members = paginate user_project.users.where("username LIKE ?", "%#{params[:query]}%") - else - @members = paginate user_project.users - end - present @members, with: Entities::ProjectMember, project: user_project - end - - # Get a project team members - # - # Parameters: - # id (required) - The ID of a project - # user_id (required) - The ID of a user - # Example Request: - # GET /projects/:id/members/:user_id - get ":id/members/:user_id" do - @member = user_project.users.find params[:user_id] - present @member, with: Entities::ProjectMember, project: user_project - end - - # Add a new project team member - # - # Parameters: - # id (required) - The ID of a project - # user_id (required) - The ID of a user - # access_level (required) - Project access level - # Example Request: - # POST /projects/:id/members - post ":id/members" do - authorize! :admin_project, user_project - required_attributes! [:user_id, :access_level] - - # either the user is already a team member or a new one - team_member = user_project.team_member_by_id(params[:user_id]) - if team_member.nil? - team_member = user_project.users_projects.new( - user_id: params[:user_id], - project_access: params[:access_level] - ) - end - - if team_member.save - @member = team_member.user - present @member, with: Entities::ProjectMember, project: user_project - else - handle_project_member_errors team_member.errors - end - end - - # Update project team member - # - # Parameters: - # id (required) - The ID of a project - # user_id (required) - The ID of a team member - # access_level (required) - Project access level - # Example Request: - # PUT /projects/:id/members/:user_id - put ":id/members/:user_id" do - authorize! :admin_project, user_project - required_attributes! [:access_level] - - team_member = user_project.users_projects.find_by(user_id: params[:user_id]) - not_found!("User can not be found") if team_member.nil? - - if team_member.update_attributes(project_access: params[:access_level]) - @member = team_member.user - present @member, with: Entities::ProjectMember, project: user_project - else - handle_project_member_errors team_member.errors - end - end - - # Remove a team member from project - # - # Parameters: - # id (required) - The ID of a project - # user_id (required) - The ID of a team member - # Example Request: - # DELETE /projects/:id/members/:user_id - delete ":id/members/:user_id" do - authorize! :admin_project, user_project - team_member = user_project.users_projects.find_by(user_id: params[:user_id]) - unless team_member.nil? - team_member.destroy - else - {message: "Access revoked", id: params[:user_id].to_i} - end - end - # search for projects current_user has access to # # Parameters: diff --git a/spec/requests/api/project_members_spec.rb b/spec/requests/api/project_members_spec.rb new file mode 100644 index 00000000000..f3c0529da92 --- /dev/null +++ b/spec/requests/api/project_members_spec.rb @@ -0,0 +1,156 @@ +require 'spec_helper' + +describe API::API do + include ApiHelpers + before(:each) { enable_observers } + after(:each) { disable_observers } + + let(:user) { create(:user) } + let(:user2) { create(:user) } + let(:user3) { create(:user) } + let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) } + let(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) } + let(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) } + + describe "GET /projects/:id/members" do + before { users_project } + before { users_project2 } + + it "should return project team members" do + get api("/projects/#{project.id}/members", user) + response.status.should == 200 + json_response.should be_an Array + json_response.count.should == 2 + json_response.map { |u| u['email'] }.should include user.email + end + + it "finds team members with query string" do + get api("/projects/#{project.id}/members", user), query: user.username + response.status.should == 200 + json_response.should be_an Array + json_response.count.should == 1 + json_response.first['email'].should == user.email + end + + it "should return a 404 error if id not found" do + get api("/projects/9999/members", user) + response.status.should == 404 + end + end + + describe "GET /projects/:id/members/:user_id" do + before { users_project } + + it "should return project team member" do + get api("/projects/#{project.id}/members/#{user.id}", user) + response.status.should == 200 + json_response['email'].should == user.email + json_response['access_level'].should == UsersProject::MASTER + end + + it "should return a 404 error if user id not found" do + get api("/projects/#{project.id}/members/1234", user) + response.status.should == 404 + end + end + + describe "POST /projects/:id/members" do + it "should add user to project team" do + expect { + post api("/projects/#{project.id}/members", user), user_id: user2.id, + access_level: UsersProject::DEVELOPER + }.to change { UsersProject.count }.by(1) + + response.status.should == 201 + json_response['email'].should == user2.email + json_response['access_level'].should == UsersProject::DEVELOPER + end + + it "should return a 201 status if user is already project member" do + post api("/projects/#{project.id}/members", user), user_id: user2.id, + access_level: UsersProject::DEVELOPER + expect { + post api("/projects/#{project.id}/members", user), user_id: user2.id, + access_level: UsersProject::DEVELOPER + }.not_to change { UsersProject.count }.by(1) + + response.status.should == 201 + json_response['email'].should == user2.email + json_response['access_level'].should == UsersProject::DEVELOPER + end + + it "should return a 400 error when user id is not given" do + post api("/projects/#{project.id}/members", user), access_level: UsersProject::MASTER + response.status.should == 400 + end + + it "should return a 400 error when access level is not given" do + post api("/projects/#{project.id}/members", user), user_id: user2.id + response.status.should == 400 + end + + it "should return a 422 error when access level is not known" do + post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: 1234 + response.status.should == 422 + end + end + + describe "PUT /projects/:id/members/:user_id" do + before { users_project2 } + + it "should update project team member" do + put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: UsersProject::MASTER + response.status.should == 200 + json_response['email'].should == user3.email + json_response['access_level'].should == UsersProject::MASTER + end + + it "should return a 404 error if user_id is not found" do + put api("/projects/#{project.id}/members/1234", user), access_level: UsersProject::MASTER + response.status.should == 404 + end + + it "should return a 400 error when access level is not given" do + put api("/projects/#{project.id}/members/#{user3.id}", user) + response.status.should == 400 + end + + it "should return a 422 error when access level is not known" do + put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: 123 + response.status.should == 422 + end + end + + describe "DELETE /projects/:id/members/:user_id" do + before { users_project } + before { users_project2 } + + it "should remove user from project team" do + expect { + delete api("/projects/#{project.id}/members/#{user3.id}", user) + }.to change { UsersProject.count }.by(-1) + end + + it "should return 200 if team member is not part of a project" do + delete api("/projects/#{project.id}/members/#{user3.id}", user) + expect { + delete api("/projects/#{project.id}/members/#{user3.id}", user) + }.to_not change { UsersProject.count }.by(1) + end + + it "should return 200 if team member already removed" do + delete api("/projects/#{project.id}/members/#{user3.id}", user) + delete api("/projects/#{project.id}/members/#{user3.id}", user) + response.status.should == 200 + end + + it "should return 200 OK when the user was not member" do + expect { + delete api("/projects/#{project.id}/members/1000000", user) + }.to change { UsersProject.count }.by(0) + response.status.should == 200 + json_response['message'].should == "Access revoked" + json_response['id'].should == 1000000 + end + end +end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 342587ba5d6..b4b5f606eee 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -311,148 +311,6 @@ describe API::API do end end - describe "GET /projects/:id/members" do - before { users_project } - before { users_project2 } - - it "should return project team members" do - get api("/projects/#{project.id}/members", user) - response.status.should == 200 - json_response.should be_an Array - json_response.count.should == 2 - json_response.map { |u| u['email'] }.should include user.email - end - - it "finds team members with query string" do - get api("/projects/#{project.id}/members", user), query: user.username - response.status.should == 200 - json_response.should be_an Array - json_response.count.should == 1 - json_response.first['email'].should == user.email - end - - it "should return a 404 error if id not found" do - get api("/projects/9999/members", user) - response.status.should == 404 - end - end - - describe "GET /projects/:id/members/:user_id" do - before { users_project } - - it "should return project team member" do - get api("/projects/#{project.id}/members/#{user.id}", user) - response.status.should == 200 - json_response['email'].should == user.email - json_response['access_level'].should == UsersProject::MASTER - end - - it "should return a 404 error if user id not found" do - get api("/projects/#{project.id}/members/1234", user) - response.status.should == 404 - end - end - - describe "POST /projects/:id/members" do - it "should add user to project team" do - expect { - post api("/projects/#{project.id}/members", user), user_id: user2.id, - access_level: UsersProject::DEVELOPER - }.to change { UsersProject.count }.by(1) - - response.status.should == 201 - json_response['email'].should == user2.email - json_response['access_level'].should == UsersProject::DEVELOPER - end - - it "should return a 201 status if user is already project member" do - post api("/projects/#{project.id}/members", user), user_id: user2.id, - access_level: UsersProject::DEVELOPER - expect { - post api("/projects/#{project.id}/members", user), user_id: user2.id, - access_level: UsersProject::DEVELOPER - }.not_to change { UsersProject.count }.by(1) - - response.status.should == 201 - json_response['email'].should == user2.email - json_response['access_level'].should == UsersProject::DEVELOPER - end - - it "should return a 400 error when user id is not given" do - post api("/projects/#{project.id}/members", user), access_level: UsersProject::MASTER - response.status.should == 400 - end - - it "should return a 400 error when access level is not given" do - post api("/projects/#{project.id}/members", user), user_id: user2.id - response.status.should == 400 - end - - it "should return a 422 error when access level is not known" do - post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: 1234 - response.status.should == 422 - end - end - - describe "PUT /projects/:id/members/:user_id" do - before { users_project2 } - - it "should update project team member" do - put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: UsersProject::MASTER - response.status.should == 200 - json_response['email'].should == user3.email - json_response['access_level'].should == UsersProject::MASTER - end - - it "should return a 404 error if user_id is not found" do - put api("/projects/#{project.id}/members/1234", user), access_level: UsersProject::MASTER - response.status.should == 404 - end - - it "should return a 400 error when access level is not given" do - put api("/projects/#{project.id}/members/#{user3.id}", user) - response.status.should == 400 - end - - it "should return a 422 error when access level is not known" do - put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: 123 - response.status.should == 422 - end - end - - describe "DELETE /projects/:id/members/:user_id" do - before { users_project } - before { users_project2 } - - it "should remove user from project team" do - expect { - delete api("/projects/#{project.id}/members/#{user3.id}", user) - }.to change { UsersProject.count }.by(-1) - end - - it "should return 200 if team member is not part of a project" do - delete api("/projects/#{project.id}/members/#{user3.id}", user) - expect { - delete api("/projects/#{project.id}/members/#{user3.id}", user) - }.to_not change { UsersProject.count }.by(1) - end - - it "should return 200 if team member already removed" do - delete api("/projects/#{project.id}/members/#{user3.id}", user) - delete api("/projects/#{project.id}/members/#{user3.id}", user) - response.status.should == 200 - end - - it "should return 200 OK when the user was not member" do - expect { - delete api("/projects/#{project.id}/members/1000000", user) - }.to change { UsersProject.count }.by(0) - response.status.should == 200 - json_response['message'].should == "Access revoked" - json_response['id'].should == 1000000 - end - end - describe "GET /projects/:id/snippets" do before { snippet } -- cgit v1.2.3 From 548f070f0e36f76c3afb285668aaa460a6fb73cc Mon Sep 17 00:00:00 2001 From: Ciro Santillli Date: Mon, 17 Mar 2014 10:29:50 +0100 Subject: Show link to public projects for new users. --- app/controllers/dashboard_controller.rb | 2 ++ app/views/dashboard/_zero_authorized_projects.html.haml | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index a74e97ac253..233b91680f6 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -22,6 +22,8 @@ class DashboardController < ApplicationController @last_push = current_user.recent_push + @publicish_project_count = Project.publicish(current_user).count + respond_to do |format| format.html format.json { pager_json("events/_events", @events.count) } diff --git a/app/views/dashboard/_zero_authorized_projects.html.haml b/app/views/dashboard/_zero_authorized_projects.html.haml index bb62a1c24fc..e0993293eab 100644 --- a/app/views/dashboard/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/_zero_authorized_projects.html.haml @@ -34,3 +34,18 @@ = link_to new_group_path, class: "btn btn-new" do New group » +-if @publicish_project_count > 0 + %hr + %div + .dashboard-intro-icon + %i.icon-globe + %div + %p.slead + There are + %strong= @publicish_project_count + public projects on this server. + %br + Public projects are an easy way to allow everyone to have read-only access. + .link_holder + = link_to public_projects_path, class: "btn btn-new" do + Browse public projects » -- cgit v1.2.3 From 55e2f353d412537a58ff19a63a8cc3d5651d881f Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 17 Mar 2014 10:41:39 +0100 Subject: Link to blob instead of linking to wiki. --- app/helpers/gitlab_markdown_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index 7f72ab54838..685ef752d84 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -134,12 +134,12 @@ module GitlabMarkdownHelper end # Checks if the path exists in the repo - # eg. checks if doc/README.md exists, if it doesn't then it is a wiki link + # eg. checks if doc/README.md exists, if not then link to blob def path_with_ref(path, ref) if file_exists?(path) "#{local_path(path)}/#{correct_ref(ref)}" else - "wikis" + "blob/#{correct_ref(ref)}" end end -- cgit v1.2.3 From f04d5bfaf6afcdbc4e91a2fa3069a5438b7fa569 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 17 Mar 2014 11:27:59 +0100 Subject: Wiki will show relative links related to the wiki gollum repository. --- app/helpers/gitlab_markdown_helper.rb | 3 +-- lib/redcarpet/render/gitlab_html.rb | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index 685ef752d84..69425bc171d 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -63,8 +63,7 @@ module GitlabMarkdownHelper # project_path_with_namespace - namespace/projectname, eg. gitlabhq/gitlabhq # ref - name of the branch or reference, eg. stable # requested_path - path of request, eg. doc/api/README.md, used in special case when path is pointing to the .md file were the original request is coming from - # wiki - whether the markdown is from wiki or not - def create_relative_links(text, project, ref, requested_path, wiki = false) + def create_relative_links(text, project, ref, requested_path) @path_to_satellite = project.satellite.path project_path_with_namespace = project.path_with_namespace paths = extract_paths(text) diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb index 2e18b0592b5..86d8b69b0ef 100644 --- a/lib/redcarpet/render/gitlab_html.rb +++ b/lib/redcarpet/render/gitlab_html.rb @@ -46,8 +46,10 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML end def preprocess(full_document) - if @project - h.create_relative_links(full_document, @project, @ref, @request_path, is_wiki?) + if is_wiki? + full_document + elsif @project + h.create_relative_links(full_document, @project, @ref, @request_path) else full_document end -- cgit v1.2.3 From 3f818a3d58bbfcd009e9985abb835fb4de56cadf Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 17 Mar 2014 12:16:26 +0100 Subject: Update wiki tests. --- features/steps/project/markdown_render.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/features/steps/project/markdown_render.rb b/features/steps/project/markdown_render.rb index 8fbf2753aa7..c94de283069 100644 --- a/features/steps/project/markdown_render.rb +++ b/features/steps/project/markdown_render.rb @@ -203,7 +203,7 @@ class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps end And 'I add various links to the wiki page' do - fill_in "wiki[content]", with: "[test](test)\n[GitLab API doc](doc/api/README.md)\n[Rake tasks](doc/raketasks)\n" + fill_in "wiki[content]", with: "[test](test)\n[GitLab API doc](api)\n[Rake tasks](raketasks)\n" fill_in "wiki[message]", with: "Adding links to wiki" click_button "Create page" end @@ -242,8 +242,8 @@ class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps end Then 'I see Gitlab API document' do - current_path.should == project_blob_path(@project, "master/doc/api/README.md") - page.should have_content "Status codes" + current_path.should == project_wiki_path(@project, "api") + page.should have_content "Editing" end And 'I click on Rake tasks link' do @@ -251,9 +251,8 @@ class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps end Then 'I see Rake tasks directory' do - current_path.should == project_tree_path(@project, "master/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" + current_path.should == project_wiki_path(@project, "raketasks") + page.should have_content "Editing" end Given 'I go directory which contains README file' do -- cgit v1.2.3 From 656d9548bcfa315751fc01b3afb0ec14104e15a8 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 17 Mar 2014 13:04:18 +0100 Subject: Update markdown documentation, fix wiki spec. --- doc/markdown/markdown.md | 47 +++++++++++++++++++++++------ spec/helpers/gitlab_markdown_helper_spec.rb | 6 ---- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md index f49f09756ab..e7ebc613431 100644 --- a/doc/markdown/markdown.md +++ b/doc/markdown/markdown.md @@ -8,23 +8,38 @@ Table of Contents **[GitLab Flavored Markdown](#gitlab-flavored-markdown-gfm)** [Newlines](#newlines) + [Multiple underscores in words](#multiple-underscores-in-words) + [URL autolinking](#url-autolinking) + [Code and Syntax Highlighting](#code-and-syntax-highlighting) + [Emoji](#emoji) + [Special GitLab references](#special-gitlab-references) + **[Standard Markdown](#standard-markdown)** [Headers](#headers) + [Emphasis](#emphasis) + [Lists](#lists) + [Links](#links) + [Images](#images) + [Blockquotes](#blockquotes) + [Inline HTML](#inline-html) + [Horizontal Rule](#horizontal-rule) + [Line Breaks](#line-breaks) + [Tables](#tables) **[References](#references)** @@ -33,7 +48,8 @@ Table of Contents GitLab Flavored Markdown (GFM) ============================== -For GitLab we developed something we call "GitLab Flavored Markdown" (GFM). It extends the standard Markdown in a few significant ways to add some useful functionality. +For GitLab we developed something we call "GitLab Flavored Markdown" (GFM). +It extends the standard Markdown in a few significant ways to add some useful functionality. You can use GFM in @@ -51,16 +67,20 @@ Please see the [github-markup gem readme](https://github.com/gitlabhq/markup#mar Newlines -------- -The biggest difference that GFM introduces is in the handling of linebreaks. With traditional Markdown you can hard wrap paragraphs of text and they will be combined into a single paragraph. We find this to be the cause of a huge number of unintentional formatting errors. GFM treats newlines in paragraph-like content as real line breaks, which is probably what you intended. +GFM honors the markdown specification in how [paragraphs and line breaks are handled](http://daringfireball.net/projects/markdown/syntax#p). -The next paragraph contains two phrases separated by a single newline character: +A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines.: Roses are red Violets are blue + Sugar is sweet + Roses are red Violets are blue +Sugar is sweet + Multiple underscores in words ----------------------------- It is not reasonable to italicize just _part_ of a word, especially when you're dealing with code and names that often appear with multiple underscores. Therefore, GFM ignores multiple underscores in words. @@ -319,13 +339,13 @@ Strikethrough uses two tildes. ~~Scratch this.~~ ## Links -There are two ways to create links. +There are two ways to create links, inline-style and reference-style. [I'm an inline-style link](https://www.google.com) [I'm a reference-style link][Arbitrary case-insensitive reference text] - [I'm a relative reference to a repository file](../blob/master/LICENSE) + [I'm a relative reference to a repository file](LICENSE) [You can use numbers for reference-style link definitions][1] @@ -341,7 +361,7 @@ There are two ways to create links. [I'm a reference-style link][Arbitrary case-insensitive reference text] -[I'm a relative reference to a repository file](../blob/master/LICENSE) +[I'm a relative reference to a repository file](LICENSE) [You can use numbers for reference-style link definitions][1] @@ -353,6 +373,15 @@ Some text to show that the reference links can follow later. [1]: http://slashdot.org [link text itself]: http://www.reddit.com +**Note** + +Relative links do not allow referencing project files in a wiki page or wiki page in a project file. +The reason for this is that, in GitLab, wiki is always a separate git repository. For example: + +`[I'm a reference-style link][style]` + +will point the link to `wikis/style` when the link is inside of a wiki markdown file. + ## Images Here's our logo (hover to see the title text): @@ -365,15 +394,15 @@ Some text to show that the reference links can follow later. [logo]: assets/logo-white.png -Here's our logo (hover to see the title text): +Here's our logo: Inline-style: -![alt text](/assets/logo-white.png "Logo Title Text 1") +![alt text](/assets/logo-white.png) Reference-style: ![alt text][logo] -[logo]: /assets/logo-white.png "Logo Title Text 2" +[logo]: /assets/logo-white.png ## Blockquotes diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 7e98b7944f1..5bd16d1c16c 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -440,12 +440,6 @@ describe GitlabMarkdownHelper do markdown(actual).should match(expected) end - it "should handle wiki urls" do - actual = "[Link](test/link)\n" - expected = "

Link

\n" - markdown(actual).should match(expected) - end - it "should handle relative urls in reference links for a file in master" do actual = "[GitLab API doc][GitLab readme]\n [GitLab readme]: doc/api/README.md\n" expected = "

GitLab API doc

\n" -- cgit v1.2.3 From a91a6491bf3e74791ecf8dd1111d54435b8578cb Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 17 Mar 2014 14:33:21 +0200 Subject: Use new grape-entity gem with fixed nested entities Signed-off-by: Dmitriy Zaporozhets --- Gemfile | 3 ++- Gemfile.lock | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index dc7b60dd380..e3acf4a153d 100644 --- a/Gemfile +++ b/Gemfile @@ -48,7 +48,8 @@ gem "gitlab-linguist", "~> 3.0.0", require: "linguist" # API gem "grape", "~> 0.6.1" -gem "grape-entity", "~> 0.3.0" +# Replace with rubygems when nesteted entities get released +gem "grape-entity", "~> 0.4.1", ref: 'd904381c951e86250c3f44213b349a3dd8e83fb1', git: 'https://github.com/intridea/grape-entity.git' gem 'rack-cors', require: 'rack/cors' # Email validation diff --git a/Gemfile.lock b/Gemfile.lock index 615ad62112a..52d6ac31463 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,6 +5,15 @@ GIT specs: github-markup (0.7.6) +GIT + remote: https://github.com/intridea/grape-entity.git + revision: d904381c951e86250c3f44213b349a3dd8e83fb1 + ref: d904381c951e86250c3f44213b349a3dd8e83fb1 + specs: + grape-entity (0.4.1) + activesupport + multi_json (>= 1.3.2) + GEM remote: https://rubygems.org/ specs: @@ -206,9 +215,6 @@ GEM rack-accept rack-mount virtus (>= 1.0.0) - grape-entity (0.3.0) - activesupport - multi_json (>= 1.3.2) growl (1.0.3) guard (2.2.4) formatador (>= 0.2.4) @@ -596,7 +602,7 @@ DEPENDENCIES gitlab_omniauth-ldap (= 1.0.4) gon (~> 5.0.0) grape (~> 0.6.1) - grape-entity (~> 0.3.0) + grape-entity (~> 0.4.1)! growl guard-rspec guard-spinach -- cgit v1.2.3 From eea317795ea970f762a1331beba6fde20e7a8aeb Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 17 Mar 2014 14:33:41 +0200 Subject: Add current user permissions info to /api/projects/:id.json Signed-off-by: Dmitriy Zaporozhets --- lib/api/entities.rb | 24 +++++++++++++++++++++++- lib/api/projects.rb | 2 +- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 9c9c7fcd6ea..6413dd0abf5 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -44,7 +44,7 @@ module API expose :id, :description, :default_branch expose :public?, as: :public expose :visibility_level, :ssh_url_to_repo, :http_url_to_repo, :web_url - expose :owner, using: Entities::UserBasic + expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group } expose :name, :name_with_namespace expose :path, :path_with_namespace expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :snippets_enabled, :created_at, :last_activity_at @@ -175,5 +175,27 @@ module API class Namespace < Grape::Entity expose :id, :path, :kind end + + class ProjectAccess < Grape::Entity + expose :project_access, as: :access_level + expose :notification_level + end + + class GroupAccess < Grape::Entity + expose :group_access, as: :access_level + expose :notification_level + end + + class ProjectWithAccess < Project + expose :permissions do + expose :project_access, using: Entities::ProjectAccess do |project, options| + project.users_projects.find_by(user_id: options[:user].id) + end + + expose :group_access, using: Entities::GroupAccess do |project, options| + project.group.users_groups.find_by(user_id: options[:user].id) + end + end + end end end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 618a582a451..4d48d2194f8 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -48,7 +48,7 @@ module API # Example Request: # GET /projects/:id get ":id" do - present user_project, with: Entities::Project + present user_project, with: Entities::ProjectWithAccess, user: current_user end # Get a single project events -- cgit v1.2.3 From 0ea0e542a93d023fb582f21d89a937c5c32cac18 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 17 Mar 2014 14:35:50 +0200 Subject: Remove old entities Signed-off-by: Dmitriy Zaporozhets --- lib/api/entities.rb | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 6413dd0abf5..34657813cbd 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -58,18 +58,6 @@ module API end end - class TeamMember < UserBasic - expose :permission, as: :access_level do |user, options| - options[:user_team].user_team_user_relationships.find_by(user_id: user.id).permission - end - end - - class TeamProject < Project - expose :greatest_access, as: :greatest_access_level do |project, options| - options[:user_team].user_team_project_relationships.find_by(project_id: project.id).greatest_access - end - end - class Group < Grape::Entity expose :id, :name, :path, :owner_id end -- cgit v1.2.3 From 928b7f3bff82c614b8b6e68be8ed51707927a8c6 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 17 Mar 2014 15:14:27 +0200 Subject: Add tests for API project permissions info Signed-off-by: Dmitriy Zaporozhets --- lib/api/entities.rb | 4 +++- spec/requests/api/projects_spec.rb | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 34657813cbd..26c14276535 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -181,7 +181,9 @@ module API end expose :group_access, using: Entities::GroupAccess do |project, options| - project.group.users_groups.find_by(user_id: options[:user].id) + if project.group + project.group.users_groups.find_by(user_id: options[:user].id) + end end end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index b4b5f606eee..cb30c98b4d2 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -259,6 +259,7 @@ describe API::API do describe "GET /projects/:id" do before { project } + before { users_project } it "should return a project by id" do get api("/projects/#{project.id}", user) @@ -284,6 +285,28 @@ describe API::API do get api("/projects/#{project.id}", other_user) response.status.should == 404 end + + describe 'permissions' do + context 'personal project' do + before { get api("/projects/#{project.id}", user) } + + it { response.status.should == 200 } + it { json_response['permissions']["project_access"]["access_level"].should == Gitlab::Access::MASTER } + it { json_response['permissions']["group_access"].should be_nil } + end + + context 'group project' do + before do + project2 = create(:project, group: create(:group)) + project2.group.add_owner(user) + get api("/projects/#{project2.id}", user) + end + + it { response.status.should == 200 } + it { json_response['permissions']["project_access"].should be_nil } + it { json_response['permissions']["group_access"]["access_level"].should == Gitlab::Access::OWNER } + end + end end describe "GET /projects/:id/events" do -- cgit v1.2.3 From 86c76eccea1bf3cf6c58b4315e6a6cb29e058a18 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 17 Mar 2014 15:22:39 +0200 Subject: Add more api docs Signed-off-by: Dmitriy Zaporozhets --- doc/api/projects.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/api/projects.md b/doc/api/projects.md index e795298c672..6e82ddd9903 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -148,6 +148,16 @@ Parameters: "path": "diaspora", "updated_at": "2013-09-30T13: 46: 02Z" } + "permissions": { + "project_access": { + "access_level": 10, + "notification_level": 3 + }, + "group_access": { + "access_level": 50, + "notification_level": 3 + } + } } ``` -- cgit v1.2.3 From c02e3d441b6ef35bdbb4a45829f47369aa911690 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 17 Mar 2014 15:29:45 +0200 Subject: Fix tests Signed-off-by: Dmitriy Zaporozhets --- lib/api/entities.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 26c14276535..8b4519af2d1 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -132,7 +132,7 @@ module API end class MergeRequest < ProjectEntity - expose :target_branch, :source_branch, :title, :state, :upvotes, :downvotes + expose :target_branch, :source_branch, :title, :state, :upvotes, :downvotes, :description expose :author, :assignee, using: Entities::UserBasic expose :source_project_id, :target_project_id end -- cgit v1.2.3 From 67eb14d308bfb98d30e44f4e8efdcba60fe2786c Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 17 Mar 2014 14:36:20 +0100 Subject: We have html targets for paragraphs now. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c1788657b95..93dd88360a8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,7 +22,7 @@ Issues and merge requests should be in English and contain appropriate language ## Issue tracker -To get support for your particular problem please use the channels as detailed in the getting help section of [the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/). +To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/). The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious bugs or misbehavior in the latest [stable or development release of GitLab](MAINTENANCE.md). When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue. -- cgit v1.2.3 From 5e7e814e813da0ab9dcadd0c223a3aff6e89dfdd Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 17 Mar 2014 11:16:55 +0100 Subject: Drop UsersGroup orphans using `rails runner` --- lib/tasks/gitlab/check.rake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 467a91fbe86..78b154cbdd9 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -186,6 +186,10 @@ namespace :gitlab do print "Database contains orphaned UsersGroups? ... " if UsersGroup.where("user_id not in (select id from users)").count > 0 puts "yes".red + try_fixing_it( + "You can delete the orphaned records using something along the lines of:", + sudo_gitlab("bundle exec rails runner -e production 'UsersGroup.where(\"user_id NOT IN (SELECT id FROM users)\").delete_all'") + ) else puts "no".green end -- cgit v1.2.3 From de855e2420465e66009b9773bc2a928b73153841 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 17 Mar 2014 15:50:16 +0200 Subject: Default value for Snippet#private Signed-off-by: Dmitriy Zaporozhets --- app/models/snippet.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/snippet.rb b/app/models/snippet.rb index edc179b20fd..c1c9ba257f2 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -20,6 +20,8 @@ class Snippet < ActiveRecord::Base attr_accessible :title, :content, :file_name, :expires_at, :private + default_value_for :private, true + belongs_to :author, class_name: "User" has_many :notes, as: :noteable, dependent: :destroy -- cgit v1.2.3 From 70994c348dede58b6ed8da84b02465e4665dc305 Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 17 Mar 2014 14:55:56 +0100 Subject: Postgresql conversion script. --- doc/update/mysql-to-postgresql.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 doc/update/mysql-to-postgresql.md diff --git a/doc/update/mysql-to-postgresql.md b/doc/update/mysql-to-postgresql.md new file mode 100644 index 00000000000..9a324545eb0 --- /dev/null +++ b/doc/update/mysql-to-postgresql.md @@ -0,0 +1,9 @@ +# Use the shell commands below to convert a MySQL GitLab database to a PostgreSQL one. + +``` +git clone https://github.com/lanyrd/mysql-postgresql-converter.git +cd mysql-postgresql-converter +mysqldump --compatible=postgresql --default-character-set=utf8 -r databasename.mysql -u root gitlabhq_production +python db_converter.py databasename.mysql databasename.psql +psql -f databasename.psql -d gitlabhq_production +``` -- cgit v1.2.3 From 1c6e93edf9f3496903cd68510e9118405fd2b8e9 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 17 Mar 2014 16:33:29 +0100 Subject: Add change to changelog. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index dc49e759415..031536816a5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,7 @@ v 6.7.0 - Fix global search - Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.5) - Create and Update MR calls now support the description parameter (Greg Messner) + - Markdown relative links in the wiki link to wiki pages, markdown relative links in repositories link to files in the repository v 6.6.5 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) -- cgit v1.2.3 From 37192d5e184f73feebde9f571d34c6af2bbb8f7a Mon Sep 17 00:00:00 2001 From: "Jamey J. DeOrio" Date: Mon, 6 Jan 2014 10:36:34 -0800 Subject: Add more descriptive line for resolving sqlite error during check --- lib/tasks/gitlab/check.rake | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index c2e6cd1be78..054f1c72589 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -65,6 +65,7 @@ namespace :gitlab do puts "no".green else puts "yes".red + puts "Please fix this by removing the SQLite entry from the database.yml".blue for_more_information( "https://github.com/gitlabhq/gitlabhq/wiki/Migrate-from-SQLite-to-MySQL", see_database_guide -- cgit v1.2.3 From a740e2d6d16271c2e3d06252e35e65b10d002834 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Tue, 18 Mar 2014 12:25:49 +0100 Subject: Do not allow password reset for ldap user. --- app/controllers/passwords_controller.rb | 18 ++++++++++++++++++ config/routes.rb | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 app/controllers/passwords_controller.rb diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb new file mode 100644 index 00000000000..988ede3007b --- /dev/null +++ b/app/controllers/passwords_controller.rb @@ -0,0 +1,18 @@ +class PasswordsController < Devise::PasswordsController + + def create + email = resource_params[:email] + resource_found = resource_class.find_by_email(email) + if resource_found && resource_found.ldap_user? + flash[:alert] = "Cannot reset password for LDAP user." + respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name)) and return + end + + self.resource = resource_class.send_reset_password_instructions(resource_params) + if successfully_sent?(resource) + respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name)) + else + respond_with(resource) + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 628d1f631bc..709b66d3e06 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -167,7 +167,7 @@ Gitlab::Application.routes.draw do resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create] - devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations } + devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords} # # Project Area -- cgit v1.2.3 From 257aa851d27076453b2dcfee2cc77a75f0e05acf Mon Sep 17 00:00:00 2001 From: dosire Date: Tue, 18 Mar 2014 16:24:49 +0100 Subject: Deploy key needed documentation. --- doc/ssh/deploy_keys.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 doc/ssh/deploy_keys.md diff --git a/doc/ssh/deploy_keys.md b/doc/ssh/deploy_keys.md new file mode 100644 index 00000000000..245d71ed9a5 --- /dev/null +++ b/doc/ssh/deploy_keys.md @@ -0,0 +1,7 @@ +Deploy keys allow read-only access one or multiple projects with a single SSH key. + +This is really useful for cloning repositories to your Continuous Integration (CI) server. By using a deploy keys you don't have to setup a dummy user account. + +If you are a project master or owner you can add a deploy key in the project settings under the section Deploy Keys. Press the 'New Deploy Key' button and upload a public ssh key. After this the machine that uses the corresponding private key has read-only access to the project. + +You can't add the same deploy key twice with the 'New Deploy Key' option. If you want to add the same key to another project please enable it in the list that says 'Deploy keys from projects available to you'. You need to be the owner of the deploy key to see it in this list. -- cgit v1.2.3 From d09f5796bff136c463edf45f621fab6cfeb660b6 Mon Sep 17 00:00:00 2001 From: dosire Date: Tue, 18 Mar 2014 16:25:54 +0100 Subject: Split up the lines for Jacob. --- doc/ssh/deploy_keys.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/ssh/deploy_keys.md b/doc/ssh/deploy_keys.md index 245d71ed9a5..56fe98bb101 100644 --- a/doc/ssh/deploy_keys.md +++ b/doc/ssh/deploy_keys.md @@ -1,7 +1,12 @@ Deploy keys allow read-only access one or multiple projects with a single SSH key. -This is really useful for cloning repositories to your Continuous Integration (CI) server. By using a deploy keys you don't have to setup a dummy user account. +This is really useful for cloning repositories to your Continuous Integration (CI) server. +By using a deploy keys you don't have to setup a dummy user account. -If you are a project master or owner you can add a deploy key in the project settings under the section Deploy Keys. Press the 'New Deploy Key' button and upload a public ssh key. After this the machine that uses the corresponding private key has read-only access to the project. +If you are a project master or owner you can add a deploy key in the project settings under the section Deploy Keys. +Press the 'New Deploy Key' button and upload a public ssh key. +After this the machine that uses the corresponding private key has read-only access to the project. -You can't add the same deploy key twice with the 'New Deploy Key' option. If you want to add the same key to another project please enable it in the list that says 'Deploy keys from projects available to you'. You need to be the owner of the deploy key to see it in this list. +You can't add the same deploy key twice with the 'New Deploy Key' option. +If you want to add the same key to another project please enable it in the list that says 'Deploy keys from projects available to you'. +You need to be the owner of the deploy key to see it in this list. -- cgit v1.2.3 From e3fc01b3eaa13a51aef380dc21f1e7d259706227 Mon Sep 17 00:00:00 2001 From: Federico Ravasio Date: Tue, 18 Mar 2014 18:27:03 +0100 Subject: Added Slack service integration. --- CHANGELOG | 1 + Gemfile | 3 + Gemfile.lock | 2 + app/models/project.rb | 3 +- app/models/project_services/slack_message.rb | 95 ++++++++++++++++++++++++++++ app/models/project_services/slack_service.rb | 67 ++++++++++++++++++++ features/project/service.feature | 6 ++ features/steps/project/services.rb | 18 ++++++ spec/models/project_spec.rb | 1 + spec/models/slack_message_spec.rb | 56 ++++++++++++++++ spec/models/slack_service_spec.rb | 69 ++++++++++++++++++++ 11 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 app/models/project_services/slack_message.rb create mode 100644 app/models/project_services/slack_service.rb create mode 100644 spec/models/slack_message_spec.rb create mode 100644 spec/models/slack_service_spec.rb diff --git a/CHANGELOG b/CHANGELOG index 031536816a5..7d61fef39a4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -24,6 +24,7 @@ v 6.7.0 - Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.5) - Create and Update MR calls now support the description parameter (Greg Messner) - Markdown relative links in the wiki link to wiki pages, markdown relative links in repositories link to files in the repository + - Added Slack service integration (Federico Ravasio) v 6.6.5 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) diff --git a/Gemfile b/Gemfile index e3acf4a153d..6a587d1d279 100644 --- a/Gemfile +++ b/Gemfile @@ -132,6 +132,9 @@ gem "gitlab-flowdock-git-hook", "~> 0.4.2" # Gemnasium integration gem "gemnasium-gitlab-service", "~> 0.2" +# Slack integration +gem "slack-notifier", "~> 0.2.0" + # d3 gem "d3_rails", "~> 3.1.4" diff --git a/Gemfile.lock b/Gemfile.lock index 52d6ac31463..de1ef59712e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -468,6 +468,7 @@ GEM rack-protection (~> 1.4) tilt (~> 1.3, >= 1.3.4) six (0.2.0) + slack-notifier (0.2.0) slim (2.0.2) temple (~> 0.6.6) tilt (>= 1.3.3, < 2.1) @@ -652,6 +653,7 @@ DEPENDENCIES simplecov sinatra six + slack-notifier (~> 0.2.0) slim spinach-rails spork (~> 1.0rc) diff --git a/app/models/project.rb b/app/models/project.rb index 7d7edc45739..769ab217625 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -56,6 +56,7 @@ class Project < ActiveRecord::Base has_one :flowdock_service, dependent: :destroy has_one :assembla_service, dependent: :destroy has_one :gemnasium_service, dependent: :destroy + has_one :slack_service, dependent: :destroy has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" has_one :forked_from_project, through: :forked_project_link # Merge Requests for target project should be removed with it @@ -304,7 +305,7 @@ class Project < ActiveRecord::Base end def available_services_names - %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium) + %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack) end def gitlab_ci? diff --git a/app/models/project_services/slack_message.rb b/app/models/project_services/slack_message.rb new file mode 100644 index 00000000000..b2b8d6fed7a --- /dev/null +++ b/app/models/project_services/slack_message.rb @@ -0,0 +1,95 @@ +require 'slack-notifier' + +class SlackMessage + def initialize(params) + @after = params.fetch(:after) + @before = params.fetch(:before) + @commits = params.fetch(:commits, []) + @project_name = params.fetch(:project_name) + @project_url = params.fetch(:project_url) + @ref = params.fetch(:ref).gsub('refs/heads/', '') + @username = params.fetch(:user_name) + end + + def compose + format(message) + end + + private + + attr_reader :after + attr_reader :before + attr_reader :commits + attr_reader :project_name + attr_reader :project_url + attr_reader :ref + attr_reader :username + + def message + if new_branch? + new_branch_message + elsif removed_branch? + removed_branch_message + else + push_message << commit_messages + end + end + + def format(string) + Slack::Notifier::LinkFormatter.format(string) + end + + def new_branch_message + "#{username} pushed new branch #{branch_link} to #{project_link}" + end + + def removed_branch_message + "#{username} removed branch #{ref} from #{project_link}" + end + + def push_message + "#{username} pushed to branch #{branch_link} of #{project_link} (#{compare_link})" + end + + def commit_messages + commits.each_with_object('') do |commit, str| + str << compose_commit_message(commit) + end + end + + def compose_commit_message(commit) + id = commit.fetch(:id)[0..5] + message = commit.fetch(:message) + url = commit.fetch(:url) + + "\n - #{message} ([#{id}](#{url}))" + end + + def new_branch? + before =~ /000000/ + end + + def removed_branch? + after =~ /000000/ + end + + def branch_url + "#{project_url}/commits/#{ref}" + end + + def compare_url + "#{project_url}/compare/#{before}...#{after}" + end + + def branch_link + "[#{ref}](#{branch_url})" + end + + def project_link + "[#{project_name}](#{project_url})" + end + + def compare_link + "[Compare changes](#{compare_url})" + end +end diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb new file mode 100644 index 00000000000..27648acf6d0 --- /dev/null +++ b/app/models/project_services/slack_service.rb @@ -0,0 +1,67 @@ +# == Schema Information +# +# Table name: services +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# token :string(255) +# project_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# active :boolean default(FALSE), not null +# project_url :string(255) +# subdomain :string(255) +# room :string(255) +# api_key :string(255) +# + +class SlackService < Service + attr_accessible :room + attr_accessible :subdomain + + validates :room, presence: true, if: :activated? + validates :subdomain, presence: true, if: :activated? + validates :token, presence: true, if: :activated? + + def title + 'Slack' + end + + def description + 'A team communication tool for the 21st century' + end + + def to_param + 'slack' + end + + def fields + [ + { type: 'text', name: 'subdomain', placeholder: '' }, + { type: 'text', name: 'token', placeholder: '' }, + { type: 'text', name: 'room', placeholder: '' }, + ] + end + + def execute(push_data) + message = SlackMessage.new(push_data.merge( + project_url: project_url, + project_name: project_name + )) + + notifier = Slack::Notifier.new(subdomain, token) + notifier.channel = room + notifier.ping(message.compose) + end + + private + + def project_name + project.name_with_namespace.gsub(/\s/, '') + end + + def project_url + project.web_url + end +end diff --git a/features/project/service.feature b/features/project/service.feature index 46b983e8f9a..a5af065c9e7 100644 --- a/features/project/service.feature +++ b/features/project/service.feature @@ -37,6 +37,12 @@ Feature: Project Services And I fill Assembla settings Then I should see Assembla service settings saved + Scenario: Activate Slack service + When I visit project "Shop" services page + And I click Slack service link + And I fill Slack settings + Then I should see Slack service settings saved + Scenario: Activate email on push service When I visit project "Shop" services page And I click email on push service link diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb index 54b3f18e084..0594a08a5e7 100644 --- a/features/steps/project/services.rb +++ b/features/steps/project/services.rb @@ -100,4 +100,22 @@ class ProjectServices < Spinach::FeatureSteps step 'I should see email on push service settings saved' do find_field('Recipients').value.should == 'qa@company.name' end + + step 'I click Slack service link' do + click_link 'Slack' + end + + step 'I fill Slack settings' do + check 'Active' + fill_in 'Subdomain', with: 'gitlab' + fill_in 'Room', with: '#gitlab' + fill_in 'Token', with: 'verySecret' + click_button 'Save' + end + + step 'I should see Slack service settings saved' do + find_field('Subdomain').value.should == 'gitlab' + find_field('Room').value.should == '#gitlab' + find_field('Token').value.should == 'verySecret' + end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 6bae5951b7b..839350bafbf 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -47,6 +47,7 @@ describe Project do it { should have_many(:hooks).dependent(:destroy) } it { should have_many(:protected_branches).dependent(:destroy) } it { should have_one(:forked_project_link).dependent(:destroy) } + it { should have_one(:slack_service).dependent(:destroy) } end describe "Mass assignment" do diff --git a/spec/models/slack_message_spec.rb b/spec/models/slack_message_spec.rb new file mode 100644 index 00000000000..b39cd4edf82 --- /dev/null +++ b/spec/models/slack_message_spec.rb @@ -0,0 +1,56 @@ +require_relative '../../app/models/project_services/slack_message' + +describe SlackMessage do + subject { SlackMessage.new(args) } + + let(:args) { + { + after: 'after', + before: 'before', + project_name: 'project_name', + ref: 'refs/heads/master', + user_name: 'user_name', + project_url: 'url' + } + } + + context 'push' do + before do + args[:commits] = [ + { message: 'message1', url: 'url1', id: 'abcdefghi' }, + { message: 'message2', url: 'url2', id: '123456789' }, + ] + end + + it 'returns a message regarding pushes' do + subject.compose.should == + 'user_name pushed to branch of ' << + ' ()' << + "\n - message1 ()" << + "\n - message2 ()" + end + end + + context 'new branch' do + before do + args[:before] = '000000' + end + + it 'returns a message regarding a new branch' do + subject.compose.should == + 'user_name pushed new branch to ' << + '' + end + end + + context 'removed branch' do + before do + args[:after] = '000000' + end + + it 'returns a message regarding a removed branch' do + subject.compose.should == + 'user_name removed branch master from ' + end + end +end diff --git a/spec/models/slack_service_spec.rb b/spec/models/slack_service_spec.rb new file mode 100644 index 00000000000..387455cb25e --- /dev/null +++ b/spec/models/slack_service_spec.rb @@ -0,0 +1,69 @@ +# == Schema Information +# +# Table name: services +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# token :string(255) +# project_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# active :boolean default(FALSE), not null +# project_url :string(255) +# subdomain :string(255) +# room :string(255) +# api_key :string(255) +# + +require 'spec_helper' + +describe SlackService do + describe "Associations" do + it { should belong_to :project } + it { should have_one :service_hook } + end + + describe "Validations" do + context "active" do + before do + subject.active = true + end + + it { should validate_presence_of :room } + it { should validate_presence_of :subdomain } + it { should validate_presence_of :token } + end + end + + describe "Execute" do + let(:slack) { SlackService.new } + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:sample_data) { GitPushService.new.sample_data(project, user) } + let(:subdomain) { 'gitlab' } + let(:token) { 'verySecret' } + let(:api_url) { + "https://#{subdomain}.slack.com/services/hooks/incoming-webhook?token=#{token}" + } + + before do + slack.stub( + project: project, + project_id: project.id, + room: '#gitlab', + service_hook: true, + subdomain: subdomain, + token: token + ) + + WebMock.stub_request(:post, api_url) + end + + it "should call Slack API" do + slack.execute(sample_data) + + WebMock.should have_requested(:post, api_url).once + end + end +end -- cgit v1.2.3 From b6778cb2ea0888b6b0e20584366518e2a128d1a5 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 18 Mar 2014 22:21:25 -0400 Subject: Fix travis setup --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d7c65286cfe..6bff3752b2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,10 +19,10 @@ rvm: services: - redis-server before_script: - - "bundle exec rake db:setup" - - "bundle exec rake db:seed_fu" - "cp config/database.yml.$DB config/database.yml" - "cp config/gitlab.yml.example config/gitlab.yml" + - "bundle exec rake db:setup" + - "bundle exec rake db:seed_fu" script: "bundle exec rake $TASK --trace" notifications: email: false -- cgit v1.2.3 From 53d3294d1de6a3ded84532c1874ca48910fd69b0 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 18 Mar 2014 21:32:40 -0400 Subject: Speed up features/notes_on_merge_requests_spec This spec featured the slowest tests in the entire suite. After some debugging, the cause was found to be the large commit diff generated by comparing the stable and master branches. To fix this, the seed repository was modified to create a simple branch off of master that consists of three simple commits and minor changes. The spec was then updated to compare master to this branch instead of stable. The result is a spec group that runs in under 30 seconds, down from about 90. --- spec/factories.rb | 6 +++- spec/features/notes_on_merge_requests_spec.rb | 49 +++++++++++--------------- spec/seed_project.tar.gz | Bin 9789938 -> 9769010 bytes 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/spec/factories.rb b/spec/factories.rb index 7fc2b7c5e97..373c2a5acff 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -146,6 +146,11 @@ FactoryGirl.define do state :reopened end + trait :simple do + source_branch "simple_merge_request" + target_branch "master" + end + factory :closed_merge_request, traits: [:closed] factory :reopened_merge_request, traits: [:reopened] factory :merge_request_with_diffs, traits: [:with_diffs] @@ -161,7 +166,6 @@ FactoryGirl.define do factory :note_on_issue, traits: [:on_issue], aliases: [:votable_note] factory :note_on_merge_request, traits: [:on_merge_request] factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff] - factory :note_on_merge_request_with_attachment, traits: [:on_merge_request, :with_attachment] trait :on_commit do project factory: :project diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb index a3d8c462bf6..25a86b11fa9 100644 --- a/spec/features/notes_on_merge_requests_spec.rb +++ b/spec/features/notes_on_merge_requests_spec.rb @@ -1,14 +1,12 @@ require 'spec_helper' describe "On a merge request", js: true do - let!(:project) { create(:project) } - let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) } - let!(:note) { create(:note_on_merge_request_with_attachment, project: project) } + let!(:merge_request) { create(:merge_request, :simple) } + let!(:project) { merge_request.source_project } + let!(:note) { create(:note_on_merge_request, :with_attachment, project: project) } before do - login_as :user - project.team << [@user, :master] - + login_as :admin visit project_merge_request_path(project, merge_request) end @@ -134,22 +132,20 @@ describe "On a merge request", js: true do end end -describe "On a merge request diff", js: true, focus: true do - let!(:project) { create(:project) } - let!(:merge_request) { create(:merge_request_with_diffs, source_project: project, target_project: project) } +describe "On a merge request diff", js: true do + let(:merge_request) { create(:merge_request, :with_diffs, :simple) } + let(:project) { merge_request.source_project } before do - login_as :user - project.team << [@user, :master] + login_as :admin visit diffs_project_merge_request_path(project, merge_request) end - subject { page } describe "when adding a note" do before do - find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185"]').click + find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7"]').click end describe "the notes holder" do @@ -160,13 +156,13 @@ describe "On a merge request diff", js: true, focus: true do describe "the note form" do it "shouldn't add a second form for same row" do - find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185"]').click + find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7"]').click - should have_css("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185'] + .js-temp-notes-holder form", count: 1) + should have_css("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7'] + .js-temp-notes-holder form", count: 1) end it "should be removed when canceled" do - within(".diff-file form[rel$='4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185']") do + within(".diff-file form[rel$='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7']") do find(".js-close-discussion-note-form").trigger("click") end @@ -176,12 +172,9 @@ describe "On a merge request diff", js: true, focus: true do end describe "with muliple note forms" do - let!(:project) { create(:project) } - let!(:merge_request) { create(:merge_request_with_diffs, source_project: project, target_project: project) } - before do - find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185"]').click - find('a[data-line-code="342e16cbbd482ac2047dc679b2749d248cc1428f_18_17"]').click + find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7"]').click + find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_10_10"]').click end it { should have_css(".js-temp-notes-holder", count: 2) } @@ -189,12 +182,12 @@ describe "On a merge request diff", js: true, focus: true do describe "previewing them separately" do before do # add two separate texts and trigger previews on both - within("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185'] + .js-temp-notes-holder") do - fill_in "note[note]", with: "One comment on line 185" + within("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7'] + .js-temp-notes-holder") do + fill_in "note[note]", with: "One comment on line 7" find(".js-note-preview-button").trigger("click") end - within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do - fill_in "note[note]", with: "Another comment on line 17" + within("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_10_10'] + .js-temp-notes-holder") do + fill_in "note[note]", with: "Another comment on line 10" find(".js-note-preview-button").trigger("click") end end @@ -202,14 +195,14 @@ describe "On a merge request diff", js: true, focus: true do describe "posting a note" do before do - within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do - fill_in "note[note]", with: "Another comment on line 17" + within("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_10_10'] + .js-temp-notes-holder") do + fill_in "note[note]", with: "Another comment on line 10" click_button("Add Comment") end end it 'should be added as discussion' do - should have_content("Another comment on line 17") + should have_content("Another comment on line 10") should have_css(".notes_holder") should have_css(".notes_holder .note", count: 1) should have_link("Reply") diff --git a/spec/seed_project.tar.gz b/spec/seed_project.tar.gz index 92b9587e3f7..8d32a927da8 100644 Binary files a/spec/seed_project.tar.gz and b/spec/seed_project.tar.gz differ -- cgit v1.2.3 From a90574fab290233225375b1c9e9c232b0e540b52 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 19 Mar 2014 03:55:59 -0400 Subject: Speed up finders/merge_requests_finder_spec Uses the :simple merge request factory trait introduced by d166e70; cuts execution time of this spec in half. --- spec/finders/merge_requests_finder_spec.rb | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb index 76f9e753dd2..0bd2ccafcc1 100644 --- a/spec/finders/merge_requests_finder_spec.rb +++ b/spec/finders/merge_requests_finder_spec.rb @@ -1,13 +1,15 @@ require 'spec_helper' describe MergeRequestsFinder do - let(:user) { create :user } + let(:user) { create :user } let(:user2) { create :user } + let(:project1) { create(:project) } let(:project2) { create(:project) } - let(:merge_request1) { create(:merge_request, author: user, source_project: project1, target_project: project2) } - let(:merge_request2) { create(:merge_request, author: user, source_project: project2, target_project: project1) } - let(:merge_request3) { create(:merge_request, author: user, source_project: project2, target_project: project2) } + + let!(:merge_request1) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2) } + let!(:merge_request2) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1) } + let!(:merge_request3) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project2) } before do project1.team << [user, :master] @@ -15,13 +17,7 @@ describe MergeRequestsFinder do project2.team << [user2, :developer] end - describe :execute do - before :each do - merge_request1 - merge_request2 - merge_request3 - end - + describe "#execute" do it 'should filter by scope' do params = { scope: 'authored', state: 'opened' } merge_requests = MergeRequestsFinder.new.execute(user, params) -- cgit v1.2.3 From 65d634706cf833fc4b0b2f263f9d8fb35219858e Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 19 Mar 2014 05:14:27 -0400 Subject: Add public/private/internal traits to :project Factory --- spec/factories.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/factories.rb b/spec/factories.rb index 7fc2b7c5e97..adde72d2e1e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -32,6 +32,18 @@ FactoryGirl.define do path { name.downcase.gsub(/\s/, '_') } namespace creator + + trait :public do + visibility_level Gitlab::VisibilityLevel::PUBLIC + end + + trait :internal do + visibility_level Gitlab::VisibilityLevel::INTERNAL + end + + trait :private do + visibility_level Gitlab::VisibilityLevel::PRIVATE + end end # Generates a test repository from the repository stored under `spec/seed_project.tar.gz`. -- cgit v1.2.3 From 1897fb00b8d804cffa40da074f83575489beddb0 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 19 Mar 2014 05:15:24 -0400 Subject: Make use of project factory traits --- features/steps/project/redirects.rb | 2 +- features/steps/public/projects.rb | 2 +- features/steps/shared/project.rb | 8 +++--- .../security/group/internal_group_access_spec.rb | 2 +- .../security/group/mixed_group_access_spec.rb | 4 +-- .../security/group/public_group_access_spec.rb | 2 +- .../security/project/internal_access_spec.rb | 7 +---- spec/finders/projects_finder_spec.rb | 8 +++--- spec/requests/api/projects_spec.rb | 28 +++++++++--------- spec/services/search_service_spec.rb | 33 +++++++++------------- 10 files changed, 42 insertions(+), 54 deletions(-) diff --git a/features/steps/project/redirects.rb b/features/steps/project/redirects.rb index 76ffea1bb6f..cfa4ce82be3 100644 --- a/features/steps/project/redirects.rb +++ b/features/steps/project/redirects.rb @@ -4,7 +4,7 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps include SharedProject step 'public project "Community"' do - create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC + create :project, :public, name: 'Community' end step 'private project "Enterprise"' do diff --git a/features/steps/public/projects.rb b/features/steps/public/projects.rb index eb1d235f435..7c7311bb91c 100644 --- a/features/steps/public/projects.rb +++ b/features/steps/public/projects.rb @@ -4,7 +4,7 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps include SharedProject step 'public empty project "Empty Public Project"' do - create :empty_project, name: 'Empty Public Project', visibility_level: Gitlab::VisibilityLevel::PUBLIC + create :empty_project, :public, name: 'Empty Public Project' end step 'I should see project "Empty Public Project"' do diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index f35beab8af2..f8cb753b78f 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -79,7 +79,7 @@ module SharedProject end step 'internal project "Internal"' do - create :project, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL + create :project, :internal, name: 'Internal' end step 'I should see project "Internal"' do @@ -91,7 +91,7 @@ module SharedProject end step 'public project "Community"' do - create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC + create :project, :public, name: 'Community' end step 'I should see project "Community"' do @@ -112,14 +112,14 @@ module SharedProject step '"John Doe" is authorized to internal project "Internal"' do user = user_exists("John Doe", username: "john_doe") project = Project.find_by(name: "Internal") - project ||= create :project, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL + project ||= create :project, :internal, name: 'Internal' project.team << [user, :master] end step '"John Doe" is authorized to public project "Community"' do user = user_exists("John Doe", username: "john_doe") project = Project.find_by(name: "Community") - project ||= create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC + project ||= create :project, :public, name: 'Community' project.team << [user, :master] end end diff --git a/spec/features/security/group/internal_group_access_spec.rb b/spec/features/security/group/internal_group_access_spec.rb index 0c354f02456..79a6aee41b5 100644 --- a/spec/features/security/group/internal_group_access_spec.rb +++ b/spec/features/security/group/internal_group_access_spec.rb @@ -16,7 +16,7 @@ describe "Group with internal project access" do group.add_user(reporter, Gitlab::Access::REPORTER) group.add_user(guest, Gitlab::Access::GUEST) - create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::INTERNAL) + create(:project, :internal, group: group) end describe "GET /groups/:path" do diff --git a/spec/features/security/group/mixed_group_access_spec.rb b/spec/features/security/group/mixed_group_access_spec.rb index 82e816e388a..028cd32d2bb 100644 --- a/spec/features/security/group/mixed_group_access_spec.rb +++ b/spec/features/security/group/mixed_group_access_spec.rb @@ -16,8 +16,8 @@ describe "Group access" do group.add_user(reporter, Gitlab::Access::REPORTER) group.add_user(guest, Gitlab::Access::GUEST) - create(:project, path: "internal_project", group: group, visibility_level: Gitlab::VisibilityLevel::INTERNAL) - create(:project, path: "public_project", group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create(:project, :internal, path: "internal_project", group: group) + create(:project, :public, path: "public_project", group: group) end describe "GET /groups/:path" do diff --git a/spec/features/security/group/public_group_access_spec.rb b/spec/features/security/group/public_group_access_spec.rb index a9c0afbb60f..f0ed7649eb5 100644 --- a/spec/features/security/group/public_group_access_spec.rb +++ b/spec/features/security/group/public_group_access_spec.rb @@ -16,7 +16,7 @@ describe "Group with public project access" do group.add_user(reporter, Gitlab::Access::REPORTER) group.add_user(guest, Gitlab::Access::GUEST) - create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) + create(:project, :public, group: group) end describe "GET /groups/:path" do diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb index 8bb1e259efa..152cf66dcfd 100644 --- a/spec/features/security/project/internal_access_spec.rb +++ b/spec/features/security/project/internal_access_spec.rb @@ -1,23 +1,18 @@ require 'spec_helper' describe "Internal Project Access" do - let(:project) { create(:project) } + let(:project) { create(:project, :internal) } let(:master) { create(:user) } let(:guest) { create(:user) } let(:reporter) { create(:user) } before do - # internal project - project.visibility_level = Gitlab::VisibilityLevel::INTERNAL - project.save! - # full access project.team << [master, :master] # readonly project.team << [reporter, :reporter] - end describe "Project should be internal" do diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb index cc6ee82ab75..6e3ae4d615b 100644 --- a/spec/finders/projects_finder_spec.rb +++ b/spec/finders/projects_finder_spec.rb @@ -4,10 +4,10 @@ describe ProjectsFinder do let(:user) { create :user } let(:group) { create :group } - let(:project1) { create(:empty_project, group: group, visibility_level: Project::PUBLIC) } - let(:project2) { create(:empty_project, group: group, visibility_level: Project::INTERNAL) } - let(:project3) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) } - let(:project4) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) } + let(:project1) { create(:empty_project, :public, group: group) } + let(:project2) { create(:empty_project, :internal, group: group) } + let(:project3) { create(:empty_project, :private, group: group) } + let(:project4) { create(:empty_project, :private, group: group) } context 'non authenticated' do subject { ProjectsFinder.new.execute(nil, group: group) } diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index cb30c98b4d2..149c5bffcda 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -133,7 +133,7 @@ describe API::API do end it "should set a project as public" do - project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PUBLIC }) + project = attributes_for(:project, :public) post api("/projects", user), project json_response['public'].should be_true json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC @@ -147,21 +147,21 @@ describe API::API do end it "should set a project as internal" do - project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::INTERNAL }) + project = attributes_for(:project, :internal) post api("/projects", user), project json_response['public'].should be_false json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL end it "should set a project as internal overriding :public" do - project = attributes_for(:project, { public: true, visibility_level: Gitlab::VisibilityLevel::INTERNAL }) + project = attributes_for(:project, :internal, { public: true }) post api("/projects", user), project json_response['public'].should be_false json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL end it "should set a project as private" do - project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PRIVATE }) + project = attributes_for(:project, :private) post api("/projects", user), project json_response['public'].should be_false json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE @@ -215,7 +215,7 @@ describe API::API do end it "should set a project as public" do - project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PUBLIC }) + project = attributes_for(:project, :public) post api("/projects/user/#{user.id}", admin), project json_response['public'].should be_true json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC @@ -229,21 +229,21 @@ describe API::API do end it "should set a project as internal" do - project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::INTERNAL }) + project = attributes_for(:project, :internal) post api("/projects/user/#{user.id}", admin), project json_response['public'].should be_false json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL end it "should set a project as internal overriding :public" do - project = attributes_for(:project, { public: true, visibility_level: Gitlab::VisibilityLevel::INTERNAL }) + project = attributes_for(:project, :internal, { public: true }) post api("/projects/user/#{user.id}", admin), project json_response['public'].should be_false json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL end it "should set a project as private" do - project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PRIVATE }) + project = attributes_for(:project, :private) post api("/projects/user/#{user.id}", admin), project json_response['public'].should be_false json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE @@ -490,10 +490,10 @@ describe API::API do describe :fork_admin do let(:project_fork_target) { create(:project) } - let(:project_fork_source) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let(:project_fork_source) { create(:project, :public) } describe "POST /projects/:id/fork/:forked_from_id" do - let(:new_project_fork_source) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let(:new_project_fork_source) { create(:project, :public) } it "shouldn't available for non admin users" do post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user) @@ -562,10 +562,10 @@ describe API::API do let!(:post) { create(:empty_project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) } let!(:pre_post) { create(:empty_project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) } let!(:unfound) { create(:empty_project, name: 'unfound', creator_id: user.id, namespace: user.namespace) } - let!(:internal) { create(:empty_project, name: "internal #{query}", visibility_level: Gitlab::VisibilityLevel::INTERNAL) } - let!(:unfound_internal) { create(:empty_project, name: 'unfound internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL) } - let!(:public) { create(:empty_project, name: "public #{query}", visibility_level: Gitlab::VisibilityLevel::PUBLIC) } - let!(:unfound_public) { create(:empty_project, name: 'unfound public', visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let!(:internal) { create(:empty_project, :internal, name: "internal #{query}") } + let!(:unfound_internal) { create(:empty_project, :internal, name: 'unfound internal') } + let!(:public) { create(:empty_project, :public, name: "public #{query}") } + let!(:unfound_public) { create(:empty_project, :public, name: 'unfound public') } context "when unauthenticated" do it "should return authentication error" do diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb index 457cb3c0ca3..b467282a5d6 100644 --- a/spec/services/search_service_spec.rb +++ b/spec/services/search_service_spec.rb @@ -1,28 +1,26 @@ require 'spec_helper' describe 'Search::GlobalService' do - let(:found_namespace) { create(:namespace, name: 'searchable namespace', path:'another_thing') } let(:user) { create(:user, namespace: found_namespace) } - let!(:found_project) { create(:project, name: 'searchable_project', creator_id: user.id, namespace: found_namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) } + let(:public_user) { create(:user, namespace: public_namespace) } + let(:internal_user) { create(:user, namespace: internal_namespace) } + let(:found_namespace) { create(:namespace, name: 'searchable namespace', path:'another_thing') } let(:unfound_namespace) { create(:namespace, name: 'unfound namespace', path: 'yet_something_else') } - let!(:unfound_project) { create(:project, name: 'unfound_project', creator_id: user.id, namespace: unfound_namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) } + let(:internal_namespace) { create(:namespace, name: 'searchable internal namespace', path: 'something_internal') } + let(:public_namespace) { create(:namespace, name: 'searchable public namespace', path: 'something_public') } - let(:internal_namespace) { create(:namespace, path: 'something_internal',name: 'searchable internal namespace') } - let(:internal_user) { create(:user, namespace: internal_namespace) } - let!(:internal_project) { create(:project, name: 'searchable_internal_project', creator_id: internal_user.id, namespace: internal_namespace, visibility_level: Gitlab::VisibilityLevel::INTERNAL) } - - let(:public_namespace) { create(:namespace, path: 'something_public',name: 'searchable public namespace') } - let(:public_user) { create(:user, namespace: public_namespace) } - let!(:public_project) { create(:project, name: 'searchable_public_project', creator_id: public_user.id, namespace: public_namespace, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let!(:found_project) { create(:project, :private, name: 'searchable_project', creator_id: user.id, namespace: found_namespace) } + let!(:unfound_project) { create(:project, :private, name: 'unfound_project', creator_id: user.id, namespace: unfound_namespace) } + let!(:internal_project) { create(:project, :internal, name: 'searchable_internal_project', creator_id: internal_user.id, namespace: internal_namespace) } + let!(:public_project) { create(:project, :public, name: 'searchable_public_project', creator_id: public_user.id, namespace: public_namespace) } describe '#execute' do context 'unauthenticated' do it 'should return public projects only' do context = Search::GlobalService.new(nil, search: "searchable") results = context.execute - results[:projects].should have(1).items - results[:projects].should include(public_project) + results[:projects].should match_array [public_project] end end @@ -30,24 +28,19 @@ describe 'Search::GlobalService' do it 'should return public, internal and private projects' do context = Search::GlobalService.new(user, search: "searchable") results = context.execute - results[:projects].should have(3).items - results[:projects].should include(public_project) - results[:projects].should include(found_project) - results[:projects].should include(internal_project) + results[:projects].should match_array [public_project, found_project, internal_project] end it 'should return only public & internal projects' do context = Search::GlobalService.new(internal_user, search: "searchable") results = context.execute - results[:projects].should have(2).items - results[:projects].should include(internal_project) - results[:projects].should include(public_project) + results[:projects].should match_array [internal_project, public_project] end it 'namespace name should be searchable' do context = Search::GlobalService.new(user, search: "searchable namespace") results = context.execute - results[:projects].should == [found_project] + results[:projects].should match_array [found_project] end end end -- cgit v1.2.3 From c1fd25ce6ed28ad19fe4928be018a189c06cc3d7 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 19 Mar 2014 12:59:23 +0200 Subject: Replace turbolink spinner with nprogress Signed-off-by: Dmitriy Zaporozhets --- Gemfile | 1 + Gemfile.lock | 2 ++ app/assets/javascripts/application.js | 2 ++ app/assets/javascripts/main.js.coffee | 8 -------- app/assets/stylesheets/application.scss | 2 ++ app/views/layouts/_head_panel.html.haml | 4 ---- 6 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index 6a587d1d279..63f5e6d057c 100644 --- a/Gemfile +++ b/Gemfile @@ -167,6 +167,7 @@ gem 'bootstrap-sass', '~> 3.0' gem "font-awesome-rails", '~> 3.2' gem "gemoji", "~> 1.3.0" gem "gon", '~> 5.0.0' +gem 'nprogress-rails' group :development do gem "annotate", "~> 2.6.0.beta2" diff --git a/Gemfile.lock b/Gemfile.lock index de1ef59712e..46540fc7b03 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -297,6 +297,7 @@ GEM net-ssh (>= 1.99.1) net-ssh (2.7.0) nokogiri (1.5.10) + nprogress-rails (0.1.2.3) oauth (0.4.7) oauth2 (0.8.1) faraday (~> 0.8) @@ -621,6 +622,7 @@ DEPENDENCIES minitest (~> 4.7.0) modernizr (= 2.6.2) mysql2 + nprogress-rails omniauth (~> 1.1.3) omniauth-github omniauth-google-oauth2 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 4a393dbfe81..f69b750bb69 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -29,3 +29,5 @@ //= require_tree . //= require d3 //= require underscore +//= require nprogress +//= require nprogress-turbolinks diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee index 70e8972d24d..89f6a547ff8 100644 --- a/app/assets/javascripts/main.js.coffee +++ b/app/assets/javascripts/main.js.coffee @@ -41,19 +41,11 @@ window.linkify = (str) -> window.simpleFormat = (str) -> linkify(sanitize(str).replace(/\n/g, '
')) -window.startSpinner = -> - $('.turbolink-spinner').fadeIn() - -window.stopSpinner = -> - $('.turbolink-spinner').fadeOut() - window.unbindEvents = -> $(document).unbind('scroll') $(document).off('scroll') -document.addEventListener("page:fetch", startSpinner) document.addEventListener("page:fetch", unbindEvents) -document.addEventListener("page:change", stopSpinner) $ -> # Click a .one_click_select field, select the contents diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 33466714681..4b7103010bb 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -7,6 +7,8 @@ *= require select2 *= require highlightjs.min *= require_self + *= require nprogress + *= require nprogress-bootstrap */ @import "main/variables.scss"; diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml index 5080a1b7ef6..d8001fd76d7 100644 --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -14,10 +14,6 @@ .navbar-collapse.collapse %ul.nav.navbar-nav - %li.hidden-sm.hidden-xs - %a - %div.hide.turbolink-spinner - %i.icon-refresh.icon-spin %li.hidden-sm.hidden-xs = render "layouts/search" %li.visible-sm.visible-xs -- cgit v1.2.3 From 7d36d71d97923aa3c73609a839c106cb03ee15fa Mon Sep 17 00:00:00 2001 From: dosire Date: Wed, 19 Mar 2014 12:46:18 +0100 Subject: Run the RC on Cloud. --- doc/release/monthly.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/release/monthly.md b/doc/release/monthly.md index 28fc260b334..e440f5d5abc 100644 --- a/doc/release/monthly.md +++ b/doc/release/monthly.md @@ -61,11 +61,11 @@ After making the release branch new commits are cherry-picked from master. When * 17th: feature freeze (stop merging new features in master) * 18th: UI freeze (stop merging changes to the user interface) * 19th: code freeze (stop merging non-essential code improvements) -* 20th: release candidate 1 (VERSION x.x.0.rc1, tag and tweet about x.x.0.rc1) +* 20th: release candidate 1 (VERSION x.x.0.rc1, tag, tweet and upgrade Cloud) * 21st: optional release candidate 2 (x.x.0.rc2, only if rc1 had problems) * 22nd: release (VERSION x.x.0, create x-x-stable branch, tag, blog and tweet) -* 23nd: optional patch releases (x.x.1, x.x.2, etc., only if there are serious problems) -* 24-end of month: release Enterprise Edition and upgrade GitLab Cloud +* 23nd: optional patch releases (x.x.1, x.x.2, etc., only if there are serious regressions) +* 24-end of month: release Enterprise Edition and upgrade GitLab Cloud to latest patch * 1-7th: official merge window (see contributing guide) * 8-16th: bugfixes and sponsored features -- cgit v1.2.3 From 1921a934a9373884133eb3859efa250794b0ea92 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 19 Mar 2014 14:42:13 +0200 Subject: Add room placeholder for Slack integration Signed-off-by: Dmitriy Zaporozhets --- app/models/project_services/slack_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb index 27648acf6d0..754fd87db02 100644 --- a/app/models/project_services/slack_service.rb +++ b/app/models/project_services/slack_service.rb @@ -40,7 +40,7 @@ class SlackService < Service [ { type: 'text', name: 'subdomain', placeholder: '' }, { type: 'text', name: 'token', placeholder: '' }, - { type: 'text', name: 'room', placeholder: '' }, + { type: 'text', name: 'room', placeholder: 'Ex. #general' }, ] end -- cgit v1.2.3 From 0e31cb40d3998f8bad3e0a1e35985e28ef825e19 Mon Sep 17 00:00:00 2001 From: Job van der Voort Date: Wed, 19 Mar 2014 14:01:13 +0100 Subject: require public email with oauth provider message --- app/views/devise/sessions/_oauth_providers.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/devise/sessions/_oauth_providers.html.haml b/app/views/devise/sessions/_oauth_providers.html.haml index 935bc6af505..9a112f56643 100644 --- a/app/views/devise/sessions/_oauth_providers.html.haml +++ b/app/views/devise/sessions/_oauth_providers.html.haml @@ -2,10 +2,11 @@ - if providers.present? %hr %div{:'data-no-turbolink' => 'data-no-turbolink'} - %span Sign in with:   + %span Sign in with*:   - providers.each do |provider| %span - if default_providers.include?(provider) = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider) - else = link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn" + %small * Make sure your email address is public -- cgit v1.2.3 From 622bbf9629d2f5f081fbad6bbd9f0e3b6f092be6 Mon Sep 17 00:00:00 2001 From: Job van der Voort Date: Wed, 19 Mar 2014 14:07:42 +0100 Subject: line break --- app/views/devise/sessions/_oauth_providers.html.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/devise/sessions/_oauth_providers.html.haml b/app/views/devise/sessions/_oauth_providers.html.haml index 9a112f56643..2b1cb9c694f 100644 --- a/app/views/devise/sessions/_oauth_providers.html.haml +++ b/app/views/devise/sessions/_oauth_providers.html.haml @@ -9,4 +9,5 @@ = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider) - else = link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn" + %br %small * Make sure your email address is public -- cgit v1.2.3 From 2e33a820722b03645c755e1b710d1226a0f72f45 Mon Sep 17 00:00:00 2001 From: dosire Date: Wed, 19 Mar 2014 17:10:22 +0100 Subject: Spinner in changelog. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index c8bbce73f5a..5bf60b3d3fb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,7 @@ v 6.7.0 - Show contribution guide link for new issue form (Jeroen van Baarsen) - Fix CI status for merge requests from fork - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) + - New page load indicator that includes a spinner that scrolls with the page - Converted all the help sections into markdown v 6.6.2 -- cgit v1.2.3 From 4f68e15d9e89f338cde64fcfa3e14c0b9bc04afd Mon Sep 17 00:00:00 2001 From: Evgeniy Sokovikov Date: Wed, 19 Mar 2014 20:08:26 +0300 Subject: typo fix --- doc/development/architecture.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/development/architecture.md b/doc/development/architecture.md index ab74af4faf9..805e115047a 100644 --- a/doc/development/architecture.md +++ b/doc/development/architecture.md @@ -18,7 +18,7 @@ New releases are generally around the same time as GitLab CE releases with excep # System Layout -When referring to ~git in the picures it means the home directory of the git user which is typically /home/git. +When referring to ~git in the pictures it means the home directory of the git user which is typically /home/git. GitLab is primarily installed within the `/home/git` user home directory as `git` user. Within the home directory is where the gitlabhq server software resides as well as the repositories (though the repository location is configurable). -- cgit v1.2.3 From 189f88de5b6a85d1bae43cc4625e5d6604bbe6a8 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 20 Mar 2014 10:03:02 +0200 Subject: rc1 Signed-off-by: Dmitriy Zaporozhets --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 998707b421c..13f32397641 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.7.0.pre +6.7.0.rc1 -- cgit v1.2.3 From 19c28822ef60da0f4eda380e6cab3be4a4cb18e5 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 19 Mar 2014 21:01:00 +0200 Subject: Add Gitlab::GitAccess class to resolve auth issues during pull/push Signed-off-by: Dmitriy Zaporozhets --- lib/gitlab/git_access.rb | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 lib/gitlab/git_access.rb diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb new file mode 100644 index 00000000000..5fb5505743f --- /dev/null +++ b/lib/gitlab/git_access.rb @@ -0,0 +1,74 @@ +module Gitlab + class GitAccess + DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive } + PUSH_COMMANDS = %w{ git-receive-pack } + + attr_reader :params, :project, :git_cmd, :user + + def allowed?(actor, cmd, project, ref = nil, oldrev = nil, newrev = nil) + case cmd + when *DOWNLOAD_COMMANDS + if actor.is_a? User + download_allowed?(actor, project) + elsif actor.is_a? DeployKey + actor.projects.include?(project) + elsif actor.is_a? Key + download_allowed?(actor.user, project) + else + raise 'Wrong actor' + end + when *PUSH_COMMANDS + if actor.is_a? User + push_allowed?(actor, project, ref, oldrev, newrev) + elsif actor.is_a? DeployKey + # Deploy key not allowed to push + return false + elsif actor.is_a? Key + push_allowed?(actor.user, project, ref, oldrev, newrev) + else + raise 'Wrong actor' + end + else + false + end + end + + def download_allowed?(user, project) + if user_allowed?(user) + user.can?(:download_code, project) + else + false + end + end + + def push_allowed?(user, project, ref, oldrev, newrev) + if user_allowed?(user) + action = if project.protected_branch?(ref) + :push_code_to_protected_branches + else + :push_code + end + user.can?(action, project) + else + false + end + end + + private + + def user_allowed?(user) + return false if user.blocked? + + if Gitlab.config.ldap.enabled + if user.ldap_user? + # Check if LDAP user exists and match LDAP user_filter + unless Gitlab::LDAP::Access.new.allowed?(user) + return false + end + end + end + + true + end + end +end -- cgit v1.2.3 From f18a714f357405a87031250f4350343ae54d528f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 19 Mar 2014 21:02:12 +0200 Subject: Use GitAccess in internal api Signed-off-by: Dmitriy Zaporozhets --- lib/api/internal.rb | 60 +++++++++++++++++------------------------------------ 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 69aad3748b3..bcf97574673 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -1,16 +1,12 @@ module API # Internal access API class Internal < Grape::API - - DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive } - PUSH_COMMANDS = %w{ git-receive-pack } - namespace 'internal' do - # - # Check if ssh key has access to project code + # Check if git command is allowed to project # # Params: - # key_id - SSH Key id + # key_id - ssh key id for Git over SSH + # user_id - user id for Git over HTTP # project - project path with namespace # action - git action (git-upload-pack or git-receive-pack) # ref - branch name @@ -22,43 +18,25 @@ module API # the wiki repository as well. project_path = params[:project] project_path.gsub!(/\.wiki/,'') if project_path =~ /\.wiki/ - - key = Key.find(params[:key_id]) project = Project.find_with_namespace(project_path) - git_cmd = params[:action] return false unless project - - if key.is_a? DeployKey - key.projects.include?(project) && DOWNLOAD_COMMANDS.include?(git_cmd) - else - user = key.user - - return false if user.blocked? - - if Gitlab.config.ldap.enabled - if user.ldap_user? - # Check if LDAP user exists and match LDAP user_filter - unless Gitlab::LDAP::Access.new.allowed?(user) - return false - end - end - end - - action = case git_cmd - when *DOWNLOAD_COMMANDS - then :download_code - when *PUSH_COMMANDS - then - if project.protected_branch?(params[:ref]) - :push_code_to_protected_branches - else - :push_code - end - end - - user.can?(action, project) - end + actor = if params[:key_id] + Key.find(params[:key_id]) + elsif params[:user_id] + User.find(params[:user_id]) + end + + return false unless actor + + Gitlab::GitAccess.new.allowed?( + actor, + params[:action], + project, + params[:ref], + params[:oldrev], + params[:newrev] + ) end # -- cgit v1.2.3 From 729b358ff2981d8931e27fdc33d29b9528232c32 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 19 Mar 2014 21:02:39 +0200 Subject: push via http now served via /allowed API Signed-off-by: Dmitriy Zaporozhets --- lib/gitlab/backend/grack_auth.rb | 47 +++++----------------------------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index 60c03ce1c04..ee99bd5f7de 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -5,7 +5,7 @@ module Grack class Auth < Rack::Auth::Basic include Helpers - attr_accessor :user, :project, :ref, :env + attr_accessor :user, :project, :env def call(env) @env = env @@ -80,24 +80,11 @@ module Grack def authorize_request(service) case service when 'git-upload-pack' - can?(user, :download_code, project) - when'git-receive-pack' - refs.each do |ref| - action = if project.protected_branch?(ref) - :push_code_to_protected_branches - else - :push_code - end - - return false unless can?(user, action, project) - end - - # Never let git-receive-pack trough unauthenticated; it's - # harmless but git < 1.8 doesn't like it - return false if user.nil? - true + # Serve only upload request. + # Authorization on push will be serverd by update hook in repository + Gitlab::GitAccess.new.download_allowed?(user, project) else - false + true end end @@ -114,29 +101,5 @@ module Grack def project @project ||= project_by_path(@request.path_info) end - - def refs - @refs ||= parse_refs - end - - def parse_refs - input = if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/ - Zlib::GzipReader.new(@request.body).read - else - @request.body.read - end - - # Need to reset seek point - @request.body.rewind - - # Parse refs - refs = input.force_encoding('ascii-8bit').scan(/refs\/heads\/([\/\w\.-]+)/n).flatten.compact - - # Cleanup grabare from refs - # if push to multiple branches - refs.map do |ref| - ref.gsub(/00.*/, "") - end - end end end -- cgit v1.2.3 From 41e981740ffc54f68ae5f8fe7b719183cd125094 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 19 Mar 2014 20:56:31 +0200 Subject: Use 2 workers in development Signed-off-by: Dmitriy Zaporozhets --- Procfile | 2 +- config/unicorn_development.rb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 config/unicorn_development.rb diff --git a/Procfile b/Procfile index 9003369c938..18df7e78f9b 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,2 @@ -web: bundle exec unicorn_rails -p $PORT -E development +web: bundle exec unicorn_rails -p $PORT -E development -c config/unicorn_development.rb worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitlab_shell diff --git a/config/unicorn_development.rb b/config/unicorn_development.rb new file mode 100644 index 00000000000..94a7061451d --- /dev/null +++ b/config/unicorn_development.rb @@ -0,0 +1,2 @@ +worker_processes 2 +timeout 30 -- cgit v1.2.3 From 83e83b6617694c03457ca3a36230b54560ce6833 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 20 Mar 2014 10:53:03 +0200 Subject: Improve grack auth Signed-off-by: Dmitriy Zaporozhets --- lib/gitlab/backend/grack_auth.rb | 21 +++++++++++++++++---- lib/gitlab/backend/grack_helpers.rb | 28 ---------------------------- 2 files changed, 17 insertions(+), 32 deletions(-) delete mode 100644 lib/gitlab/backend/grack_helpers.rb diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index ee99bd5f7de..b3e111354f5 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -1,9 +1,7 @@ require_relative 'shell_env' -require_relative 'grack_helpers' module Grack class Auth < Rack::Auth::Basic - include Helpers attr_accessor :user, :project, :env @@ -79,12 +77,14 @@ module Grack def authorize_request(service) case service - when 'git-upload-pack' + when *Gitlab::GitAccess::DOWNLOAD_COMMANDS # Serve only upload request. # Authorization on push will be serverd by update hook in repository Gitlab::GitAccess.new.download_allowed?(user, project) - else + when *Gitlab::GitAccess::PUSH_COMMANDS true + else + false end end @@ -101,5 +101,18 @@ module Grack def project @project ||= project_by_path(@request.path_info) end + + def project_by_path(path) + if m = /^([\w\.\/-]+)\.git/.match(path).to_a + path_with_namespace = m.last + path_with_namespace.gsub!(/\.wiki$/, '') + + Project.find_with_namespace(path_with_namespace) + end + end + + def render_not_found + [404, {"Content-Type" => "text/plain"}, ["Not Found"]] + end end end diff --git a/lib/gitlab/backend/grack_helpers.rb b/lib/gitlab/backend/grack_helpers.rb deleted file mode 100644 index cb747fe0137..00000000000 --- a/lib/gitlab/backend/grack_helpers.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Grack - module Helpers - def project_by_path(path) - if m = /^([\w\.\/-]+)\.git/.match(path).to_a - path_with_namespace = m.last - path_with_namespace.gsub!(/\.wiki$/, '') - - Project.find_with_namespace(path_with_namespace) - end - end - - def render_not_found - [404, {"Content-Type" => "text/plain"}, ["Not Found"]] - end - - def can?(object, action, subject) - abilities.allowed?(object, action, subject) - end - - def abilities - @abilities ||= begin - abilities = Six.new - abilities << Ability - abilities - end - end - end -end -- cgit v1.2.3 From 3a294daf535a733054ed4d79a64ee64904bf5218 Mon Sep 17 00:00:00 2001 From: Marc Radulescu Date: Thu, 20 Mar 2014 10:04:41 +0100 Subject: added OReilly sponsorship to CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index f82da87a806..93a31e7377f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -26,6 +26,7 @@ v 6.7.0 - Create and Update MR calls now support the description parameter (Greg Messner) - Markdown relative links in the wiki link to wiki pages, markdown relative links in repositories link to files in the repository - Added Slack service integration (Federico Ravasio) + - Better API responses for access_levels (sponsored by O'Reilly Media) v 6.6.5 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) -- cgit v1.2.3 From e013be10d7185dcdc814c11a65537ecd903e404d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 20 Mar 2014 13:37:35 +0200 Subject: GitLab requires gitlab-shell v1.9.0 Signed-off-by: Dmitriy Zaporozhets --- CHANGELOG | 2 ++ lib/tasks/gitlab/check.rake | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 93a31e7377f..a9a8c00666d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -27,6 +27,8 @@ v 6.7.0 - Markdown relative links in the wiki link to wiki pages, markdown relative links in repositories link to files in the repository - Added Slack service integration (Federico Ravasio) - Better API responses for access_levels (sponsored by O'Reilly Media) + - Requires at least 2 unicorn workers + - Requires gitlab-shell v1.9+ v 6.6.5 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index d4d5e48ce3f..067735d66b1 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -742,7 +742,7 @@ namespace :gitlab do end def check_gitlab_shell - required_version = Gitlab::VersionInfo.new(1, 8, 5) + required_version = Gitlab::VersionInfo.new(1, 9, 0) current_version = Gitlab::VersionInfo.parse(gitlab_shell_version) print "GitLab Shell version >= #{required_version} ? ... " -- cgit v1.2.3 From 2767abd90d94b3fd0fedfad85015abbffd7e4cd9 Mon Sep 17 00:00:00 2001 From: Tom de Bruijn Date: Thu, 20 Mar 2014 13:23:07 +0100 Subject: Clearfix on well-lists. Pages affected: Pages affected: - admin/groups#show - admin/projets#index - admin/users#index - dashboard/issues#index (on small screens) --- app/assets/stylesheets/generic/lists.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/assets/stylesheets/generic/lists.scss b/app/assets/stylesheets/generic/lists.scss index de70e47333f..8a6d7f68175 100644 --- a/app/assets/stylesheets/generic/lists.scss +++ b/app/assets/stylesheets/generic/lists.scss @@ -13,6 +13,12 @@ border-bottom: 1px solid #eee; border-bottom: 1px solid rgba(0, 0, 0, 0.05); + &:after { + content: " "; + display: table; + clear: both; + } + &.disabled { color: #888; } -- cgit v1.2.3 From 817f5ff6a3da3bcb494109bffbd9eca2fedc20b0 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Thu, 20 Mar 2014 11:56:52 +0100 Subject: Use gitlab_emoji gem instead of gemoji. --- Gemfile | 2 +- Gemfile.lock | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 63f5e6d057c..786b0ad4db3 100644 --- a/Gemfile +++ b/Gemfile @@ -165,7 +165,7 @@ gem "modernizr", "2.6.2" gem "raphael-rails", "~> 2.1.2" gem 'bootstrap-sass', '~> 3.0' gem "font-awesome-rails", '~> 3.2' -gem "gemoji", "~> 1.3.0" +gem "gitlab_emoji", "~> 0.0.1" gem "gon", '~> 5.0.0' gem 'nprogress-rails' diff --git a/Gemfile.lock b/Gemfile.lock index 46540fc7b03..dc2f920619d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -128,6 +128,8 @@ GEM mail (~> 2.2) email_validator (1.4.0) activemodel + emoji (1.0.1) + json enumerize (0.7.0) activesupport (>= 3.2) equalizer (0.0.8) @@ -165,7 +167,6 @@ GEM formatador (0.2.4) gemnasium-gitlab-service (0.2.1) rugged (~> 0.19) - gemoji (1.3.1) gherkin-ruby (0.3.1) racc github-markdown (0.5.5) @@ -190,6 +191,8 @@ GEM charlock_holmes (~> 0.6.6) escape_utils (~> 0.2.4) mime-types (~> 1.19) + gitlab_emoji (0.0.1) + emoji (~> 1.0.1) gitlab_git (5.7.1) activesupport (~> 4.0.0) charlock_holmes (~> 0.6.9) @@ -593,12 +596,12 @@ DEPENDENCIES font-awesome-rails (~> 3.2) foreman gemnasium-gitlab-service (~> 0.2) - gemoji (~> 1.3.0) github-markup (~> 0.7.4)! gitlab-flowdock-git-hook (~> 0.4.2) gitlab-gollum-lib (~> 1.1.0) gitlab-grack (~> 2.0.0.pre) gitlab-linguist (~> 3.0.0) + gitlab_emoji (~> 0.0.1) gitlab_git (~> 5.7.1) gitlab_meta (= 6.0) gitlab_omniauth-ldap (= 1.0.4) -- cgit v1.2.3 From 5f595be4b80ae57c92d01dc1c0026566f80e67d4 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Thu, 20 Mar 2014 13:30:27 +0100 Subject: Use new gems methods. --- app/views/layouts/_init_auto_complete.html.haml | 2 +- app/views/projects/notes/_note.html.haml | 2 +- config/initializers/gemoji.rb | 3 --- lib/gitlab/markdown.rb | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) delete mode 100644 config/initializers/gemoji.rb diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml index 6a20dedf62f..fd6097dcc7b 100644 --- a/app/views/layouts/_init_auto_complete.html.haml +++ b/app/views/layouts/_init_auto_complete.html.haml @@ -1,4 +1,4 @@ :javascript GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_project_path(@project)}" - GitLab.GfmAutoComplete.Emoji.assetBase = "#{Gitlab.config.gitlab.relative_url_root + '/assets/emoji'}" + GitLab.GfmAutoComplete.Emoji.assetBase = "#{Gitlab.config.gitlab.relative_url_root + Emoji.asset_path}" GitLab.GfmAutoComplete.setup(); diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index 217e36e38d0..81bf0611ec6 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -23,7 +23,7 @@ %i.icon-thumbs-up \+1 - if note.downvote? - %span.vote.downvote.label.label-error + %span.vote.downvote.label.label-danger %i.icon-thumbs-down \-1 diff --git a/config/initializers/gemoji.rb b/config/initializers/gemoji.rb deleted file mode 100644 index 6cc33aced77..00000000000 --- a/config/initializers/gemoji.rb +++ /dev/null @@ -1,3 +0,0 @@ -# Workaround for https://github.com/github/gemoji/pull/18 -require 'gemoji' -Gitlab::Application.config.assets.paths << Emoji.images_path diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index e72f4f5d0ce..80bb00821f7 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -152,7 +152,7 @@ module Gitlab # # Returns boolean def valid_emoji?(emoji) - Emoji.names.include? emoji + Emoji.find_by_name emoji end # Private: Dispatches to a dedicated processing method based on reference -- cgit v1.2.3 From 4dc09e5c1dbed7aa40209499e4d0889936bc72a1 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Thu, 20 Mar 2014 13:31:43 +0100 Subject: New bindings to vote on notes. --- app/models/note.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/note.rb b/app/models/note.rb index 48c03c9d587..906de4855ab 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -199,7 +199,8 @@ class Note < ActiveRecord::Base def downvote? votable? && (note.start_with?('-1') || note.start_with?(':-1:') || - note.start_with?(':thumbsdown:') + note.start_with?(':thumbsdown:') || + note.start_with?(':thumbs_down_sign:') ) end @@ -249,7 +250,8 @@ class Note < ActiveRecord::Base def upvote? votable? && (note.start_with?('+1') || note.start_with?(':+1:') || - note.start_with?(':thumbsup:') + note.start_with?(':thumbsup:') || + note.start_with?(':thumbs_up_sign:') ) end -- cgit v1.2.3 From 9afd04842f6658dcd1dc02cda17247c321ff6a67 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Thu, 20 Mar 2014 13:46:31 +0100 Subject: Update Changelog --- CHANGELOG | 1 + Gemfile | 2 +- Gemfile.lock | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a9a8c00666d..f2124408b42 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -29,6 +29,7 @@ v 6.7.0 - Better API responses for access_levels (sponsored by O'Reilly Media) - Requires at least 2 unicorn workers - Requires gitlab-shell v1.9+ + - Replaced gemoji(due to closed licencing problem) with Phantom Open Emoji library(combined SIL Open Font License, MIT License and the CC 3.0 License) v 6.6.5 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) diff --git a/Gemfile b/Gemfile index 786b0ad4db3..5b58ce443ae 100644 --- a/Gemfile +++ b/Gemfile @@ -165,7 +165,7 @@ gem "modernizr", "2.6.2" gem "raphael-rails", "~> 2.1.2" gem 'bootstrap-sass', '~> 3.0' gem "font-awesome-rails", '~> 3.2' -gem "gitlab_emoji", "~> 0.0.1" +gem "gitlab_emoji", "~> 0.0.1.1" gem "gon", '~> 5.0.0' gem 'nprogress-rails' diff --git a/Gemfile.lock b/Gemfile.lock index dc2f920619d..167fd960ff5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -191,7 +191,7 @@ GEM charlock_holmes (~> 0.6.6) escape_utils (~> 0.2.4) mime-types (~> 1.19) - gitlab_emoji (0.0.1) + gitlab_emoji (0.0.1.1) emoji (~> 1.0.1) gitlab_git (5.7.1) activesupport (~> 4.0.0) @@ -601,7 +601,7 @@ DEPENDENCIES gitlab-gollum-lib (~> 1.1.0) gitlab-grack (~> 2.0.0.pre) gitlab-linguist (~> 3.0.0) - gitlab_emoji (~> 0.0.1) + gitlab_emoji (~> 0.0.1.1) gitlab_git (~> 5.7.1) gitlab_meta (= 6.0) gitlab_omniauth-ldap (= 1.0.4) -- cgit v1.2.3 From dd7efd1768f7f61dfa8c47200fc95bac831c9ff5 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 13 Mar 2014 15:20:31 +0100 Subject: Add load_ok check to script/background_jobs --- script/background_jobs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/script/background_jobs b/script/background_jobs index 06125c11ffe..a41ae3956c2 100755 --- a/script/background_jobs +++ b/script/background_jobs @@ -6,6 +6,11 @@ sidekiq_pidfile="$app_root/tmp/pids/sidekiq.pid" sidekiq_logfile="$app_root/log/sidekiq.log" gitlab_user=$(ls -l config.ru | awk '{print $3}') +function warn +{ + echo "$@" 1>&2 +} + function stop { bundle exec sidekiqctl stop $sidekiq_pidfile >> $sidekiq_logfile 2>&1 @@ -35,6 +40,22 @@ function start_sidekiq bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e $RAILS_ENV -P $sidekiq_pidfile $@ >> $sidekiq_logfile 2>&1 } +function load_ok +{ + sidekiq_pid=$(cat $sidekiq_pidfile) + if [[ -z $sidekiq_pid ]] ; then + warn "Could not find a PID in $sidekiq_pidfile" + exit 0 + fi + + if (ps -p $sidekiq_pid -o args | grep '\([0-9]\+\) of \1 busy' 1>&2) ; then + warn "Too many busy Sidekiq workers" + exit 1 + fi + + exit 0 +} + case "$1" in stop) stop @@ -51,6 +72,9 @@ case "$1" in killall) killall ;; + load_ok) + load_ok + ;; *) echo "Usage: RAILS_ENV=your_env $0 {stop|start|start_no_deamonize|restart|killall}" esac -- cgit v1.2.3 From cc83c696c0f453c48811263b08505dba77b34315 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 20 Mar 2014 14:47:06 +0100 Subject: Add load_ok to background_jobs usage message --- script/background_jobs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/background_jobs b/script/background_jobs index a41ae3956c2..52732f5532b 100755 --- a/script/background_jobs +++ b/script/background_jobs @@ -76,5 +76,5 @@ case "$1" in load_ok ;; *) - echo "Usage: RAILS_ENV=your_env $0 {stop|start|start_no_deamonize|restart|killall}" + echo "Usage: RAILS_ENV=your_env $0 {stop|start|start_no_deamonize|restart|killall|load_ok}" esac -- cgit v1.2.3 From 0bc88794684fe89af61360c6b88056dec18f1ecc Mon Sep 17 00:00:00 2001 From: dosire Date: Thu, 20 Mar 2014 15:32:30 +0100 Subject: Tell how to do it, solves https://twitter.com/unwiredbrain/status/446588631424462848 --- doc/integration/external-issue-tracker.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/integration/external-issue-tracker.md b/doc/integration/external-issue-tracker.md index 02eadfd410a..3212ebd64b5 100644 --- a/doc/integration/external-issue-tracker.md +++ b/doc/integration/external-issue-tracker.md @@ -5,3 +5,5 @@ GitLab has a great issue tracker but you can also use an external issue tracker - textual references to PROJECT-1234 in comments, commit messages get turned into HTML links to the corresponding JIRA issue. ![jira screenshot](jira-intergration-points.png) + +You can configure the integration in the gitlab.yml configuration file. -- cgit v1.2.3 From fefab474569f231676a4fd1579a70723d729f206 Mon Sep 17 00:00:00 2001 From: Dmitry Medvinsky Date: Wed, 19 Mar 2014 17:32:38 +0400 Subject: Fix `/:username.keys` response content type Currently this method responds with `text/html`. It is kind of unusable if you open it in a browser. The browser thinks it is HTML and renders it as HTML, meaning new lines are dropped. So it's very hard to distinguish where the key starts and where it ends. This commit changes the content type header to `text/plain`. --- CHANGELOG | 1 + app/controllers/profiles/keys_controller.rb | 2 +- spec/controllers/profile_keys_controller_spec.rb | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index a9a8c00666d..1d41a3505da 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -29,6 +29,7 @@ v 6.7.0 - Better API responses for access_levels (sponsored by O'Reilly Media) - Requires at least 2 unicorn workers - Requires gitlab-shell v1.9+ + - Fix `/:username.keys` response content type (Dmitry Medvinsky) v 6.6.5 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb index b4f14e649e2..6713cd7c8c7 100644 --- a/app/controllers/profiles/keys_controller.rb +++ b/app/controllers/profiles/keys_controller.rb @@ -41,7 +41,7 @@ class Profiles::KeysController < ApplicationController begin user = User.find_by_username(params[:username]) if user.present? - render text: user.all_ssh_keys.join("\n") + render text: user.all_ssh_keys.join("\n"), content_type: "text/plain" else render_404 and return end diff --git a/spec/controllers/profile_keys_controller_spec.rb b/spec/controllers/profile_keys_controller_spec.rb index 121012d5d49..593d3e9eb56 100644 --- a/spec/controllers/profile_keys_controller_spec.rb +++ b/spec/controllers/profile_keys_controller_spec.rb @@ -24,6 +24,11 @@ describe Profiles::KeysController do expect(response.body).to eq("") end + + it "should respond with text/plain content type" do + get :get_keys, username: user.username + expect(response.content_type).to eq("text/plain") + end end describe "user with keys" do @@ -44,6 +49,11 @@ describe Profiles::KeysController do expect(response.body).not_to eq("") expect(response.body).to eq(user.all_ssh_keys.join("\n")) end + + it "should respond with text/plain content type" do + get :get_keys, username: user.username + expect(response.content_type).to eq("text/plain") + end end end end -- cgit v1.2.3 From 44aa6b90ddde3a7babc6ed9f50d73040d6184789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81bner=20Silva=20de=20Oliveira?= Date: Fri, 21 Mar 2014 06:18:19 -0300 Subject: added api method to return labels of a given project --- lib/api/entities.rb | 4 ++++ lib/api/projects.rb | 9 +++++++++ spec/requests/api/labels_spec.rb | 26 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 spec/requests/api/labels_spec.rb diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 8b4519af2d1..9fa8506926c 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -187,5 +187,9 @@ module API end end end + + class Label < Grape::Entity + expose :name + end end end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 4d48d2194f8..40b5ce86c93 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -215,6 +215,15 @@ module API @users = paginate @users present @users, with: Entities::User end + + # Get a labels list + # + # Example Request: + # GET /users + get ':id/labels' do + @labels = user_project.issues_labels + present @labels, with: Entities::Label + end end end end diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb new file mode 100644 index 00000000000..ba5efb6c603 --- /dev/null +++ b/spec/requests/api/labels_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe API::API do + include ApiHelpers + before(:each) { ActiveRecord::Base.observers.enable(:user_observer) } + after(:each) { ActiveRecord::Base.observers.disable(:user_observer) } + + let(:user) { create(:user) } + let!(:project) { create(:project, namespace: user.namespace ) } + let!(:issue) { create(:issue, author: user, assignee: user, project: project, :label_list => "label1, label2") } + before { project.team << [user, :reporter] } + + + describe "GET /projects/:id/labels" do + it "should return project labels" do + get api("/projects/#{project.id}/labels", user) + response.status.should == 200 + json_response.should be_an Array + json_response.first['name'].should == 'label1' + json_response.last['name'].should == 'label2' + end + end + + +end + -- cgit v1.2.3 From 6d9dccbec802d8d5956f31eda4af4f03fafd66b8 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 21 Mar 2014 12:26:34 +0100 Subject: Checkout gitlab-shell v 1.9.0 --- doc/update/6.6-to-6.7.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/update/6.6-to-6.7.md b/doc/update/6.6-to-6.7.md index e4a0cafa911..f5b90c8ac5e 100644 --- a/doc/update/6.6-to-6.7.md +++ b/doc/update/6.6-to-6.7.md @@ -37,7 +37,7 @@ sudo -u git -H git checkout 6-7-stable-ee ```bash cd /home/git/gitlab-shell sudo -u git -H git fetch -sudo -u git -H git checkout v1.8.0 +sudo -u git -H git checkout v1.9.0 ``` ### 4. Install libs, migrations, etc. -- cgit v1.2.3 From 895c913247e0444374316ea46dec9304ce1efdf4 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 21 Mar 2014 12:42:59 +0100 Subject: Use the latest tag, 1.9.1 for gitlab-shell. --- doc/install/installation.md | 2 +- doc/update/6.6-to-6.7.md | 2 +- lib/tasks/gitlab/check.rake | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/install/installation.md b/doc/install/installation.md index a0eac76ab5b..a37eb733147 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -128,7 +128,7 @@ GitLab Shell is an ssh access and repository management software developed speci cd /home/git # Clone gitlab shell - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-shell.git -b v1.8.0 + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-shell.git -b v1.9.1 cd gitlab-shell diff --git a/doc/update/6.6-to-6.7.md b/doc/update/6.6-to-6.7.md index f5b90c8ac5e..8a16e5d67be 100644 --- a/doc/update/6.6-to-6.7.md +++ b/doc/update/6.6-to-6.7.md @@ -37,7 +37,7 @@ sudo -u git -H git checkout 6-7-stable-ee ```bash cd /home/git/gitlab-shell sudo -u git -H git fetch -sudo -u git -H git checkout v1.9.0 +sudo -u git -H git checkout v1.9.1 ``` ### 4. Install libs, migrations, etc. diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 067735d66b1..071760c0c36 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -742,7 +742,7 @@ namespace :gitlab do end def check_gitlab_shell - required_version = Gitlab::VersionInfo.new(1, 9, 0) + required_version = Gitlab::VersionInfo.new(1, 9, 1) current_version = Gitlab::VersionInfo.parse(gitlab_shell_version) print "GitLab Shell version >= #{required_version} ? ... " -- cgit v1.2.3 From 7dd18a3ec832cb5e49932dff33f3a4ced30fe1e8 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 21 Mar 2014 14:52:30 +0200 Subject: Fix http clone for public project Signed-off-by: Dmitriy Zaporozhets --- lib/gitlab/backend/grack_auth.rb | 60 ++++++++++++++++++++++++---------------- lib/gitlab/git_access.rb | 4 +-- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index b3e111354f5..de18d904916 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -22,14 +22,16 @@ module Grack @env['SCRIPT_NAME'] = "" - auth! + if project + auth! + else + render_not_found + end end private def auth! - return render_not_found unless project - if @auth.provided? return bad_request unless @auth.basic? @@ -38,12 +40,8 @@ module Grack # Allow authentication for GitLab CI service # if valid token passed - if login == "gitlab-ci-token" && project.gitlab_ci? - token = project.gitlab_ci_service.token - - if token.present? && token == password && service_name == 'git-upload-pack' - return @app.call(env) - end + if gitlab_ci_request?(login, password) + return @app.call(env) end @user = authenticate_user(login, password) @@ -51,23 +49,26 @@ module Grack if @user Gitlab::ShellEnv.set_env(@user) @env['REMOTE_USER'] = @auth.username - else - return unauthorized end - - else - return unauthorized unless project.public? end - if authorized_git_request? + if authorized_request? @app.call(env) else unauthorized end end - def authorized_git_request? - authorize_request(service_name) + def gitlab_ci_request?(login, password) + if login == "gitlab-ci-token" && project.gitlab_ci? + token = project.gitlab_ci_service.token + + if token.present? && token == password && git_cmd == 'git-upload-pack' + true + end + end + + false end def authenticate_user(login, password) @@ -75,20 +76,31 @@ module Grack auth.find(login, password) end - def authorize_request(service) - case service + def authorized_request? + case git_cmd when *Gitlab::GitAccess::DOWNLOAD_COMMANDS - # Serve only upload request. - # Authorization on push will be serverd by update hook in repository - Gitlab::GitAccess.new.download_allowed?(user, project) + if user + Gitlab::GitAccess.new.download_allowed?(user, project) + elsif project.public? + # Allow clone/fetch for public projects + true + else + false + end when *Gitlab::GitAccess::PUSH_COMMANDS - true + if user + # Skip user authorization on upload request. + # It will be serverd by update hook in repository + true + else + false + end else false end end - def service_name + def git_cmd if @request.get? @request.params['service'] elsif @request.post? diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 5fb5505743f..1ab8f9213a3 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -34,7 +34,7 @@ module Gitlab end def download_allowed?(user, project) - if user_allowed?(user) + if user && user_allowed?(user) user.can?(:download_code, project) else false @@ -42,7 +42,7 @@ module Gitlab end def push_allowed?(user, project, ref, oldrev, newrev) - if user_allowed?(user) + if user && user_allowed?(user) action = if project.protected_branch?(ref) :push_code_to_protected_branches else -- cgit v1.2.3 From 20c3cbb18cfc414e144e5cb214d6b663ba17f828 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 21 Mar 2014 15:04:45 +0100 Subject: Update monster update guide to 6.0-to-6.7 --- doc/update/6.0-to-6.5.md | 127 ------------------------------------------ doc/update/6.0-to-6.7.md | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 127 deletions(-) delete mode 100644 doc/update/6.0-to-6.5.md create mode 100644 doc/update/6.0-to-6.7.md diff --git a/doc/update/6.0-to-6.5.md b/doc/update/6.0-to-6.5.md deleted file mode 100644 index e01cc589a83..00000000000 --- a/doc/update/6.0-to-6.5.md +++ /dev/null @@ -1,127 +0,0 @@ -# From 6.0 to 6.5 - -# In 6.1 we remove a lot of deprecated code. -# You should update to 6.0 before installing 6.1 or higher so all the necessary conversions are run. - -### Deprecations - -#### Global issue numbers - -As of 6.1 issue numbers are project specific. This means all issues are renumbered and get a new number in their url. If you use an old issue number url and the issue number does not exist yet you are redirected to the new one. This conversion does not trigger if the old number already exists for this project, this is unlikely but will happen with old issues and large projects. - -### 0. Backup - -It's useful to make a backup just in case things go south: -(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version) - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 1. Stop server - - sudo service gitlab stop - -### 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -sudo -u git -H git checkout 6-5-stable -# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-5-stable-ee -``` - - -### 3. Install additional packages - -```bash -# Add support for lograte for better log file handling -sudo apt-get install logrotate -``` - -### 4. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.8.0 # Addresses multiple critical security vulnerabilities -``` - -### 5. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_iids RAILS_ENV=production -sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production -``` - -### 6. Update config files - -TIP: to see what changed in gitlab.yml.example in this release use next command: - -``` -git diff 6-0-stable:config/gitlab.yml.example 6-5-stable:config/gitlab.yml.example -``` - -* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-5-stable/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-5-stable/config/unicorn.rb.example but with your settings. -* Copy rack attack middleware config - -```bash -sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb -``` - -* Set up logrotate - -```bash -sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab -``` - -### 7. Update Init script - -```bash -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 8. Start application - - sudo service gitlab start - sudo service nginx restart - -### 9. Check application status - -Check if GitLab and its environment are configured correctly: - - cd /home/git/gitlab - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (6.0) - -### 1. Revert the code to the previous version -Follow the [`upgrade guide from 5.4 to 6.0`](5.4-to-6.0.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/6.0-to-6.7.md b/doc/update/6.0-to-6.7.md new file mode 100644 index 00000000000..68878bb9cd9 --- /dev/null +++ b/doc/update/6.0-to-6.7.md @@ -0,0 +1,142 @@ +# From 6.0 to 6.7 + +# In 6.1 we remove a lot of deprecated code. +# You should update to 6.0 before installing 6.1 or higher so all the necessary conversions are run. + +### Deprecations + +#### Global issue numbers + +As of 6.1 issue numbers are project specific. This means all issues are renumbered and get a new number in their url. If you use an old issue number url and the issue number does not exist yet you are redirected to the new one. This conversion does not trigger if the old number already exists for this project, this is unlikely but will happen with old issues and large projects. + +### 0. Backup + +It's useful to make a backup just in case things go south: +(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version) + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production +``` + +### 1. Stop server + + sudo service gitlab stop + +### 2. Get latest code + +```bash +cd /home/git/gitlab +sudo -u git -H git fetch --all +``` + +For Gitlab Community Edition: + +```bash +sudo -u git -H git checkout 6-7-stable +``` + +OR + +For GitLab Enterprise Edition: + +```bash +sudo -u git -H git checkout 6-7-stable-ee +``` + + +### 3. Install additional packages + +```bash +# Add support for lograte for better log file handling +sudo apt-get install logrotate +``` + +### 4. Update gitlab-shell + +```bash +cd /home/git/gitlab-shell +sudo -u git -H git fetch +sudo -u git -H git checkout v1.9.1 # Addresses multiple critical security vulnerabilities +``` + +### 5. Install libs, migrations, etc. + +```bash +cd /home/git/gitlab + +# MySQL installations (note: the line below states '--without ... postgres') +sudo -u git -H bundle install --without development test postgres --deployment + +# PostgreSQL installations (note: the line below states '--without ... mysql') +sudo -u git -H bundle install --without development test mysql --deployment + + +# Run database migrations +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production + +# Enable internal issue IDs (introduced in GitLab 6.1) +sudo -u git -H bundle exec rake migrate_iids RAILS_ENV=production + +# Clean up assets and cache +sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production +``` + +### 6. Update config files + +TIP: to see what changed in gitlab.yml.example in this release use next command: + +``` +git diff 6-0-stable:config/gitlab.yml.example 6-7-stable:config/gitlab.yml.example +``` + +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-7-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-7-stable/config/unicorn.rb.example but with your settings. +* Copy rack attack middleware config + +```bash +sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb +``` + +* Set up logrotate + +```bash +sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab +``` + +### 7. Update Init script + +```bash +sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab +``` + +### 8. Start application + + sudo service gitlab start + sudo service nginx restart + +### 9. Check application status + +Check if GitLab and its environment are configured correctly: + + cd /home/git/gitlab + sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production + +To make sure you didn't miss anything run a more thorough check with: + + sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production + +If all items are green, then congratulations upgrade complete! + +## Things went south? Revert to previous version (6.0) + +### 1. Revert the code to the previous version +Follow the [`upgrade guide from 5.4 to 6.0`](5.4-to-6.0.md), except for the database migration +(The backup is already migrated to the previous version) + +### 2. Restore from the backup: + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production +``` -- cgit v1.2.3 From af3aaaddbd6d29e5e78f28ade1f18e65404227ab Mon Sep 17 00:00:00 2001 From: dosire Date: Fri, 21 Mar 2014 15:50:33 +0100 Subject: Features people are missing are not bugs. --- CONTRIBUTING.md | 8 ++++---- PROCESS.md | 4 +--- README.md | 4 ++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c1788657b95..c3c615b004c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,9 +24,9 @@ Issues and merge requests should be in English and contain appropriate language To get support for your particular problem please use the channels as detailed in the getting help section of [the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/). -The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious bugs or misbehavior in the latest [stable or development release of GitLab](MAINTENANCE.md). When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue. +The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious bugs in the latest [stable or development release of GitLab](MAINTENANCE.md). If something is missing but it is not a regression compared to older versions of GitLab please do not open an issue but a feature request. When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue. -Do not use the issue tracker for feature requests. We have a specific [feedback and suggestions forum](http://feedback.gitlab.com) for this purpose. +Do not use the issue tracker for feature requests. We have a specific [feature request forum](http://feedback.gitlab.com) for this purpose. Please send a merge request with a tested solution or a merge request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [mailing list](https://groups.google.com/forum/#!forum/gitlabhq) or [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there. @@ -48,7 +48,7 @@ Please send a merge request with a tested solution or a merge request with a fai ## Merge requests -We welcome merge requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a merge request for are listed with the [status 'accepting merge requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. If you want to add a new feature that is not marked it is best to first create a feedback issue (if there isn't one already) and leave a comment asking for it to be marked accepting merge requests. Please include screenshots or wireframes if the feature will also change the UI. +We welcome merge requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a merge request for are listed with the [status 'accepting merge requests' on our feature request forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. If you want to add a new feature that is not marked it is best to first create a feedback issue (if there isn't one already) and leave a comment asking for it to be marked accepting merge requests. Please include screenshots or wireframes if the feature will also change the UI. ### Merge request guidelines @@ -64,7 +64,7 @@ If you can, please submit a merge request with the fix or improvements including 1. The MR title should describes the change you want to make 1. The MR description should give a motive for your change and the method you used to achieve it 1. If the MR changes the UI it should include before and after screenshots -1. Link relevant [issues](https://gitlab.com/gitlab-org/gitlab-ce/issues) and/or [feedback items](http://feedback.gitlab.com/) from the merge request description and leave a comment on them with a link back to the MR +1. Link relevant [issues](https://gitlab.com/gitlab-org/gitlab-ce/issues) and/or [feature requests](http://feedback.gitlab.com/) from the merge request description and leave a comment on them with a link back to the MR 1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submittion 1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md). diff --git a/PROCESS.md b/PROCESS.md index bf757025c40..feabc6c09a4 100644 --- a/PROCESS.md +++ b/PROCESS.md @@ -24,8 +24,6 @@ Below we describe the contributing process to GitLab for two reasons. So that co - Monitors for new merge requests (at least once a week) - Manages their work queue by looking at issues and merge requests assigned to them - Close fixed issues (via commit messages or manually) -- Codes [new features](http://feedback.gitlab.com/forums/176466-general/filters/top)! -- Response guidelines - Be kind to people trying to contribute. Be aware that people can be a non-native or a native English speaker, they might not understand thing or they might be very sensitive to how your word things. Use emoji to express your feelings (heart, star, smile, etc.). Some good tips about giving feedback to merge requests is in the [Thoughtbot code review guide](https://github.com/thoughtbot/guides/tree/master/code-review). ## Priorities of the issue team @@ -73,7 +71,7 @@ Thanks for the issue report. Please reformat your issue to conform to the issue ### Feature requests -Thanks for your interest in GitLab. We don't use the issue tracker for feature requests. Please use http://feedback.gitlab.com/ for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. +Thanks for your interest in GitLab. We don't use the issue tracker for feature requests. Please use the [feature request forum](http://feedback.gitlab.com/) for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. ### Issue report for old version diff --git a/README.md b/README.md index 3bffdbe1f3a..c6a78e2807b 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Since 2011 GitLab is released on the 22nd of every month. Every new release incl It is recommended to follow a monthly upgrade schedule. Security releases come out when needed. For more information about the release process see the documentation for [monthly](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/monthly.md) and [security](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/security.md) releases. -* Features that will be in the next releases are listed on [the feedback and suggestions forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457). +* Features that will be in the next releases are listed on the [feature request forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457). ### Run in production mode @@ -142,7 +142,7 @@ or start each component separately * [Mailing list](https://groups.google.com/forum/#!forum/gitlabhq) and [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) are the best places to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and has resolved it. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix. -* [Feedback and suggestions forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab. +* [Feature request forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab. * [Contributing guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) describes how to submit merge requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed. -- cgit v1.2.3 From d03612412a575bb7bb05a2f51570b36493283b8a Mon Sep 17 00:00:00 2001 From: dosire Date: Fri, 21 Mar 2014 15:51:30 +0100 Subject: Ensure I can link to this line. --- CONTRIBUTING.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c3c615b004c..70ab1407500 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,10 @@ Issues and merge requests should be in English and contain appropriate language To get support for your particular problem please use the channels as detailed in the getting help section of [the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/). -The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious bugs in the latest [stable or development release of GitLab](MAINTENANCE.md). If something is missing but it is not a regression compared to older versions of GitLab please do not open an issue but a feature request. When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue. +The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious bugs in the latest [stable or development release of GitLab](MAINTENANCE.md). +If something is missing but it is not a regression compared to older versions of GitLab please do not open an issue but a feature request. +When submitting an issue please conform to the issue submission guidelines listed below. +Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue. Do not use the issue tracker for feature requests. We have a specific [feature request forum](http://feedback.gitlab.com) for this purpose. -- cgit v1.2.3 From 6bb474a0dc7a01108e9d2345da1c5a6e70d8aed0 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 21 Mar 2014 17:22:12 +0100 Subject: Version 6.7.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 13f32397641..f0e13c50902 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.7.0.rc1 +6.7.0 -- cgit v1.2.3 From d8a015cc9723557665ada26609b3f13820b03665 Mon Sep 17 00:00:00 2001 From: dosire Date: Fri, 21 Mar 2014 18:34:59 +0100 Subject: Should be 6-7. --- doc/install/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/install/installation.md b/doc/install/installation.md index a37eb733147..addb21b50e0 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -173,7 +173,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da ## Clone the Source # Clone GitLab repository - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-6-stable gitlab + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-7-stable gitlab # Go to gitlab dir cd /home/git/gitlab -- cgit v1.2.3 From 5c038d949f1e40939548c530214d65d33ab94904 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 21 Mar 2014 23:04:57 +0200 Subject: Fix gitlab-ci integration Signed-off-by: Dmitriy Zaporozhets --- lib/gitlab/backend/grack_auth.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index de18d904916..c2f3b851c07 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -64,7 +64,7 @@ module Grack token = project.gitlab_ci_service.token if token.present? && token == password && git_cmd == 'git-upload-pack' - true + return true end end -- cgit v1.2.3 From ae1a3148242907b21e9952f1964919622b4f3129 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 21 Mar 2014 23:08:36 +0200 Subject: Fix upgrader Signed-off-by: Dmitriy Zaporozhets --- lib/gitlab/upgrader.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/gitlab/upgrader.rb b/lib/gitlab/upgrader.rb index 0fe4888665d..0846359f9b1 100644 --- a/lib/gitlab/upgrader.rb +++ b/lib/gitlab/upgrader.rb @@ -1,3 +1,4 @@ +require_relative "popen" require_relative "version_info" module Gitlab -- cgit v1.2.3 From 4b2c50d53f32fcd09674dc8ba0aa9719ece73d56 Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Sat, 22 Mar 2014 20:09:23 +0100 Subject: Added some extra information how a good MR looks like --- CONTRIBUTING.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a6d6ec28ed9..47b04c11d24 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -77,6 +77,14 @@ Please keep the change in a single MR **as small as possible**. If you want to c For examples of feedback on merge requests please look at already [closed merge requests](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed). Please ensure that your merge request meets the following contribution acceptance criteria. +**Please format your merge request as follow:** + +1. What does this MR do? +2. Are there points in the code the reviewer needs to double check? +3. Why was this MR needed? +4. What are the relevant issue numbers / [Feedback items](http://feedback.gitlab.com/)? +5. Screenshots (If appropiate) + ## Contribution acceptance criteria 1. The change is as small as possible (see the above paragraph for details) -- cgit v1.2.3 From fa340595746ba18fae3c6422ff4c9ea4af8e3023 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sat, 22 Mar 2014 15:36:54 -0400 Subject: Default message for SatelliteNotExistError --- lib/gitlab/satellite/satellite.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb index bcf3012bd92..9e3c3997e55 100644 --- a/lib/gitlab/satellite/satellite.rb +++ b/lib/gitlab/satellite/satellite.rb @@ -1,5 +1,9 @@ module Gitlab - class SatelliteNotExistError < StandardError; end + class SatelliteNotExistError < StandardError + def initialize(msg = "Satellite doesn't exist") + super + end + end module Satellite class Satellite @@ -17,12 +21,8 @@ module Gitlab Gitlab::Satellite::Logger.error(message) end - def raise_no_satellite - raise SatelliteNotExistError.new("Satellite doesn't exist") - end - def clear_and_update! - raise_no_satellite unless exists? + raise SatelliteNotExistError unless exists? File.exists? path @repo = nil @@ -55,7 +55,7 @@ module Gitlab # * Changes the current directory to the satellite's working dir # * Yields def lock - raise_no_satellite unless exists? + raise SatelliteNotExistError unless exists? File.open(lock_file, "w+") do |f| begin @@ -77,7 +77,7 @@ module Gitlab end def repo - raise_no_satellite unless exists? + raise SatelliteNotExistError unless exists? @repo ||= Grit::Repo.new(path) end -- cgit v1.2.3 From 760f827ba0257d6664f429a832d1962fcac6e58e Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sat, 22 Mar 2014 15:40:42 -0400 Subject: Remove code that does nothing ping @karlhungus --- lib/gitlab/satellite/satellite.rb | 1 - spec/support/test_env.rb | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb index 9e3c3997e55..bdfcf254e9e 100644 --- a/lib/gitlab/satellite/satellite.rb +++ b/lib/gitlab/satellite/satellite.rb @@ -24,7 +24,6 @@ module Gitlab def clear_and_update! raise SatelliteNotExistError unless exists? - File.exists? path @repo = nil clear_working_dir! delete_heads! diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index e2c3f648ccf..d00decf6121 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -29,7 +29,6 @@ module TestEnv disable_mailer if opts[:mailer] == false setup_stubs - clear_test_repo_dir if opts[:init_repos] == true setup_test_repos(opts) if opts[:repos] == true end @@ -165,8 +164,7 @@ module TestEnv def clear_test_repo_dir setup_stubs - # Use tmp dir for FS manipulations - repos_path = testing_path() + # Remove tmp/test-git-base-path FileUtils.rm_rf Gitlab.config.gitlab_shell.repos_path -- cgit v1.2.3 From 85b5812bc21623c6a11ed92f482ac8282ec12fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81bner=20Silva=20de=20Oliveira?= Date: Sat, 22 Mar 2014 17:29:13 -0300 Subject: moving labels specs to projects_spec file --- spec/requests/api/labels_spec.rb | 26 -------------------------- spec/requests/api/projects_spec.rb | 13 +++++++++++++ 2 files changed, 13 insertions(+), 26 deletions(-) delete mode 100644 spec/requests/api/labels_spec.rb diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb deleted file mode 100644 index ba5efb6c603..00000000000 --- a/spec/requests/api/labels_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe API::API do - include ApiHelpers - before(:each) { ActiveRecord::Base.observers.enable(:user_observer) } - after(:each) { ActiveRecord::Base.observers.disable(:user_observer) } - - let(:user) { create(:user) } - let!(:project) { create(:project, namespace: user.namespace ) } - let!(:issue) { create(:issue, author: user, assignee: user, project: project, :label_list => "label1, label2") } - before { project.team << [user, :reporter] } - - - describe "GET /projects/:id/labels" do - it "should return project labels" do - get api("/projects/#{project.id}/labels", user) - response.status.should == 200 - json_response.should be_an Array - json_response.first['name'].should == 'label1' - json_response.last['name'].should == 'label2' - end - end - - -end - diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 149c5bffcda..7fe65639657 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -13,6 +13,7 @@ describe API::API do let(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') } let(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) } let(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) } + let(:issue_with_labels) { create(:issue, author: user, assignee: user, project: project, :label_list => "label1, label2") } describe "GET /projects" do before { project } @@ -632,4 +633,16 @@ describe API::API do end end end + + describe "GET /projects/:id/labels" do + before { issue_with_labels } + + it "should return project labels" do + get api("/projects/#{project.id}/labels", user) + response.status.should == 200 + json_response.should be_an Array + json_response.first['name'].should == issue_with_labels.labels.first.name + json_response.last['name'].should == issue_with_labels.labels.last.name + end + end end -- cgit v1.2.3 From 07833d16760bf30e4c9c84653909d4efe2dbcaff Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sat, 22 Mar 2014 16:37:54 -0400 Subject: Move Project's service specs to the correct location [ci skip] --- spec/services/project_transfer_service_spec.rb | 33 ----- spec/services/projects/create_service_spec.rb | 163 ++++++++++++++++++++++++ spec/services/projects/transfer_service_spec.rb | 33 +++++ spec/services/projects/update_service_spec.rb | 111 ++++++++++++++++ spec/services/projects_create_service_spec.rb | 163 ------------------------ spec/services/projects_update_service_spec.rb | 111 ---------------- 6 files changed, 307 insertions(+), 307 deletions(-) delete mode 100644 spec/services/project_transfer_service_spec.rb create mode 100644 spec/services/projects/create_service_spec.rb create mode 100644 spec/services/projects/transfer_service_spec.rb create mode 100644 spec/services/projects/update_service_spec.rb delete mode 100644 spec/services/projects_create_service_spec.rb delete mode 100644 spec/services/projects_update_service_spec.rb diff --git a/spec/services/project_transfer_service_spec.rb b/spec/services/project_transfer_service_spec.rb deleted file mode 100644 index 109b429967e..00000000000 --- a/spec/services/project_transfer_service_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'spec_helper' - -describe ProjectTransferService do - before(:each) { enable_observers } - after(:each) {disable_observers} - - context 'namespace -> namespace' do - let(:user) { create(:user) } - let(:group) { create(:group) } - let(:project) { create(:project, namespace: user.namespace) } - - before do - @result = service.transfer(project, group) - end - - it { @result.should be_true } - it { project.namespace.should == group } - end - - context 'namespace -> no namespace' do - let(:user) { create(:user) } - let(:project) { create(:project, namespace: user.namespace) } - - it { lambda{service.transfer(project, nil)}.should raise_error(ActiveRecord::RecordInvalid) } - end - - def service - service = ProjectTransferService.new - service.gitlab_shell.stub(mv_repository: true) - service - end -end - diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb new file mode 100644 index 00000000000..f2a784df103 --- /dev/null +++ b/spec/services/projects/create_service_spec.rb @@ -0,0 +1,163 @@ +require 'spec_helper' + +describe Projects::CreateService do + before(:each) { ActiveRecord::Base.observers.enable(:user_observer) } + after(:each) { ActiveRecord::Base.observers.disable(:user_observer) } + + describe :create_by_user do + before do + @user = create :user + @admin = create :user, admin: true + @opts = { + name: "GitLab", + namespace: @user.namespace + } + end + + context 'user namespace' do + before do + @project = create_project(@user, @opts) + end + + it { @project.should be_valid } + it { @project.owner.should == @user } + it { @project.namespace.should == @user.namespace } + end + + context 'group namespace' do + before do + @group = create :group + @group.add_owner(@user) + + @opts.merge!(namespace_id: @group.id) + @project = create_project(@user, @opts) + end + + it { @project.should be_valid } + it { @project.owner.should == @group } + it { @project.namespace.should == @group } + end + + context 'wiki_enabled creates repository directory' do + context 'wiki_enabled true creates wiki repository directory' do + before do + @project = create_project(@user, @opts) + @path = GollumWiki.new(@project, @user).send(:path_to_repo) + end + + it { File.exists?(@path).should be_true } + end + + context 'wiki_enabled false does not create wiki repository directory' do + before do + @opts.merge!(wiki_enabled: false) + @project = create_project(@user, @opts) + @path = GollumWiki.new(@project, @user).send(:path_to_repo) + end + + it { File.exists?(@path).should be_false } + end + end + + context 'respect configured visibility setting' do + before(:each) do + @settings = double("settings") + @settings.stub(:issues) { true } + @settings.stub(:merge_requests) { true } + @settings.stub(:wiki) { true } + @settings.stub(:wall) { true } + @settings.stub(:snippets) { true } + stub_const("Settings", Class.new) + @restrictions = double("restrictions") + @restrictions.stub(:restricted_visibility_levels) { [] } + Settings.stub_chain(:gitlab).and_return(@restrictions) + Settings.stub_chain(:gitlab, :default_projects_features).and_return(@settings) + end + + context 'should be public when setting is public' do + before do + @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PUBLIC } + @project = create_project(@user, @opts) + end + + it { @project.public?.should be_true } + end + + context 'should be private when setting is private' do + before do + @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PRIVATE } + @project = create_project(@user, @opts) + end + + it { @project.private?.should be_true } + end + + context 'should be internal when setting is internal' do + before do + @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::INTERNAL } + @project = create_project(@user, @opts) + end + + it { @project.internal?.should be_true } + end + end + + context 'respect configured visibility restrictions setting' do + before(:each) do + @settings = double("settings") + @settings.stub(:issues) { true } + @settings.stub(:merge_requests) { true } + @settings.stub(:wiki) { true } + @settings.stub(:wall) { true } + @settings.stub(:snippets) { true } + @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PRIVATE } + stub_const("Settings", Class.new) + @restrictions = double("restrictions") + @restrictions.stub(:restricted_visibility_levels) { [ Gitlab::VisibilityLevel::PUBLIC ] } + Settings.stub_chain(:gitlab).and_return(@restrictions) + Settings.stub_chain(:gitlab, :default_projects_features).and_return(@settings) + end + + context 'should be private when option is public' do + before do + @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + @project = create_project(@user, @opts) + end + + it { @project.private?.should be_true } + end + + context 'should be public when option is public for admin' do + before do + @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + @project = create_project(@admin, @opts) + end + + it { @project.public?.should be_true } + end + + context 'should be private when option is private' do + before do + @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + @project = create_project(@user, @opts) + end + + it { @project.private?.should be_true } + end + + context 'should be internal when option is internal' do + before do + @opts.merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + @project = create_project(@user, @opts) + end + + it { @project.internal?.should be_true } + end + end + end + + def create_project(user, opts) + Projects::CreateService.new(user, opts).execute + end +end + diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb new file mode 100644 index 00000000000..109b429967e --- /dev/null +++ b/spec/services/projects/transfer_service_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe ProjectTransferService do + before(:each) { enable_observers } + after(:each) {disable_observers} + + context 'namespace -> namespace' do + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project) { create(:project, namespace: user.namespace) } + + before do + @result = service.transfer(project, group) + end + + it { @result.should be_true } + it { project.namespace.should == group } + end + + context 'namespace -> no namespace' do + let(:user) { create(:user) } + let(:project) { create(:project, namespace: user.namespace) } + + it { lambda{service.transfer(project, nil)}.should raise_error(ActiveRecord::RecordInvalid) } + end + + def service + service = ProjectTransferService.new + service.gitlab_shell.stub(mv_repository: true) + service + end +end + diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb new file mode 100644 index 00000000000..1854c0d8233 --- /dev/null +++ b/spec/services/projects/update_service_spec.rb @@ -0,0 +1,111 @@ +require 'spec_helper' + +describe Projects::UpdateService do + before(:each) { ActiveRecord::Base.observers.enable(:user_observer) } + after(:each) { ActiveRecord::Base.observers.disable(:user_observer) } + + describe :update_by_user do + before do + @user = create :user + @admin = create :user, admin: true + @project = create :project, creator_id: @user.id, namespace: @user.namespace + @opts = { project: {} } + end + + context 'should be private when updated to private' do + before do + @created_private = @project.private? + + @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + update_project(@project, @user, @opts) + end + + it { @created_private.should be_true } + it { @project.private?.should be_true } + end + + context 'should be internal when updated to internal' do + before do + @created_private = @project.private? + + @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + update_project(@project, @user, @opts) + end + + it { @created_private.should be_true } + it { @project.internal?.should be_true } + end + + context 'should be public when updated to public' do + before do + @created_private = @project.private? + + @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + update_project(@project, @user, @opts) + end + + it { @created_private.should be_true } + it { @project.public?.should be_true } + end + + context 'respect configured visibility restrictions setting' do + before(:each) do + @restrictions = double("restrictions") + @restrictions.stub(:restricted_visibility_levels) { [ Gitlab::VisibilityLevel::PUBLIC ] } + Settings.stub_chain(:gitlab).and_return(@restrictions) + end + + context 'should be private when updated to private' do + before do + @created_private = @project.private? + + @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + update_project(@project, @user, @opts) + end + + it { @created_private.should be_true } + it { @project.private?.should be_true } + end + + context 'should be internal when updated to internal' do + before do + @created_private = @project.private? + + @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + update_project(@project, @user, @opts) + end + + it { @created_private.should be_true } + it { @project.internal?.should be_true } + end + + context 'should be private when updated to public' do + before do + @created_private = @project.private? + + @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + update_project(@project, @user, @opts) + end + + it { @created_private.should be_true } + it { @project.private?.should be_true } + end + + context 'should be public when updated to public by admin' do + before do + @created_private = @project.private? + + @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + update_project(@project, @admin, @opts) + end + + it { @created_private.should be_true } + it { @project.public?.should be_true } + end + end + end + + def update_project(project, user, opts) + Projects::UpdateService.new(project, user, opts).execute + end +end diff --git a/spec/services/projects_create_service_spec.rb b/spec/services/projects_create_service_spec.rb deleted file mode 100644 index f2a784df103..00000000000 --- a/spec/services/projects_create_service_spec.rb +++ /dev/null @@ -1,163 +0,0 @@ -require 'spec_helper' - -describe Projects::CreateService do - before(:each) { ActiveRecord::Base.observers.enable(:user_observer) } - after(:each) { ActiveRecord::Base.observers.disable(:user_observer) } - - describe :create_by_user do - before do - @user = create :user - @admin = create :user, admin: true - @opts = { - name: "GitLab", - namespace: @user.namespace - } - end - - context 'user namespace' do - before do - @project = create_project(@user, @opts) - end - - it { @project.should be_valid } - it { @project.owner.should == @user } - it { @project.namespace.should == @user.namespace } - end - - context 'group namespace' do - before do - @group = create :group - @group.add_owner(@user) - - @opts.merge!(namespace_id: @group.id) - @project = create_project(@user, @opts) - end - - it { @project.should be_valid } - it { @project.owner.should == @group } - it { @project.namespace.should == @group } - end - - context 'wiki_enabled creates repository directory' do - context 'wiki_enabled true creates wiki repository directory' do - before do - @project = create_project(@user, @opts) - @path = GollumWiki.new(@project, @user).send(:path_to_repo) - end - - it { File.exists?(@path).should be_true } - end - - context 'wiki_enabled false does not create wiki repository directory' do - before do - @opts.merge!(wiki_enabled: false) - @project = create_project(@user, @opts) - @path = GollumWiki.new(@project, @user).send(:path_to_repo) - end - - it { File.exists?(@path).should be_false } - end - end - - context 'respect configured visibility setting' do - before(:each) do - @settings = double("settings") - @settings.stub(:issues) { true } - @settings.stub(:merge_requests) { true } - @settings.stub(:wiki) { true } - @settings.stub(:wall) { true } - @settings.stub(:snippets) { true } - stub_const("Settings", Class.new) - @restrictions = double("restrictions") - @restrictions.stub(:restricted_visibility_levels) { [] } - Settings.stub_chain(:gitlab).and_return(@restrictions) - Settings.stub_chain(:gitlab, :default_projects_features).and_return(@settings) - end - - context 'should be public when setting is public' do - before do - @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PUBLIC } - @project = create_project(@user, @opts) - end - - it { @project.public?.should be_true } - end - - context 'should be private when setting is private' do - before do - @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PRIVATE } - @project = create_project(@user, @opts) - end - - it { @project.private?.should be_true } - end - - context 'should be internal when setting is internal' do - before do - @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::INTERNAL } - @project = create_project(@user, @opts) - end - - it { @project.internal?.should be_true } - end - end - - context 'respect configured visibility restrictions setting' do - before(:each) do - @settings = double("settings") - @settings.stub(:issues) { true } - @settings.stub(:merge_requests) { true } - @settings.stub(:wiki) { true } - @settings.stub(:wall) { true } - @settings.stub(:snippets) { true } - @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PRIVATE } - stub_const("Settings", Class.new) - @restrictions = double("restrictions") - @restrictions.stub(:restricted_visibility_levels) { [ Gitlab::VisibilityLevel::PUBLIC ] } - Settings.stub_chain(:gitlab).and_return(@restrictions) - Settings.stub_chain(:gitlab, :default_projects_features).and_return(@settings) - end - - context 'should be private when option is public' do - before do - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - @project = create_project(@user, @opts) - end - - it { @project.private?.should be_true } - end - - context 'should be public when option is public for admin' do - before do - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - @project = create_project(@admin, @opts) - end - - it { @project.public?.should be_true } - end - - context 'should be private when option is private' do - before do - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) - @project = create_project(@user, @opts) - end - - it { @project.private?.should be_true } - end - - context 'should be internal when option is internal' do - before do - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - @project = create_project(@user, @opts) - end - - it { @project.internal?.should be_true } - end - end - end - - def create_project(user, opts) - Projects::CreateService.new(user, opts).execute - end -end - diff --git a/spec/services/projects_update_service_spec.rb b/spec/services/projects_update_service_spec.rb deleted file mode 100644 index 1854c0d8233..00000000000 --- a/spec/services/projects_update_service_spec.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'spec_helper' - -describe Projects::UpdateService do - before(:each) { ActiveRecord::Base.observers.enable(:user_observer) } - after(:each) { ActiveRecord::Base.observers.disable(:user_observer) } - - describe :update_by_user do - before do - @user = create :user - @admin = create :user, admin: true - @project = create :project, creator_id: @user.id, namespace: @user.namespace - @opts = { project: {} } - end - - context 'should be private when updated to private' do - before do - @created_private = @project.private? - - @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) - update_project(@project, @user, @opts) - end - - it { @created_private.should be_true } - it { @project.private?.should be_true } - end - - context 'should be internal when updated to internal' do - before do - @created_private = @project.private? - - @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - update_project(@project, @user, @opts) - end - - it { @created_private.should be_true } - it { @project.internal?.should be_true } - end - - context 'should be public when updated to public' do - before do - @created_private = @project.private? - - @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - update_project(@project, @user, @opts) - end - - it { @created_private.should be_true } - it { @project.public?.should be_true } - end - - context 'respect configured visibility restrictions setting' do - before(:each) do - @restrictions = double("restrictions") - @restrictions.stub(:restricted_visibility_levels) { [ Gitlab::VisibilityLevel::PUBLIC ] } - Settings.stub_chain(:gitlab).and_return(@restrictions) - end - - context 'should be private when updated to private' do - before do - @created_private = @project.private? - - @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) - update_project(@project, @user, @opts) - end - - it { @created_private.should be_true } - it { @project.private?.should be_true } - end - - context 'should be internal when updated to internal' do - before do - @created_private = @project.private? - - @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - update_project(@project, @user, @opts) - end - - it { @created_private.should be_true } - it { @project.internal?.should be_true } - end - - context 'should be private when updated to public' do - before do - @created_private = @project.private? - - @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - update_project(@project, @user, @opts) - end - - it { @created_private.should be_true } - it { @project.private?.should be_true } - end - - context 'should be public when updated to public by admin' do - before do - @created_private = @project.private? - - @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - update_project(@project, @admin, @opts) - end - - it { @created_private.should be_true } - it { @project.public?.should be_true } - end - end - end - - def update_project(project, user, opts) - Projects::UpdateService.new(project, user, opts).execute - end -end -- cgit v1.2.3 From 3704d85bc49e76891f37f3b14d6fddb499921ed8 Mon Sep 17 00:00:00 2001 From: awiddersheim Date: Sat, 22 Mar 2014 16:44:13 -0400 Subject: Remove periods from merge request The "Merged by" and "Closed by" statements end with an extra space followed by a period. This doesn't seem necessary to me and not having the extra space followed by a period looks better to me. Also, the top of the merge request doesn't have the sentence ending with a period. --- app/views/projects/merge_requests/show/_mr_box.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml index 38db4363ade..abdcd127a0c 100644 --- a/app/views/projects/merge_requests/show/_mr_box.html.haml +++ b/app/views/projects/merge_requests/show/_mr_box.html.haml @@ -29,13 +29,13 @@ %span %i.icon-remove Closed by #{link_to_member(@project, @merge_request.closed_event.author)} - #{time_ago_with_tooltip(@merge_request.closed_event.created_at)}. + #{time_ago_with_tooltip(@merge_request.closed_event.created_at)} - if @merge_request.merged? .alert.alert-info %span %i.icon-ok Merged by #{link_to_member(@project, @merge_request.merge_event.author)} - #{time_ago_with_tooltip(@merge_request.merge_event.created_at)}. + #{time_ago_with_tooltip(@merge_request.merge_event.created_at)} - if !@closes_issues.empty? && @merge_request.open? .alert.alert-info.alert-info %span -- cgit v1.2.3 From 6adbfda2f832b7e0e5a16718d625a3be3f137819 Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Sun, 23 Mar 2014 19:07:09 +0100 Subject: Better naming things --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47b04c11d24..d816f8e72a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -77,12 +77,12 @@ Please keep the change in a single MR **as small as possible**. If you want to c For examples of feedback on merge requests please look at already [closed merge requests](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed). Please ensure that your merge request meets the following contribution acceptance criteria. -**Please format your merge request as follow:** +**Please format your merge request description as follows:** 1. What does this MR do? 2. Are there points in the code the reviewer needs to double check? 3. Why was this MR needed? -4. What are the relevant issue numbers / [Feedback items](http://feedback.gitlab.com/)? +4. What are the relevant issue numbers / [Feature requests](http://feedback.gitlab.com/)? 5. Screenshots (If appropiate) ## Contribution acceptance criteria -- cgit v1.2.3 From e153469f31db106d0720e357a5e22431635f2b9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81bner=20Silva=20de=20Oliveira?= Date: Sun, 23 Mar 2014 19:07:18 -0300 Subject: changed doc comment for get labels of a project --- lib/api/projects.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 40b5ce86c93..9d290c75ba9 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -216,10 +216,12 @@ module API present @users, with: Entities::User end - # Get a labels list + # Get a project labels # + # Parameters: + # id (required) - The ID of a project # Example Request: - # GET /users + # GET /projects/:id/labels get ':id/labels' do @labels = user_project.issues_labels present @labels, with: Entities::Label -- cgit v1.2.3 From 19938156d89ea980596fd5b1d72856f3defb228a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81bner=20Silva=20de=20Oliveira?= Date: Sun, 23 Mar 2014 19:20:17 -0300 Subject: documentation for api method which get labels of a project --- doc/api/projects.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/doc/api/projects.md b/doc/api/projects.md index 6e82ddd9903..54618d7c045 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -621,3 +621,29 @@ Parameters: + query (required) - A string contained in the project name + per_page (optional) - number of projects to return per page + page (optional) - the page to retrieve + + +## Labels + +### List project labels + +Get a list of project labels. + +``` +GET /projects/:id/labels +``` + +Parameters: + ++ `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project + +```json +[ + { + "name":"featute" + }, + { + "name": "bug" + } +] +``` -- cgit v1.2.3 From 6672d6492f8a118d6ef26efaec38d3b1bab9223a Mon Sep 17 00:00:00 2001 From: Ciro Santillli Date: Sun, 23 Mar 2014 23:49:22 +0100 Subject: Start development Key seed id from 1. --- db/fixtures/development/11_keys.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/fixtures/development/11_keys.rb b/db/fixtures/development/11_keys.rb index 42171393d1b..61329f197c3 100644 --- a/db/fixtures/development/11_keys.rb +++ b/db/fixtures/development/11_keys.rb @@ -2,7 +2,7 @@ Gitlab::Seeder.quiet do User.first(30).each_with_index do |user, i| Key.seed(:id, [ { - id: i, + id: i + 1, title: "Sample key #{i}", key: "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt#{i + 100}6k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", user_id: user.id, -- cgit v1.2.3 From dab09af518a1ab573b30f12895b448790bc66222 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Sun, 23 Mar 2014 21:17:01 -0500 Subject: Mobile UI Improvements Move spinner for mobile --- app/assets/stylesheets/sections/header.scss | 6 ++++++ app/views/layouts/_public_head_panel.html.haml | 16 ++++++++++------ app/views/layouts/public_projects.html.haml | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss index f8da4f0f87b..06709bd7ef6 100644 --- a/app/assets/stylesheets/sections/header.scss +++ b/app/assets/stylesheets/sections/header.scss @@ -273,3 +273,9 @@ header { } } } + +@media (max-width: $screen-xs-max) { + #nprogress .spinner { + right: 35px !important; + } +} diff --git a/app/views/layouts/_public_head_panel.html.haml b/app/views/layouts/_public_head_panel.html.haml index 99e11cd2b5c..63992a22f32 100644 --- a/app/views/layouts/_public_head_panel.html.haml +++ b/app/views/layouts/_public_head_panel.html.haml @@ -8,11 +8,15 @@ %span.separator %h1.title= title - .pull-right + %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} + %span.sr-only Toggle navigation + %i.icon-reorder + + .pull-right.hidden-xs = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in btn-new' - %ul.nav.navbar-nav - %li - %a - %div.hide.turbolink-spinner - %i.icon-refresh.icon-spin + .navbar-collapse.collapse + %ul.nav.navbar-nav + %li.visible-xs + = link_to "Sign in", new_session_path(:user) + diff --git a/app/views/layouts/public_projects.html.haml b/app/views/layouts/public_projects.html.haml index cf4ca9c7a84..2a9230244f8 100644 --- a/app/views/layouts/public_projects.html.haml +++ b/app/views/layouts/public_projects.html.haml @@ -4,7 +4,7 @@ %body{class: "#{app_theme} application", :'data-page' => body_data_page} = render "layouts/broadcast" = render "layouts/public_head_panel", title: project_title(@project) - %nav.main-nav + %nav.main-nav.navbar-collapse.collapse .container= render 'layouts/nav/project' .container .content= yield -- cgit v1.2.3 From b816389182084bd0234d8409bdd4cfef41f8e502 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 24 Mar 2014 09:52:50 +0100 Subject: Suppress 'Rendered' messages in production.log --- config/environments/production.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/environments/production.rb b/config/environments/production.rb index 9ac4622abc2..87c5efd2142 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -33,6 +33,11 @@ Gitlab::Application.configure do # See everything in the log (default is :info) # config.log_level = :debug + # Suppress 'Rendered template ...' messages in the log + %w{render_template render_partial render_collection}.each do |event| + ActiveSupport::Notifications.unsubscribe "#{event}.action_view" + end + # Prepend all log lines with the following tags # config.log_tags = [ :subdomain, :uuid ] -- cgit v1.2.3 From 7862201de9e3e8229e33a28d17fb2edb691eead0 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 24 Mar 2014 09:57:28 +0100 Subject: Add source for 'Rendered' message suppression --- config/environments/production.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/environments/production.rb b/config/environments/production.rb index 87c5efd2142..ad3c03d8fc9 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -34,6 +34,7 @@ Gitlab::Application.configure do # config.log_level = :debug # Suppress 'Rendered template ...' messages in the log + # source: http://stackoverflow.com/a/16369363 %w{render_template render_partial render_collection}.each do |event| ActiveSupport::Notifications.unsubscribe "#{event}.action_view" end -- cgit v1.2.3 From 00487d455a10e074a4539a231a9b3028853a7334 Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 24 Mar 2014 12:04:43 +0100 Subject: References for the issues the guide addresses. --- doc/development/shell_commands.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/development/shell_commands.md b/doc/development/shell_commands.md index 57b1172d5e6..63e58a63080 100644 --- a/doc/development/shell_commands.md +++ b/doc/development/shell_commands.md @@ -1,5 +1,11 @@ # Guidelines for shell commands in the GitLab codebase +## References + +- [Google Ruby Security Reviewer's Guide](https://code.google.com/p/ruby-security/wiki/Guide) +- [OWASP Command Injection](https://www.owasp.org/index.php/Command_Injection) +- [Ruby on Rails Security Guide](http://guides.rubyonrails.org/security.html) section 7.7 + ## Use File and FileUtils instead of shell commands Sometimes we invoke basic Unix commands via the shell when there is also a Ruby API for doing it. -- cgit v1.2.3 From de5e41c67d1e0c2d4aa53fbe863a8b3f7e24f731 Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 24 Mar 2014 13:35:24 +0100 Subject: Move up in the month. --- doc/release/monthly.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/doc/release/monthly.md b/doc/release/monthly.md index 28fc260b334..77502a97833 100644 --- a/doc/release/monthly.md +++ b/doc/release/monthly.md @@ -58,16 +58,14 @@ Check if changed since last release (~22nd of last month depending on when last After making the release branch new commits are cherry-picked from master. When the release gets closer we get more selective what is cherry-picked. The days of the month are approximately as follows: -* 17th: feature freeze (stop merging new features in master) -* 18th: UI freeze (stop merging changes to the user interface) -* 19th: code freeze (stop merging non-essential code improvements) -* 20th: release candidate 1 (VERSION x.x.0.rc1, tag and tweet about x.x.0.rc1) -* 21st: optional release candidate 2 (x.x.0.rc2, only if rc1 had problems) +* 1-7th: official merge window (see contributing guide) +* 8-14th: work on bugfixes, sponsored features and GitLab EE +* 15th: code freeze (stop merging into master except essential bugfixes) +* 18th: release candidate 1 (VERSION x.x.0.rc1, tag and tweet about x.x.0.rc1, release on GitLab Cloud) +* 20st: optional release candidate 2 (x.x.0.rc2, only if rc1 had problems) * 22nd: release (VERSION x.x.0, create x-x-stable branch, tag, blog and tweet) * 23nd: optional patch releases (x.x.1, x.x.2, etc., only if there are serious problems) -* 24-end of month: release Enterprise Edition and upgrade GitLab Cloud -* 1-7th: official merge window (see contributing guide) -* 8-16th: bugfixes and sponsored features +* 24-end of month: release GitLab EE and GitLab CI # Write a blog post -- cgit v1.2.3 From 1e3b5c3787bcd7f1fce775e2c3de5ce0aabc813d Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 13 Mar 2014 18:34:12 -0400 Subject: Remove Spork --- Gemfile | 1 - Gemfile.lock | 2 -- spec/spec_helper.rb | 101 +++++++++++++++++++++++----------------------------- 3 files changed, 44 insertions(+), 60 deletions(-) diff --git a/Gemfile b/Gemfile index 5b58ce443ae..397165f668f 100644 --- a/Gemfile +++ b/Gemfile @@ -218,7 +218,6 @@ group :development, :test do # PhantomJS driver for Capybara gem 'poltergeist', '~> 1.4.1' - gem 'spork', '~> 1.0rc' gem 'jasmine', '2.0.0.rc5' gem "spring", '1.1.1' diff --git a/Gemfile.lock b/Gemfile.lock index 167fd960ff5..1a0bce98ac5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -484,7 +484,6 @@ GEM capybara (>= 2.0.0) railties (>= 3) spinach (>= 0.4) - spork (1.0.0rc4) spring (1.1.1) spring-commands-rspec (1.0.1) spring (>= 0.9.1) @@ -661,7 +660,6 @@ DEPENDENCIES slack-notifier (~> 0.2.0) slim spinach-rails - spork (~> 1.0rc) spring (= 1.1.1) spring-commands-rspec (= 1.0.1) spring-commands-spinach (= 1.0.0) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dd008ed02ad..e6b1f816df0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,63 +1,50 @@ -require 'rubygems' -require 'spork' +# This file is copied to spec/ when you run 'rails generate rspec:install' +ENV["RAILS_ENV"] ||= 'test' +require File.expand_path("../../config/environment", __FILE__) -Spork.prefork do - require 'simplecov' unless ENV['CI'] +require 'simplecov' unless ENV['CI'] - if ENV['TRAVIS'] - require 'coveralls' - Coveralls.wear! - end - - # This file is copied to spec/ when you run 'rails generate rspec:install' - ENV["RAILS_ENV"] ||= 'test' - require File.expand_path("../../config/environment", __FILE__) - require 'rspec/rails' - require 'capybara/rails' - require 'capybara/rspec' - require 'webmock/rspec' - require 'email_spec' - require 'sidekiq/testing/inline' - require 'capybara/poltergeist' - - # Loading more in this block will cause your tests to run faster. However, - - # if you change any configuration or code from libraries loaded here, you'll - # need to restart spork for it take effect. - Capybara.javascript_driver = :poltergeist - Capybara.default_wait_time = 10 - - # Requires supporting ruby files with custom matchers and macros, etc, - # in spec/support/ and its subdirectories. - Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} - - WebMock.disable_net_connect!(allow_localhost: true) - - RSpec.configure do |config| - config.mock_with :rspec - - config.include LoginHelpers, type: :feature - config.include LoginHelpers, type: :request - config.include FactoryGirl::Syntax::Methods - config.include Devise::TestHelpers, type: :controller - - config.include TestEnv - - # If you're not using ActiveRecord, or you'd prefer not to run each of your - # examples within a transaction, remove the following line or assign false - # instead of true. - config.use_transactional_fixtures = false - - config.before(:suite) do - TestEnv.init(observers: false, init_repos: true, repos: false) - end - config.before(:each) do - TestEnv.setup_stubs - end - end +if ENV['TRAVIS'] + require 'coveralls' + Coveralls.wear! end -Spork.each_run do - # This code will be run each time you run your specs. +require 'rspec/rails' +require 'capybara/rails' +require 'capybara/rspec' +require 'webmock/rspec' +require 'email_spec' +require 'sidekiq/testing/inline' +require 'capybara/poltergeist' + +Capybara.javascript_driver = :poltergeist +Capybara.default_wait_time = 10 + +# Requires supporting ruby files with custom matchers and macros, etc, +# in spec/support/ and its subdirectories. +Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} + +WebMock.disable_net_connect!(allow_localhost: true) +RSpec.configure do |config| + config.mock_with :rspec + + config.include LoginHelpers, type: :feature + config.include LoginHelpers, type: :request + config.include FactoryGirl::Syntax::Methods + config.include Devise::TestHelpers, type: :controller + + config.include TestEnv + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = false + + config.before(:suite) do + TestEnv.init(observers: false, init_repos: true, repos: false) + end + config.before(:each) do + TestEnv.setup_stubs + end end -- cgit v1.2.3 From 2855a799fde6ec60c5bfff348f6dfa9b1e480bcc Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 18 Mar 2014 20:01:17 -0400 Subject: Remove --drb from .rspec --- .rspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rspec b/.rspec index 7488cbe7792..4e1e0d2f722 100644 --- a/.rspec +++ b/.rspec @@ -1 +1 @@ ---color --drb +--color -- cgit v1.2.3 From a87f03768f87c3ebe62b7aaf94380eb56239bd4e Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 18 Mar 2014 20:05:10 -0400 Subject: Fix deprecation warning output Removes the following from test output: DEPRECATION WARNING: It looks like you are eager loading table(s) (one of: merge_requests, projects) that are referenced in a string SQL snippet. For example: Post.includes(:comments).where("comments.title = 'foo'") Currently, Active Record recognizes the table in the string, and knows to JOIN the comments table to the query, rather than loading comments in a separate query. However, doing this without writing a full-blown SQL parser is inherently flawed. Since we don't want to write an SQL parser, we are removing this functionality. From now on, you must explicitly tell Active Record when you are referencing a table from a string: Post.includes(:comments).where("comments.title = 'foo'").references(:comments) If you don't rely on implicit join references you can disable the feature entirely by setting `config.active_record.disable_implicit_join_references = true`. --- app/finders/base_finder.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/finders/base_finder.rb b/app/finders/base_finder.rb index d20716fb170..7fc5840561c 100644 --- a/app/finders/base_finder.rb +++ b/app/finders/base_finder.rb @@ -47,9 +47,9 @@ class BaseFinder [] end elsif current_user && params[:authorized_only].presence - klass.of_projects(current_user.authorized_projects) + klass.of_projects(current_user.authorized_projects).references(:project) else - klass.of_projects(Project.accessible_to(current_user)) + klass.of_projects(Project.accessible_to(current_user)).references(:project) end end -- cgit v1.2.3 From 5fbf15cb88411ebca2156dfefe993503e074ce3e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 24 Mar 2014 15:10:21 +0200 Subject: Add proper explanation to MR in archived projects Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/merge_requests/show/_mr_accept.html.haml | 8 ++++++-- app/views/projects/show.html.haml | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml index 97706a5a4b0..4b1857ccb68 100644 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml @@ -1,6 +1,10 @@ - unless @allowed_to_merge - .bs-callout - %strong You don't have permission to merge this MR + - if @project.archived? + .bs-callout.bs-callout-warning + %strong Archived projects cannot be committed to! + - else + .bs-callout + %strong You don't have permission to merge this MR - if @show_merge_controls diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 8a1e1d3354b..20879d69091 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -9,8 +9,8 @@ .col-md-3.project-side.hidden-sm .clearfix - if @project.archived? - .alert - %h5 + .alert.alert-warning + %h4 %i.icon-warning-sign Archived project! %p Repository is read-only -- cgit v1.2.3 From eb4320cb07db2b704d6e976fe9e2ac7d959b6c25 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 24 Mar 2014 15:20:29 +0200 Subject: Remove assignee/milestone selects from MR form Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/merge_requests/_form.html.haml | 45 +++++++---------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml index 51fa29ddcbe..22502760e50 100644 --- a/app/views/projects/merge_requests/_form.html.haml +++ b/app/views/projects/merge_requests/_form.html.haml @@ -1,13 +1,18 @@ -- if @repository.contribution_guide && !@merge_request.persisted? - - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name)) - .alert.alert-info.col-sm-10.col-sm-offset-2 - ="Please review the #{link_to "guidelines for contribution", contribution_guide_url} to this repository.".html_safe = form_for [@project, @merge_request], html: { class: "merge-request-form form-horizontal" } do |f| - -if @merge_request.errors.any? - .alert.alert-danger - %ul - - @merge_request.errors.full_messages.each do |msg| - %li= msg + .row + .col-sm-2 + .col-sm-10 + - if @repository.contribution_guide && !@merge_request.persisted? + - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name)) + .alert.alert-info + Please review the + %strong #{link_to "guidelines for contribution", contribution_guide_url} + to this repository. + + -if @merge_request.errors.any? + .alert.alert-danger + - @merge_request.errors.full_messages.each do |msg| + %div= msg .merge-request-branches .form-group @@ -47,24 +52,6 @@ = f.text_area :description, class: "form-control js-gfm-input", rows: 14 %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. - %hr - .form-group - .merge-request-assignee - = f.label :assignee_id, class: 'control-label' do - %i.icon-user - Assign to - .col-sm-10 - = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id) -   - = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link' - .form-group - .merge-request-milestone - = f.label :milestone_id, class: 'control-label' do - %i.icon-time - Milestone - .col-sm-10= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'}) - - .form-actions - if @merge_request.new_record? = f.submit 'Submit merge request', class: "btn btn-create" @@ -96,7 +83,3 @@ target_branch.on("change", function() { $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() }); }); - $('.assign-to-me-link').on('click', function(e){ - $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change"); - e.preventDefault(); - }); -- cgit v1.2.3 From 5e985a7eed7317d4f0ed323c4f6f7d0f386fbde4 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 24 Mar 2014 14:22:11 +0100 Subject: Use emoji assets on autocomplete. --- app/assets/javascripts/gfm_auto_complete.js.coffee | 3 +-- app/controllers/projects_controller.rb | 2 +- app/views/layouts/_init_auto_complete.html.haml | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index dd12000a1cf..00d56ae5b4b 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -6,7 +6,6 @@ GitLab.GfmAutoComplete = dataSource: '' # Emoji Emoji: - assetBase: '' template: '
  • ${name} ${name}
  • ' # Team Members @@ -27,7 +26,7 @@ GitLab.GfmAutoComplete = tpl: @Emoji.template callbacks: before_save: (emojis) => - $.map emojis, (em) => name: em, insert: em+ ':', image: "#{@Emoji.assetBase}/#{em}.png" + $.map emojis, (em) => name: em.name, insert: em.name+ ':', image: em.path # Team Members input.atwho diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 8d24052f724..e181a0ec7fa 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -124,7 +124,7 @@ class ProjectsController < ApplicationController def autocomplete_sources @suggestions = { - emojis: Emoji.names, + emojis: Emoji.names.map { |e| { name: e, path: view_context.image_url("emoji/#{e}.png") } }, issues: @project.issues.select([:iid, :title, :description]), mergerequests: @project.merge_requests.select([:iid, :title, :description]), members: @project.team.members.sort_by(&:username).map { |user| { username: user.username, name: user.name } } diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml index fd6097dcc7b..9e728b462bb 100644 --- a/app/views/layouts/_init_auto_complete.html.haml +++ b/app/views/layouts/_init_auto_complete.html.haml @@ -1,4 +1,3 @@ :javascript GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_project_path(@project)}" - GitLab.GfmAutoComplete.Emoji.assetBase = "#{Gitlab.config.gitlab.relative_url_root + Emoji.asset_path}" GitLab.GfmAutoComplete.setup(); -- cgit v1.2.3 From f9a69ab1da1f311e11f56b29ffe295598a754fe5 Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 24 Mar 2014 14:22:26 +0100 Subject: Inform people about the verify-none for webhooks. --- doc/web_hooks/web_hooks.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md index 64cce45945e..f80891e264d 100644 --- a/doc/web_hooks/web_hooks.md +++ b/doc/web_hooks/web_hooks.md @@ -5,6 +5,7 @@ Project web hooks allow you to trigger an URL if new code is pushed or a new iss You can configure web hook to listen for specific events like pushes, issues, merge requests. GitLab will send POST request with data to web hook URL. Web Hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. +If you send a web hook to an SSL endpoint [the certificate will not be verified](https://gitlab.com/gitlab-org/gitlab-ce/blob/ccd617e58ea71c42b6b073e692447d0fe3c00be6/app/models/web_hook.rb#L35) since many people use self-signed certificates. --- -- cgit v1.2.3 From 842c0d6b5f7a60a4e4523fe1faefaab5038c96eb Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 24 Mar 2014 14:31:35 +0100 Subject: Can deeplink after all. --- doc/development/shell_commands.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/development/shell_commands.md b/doc/development/shell_commands.md index 63e58a63080..af0d5ca4426 100644 --- a/doc/development/shell_commands.md +++ b/doc/development/shell_commands.md @@ -4,7 +4,7 @@ - [Google Ruby Security Reviewer's Guide](https://code.google.com/p/ruby-security/wiki/Guide) - [OWASP Command Injection](https://www.owasp.org/index.php/Command_Injection) -- [Ruby on Rails Security Guide](http://guides.rubyonrails.org/security.html) section 7.7 +- [Ruby on Rails Security Guide Command Line Injection](http://guides.rubyonrails.org/security.html#command-line-injection) ## Use File and FileUtils instead of shell commands -- cgit v1.2.3 From 8af94ed75505f0253823b9b2d44320fecea5b5fb Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 24 Mar 2014 14:59:09 +0100 Subject: Add gzip compression for assets to nginx example. --- lib/support/nginx/gitlab | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 7a0f3efbb53..5bff362da0e 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -54,6 +54,14 @@ server { proxy_pass http://gitlab; } + # Enable gzip compression as per rails guide: http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression + location ~ ^/(assets)/ { + root /home/git/gitlab/public; + gzip_static on; # to serve pre-gzipped version + expires max; + add_header Cache-Control public; + } + error_page 502 /502.html; } -- cgit v1.2.3 From 65f5496e0210be96b4803f655d1a4c94ef1e07fe Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 24 Mar 2014 15:11:35 +0100 Subject: Fix the merge notification email not being sent The 'author_id_of_changes' attribute is not persisted in the database. As we retrieve the merge request from the DB just before sending the email, this attribute was always nil. Also there was no tests for the merge notification code - tests have been added. Fix #6605 --- app/mailers/emails/merge_requests.rb | 4 ++-- app/services/notification_service.rb | 2 +- spec/mailers/notify_spec.rb | 24 ++++++++++++++++++++++++ spec/services/notification_service_spec.rb | 6 +++--- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb index 5e1b8faf13e..a97d55f1b50 100644 --- a/app/mailers/emails/merge_requests.rb +++ b/app/mailers/emails/merge_requests.rb @@ -29,11 +29,11 @@ module Emails subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) end - def merged_merge_request_email(recipient_id, merge_request_id) + def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) @merge_request = MergeRequest.find(merge_request_id) @project = @merge_request.project @target_url = project_merge_request_url(@project, @merge_request) - mail(from: sender(@merge_request.author_id_of_changes), + mail(from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 5daf573630d..44fe9893e74 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -91,7 +91,7 @@ class NotificationService recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq recipients.each do |recipient| - mailer.merged_merge_request_email(recipient.id, merge_request.id) + mailer.merged_merge_request_email(recipient.id, merge_request.id, merge_request.author_id_of_changes) end end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index f990ed659b8..22d60429ccd 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -229,6 +229,7 @@ describe Notify do end context 'for merge requests' do + let(:merge_author) { create(:user) } let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) } let(:merge_request_with_description) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project, description: Faker::Lorem.sentence) } @@ -288,7 +289,30 @@ describe Notify do it 'contains a link to the merge request' do should have_body_text /#{project_merge_request_path project, merge_request}/ end + end + + describe 'that are merged' do + subject { Notify.merged_merge_request_email(recipient.id, merge_request.id, merge_author.id) } + + it_behaves_like 'a multiple recipients email' + + it 'is sent as the merge author' do + sender = subject.header[:from].addrs[0] + sender.display_name.should eq(merge_author.name) + sender.address.should eq(gitlab_sender) + end + + it 'has the correct subject' do + should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/ + end + it 'contains the new status' do + should have_body_text /merged/i + end + + it 'contains a link to the merge request' do + should have_body_text /#{project_merge_request_path project, merge_request}/ + end end end end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 077ad8b6e12..59c17d6e4d7 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -233,15 +233,15 @@ describe NotificationService do should_email(@u_watcher.id) should_not_email(@u_participating.id) should_not_email(@u_disabled.id) - notification.merge_mr(merge_request) + notification.merge_mr(merge_request, @u_disabled) end def should_email(user_id) - Notify.should_receive(:merged_merge_request_email).with(user_id, merge_request.id) + Notify.should_receive(:merged_merge_request_email).with(user_id, merge_request.id, @u_disabled.id) end def should_not_email(user_id) - Notify.should_not_receive(:merged_merge_request_email).with(user_id, merge_request.id) + Notify.should_not_receive(:merged_merge_request_email).with(user_id, merge_request.id, @u_disabled.id) end end end -- cgit v1.2.3 From 3ef0a625ac656e64861df912492dc3b8febb66c3 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 24 Mar 2014 16:12:23 +0200 Subject: Applications js to coffee Signed-off-by: Dmitriy Zaporozhets --- app/assets/javascripts/application.js | 33 ------ app/assets/javascripts/application.js.coffee | 154 +++++++++++++++++++++++++++ app/assets/javascripts/main.js.coffee | 120 --------------------- 3 files changed, 154 insertions(+), 153 deletions(-) delete mode 100644 app/assets/javascripts/application.js create mode 100644 app/assets/javascripts/application.js.coffee delete mode 100644 app/assets/javascripts/main.js.coffee diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js deleted file mode 100644 index f69b750bb69..00000000000 --- a/app/assets/javascripts/application.js +++ /dev/null @@ -1,33 +0,0 @@ -// This is a manifest file that'll be compiled into including all the files listed below. -// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically -// be included in the compiled file accessible from http://example.com/assets/application.js -// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -// the compiled file. -// -//= require jquery -//= require jquery.ui.all -//= require jquery_ujs -//= require jquery.cookie -//= require jquery.endless-scroll -//= require jquery.highlight -//= require jquery.history -//= require jquery.waitforimages -//= require jquery.atwho -//= require jquery.scrollto -//= require jquery.blockUI -//= require turbolinks -//= require jquery.turbolinks -//= require bootstrap -//= require modernizr -//= require select2 -//= require raphael -//= require g.raphael-min -//= require g.bar-min -//= require branch-graph -//= require highlightjs.min -//= require ace/ace -//= require_tree . -//= require d3 -//= require underscore -//= require nprogress -//= require nprogress-turbolinks diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee new file mode 100644 index 00000000000..5042221abe4 --- /dev/null +++ b/app/assets/javascripts/application.js.coffee @@ -0,0 +1,154 @@ +# This is a manifest file that'll be compiled into including all the files listed below. +# Add new JavaScript/Coffee code in separate files in this directory and they'll automatically +# be included in the compiled file accessible from http://example.com/assets/application.js +# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +# the compiled file. +# +#= require jquery +#= require jquery.ui.all +#= require jquery_ujs +#= require jquery.cookie +#= require jquery.endless-scroll +#= require jquery.highlight +#= require jquery.history +#= require jquery.waitforimages +#= require jquery.atwho +#= require jquery.scrollto +#= require jquery.blockUI +#= require turbolinks +#= require jquery.turbolinks +#= require bootstrap +#= require modernizr +#= require select2 +#= require raphael +#= require g.raphael-min +#= require g.bar-min +#= require branch-graph +#= require highlightjs.min +#= require ace/ace +#= require d3 +#= require underscore +#= require nprogress +#= require nprogress-turbolinks +#= require_tree . + +window.slugify = (text) -> + text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase() + +window.ajaxGet = (url) -> + $.ajax({type: "GET", url: url, dataType: "script"}) + +window.showAndHide = (selector) -> + +window.errorMessage = (message) -> + ehtml = $("

    ") + ehtml.addClass("error_message") + ehtml.html(message) + ehtml + +window.split = (val) -> + return val.split( /,\s*/ ) + +window.extractLast = (term) -> + return split( term ).pop() + +# Disable button if text field is empty +window.disableButtonIfEmptyField = (field_selector, button_selector) -> + field = $(field_selector) + closest_submit = field.closest("form").find(button_selector) + + closest_submit.disable() if field.val() is "" + + field.on "input", -> + if $(@).val() is "" + closest_submit.disable() + else + closest_submit.enable() + +window.sanitize = (str) -> + return str.replace(/<(?:.|\n)*?>/gm, '') + +window.linkify = (str) -> + exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig + return str.replace(exp,"$1") + +window.simpleFormat = (str) -> + linkify(sanitize(str).replace(/\n/g, '
    ')) + +window.unbindEvents = -> + $(document).unbind('scroll') + $(document).off('scroll') + +document.addEventListener("page:fetch", unbindEvents) + +$ -> + # Click a .one_click_select field, select the contents + $(".one_click_select").on 'click', -> $(@).select() + + $('.remove-row').bind 'ajax:success', -> + $(this).closest('li').fadeOut() + + # Initialize select2 selects + $('select.select2').select2(width: 'resolve', dropdownAutoWidth: true) + + # Initialize tooltips + $('.has_tooltip').tooltip() + + # Bottom tooltip + $('.has_bottom_tooltip').tooltip(placement: 'bottom') + + # Form submitter + $('.trigger-submit').on 'change', -> + $(@).parents('form').submit() + + $("abbr.timeago").timeago() + $('.js-timeago').timeago() + + # Flash + if (flash = $(".flash-container")).length > 0 + flash.click -> $(@).fadeOut() + flash.show() + setTimeout (-> flash.fadeOut()), 5000 + + # Disable form buttons while a form is submitting + $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> + buttons = $('[type="submit"]', @) + + switch e.type + when 'ajax:beforeSend', 'submit' + buttons.disable() + else + buttons.enable() + + # Show/Hide the profile menu when hovering the account box + $('.account-box').hover -> $(@).toggleClass('hover') + + # Focus search field by pressing 's' key + $(document).keypress (e) -> + # Don't do anything if typing in an input + return if $(e.target).is(":input") + + switch e.which + when 115 + $("#search").focus() + e.preventDefault() + when 63 + new Shortcuts() + e.preventDefault() + + + # Commit show suppressed diff + $(".diff-content").on "click", ".supp_diff_link", -> + $(@).next('table').show() + $(@).remove() + +(($) -> + # Disable an element and add the 'disabled' Bootstrap class + $.fn.extend disable: -> + $(@).attr('disabled', 'disabled').addClass('disabled') + + # Enable an element and remove the 'disabled' Bootstrap class + $.fn.extend enable: -> + $(@).removeAttr('disabled').removeClass('disabled') + +)(jQuery) diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee deleted file mode 100644 index 89f6a547ff8..00000000000 --- a/app/assets/javascripts/main.js.coffee +++ /dev/null @@ -1,120 +0,0 @@ -window.slugify = (text) -> - text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase() - -window.ajaxGet = (url) -> - $.ajax({type: "GET", url: url, dataType: "script"}) - -window.showAndHide = (selector) -> - -window.errorMessage = (message) -> - ehtml = $("

    ") - ehtml.addClass("error_message") - ehtml.html(message) - ehtml - -window.split = (val) -> - return val.split( /,\s*/ ) - -window.extractLast = (term) -> - return split( term ).pop() - -# Disable button if text field is empty -window.disableButtonIfEmptyField = (field_selector, button_selector) -> - field = $(field_selector) - closest_submit = field.closest("form").find(button_selector) - - closest_submit.disable() if field.val() is "" - - field.on "input", -> - if $(@).val() is "" - closest_submit.disable() - else - closest_submit.enable() - -window.sanitize = (str) -> - return str.replace(/<(?:.|\n)*?>/gm, '') - -window.linkify = (str) -> - exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig - return str.replace(exp,"$1") - -window.simpleFormat = (str) -> - linkify(sanitize(str).replace(/\n/g, '
    ')) - -window.unbindEvents = -> - $(document).unbind('scroll') - $(document).off('scroll') - -document.addEventListener("page:fetch", unbindEvents) - -$ -> - # Click a .one_click_select field, select the contents - $(".one_click_select").on 'click', -> $(@).select() - - $('.remove-row').bind 'ajax:success', -> - $(this).closest('li').fadeOut() - - # Initialize select2 selects - $('select.select2').select2(width: 'resolve', dropdownAutoWidth: true) - - # Initialize tooltips - $('.has_tooltip').tooltip() - - # Bottom tooltip - $('.has_bottom_tooltip').tooltip(placement: 'bottom') - - # Form submitter - $('.trigger-submit').on 'change', -> - $(@).parents('form').submit() - - $("abbr.timeago").timeago() - $('.js-timeago').timeago() - - # Flash - if (flash = $(".flash-container")).length > 0 - flash.click -> $(@).fadeOut() - flash.show() - setTimeout (-> flash.fadeOut()), 5000 - - # Disable form buttons while a form is submitting - $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> - buttons = $('[type="submit"]', @) - - switch e.type - when 'ajax:beforeSend', 'submit' - buttons.disable() - else - buttons.enable() - - # Show/Hide the profile menu when hovering the account box - $('.account-box').hover -> $(@).toggleClass('hover') - - # Focus search field by pressing 's' key - $(document).keypress (e) -> - # Don't do anything if typing in an input - return if $(e.target).is(":input") - - switch e.which - when 115 - $("#search").focus() - e.preventDefault() - when 63 - new Shortcuts() - e.preventDefault() - - - # Commit show suppressed diff - $(".diff-content").on "click", ".supp_diff_link", -> - $(@).next('table').show() - $(@).remove() - -(($) -> - # Disable an element and add the 'disabled' Bootstrap class - $.fn.extend disable: -> - $(@).attr('disabled', 'disabled').addClass('disabled') - - # Enable an element and remove the 'disabled' Bootstrap class - $.fn.extend enable: -> - $(@).removeAttr('disabled').removeClass('disabled') - -)(jQuery) -- cgit v1.2.3 From 394737b2cb2ab82caa3b192ee4ae8fd17cb22cb9 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 24 Mar 2014 16:15:57 +0200 Subject: Use humanize instead of titleize for MR title suggestion Signed-off-by: Dmitriy Zaporozhets --- app/helpers/merge_requests_helper.rb | 2 +- app/views/projects/merge_requests/branch_from.js.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 1381b0220d6..ba25a87f392 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -20,7 +20,7 @@ module MergeRequestsHelper target_project_id: target_project.id, source_branch: event.branch_name, target_branch: target_project.repository.root_ref, - title: event.branch_name.titleize + title: event.branch_name.humanize } end diff --git a/app/views/projects/merge_requests/branch_from.js.haml b/app/views/projects/merge_requests/branch_from.js.haml index d3147188d1c..1b1082baafe 100644 --- a/app/views/projects/merge_requests/branch_from.js.haml +++ b/app/views/projects/merge_requests/branch_from.js.haml @@ -3,5 +3,5 @@ var mrTitle = $('#merge_request_title'); if(mrTitle.val().length == 0) { - mrTitle.val("#{params[:ref].titleize}"); + mrTitle.val("#{params[:ref].humanize}"); } -- cgit v1.2.3 From 369bd858d880dfdcadc75a87970c25c9c4d82a4a Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 24 Mar 2014 15:17:43 +0100 Subject: We should only specify unsafe version, never give advise since it it perishable. --- doc/update/4.2-to-5.0.md | 2 +- doc/update/5.0-to-5.1.md | 2 +- doc/update/5.1-to-5.2.md | 2 +- doc/update/5.1-to-5.4.md | 3 --- doc/update/5.1-to-6.0.md | 2 +- doc/update/5.2-to-5.3.md | 2 +- doc/update/5.3-to-5.4.md | 3 --- doc/update/5.4-to-6.0.md | 2 +- doc/update/6.0-to-6.1.md | 2 +- doc/update/6.1-to-6.2.md | 3 --- 10 files changed, 7 insertions(+), 16 deletions(-) diff --git a/doc/update/4.2-to-5.0.md b/doc/update/4.2-to-5.0.md index 5bf8c367734..f8fb607e016 100644 --- a/doc/update/4.2-to-5.0.md +++ b/doc/update/4.2-to-5.0.md @@ -1,7 +1,7 @@ # From 4.2 to 5.0 ## Warning -GitLab 5.0 is affected by critical security vulnerability CVE-2013-4490. Please update to GitLab 5.4 immediately. +GitLab 5.0 is affected by critical security vulnerability CVE-2013-4490. ## Important changes diff --git a/doc/update/5.0-to-5.1.md b/doc/update/5.0-to-5.1.md index 24d96e43bad..ba56507dd81 100644 --- a/doc/update/5.0-to-5.1.md +++ b/doc/update/5.0-to-5.1.md @@ -1,7 +1,7 @@ # From 5.0 to 5.1 ## Warning -GitLab 5.1 is affected by critical security vulnerability CVE-2013-4490. Please [update to GitLab 5.4 immediately](5.1-to-5.4.md). +GitLab 5.1 is affected by critical security vulnerability CVE-2013-4490. ## Release notes: diff --git a/doc/update/5.1-to-5.2.md b/doc/update/5.1-to-5.2.md index e4eaee91b8e..466c815195f 100644 --- a/doc/update/5.1-to-5.2.md +++ b/doc/update/5.1-to-5.2.md @@ -1,7 +1,7 @@ # From 5.1 to 5.2 ## Warning -GitLab 5.2 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 5.4 directly](5.1-to-5.4.md). +GitLab 5.2 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. ### 0. Backup diff --git a/doc/update/5.1-to-5.4.md b/doc/update/5.1-to-5.4.md index 39cacd381a3..56f4854daf0 100644 --- a/doc/update/5.1-to-5.4.md +++ b/doc/update/5.1-to-5.4.md @@ -1,9 +1,6 @@ # From 5.1 to 5.4 Also works starting from 5.2. -## Notice -Security vulnerabilities CVE-2013-4490 and CVE-2013-4489 have been patched in the latest version of GitLab 5.4. - ### 0. Backup It's useful to make a backup just in case things go south: diff --git a/doc/update/5.1-to-6.0.md b/doc/update/5.1-to-6.0.md index fa0f9ce54b6..5b74b1f893d 100644 --- a/doc/update/5.1-to-6.0.md +++ b/doc/update/5.1-to-6.0.md @@ -1,7 +1,7 @@ # From 5.1 to 6.0 ## Warning -GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 6.2 immediately](6.0-to-6.2.md). +GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. ### Deprecations diff --git a/doc/update/5.2-to-5.3.md b/doc/update/5.2-to-5.3.md index 7f89f6bf887..e3c3016db64 100644 --- a/doc/update/5.2-to-5.3.md +++ b/doc/update/5.2-to-5.3.md @@ -1,7 +1,7 @@ # From 5.2 to 5.3 ## Warning -GitLab 5.3 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 5.4 directly](5.1-to-5.4.md). +GitLab 5.3 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. ### 0. Backup diff --git a/doc/update/5.3-to-5.4.md b/doc/update/5.3-to-5.4.md index 7a24c11c223..213ce77ec38 100644 --- a/doc/update/5.3-to-5.4.md +++ b/doc/update/5.3-to-5.4.md @@ -1,8 +1,5 @@ # From 5.3 to 5.4 -## Notice -Security vulnerabilities CVE-2013-4490 and CVE-2013-4489 have been patched in the latest version of GitLab 5.4. - ### 0. Backup It's useful to make a backup just in case things go south: diff --git a/doc/update/5.4-to-6.0.md b/doc/update/5.4-to-6.0.md index 312e9a46080..c289fcb57fd 100644 --- a/doc/update/5.4-to-6.0.md +++ b/doc/update/5.4-to-6.0.md @@ -1,7 +1,7 @@ # From 5.4 to 6.0 ## Warning -GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 6.2 immediately](6.0-to-6.2.md). +GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. ### Deprecations diff --git a/doc/update/6.0-to-6.1.md b/doc/update/6.0-to-6.1.md index b7fd7634859..b4cc9203587 100644 --- a/doc/update/6.0-to-6.1.md +++ b/doc/update/6.0-to-6.1.md @@ -1,7 +1,7 @@ # From 6.0 to 6.1 ## Warning -GitLab 6.1 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 6.2 directly](6.0-to-6.2.md). +GitLab 6.1 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. # In 6.1 we remove a lot of deprecated code. # You should update to 6.0 before installing 6.1 so all the necessary conversions are run. diff --git a/doc/update/6.1-to-6.2.md b/doc/update/6.1-to-6.2.md index 3c453a5ab42..c618e599dcb 100644 --- a/doc/update/6.1-to-6.2.md +++ b/doc/update/6.1-to-6.2.md @@ -1,8 +1,5 @@ # From 6.1 to 6.2 -## Notice -Security vulnerabilities CVE-2013-4490 and CVE-2013-4489 have been patched in the latest version of GitLab 6.2. - # You should update to 6.1 before installing 6.2 so all the necessary conversions are run. ### 0. Backup -- cgit v1.2.3 From 842ad4a42590484ee12a9e76ffde90a300e9f3b8 Mon Sep 17 00:00:00 2001 From: George Dewar Date: Mon, 24 Mar 2014 16:13:01 +1300 Subject: Initial implementation --- app/assets/stylesheets/print.scss | 13 +++++++++++++ app/views/layouts/_head.html.haml | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 app/assets/stylesheets/print.scss diff --git a/app/assets/stylesheets/print.scss b/app/assets/stylesheets/print.scss new file mode 100644 index 00000000000..42dbf4d6ef3 --- /dev/null +++ b/app/assets/stylesheets/print.scss @@ -0,0 +1,13 @@ +/* Generic print styles */ +header, nav, nav.main-nav, nav.navbar-collapse, nav.navbar-collapse.collapse {display: none!important;} +.profiler-results {display: none;} + +/* Styles targeted specifically at printing files */ +.tree-ref-holder, .tree-holder .breadcrumb, .blob-commit-info {display: none;} +.file-title {display: none;} +.file-holder {border: none;} + +.wiki h1, .wiki h2, .wiki h3, .wiki h4, .wiki h5, .wiki h6 {margin-top: 17px; } +.wiki h1 {font-size: 30px;} +.wiki h2 {font-size: 22px;} +.wiki h3 {font-size: 18px; font-weight: bold; } diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 9ba20f1347d..d9a7a2d31cf 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -4,7 +4,8 @@ = "#{title} | " if defined?(title) GitLab = favicon_link_tag 'favicon.ico' - = stylesheet_link_tag "application" + = stylesheet_link_tag "application", :media => "all" + = stylesheet_link_tag "print", :media => "print" = javascript_include_tag "application" = csrf_meta_tags = include_gon -- cgit v1.2.3 From 7847e108631f739ed4278ee40118073bdda8250b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 25 Mar 2014 12:05:37 +0200 Subject: Fix tests Signed-off-by: Dmitriy Zaporozhets --- features/steps/dashboard/dashboard.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index 3526006c94a..394acd3fe8f 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -25,7 +25,7 @@ class Dashboard < Spinach::FeatureSteps find("#merge_request_target_project_id").value.should == @project.id.to_s find("#merge_request_source_branch").value.should == "new_design" find("#merge_request_target_branch").value.should == "master" - find("#merge_request_title").value.should == "New Design" + find("#merge_request_title").value.should == "New design" end Given 'user with name "John Doe" joined project "Shop"' do -- cgit v1.2.3 From 8bbac4576b7c75f47a3a940dc5fb6b1217a3c397 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 25 Mar 2014 12:10:50 +0200 Subject: Simplify run tests command Signed-off-by: Dmitriy Zaporozhets --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index 7d1dc09b4d6..7818d40ac55 100644 --- a/README.md +++ b/README.md @@ -96,14 +96,9 @@ or start each component separately ### Run the tests -* Seed the database - - bundle exec rake db:setup RAILS_ENV=test - bundle exec rake db:seed_fu RAILS_ENV=test - * Run all tests - bundle exec rake gitlab:test RAILS_ENV=test + bundle exec rake test * [RSpec](http://rspec.info/) unit and functional tests -- cgit v1.2.3 From 80daf9a7774fd757a8838f0b49b6384ec7ceb724 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 25 Mar 2014 13:47:48 +0200 Subject: Use current_user for Notification#merge_mr Signed-off-by: Dmitriy Zaporozhets --- app/services/merge_requests/auto_merge_service.rb | 2 +- app/services/merge_requests/merge_service.rb | 2 +- app/services/notification_service.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/merge_requests/auto_merge_service.rb b/app/services/merge_requests/auto_merge_service.rb index d60d61ed54a..9c9117f4687 100644 --- a/app/services/merge_requests/auto_merge_service.rb +++ b/app/services/merge_requests/auto_merge_service.rb @@ -12,7 +12,7 @@ module MergeRequests merge_request.author_id_of_changes = current_user.id merge_request.merge - notification.merge_mr(merge_request) + notification.merge_mr(merge_request, current_user) create_merge_event(merge_request) execute_project_hooks(merge_request) diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 1d5af04cdbb..80487f661e0 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -10,7 +10,7 @@ module MergeRequests merge_request.author_id_of_changes = current_user.id merge_request.merge - notification.merge_mr(merge_request) + notification.merge_mr(merge_request, current_user) create_merge_event(merge_request) execute_project_hooks(merge_request) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 9edb7fd3e31..6fda9868aa5 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -86,12 +86,12 @@ class NotificationService # * merge_request assignee if their notification level is not Disabled # * project team members with notification level higher then Participating # - def merge_mr(merge_request) + def merge_mr(merge_request, current_user) recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.target_project) recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq recipients.each do |recipient| - mailer.merged_merge_request_email(recipient.id, merge_request.id, merge_request.author_id_of_changes) + mailer.merged_merge_request_email(recipient.id, merge_request.id, current_user.id) end end -- cgit v1.2.3 From c21c3e5707c4f6e28a3733153f2e898279e0730d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 25 Mar 2014 19:32:49 +0200 Subject: Add bottom margin to highlighed code block in comment/wiki Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/generic/common.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index b5ccaed0401..4e660d0b1e0 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -355,3 +355,7 @@ table { @media (max-width: $screen-xs-max) { .container .content { margin-top: 20px; } } + +.wiki .highlight, .note-body .highlight { + margin-bottom: 9px; +} -- cgit v1.2.3 From e421772f8935b9bdce02b6f552593f8dabca9074 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 25 Mar 2014 19:53:30 +0200 Subject: Revert "Clearfix on well-lists. Pages affected:" Because it adds extra spaces at each project row on dashboard This reverts commit 2767abd90d94b3fd0fedfad85015abbffd7e4cd9. --- app/assets/stylesheets/generic/lists.scss | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/assets/stylesheets/generic/lists.scss b/app/assets/stylesheets/generic/lists.scss index 8a6d7f68175..de70e47333f 100644 --- a/app/assets/stylesheets/generic/lists.scss +++ b/app/assets/stylesheets/generic/lists.scss @@ -13,12 +13,6 @@ border-bottom: 1px solid #eee; border-bottom: 1px solid rgba(0, 0, 0, 0.05); - &:after { - content: " "; - display: table; - clear: both; - } - &.disabled { color: #888; } -- cgit v1.2.3 From 7f67e066dc9749d2532d220fafa3f397a5fe1f24 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 25 Mar 2014 20:10:08 +0200 Subject: More compact event feed and projects list Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/sections/dashboard.scss | 2 +- app/assets/stylesheets/sections/events.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/sections/dashboard.scss b/app/assets/stylesheets/sections/dashboard.scss index 6fc394e2e2b..e088ef82203 100644 --- a/app/assets/stylesheets/sections/dashboard.scss +++ b/app/assets/stylesheets/sections/dashboard.scss @@ -61,7 +61,7 @@ } .project-row, .group-row { - padding: 10px 12px !important; + padding: 8px 12px !important; font-size: 14px; line-height: 24px; diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss index 6ef12b20a5a..fe7ab426e8d 100644 --- a/app/assets/stylesheets/sections/events.scss +++ b/app/assets/stylesheets/sections/events.scss @@ -42,7 +42,7 @@ } } - padding: 14px 0px; + padding: 12px 0px; border-bottom: 1px solid #eee; .event-title { color: #333; -- cgit v1.2.3