Commit b9ccc79c authored by Kamil Trzcinski's avatar Kamil Trzcinski
Browse files

Delegate ci_project parameters to projects

- It delegates name, path, gitlab_url, ssh_url_to_repo
- Remove ability to set this parameters using CI API

This fixes GitLab project rename, namespace change, repository rename, etc.
parent 171eeedda109
......@@ -12,7 +12,10 @@ def index
def show
@builds = @runner.builds.order('id DESC').first(30)
@projects = Ci::Project.all
@projects = @projects.search(params[:search]) if params[:search].present?
if params[:search].present?
@gl_projects = ::Project.search(params[:search])
@projects = @projects.where(gitlab_id: @gl_projects.select(:id))
end
@projects = @projects.where("ci_projects.id NOT IN (?)", @runner.projects.pluck(:id)) if @runner.projects.any?
@projects = @projects.page(params[:page]).per(30)
end
......
......@@ -48,11 +48,12 @@ class Project < ActiveRecord::Base
accepts_nested_attributes_for :variables, allow_destroy: true
delegate :name_with_namespace, :path_with_namespace, :web_url, :http_url_to_repo, :ssh_url_to_repo, to: :gl_project
#
# Validations
#
validates_presence_of :name, :timeout, :token, :default_ref,
:path, :ssh_url_to_repo, :gitlab_id
validates_presence_of :timeout, :token, :default_ref, :gitlab_id
validates_uniqueness_of :gitlab_id
......@@ -60,8 +61,6 @@ class Project < ActiveRecord::Base
presence: true,
if: ->(project) { project.always_build.present? }
scope :public_only, ->() { where(public: true) }
before_validation :set_default_values
class << self
......@@ -76,12 +75,9 @@ def base_build_script
def parse(project)
params = {
name: project.name_with_namespace,
gitlab_id: project.id,
path: project.path_with_namespace,
default_ref: project.default_branch || 'master',
ssh_url_to_repo: project.ssh_url_to_repo,
email_add_pusher: current_application_settings.add_pusher,
gitlab_id: project.id,
default_ref: project.default_branch || 'master',
email_add_pusher: current_application_settings.add_pusher,
email_only_broken_builds: current_application_settings.all_broken_builds,
}
......@@ -105,11 +101,18 @@ def ordered_by_last_commit_date
joins("LEFT JOIN #{last_commit_subquery} AS last_commit ON #{Ci::Project.table_name}.gitlab_id = last_commit.gl_project_id").
order("CASE WHEN last_commit.committed_at IS NULL THEN 1 ELSE 0 END, last_commit.committed_at DESC")
end
end
def search(query)
where("LOWER(#{Ci::Project.table_name}.name) LIKE :query",
query: "%#{query.try(:downcase)}%")
end
def name
name_with_namespace
end
def path
path_with_namespace
end
def gitlab_url
web_url
end
def any_runners?
......@@ -123,9 +126,6 @@ def any_runners?
def set_default_values
self.token = SecureRandom.hex(15) if self.token.blank?
self.default_ref ||= 'master'
self.name ||= gl_project.name_with_namespace
self.path ||= gl_project.path_with_namespace
self.ssh_url_to_repo ||= gl_project.ssh_url_to_repo
end
def tracked_refs
......@@ -169,7 +169,7 @@ def coverage_enabled?
# using http and basic auth
def repo_url_with_auth
auth = "gitlab-ci-token:#{token}@"
url = gitlab_url + ".git"
url = http_url_to_repo + ".git"
url.sub(/^https?:\/\//) do |prefix|
prefix + auth
end
......@@ -201,10 +201,6 @@ def execute_services(data)
end
end
def gitlab_url
File.join(Gitlab.config.gitlab.url, path)
end
def setup_finished?
commits.any?
end
......
......@@ -70,11 +70,7 @@ def commit_status(sha, ref)
def fork_registration(new_project, current_user)
params = OpenStruct.new({
id: new_project.id,
name_with_namespace: new_project.name_with_namespace,
path_with_namespace: new_project.path_with_namespace,
web_url: new_project.web_url,
default_branch: new_project.default_branch,
ssh_url_to_repo: new_project.ssh_url_to_repo
default_branch: new_project.default_branch
})
ci_project = Ci::Project.find_by!(gitlab_id: project.id)
......
class ChangeNameOfCiProjects < ActiveRecord::Migration
def up
change_column_null :ci_projects, :name, true
end
def down
change_column_null :ci_projects, :name, false
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150924125436) do
ActiveRecord::Schema.define(version: 20150930095736) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -158,7 +158,7 @@
add_index "ci_jobs", ["project_id"], name: "index_ci_jobs_on_project_id", using: :btree
create_table "ci_projects", force: true do |t|
t.string "name", null: false
t.string "name"
t.integer "timeout", default: 3600, null: false
t.datetime "created_at"
t.datetime "updated_at"
......
......@@ -100,8 +100,6 @@ Parameters:
* `name` (required) - The name of the project
* `gitlab_id` (required) - The ID of the project on the Gitlab instance
* `path` (required) - The gitlab project path
* `ssh_url_to_repo` (required) - The gitlab SSH url to the repo
* `default_ref` (optional) - The branch to run on (default to `master`)
### Update Project
......@@ -114,9 +112,6 @@ authenticated user has access to.
Parameters:
* `name` - The name of the project
* `gitlab_id` - The ID of the project on the Gitlab instance
* `path` - The gitlab project path
* `ssh_url_to_repo` - The gitlab SSH url to the repo
* `default_ref` - The branch to run on (default to `master`)
### Remove Project
......
......@@ -75,23 +75,17 @@ class Projects < Grape::API
# Create Gitlab CI project using Gitlab project info
#
# Parameters:
# name (required) - The name of the project
# gitlab_id (required) - The gitlab id of the project
# path (required) - The gitlab project path, ex. randx/six
# ssh_url_to_repo (required) - The gitlab ssh url to the repo
# default_ref - The branch to run against (defaults to `master`)
# Example Request:
# POST /projects
post do
required_attributes! [:name, :gitlab_id, :ssh_url_to_repo]
required_attributes! [:gitlab_id]
filtered_params = {
name: params[:name],
gitlab_id: params[:gitlab_id],
# we accept gitlab_url for backward compatibility for a while (added to 7.11)
path: params[:path] || params[:gitlab_url].sub(/.*\/(.*\/.*)$/, '\1'),
default_ref: params[:default_ref] || 'master',
ssh_url_to_repo: params[:ssh_url_to_repo]
default_ref: params[:default_ref] || 'master'
}
project = Ci::Project.new(filtered_params)
......@@ -109,11 +103,7 @@ class Projects < Grape::API
#
# Parameters:
# id (required) - The ID of a project
# name - The name of the project
# gitlab_id - The gitlab id of the project
# path - The gitlab project path, ex. randx/six
# ssh_url_to_repo - The gitlab ssh url to the repo
# default_ref - The branch to run against (defaults to `master`)
# default_ref - The branch to run against (defaults to `master`)
# Example Request:
# PUT /projects/:id
put ":id" do
......@@ -121,12 +111,7 @@ class Projects < Grape::API
unauthorized! unless can?(current_user, :admin_project, project.gl_project)
attrs = attributes_for_keys [:name, :gitlab_id, :path, :gitlab_url, :default_ref, :ssh_url_to_repo]
# we accept gitlab_url for backward compatibility for a while (added to 7.11)
if attrs[:gitlab_url] && !attrs[:path]
attrs[:path] = attrs[:gitlab_url].sub(/.*\/(.*\/.*)$/, '\1')
end
attrs = attributes_for_keys [:default_ref]
if project.update_attributes(attrs)
present project, with: Entities::Project
......
......@@ -29,20 +29,8 @@
FactoryGirl.define do
factory :ci_project_without_token, class: Ci::Project do
sequence :name do |n|
"GitLab / gitlab-shell#{n}"
end
default_ref 'master'
sequence :path do |n|
"gitlab/gitlab-shell#{n}"
end
sequence :ssh_url_to_repo do |n|
"git@demo.gitlab.com:gitlab/gitlab-shell#{n}.git"
end
gl_project factory: :empty_project
factory :ci_project do
......
......@@ -2,8 +2,7 @@
describe "Admin Runners" do
before do
skip_ci_admin_auth
login_as :user
login_as :admin
end
describe "Runners page" do
......@@ -37,8 +36,8 @@
let(:runner) { FactoryGirl.create :ci_runner }
before do
FactoryGirl.create(:ci_project, name: "foo")
FactoryGirl.create(:ci_project, name: "bar")
@project1 = FactoryGirl.create(:ci_project)
@project2 = FactoryGirl.create(:ci_project)
visit ci_admin_runner_path(runner)
end
......@@ -47,19 +46,19 @@
end
describe 'projects' do
it { expect(page).to have_content("foo") }
it { expect(page).to have_content("bar") }
it { expect(page).to have_content(@project1.name_with_namespace) }
it { expect(page).to have_content(@project2.name_with_namespace) }
end
describe 'search' do
before do
search_form = find('#runner-projects-search')
search_form.fill_in 'search', with: 'foo'
search_form.fill_in 'search', with: @project1.gl_project.name
search_form.click_button 'Search'
end
it { expect(page).to have_content("foo") }
it { expect(page).not_to have_content("bar") }
it { expect(page).to have_content(@project1.name_with_namespace) }
it { expect(page).not_to have_content(@project2.name_with_namespace) }
end
end
end
......@@ -29,7 +29,8 @@
describe Ci::Project do
let(:gl_project) { FactoryGirl.create :empty_project }
subject { FactoryGirl.create :ci_project, gl_project: gl_project }
let(:project) { FactoryGirl.create :ci_project, gl_project: gl_project }
subject { project }
it { is_expected.to have_many(:runner_projects) }
it { is_expected.to have_many(:runners) }
......@@ -40,6 +41,7 @@
it { is_expected.to have_many(:services) }
it { is_expected.to validate_presence_of :timeout }
it { is_expected.to validate_presence_of :gitlab_id }
describe 'before_validation' do
it 'should set an random token if none provided' do
......@@ -53,6 +55,66 @@
end
end
describe :name_with_namespace do
subject { project.name_with_namespace }
it { is_expected.to eq(project.name) }
it { is_expected.to eq(gl_project.name_with_namespace) }
end
describe :path_with_namespace do
subject { project.path_with_namespace }
it { is_expected.to eq(project.path) }
it { is_expected.to eq(gl_project.path_with_namespace) }
end
describe :path_with_namespace do
subject { project.web_url }
it { is_expected.to eq(gl_project.web_url) }
end
describe :web_url do
subject { project.web_url }
it { is_expected.to eq(project.gitlab_url) }
it { is_expected.to eq(gl_project.web_url) }
end
describe :http_url_to_repo do
subject { project.http_url_to_repo }
it { is_expected.to eq(gl_project.http_url_to_repo) }
end
describe :ssh_url_to_repo do
subject { project.ssh_url_to_repo }
it { is_expected.to eq(gl_project.ssh_url_to_repo) }
end
describe :commits do
subject { project.commits }
before do
FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: gl_project
end
it { is_expected.to eq(gl_project.ci_commits) }
end
describe :builds do
subject { project.builds }
before do
commit = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: gl_project
FactoryGirl.create :ci_build, commit: commit
end
it { is_expected.to eq(gl_project.ci_builds) }
end
describe "ordered_by_last_commit_date" do
it "returns ordered projects" do
newest_project = FactoryGirl.create :empty_project
......@@ -174,13 +236,6 @@
it { is_expected.to include(project.gitlab_url[7..-1]) }
end
describe :search do
let!(:project) { FactoryGirl.create(:ci_project, name: "foo") }
it { expect(Ci::Project.search('fo')).to include(project) }
it { expect(Ci::Project.search('bar')).to be_empty }
end
describe :any_runners do
it "there are no runners available" do
project = FactoryGirl.create(:ci_project)
......
......@@ -134,7 +134,7 @@
describe "PUT /projects/:id" do
let!(:project) { FactoryGirl.create(:ci_project) }
let!(:project_info) { { name: "An updated name!" } }
let!(:project_info) { { default_ref: "develop" } }
before do
options.merge!(project_info)
......@@ -144,7 +144,7 @@
project.gl_project.team << [user, :master]
put ci_api("/projects/#{project.id}"), options
expect(response.status).to eq(200)
expect(json_response["name"]).to eq(project_info[:name])
expect(json_response["default_ref"]).to eq(project_info[:default_ref])
end
it "fails to update a non-existing project" do
......@@ -181,12 +181,10 @@
end
describe "POST /projects" do
let(:gl_project) { FactoryGirl.create :empty_project }
let(:project_info) do
{
name: "My project",
gitlab_id: 1,
path: "testing/testing",
ssh_url_to_repo: "ssh://example.com/testing/testing.git"
gitlab_id: gl_project.id
}
end
......@@ -200,7 +198,7 @@
it "should create a project with valid data" do
post ci_api("/projects"), options
expect(response.status).to eq(201)
expect(json_response['name']).to eq(project_info[:name])
expect(json_response['name']).to eq(gl_project.name_with_namespace)
end
end
......
require 'spec_helper'
describe Ci::EventService do
let(:project) { FactoryGirl.create :ci_project, name: "GitLab / gitlab-shell" }
let(:project) { FactoryGirl.create :ci_project }
let(:user) { double(username: "root", id: 1) }
before do
......@@ -12,7 +12,7 @@
it "creates event" do
Ci::EventService.new.remove_project(user, project)
expect(Ci::Event.admin.last.description).to eq("Project \"GitLab / gitlab-shell\" has been removed by root")
expect(Ci::Event.admin.last.description).to eq("Project \"#{project.name_with_namespace}\" has been removed by root")
end
end
......@@ -20,7 +20,7 @@
it "creates event" do
Ci::EventService.new.create_project(user, project)
expect(Ci::Event.admin.last.description).to eq("Project \"GitLab / gitlab-shell\" has been created by root")
expect(Ci::Event.admin.last.description).to eq("Project \"#{project.name_with_namespace}\" has been created by root")
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