summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-04-08 13:55:01 +0000
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-04-08 13:55:01 +0000
commite91a2cf15942af6e90b736eb5d9e2d994f4a023f (patch)
tree16c153cfa5ea224f665b9c1c21a9c716e37c7d20
parent306ac71b7f7fdf710eaf8e3d5d8be0803f7d3b88 (diff)
parentb13c8b91bc3441e6012c5dd249f4689e0ae94704 (diff)
downloadgitlab-ci-e91a2cf15942af6e90b736eb5d9e2d994f4a023f.tar.gz
Merge branch 'fork_support' into 'master'
Support for forks https://dev.gitlab.org/gitlab/gitlab-ci/issues/187 !!! GitLab side MR - https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/499 See merge request !56
-rw-r--r--app/models/project.rb8
-rw-r--r--app/services/create_project_service.rb20
-rw-r--r--doc/api/README.md1
-rw-r--r--doc/api/forks.md23
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/forks.rb38
-rw-r--r--spec/models/project_spec.rb5
-rw-r--r--spec/requests/api/forks_spec.rb66
-rw-r--r--spec/services/create_project_service_spec.rb18
-rw-r--r--spec/support/stub_gitlab_calls.rb7
10 files changed, 181 insertions, 6 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index c931c50..4351da1 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -74,8 +74,12 @@ ls -la
eos
end
- def parse(project_yaml)
- project = YAML.load(project_yaml)
+ def parse(project_params)
+ project = if project_params.is_a?(String)
+ YAML.load(project_params)
+ else
+ project_params
+ end
params = {
name: project.name_with_namespace,
diff --git a/app/services/create_project_service.rb b/app/services/create_project_service.rb
index 1d99330..e5f9440 100644
--- a/app/services/create_project_service.rb
+++ b/app/services/create_project_service.rb
@@ -1,7 +1,7 @@
class CreateProjectService
include Rails.application.routes.url_helpers
- def execute(current_user, params, project_route)
+ def execute(current_user, params, project_route, forked_project = nil)
@project = Project.parse(params)
Project.transaction do
@@ -13,13 +13,25 @@ class CreateProjectService
project_url: project_route.gsub(":project_id", @project.id.to_s),
}
- if Network.new.enable_ci(current_user.url, @project.gitlab_id, opts, current_user.private_token)
- true
- else
+ unless Network.new.enable_ci(current_user.url, @project.gitlab_id, opts, current_user.private_token)
raise ActiveRecord::Rollback
end
end
+ if forked_project
+ # Copy jobs
+ @project.jobs = forked_project.jobs.map do |job|
+ Job.new(job.attributes)
+ end
+
+ # Copy settings
+ settings = forked_project.attributes.select do |attr_name, value|
+ ["public", "shared_runners_enabled", "allow_git_fetch"].include? attr_name
+ end
+
+ @project.update(settings)
+ end
+
EventService.new.create_project(current_user, @project)
@project
diff --git a/doc/api/README.md b/doc/api/README.md
index 9e3a868..95fe2f8 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -6,6 +6,7 @@
- [Runners](runners.md)
- [Commits](commits.md)
- [Builds](builds.md)
+- [Forks](forks.md)
## Authentication
diff --git a/doc/api/forks.md b/doc/api/forks.md
new file mode 100644
index 0000000..1a5ea80
--- /dev/null
+++ b/doc/api/forks.md
@@ -0,0 +1,23 @@
+# 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 /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)
diff --git a/lib/api/api.rb b/lib/api/api.rb
index a969e4b..d1127ed 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -29,5 +29,6 @@ module API
mount Commits
mount Runners
mount Projects
+ mount Forks
end
end
diff --git a/lib/api/forks.rb b/lib/api/forks.rb
new file mode 100644
index 0000000..92f232c
--- /dev/null
+++ b/lib/api/forks.rb
@@ -0,0 +1,38 @@
+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 = Project.find_by!(gitlab_id: params[:project_id])
+ authenticate_project_token!(project)
+
+ user_session = UserSession.new
+ user = user_session.authenticate_by_token(private_token: params[:private_token], url: GitlabCi.config.gitlab_server.url)
+
+ fork = CreateProjectService.new.execute(
+ user,
+ params[:data],
+ RoutesHelper.project_url(":project_id"),
+ project
+ )
+
+ if fork
+ present fork, with: Entities::Project
+ else
+ not_found!
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 28ccca7..482a401 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -133,6 +133,11 @@ describe Project do
it { parsed_project.name.should eq("GitLab / api.gitlab.org") }
it { parsed_project.gitlab_id.should eq(189) }
it { parsed_project.gitlab_url.should eq("http://localhost:3000/gitlab/api-gitlab-org") }
+
+ it "parses plain hash" do
+ data = YAML.load(project_dump)
+ Project.parse(data).name.should eq("GitLab / api.gitlab.org")
+ end
end
describe :repo_url_with_auth do
diff --git a/spec/requests/api/forks_spec.rb b/spec/requests/api/forks_spec.rb
new file mode 100644
index 0000000..e0469db
--- /dev/null
+++ b/spec/requests/api/forks_spec.rb
@@ -0,0 +1,66 @@
+require 'spec_helper'
+
+describe API::API do
+ include ApiHelpers
+
+ let(:project) { FactoryGirl.create(:project) }
+ let(:gitlab_url) { GitlabCi.config.gitlab_server.url }
+ let(:auth_opts) {
+ {
+ email: "test@test.com",
+ password: "123456"
+ }
+ }
+ let(:private_token) { Network.new.authenticate(gitlab_url, auth_opts)["private_token"] }
+
+ let(:options) {
+ {
+ private_token: private_token,
+ url: gitlab_url
+ }
+ }
+
+ before {
+ stub_gitlab_calls
+ }
+
+
+ describe "POST /forks" do
+ let(:project_info) {
+ {
+ project_id: project.gitlab_id,
+ project_token: project.token,
+ data: {
+ id: 2,
+ name_with_namespace: "Gitlab.org / Underscore",
+ web_url: "http://example.com/gitlab-org/underscore",
+ default_branch: "master",
+ ssh_url_to_repo: "git@example.com:gitlab-org/underscore"
+ }
+ }
+ }
+
+ context "with valid info" do
+ before do
+ options.merge!(project_info)
+ end
+
+ it "should create a project with valid data" do
+ post api("/forks"), options
+ response.status.should == 201
+ json_response['name'].should == "Gitlab.org / Underscore"
+ end
+ end
+
+ context "with invalid project info" do
+ before do
+ options.merge!({})
+ end
+
+ it "should error with invalid data" do
+ post api("/forks"), options
+ response.status.should == 400
+ end
+ end
+ end
+end
diff --git a/spec/services/create_project_service_spec.rb b/spec/services/create_project_service_spec.rb
index 7046830..6ecb93e 100644
--- a/spec/services/create_project_service_spec.rb
+++ b/spec/services/create_project_service_spec.rb
@@ -20,5 +20,23 @@ describe CreateProjectService do
expect { service.execute(current_user, '', '') }.to raise_error
end
end
+
+ context "forking" do
+ it "uses project as a template for settings and jobs" do
+ origin_project = FactoryGirl.create(:project)
+ origin_project.jobs << Job.new(commands: "pwd")
+ origin_project.shared_runners_enabled = true
+ origin_project.public = true
+ origin_project.allow_git_fetch = true
+ origin_project.save!
+
+ project = service.execute(current_user, project_dump, 'http://localhost/projects/:project_id', origin_project)
+
+ project.shared_runners_enabled.should be_true
+ project.public.should be_true
+ project.allow_git_fetch.should be_true
+ project.jobs.last.commands.should == "pwd"
+ end
+ end
end
end
diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb
index 6c047ec..3058d03 100644
--- a/spec/support/stub_gitlab_calls.rb
+++ b/spec/support/stub_gitlab_calls.rb
@@ -7,6 +7,7 @@ module StubGitlabCalls
stub_project_8_hooks
stub_projects
stub_projects_owned
+ stub_ci_enable
end
def stub_js_gitlab_calls
@@ -73,6 +74,12 @@ module StubGitlabCalls
to_return(:status => 200, :body => "", :headers => {})
end
+ def stub_ci_enable
+ stub_request(:put, "#{gitlab_url}api/v3/projects/2/services/gitlab-ci.json?private_token=Wvjy2Krpb7y8xi93owUz").
+ with(:headers => {'Content-Type'=>'application/json'}).
+ to_return(:status => 200, :body => "", :headers => {})
+ end
+
def project_hash_array
f = File.read(Rails.root.join('spec/support/gitlab_stubs/projects.json'))
return JSON.parse f