Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-04-12 12:09:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-04-12 12:09:09 +0300
commitede2fbdc8734f095d371614d362b5ae373d6a243 (patch)
tree187152bbc2a4f24aae99d30a78ca9b06cc0468a8
parent4044a01bd7e32c814217b34c512c3dd02202ea29 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop_manual_todo.yml7
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/jobs/components/manual_variables_form.vue12
-rw-r--r--app/models/clusters/concerns/application_version.rb6
-rw-r--r--changelogs/unreleased/btn-confirm-push-rules.yml5
-rw-r--r--changelogs/unreleased/issue-325836-fix-empty-line-after-let-it-be-services-merge-request.yml5
-rw-r--r--changelogs/unreleased/pks-lfs-quarantine.yml5
-rw-r--r--changelogs/unreleased/pl-rubocop-style-hashtransformation-ee-directory.yml5
-rw-r--r--changelogs/unreleased/pl-rubocop-style-hashtransformation-spec-directory.yml5
-rw-r--r--config/feature_flags/development/lfs_integrity_inspect_quarantined_objects.yml8
-rw-r--r--doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md15
-rw-r--r--lib/gitlab/gitaly_client/blob_service.rb47
-rw-r--r--spec/frontend/jobs/components/manual_variables_form_spec.js119
-rw-r--r--spec/knapsack_env.rb46
-rw-r--r--spec/lib/atlassian/jira_connect/serializers/pull_request_entity_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/composite_spec.rb8
-rw-r--r--spec/lib/gitlab/conflict/file_spec.rb6
-rw-r--r--spec/lib/gitlab/gitaly_client/blob_service_spec.rb27
-rw-r--r--spec/lib/gitlab/import_export/project/tree_restorer_spec.rb2
-rw-r--r--spec/models/concerns/featurable_spec.rb2
-rw-r--r--spec/models/event_spec.rb8
-rw-r--r--spec/models/packages/dependency_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb2
-rw-r--r--spec/services/merge_requests/base_service_spec.rb1
-rw-r--r--spec/services/merge_requests/create_pipeline_service_spec.rb2
-rw-r--r--spec/services/merge_requests/export_csv_service_spec.rb2
-rw-r--r--spec/services/merge_requests/merge_orchestration_service_spec.rb1
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb1
-rw-r--r--spec/services/merge_requests/merge_to_ref_service_spec.rb2
-rw-r--r--spec/spec_helper.rb10
-rw-r--r--spec/support/helpers/graphql_helpers.rb4
-rw-r--r--spec/support/import_export/project_tree_expectations.rb4
-rw-r--r--spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb2
-rw-r--r--spec/support/shared_examples/models/cluster_application_version_shared_examples.rb11
39 files changed, 278 insertions, 120 deletions
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index 855b68bc1ab..0bda1b60623 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -442,7 +442,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
- ee/spec/controllers/registrations/groups_controller_spec.rb
- ee/spec/controllers/registrations/projects_controller_spec.rb
- ee/spec/controllers/subscriptions_controller_spec.rb
- - ee/spec/features/admin/admin_show_new_user_signups_cap_alert_spec.rb
- ee/spec/features/boards/group_boards/multiple_boards_spec.rb
- ee/spec/features/ci_shared_runner_warnings_spec.rb
- ee/spec/features/dashboards/todos_spec.rb
@@ -1036,12 +1035,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
- spec/services/markdown_content_rewriter_service_spec.rb
- spec/services/members/create_service_spec.rb
- spec/services/members/invite_service_spec.rb
- - spec/services/merge_requests/base_service_spec.rb
- - spec/services/merge_requests/create_pipeline_service_spec.rb
- - spec/services/merge_requests/export_csv_service_spec.rb
- - spec/services/merge_requests/merge_orchestration_service_spec.rb
- - spec/services/merge_requests/merge_service_spec.rb
- - spec/services/merge_requests/merge_to_ref_service_spec.rb
- spec/services/metrics/dashboard/annotations/create_service_spec.rb
- spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb
- spec/services/metrics/users_starred_dashboards/create_service_spec.rb
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 6481c6362c3..97af8533d21 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-2b9f2f35e178b8b56b5f657420aa72c6a77c62eb
+ca2b1ea56e839a9bc4878abb1e9ecac8002b4b07
diff --git a/Gemfile b/Gemfile
index 759d0cb3047..7cb30fd26fc 100644
--- a/Gemfile
+++ b/Gemfile
@@ -475,7 +475,7 @@ group :ed25519 do
end
# Gitaly GRPC protocol definitions
-gem 'gitaly', '~> 13.9.0.pre.rc1'
+gem 'gitaly', '~> 13.11.0.pre.rc1'
gem 'grpc', '~> 1.30.2'
diff --git a/Gemfile.lock b/Gemfile.lock
index b587b0f77c6..fe836915448 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -440,7 +440,7 @@ GEM
rails (>= 3.2.0)
git (1.7.0)
rchardet (~> 1.8)
- gitaly (13.9.0.pre.rc1)
+ gitaly (13.11.0.pre.rc1)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab (4.16.1)
@@ -1427,7 +1427,7 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
- gitaly (~> 13.9.0.pre.rc1)
+ gitaly (~> 13.11.0.pre.rc1)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 1.1.1)
diff --git a/app/assets/javascripts/jobs/components/manual_variables_form.vue b/app/assets/javascripts/jobs/components/manual_variables_form.vue
index 793f790931c..d45012d2023 100644
--- a/app/assets/javascripts/jobs/components/manual_variables_form.vue
+++ b/app/assets/javascripts/jobs/components/manual_variables_form.vue
@@ -117,7 +117,12 @@ export default {
<div class="table-section section-50" role="rowheader">{{ s__('CiVariables|Value') }}</div>
</div>
- <div v-for="variable in variables" :key="variable.id" class="gl-responsive-table-row">
+ <div
+ v-for="variable in variables"
+ :key="variable.id"
+ class="gl-responsive-table-row"
+ data-testid="ci-variable-row"
+ >
<div class="table-section section-50">
<div class="table-mobile-header" role="rowheader">{{ s__('Pipeline|Key') }}</div>
<div class="table-mobile-content gl-mr-3">
@@ -126,6 +131,7 @@ export default {
v-model="variable.key"
:placeholder="$options.i18n.keyPlaceholder"
class="ci-variable-body-item form-control"
+ data-testid="ci-variable-key"
/>
</div>
</div>
@@ -138,6 +144,7 @@ export default {
v-model="variable.secret_value"
:placeholder="$options.i18n.valuePlaceholder"
class="ci-variable-body-item form-control"
+ data-testid="ci-variable-value"
/>
</div>
</div>
@@ -149,6 +156,7 @@ export default {
category="tertiary"
icon="clear"
:aria-label="__('Delete variable')"
+ data-testid="delete-variable-btn"
@click="deleteVariable(variable.id)"
/>
</div>
@@ -181,7 +189,7 @@ export default {
</div>
</div>
<div class="d-flex gl-mt-3 justify-content-center">
- <p class="text-muted" v-html="helpText"></p>
+ <p class="text-muted" data-testid="form-help-text" v-html="helpText"></p>
</div>
<div class="d-flex justify-content-center">
<gl-button
diff --git a/app/models/clusters/concerns/application_version.rb b/app/models/clusters/concerns/application_version.rb
index 6c0b014662c..dab0bd23e2e 100644
--- a/app/models/clusters/concerns/application_version.rb
+++ b/app/models/clusters/concerns/application_version.rb
@@ -5,11 +5,17 @@ module Clusters
module ApplicationVersion
extend ActiveSupport::Concern
+ EXTERNAL_VERSION = 'EXTERNALLY_INSTALLED'
+
included do
state_machine :status do
before_transition any => [:installed, :updated] do |application|
application.version = application.class.const_get(:VERSION, false)
end
+
+ before_transition any => [:externally_installed] do |application|
+ application.version = EXTERNAL_VERSION
+ end
end
end
diff --git a/changelogs/unreleased/btn-confirm-push-rules.yml b/changelogs/unreleased/btn-confirm-push-rules.yml
new file mode 100644
index 00000000000..41ede801659
--- /dev/null
+++ b/changelogs/unreleased/btn-confirm-push-rules.yml
@@ -0,0 +1,5 @@
+---
+title: Move to btn-confirm from btn-success in push_rules directory
+merge_request: 58033
+author: Yogi (@yo)
+type: changed
diff --git a/changelogs/unreleased/issue-325836-fix-empty-line-after-let-it-be-services-merge-request.yml b/changelogs/unreleased/issue-325836-fix-empty-line-after-let-it-be-services-merge-request.yml
new file mode 100644
index 00000000000..dd7b6e30576
--- /dev/null
+++ b/changelogs/unreleased/issue-325836-fix-empty-line-after-let-it-be-services-merge-request.yml
@@ -0,0 +1,5 @@
+---
+title: Fix EmptyLineAfterFinalLetItBe offenses in spec/services/merge_requests
+merge_request: 58429
+author: Huzaifa Iftikhar @huzaifaiftikhar
+type: fixed
diff --git a/changelogs/unreleased/pks-lfs-quarantine.yml b/changelogs/unreleased/pks-lfs-quarantine.yml
new file mode 100644
index 00000000000..19821eda678
--- /dev/null
+++ b/changelogs/unreleased/pks-lfs-quarantine.yml
@@ -0,0 +1,5 @@
+---
+title: Use object quarantine directory to enumerate new LFS pointers
+merge_request: 58634
+author:
+type: performance
diff --git a/changelogs/unreleased/pl-rubocop-style-hashtransformation-ee-directory.yml b/changelogs/unreleased/pl-rubocop-style-hashtransformation-ee-directory.yml
new file mode 100644
index 00000000000..bb10b5d9703
--- /dev/null
+++ b/changelogs/unreleased/pl-rubocop-style-hashtransformation-ee-directory.yml
@@ -0,0 +1,5 @@
+---
+title: Fix cop offenses for Style/HashTransformation in ee directory
+merge_request: 56581
+author: Karthik Sivadas @karthik.sivadas
+type: other
diff --git a/changelogs/unreleased/pl-rubocop-style-hashtransformation-spec-directory.yml b/changelogs/unreleased/pl-rubocop-style-hashtransformation-spec-directory.yml
new file mode 100644
index 00000000000..fa96b475216
--- /dev/null
+++ b/changelogs/unreleased/pl-rubocop-style-hashtransformation-spec-directory.yml
@@ -0,0 +1,5 @@
+---
+title: Fix cop offenses for Style/HashTransformation in spec directory
+merge_request: 56586
+author: Karthik Sivadas @karthik.sivadas
+type: other
diff --git a/config/feature_flags/development/lfs_integrity_inspect_quarantined_objects.yml b/config/feature_flags/development/lfs_integrity_inspect_quarantined_objects.yml
new file mode 100644
index 00000000000..f8b589c0a4f
--- /dev/null
+++ b/config/feature_flags/development/lfs_integrity_inspect_quarantined_objects.yml
@@ -0,0 +1,8 @@
+---
+name: lfs_integrity_inspect_quarantined_objects
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58634
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327440
+milestone: '13.11'
+type: development
+group: group::gitaly
+default_enabled: false
diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
index 2506d4cbf0e..6b1cf2d1194 100644
--- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
+++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
@@ -762,6 +762,21 @@ end
Gitlab::CurrentSettings.current_application_settings.runners_registration_token
```
+### Run pipeline schedules manually
+
+You can run pipeline schedules manually through the Rails console to reveal any errors that are usually not visible.
+
+```ruby
+# schedule_id can be obtained from Edit Pipeline Schedule page
+schedule = Ci::PipelineSchedule.find_by(id: <schedule_id>)
+
+# Select the user that you want to run the schedule for
+user = User.find_by_username('<username>')
+
+# Run the schedule
+ps = Ci::CreatePipelineService.new(schedule.project, user, ref: schedule.ref).execute!(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: schedule)
+```
+
## License
### See current license information
diff --git a/lib/gitlab/gitaly_client/blob_service.rb b/lib/gitlab/gitaly_client/blob_service.rb
index c66b3335d89..669fb1c0a31 100644
--- a/lib/gitlab/gitaly_client/blob_service.rb
+++ b/lib/gitlab/gitaly_client/blob_service.rb
@@ -78,17 +78,7 @@ module Gitlab
end
def get_new_lfs_pointers(revision, limit, not_in, dynamic_timeout = nil)
- request = Gitaly::GetNewLFSPointersRequest.new(
- repository: @gitaly_repo,
- revision: encode_binary(revision),
- limit: limit || 0
- )
-
- if not_in.nil? || not_in == :all
- request.not_in_all = true
- else
- request.not_in_refs += not_in
- end
+ request, rpc = create_new_lfs_pointers_request(revision, limit, not_in)
timeout =
if dynamic_timeout
@@ -100,7 +90,7 @@ module Gitlab
response = GitalyClient.call(
@gitaly_repo.storage_name,
:blob_service,
- :get_new_lfs_pointers,
+ rpc,
request,
timeout: timeout
)
@@ -118,6 +108,39 @@ module Gitlab
private
+ def create_new_lfs_pointers_request(revision, limit, not_in)
+ # If the check happens for a change which is using a quarantine
+ # environment for incoming objects, then we can avoid doing the
+ # necessary graph walk to detect only new LFS pointers and instead scan
+ # through all quarantined objects.
+ git_env = ::Gitlab::Git::HookEnv.all(@gitaly_repo.gl_repository)
+ if Feature.enabled?(:lfs_integrity_inspect_quarantined_objects, @project, default_enabled: :yaml) && git_env['GIT_OBJECT_DIRECTORY_RELATIVE'].present?
+ repository = @gitaly_repo.dup
+ repository.git_alternate_object_directories = Google::Protobuf::RepeatedField.new(:string)
+
+ request = Gitaly::ListAllLFSPointersRequest.new(
+ repository: repository,
+ limit: limit || 0
+ )
+
+ [request, :list_all_lfs_pointers]
+ else
+ request = Gitaly::GetNewLFSPointersRequest.new(
+ repository: @gitaly_repo,
+ revision: encode_binary(revision),
+ limit: limit || 0
+ )
+
+ if not_in.nil? || not_in == :all
+ request.not_in_all = true
+ else
+ request.not_in_refs += not_in
+ end
+
+ [request, :get_new_lfs_pointers]
+ end
+ end
+
def consume_blob_response(response)
data = []
blob = nil
diff --git a/spec/frontend/jobs/components/manual_variables_form_spec.js b/spec/frontend/jobs/components/manual_variables_form_spec.js
index aecbf1f5330..376a822dde5 100644
--- a/spec/frontend/jobs/components/manual_variables_form_spec.js
+++ b/spec/frontend/jobs/components/manual_variables_form_spec.js
@@ -1,7 +1,7 @@
-import { GlButton } from '@gitlab/ui';
import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import Form from '~/jobs/components/manual_variables_form.vue';
const localVue = createLocalVue();
@@ -21,49 +21,48 @@ describe('Manual Variables Form', () => {
variablesSettingsUrl: '/settings',
};
- const createComponent = (props = {}, mountFn = shallowMount) => {
+ const createComponent = ({ props = {}, mountFn = shallowMount } = {}) => {
store = new Vuex.Store({
actions: {
triggerManualJob: jest.fn(),
},
});
- wrapper = mountFn(localVue.extend(Form), {
- propsData: props,
- localVue,
- store,
- });
+ wrapper = extendedWrapper(
+ mountFn(localVue.extend(Form), {
+ propsData: { ...requiredProps, ...props },
+ localVue,
+ store,
+ }),
+ );
};
- const findTriggerBtn = () => wrapper.find('[data-testid="trigger-manual-job-btn"]');
+ const findInputKey = () => wrapper.findComponent({ ref: 'inputKey' });
+ const findInputValue = () => wrapper.findComponent({ ref: 'inputSecretValue' });
- afterEach((done) => {
- // The component has a `nextTick` callback after some events so we need
- // to wait for those to finish before destroying.
- setImmediate(() => {
- wrapper.destroy();
- wrapper = null;
+ const findTriggerBtn = () => wrapper.findByTestId('trigger-manual-job-btn');
+ const findHelpText = () => wrapper.findByTestId('form-help-text');
+ const findDeleteVarBtn = () => wrapper.findByTestId('delete-variable-btn');
+ const findCiVariableKey = () => wrapper.findByTestId('ci-variable-key');
+ const findCiVariableValue = () => wrapper.findByTestId('ci-variable-value');
+ const findAllVariables = () => wrapper.findAllByTestId('ci-variable-row');
- done();
- });
+ afterEach(() => {
+ wrapper.destroy();
});
describe('shallowMount', () => {
beforeEach(() => {
- createComponent(requiredProps);
+ createComponent();
});
it('renders empty form with correct placeholders', () => {
- expect(wrapper.find({ ref: 'inputKey' }).attributes('placeholder')).toBe(
- 'Input variable key',
- );
- expect(wrapper.find({ ref: 'inputSecretValue' }).attributes('placeholder')).toBe(
- 'Input variable value',
- );
+ expect(findInputKey().attributes('placeholder')).toBe('Input variable key');
+ expect(findInputValue().attributes('placeholder')).toBe('Input variable value');
});
it('renders help text with provided link', () => {
- expect(wrapper.find('p').text()).toBe(
+ expect(findHelpText().text()).toBe(
'Specify variable values to be used in this run. The values specified in CI/CD settings will be used as default',
);
@@ -71,57 +70,47 @@ describe('Manual Variables Form', () => {
});
describe('when adding a new variable', () => {
- it('creates a new variable when user types a new key and resets the form', (done) => {
- wrapper.vm
- .$nextTick()
- .then(() => wrapper.find({ ref: 'inputKey' }).setValue('new key'))
- .then(() => {
- expect(wrapper.vm.variables.length).toBe(1);
- expect(wrapper.vm.variables[0].key).toBe('new key');
- expect(wrapper.find({ ref: 'inputKey' }).attributes('value')).toBe(undefined);
- })
- .then(done)
- .catch(done.fail);
- });
+ it('creates a new variable when user types a new key and resets the form', async () => {
+ await findInputKey().setValue('new key');
- it('creates a new variable when user types a new value and resets the form', (done) => {
- wrapper.vm
- .$nextTick()
- .then(() => wrapper.find({ ref: 'inputSecretValue' }).setValue('new value'))
- .then(() => {
- expect(wrapper.vm.variables.length).toBe(1);
- expect(wrapper.vm.variables[0].secret_value).toBe('new value');
- expect(wrapper.find({ ref: 'inputSecretValue' }).attributes('value')).toBe(undefined);
- })
- .then(done)
- .catch(done.fail);
+ expect(findAllVariables()).toHaveLength(1);
+ expect(findCiVariableKey().element.value).toBe('new key');
+ expect(findInputKey().attributes('value')).toBe(undefined);
});
- });
- describe('when deleting a variable', () => {
- beforeEach((done) => {
- wrapper.vm.variables = [
- {
- key: 'new key',
- secret_value: 'value',
- id: '1',
- },
- ];
-
- wrapper.vm.$nextTick(done);
- });
-
- it('removes the variable row', () => {
- wrapper.find(GlButton).vm.$emit('click');
+ it('creates a new variable when user types a new value and resets the form', async () => {
+ await findInputValue().setValue('new value');
- expect(wrapper.vm.variables.length).toBe(0);
+ expect(findAllVariables()).toHaveLength(1);
+ expect(findCiVariableValue().element.value).toBe('new value');
+ expect(findInputValue().attributes('value')).toBe(undefined);
});
});
});
describe('mount', () => {
beforeEach(() => {
- createComponent(requiredProps, mount);
+ createComponent({ mountFn: mount });
+ });
+
+ describe('when deleting a variable', () => {
+ it('removes the variable row', async () => {
+ await wrapper.setData({
+ variables: [
+ {
+ key: 'new key',
+ secret_value: 'value',
+ id: '1',
+ },
+ ],
+ });
+
+ findDeleteVarBtn().trigger('click');
+
+ await wrapper.vm.$nextTick();
+
+ expect(findAllVariables()).toHaveLength(0);
+ });
});
it('trigger button is disabled after trigger action', async () => {
diff --git a/spec/knapsack_env.rb b/spec/knapsack_env.rb
new file mode 100644
index 00000000000..7dc1a43d644
--- /dev/null
+++ b/spec/knapsack_env.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'knapsack'
+
+module KnapsackEnv
+ class RSpecContextAdapter < Knapsack::Adapters::RSpecAdapter
+ def bind_time_tracker
+ ::RSpec.configure do |config|
+ # Original version starts timer in `config.prepend_before(:each) do`
+ # https://github.com/KnapsackPro/knapsack/blob/v1.17.0/lib/knapsack/adapters/rspec_adapter.rb#L9
+ config.prepend_before(:context) do
+ Knapsack.tracker.start_timer
+ end
+
+ # Original version is `config.prepend_before(:each) do`
+ # https://github.com/KnapsackPro/knapsack/blob/v1.17.0/lib/knapsack/adapters/rspec_adapter.rb#L9
+ config.prepend_before(:each) do # rubocop:disable RSpec/HookArgument
+ current_example_group =
+ if ::RSpec.respond_to?(:current_example)
+ ::RSpec.current_example.metadata[:example_group]
+ else
+ example.metadata
+ end
+
+ Knapsack.tracker.test_path = Knapsack::Adapters::RSpecAdapter.test_path(current_example_group)
+ end
+
+ # Original version stops timer in `config.append_after(:each) do`
+ # https://github.com/KnapsackPro/knapsack/blob/v1.17.0/lib/knapsack/adapters/rspec_adapter.rb#L20
+ config.append_after(:context) do
+ Knapsack.tracker.stop_timer
+ end
+
+ config.after(:suite) do
+ Knapsack.logger.info(Knapsack::Presenter.global_time)
+ end
+ end
+ end
+ end
+
+ def self.configure!
+ return unless ENV['CI'] && ENV['KNAPSACK_GENERATE_REPORT'] && !ENV['NO_KNAPSACK']
+
+ RSpecContextAdapter.bind
+ end
+end
diff --git a/spec/lib/atlassian/jira_connect/serializers/pull_request_entity_spec.rb b/spec/lib/atlassian/jira_connect/serializers/pull_request_entity_spec.rb
index 872ba1ab43d..6399fc9053b 100644
--- a/spec/lib/atlassian/jira_connect/serializers/pull_request_entity_spec.rb
+++ b/spec/lib/atlassian/jira_connect/serializers/pull_request_entity_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Atlassian::JiraConnect::Serializers::PullRequestEntity do
end
context 'with user_notes_count option' do
- let(:user_notes_count) { merge_requests.map { |merge_request| [merge_request.id, 1] }.to_h }
+ let(:user_notes_count) { merge_requests.to_h { |merge_request| [merge_request.id, 1] } }
subject { described_class.represent(merge_requests, user_notes_count: user_notes_count).as_json }
diff --git a/spec/lib/gitlab/ci/status/composite_spec.rb b/spec/lib/gitlab/ci/status/composite_spec.rb
index 543cfe874ca..2b9523bd83d 100644
--- a/spec/lib/gitlab/ci/status/composite_spec.rb
+++ b/spec/lib/gitlab/ci/status/composite_spec.rb
@@ -6,13 +6,13 @@ RSpec.describe Gitlab::Ci::Status::Composite do
let_it_be(:pipeline) { create(:ci_pipeline) }
before_all do
- @statuses = Ci::HasStatus::STATUSES_ENUM.map do |status, idx|
+ @statuses = Ci::HasStatus::STATUSES_ENUM.to_h do |status, idx|
[status, create(:ci_build, pipeline: pipeline, status: status, importing: true)]
- end.to_h
+ end
- @statuses_with_allow_failure = Ci::HasStatus::STATUSES_ENUM.map do |status, idx|
+ @statuses_with_allow_failure = Ci::HasStatus::STATUSES_ENUM.to_h do |status, idx|
[status, create(:ci_build, pipeline: pipeline, status: status, allow_failure: true, importing: true)]
- end.to_h
+ end
end
describe '#status' do
diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb
index bb9bee763d8..46e5334cd81 100644
--- a/spec/lib/gitlab/conflict/file_spec.rb
+++ b/spec/lib/gitlab/conflict/file_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe Gitlab::Conflict::File do
let(:section_keys) { conflict_file.sections.map { |section| section[:id] }.compact }
context 'when resolving everything to the same side' do
- let(:resolution_hash) { section_keys.map { |key| [key, 'head'] }.to_h }
+ let(:resolution_hash) { section_keys.to_h { |key| [key, 'head'] } }
let(:resolved_lines) { conflict_file.resolve_lines(resolution_hash) }
let(:expected_lines) { conflict_file.lines.reject { |line| line.type == 'old' } }
@@ -54,8 +54,8 @@ RSpec.describe Gitlab::Conflict::File do
end
it 'raises ResolutionError when passed a hash without resolutions for all sections' do
- empty_hash = section_keys.map { |key| [key, nil] }.to_h
- invalid_hash = section_keys.map { |key| [key, 'invalid'] }.to_h
+ empty_hash = section_keys.to_h { |key| [key, nil] }
+ invalid_hash = section_keys.to_h { |key| [key, 'invalid'] }
expect { conflict_file.resolve_lines({}) }
.to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError)
diff --git a/spec/lib/gitlab/gitaly_client/blob_service_spec.rb b/spec/lib/gitlab/gitaly_client/blob_service_spec.rb
index 037734f1b13..e35f541f5c8 100644
--- a/spec/lib/gitlab/gitaly_client/blob_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/blob_service_spec.rb
@@ -43,6 +43,33 @@ RSpec.describe Gitlab::GitalyClient::BlobService do
subject
end
end
+
+ context 'with hook environment' do
+ let(:git_env) do
+ {
+ 'GIT_OBJECT_DIRECTORY_RELATIVE' => '.git/objects',
+ 'GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE' => ['/dir/one', '/dir/two']
+ }
+ end
+
+ let(:expected_params) do
+ expected_repository = repository.gitaly_repository
+ expected_repository.git_alternate_object_directories = Google::Protobuf::RepeatedField.new(:string)
+
+ { limit: limit, repository: expected_repository }
+ end
+
+ it 'sends a list_all_lfs_pointers message' do
+ allow(Gitlab::Git::HookEnv).to receive(:all).with(repository.gl_repository).and_return(git_env)
+
+ expect_any_instance_of(Gitaly::BlobService::Stub)
+ .to receive(:list_all_lfs_pointers)
+ .with(gitaly_request_with_params(expected_params), kind_of(Hash))
+ .and_return([])
+
+ subject
+ end
+ end
end
describe '#get_all_lfs_pointers' do
diff --git a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
index e2bf87bf29f..bc5e6ea7bb3 100644
--- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
@@ -684,7 +684,7 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do
it 'overrides project feature access levels' do
access_level_keys = ProjectFeature.available_features.map { |feature| ProjectFeature.access_level_attribute(feature) }
- disabled_access_levels = Hash[access_level_keys.collect { |item| [item, 'disabled'] }]
+ disabled_access_levels = access_level_keys.to_h { |item| [item, 'disabled'] }
project.create_import_data(data: { override_params: disabled_access_levels })
diff --git a/spec/models/concerns/featurable_spec.rb b/spec/models/concerns/featurable_spec.rb
index bcff5ce383e..295f3523dd5 100644
--- a/spec/models/concerns/featurable_spec.rb
+++ b/spec/models/concerns/featurable_spec.rb
@@ -164,7 +164,7 @@ RSpec.describe Featurable do
end
def update_all_project_features(project, features, value)
- project_feature_attributes = features.map { |f| ["#{f}_access_level", value] }.to_h
+ project_feature_attributes = features.to_h { |f| ["#{f}_access_level", value] }
project.project_feature.update!(project_feature_attributes)
end
end
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index 47148c4febc..949e8ec0a72 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -299,11 +299,11 @@ RSpec.describe Event do
end
def visible_to_none_except(*roles)
- visible_to_none.merge(roles.map { |role| [role, true] }.to_h)
+ visible_to_none.merge(roles.to_h { |role| [role, true] })
end
def visible_to_all_except(*roles)
- visible_to_all.merge(roles.map { |role| [role, false] }.to_h)
+ visible_to_all.merge(roles.to_h { |role| [role, false] })
end
shared_examples 'visibility examples' do
@@ -723,7 +723,7 @@ RSpec.describe Event do
note_on_design: true,
note_on_commit: true
}
- valid_target_factories.map do |kind, needs_project|
+ valid_target_factories.to_h do |kind, needs_project|
extra_data = if kind == :merge_request
{ source_project: project }
elsif needs_project
@@ -735,7 +735,7 @@ RSpec.describe Event do
target = kind == :project ? nil : build(kind, **extra_data)
[kind, build(:event, :created, author: project.owner, project: project, target: target)]
- end.to_h
+ end
end
it 'passes a sanity check', :aggregate_failures do
diff --git a/spec/models/packages/dependency_spec.rb b/spec/models/packages/dependency_spec.rb
index fa6b0fd1848..4437cad46cd 100644
--- a/spec/models/packages/dependency_spec.rb
+++ b/spec/models/packages/dependency_spec.rb
@@ -54,7 +54,7 @@ RSpec.describe Packages::Dependency, type: :model do
context 'with too big parameter' do
let(:size) { (Packages::Dependency::MAX_CHUNKED_QUERIES_COUNT * chunk_size) + 1 }
- let(:names_and_version_patterns) { Hash[(1..size).map { |v| [v, v] }] }
+ let(:names_and_version_patterns) { (1..size).to_h { |v| [v, v] } }
it { expect { subject }.to raise_error(ArgumentError, 'Too many names_and_version_patterns') }
end
diff --git a/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
index 9ab94f1d749..a59402208ec 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'getting Alert Management Alert Assignees' do
end
let(:alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
- let(:assignees) { alerts.map { |alert| [alert['iid'], alert['assignees']['nodes']] }.to_h }
+ let(:assignees) { alerts.to_h { |alert| [alert['iid'], alert['assignees']['nodes']] } }
let(:first_assignees) { assignees[first_alert.iid.to_s] }
let(:second_assignees) { assignees[second_alert.iid.to_s] }
diff --git a/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
index 5d46f370756..72d185144ef 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe 'getting Alert Management Alert Notes' do
end
let(:alerts_result) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
- let(:notes_result) { alerts_result.map { |alert| [alert['iid'], alert['notes']['nodes']] }.to_h }
+ let(:notes_result) { alerts_result.to_h { |alert| [alert['iid'], alert['notes']['nodes']] } }
let(:first_notes_result) { notes_result[first_alert.iid.to_s] }
let(:second_notes_result) { notes_result[second_alert.iid.to_s] }
diff --git a/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
index 3a9077061ad..ca58079fdfe 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'getting Alert Management Alert Assignees' do
end
let(:gql_alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
- let(:gql_todos) { gql_alerts.map { |gql_alert| [gql_alert['iid'], gql_alert['todos']['nodes']] }.to_h }
+ let(:gql_todos) { gql_alerts.to_h { |gql_alert| [gql_alert['iid'], gql_alert['todos']['nodes']] } }
let(:gql_alert_todo) { gql_todos[alert.iid.to_s].first }
let(:gql_other_alert_todo) { gql_todos[other_alert.iid.to_s].first }
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 0a63f1d7fa0..00b732b4a36 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.shared_examples 'languages and percentages JSON response' do
- let(:expected_languages) { project.repository.languages.map { |language| language.values_at(:label, :value)}.to_h }
+ let(:expected_languages) { project.repository.languages.to_h { |language| language.values_at(:label, :value) } }
before do
allow(project.repository).to receive(:languages).and_return(
diff --git a/spec/services/merge_requests/base_service_spec.rb b/spec/services/merge_requests/base_service_spec.rb
index 83431105545..d8ba2bc43fb 100644
--- a/spec/services/merge_requests/base_service_spec.rb
+++ b/spec/services/merge_requests/base_service_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe MergeRequests::BaseService do
include ProjectForksHelper
let_it_be(:project) { create(:project, :repository) }
+
let(:title) { 'Awesome merge_request' }
let(:params) do
{
diff --git a/spec/services/merge_requests/create_pipeline_service_spec.rb b/spec/services/merge_requests/create_pipeline_service_spec.rb
index 4dd70627977..3e2e940dc24 100644
--- a/spec/services/merge_requests/create_pipeline_service_spec.rb
+++ b/spec/services/merge_requests/create_pipeline_service_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe MergeRequests::CreatePipelineService do
let_it_be(:project, reload: true) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
+
let(:service) { described_class.new(project, actor, params) }
let(:actor) { user }
let(:params) { {} }
@@ -50,6 +51,7 @@ RSpec.describe MergeRequests::CreatePipelineService do
context 'with fork merge request' do
let_it_be(:forked_project) { fork_project(project, nil, repository: true, target_project: create(:project, :private, :repository)) }
+
let(:source_project) { forked_project }
context 'when actor has permission to create pipelines in target project' do
diff --git a/spec/services/merge_requests/export_csv_service_spec.rb b/spec/services/merge_requests/export_csv_service_spec.rb
index 4ce032c396e..97217e979a5 100644
--- a/spec/services/merge_requests/export_csv_service_spec.rb
+++ b/spec/services/merge_requests/export_csv_service_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe MergeRequests::ExportCsvService do
let_it_be(:merge_request) { create(:merge_request) }
+
let(:csv) { CSV.parse(subject.csv_data, headers: true).first }
subject { described_class.new(MergeRequest.where(id: merge_request.id), merge_request.project) }
@@ -46,6 +47,7 @@ RSpec.describe MergeRequests::ExportCsvService do
describe 'approvers' do
context 'when approved' do
let_it_be(:merge_request) { create(:merge_request) }
+
let(:approvers) { create_list(:user, 2) }
before do
diff --git a/spec/services/merge_requests/merge_orchestration_service_spec.rb b/spec/services/merge_requests/merge_orchestration_service_spec.rb
index 67dbb5a1a01..da37cc97857 100644
--- a/spec/services/merge_requests/merge_orchestration_service_spec.rb
+++ b/spec/services/merge_requests/merge_orchestration_service_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe MergeRequests::MergeOrchestrationService do
let_it_be(:maintainer) { create(:user) }
+
let(:merge_params) { { sha: merge_request.diff_head_sha } }
let(:user) { maintainer }
let(:service) { described_class.new(project, user, merge_params) }
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index 561fb524897..c73cbad9d2f 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe MergeRequests::MergeService do
let_it_be(:user) { create(:user) }
let_it_be(:user2) { create(:user) }
+
let(:merge_request) { create(:merge_request, :simple, author: user2, assignees: [user2]) }
let(:project) { merge_request.project }
diff --git a/spec/services/merge_requests/merge_to_ref_service_spec.rb b/spec/services/merge_requests/merge_to_ref_service_spec.rb
index 4806da7cbe7..938165a807c 100644
--- a/spec/services/merge_requests/merge_to_ref_service_spec.rb
+++ b/spec/services/merge_requests/merge_to_ref_service_spec.rb
@@ -68,6 +68,7 @@ RSpec.describe MergeRequests::MergeToRefService do
end
let_it_be(:user) { create(:user) }
+
let(:merge_request) { create(:merge_request, :simple) }
let(:project) { merge_request.project }
@@ -226,6 +227,7 @@ RSpec.describe MergeRequests::MergeToRefService do
describe 'cascading merge refs' do
let_it_be(:project) { create(:project, :repository) }
+
let(:params) { { commit_message: 'Cascading merge', first_parent_ref: first_parent_ref, target_ref: target_ref, sha: merge_request.diff_head_sha } }
context 'when first merge happens' do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 1550e2f9b3b..487c7bb10e2 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -15,6 +15,9 @@ Warning[:deprecated] = true unless ENV.key?('SILENCE_DEPRECATIONS')
require './spec/deprecation_toolkit_env'
DeprecationToolkitEnv.configure!
+require './spec/knapsack_env'
+KnapsackEnv.configure!
+
require './spec/simplecov_env'
SimpleCovEnv.start!
@@ -47,11 +50,6 @@ if rspec_profiling_is_configured && (!ENV.key?('CI') || branch_can_be_profiled)
require 'rspec_profiling/rspec'
end
-if ENV['CI'] && ENV['KNAPSACK_GENERATE_REPORT'] && !ENV['NO_KNAPSACK']
- require 'knapsack'
- Knapsack::Adapters::RSpecAdapter.bind
-end
-
# require rainbow gem String monkeypatch, so we can test SystemChecks
require 'rainbow/ext/string'
Rainbow.enabled = false
@@ -81,7 +79,7 @@ RSpec.configure do |config|
config.run_all_when_everything_filtered = true
config.use_transactional_fixtures = true
- config.use_instantiated_fixtures = false
+ config.use_instantiated_fixtures = false
config.fixture_path = Rails.root
config.verbose_retry = true
diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb
index a7f9e16c489..fc21efa6db4 100644
--- a/spec/support/helpers/graphql_helpers.rb
+++ b/spec/support/helpers/graphql_helpers.rb
@@ -277,11 +277,11 @@ module GraphqlHelpers
# prepare_input_for_mutation({ 'my_key' => 1 })
# => { 'myKey' => 1}
def prepare_input_for_mutation(input)
- input.map do |name, value|
+ input.to_h do |name, value|
value = prepare_input_for_mutation(value) if value.is_a?(Hash)
[GraphqlHelpers.fieldnamerize(name), value]
- end.to_h
+ end
end
def input_variable_name_for_mutation(mutation_name)
diff --git a/spec/support/import_export/project_tree_expectations.rb b/spec/support/import_export/project_tree_expectations.rb
index 966c977e8e9..2423a58a3e6 100644
--- a/spec/support/import_export/project_tree_expectations.rb
+++ b/spec/support/import_export/project_tree_expectations.rb
@@ -97,13 +97,13 @@ module ImportExport
def normalize_elements(elem)
case elem
when Hash
- elem.map do |key, value|
+ elem.to_h do |key, value|
if ignore_key?(key, value)
[key, :ignored]
else
[key, normalize_elements(value)]
end
- end.to_h
+ end
when Array
elem.map { |a| normalize_elements(a) }
else
diff --git a/spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb b/spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb
index bcc98cf6416..80f011f622b 100644
--- a/spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb
+++ b/spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb
@@ -23,7 +23,7 @@ RSpec.shared_context 'container repository delete tags service shared context' d
end
def stub_delete_reference_requests(tags)
- tags = Hash[Array.wrap(tags).map { |tag| [tag, 200] }] unless tags.is_a?(Hash)
+ tags = Array.wrap(tags).to_h { |tag| [tag, 200] } unless tags.is_a?(Hash)
tags.each do |tag, status|
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/#{tag}")
diff --git a/spec/support/shared_examples/models/cluster_application_version_shared_examples.rb b/spec/support/shared_examples/models/cluster_application_version_shared_examples.rb
index ed2e4fee2de..3acc43eb0da 100644
--- a/spec/support/shared_examples/models/cluster_application_version_shared_examples.rb
+++ b/spec/support/shared_examples/models/cluster_application_version_shared_examples.rb
@@ -47,4 +47,15 @@ RSpec.shared_examples 'cluster application version specs' do |application_name|
end
end
end
+
+ describe '#make_externally_installed' do
+ subject { build(application_name) }
+
+ it 'sets to a special version' do
+ subject.make_externally_installed!
+
+ expect(subject).to be_persisted
+ expect(subject.version).to eq('EXTERNALLY_INSTALLED')
+ end
+ end
end