Commit 442db080 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' into ci-build-list

parents 6776dcf9 5a8d7324
...@@ -54,6 +54,8 @@ v 8.0.0 (unreleased) ...@@ -54,6 +54,8 @@ v 8.0.0 (unreleased)
- Sort users autocomplete lists by user (Allister Antosik) - Sort users autocomplete lists by user (Allister Antosik)
- Webhook for issue now contains repository field (Jungkook Park) - Webhook for issue now contains repository field (Jungkook Park)
- Add ability to add custom text to the help page (Jeroen van Baarsen) - Add ability to add custom text to the help page (Jeroen van Baarsen)
- Add pg_schema to backup config
- Removed API calls from CE to CI
v 7.14.3 v 7.14.3
- No changes - No changes
......
...@@ -11,12 +11,13 @@ class @IssuableContext ...@@ -11,12 +11,13 @@ class @IssuableContext
$(this).submit() $(this).submit()
$('.issuable-details').waitForImages -> $('.issuable-details').waitForImages ->
$('.issuable-affix').on 'affix.bs.affix', ->
$(@).width($(@).outerWidth())
.on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
$(@).width('')
$('.issuable-affix').affix offset: $('.issuable-affix').affix offset:
top: -> top: ->
@top = ($('.issuable-affix').offset().top - 70) @top = ($('.issuable-affix').offset().top - 70)
bottom: -> bottom: ->
@bottom = $('.footer').outerHeight(true) @bottom = $('.footer').outerHeight(true)
$('.issuable-affix').on 'affix.bs.affix', ->
$(@).width($(@).outerWidth())
.on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
$(@).width('')
...@@ -56,6 +56,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -56,6 +56,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:restricted_signup_domains_raw, :restricted_signup_domains_raw,
:version_check_enabled, :version_check_enabled,
:user_oauth_applications, :user_oauth_applications,
:ci_enabled,
restricted_visibility_levels: [], restricted_visibility_levels: [],
import_sources: [] import_sources: []
) )
......
module Ci module Ci
class ApplicationController < ::ApplicationController class ApplicationController < ::ApplicationController
before_action :check_enable_flag!
def self.railtie_helpers_paths def self.railtie_helpers_paths
"app/helpers/ci" "app/helpers/ci"
end end
...@@ -8,6 +10,13 @@ module Ci ...@@ -8,6 +10,13 @@ module Ci
private private
def check_enable_flag!
unless current_application_settings.ci_enabled
redirect_to(disabled_ci_projects_path)
return
end
end
def authenticate_public_page! def authenticate_public_page!
unless project.public unless project.public
authenticate_user! authenticate_user!
......
...@@ -5,13 +5,17 @@ module Ci ...@@ -5,13 +5,17 @@ module Ci
before_action :authenticate_user!, except: [:build, :badge, :index, :show] before_action :authenticate_user!, except: [:build, :badge, :index, :show]
before_action :authenticate_public_page!, only: :show before_action :authenticate_public_page!, only: :show
before_action :project, only: [:build, :integration, :show, :badge, :edit, :update, :destroy, :toggle_shared_runners, :dumped_yaml] before_action :project, only: [:build, :integration, :show, :badge, :edit, :update, :destroy, :toggle_shared_runners, :dumped_yaml]
before_action :authorize_access_project!, except: [:build, :badge, :index, :show, :new, :create] before_action :authorize_access_project!, except: [:build, :badge, :index, :show, :new, :create, :disabled]
before_action :authorize_manage_project!, only: [:edit, :integration, :update, :destroy, :toggle_shared_runners, :dumped_yaml] before_action :authorize_manage_project!, only: [:edit, :integration, :update, :destroy, :toggle_shared_runners, :dumped_yaml]
before_action :authenticate_token!, only: [:build] before_action :authenticate_token!, only: [:build]
before_action :no_cache, only: [:badge] before_action :no_cache, only: [:badge]
skip_before_action :check_enable_flag!, only: [:disabled]
protect_from_forgery except: :build protect_from_forgery except: :build
layout 'ci/project', except: :index layout 'ci/project', except: [:index, :disabled]
def disabled
end
def index def index
@limit, @offset = (params[:limit] || PROJECTS_BATCH).to_i, (params[:offset] || 0).to_i @limit, @offset = (params[:limit] || PROJECTS_BATCH).to_i, (params[:offset] || 0).to_i
...@@ -51,7 +55,7 @@ module Ci ...@@ -51,7 +55,7 @@ module Ci
return redirect_to ci_root_path, alert: 'You have to have at least master role to enable CI for this project' return redirect_to ci_root_path, alert: 'You have to have at least master role to enable CI for this project'
end end
@project = Ci::CreateProjectService.new.execute(current_user, project_data, ci_project_url(":project_id")) @project = Ci::CreateProjectService.new.execute(current_user, project_data)
if @project.persisted? if @project.persisted?
redirect_to ci_project_path(@project, show_guide: true), notice: 'Project was successfully created.' redirect_to ci_project_path(@project, show_guide: true), notice: 'Project was successfully created.'
...@@ -82,16 +86,6 @@ module Ci ...@@ -82,16 +86,6 @@ module Ci
redirect_to ci_projects_url redirect_to ci_projects_url
end end
def build
@commit = Ci::CreateCommitService.new.execute(@project, params.dup)
if @commit && @commit.valid?
head 201
else
head 400
end
end
# Project status badge # Project status badge
# Image with build status for sha or ref # Image with build status for sha or ref
def badge def badge
......
...@@ -83,7 +83,8 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -83,7 +83,8 @@ class ApplicationSetting < ActiveRecord::Base
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
restricted_signup_domains: Settings.gitlab['restricted_signup_domains'], restricted_signup_domains: Settings.gitlab['restricted_signup_domains'],
import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'] import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'],
ci_enabled: Settings.gitlab_ci['enabled']
) )
end end
......
...@@ -92,21 +92,6 @@ module Ci ...@@ -92,21 +92,6 @@ module Ci
project project
end end
# TODO: remove
def from_gitlab(user, scope = :owned, options)
opts = user.authenticate_options
opts.merge! options
raise 'Implement me of fix'
#projects = Ci::Network.new.projects(opts.compact, scope)
if projects
projects.map { |pr| OpenStruct.new(pr) }
else
[]
end
end
def already_added?(project) def already_added?(project)
where(gitlab_id: project.id).any? where(gitlab_id: project.id).any?
end end
......
...@@ -69,14 +69,6 @@ class BuildkiteService < CiService ...@@ -69,14 +69,6 @@ class BuildkiteService < CiService
"#{project_url}/builds?commit=#{sha}" "#{project_url}/builds?commit=#{sha}"
end end
def builds_path
"#{project_url}/builds?branch=#{project.default_branch}"
end
def status_img_path
"#{buildkite_endpoint('badge')}/#{status_token}.svg"
end
def title def title
'Buildkite' 'Buildkite'
end end
......
...@@ -135,20 +135,6 @@ class DroneCiService < CiService ...@@ -135,20 +135,6 @@ class DroneCiService < CiService
commit_page(sha, ref) commit_page(sha, ref)
end end
def builds_path
url = [drone_url, "#{project.namespace.path}/#{project.path}"]
URI.join(*url).to_s
end
def status_img_path
url = [drone_url,
"api/badges/#{project.namespace.path}/#{project.path}/status.svg",
"?branch=#{URI::encode(project.default_branch)}"]
URI.join(*url).to_s
end
def title def title
'Drone CI' 'Drone CI'
end end
......
...@@ -19,22 +19,12 @@ ...@@ -19,22 +19,12 @@
# #
class GitlabCiService < CiService class GitlabCiService < CiService
API_PREFIX = "api/v1" prop_accessor :token
prop_accessor :project_url, :token, :enable_ssl_verification
validates :project_url,
presence: true,
format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated?
validates :token,
presence: true,
format: { with: /\A([A-Za-z0-9]+)\z/ }, if: :activated?
after_save :compose_service_hook, if: :activated? after_save :compose_service_hook, if: :activated?
def compose_service_hook def compose_service_hook
hook = service_hook || build_service_hook hook = service_hook || build_service_hook
hook.url = [project_url, "/build", "?token=#{token}"].join("")
hook.enable_ssl_verification = enable_ssl_verification
hook.save hook.save
end end
...@@ -55,71 +45,47 @@ class GitlabCiService < CiService ...@@ -55,71 +45,47 @@ class GitlabCiService < CiService
end end
end end
service_hook.execute(data) ci_project = Ci::Project.find_by(gitlab_id: project.id)
end Ci::CreateCommitService.new.execute(ci_project, data)
def commit_status_path(sha, ref)
URI::encode(project_url + "/refs/#{ref}/commits/#{sha}/status.json?token=#{token}")
end end
def get_ci_build(sha, ref) def get_ci_commit(sha, ref)
@ci_builds ||= {} Ci::Project.find(project.gitlab_ci_project).commits.find_by_sha_and_ref!(sha, ref)
@ci_builds[sha] ||= HTTParty.get(commit_status_path(sha, ref), verify: false)
end end
def commit_status(sha, ref) def commit_status(sha, ref)
response = get_ci_build(sha, ref) get_ci_commit(sha, ref).status
rescue ActiveRecord::RecordNotFound
if response.code == 200 and response["status"]
response["status"]
else
:error
end
rescue Errno::ECONNREFUSED
:error :error
end end
def fork_registration(new_project, private_token) def fork_registration(new_project, current_user)
params = { params = OpenStruct.new({
id: new_project.id, id: new_project.id,
name_with_namespace: new_project.name_with_namespace, name_with_namespace: new_project.name_with_namespace,
path_with_namespace: new_project.path_with_namespace, path_with_namespace: new_project.path_with_namespace,
web_url: new_project.web_url, web_url: new_project.web_url,
default_branch: new_project.default_branch, default_branch: new_project.default_branch,
ssh_url_to_repo: new_project.ssh_url_to_repo ssh_url_to_repo: new_project.ssh_url_to_repo
} })
HTTParty.post( ci_project = Ci::Project.find_by!(gitlab_id: project.id)
fork_registration_path,
body: { Ci::CreateProjectService.new.execute(
project_id: project.id, current_user,
project_token: token, params,
private_token: private_token, ci_project
data: params },
verify: false
) )
end end
def commit_coverage(sha, ref) def commit_coverage(sha, ref)
response = get_ci_build(sha, ref) get_ci_commit(sha, ref).coverage
rescue ActiveRecord::RecordNotFound
if response.code == 200 and response["coverage"] :error
response["coverage"]
end
rescue Errno::ECONNREFUSED
nil
end end
def build_page(sha, ref) def build_page(sha, ref)
URI::encode(project_url + "/refs/#{ref}/commits/#{sha}") Ci::RoutesHelper.ci_project_ref_commits_path(project.gitlab_ci_project, ref, sha)
end
def builds_path
project_url + "?ref=" + project.default_branch
end
def status_img_path
project_url + "/status.png?ref=" + project.default_branch
end end
def title def title
...@@ -135,11 +101,7 @@ class GitlabCiService < CiService ...@@ -135,11 +101,7 @@ class GitlabCiService < CiService
end end
def fields def fields
[ []
{ type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' },
{ type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' },
{ type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
]
end end
private private
...@@ -148,10 +110,6 @@ class GitlabCiService < CiService ...@@ -148,10 +110,6 @@ class GitlabCiService < CiService
repository.blob_at(sha, '.gitlab-ci.yml') repository.blob_at(sha, '.gitlab-ci.yml')
end end
def fork_registration_path
project_url.sub(/projects\/\d*/, "#{API_PREFIX}/forks")
end
def repository def repository
project.repository project.repository
end end
......
...@@ -2,20 +2,15 @@ module Ci ...@@ -2,20 +2,15 @@ module Ci
class CreateProjectService class CreateProjectService
include Gitlab::Application.routes.url_helpers include Gitlab::Application.routes.url_helpers
def execute(current_user, params, project_route, forked_project = nil) def execute(current_user, params, forked_project = nil)
@project = Ci::Project.parse(params) @project = Ci::Project.parse(params)
Ci::Project.transaction do Ci::Project.transaction do
@project.save! @project.save!
data = {
token: @project.token,
project_url: project_route.gsub(":project_id", @project.id.to_s),
}
gl_project = ::Project.find(@project.gitlab_id) gl_project = ::Project.find(@project.gitlab_id)
gl_project.build_missing_services gl_project.build_missing_services
gl_project.gitlab_ci_service.update_attributes(data.merge(active: true)) gl_project.gitlab_ci_service.update_attributes(active: true, token: @project.token)
end end
if forked_project if forked_project
......
...@@ -18,7 +18,7 @@ module Projects ...@@ -18,7 +18,7 @@ module Projects
if new_project.persisted? if new_project.persisted?
if @project.gitlab_ci? if @project.gitlab_ci?
ForkRegistrationWorker.perform_async(@project.id, new_project.id, @current_user.private_token) @project.gitlab_ci_service.fork_registration(new_project, @current_user)
end end
end end
......
...@@ -124,5 +124,14 @@ ...@@ -124,5 +124,14 @@
= f.text_area :help_page_text, class: 'form-control', rows: 4 = f.text_area :help_page_text, class: 'form-control', rows: 4
.help-block Markdown enabled .help-block Markdown enabled
%fieldset
%legend Continuous Integration
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
= f.label :ci_enabled do
= f.check_box :ci_enabled
Enable Continuous Integration
.form-actions .form-actions
= f.submit 'Save', class: 'btn btn-primary' = f.submit 'Save', class: 'btn btn-primary'
Continuous Integration has been disabled. Please ask your administrator to enable it.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
%html{ lang: "en"} %html{ lang: "en"}
= render 'layouts/head' = render 'layouts/head'
%body{class: "ci-body #{user_application_theme}", 'data-page' => body_data_page} %body{class: "ci-body #{user_application_theme}", 'data-page' => body_data_page}
- header_title = "CI Projects" - header_title = "Continuous Integration"
- if current_user - if current_user
= render "layouts/header/default", title: header_title = render "layouts/header/default", title: header_title
- else - else
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
%span %span
Merge Requests Merge Requests
%span.count= current_user.assigned_merge_requests.opened.count %span.count= current_user.assigned_merge_requests.opened.count
= nav_link(path: 'ci/projects#index') do = nav_link(path: ['ci/projects#index', 'ci/projects#disabled']) do
= link_to ci_projects_path, title: 'Continuous Integration', data: {placement: 'right'} do = link_to ci_projects_path, title: 'Continuous Integration', data: {placement: 'right'} do
= icon('building fw') = icon('building fw')
%span %span
......
class ForkRegistrationWorker
include Sidekiq::Worker
sidekiq_options queue: :default
def perform(from_project_id, to_project_id, private_token)
from_project = Project.find(from_project_id)
to_project = Project.find(to_project_id)
from_project.gitlab_ci_service.fork_registration(to_project, private_token)
end
end
...@@ -306,6 +306,7 @@ production: &base ...@@ -306,6 +306,7 @@ production: &base
path: "tmp/backups" # Relative paths are relative to Rails.root (default: tmp/backups/) path: "tmp/backups" # Relative paths are relative to Rails.root (default: tmp/backups/)
# archive_permissions: 0640 # Permissions for the resulting backup.tar file (default: 0600) # archive_permissions: 0640 # Permissions for the resulting backup.tar file (default: 0600)
# keep_time: 604800 # default: 0 (forever) (in seconds) # keep_time: 604800 # default: 0 (forever) (in seconds)
# pg_schema: public # default: nil, it means that all schemas will be backed up
# upload: # upload:
# # Fog storage connection settings, see http://fog.io/storage/ . # # Fog storage connection settings, see http://fog.io/storage/ .
# connection: # connection:
......
...@@ -178,6 +178,7 @@ Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious' ...@@ -178,6 +178,7 @@ Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious'
# CI # CI
# #
Settings['gitlab_ci'] ||= Settingslogic.new({}) Settings['gitlab_ci'] ||= Settingslogic.new({})
Settings.gitlab_ci['enabled'] = true if Settings.gitlab_ci['enabled'].nil?
Settings.gitlab_ci['all_broken_builds'] = true if Settings.gitlab_ci['all_broken_builds'].nil? Settings.gitlab_ci['all_broken_builds'] = true if Settings.gitlab_ci['all_broken_builds'].nil?
Settings.gitlab_ci['add_pusher'] = false if Settings.gitlab_ci['add_pusher'].nil? Settings.gitlab_ci['add_pusher'] = false if Settings.gitlab_ci['add_pusher'].nil?
Settings.gitlab_ci['url'] ||= Settings.send(:build_gitlab_ci_url) Settings.gitlab_ci['url'] ||= Settings.send(:build_gitlab_ci_url)
...@@ -219,6 +220,7 @@ Settings.gitlab_shell['ssh_path_prefix'] ||= Settings.send(:build_gitlab_shell_s ...@@ -219,6 +220,7 @@ Settings.gitlab_shell['ssh_path_prefix'] ||= Settings.send(:build_gitlab_shell_s
# #
Settings['backup'] ||= Settingslogic.new({}) Settings['backup'] ||= Settingslogic.new({})
Settings.backup['keep_time'] ||= 0 Settings.backup['keep_time'] ||= 0
Settings.backup['pg_schema'] = nil
Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root) Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root)
Settings.backup['archive_permissions'] ||= 0600 Settings.backup['archive_permissions'] ||= 0600
Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil }) Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil })
......
...@@ -12,13 +12,12 @@ Gitlab::Application.routes.draw do ...@@ -12,13 +12,12 @@ Gitlab::Application.routes.draw do
resources :projects do resources :projects do
collection do collection do
post :add post :add
get :gitlab get :disabled
end end
member do member do
get :status, to: 'projects#badge' get :status, to: 'projects#badge'
get :integration get :integration
post :build
post :toggle_shared_runners post :toggle_shared_runners
get :dumped_yaml get :dumped_yaml
end end
......
class AddCiEnabledToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :ci_enabled, :boolean, null: false, default: true
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150916145038) do ActiveRecord::Schema.define(version: 20150918084513) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -46,6 +46,7 @@ ActiveRecord::Schema.define(version: 20150916145038) do ...@@ -46,6 +46,7 @@ ActiveRecord::Schema.define(version: 20150916145038) do
t.integer "session_expire_delay", default: 10080, null: false t.integer "session_expire_delay", default: 10080, null: false
t.text "import_sources" t.text "import_sources"
t.text "help_page_text" t.text "help_page_text"
t.boolean "ci_enabled", default: true, null: false
end end
create_table "audit_events", force: true do |t| create_table "audit_events", force: true do |t|
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
- [Runners](runners.md) - [Runners](runners.md)
- [Commits](commits.md) - [Commits](commits.md)
- [Builds](builds.md) - [Builds](builds.md)
- [Forks](forks.md)
## Authentication ## Authentication
......
# Forks API
This API is intended to aid in the setup and configuration of
forked projects on Gitlab CI.
__Authentication is done by GitLab user token & GitLab project token__
## Forks
### Create fork for project
```
POST /ci/forks
```
Parameters:
project_id (required) - The ID of a project
project_token (requires) - Project token
private_token(required) - User private token
data (required) - GitLab project data (name_with_namespace, web_url, default_branch, ssh_url_to_repo)
...@@ -303,8 +303,8 @@ Courier, which we will install later to add IMAP authentication, requires mailbo ...@@ -303,8 +303,8 @@ Courier, which we will install later to add IMAP authentication, requires mailbo
## Done! ## Done!
If all the tests were successfull, Postfix is all set up and ready to receive email! Continue with the [Reply by email](./README.md) guide to configure GitLab. If all the tests were successful, Postfix is all set up and ready to receive email! Continue with the [Reply by email](./README.md) guide to configure GitLab.
--------- ---------
_This document was adapted from https://help.ubuntu.com/community/PostfixBasicSetupHowto, by contributors to the Ubuntu documentation wiki._ _This document was adapted from https://help.ubuntu.com/community/PostfixBasicSetupHowto, by contributors to the Ubuntu documentation wiki._
\ No newline at end of file
...@@ -26,13 +26,11 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps ...@@ -26,13 +26,11 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
step 'I fill gitlab-ci settings' do step 'I fill gitlab-ci settings' do
check 'Active' check 'Active'
fill_in 'Project url', with: 'http://ci.gitlab.org/projects/3'
fill_in 'Token', with: 'verySecret'
click_button 'Save' click_button 'Save'
end end
step 'I should see service settings saved' do step 'I should see service settings saved' do
expect(find_field('Project url').value).to eq 'http://ci.gitlab.org/projects/3' expect(find_field('Active').value).to eq '1'
end end
step 'I click hipchat service link' do step 'I click hipchat service link' do
......
...@@ -25,8 +25,12 @@ module Backup ...@@ -25,8 +25,12 @@ module Backup
when "postgresql" then when "postgresql" then
$progress.print "Dumping PostgreSQL database #{config['database']} ... " $progress.print "Dumping PostgreSQL database #{config['database']} ... "
pg_env pg_env
# Pass '--clean' to include 'DROP TABLE' statements in the DB dump. pgsql_args = ["--clean"] # Pass '--clean' to include 'DROP TABLE' statements in the DB dump.
system('pg_dump', '--clean', config['database'], out: db_file_name) if Gitlab.config.backup.pg_schema
pgsql_args << "-n"
pgsql_args << Gitlab.config.backup.pg_schema
end
system('pg_dump', *pgsql_args, config['database'], out: db_file_name)
end end
report_success(success) report_success(success)
abort 'Backup failed' unless success abort 'Backup failed' unless success
......
...@@ -23,6 +23,10 @@ module Ci ...@@ -23,6 +23,10 @@ module Ci
rack_response({ 'message' => '500 Internal Server Error' }, 500) rack_response({ 'message' => '500 Internal Server Error' }, 500)
end end
before do
check_enable_flag!
end
format :json format :json
helpers Helpers helpers Helpers
...@@ -32,7 +36,6 @@ module Ci ...@@ -32,7 +36,6 @@ module Ci
mount Commits mount Commits
mount Runners mount Runners
mount Projects mount Projects
mount Forks
mount Triggers mount Triggers
end end
end end
......
module Ci
module API
class Forks < Grape::API
resource :forks do
# Create a fork
#
# Parameters:
# project_id (required) - The ID of a project
# project_token (requires) - Project token
# private_token(required) - User private token
# data (required) - GitLab project data (name_with_namespace, web_url, default_branch, ssh_url_to_repo)
#
#
# Example Request:
# POST /forks
post do
required_attributes! [:project_id, :data, :project_token, :private_token]
project = Ci::Project.find_by!(gitlab_id: params[:project_id])
authenticate_project_token!(project)
fork = Ci::CreateProjectService.new.execute(
current_user,
params[:data],
Ci::RoutesHelper.ci_project_url(":project_id"),
project
)
if fork
present fork, with: Entities::Project
else
not_found!
end
end
end
end
end
end
...@@ -3,6 +3,12 @@ module Ci ...@@ -3,6 +3,12 @@ module Ci
module Helpers module Helpers
UPDATE_RUNNER_EVERY = 60 UPDATE_RUNNER_EVERY = 60
def check_enable_flag!
unless current_application_settings.ci_enabled
render_api_error!('400 (Bad request) CI is disabled', 400)
end
end
def authenticate_runners! def authenticate_runners!
forbidden! unless params[:token] == GitlabCi::REGISTRATION_TOKEN forbidden! unless params[:token] == GitlabCi::REGISTRATION_TOKEN
end end
......
...@@ -5,49 +5,6 @@ describe Ci::ProjectsController do ...@@ -5,49 +5,6 @@ describe Ci::ProjectsController do
@project = FactoryGirl.create :ci_project @project = FactoryGirl.create :ci_project
end end
describe "POST #build" do
it 'should respond 200 if params is ok' do
post :build, {
id: @project.id,
ref: 'master',
before: '2aa371379db71ac89ae20843fcff3b3477cf1a1d',
after: '1c8a9df454ef68c22c2a33cca8232bb50849e5c5',
token: @project.token,
ci_yaml_file: gitlab_ci_yaml,
commits: [ { message: "Message" } ]
}
expect(response).to be_success
expect(response.code).to eq('201')
end
it 'should respond 400 if push about removed branch' do
post :build, {
id: @project.id,
ref: 'master',
before: '2aa371379db71ac89ae20843fcff3b3477cf1a1d',
after: '0000000000000000000000000000000000000000',
token: @project.token,
ci_yaml_file: gitlab_ci_yaml
}
expect(response).not_to be_success
expect(response.code).to eq('400')
end
it 'should respond 400 if some params missed' do
post :build, id: @project.id, token: @project.token, ci_yaml_file: gitlab_ci_yaml
expect(response).not_to be_success
expect(response.code).to eq('400')
end
it 'should respond 403 if token is wrong' do
post :build, id: @project.id, token: 'invalid-token'
expect(response).not_to be_success
expect(response.code).to eq('403')
end
end
describe "POST /projects" do describe "POST /projects" do
let(:project_dump) { OpenStruct.new({ id: @project.gitlab_id }) } let(:project_dump) { OpenStruct.new({ id: @project.gitlab_id }) }
......
...@@ -180,7 +180,6 @@ describe Grack::Auth do ...@@ -180,7 +180,6 @@ describe Grack::Auth do
gitlab_ci_service = project.build_gitlab_ci_service gitlab_ci_service = project.build_gitlab_ci_service
gitlab_ci_service.active = true gitlab_ci_service.active = true
gitlab_ci_service.token = token gitlab_ci_service.token = token
gitlab_ci_service.project_url = "http://google.com"
gitlab_ci_service.save gitlab_ci_service.save
env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials("gitlab-ci-token", token) env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials("gitlab-ci-token", token)
......
...@@ -63,19 +63,5 @@ describe BuildkiteService do ...@@ -63,19 +63,5 @@ describe BuildkiteService do
) )
end end
end end
describe :builds_page do
it 'returns the correct path to the builds page' do
expect(@service.builds_path).to eq(
'https://buildkite.com/account-name/example-project/builds?branch=default-brancho'
)
end
end
describe :status_img_path do
it 'returns the correct path to the status image' do
expect(@service.status_img_path).to eq('https://badge.buildkite.com/secret-sauce-status-token.svg')
end
end
end end
end end
...@@ -26,51 +26,21 @@ describe GitlabCiService do ...@@ -26,51 +26,21 @@ describe GitlabCiService do
it { is_expected.to have_one(:service_hook) } it { is_expected.to have_one(:service_hook) }
end end
describe 'validations' do
context 'active' do
before { allow(subject).to receive(:activated?).and_return(true) }
it { is_expected.to validate_presence_of(:token) }
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to allow_value('ewf9843kdnfdfs89234n').for(:token) }
it { is_expected.to allow_value('http://ci.example.com/project/1').for(:project_url) }
it { is_expected.not_to allow_value('token with spaces').for(:token) }
it { is_expected.not_to allow_value('token/with%spaces').for(:token) }
it { is_expected.not_to allow_value('this is not url').for(:project_url) }
it { is_expected.not_to allow_value('http//noturl').for(:project_url) }
it { is_expected.not_to allow_value('ftp://ci.example.com/projects/3').for(:project_url) }
end
context 'inactive' do
before { allow(subject).to receive(:activated?).and_return(false) }
it { is_expected.not_to validate_presence_of(:token) }
it { is_expected.not_to validate_presence_of(:project_url) }
it { is_expected.to allow_value('ewf9843kdnfdfs89234n').for(:token) }
it { is_expected.to allow_value('http://ci.example.com/project/1').for(:project_url) }
it { is_expected.to allow_value('token with spaces').for(:token) }
it { is_expected.to allow_value('ftp://ci.example.com/projects/3').for(:project_url) }
end
end
describe 'commits methods' do describe 'commits methods' do
before do before do
@ci_project = create(:ci_project)
@service = GitlabCiService.new @service = GitlabCiService.new
allow(@service).to receive_messages( allow(@service).to receive_messages(
service_hook: true, service_hook: true,
project_url: 'http://ci.gitlab.org/projects/2', project_url: 'http://ci.gitlab.org/projects/2',
token: 'verySecret' token: 'verySecret',
project: @ci_project.gl_project
) )
end end
describe :commit_status_path do
it { expect(@service.commit_status_path("2ab7834c", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/2ab7834c/status.json?token=verySecret")}
it { expect(@service.commit_status_path("issue#2", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/issue%232/status.json?token=verySecret")}
end
describe :build_page do describe :build_page do
it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/2ab7834c")} it { expect(@service.build_page("2ab7834c", 'master')).to eq("/ci/projects/#{@ci_project.id}/refs/master/commits/2ab7834c")}
it { expect(@service.build_page("issue#2", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/issue%232")} it { expect(@service.build_page("issue#2", 'master')).to eq("/ci/projects/#{@ci_project.id}/refs/master/commits/issue%232")}
end end
describe "execute" do describe "execute" do
...@@ -80,8 +50,6 @@ describe GitlabCiService do ...@@ -80,8 +50,6 @@ describe GitlabCiService do
it "calls ci_yaml_file" do it "calls ci_yaml_file" do
service_hook = double service_hook = double
expect(service_hook).to receive(:execute)
expect(@service).to receive(:service_hook).and_return(service_hook)
expect(@service).to receive(:ci_yaml_file).with(push_sample_data[:checkout_sha]) expect(@service).to receive(:ci_yaml_file).with(push_sample_data[:checkout_sha])
@service.execute(push_sample_data) @service.execute(push_sample_data)
...@@ -91,7 +59,7 @@ describe GitlabCiService do ...@@ -91,7 +59,7 @@ describe GitlabCiService do
describe "Fork registration" do describe "Fork registration" do
before do before do
@old_project = create(:empty_project) @old_project = create(:ci_project).gl_project
@project = create(:empty_project) @project = create(:empty_project)
@user = create(:user) @user = create(:user)
...@@ -104,9 +72,9 @@ describe GitlabCiService do ...@@ -104,9 +72,9 @@ describe GitlabCiService do
) )
end end
it "performs http reuquest to ci" do it "creates fork on CI" do
stub_request(:post, "http://ci.gitlab.org/api/v1/forks") expect_any_instance_of(Ci::CreateProjectService).to receive(:execute)
@service.fork_registration(@project, @user.private_token) @service.fork_registration(@project, @user)
end end
end end
end end
...@@ -89,7 +89,7 @@ describe API::API, api: true do ...@@ -89,7 +89,7 @@ describe API::API, api: true do
it 'returns projects in the correct order when ci_enabled_first parameter is passed' do it 'returns projects in the correct order when ci_enabled_first parameter is passed' do
[project, project2, project3].each{ |project| project.build_missing_services } [project, project2, project3].each{ |project| project.build_missing_services }
project2.gitlab_ci_service.update(active: true, token: "token", project_url: "http://ci.example.com/projects/1") project2.gitlab_ci_service.update(active: true, token: "token")
get api('/projects', user), { ci_enabled_first: 'true' } get api('/projects', user), { ci_enabled_first: 'true' }
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response).to be_an Array expect(json_response).to be_an Array
......
...@@ -17,9 +17,9 @@ describe API::API, api: true do ...@@ -17,9 +17,9 @@ describe API::API, api: true do
it "should return if required fields missing" do it "should return if required fields missing" do
attrs = service_attrs attrs = service_attrs
required_attributes = service_attrs_list.select do |attr| required_attributes = service_attrs_list.select do |attr|
service_klass.validators_on(attr).any? do |v| service_klass.validators_on(attr).any? do |v|
v.class == ActiveRecord::Validations::PresenceValidator v.class == ActiveRecord::Validations::PresenceValidator
end end
end end
......
require 'spec_helper'
describe Ci::API::API do
include ApiHelpers
let(:project) { FactoryGirl.create(:ci_project) }
let(:private_token) { create(:user).private_token }
let(:options) do
{
private_token: private_token,
url: GitlabCi.config.gitlab_ci.url
}
end
before do
stub_gitlab_calls
end
describe "POST /forks" do
let(:project_info) do
{
project_id: project.gitlab_id,
project_token: project.token,
data: {
id: create(:empty_project).id,
name_with_namespace: "Gitlab.org / Underscore",
path_with_namespace: "gitlab-org/underscore",
default_branch: "master",
ssh_url_to_repo: "git@example.com:gitlab-org/underscore"
}
}
end
context "with valid info" do
before do
options.merge!(project_info)
end
it "should create a project with valid data" do
post ci_api("/forks"), options
expect(response.status).to eq(201)
expect(json_response['name']).to eq("Gitlab.org / Underscore")
end
end
context "with invalid project info" do
before do
options.merge!({})
end
it "should error with invalid data" do
post ci_api("/forks"), options
expect(response.status).to eq(400)
end
end
end
end
...@@ -7,7 +7,7 @@ describe Ci::CreateProjectService do ...@@ -7,7 +7,7 @@ describe Ci::CreateProjectService do
describe :execute do describe :execute do
context 'valid params' do context 'valid params' do
subject { service.execute(current_user, project, 'http://localhost/projects/:project_id') } subject { service.execute(current_user, project) }
it { is_expected.to be_kind_of(Ci::Project) } it { is_expected.to be_kind_of(Ci::Project) }
it { is_expected.to be_persisted } it { is_expected.to be_persisted }
...@@ -24,7 +24,7 @@ describe Ci::CreateProjectService do ...@@ -24,7 +24,7 @@ describe Ci::CreateProjectService do
FactoryGirl.create(:ci_project, shared_runners_enabled: true, public: true, allow_git_fetch: true) FactoryGirl.create(:ci_project, shared_runners_enabled: true, public: true, allow_git_fetch: true)
end end
subject { service.execute(current_user, project, 'http://localhost/projects/:project_id', ci_origin_project) } subject { service.execute(current_user, project, ci_origin_project) }
it "uses project as a template for settings and jobs" do it "uses project as a template for settings and jobs" do
expect(subject.shared_runners_enabled).to be_truthy expect(subject.shared_runners_enabled).to be_truthy
......
...@@ -44,10 +44,11 @@ describe Projects::ForkService do ...@@ -44,10 +44,11 @@ describe Projects::ForkService do
context 'GitLab CI is enabled' do context 'GitLab CI is enabled' do
it "calls fork registrator for CI" do it "calls fork registrator for CI" do
create(:ci_project, gl_project: @from_project)
@from_project.build_missing_services @from_project.build_missing_services
@from_project.gitlab_ci_service.update_attributes(active: true) @from_project.gitlab_ci_service.update_attributes(active: true)
expect(ForkRegistrationWorker).to receive(:perform_async) expect_any_instance_of(Ci::CreateProjectService).to receive(:execute)
fork_project(@from_project, @to_user) fork_project(@from_project, @to_user)
end end
......
require 'spec_helper'
describe ForkRegistrationWorker do
context "as a resque worker" do
it "reponds to #perform" do
expect(ForkRegistrationWorker.new).to respond_to(:perform)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment