summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJames Edwards-Jones <jamedjo@gmail.com>2017-02-06 15:12:27 +0000
committerJames Edwards-Jones <jamedjo@gmail.com>2017-02-06 15:12:27 +0000
commitb988faaf85c8e68d501f242b980e5e79a00e2b15 (patch)
treefaffbfe623bfcbfe1c09bddac00b2cc879baff63 /lib
parent5af4cae544c8526de63e639bd6c7db730526add3 (diff)
parent53db7d1d75e1d14cb20278bd0c1a75ce24a6626d (diff)
downloadgitlab-ce-b988faaf85c8e68d501f242b980e5e79a00e2b15.tar.gz
Merge branch 'master' into 'jej-pages-to-ce'jej-pages-to-ce
# Conflicts: # db/schema.rb
Diffstat (limited to 'lib')
-rw-r--r--lib/api/api.rb7
-rw-r--r--lib/api/boards.rb2
-rw-r--r--lib/api/entities.rb1
-rw-r--r--lib/api/helpers.rb2
-rw-r--r--lib/api/projects.rb16
-rw-r--r--lib/api/settings.rb3
-rw-r--r--lib/api/v3/projects.rb458
-rw-r--r--lib/gitlab/kubernetes.rb4
-rw-r--r--lib/gitlab/middleware/webpack_proxy.rb24
-rw-r--r--lib/gitlab/workhorse.rb3
-rw-r--r--lib/tasks/gitlab/assets.rake1
-rw-r--r--lib/tasks/gitlab/test.rake2
-rw-r--r--lib/tasks/karma.rake25
-rw-r--r--lib/tasks/teaspoon.rake25
-rw-r--r--lib/tasks/test.rake2
15 files changed, 525 insertions, 50 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 6cf6b501021..090109d5e6f 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -1,7 +1,12 @@
module API
class API < Grape::API
include APIGuard
- version 'v3', using: :path
+
+ version %w(v3 v4), using: :path
+
+ version 'v3', using: :path do
+ mount ::API::V3::Projects
+ end
before { allow_access_with_scope :api }
diff --git a/lib/api/boards.rb b/lib/api/boards.rb
index 4ac491edc1b..13752eb4947 100644
--- a/lib/api/boards.rb
+++ b/lib/api/boards.rb
@@ -37,7 +37,7 @@ module API
end
desc 'Get the lists of a project board' do
- detail 'Does not include `backlog` and `done` lists. This feature was introduced in 8.13'
+ detail 'Does not include `done` list. This feature was introduced in 8.13'
success Entities::List
end
get '/lists' do
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index a07b2a9ca0f..b1ead48caf7 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -575,6 +575,7 @@ module API
expose :koding_url
expose :plantuml_enabled
expose :plantuml_url
+ expose :terminal_max_session_time
end
class Release < Grape::Entity
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index eb5b947172a..dfab60f7fa5 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -304,7 +304,7 @@ module API
header['X-Sendfile'] = path
body
else
- path
+ file path
end
end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 941f47114a4..92a70faf1c2 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -151,22 +151,6 @@ module API
present_projects Project.all, with: Entities::ProjectWithAccess, statistics: params[:statistics]
end
- desc 'Search for projects the current user has access to' do
- success Entities::Project
- end
- params do
- requires :query, type: String, desc: 'The project name to be searched'
- use :sort_params
- use :pagination
- end
- get "/search/:query", requirements: { query: /[^\/]+/ } do
- search_service = Search::GlobalService.new(current_user, search: params[:query]).execute
- projects = search_service.objects('projects', params[:page])
- projects = projects.reorder(params[:order_by] => params[:sort])
-
- present paginate(projects), with: Entities::Project
- end
-
desc 'Create new project' do
success Entities::Project
end
diff --git a/lib/api/settings.rb b/lib/api/settings.rb
index 5206ee4f521..747ceb4e3e0 100644
--- a/lib/api/settings.rb
+++ b/lib/api/settings.rb
@@ -108,6 +108,7 @@ module API
requires :housekeeping_full_repack_period, type: Integer, desc: "Number of Git pushes after which a full 'git repack' is run."
requires :housekeeping_gc_period, type: Integer, desc: "Number of Git pushes after which 'git gc' is run."
end
+ optional :terminal_max_session_time, type: Integer, desc: 'Maximum time for web terminal websocket connection (in seconds). Set to 0 for unlimited time.'
at_least_one_of :default_branch_protection, :default_project_visibility, :default_snippet_visibility,
:default_group_visibility, :restricted_visibility_levels, :import_sources,
:enabled_git_access_protocol, :gravatar_enabled, :default_projects_limit,
@@ -121,7 +122,7 @@ module API
:akismet_enabled, :admin_notification_email, :sentry_enabled,
:repository_storage, :repository_checks_enabled, :koding_enabled, :plantuml_enabled,
:version_check_enabled, :email_author_in_body, :html_emails_enabled,
- :housekeeping_enabled
+ :housekeeping_enabled, :terminal_max_session_time
end
put "application/settings" do
if current_settings.update_attributes(declared_params(include_missing: false))
diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb
new file mode 100644
index 00000000000..bac7d485a22
--- /dev/null
+++ b/lib/api/v3/projects.rb
@@ -0,0 +1,458 @@
+module API
+ module V3
+ class Projects < Grape::API
+ include PaginationParams
+
+ before { authenticate_non_get! }
+
+ helpers do
+ params :optional_params do
+ optional :description, type: String, desc: 'The description of the project'
+ optional :issues_enabled, type: Boolean, desc: 'Flag indication if the issue tracker is enabled'
+ optional :merge_requests_enabled, type: Boolean, desc: 'Flag indication if merge requests are enabled'
+ optional :wiki_enabled, type: Boolean, desc: 'Flag indication if the wiki is enabled'
+ optional :builds_enabled, type: Boolean, desc: 'Flag indication if builds are enabled'
+ optional :snippets_enabled, type: Boolean, desc: 'Flag indication if snippets are enabled'
+ optional :shared_runners_enabled, type: Boolean, desc: 'Flag indication if shared runners are enabled for that project'
+ optional :container_registry_enabled, type: Boolean, desc: 'Flag indication if the container registry is enabled for that project'
+ optional :lfs_enabled, type: Boolean, desc: 'Flag indication if Git LFS is enabled for that project'
+ optional :public, type: Boolean, desc: 'Create a public project. The same as visibility_level = 20.'
+ optional :visibility_level, type: Integer, values: [
+ Gitlab::VisibilityLevel::PRIVATE,
+ Gitlab::VisibilityLevel::INTERNAL,
+ Gitlab::VisibilityLevel::PUBLIC ], desc: 'Create a public project. The same as visibility_level = 20.'
+ optional :public_builds, type: Boolean, desc: 'Perform public builds'
+ optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access'
+ optional :only_allow_merge_if_build_succeeds, type: Boolean, desc: 'Only allow to merge if builds succeed'
+ optional :only_allow_merge_if_all_discussions_are_resolved, type: Boolean, desc: 'Only allow to merge if all discussions are resolved'
+ end
+
+ def map_public_to_visibility_level(attrs)
+ publik = attrs.delete(:public)
+ if !publik.nil? && !attrs[:visibility_level].present?
+ # Since setting the public attribute to private could mean either
+ # private or internal, use the more conservative option, private.
+ attrs[:visibility_level] = (publik == true) ? Gitlab::VisibilityLevel::PUBLIC : Gitlab::VisibilityLevel::PRIVATE
+ end
+ attrs
+ end
+ end
+
+ resource :projects do
+ helpers do
+ params :collection_params do
+ use :sort_params
+ use :filter_params
+ use :pagination
+
+ optional :simple, type: Boolean, default: false,
+ desc: 'Return only the ID, URL, name, and path of each project'
+ end
+
+ params :sort_params do
+ optional :order_by, type: String, values: %w[id name path created_at updated_at last_activity_at],
+ default: 'created_at', desc: 'Return projects ordered by field'
+ optional :sort, type: String, values: %w[asc desc], default: 'desc',
+ desc: 'Return projects sorted in ascending and descending order'
+ end
+
+ params :filter_params do
+ optional :archived, type: Boolean, default: false, desc: 'Limit by archived status'
+ optional :visibility, type: String, values: %w[public internal private],
+ desc: 'Limit by visibility'
+ optional :search, type: String, desc: 'Return list of authorized projects matching the search criteria'
+ end
+
+ params :statistics_params do
+ optional :statistics, type: Boolean, default: false, desc: 'Include project statistics'
+ end
+
+ params :create_params do
+ optional :namespace_id, type: Integer, desc: 'Namespace ID for the new project. Default to the user namespace.'
+ optional :import_url, type: String, desc: 'URL from which the project is imported'
+ end
+
+ def present_projects(projects, options = {})
+ options = options.reverse_merge(
+ with: Entities::Project,
+ current_user: current_user,
+ simple: params[:simple],
+ )
+
+ projects = filter_projects(projects)
+ projects = projects.with_statistics if options[:statistics]
+ options[:with] = Entities::BasicProjectDetails if options[:simple]
+
+ present paginate(projects), options
+ end
+ end
+
+ desc 'Get a list of visible projects for authenticated user' do
+ success Entities::BasicProjectDetails
+ end
+ params do
+ use :collection_params
+ end
+ get '/visible' do
+ entity = current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails
+ present_projects ProjectsFinder.new.execute(current_user), with: entity
+ end
+
+ desc 'Get a projects list for authenticated user' do
+ success Entities::BasicProjectDetails
+ end
+ params do
+ use :collection_params
+ end
+ get do
+ authenticate!
+
+ present_projects current_user.authorized_projects,
+ with: Entities::ProjectWithAccess
+ end
+
+ desc 'Get an owned projects list for authenticated user' do
+ success Entities::BasicProjectDetails
+ end
+ params do
+ use :collection_params
+ use :statistics_params
+ end
+ get '/owned' do
+ authenticate!
+
+ present_projects current_user.owned_projects,
+ with: Entities::ProjectWithAccess,
+ statistics: params[:statistics]
+ end
+
+ desc 'Gets starred project for the authenticated user' do
+ success Entities::BasicProjectDetails
+ end
+ params do
+ use :collection_params
+ end
+ get '/starred' do
+ authenticate!
+
+ present_projects current_user.viewable_starred_projects
+ end
+
+ desc 'Get all projects for admin user' do
+ success Entities::BasicProjectDetails
+ end
+ params do
+ use :collection_params
+ use :statistics_params
+ end
+ get '/all' do
+ authenticated_as_admin!
+
+ present_projects Project.all, with: Entities::ProjectWithAccess, statistics: params[:statistics]
+ end
+
+ desc 'Search for projects the current user has access to' do
+ success Entities::Project
+ end
+ params do
+ requires :query, type: String, desc: 'The project name to be searched'
+ use :sort_params
+ use :pagination
+ end
+ get "/search/:query", requirements: { query: /[^\/]+/ } do
+ search_service = Search::GlobalService.new(current_user, search: params[:query]).execute
+ projects = search_service.objects('projects', params[:page])
+ projects = projects.reorder(params[:order_by] => params[:sort])
+
+ present paginate(projects), with: Entities::Project
+ end
+
+ desc 'Create new project' do
+ success Entities::Project
+ end
+ params do
+ requires :name, type: String, desc: 'The name of the project'
+ optional :path, type: String, desc: 'The path of the repository'
+ use :optional_params
+ use :create_params
+ end
+ post do
+ attrs = map_public_to_visibility_level(declared_params(include_missing: false))
+ project = ::Projects::CreateService.new(current_user, attrs).execute
+
+ if project.saved?
+ present project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, project)
+ else
+ if project.errors[:limit_reached].present?
+ error!(project.errors[:limit_reached], 403)
+ end
+ render_validation_error!(project)
+ end
+ end
+
+ desc 'Create new project for a specified user. Only available to admin users.' do
+ success Entities::Project
+ end
+ params do
+ requires :name, type: String, desc: 'The name of the project'
+ requires :user_id, type: Integer, desc: 'The ID of a user'
+ optional :default_branch, type: String, desc: 'The default branch of the project'
+ use :optional_params
+ use :create_params
+ end
+ post "user/:user_id" do
+ authenticated_as_admin!
+ user = User.find_by(id: params.delete(:user_id))
+ not_found!('User') unless user
+
+ attrs = map_public_to_visibility_level(declared_params(include_missing: false))
+ project = ::Projects::CreateService.new(user, attrs).execute
+
+ if project.saved?
+ present project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, project)
+ else
+ render_validation_error!(project)
+ end
+ end
+ end
+
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+ resource :projects, requirements: { id: /[^\/]+/ } do
+ desc 'Get a single project' do
+ success Entities::ProjectWithAccess
+ end
+ get ":id" do
+ entity = current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails
+ present user_project, with: entity, current_user: current_user,
+ user_can_admin_project: can?(current_user, :admin_project, user_project)
+ end
+
+ desc 'Get events for a single project' do
+ success Entities::Event
+ end
+ params do
+ use :pagination
+ end
+ get ":id/events" do
+ present paginate(user_project.events.recent), with: Entities::Event
+ end
+
+ desc 'Fork new project for the current user or provided namespace.' do
+ success Entities::Project
+ end
+ params do
+ optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be forked into'
+ end
+ post 'fork/:id' do
+ fork_params = declared_params(include_missing: false)
+ namespace_id = fork_params[:namespace]
+
+ if namespace_id.present?
+ fork_params[:namespace] = if namespace_id =~ /^\d+$/
+ Namespace.find_by(id: namespace_id)
+ else
+ Namespace.find_by_path_or_name(namespace_id)
+ end
+
+ unless fork_params[:namespace] && can?(current_user, :create_projects, fork_params[:namespace])
+ not_found!('Target Namespace')
+ end
+ end
+
+ forked_project = ::Projects::ForkService.new(user_project, current_user, fork_params).execute
+
+ if forked_project.errors.any?
+ conflict!(forked_project.errors.messages)
+ else
+ present forked_project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, forked_project)
+ end
+ end
+
+ desc 'Update an existing project' do
+ success Entities::Project
+ end
+ params do
+ optional :name, type: String, desc: 'The name of the project'
+ optional :default_branch, type: String, desc: 'The default branch of the project'
+ optional :path, type: String, desc: 'The path of the repository'
+ use :optional_params
+ at_least_one_of :name, :description, :issues_enabled, :merge_requests_enabled,
+ :wiki_enabled, :builds_enabled, :snippets_enabled,
+ :shared_runners_enabled, :container_registry_enabled,
+ :lfs_enabled, :public, :visibility_level, :public_builds,
+ :request_access_enabled, :only_allow_merge_if_build_succeeds,
+ :only_allow_merge_if_all_discussions_are_resolved, :path,
+ :default_branch
+ end
+ put ':id' do
+ authorize_admin_project
+ attrs = map_public_to_visibility_level(declared_params(include_missing: false))
+ authorize! :rename_project, user_project if attrs[:name].present?
+ authorize! :change_visibility_level, user_project if attrs[:visibility_level].present?
+
+ result = ::Projects::UpdateService.new(user_project, current_user, attrs).execute
+
+ if result[:status] == :success
+ present user_project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, user_project)
+ else
+ render_validation_error!(user_project)
+ end
+ end
+
+ desc 'Archive a project' do
+ success Entities::Project
+ end
+ post ':id/archive' do
+ authorize!(:archive_project, user_project)
+
+ user_project.archive!
+
+ present user_project, with: Entities::Project
+ end
+
+ desc 'Unarchive a project' do
+ success Entities::Project
+ end
+ post ':id/unarchive' do
+ authorize!(:archive_project, user_project)
+
+ user_project.unarchive!
+
+ present user_project, with: Entities::Project
+ end
+
+ desc 'Star a project' do
+ success Entities::Project
+ end
+ post ':id/star' do
+ if current_user.starred?(user_project)
+ not_modified!
+ else
+ current_user.toggle_star(user_project)
+ user_project.reload
+
+ present user_project, with: Entities::Project
+ end
+ end
+
+ desc 'Unstar a project' do
+ success Entities::Project
+ end
+ delete ':id/star' do
+ if current_user.starred?(user_project)
+ current_user.toggle_star(user_project)
+ user_project.reload
+
+ present user_project, with: Entities::Project
+ else
+ not_modified!
+ end
+ end
+
+ desc 'Remove a project'
+ delete ":id" do
+ authorize! :remove_project, user_project
+ ::Projects::DestroyService.new(user_project, current_user, {}).async_execute
+ end
+
+ desc 'Mark this project as forked from another'
+ params do
+ requires :forked_from_id, type: String, desc: 'The ID of the project it was forked from'
+ end
+ post ":id/fork/:forked_from_id" do
+ authenticated_as_admin!
+
+ forked_from_project = find_project!(params[:forked_from_id])
+ not_found!("Source Project") unless forked_from_project
+
+ if user_project.forked_from_project.nil?
+ user_project.create_forked_project_link(forked_to_project_id: user_project.id, forked_from_project_id: forked_from_project.id)
+ else
+ render_api_error!("Project already forked", 409)
+ end
+ end
+
+ desc 'Remove a forked_from relationship'
+ delete ":id/fork" do
+ authorize! :remove_fork_project, user_project
+
+ if user_project.forked?
+ user_project.forked_project_link.destroy
+ else
+ not_modified!
+ end
+ end
+
+ desc 'Share the project with a group' do
+ success Entities::ProjectGroupLink
+ end
+ params do
+ requires :group_id, type: Integer, desc: 'The ID of a group'
+ requires :group_access, type: Integer, values: Gitlab::Access.values, desc: 'The group access level'
+ optional :expires_at, type: Date, desc: 'Share expiration date'
+ end
+ post ":id/share" do
+ authorize! :admin_project, user_project
+ group = Group.find_by_id(params[:group_id])
+
+ unless group && can?(current_user, :read_group, group)
+ not_found!('Group')
+ end
+
+ unless user_project.allowed_to_share_with_group?
+ return render_api_error!("The project sharing with group is disabled", 400)
+ end
+
+ link = user_project.project_group_links.new(declared_params(include_missing: false))
+
+ if link.save
+ present link, with: Entities::ProjectGroupLink
+ else
+ render_api_error!(link.errors.full_messages.first, 409)
+ end
+ end
+
+ params do
+ requires :group_id, type: Integer, desc: 'The ID of the group'
+ end
+ delete ":id/share/:group_id" do
+ authorize! :admin_project, user_project
+
+ link = user_project.project_group_links.find_by(group_id: params[:group_id])
+ not_found!('Group Link') unless link
+
+ link.destroy
+ no_content!
+ end
+
+ desc 'Upload a file'
+ params do
+ requires :file, type: File, desc: 'The file to be uploaded'
+ end
+ post ":id/uploads" do
+ ::Projects::UploadService.new(user_project, params[:file]).execute
+ end
+
+ desc 'Get the users list of a project' do
+ success Entities::UserBasic
+ end
+ params do
+ optional :search, type: String, desc: 'Return list of users matching the search criteria'
+ use :pagination
+ end
+ get ':id/users' do
+ users = user_project.team.users
+ users = users.search(params[:search]) if params[:search].present?
+
+ present paginate(users), with: Entities::UserBasic
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes.rb b/lib/gitlab/kubernetes.rb
index 288771c1c12..3a7af363548 100644
--- a/lib/gitlab/kubernetes.rb
+++ b/lib/gitlab/kubernetes.rb
@@ -43,10 +43,10 @@ module Gitlab
end
end
- def add_terminal_auth(terminal, token, ca_pem = nil)
+ def add_terminal_auth(terminal, token:, max_session_time:, ca_pem: nil)
terminal[:headers]['Authorization'] << "Bearer #{token}"
+ terminal[:max_session_time] = max_session_time
terminal[:ca_pem] = ca_pem if ca_pem.present?
- terminal
end
def container_exec_url(api_url, namespace, pod_name, container_name)
diff --git a/lib/gitlab/middleware/webpack_proxy.rb b/lib/gitlab/middleware/webpack_proxy.rb
new file mode 100644
index 00000000000..3fe32adeade
--- /dev/null
+++ b/lib/gitlab/middleware/webpack_proxy.rb
@@ -0,0 +1,24 @@
+# This Rack middleware is intended to proxy the webpack assets directory to the
+# webpack-dev-server. It is only intended for use in development.
+
+module Gitlab
+ module Middleware
+ class WebpackProxy < Rack::Proxy
+ def initialize(app = nil, opts = {})
+ @proxy_host = opts.fetch(:proxy_host, 'localhost')
+ @proxy_port = opts.fetch(:proxy_port, 3808)
+ @proxy_path = opts[:proxy_path] if opts[:proxy_path]
+ super(app, opts)
+ end
+
+ def perform_request(env)
+ unless @proxy_path && env['PATH_INFO'].start_with?("/#{@proxy_path}")
+ return @app.call(env)
+ end
+
+ env['HTTP_HOST'] = "#{@proxy_host}:#{@proxy_port}"
+ super(env)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/workhorse.rb b/lib/gitlab/workhorse.rb
index a3b502ffd6a..c8872df8a93 100644
--- a/lib/gitlab/workhorse.rb
+++ b/lib/gitlab/workhorse.rb
@@ -107,7 +107,8 @@ module Gitlab
'Terminal' => {
'Subprotocols' => terminal[:subprotocols],
'Url' => terminal[:url],
- 'Header' => terminal[:headers]
+ 'Header' => terminal[:headers],
+ 'MaxSessionTime' => terminal[:max_session_time],
}
}
details['Terminal']['CAPem'] = terminal[:ca_pem] if terminal.has_key?(:ca_pem)
diff --git a/lib/tasks/gitlab/assets.rake b/lib/tasks/gitlab/assets.rake
index 5d884bf9f66..b6ef8260191 100644
--- a/lib/tasks/gitlab/assets.rake
+++ b/lib/tasks/gitlab/assets.rake
@@ -3,6 +3,7 @@ namespace :gitlab do
desc 'GitLab | Assets | Compile all frontend assets'
task :compile do
Rake::Task['assets:precompile'].invoke
+ Rake::Task['webpack:compile'].invoke
Rake::Task['gitlab:assets:fix_urls'].invoke
end
diff --git a/lib/tasks/gitlab/test.rake b/lib/tasks/gitlab/test.rake
index 4d4e746503a..84810b489ce 100644
--- a/lib/tasks/gitlab/test.rake
+++ b/lib/tasks/gitlab/test.rake
@@ -6,7 +6,7 @@ namespace :gitlab do
%W(rake rubocop),
%W(rake spinach),
%W(rake spec),
- %W(rake teaspoon)
+ %W(rake karma)
]
cmds.each do |cmd|
diff --git a/lib/tasks/karma.rake b/lib/tasks/karma.rake
new file mode 100644
index 00000000000..89812a179ec
--- /dev/null
+++ b/lib/tasks/karma.rake
@@ -0,0 +1,25 @@
+unless Rails.env.production?
+ Rake::Task['karma'].clear if Rake::Task.task_defined?('karma')
+
+ namespace :karma do
+ desc 'GitLab | Karma | Generate fixtures for JavaScript tests'
+ RSpec::Core::RakeTask.new(:fixtures) do |t|
+ ENV['NO_KNAPSACK'] = 'true'
+ t.pattern = 'spec/javascripts/fixtures/*.rb'
+ t.rspec_opts = '--format documentation'
+ end
+
+ desc 'GitLab | Karma | Run JavaScript tests'
+ task :tests do
+ sh "npm run karma" do |ok, res|
+ abort('rake karma:tests failed') unless ok
+ end
+ end
+ end
+
+ desc 'GitLab | Karma | Shortcut for karma:fixtures and karma:tests'
+ task :karma do
+ Rake::Task['karma:fixtures'].invoke
+ Rake::Task['karma:tests'].invoke
+ end
+end
diff --git a/lib/tasks/teaspoon.rake b/lib/tasks/teaspoon.rake
deleted file mode 100644
index 08caedd7ff3..00000000000
--- a/lib/tasks/teaspoon.rake
+++ /dev/null
@@ -1,25 +0,0 @@
-unless Rails.env.production?
- Rake::Task['teaspoon'].clear if Rake::Task.task_defined?('teaspoon')
-
- namespace :teaspoon do
- desc 'GitLab | Teaspoon | Generate fixtures for JavaScript tests'
- RSpec::Core::RakeTask.new(:fixtures) do |t|
- ENV['NO_KNAPSACK'] = 'true'
- t.pattern = 'spec/javascripts/fixtures/*.rb'
- t.rspec_opts = '--format documentation'
- end
-
- desc 'GitLab | Teaspoon | Run JavaScript tests'
- task :tests do
- require "teaspoon/console"
- options = {}
- abort('rake teaspoon:tests failed') if Teaspoon::Console.new(options).failures?
- end
- end
-
- desc 'GitLab | Teaspoon | Shortcut for teaspoon:fixtures and teaspoon:tests'
- task :teaspoon do
- Rake::Task['teaspoon:fixtures'].invoke
- Rake::Task['teaspoon:tests'].invoke
- end
-end
diff --git a/lib/tasks/test.rake b/lib/tasks/test.rake
index d3dcbd2c29b..3e01f91d32c 100644
--- a/lib/tasks/test.rake
+++ b/lib/tasks/test.rake
@@ -7,5 +7,5 @@ end
unless Rails.env.production?
desc "GitLab | Run all tests on CI with simplecov"
- task test_ci: [:rubocop, :brakeman, :teaspoon, :spinach, :spec]
+ task test_ci: [:rubocop, :brakeman, :karma, :spinach, :spec]
end