summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_triggerer.vue35
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_url.vue11
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table.vue13
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table_row.vue7
-rw-r--r--app/models/merge_request.rb10
-rw-r--r--app/services/merge_requests/base_service.rb2
-rw-r--r--changelogs/unreleased/58105-pipeline-author-and-commit-author-too-close-together-in-pipeline-list.yml5
-rw-r--r--changelogs/unreleased/fix-merge-request-pipeline-exist-method.yml5
-rw-r--r--db/migrate/20190418182545_create_merge_request_trains_table.rb18
-rw-r--r--db/schema.rb14
-rw-r--r--lib/gitlab/git/repository.rb6
-rw-r--r--lib/gitlab/gitaly_client/repository_service.rb8
-rw-r--r--locale/gitlab.pot6
-rw-r--r--spec/factories/merge_requests.rb6
-rw-r--r--spec/javascripts/pipelines/pipeline_triggerer_spec.js54
-rw-r--r--spec/javascripts/pipelines/pipeline_url_spec.js48
-rw-r--r--spec/javascripts/pipelines/pipelines_table_row_spec.js4
-rw-r--r--spec/lib/gitlab/git/object_pool_spec.rb6
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb39
-rw-r--r--spec/lib/gitlab/gitaly_client/repository_service_spec.rb30
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml2
-rw-r--r--spec/models/ci/build_spec.rb4
-rw-r--r--spec/models/ci/pipeline_spec.rb2
-rw-r--r--spec/models/concerns/has_ref_spec.rb4
-rw-r--r--spec/serializers/pipeline_entity_spec.rb4
-rw-r--r--spec/services/merge_requests/create_service_spec.rb6
-rw-r--r--spec/services/merge_requests/refresh_service_spec.rb22
27 files changed, 270 insertions, 101 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipeline_triggerer.vue b/app/assets/javascripts/pipelines/components/pipeline_triggerer.vue
new file mode 100644
index 00000000000..740b54cd8e0
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/pipeline_triggerer.vue
@@ -0,0 +1,35 @@
+<script>
+import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
+
+export default {
+ components: {
+ UserAvatarLink,
+ },
+ props: {
+ pipeline: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ user() {
+ return this.pipeline.user;
+ },
+ },
+};
+</script>
+<template>
+ <div class="table-section section-10 d-none d-sm-none d-md-block pipeline-triggerer">
+ <user-avatar-link
+ v-if="user"
+ :link-href="user.path"
+ :img-src="user.avatar_url"
+ :img-size="26"
+ :tooltip-text="user.name"
+ class="prepend-left-default js-pipeline-url-user"
+ />
+ <span v-else class="prepend-left-default js-pipeline-url-api api">
+ {{ s__('Pipelines|API') }}
+ </span>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue
index 3e7bf20470c..c41ecab1294 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_url.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue
@@ -59,19 +59,10 @@ export default {
};
</script>
<template>
- <div class="table-section section-15 d-none d-sm-none d-md-block pipeline-tags">
+ <div class="table-section section-10 d-none d-sm-none d-md-block pipeline-tags">
<gl-link :href="pipeline.path" class="js-pipeline-url-link">
<span class="pipeline-id">#{{ pipeline.id }}</span>
</gl-link>
- <span>by</span>
- <user-avatar-link
- v-if="user"
- :link-href="user.path"
- :img-src="user.avatar_url"
- :tooltip-text="user.name"
- class="js-pipeline-url-user"
- />
- <span v-if="!user" class="js-pipeline-url-api api"> API </span>
<div class="label-container">
<span
v-if="pipeline.flags.latest"
diff --git a/app/assets/javascripts/pipelines/components/pipelines_table.vue b/app/assets/javascripts/pipelines/components/pipelines_table.vue
index fcd1f119df0..03d332cd430 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_table.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table.vue
@@ -1,4 +1,5 @@
<script>
+import { GlTooltipDirective } from '@gitlab/ui';
import PipelinesTableRowComponent from './pipelines_table_row.vue';
import PipelineStopModal from './pipeline_stop_modal.vue';
import eventHub from '../event_hub';
@@ -13,6 +14,9 @@ export default {
PipelinesTableRowComponent,
PipelineStopModal,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
props: {
pipelines: {
type: Array,
@@ -62,16 +66,19 @@ export default {
<template>
<div class="ci-table">
<div class="gl-responsive-table-row table-row-header" role="row">
- <div class="table-section section-10 js-pipeline-status pipeline-status" role="rowheader">
+ <div class="table-section section-10 js-pipeline-status" role="rowheader">
{{ s__('Pipeline|Status') }}
</div>
- <div class="table-section section-15 js-pipeline-info pipeline-info" role="rowheader">
+ <div class="table-section section-10 js-pipeline-info pipeline-info" role="rowheader">
{{ s__('Pipeline|Pipeline') }}
</div>
+ <div class="table-section section-10 js-triggerer-info triggerer-info" role="rowheader">
+ {{ s__('Pipeline|Triggerer') }}
+ </div>
<div class="table-section section-20 js-pipeline-commit pipeline-commit" role="rowheader">
{{ s__('Pipeline|Commit') }}
</div>
- <div class="table-section section-20 js-pipeline-stages pipeline-stages" role="rowheader">
+ <div class="table-section section-15 js-pipeline-stages pipeline-stages" role="rowheader">
{{ s__('Pipeline|Stages') }}
</div>
</div>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
index 1c44427e720..e32e2f785bd 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
@@ -5,6 +5,7 @@ import PipelinesArtifactsComponent from './pipelines_artifacts.vue';
import CiBadge from '../../vue_shared/components/ci_badge_link.vue';
import PipelineStage from './stage.vue';
import PipelineUrl from './pipeline_url.vue';
+import PipelineTriggerer from './pipeline_triggerer.vue';
import PipelinesTimeago from './time_ago.vue';
import CommitComponent from '../../vue_shared/components/commit.vue';
import LoadingButton from '../../vue_shared/components/loading_button.vue';
@@ -23,6 +24,7 @@ export default {
CommitComponent,
PipelineStage,
PipelineUrl,
+ PipelineTriggerer,
CiBadge,
PipelinesTimeago,
LoadingButton,
@@ -264,8 +266,9 @@ export default {
</div>
<pipeline-url :pipeline="pipeline" :auto-devops-help-path="autoDevopsHelpPath" />
+ <pipeline-triggerer :pipeline="pipeline" />
- <div class="table-section section-20">
+ <div class="table-section section-wrap section-20">
<div class="table-mobile-header" role="rowheader">{{ s__('Pipeline|Commit') }}</div>
<div class="table-mobile-content">
<commit-component
@@ -281,7 +284,7 @@ export default {
</div>
</div>
- <div class="table-section section-wrap section-20 stage-cell">
+ <div class="table-section section-wrap section-15 stage-cell">
<div class="table-mobile-header" role="rowheader">{{ s__('Pipeline|Stages') }}</div>
<div class="table-mobile-content">
<template v-if="pipeline.details.stages.length > 0">
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index c2a1487fc6e..df162e4844c 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -66,7 +66,7 @@ class MergeRequest < ApplicationRecord
dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
has_many :cached_closes_issues, through: :merge_requests_closing_issues, source: :issue
- has_many :merge_request_pipelines, foreign_key: 'merge_request_id', class_name: 'Ci::Pipeline'
+ has_many :pipelines_for_merge_request, foreign_key: 'merge_request_id', class_name: 'Ci::Pipeline'
has_many :suggestions, through: :notes
has_many :merge_request_assignees
@@ -1157,10 +1157,6 @@ class MergeRequest < ApplicationRecord
end
end
- def merge_request_pipeline_exists?
- merge_request_pipelines.exists?(sha: diff_head_sha)
- end
-
def has_test_reports?
actual_head_pipeline&.has_reports?(Ci::JobArtifact.test_reports)
end
@@ -1379,12 +1375,12 @@ class MergeRequest < ApplicationRecord
source_project.repository.squash_in_progress?(id)
end
- private
-
def find_actual_head_pipeline
all_pipelines.for_sha_or_source_sha(diff_head_sha).first
end
+ private
+
def source_project_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
break variables unless source_project
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index a9dd26c02ad..bb9062e9b40 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -81,7 +81,7 @@ module MergeRequests
##
# UpdateMergeRequestsWorker could be retried by an exception.
# pipelines for merge request should not be recreated in such case.
- return false if merge_request.merge_request_pipeline_exists?
+ return false if merge_request.find_actual_head_pipeline&.triggered_by_merge_request?
return false if merge_request.has_no_commits?
true
diff --git a/changelogs/unreleased/58105-pipeline-author-and-commit-author-too-close-together-in-pipeline-list.yml b/changelogs/unreleased/58105-pipeline-author-and-commit-author-too-close-together-in-pipeline-list.yml
new file mode 100644
index 00000000000..aef0a5ad53e
--- /dev/null
+++ b/changelogs/unreleased/58105-pipeline-author-and-commit-author-too-close-together-in-pipeline-list.yml
@@ -0,0 +1,5 @@
+---
+title: Improve pipelines table spacing, add triggerer column
+merge_request: 26136
+author:
+type: changed
diff --git a/changelogs/unreleased/fix-merge-request-pipeline-exist-method.yml b/changelogs/unreleased/fix-merge-request-pipeline-exist-method.yml
new file mode 100644
index 00000000000..294a665ff3e
--- /dev/null
+++ b/changelogs/unreleased/fix-merge-request-pipeline-exist-method.yml
@@ -0,0 +1,5 @@
+---
+title: Fix duplicate merge request pipelines created by Sidekiq worker retry
+merge_request: 26643
+author:
+type: fixed
diff --git a/db/migrate/20190418182545_create_merge_request_trains_table.rb b/db/migrate/20190418182545_create_merge_request_trains_table.rb
new file mode 100644
index 00000000000..ac927c9c6b9
--- /dev/null
+++ b/db/migrate/20190418182545_create_merge_request_trains_table.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class CreateMergeRequestTrainsTable < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def change
+ create_table :merge_trains, id: :bigserial do |t|
+ t.references :merge_request, foreign_key: { on_delete: :cascade }, type: :integer, index: false, null: false
+ t.references :user, foreign_key: { on_delete: :cascade }, type: :integer, null: false
+ t.references :pipeline, foreign_key: { to_table: :ci_pipelines, on_delete: :nullify }, type: :integer
+ t.timestamps_with_timezone null: false
+
+ t.index [:merge_request_id], unique: true
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index de9e6f0b40d..ef8cb4abf31 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -1361,6 +1361,17 @@ ActiveRecord::Schema.define(version: 20190426180107) do
t.index ["merge_request_id"], name: "index_merge_requests_closing_issues_on_merge_request_id", using: :btree
end
+ create_table "merge_trains", force: :cascade do |t|
+ t.integer "merge_request_id", null: false
+ t.integer "user_id", null: false
+ t.integer "pipeline_id"
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["merge_request_id"], name: "index_merge_trains_on_merge_request_id", unique: true, using: :btree
+ t.index ["pipeline_id"], name: "index_merge_trains_on_pipeline_id", using: :btree
+ t.index ["user_id"], name: "index_merge_trains_on_user_id", using: :btree
+ end
+
create_table "milestones", id: :serial, force: :cascade do |t|
t.string "title", null: false
t.integer "project_id"
@@ -2514,6 +2525,9 @@ ActiveRecord::Schema.define(version: 20190426180107) do
add_foreign_key "merge_requests", "users", column: "updated_by_id", name: "fk_641731faff", on_delete: :nullify
add_foreign_key "merge_requests_closing_issues", "issues", on_delete: :cascade
add_foreign_key "merge_requests_closing_issues", "merge_requests", on_delete: :cascade
+ add_foreign_key "merge_trains", "ci_pipelines", column: "pipeline_id", on_delete: :nullify
+ add_foreign_key "merge_trains", "merge_requests", on_delete: :cascade
+ add_foreign_key "merge_trains", "users", on_delete: :cascade
add_foreign_key "milestones", "namespaces", column: "group_id", name: "fk_95650a40d4", on_delete: :cascade
add_foreign_key "milestones", "projects", name: "fk_9bd0a0c791", on_delete: :cascade
add_foreign_key "note_diff_files", "notes", column: "diff_note_id", on_delete: :cascade
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 508499f227c..fc9bcbdcca2 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -922,6 +922,12 @@ module Gitlab
end
end
+ def disconnect_alternates
+ wrapped_gitaly_errors do
+ gitaly_repository_client.disconnect_alternates
+ end
+ end
+
def gitaly_repository
Gitlab::GitalyClient::Util.repository(@storage, @relative_path, @gl_repository, @gl_project_path)
end
diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb
index 74aae4a8e97..68b17e86608 100644
--- a/lib/gitlab/gitaly_client/repository_service.rb
+++ b/lib/gitlab/gitaly_client/repository_service.rb
@@ -331,6 +331,14 @@ module Gitlab
search_results_from_response(response)
end
+ def disconnect_alternates
+ request = Gitaly::DisconnectGitAlternatesRequest.new(
+ repository: @gitaly_repo
+ )
+
+ GitalyClient.call(@storage, :object_pool_service, :disconnect_git_alternates, request)
+ end
+
private
def search_results_from_response(gitaly_response)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ccf9725e3ff..122f31fec44 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -6719,6 +6719,9 @@ msgstr ""
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
+msgid "Pipelines|API"
+msgstr ""
+
msgid "Pipelines|Build with confidence"
msgstr ""
@@ -6797,6 +6800,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Triggerer"
+msgstr ""
+
msgid "Pipeline|Variables"
msgstr ""
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index abf0e6bccb7..e8df5094b83 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -119,7 +119,7 @@ FactoryBot.define do
trait :with_legacy_detached_merge_request_pipeline do
after(:create) do |merge_request|
- merge_request.merge_request_pipelines << create(:ci_pipeline,
+ merge_request.pipelines_for_merge_request << create(:ci_pipeline,
source: :merge_request_event,
merge_request: merge_request,
project: merge_request.source_project,
@@ -130,7 +130,7 @@ FactoryBot.define do
trait :with_detached_merge_request_pipeline do
after(:create) do |merge_request|
- merge_request.merge_request_pipelines << create(:ci_pipeline,
+ merge_request.pipelines_for_merge_request << create(:ci_pipeline,
source: :merge_request_event,
merge_request: merge_request,
project: merge_request.source_project,
@@ -147,7 +147,7 @@ FactoryBot.define do
end
after(:create) do |merge_request, evaluator|
- merge_request.merge_request_pipelines << create(:ci_pipeline,
+ merge_request.pipelines_for_merge_request << create(:ci_pipeline,
source: :merge_request_event,
merge_request: merge_request,
project: merge_request.source_project,
diff --git a/spec/javascripts/pipelines/pipeline_triggerer_spec.js b/spec/javascripts/pipelines/pipeline_triggerer_spec.js
new file mode 100644
index 00000000000..8cf290f2663
--- /dev/null
+++ b/spec/javascripts/pipelines/pipeline_triggerer_spec.js
@@ -0,0 +1,54 @@
+import { mount } from '@vue/test-utils';
+import pipelineTriggerer from '~/pipelines/components/pipeline_triggerer.vue';
+
+describe('Pipelines Triggerer', () => {
+ let wrapper;
+
+ const mockData = {
+ pipeline: {
+ user: {
+ name: 'foo',
+ avatar_url: '/avatar',
+ path: '/path',
+ },
+ },
+ };
+
+ const createComponent = () => {
+ wrapper = mount(pipelineTriggerer, {
+ propsData: mockData,
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('should render a table cell', () => {
+ expect(wrapper.contains('.table-section')).toBe(true);
+ });
+
+ it('should render triggerer information when triggerer is provided', () => {
+ const link = wrapper.find('.js-pipeline-url-user');
+
+ expect(link.attributes('href')).toEqual(mockData.pipeline.user.path);
+ expect(link.find('.js-user-avatar-image-toolip').text()).toEqual(mockData.pipeline.user.name);
+ expect(link.find('img.avatar').attributes('src')).toEqual(
+ `${mockData.pipeline.user.avatar_url}?width=26`,
+ );
+ });
+
+ it('should render "API" when no triggerer is provided', () => {
+ wrapper.setProps({
+ pipeline: {
+ user: null,
+ },
+ });
+
+ expect(wrapper.find('.js-pipeline-url-api').text()).toEqual('API');
+ });
+});
diff --git a/spec/javascripts/pipelines/pipeline_url_spec.js b/spec/javascripts/pipelines/pipeline_url_spec.js
index faad49a78b0..aa196af2f33 100644
--- a/spec/javascripts/pipelines/pipeline_url_spec.js
+++ b/spec/javascripts/pipelines/pipeline_url_spec.js
@@ -42,54 +42,6 @@ describe('Pipeline Url Component', () => {
expect(component.$el.querySelector('.js-pipeline-url-link span').textContent).toEqual('#1');
});
- it('should render user information when a user is provided', () => {
- const mockData = {
- pipeline: {
- id: 1,
- path: 'foo',
- flags: {},
- user: {
- web_url: '/',
- name: 'foo',
- avatar_url: '/',
- path: '/',
- },
- },
- autoDevopsHelpPath: 'foo',
- };
-
- const component = new PipelineUrlComponent({
- propsData: mockData,
- }).$mount();
-
- const image = component.$el.querySelector('.js-pipeline-url-user img');
- const tooltip = component.$el.querySelector(
- '.js-pipeline-url-user .js-user-avatar-image-toolip',
- );
-
- expect(component.$el.querySelector('.js-pipeline-url-user').getAttribute('href')).toEqual(
- mockData.pipeline.user.web_url,
- );
-
- expect(tooltip.textContent.trim()).toEqual(mockData.pipeline.user.name);
- expect(image.getAttribute('src')).toEqual(`${mockData.pipeline.user.avatar_url}?width=20`);
- });
-
- it('should render "API" when no user is provided', () => {
- const component = new PipelineUrlComponent({
- propsData: {
- pipeline: {
- id: 1,
- path: 'foo',
- flags: {},
- },
- autoDevopsHelpPath: 'foo',
- },
- }).$mount();
-
- expect(component.$el.querySelector('.js-pipeline-url-api').textContent).toContain('API');
- });
-
it('should render latest, yaml invalid, merge request, and stuck flags when provided', () => {
const component = new PipelineUrlComponent({
propsData: {
diff --git a/spec/javascripts/pipelines/pipelines_table_row_spec.js b/spec/javascripts/pipelines/pipelines_table_row_spec.js
index 234fc705a81..d47504d2f54 100644
--- a/spec/javascripts/pipelines/pipelines_table_row_spec.js
+++ b/spec/javascripts/pipelines/pipelines_table_row_spec.js
@@ -80,13 +80,13 @@ describe('Pipelines Table Row', () => {
it('should render user information', () => {
expect(
component.$el
- .querySelector('.table-section:nth-child(2) a:nth-child(3)')
+ .querySelector('.table-section:nth-child(3) .js-pipeline-url-user')
.getAttribute('href'),
).toEqual(pipeline.user.path);
expect(
component.$el
- .querySelector('.table-section:nth-child(2) .js-user-avatar-image-toolip')
+ .querySelector('.table-section:nth-child(3) .js-user-avatar-image-toolip')
.textContent.trim(),
).toEqual(pipeline.user.name);
});
diff --git a/spec/lib/gitlab/git/object_pool_spec.rb b/spec/lib/gitlab/git/object_pool_spec.rb
index 6511c2b61bf..ebeb7b7b633 100644
--- a/spec/lib/gitlab/git/object_pool_spec.rb
+++ b/spec/lib/gitlab/git/object_pool_spec.rb
@@ -7,8 +7,6 @@ describe Gitlab::Git::ObjectPool do
let(:pool_repository) { create(:pool_repository) }
let(:source_repository) { pool_repository.source_project.repository }
- let(:source_repository_path) { File.join(TestEnv.repos_path, source_repository.relative_path) }
- let(:source_repository_rugged) { Rugged::Repository.new(source_repository_path) }
subject { pool_repository.object_pool }
@@ -82,6 +80,8 @@ describe Gitlab::Git::ObjectPool do
end
describe '#fetch' do
+ let(:source_repository_path) { File.join(TestEnv.repos_path, source_repository.relative_path) }
+ let(:source_repository_rugged) { Rugged::Repository.new(source_repository_path) }
let(:commit_count) { source_repository.commit_count }
context "when the object's pool repository exists" do
@@ -98,7 +98,7 @@ describe Gitlab::Git::ObjectPool do
it "re-creates the object pool's repository" do
subject.fetch
- expect(subject.repository.exists?).to be(true)
+ expect(subject.repository.exists?).to be true
end
it 'does not raise an error' do
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 0f6aac9b6de..7644d83992f 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -2215,4 +2215,43 @@ describe Gitlab::Git::Repository, :seed_helper do
line.split("\t").last
end
end
+
+ describe '#disconnect_alternates' do
+ let(:project) { create(:project, :repository) }
+ let(:pool_repository) { create(:pool_repository) }
+ let(:repository) { project.repository }
+ let(:repository_path) { File.join(TestEnv.repos_path, repository.relative_path) }
+ let(:object_pool) { pool_repository.object_pool }
+ let(:object_pool_path) { File.join(TestEnv.repos_path, object_pool.repository.relative_path) }
+ let(:object_pool_rugged) { Rugged::Repository.new(object_pool_path) }
+
+ before do
+ object_pool.create
+ end
+
+ it 'does not raise an error when disconnecting a non-linked repository' do
+ expect { repository.disconnect_alternates }.not_to raise_error
+ end
+
+ it 'removes the alternates file' do
+ object_pool.link(repository)
+
+ alternates_file = File.join(repository_path, "objects", "info", "alternates")
+ expect(File.exist?(alternates_file)).to be_truthy
+
+ repository.disconnect_alternates
+
+ expect(File.exist?(alternates_file)).to be_falsey
+ end
+
+ it 'can still access objects in the object pool' do
+ object_pool.link(repository)
+ new_commit = new_commit_edit_old_file(object_pool_rugged)
+ expect(repository.commit(new_commit.oid).id).to eq(new_commit.oid)
+
+ repository.disconnect_alternates
+
+ expect(repository.commit(new_commit.oid).id).to eq(new_commit.oid)
+ end
+ end
end
diff --git a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
index 46ca2340389..09de7ca6afd 100644
--- a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
@@ -231,4 +231,34 @@ describe Gitlab::GitalyClient::RepositoryService do
client.raw_changes_between('deadbeef', 'deadpork')
end
end
+
+ describe '#disconnect_alternates' do
+ let(:project) { create(:project, :repository) }
+ let(:repository) { project.repository }
+ let(:repository_path) { File.join(TestEnv.repos_path, repository.relative_path) }
+ let(:pool_repository) { create(:pool_repository) }
+ let(:object_pool) { pool_repository.object_pool }
+ let(:object_pool_service) { Gitlab::GitalyClient::ObjectPoolService.new(object_pool) }
+
+ before do
+ object_pool_service.create(repository)
+ object_pool_service.link_repository(repository)
+ end
+
+ it 'deletes the alternates file' do
+ repository.disconnect_alternates
+
+ alternates_file = File.join(repository_path, "objects", "info", "alternates")
+
+ expect(File.exist?(alternates_file)).to be_falsey
+ end
+
+ context 'when called twice' do
+ it "doesn't raise an error" do
+ repository.disconnect_alternates
+
+ expect { repository.disconnect_alternates }.not_to raise_error
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 482e9c05da8..2242543daad 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -99,7 +99,7 @@ merge_requests:
- timelogs
- head_pipeline
- latest_merge_request_diff
-- merge_request_pipelines
+- pipelines_for_merge_request
- merge_request_assignees
- suggestions
- assignees
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 8c73f37bd32..9b489baf163 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -2817,7 +2817,7 @@ describe Ci::Build do
context 'when ref is merge request' do
let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
- let(:pipeline) { merge_request.merge_request_pipelines.first }
+ let(:pipeline) { merge_request.pipelines_for_merge_request.first }
let(:build) { create(:ci_build, ref: merge_request.source_branch, tag: false, pipeline: pipeline, project: project) }
context 'when ref is protected' do
@@ -2875,7 +2875,7 @@ describe Ci::Build do
context 'when ref is merge request' do
let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
- let(:pipeline) { merge_request.merge_request_pipelines.first }
+ let(:pipeline) { merge_request.pipelines_for_merge_request.first }
let(:build) { create(:ci_build, ref: merge_request.source_branch, tag: false, pipeline: pipeline, project: project) }
context 'when ref is protected' do
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index af455a72f50..a0319b3eb0a 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -466,7 +466,7 @@ describe Ci::Pipeline, :mailer do
target_branch: 'master')
end
- let(:pipeline) { merge_request.merge_request_pipelines.first }
+ let(:pipeline) { merge_request.pipelines_for_merge_request.first }
it 'does not return the pipeline' do
is_expected.to be_empty
diff --git a/spec/models/concerns/has_ref_spec.rb b/spec/models/concerns/has_ref_spec.rb
index 6805731fed3..66b25c77430 100644
--- a/spec/models/concerns/has_ref_spec.rb
+++ b/spec/models/concerns/has_ref_spec.rb
@@ -19,7 +19,7 @@ describe HasRef do
context 'when it was triggered by merge request' do
let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
- let(:pipeline) { merge_request.merge_request_pipelines.first }
+ let(:pipeline) { merge_request.pipelines_for_merge_request.first }
let(:build) { create(:ci_build, pipeline: pipeline) }
it 'returns false' do
@@ -68,7 +68,7 @@ describe HasRef do
context 'when it is triggered by a merge request' do
let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
- let(:pipeline) { merge_request.merge_request_pipelines.first }
+ let(:pipeline) { merge_request.pipelines_for_merge_request.first }
let(:build) { create(:ci_build, tag: false, pipeline: pipeline) }
it 'returns nil' do
diff --git a/spec/serializers/pipeline_entity_spec.rb b/spec/serializers/pipeline_entity_spec.rb
index dba7fd91747..47f767ae4ab 100644
--- a/spec/serializers/pipeline_entity_spec.rb
+++ b/spec/serializers/pipeline_entity_spec.rb
@@ -137,7 +137,7 @@ describe PipelineEntity do
context 'when pipeline is detached merge request pipeline' do
let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
let(:project) { merge_request.target_project }
- let(:pipeline) { merge_request.merge_request_pipelines.first }
+ let(:pipeline) { merge_request.pipelines_for_merge_request.first }
it 'makes detached flag true' do
expect(subject[:flags][:detached_merge_request_pipeline]).to be_truthy
@@ -185,7 +185,7 @@ describe PipelineEntity do
context 'when pipeline is merge request pipeline' do
let(:merge_request) { create(:merge_request, :with_merge_request_pipeline, merge_sha: 'abc') }
let(:project) { merge_request.target_project }
- let(:pipeline) { merge_request.merge_request_pipelines.first }
+ let(:pipeline) { merge_request.pipelines_for_merge_request.first }
it 'makes detached flag false' do
expect(subject[:flags][:detached_merge_request_pipeline]).to be_falsy
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index c795176a1e4..ed48f4b1e44 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -195,7 +195,7 @@ describe MergeRequests::CreateService do
expect(merge_request).to be_persisted
merge_request.reload
- expect(merge_request.merge_request_pipelines.count).to eq(1)
+ expect(merge_request.pipelines_for_merge_request.count).to eq(1)
expect(merge_request.actual_head_pipeline).to be_detached_merge_request_pipeline
end
@@ -247,7 +247,7 @@ describe MergeRequests::CreateService do
expect(merge_request).to be_persisted
merge_request.reload
- expect(merge_request.merge_request_pipelines.count).to eq(0)
+ expect(merge_request.pipelines_for_merge_request.count).to eq(0)
end
end
@@ -281,7 +281,7 @@ describe MergeRequests::CreateService do
expect(merge_request).to be_persisted
merge_request.reload
- expect(merge_request.merge_request_pipelines.count).to eq(0)
+ expect(merge_request.pipelines_for_merge_request.count).to eq(0)
end
end
end
diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb
index d20b2d81763..7258428589f 100644
--- a/spec/services/merge_requests/refresh_service_spec.rb
+++ b/spec/services/merge_requests/refresh_service_spec.rb
@@ -166,8 +166,8 @@ describe MergeRequests::RefreshService do
it 'create detached merge request pipeline with commits' do
expect { subject }
- .to change { @merge_request.merge_request_pipelines.count }.by(1)
- .and change { @another_merge_request.merge_request_pipelines.count }.by(0)
+ .to change { @merge_request.pipelines_for_merge_request.count }.by(1)
+ .and change { @another_merge_request.pipelines_for_merge_request.count }.by(0)
expect(@merge_request.has_commits?).to be_truthy
expect(@another_merge_request.has_commits?).to be_falsy
@@ -175,13 +175,13 @@ describe MergeRequests::RefreshService do
it 'does not create detached merge request pipeline for forked project' do
expect { subject }
- .not_to change { @fork_merge_request.merge_request_pipelines.count }
+ .not_to change { @fork_merge_request.pipelines_for_merge_request.count }
end
it 'create detached merge request pipeline for non-fork merge request' do
subject
- expect(@merge_request.merge_request_pipelines.first)
+ expect(@merge_request.pipelines_for_merge_request.first)
.to be_detached_merge_request_pipeline
end
@@ -190,7 +190,7 @@ describe MergeRequests::RefreshService do
it 'does not create detached merge request pipeline' do
expect { subject }
- .not_to change { @merge_request.merge_request_pipelines.count }
+ .not_to change { @merge_request.pipelines_for_merge_request.count }
end
end
@@ -199,9 +199,9 @@ describe MergeRequests::RefreshService do
it 'creates legacy detached merge request pipeline for fork merge request' do
expect { subject }
- .to change { @fork_merge_request.merge_request_pipelines.count }.by(1)
+ .to change { @fork_merge_request.pipelines_for_merge_request.count }.by(1)
- expect(@fork_merge_request.merge_request_pipelines.first)
+ expect(@fork_merge_request.pipelines_for_merge_request.first)
.to be_legacy_detached_merge_request_pipeline
end
end
@@ -214,7 +214,7 @@ describe MergeRequests::RefreshService do
it 'create legacy detached merge request pipeline for non-fork merge request' do
subject
- expect(@merge_request.merge_request_pipelines.first)
+ expect(@merge_request.pipelines_for_merge_request.first)
.to be_legacy_detached_merge_request_pipeline
end
end
@@ -245,11 +245,11 @@ describe MergeRequests::RefreshService do
it 'does not re-create a duplicate detached merge request pipeline' do
expect do
service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master')
- end.to change { @merge_request.merge_request_pipelines.count }.by(1)
+ end.to change { @merge_request.pipelines_for_merge_request.count }.by(1)
expect do
service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master')
- end.not_to change { @merge_request.merge_request_pipelines.count }
+ end.not_to change { @merge_request.pipelines_for_merge_request.count }
end
end
end
@@ -266,7 +266,7 @@ describe MergeRequests::RefreshService do
it 'does not create a detached merge request pipeline' do
expect { subject }
- .not_to change { @merge_request.merge_request_pipelines.count }
+ .not_to change { @merge_request.pipelines_for_merge_request.count }
end
end
end