diff options
author | Vinnie Okada <vokada@mrvinn.com> | 2015-03-22 21:50:28 -0600 |
---|---|---|
committer | Vinnie Okada <vokada@mrvinn.com> | 2015-03-22 21:50:28 -0600 |
commit | 637ca0b388382112850fd3052a961bb07db34d14 (patch) | |
tree | 15f8abdad066ffcda26a49e645d8f8aee4571002 | |
parent | a7afc0634240f5cddb6c6e1bf1f9fcf4374b852e (diff) | |
parent | bc4e25189805879490555ef2782193470f4fe295 (diff) | |
download | gitlab-ce-637ca0b388382112850fd3052a961bb07db34d14.tar.gz |
Merge branch 'master' into markdown-tags
46 files changed, 466 insertions, 141 deletions
diff --git a/CHANGELOG b/CHANGELOG index f039a45b0b0..af0f330884a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,12 +2,18 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.10.0 (unreleased) - Allow HTML tags in Markdown input + - Fix "Import projects from" button to show the correct instructions (Stan Hu) + - Fix dots in Wiki slugs causing errors (Stan Hu) + - Fix OAuth2 issue importing a new project from GitHub and GitLab (Stan Hu) - Update poltergeist to version 1.6.0 to support PhantomJS 2.0 (Zeger-Jan van de Weg) - Fix cross references when usernames, milestones, or project names contain underscores (Stan Hu) + - Disable reference creation for comments surrounded by code/preformatted blocks (Stan Hu) - enable line wrapping per default and remove the checkbox to toggle it (Hannes Rosenögger) - extend the commit calendar to show the actual commits made on a date (Hannes Rosenögger) + - Fix a link in the patch update guide - Add a service to support external wikis (Hannes Rosenögger) - List new commits for newly pushed branch in activity view. + - Add sidetiq gem dependency to match EE - Add changelog, license and contribution guide links to project sidebar. - Improve diff UI - Fix alignment of navbar toggle button (Cody Mize) @@ -16,8 +22,14 @@ v 7.10.0 (unreleased) - Improve error message when save profile has error. - Passing the name of pushed ref to CI service (requires GitLab CI 7.9+) - Add location field to user profile - -v 7.9.0 (unreleased) + - Fix print view for markdown files and wiki pages + - Improve GitLab performance when working with git repositories + - Add tag message and last commit to tag hook (Kamil Trzciński) + - Restrict permissions on backup files + - Improve oauth accounts UI in profile page + - Add ability to unlink connected accounts + +v 7.9.0 - Add HipChat integration documentation (Stan Hu) - Update documentation for object_kind field in Webhook push and tag push Webhooks (Stan Hu) - Fix broken email images (Hannes Rosenögger) @@ -121,6 +121,7 @@ gem "acts-as-taggable-on" gem 'slim' gem 'sinatra', require: nil gem 'sidekiq', '~> 3.3' +gem 'sidetiq', '0.6.3' # HTTP requests gem "httparty" diff --git a/Gemfile.lock b/Gemfile.lock index 80eebc16e4c..4f1cab43dd5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -290,6 +290,7 @@ GEM httpauth (0.2.1) httpclient (2.5.3.3) i18n (0.7.0) + ice_cube (0.11.1) ice_nine (0.10.0) jasmine (2.0.2) jasmine-core (~> 2.0.0) @@ -546,6 +547,10 @@ GEM json redis (>= 3.0.6) redis-namespace (>= 1.3.1) + sidetiq (0.6.3) + celluloid (>= 0.14.1) + ice_cube (= 0.11.1) + sidekiq (>= 3.0.0) simple_oauth (0.1.9) simplecov (0.9.0) docile (~> 1.1.0) @@ -764,6 +769,7 @@ DEPENDENCIES settingslogic shoulda-matchers (~> 2.7.0) sidekiq (~> 3.3) + sidetiq (= 0.6.3) simplecov sinatra six diff --git a/app/assets/images/authbuttons/bitbucket_32.png b/app/assets/images/authbuttons/bitbucket_32.png Binary files differdeleted file mode 100644 index 27702eb973d..00000000000 --- a/app/assets/images/authbuttons/bitbucket_32.png +++ /dev/null diff --git a/app/assets/images/authbuttons/github_32.png b/app/assets/images/authbuttons/github_32.png Binary files differdeleted file mode 100644 index 0445b567bbc..00000000000 --- a/app/assets/images/authbuttons/github_32.png +++ /dev/null diff --git a/app/assets/images/authbuttons/gitlab_32.png b/app/assets/images/authbuttons/gitlab_32.png Binary files differdeleted file mode 100644 index f3b78cb6efb..00000000000 --- a/app/assets/images/authbuttons/gitlab_32.png +++ /dev/null diff --git a/app/assets/images/authbuttons/gitlab_64.png b/app/assets/images/authbuttons/gitlab_64.png Binary files differindex ff2945fe89e..31281a19444 100644 --- a/app/assets/images/authbuttons/gitlab_64.png +++ b/app/assets/images/authbuttons/gitlab_64.png diff --git a/app/assets/images/authbuttons/google_32.png b/app/assets/images/authbuttons/google_32.png Binary files differdeleted file mode 100644 index b03c3ec5207..00000000000 --- a/app/assets/images/authbuttons/google_32.png +++ /dev/null diff --git a/app/assets/images/authbuttons/twitter_32.png b/app/assets/images/authbuttons/twitter_32.png Binary files differdeleted file mode 100644 index a3d4964f40f..00000000000 --- a/app/assets/images/authbuttons/twitter_32.png +++ /dev/null diff --git a/app/assets/stylesheets/base/gl_bootstrap.scss b/app/assets/stylesheets/base/gl_bootstrap.scss index 82c51cf4852..e176cce5c69 100644 --- a/app/assets/stylesheets/base/gl_bootstrap.scss +++ b/app/assets/stylesheets/base/gl_bootstrap.scss @@ -152,6 +152,8 @@ */ .panel { .panel-heading { + font-weight: bold; + .panel-head-actions { position: relative; top: -5px; diff --git a/app/assets/stylesheets/generic/forms.scss b/app/assets/stylesheets/generic/forms.scss index 31fe5a03f37..266041403e0 100644 --- a/app/assets/stylesheets/generic/forms.scss +++ b/app/assets/stylesheets/generic/forms.scss @@ -15,10 +15,6 @@ input[type='text'].danger { text-shadow: 0 1px 1px #fff } -fieldset legend { - font-size: 16px; -} - .datetime-controls { select { width: 100px; diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index d366300511e..83b866c3a64 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -113,3 +113,12 @@ } } } + +.oauth-image-link { + margin-right: 10px; + + img { + width: 32px; + height: 32px; + } +} diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index fbe71a5b5ad..65655d4bfa3 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -1,31 +1,7 @@ .account-page { fieldset { margin-bottom: 15px; - border-bottom: 1px dashed #ddd; padding-bottom: 15px; - - &:last-child { - border: none; - } - - legend { - border: none; - margin-bottom: 10px; - } - } -} - -.oauth_select_holder { - img { - padding: 2px; - margin-right: 10px; - } - .active { - img { - border: 1px solid #4BD; - background: $hover; - @include border-radius(5px); - } } } @@ -101,3 +77,19 @@ } } } + +.oauth-buttons { + .btn-group { + margin-right: 10px; + } + + .btn { + line-height: 36px; + height: 56px; + + img { + width: 32px; + height: 32px; + } + } +} diff --git a/app/assets/stylesheets/print.scss b/app/assets/stylesheets/print.scss index 42dbf4d6ef3..1be0551ad3b 100644 --- a/app/assets/stylesheets/print.scss +++ b/app/assets/stylesheets/print.scss @@ -11,3 +11,7 @@ header, nav, nav.main-nav, nav.navbar-collapse, nav.navbar-collapse.collapse {di .wiki h1 {font-size: 30px;} .wiki h2 {font-size: 22px;} .wiki h3 {font-size: 18px; font-weight: bold; } + +.sidebar-wrapper { display: none; } +.nav { display: none; } +.btn { display: none; } diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb index fe121691a10..9bd34fe2261 100644 --- a/app/controllers/profiles/accounts_controller.rb +++ b/app/controllers/profiles/accounts_controller.rb @@ -4,4 +4,10 @@ class Profiles::AccountsController < ApplicationController def show @user = current_user end + + def unlink + provider = params[:provider] + current_user.identities.find_by(provider: provider).destroy + redirect_to profile_account_path + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 8ed6d59c20d..38b5fc4a011 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -174,16 +174,10 @@ module ApplicationHelper Digest::SHA1.hexdigest string end - def authbutton(provider, size = 64) - file_name = "#{provider.to_s.split('_').first}_#{size}.png" - image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}") - end - def simple_sanitize(str) sanitize(str, tags: %w(a span)) end - def body_data_page path = controller.controller_path.split('/') namespace = path.first if path.second diff --git a/app/helpers/oauth_helper.rb b/app/helpers/oauth_helper.rb index 1a0ad17b607..997b91de077 100644 --- a/app/helpers/oauth_helper.rb +++ b/app/helpers/oauth_helper.rb @@ -20,6 +20,15 @@ module OauthHelper def additional_providers enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')} end - + + def oauth_image_tag(provider, size = 64) + file_name = "#{provider.to_s.split('_').first}_#{size}.png" + image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}") + end + + def oauth_active?(provider) + current_user.identities.exists?(provider: provider.to_s) + end + extend self end diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb index 9e37e44732a..780c7cd5133 100644 --- a/app/helpers/profile_helper.rb +++ b/app/helpers/profile_helper.rb @@ -1,10 +1,4 @@ module ProfileHelper - def oauth_active_class(provider) - if current_user.identities.exists?(provider: provider.to_s) - 'active' - end - end - def show_profile_username_tab? current_user.can_change_username? end diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index 55438bee245..772c868d9cd 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -104,7 +104,7 @@ class ProjectWiki def page_title_and_dir(title) title_array = title.split("/") title = title_array.pop - [title.gsub(/\.[^.]*$/, ""), title_array.join("/")] + [title, title_array.join("/")] end def search_files(query) diff --git a/app/models/repository.rb b/app/models/repository.rb index c6eaa485b8a..082ad7a0c6a 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -62,24 +62,28 @@ class Repository def add_branch(branch_name, ref) cache.expire(:branch_names) + @branches = nil gitlab_shell.add_branch(path_with_namespace, branch_name, ref) end def add_tag(tag_name, ref, message = nil) cache.expire(:tag_names) + @tags = nil gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message) end def rm_branch(branch_name) cache.expire(:branch_names) + @branches = nil gitlab_shell.rm_branch(path_with_namespace, branch_name) end def rm_tag(tag_name) cache.expire(:tag_names) + @tags = nil gitlab_shell.rm_tag(path_with_namespace, tag_name) end @@ -180,8 +184,17 @@ class Repository end end + def lookup_cache + @lookup_cache ||= {} + end + def method_missing(m, *args, &block) - raw_repository.send(m, *args, &block) + if m == :lookup && !block_given? + lookup_cache[m] ||= {} + lookup_cache[m][args.join(":")] ||= raw_repository.send(m, *args, &block) + else + raw_repository.send(m, *args, &block) + end end def respond_to?(method) @@ -235,12 +248,20 @@ class Repository end def head_commit - commit(self.root_ref) + @head_commit ||= commit(self.root_ref) + end + + def head_tree + @head_tree ||= Tree.new(self, head_commit.sha, nil) end def tree(sha = :head, path = nil) if sha == :head - sha = head_commit.sha + if path.nil? + return head_tree + else + sha = head_commit.sha + end end Tree.new(self, sha, path) @@ -368,6 +389,18 @@ class Repository end end + def branches + @branches ||= raw_repository.branches + end + + def tags + @tags ||= raw_repository.tags + end + + def root_ref + @root_ref ||= raw_repository.root_ref + end + private def cache diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 32981a0e664..e9413c34bae 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -179,7 +179,8 @@ class WikiPage if valid? && project_wiki.send(method, *args) page_details = if method == :update_page - @page.path + # Use url_path instead of path to omit format extension + @page.url_path else title end diff --git a/app/services/create_tag_service.rb b/app/services/create_tag_service.rb index af4b537cb93..4115d689925 100644 --- a/app/services/create_tag_service.rb +++ b/app/services/create_tag_service.rb @@ -40,7 +40,8 @@ class CreateTagService < BaseService end def create_push_data(project, user, tag) + commits = [project.repository.commit(tag.target)].compact Gitlab::PushDataBuilder. - build(project, user, Gitlab::Git::BLANK_SHA, tag.target, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", []) + build(project, user, Gitlab::Git::BLANK_SHA, tag.target, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", commits, tag.message) end end diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index a0da07f5c90..1f0b29dff5e 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -23,42 +23,40 @@ class GitPushService project.repository.expire_cache project.update_repository_size - if push_to_branch?(ref) - if push_remove_branch?(ref, newrev) - @push_commits = [] - elsif push_to_new_branch?(ref, oldrev) - # Re-find the pushed commits. - if is_default_branch?(ref) - # Initial push to the default branch. Take the full history of that branch as "newly pushed". - @push_commits = project.repository.commits(newrev) - - # Set protection on the default branch if configured - if (current_application_settings.default_branch_protection != PROTECTION_NONE) - developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false - project.protected_branches.create({ name: project.default_branch, developers_can_push: developers_can_push }) - end - else - # Use the pushed commits that aren't reachable by the default branch - # as a heuristic. This may include more commits than are actually pushed, but - # that shouldn't matter because we check for existing cross-references later. - @push_commits = project.repository.commits_between(project.default_branch, newrev) - - # don't process commits for the initial push to the default branch - process_commit_messages(ref) + if push_remove_branch?(ref, newrev) + @push_commits = [] + elsif push_to_new_branch?(ref, oldrev) + # Re-find the pushed commits. + if is_default_branch?(ref) + # Initial push to the default branch. Take the full history of that branch as "newly pushed". + @push_commits = project.repository.commits(newrev) + + # Set protection on the default branch if configured + if (current_application_settings.default_branch_protection != PROTECTION_NONE) + developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false + project.protected_branches.create({ name: project.default_branch, developers_can_push: developers_can_push }) end - elsif push_to_existing_branch?(ref, oldrev) - # Collect data for this git push - @push_commits = project.repository.commits_between(oldrev, newrev) - project.update_merge_requests(oldrev, newrev, ref, @user) + else + # Use the pushed commits that aren't reachable by the default branch + # as a heuristic. This may include more commits than are actually pushed, but + # that shouldn't matter because we check for existing cross-references later. + @push_commits = project.repository.commits_between(project.default_branch, newrev) + + # don't process commits for the initial push to the default branch process_commit_messages(ref) end + elsif push_to_existing_branch?(ref, oldrev) + # Collect data for this git push + @push_commits = project.repository.commits_between(oldrev, newrev) + project.update_merge_requests(oldrev, newrev, ref, @user) + process_commit_messages(ref) + end - @push_data = build_push_data(oldrev, newrev, ref) + @push_data = build_push_data(oldrev, newrev, ref) - EventCreateService.new.push(project, user, @push_data) - project.execute_hooks(@push_data.dup, :push_hooks) - project.execute_services(@push_data.dup, :push_hooks) - end + EventCreateService.new.push(project, user, @push_data) + project.execute_hooks(@push_data.dup, :push_hooks) + project.execute_services(@push_data.dup, :push_hooks) end protected diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb index 0d8e6e85e47..bf203bbd692 100644 --- a/app/services/git_tag_push_service.rb +++ b/app/services/git_tag_push_service.rb @@ -3,7 +3,7 @@ class GitTagPushService def execute(project, user, oldrev, newrev, ref) @project, @user = project, user - + @push_data = build_push_data(oldrev, newrev, ref) EventCreateService.new.push(project, user, @push_data) @@ -18,6 +18,20 @@ class GitTagPushService private def build_push_data(oldrev, newrev, ref) - Gitlab::PushDataBuilder.build(project, user, oldrev, newrev, ref, []) + commits = [] + message = nil + + if !Gitlab::Git.blank_ref?(newrev) + tag_name = Gitlab::Git.ref_name(ref) + tag = project.repository.find_tag(tag_name) + if tag && tag.target == newrev + commit = project.repository.commit(tag.target) + commits = [commit].compact + message = tag.message + end + end + + Gitlab::PushDataBuilder. + build(project, user, oldrev, newrev, ref, commits, message) end end diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml index 4cd1c303b22..b647b906b71 100644 --- a/app/views/devise/shared/_omniauth_box.html.haml +++ b/app/views/devise/shared/_omniauth_box.html.haml @@ -5,6 +5,6 @@ - providers.each do |provider| %span.light - if default_providers.include?(provider) - = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider) + = link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), class: 'oauth-image-link' - else = link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn" diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 6bafcb56551..5bffb4acc1d 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -1,11 +1,6 @@ -%h3.page-title - Account Settings -%p.light - You can change your username and private token here. - - if current_user.ldap_user? +- if current_user.ldap_user? + .alert.alert-info Some options are unavailable for LDAP accounts -%hr - .account-page %fieldset.update-token @@ -33,12 +28,16 @@ - if show_profile_social_tab? %fieldset - %legend Social Accounts - .oauth_select_holder.append-bottom-10 + %legend Connected Accounts + .oauth-buttons.append-bottom-10 %p Click on icon to activate signin with one of the following services - enabled_social_providers.each do |provider| - %span{class: oauth_active_class(provider) } - = link_to authbutton(provider, 32), omniauth_authorize_path(User, provider) + .btn-group + = link_to oauth_image_tag(provider), omniauth_authorize_path(User, provider), + class: "btn btn-lg #{'active' if oauth_active?(provider)}" + - if oauth_active?(provider) + = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do + %i.fa.fa-close - if show_profile_username_tab? %fieldset.update-username diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 173a3080b31..9687c8ad87c 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -74,9 +74,9 @@ = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git' .alert.alert-info.prepend-top-10 %ul - %li + %li The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>. - %li + %li The import will time out after 4 minutes. For big repositories, use a clone/push combination. %li To migrate an SVN repository, check out #{link_to "this document", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}. @@ -112,6 +112,6 @@ $ -> $('.how_to_import_link').bind 'click', (e) -> e.preventDefault() - import_modal = $(this).parent().find(".modal").show() + import_modal = $(this).next(".modal").show() $('.modal-header .close').bind 'click', -> $(".modal").hide() diff --git a/config/routes.rb b/config/routes.rb index 03b4a32a9dd..c30cd768572 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -184,7 +184,11 @@ Gitlab::Application.routes.draw do end scope module: :profiles do - resource :account, only: [:show, :update] + resource :account, only: [:show, :update] do + member do + delete :unlink + end + end resource :notifications, only: [:show, :update] resource :password, only: [:new, :create, :edit, :update] do member do diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md index ad302492556..e29ee2a7b3d 100644 --- a/doc/update/patch_versions.md +++ b/doc/update/patch_versions.md @@ -1,5 +1,5 @@ # Universal update guide for patch versions -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/patch_versions.md) for the most up to date instructions.* +*Make sure you view this [upgrade guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/patch_versions.md) from the `master` branch for the most up to date instructions.* For example from 6.2.0 to 6.2.1, also see the [semantic versioning specification](http://semver.org/). diff --git a/doc/update/upgrader.md b/doc/update/upgrader.md index d8476fb3457..f62a53d3340 100644 --- a/doc/update/upgrader.md +++ b/doc/update/upgrader.md @@ -24,7 +24,7 @@ If you have local changes to your GitLab repository the script will stash them a ## 2. Run GitLab upgrade tool -Note: GitLab 7.9 adds nodejs as a dependency. GitLab 7.6 adds `libkrb5-dev` as a dependency (installed by default on Ubuntu and OSX). GitLab 7.2 adds `pkg-config` and `cmake` as dependency. Please check the dependencies in the [installation guide.](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies) +Note: GitLab 7.9 adds `nodejs` as a dependency. GitLab 7.6 adds `libkrb5-dev` as a dependency (installed by default on Ubuntu and OSX). GitLab 7.2 adds `pkg-config` and `cmake` as dependency. Please check the dependencies in the [installation guide.](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies) # Starting with GitLab version 7.0 upgrader script has been moved to bin directory cd /home/git/gitlab diff --git a/features/dashboard/new_project.feature b/features/dashboard/new_project.feature new file mode 100644 index 00000000000..431dc4ccfcb --- /dev/null +++ b/features/dashboard/new_project.feature @@ -0,0 +1,13 @@ +@dashboard +Feature: New Project +Background: + Given I sign in as a user + And I own project "Shop" + And I visit dashboard page + + @javascript + Scenario: I should see New projects page + Given I click "New project" link + Then I see "New project" page + When I click on "Import project from GitHub" + Then I see instructions on how to import from GitHub diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb new file mode 100644 index 00000000000..5e588ceb780 --- /dev/null +++ b/features/steps/dashboard/new_project.rb @@ -0,0 +1,27 @@ +class Spinach::Features::NewProject < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + step 'I click "New project" link' do + click_link "New project" + end + + step 'I see "New project" page' do + page.should have_content("Project path") + end + + step 'I click on "Import project from GitHub"' do + first('.how_to_import_link').click + end + + step 'I see instructions on how to import from GitHub' do + github_modal = first('.modal-body') + github_modal.should be_visible + github_modal.should have_content "To enable importing projects from GitHub" + + all('.modal-body').each do |element| + element.should_not be_visible unless element == github_modal + end + end +end diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index ab8db4e9837..c6087830b40 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -11,22 +11,27 @@ module Backup s[:tar_version] = tar_version tar_file = "#{s[:backup_created_at].to_i}_gitlab_backup.tar" - Dir.chdir(Gitlab.config.backup.path) + Dir.chdir(Gitlab.config.backup.path) do + File.open("#{Gitlab.config.backup.path}/backup_information.yml", + "w+") do |file| + file << s.to_yaml.gsub(/^---\n/,'') + end - File.open("#{Gitlab.config.backup.path}/backup_information.yml", "w+") do |file| - file << s.to_yaml.gsub(/^---\n/,'') - end + FileUtils.chmod_R(0700, %w{db uploads repositories}) - # create archive - $progress.print "Creating backup archive: #{tar_file} ... " - if Kernel.system('tar', '-cf', tar_file, *BACKUP_CONTENTS) - $progress.puts "done".green - else - puts "creating archive #{tar_file} failed".red - abort 'Backup failed' - end + # create archive + $progress.print "Creating backup archive: #{tar_file} ... " + orig_umask = File.umask(0077) + if Kernel.system('tar', '-cf', tar_file, *BACKUP_CONTENTS) + $progress.puts "done".green + else + puts "creating archive #{tar_file} failed".red + abort 'Backup failed' + end + File.umask(orig_umask) - upload(tar_file) + upload(tar_file) + end end def upload(tar_file) @@ -51,11 +56,13 @@ module Backup def cleanup $progress.print "Deleting tmp directories ... " - if Kernel.system('rm', '-rf', *BACKUP_CONTENTS) - $progress.puts "done".green - else - puts "deleting tmp directory failed".red - abort 'Backup failed' + BACKUP_CONTENTS.each do |dir| + if FileUtils.rm_rf(File.join(Gitlab.config.backup.path, dir)) + $progress.puts "done".green + else + puts "deleting tmp directory '#{dir}' failed".red + abort 'Backup failed' + end end end diff --git a/lib/gitlab/bitbucket_import/client.rb b/lib/gitlab/bitbucket_import/client.rb index 1e4906c9e31..5b1952b9675 100644 --- a/lib/gitlab/bitbucket_import/client.rb +++ b/lib/gitlab/bitbucket_import/client.rb @@ -62,7 +62,7 @@ module Gitlab end def find_deploy_key(project_identifier, key) - JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/deploy-keys").body).find do |deploy_key| + JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/deploy-keys").body).find do |deploy_key| deploy_key["key"].chomp == key.chomp end end @@ -92,7 +92,7 @@ module Gitlab end def bitbucket_options - OmniAuth::Strategies::Bitbucket.default_options[:client_options].dup + OmniAuth::Strategies::Bitbucket.default_options[:client_options].symbolize_keys end end end diff --git a/lib/gitlab/github_import/client.rb b/lib/gitlab/github_import/client.rb index 7fe076b333b..270cbcd9ccd 100644 --- a/lib/gitlab/github_import/client.rb +++ b/lib/gitlab/github_import/client.rb @@ -46,7 +46,7 @@ module Gitlab end def github_options - OmniAuth::Strategies::GitHub.default_options[:client_options].dup + OmniAuth::Strategies::GitHub.default_options[:client_options].symbolize_keys end end end diff --git a/lib/gitlab/gitlab_import/client.rb b/lib/gitlab/gitlab_import/client.rb index 2236439c6ce..f48ede9d067 100644 --- a/lib/gitlab/gitlab_import/client.rb +++ b/lib/gitlab/gitlab_import/client.rb @@ -71,7 +71,7 @@ module Gitlab end def gitlab_options - OmniAuth::Strategies::GitLab.default_options[:client_options].dup + OmniAuth::Strategies::GitLab.default_options[:client_options].symbolize_keys end end end diff --git a/lib/gitlab/push_data_builder.rb b/lib/gitlab/push_data_builder.rb index 948cf58fd9a..f8da452e4c0 100644 --- a/lib/gitlab/push_data_builder.rb +++ b/lib/gitlab/push_data_builder.rb @@ -21,7 +21,7 @@ module Gitlab # total_commits_count: Fixnum # } # - def build(project, user, oldrev, newrev, ref, commits = []) + def build(project, user, oldrev, newrev, ref, commits = [], message = nil) # Total commits count commits_count = commits.size @@ -42,6 +42,7 @@ module Gitlab after: newrev, ref: ref, checkout_sha: checkout_sha(project.repository, newrev, ref), + message: message, user_id: user.id, user_name: user.name, user_email: user.email, diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index 5b9772de168..1058d4c43d9 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -11,7 +11,13 @@ module Gitlab end def analyze(string, project) - parse_references(string.dup, project) + text = string.dup + + # Remove preformatted/code blocks so that references are not included + text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) { |match| '' } + text.gsub!(%r{^```.*?^```}m) { |match| '' } + + parse_references(text, project) end # Given a valid project, resolve the extracted identifiers of the requested type to diff --git a/spec/lib/gitlab/bitbucket_import/client_spec.rb b/spec/lib/gitlab/bitbucket_import/client_spec.rb new file mode 100644 index 00000000000..dd450e9967b --- /dev/null +++ b/spec/lib/gitlab/bitbucket_import/client_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe Gitlab::BitbucketImport::Client do + let(:token) { '123456' } + let(:secret) { 'secret' } + let(:client) { Gitlab::BitbucketImport::Client.new(token, secret) } + + before do + Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "bitbucket") + end + + it 'all OAuth client options are symbols' do + client.consumer.options.keys.each do |key| + expect(key).to be_kind_of(Symbol) + end + end +end diff --git a/spec/lib/gitlab/github_import/client_spec.rb b/spec/lib/gitlab/github_import/client_spec.rb new file mode 100644 index 00000000000..26618120316 --- /dev/null +++ b/spec/lib/gitlab/github_import/client_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe Gitlab::GithubImport::Client do + let(:token) { '123456' } + let(:client) { Gitlab::GithubImport::Client.new(token) } + + before do + Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "github") + end + + it 'all OAuth2 client options are symbols' do + client.client.options.keys.each do |key| + expect(key).to be_kind_of(Symbol) + end + end +end diff --git a/spec/lib/gitlab/gitlab_import/client_spec.rb b/spec/lib/gitlab/gitlab_import/client_spec.rb new file mode 100644 index 00000000000..c511c515474 --- /dev/null +++ b/spec/lib/gitlab/gitlab_import/client_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe Gitlab::GitlabImport::Client do + let(:token) { '123456' } + let(:client) { Gitlab::GitlabImport::Client.new(token) } + + before do + Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "gitlab") + end + + it 'all OAuth2 client options are symbols' do + client.client.options.keys.each do |key| + expect(key).to be_kind_of(Symbol) + end + end +end diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb index 5ebe44f6fb7..b3f4bb5aeda 100644 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ b/spec/lib/gitlab/reference_extractor_spec.rb @@ -50,6 +50,26 @@ describe Gitlab::ReferenceExtractor do expect(text).to eq('issue #123 is just the worst, @user') end + it 'extracts no references for <pre>..</pre> blocks' do + subject.analyze("<pre>def puts '#1 issue'\nend\n</pre>```", nil) + expect(subject.issues).to be_blank + end + + it 'extracts no references for <code>..</code> blocks' do + subject.analyze("<code>def puts '!1 request'\nend\n</code>```", nil) + expect(subject.merge_requests).to be_blank + end + + it 'extracts no references for code blocks with language' do + subject.analyze("this code:\n```ruby\ndef puts '#1 issue'\nend\n```", nil) + expect(subject.issues).to be_blank + end + + it 'extracts issue references for invalid code blocks' do + subject.analyze('test: ```this one talks about issue #1234```', nil) + expect(subject.issues).to eq([{ project: nil, id: '1234' }]) + end + it 'handles all possible kinds of references' do accessors = Gitlab::Markdown::TYPES.map { |t| "#{t}s".to_sym } expect(subject).to respond_to(*accessors) diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index f3fd805783f..fceb7668cac 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -78,6 +78,47 @@ describe WikiPage do end end + describe "dot in the title" do + let(:title) { 'Index v1.2.3' } + + before do + @wiki_attr = {title: title, content: "Home Page", format: "markdown"} + end + + describe "#create" do + after do + destroy_page(title) + end + + context "with valid attributes" do + it "saves the wiki page" do + subject.create(@wiki_attr) + expect(wiki.find_page(title)).not_to be_nil + end + + it "returns true" do + expect(subject.create(@wiki_attr)).to eq(true) + end + end + end + + describe "#update" do + before do + create_page(title, "content") + @page = wiki.find_page(title) + end + + it "updates the content of the page" do + @page.update("new content") + @page = wiki.find_page(title) + end + + it "returns true" do + expect(@page.update("more content")).to be_truthy + end + end + end + describe "#update" do before do create_page("Update", "content") diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index 1b1e3ca5f8b..aa9b15dd9ec 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -145,11 +145,6 @@ describe GitPushService do expect(project).to receive(:execute_hooks) service.execute(project, user, 'oldrev', 'newrev', 'refs/heads/master') end - - it "when pushing tags" do - expect(project).not_to receive(:execute_hooks) - service.execute(project, user, 'newrev', 'newrev', 'refs/tags/v1.0.0') - end end end diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb index fcf462edbfc..a050fdf6c0e 100644 --- a/spec/services/git_tag_push_service_spec.rb +++ b/spec/services/git_tag_push_service_spec.rb @@ -1,32 +1,39 @@ require 'spec_helper' describe GitTagPushService do + include RepoHelpers + let (:user) { create :user } let (:project) { create :project } let (:service) { GitTagPushService.new } before do - @ref = 'refs/tags/super-tag' - @oldrev = 'b98a310def241a6fd9c9a9a3e7934c48e498fe81' - @newrev = 'b19a04f53caeebf4fe5ec2327cb83e9253dc91bb' + @oldrev = Gitlab::Git::BLANK_SHA + @newrev = "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b" # gitlab-test: git rev-parse refs/tags/v1.1.0 + @ref = 'refs/tags/v1.1.0' end - describe 'Git Tag Push Data' do + describe "Git Tag Push Data" do before do service.execute(project, user, @oldrev, @newrev, @ref) @push_data = service.push_data + @tag_name = Gitlab::Git.ref_name(@ref) + @tag = project.repository.find_tag(@tag_name) + @commit = project.repository.commit(@tag.target) end subject { @push_data } + it { is_expected.to include(object_kind: 'tag_push') } it { is_expected.to include(ref: @ref) } it { is_expected.to include(before: @oldrev) } it { is_expected.to include(after: @newrev) } + it { is_expected.to include(message: @tag.message) } it { is_expected.to include(user_id: user.id) } it { is_expected.to include(user_name: user.name) } it { is_expected.to include(project_id: project.id) } - context 'With repository data' do + context "with repository data" do subject { @push_data[:repository] } it { is_expected.to include(name: project.name) } @@ -34,6 +41,41 @@ describe GitTagPushService do it { is_expected.to include(description: project.description) } it { is_expected.to include(homepage: project.web_url) } end + + context "with commits" do + subject { @push_data[:commits] } + + it { is_expected.to be_an(Array) } + it 'has 1 element' do + expect(subject.size).to eq(1) + end + + context "the commit" do + subject { @push_data[:commits].first } + + it { is_expected.to include(id: @commit.id) } + it { is_expected.to include(message: @commit.safe_message) } + it { is_expected.to include(timestamp: @commit.date.xmlschema) } + it do + is_expected.to include( + url: [ + Gitlab.config.gitlab.url, + project.namespace.to_param, + project.to_param, + 'commit', + @commit.id + ].join('/') + ) + end + + context "with a author" do + subject { @push_data[:commits].first[:author] } + + it { is_expected.to include(name: @commit.author_name) } + it { is_expected.to include(email: @commit.author_email) } + end + end + end end describe "Web Hooks" do diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb index 60942cc95fc..8a411b7720a 100644 --- a/spec/tasks/gitlab/backup_rake_spec.rb +++ b/spec/tasks/gitlab/backup_rake_spec.rb @@ -10,17 +10,17 @@ describe 'gitlab:app namespace rake task' do Rake::Task.define_task :environment end + def run_rake_task(task_name) + Rake::Task[task_name].reenable + Rake.application.invoke_task task_name + end + describe 'backup_restore' do before do # avoid writing task output to spec progress allow($stdout).to receive :write end - let :run_rake_task do - Rake::Task["gitlab:backup:restore"].reenable - Rake.application.invoke_task "gitlab:backup:restore" - end - context 'gitlab version' do before do Dir.stub glob: [] @@ -36,7 +36,9 @@ describe 'gitlab:app namespace rake task' do it 'should fail on mismatch' do YAML.stub load_file: {gitlab_version: "not #{gitlab_version}" } - expect { run_rake_task }.to raise_error SystemExit + expect { run_rake_task('gitlab:backup:restore') }.to( + raise_error SystemExit + ) end it 'should invoke restoration on mach' do @@ -44,9 +46,56 @@ describe 'gitlab:app namespace rake task' do expect(Rake::Task["gitlab:backup:db:restore"]).to receive :invoke expect(Rake::Task["gitlab:backup:repo:restore"]).to receive :invoke expect(Rake::Task["gitlab:shell:setup"]).to receive :invoke - expect { run_rake_task }.to_not raise_error + expect { run_rake_task('gitlab:backup:restore') }.to_not raise_error end end end # backup_restore task + + describe 'backup_create' do + def tars_glob + Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar')) + end + + before :all do + # Record the existing backup tars so we don't touch them + existing_tars = tars_glob + + # Redirect STDOUT and run the rake task + orig_stdout = $stdout + $stdout = StringIO.new + run_rake_task('gitlab:backup:create') + $stdout = orig_stdout + + @backup_tar = (tars_glob - existing_tars).first + end + + after :all do + FileUtils.rm(@backup_tar) + end + + it 'should set correct permissions on the tar file' do + expect(File.exist?(@backup_tar)).to be_truthy + expect(File::Stat.new(@backup_tar).mode.to_s(8)).to eq('100600') + end + + it 'should set correct permissions on the tar contents' do + tar_contents, exit_status = Gitlab::Popen.popen( + %W{tar -tvf #{@backup_tar} db uploads repositories} + ) + expect(exit_status).to eq(0) + expect(tar_contents).to match('db/') + expect(tar_contents).to match('uploads/') + expect(tar_contents).to match('repositories/') + expect(tar_contents).not_to match(/^.{4,9}[rwx]/) + end + + it 'should delete temp directories' do + temp_dirs = Dir.glob( + File.join(Gitlab.config.backup.path, '{db,repositories,uploads}') + ) + + expect(temp_dirs).to be_empty + end + end # backup_create task end # gitlab:app namespace |