mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-13 13:31:19 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
@ -0,0 +1,67 @@
|
||||
<script>
|
||||
import { GlAlert } from '@gitlab/ui';
|
||||
import StorageUsageStatistics from 'ee_else_ce/usage_quotas/storage/components/storage_usage_statistics.vue';
|
||||
|
||||
export default {
|
||||
name: 'NamespaceStorageApp',
|
||||
components: {
|
||||
GlAlert,
|
||||
StorageUsageStatistics,
|
||||
},
|
||||
props: {
|
||||
namespaceLoadingError: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
projectsLoadingError: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
isNamespaceStorageStatisticsLoading: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
namespace: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
usedStorage() {
|
||||
return (
|
||||
// This is the coefficient adjusted forked repo size, only used in EE
|
||||
this.namespace.rootStorageStatistics?.costFactoredStorageSize ??
|
||||
// This is the actual storage size value, used in CE or when the above is disabled
|
||||
this.namespace.rootStorageStatistics?.storageSize
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<gl-alert
|
||||
v-if="namespaceLoadingError || projectsLoadingError"
|
||||
variant="danger"
|
||||
:dismissible="false"
|
||||
class="gl-mt-4"
|
||||
>
|
||||
{{
|
||||
s__(
|
||||
'UsageQuota|An error occured while loading the storage usage details. Please refresh the page to try again.',
|
||||
)
|
||||
}}
|
||||
</gl-alert>
|
||||
<storage-usage-statistics
|
||||
:additional-purchased-storage-size="namespace.additionalPurchasedStorageSize"
|
||||
:used-storage="usedStorage"
|
||||
:loading="isNamespaceStorageStatisticsLoading"
|
||||
/>
|
||||
|
||||
<slot name="ee-storage-app"></slot>
|
||||
</div>
|
||||
</template>
|
@ -0,0 +1,51 @@
|
||||
<script>
|
||||
import { GlCard, GlSkeletonLoader } from '@gitlab/ui';
|
||||
import NumberToHumanSize from '~/vue_shared/components/number_to_human_size/number_to_human_size.vue';
|
||||
|
||||
export default {
|
||||
name: 'StorageUsageOverviewCard',
|
||||
components: {
|
||||
GlCard,
|
||||
GlSkeletonLoader,
|
||||
NumberToHumanSize,
|
||||
},
|
||||
props: {
|
||||
usedStorage: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<gl-card>
|
||||
<gl-skeleton-loader v-if="loading" :height="64">
|
||||
<rect width="140" height="30" x="5" y="0" rx="4" />
|
||||
<rect width="240" height="10" x="5" y="40" rx="4" />
|
||||
<rect width="340" height="10" x="5" y="54" rx="4" />
|
||||
</gl-skeleton-loader>
|
||||
|
||||
<div v-else>
|
||||
<div class="gl-font-weight-bold" data-testid="namespace-storage-card-title">
|
||||
{{ s__('UsageQuota|Namespace storage used') }}
|
||||
</div>
|
||||
<div class="gl-font-size-h-display gl-font-weight-bold gl-line-height-ratio-1000 gl-my-3">
|
||||
<number-to-human-size label-class="gl-font-lg" :value="Number(usedStorage)" plain-zero />
|
||||
</div>
|
||||
<hr class="gl-my-4" />
|
||||
<p>
|
||||
{{
|
||||
s__(
|
||||
'UsageQuota|Namespace total storage represents the sum of storage consumed by all projects, Container Registry, and Dependency Proxy.',
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</gl-card>
|
||||
</template>
|
@ -0,0 +1,33 @@
|
||||
<script>
|
||||
import StorageUsageOverviewCard from './storage_usage_overview_card.vue';
|
||||
|
||||
export default {
|
||||
name: 'StorageUsageStatistics',
|
||||
components: {
|
||||
StorageUsageOverviewCard,
|
||||
},
|
||||
props: {
|
||||
usedStorage: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<h3 data-testid="overview-subtitle">{{ s__('UsageQuota|Namespace overview') }}</h3>
|
||||
<div class="gl-display-grid gl-md-grid-template-columns-2 gl-gap-5 gl-py-4">
|
||||
<storage-usage-overview-card
|
||||
:used-storage="usedStorage"
|
||||
:loading="loading"
|
||||
data-testid="namespace-usage-total"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -131,7 +131,7 @@ export default {
|
||||
class="item-body work-item-link-child gl-relative gl-display-flex gl-flex-grow-1 gl-overflow-break-word gl-min-w-0 gl-pl-3 gl-pr-2 gl-py-2 gl-mx-n2 gl-rounded-base gl-gap-3"
|
||||
data-testid="links-child"
|
||||
>
|
||||
<div class="item-contents gl-display-flex gl-flex-grow-1 gl-flex-wrap gl-min-w-0">
|
||||
<div class="gl-display-flex gl-flex-grow-1 gl-flex-wrap gl-min-w-0">
|
||||
<div
|
||||
class="gl-display-flex gl-flex-grow-1 gl-flex-wrap flex-xl-nowrap gl-align-items-center gl-justify-content-space-between gl-gap-3 gl-min-w-0"
|
||||
>
|
||||
|
@ -205,6 +205,95 @@ If you have any concerns, put the new ability behind a feature flag.
|
||||
- When you enable the ability by default, add the `feature_flag_enabled_milestone` and `feature_flag_enabled_mr` attributes to the appropriate ability YAML file and regenerate the documentation.
|
||||
- You do not have to include these attributes in the YAML file if the feature flag is enabled by default in the same release as the ability is introduced.
|
||||
|
||||
#### Testing
|
||||
|
||||
Unit tests are preferred to test out changes to any policies affected by the
|
||||
addition of new custom permissions. Custom Roles is an Ultimate tier feature so
|
||||
these tests can be found in the `ee/spec/policies` directory. The [spec file](https://gitlab.com/gitlab-org/gitlab/-/blob/13baa4e8c92a56260591a5bf0a58d3339890ee10/ee/spec/policies/project_policy_spec.rb#L2726-2740) for
|
||||
the `ProjectPolicy` contains shared examples that can be used to test out the
|
||||
following conditions:
|
||||
|
||||
- when the `custom_roles` licensed feature is not enabled
|
||||
- when the `custom_roles` licensed feature is enabled
|
||||
- when a user is a member of a custom role via an inherited group member
|
||||
- when a user is a member of a custom role via a direct group member
|
||||
- when a user is a member of a custom role via a direct project membership
|
||||
|
||||
Below is an example for testing out `ProjectPolicy` related changes.
|
||||
|
||||
```ruby
|
||||
context 'for a role with `custom_permission` enabled' do
|
||||
let(:member_role_abilities) { { custom_permission: true } }
|
||||
let(:allowed_abilities) { [:custom_permission] }
|
||||
|
||||
it_behaves_like 'custom roles abilities'
|
||||
end
|
||||
```
|
||||
|
||||
Request specs are preferred to test out any endpoint that allow access via a custom role permission.
|
||||
This includes controllers, REST API, and GraphQL. Examples of request specs can be found in `ee/spec/requests/custom_roles/`. In this directory you will find a sub-directory named after each permission that can be enabled via a custom role.
|
||||
The `custom_roles` licensed feature must be enabled to test this functionality.
|
||||
|
||||
Below is an example of the typical setup that is required to test out a
|
||||
Rails Controller endpoint.
|
||||
|
||||
```ruby
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project, :repository, :in_group) }
|
||||
let_it_be(:role) { create(:member_role, :guest, namespace: project.group, custom_permission: true) }
|
||||
let_it_be(:membership) { create(:project_member, :guest, member_role: role, user: user, project: project) }
|
||||
|
||||
before do
|
||||
stub_licensed_features(custom_roles: true)
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
describe MyController do
|
||||
describe '#show' do
|
||||
it 'allows access' do
|
||||
get my_controller_path(project)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to render_template(:show)
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Below is an example of the typical setup that is required to test out a GraphQL
|
||||
mutation.
|
||||
|
||||
```ruby
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project, :repository, :in_group) }
|
||||
let_it_be(:role) { create(:member_role, :guest, namespace: project.group, custom_permission: true) }
|
||||
let_it_be(:membership) { create(:project_member, :guest, member_role: role, user: user, project: project) }
|
||||
|
||||
before do
|
||||
stub_licensed_features(custom_roles: true)
|
||||
end
|
||||
|
||||
describe MyMutation do
|
||||
include GraphqlHelpers
|
||||
|
||||
describe '#show' do
|
||||
it 'allows access' do
|
||||
post_graphql_mutation(graphql_mutation(:my_mutation, {
|
||||
example: "Example"
|
||||
}), current_user: user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:success)
|
||||
mutation_response = graphql_mutation_response(:my_mutation)
|
||||
expect(mutation_response).to be_present
|
||||
expect(mutation_response["errors"]).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
[`GITLAB_DEBUG_POLICIES=true`](#finding-existing-abilities-checks) can be used
|
||||
to troubleshoot runtime policy decisions.
|
||||
|
||||
## Custom abilities definition
|
||||
|
||||
All new custom abilities must have a type definition stored in `ee/config/custom_abilities` that contains a single source of truth for every ability that is part of custom roles feature.
|
||||
@ -217,6 +306,7 @@ To add a new custom ability:
|
||||
- Use the `ee/bin/custom-ability` CLI to create the YAML definition automatically.
|
||||
- Perform manual steps to create a new file in `ee/config/custom_abilities/` with the filename matching the name of the ability name.
|
||||
1. Add contents to the file that conform to the [schema](#schema) defined in `ee/config/custom_abilities/types/type_schema.json`.
|
||||
1. Add [tests](#testing) for the new ability in `ee/spec/requests/custom_roles/` with a new directory named after the ability name.
|
||||
|
||||
### Schema
|
||||
|
||||
|
@ -83,10 +83,10 @@ module):
|
||||
- Maintainer (`40`)
|
||||
- Owner (`50`)
|
||||
|
||||
If a user is the member of both a project and the project parent groups, the
|
||||
If a user is a member of both a project and the project parent groups, the
|
||||
highest permission is the applied access level for the project.
|
||||
|
||||
If a user is the member of a project, but not the parent groups, they
|
||||
If a user is a member of a project, but not the parent groups, they
|
||||
can still view the groups and their entities (like epics).
|
||||
|
||||
Project membership (where the group membership is already taken into account)
|
||||
|
@ -92,9 +92,6 @@ the following sections and tables provide an alternative.
|
||||
|
||||
> The `approval_settings` fields were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/418752) in GitLab 16.4 [with flags](../../../administration/feature_flags.md) named `scan_result_policies_block_unprotecting_branches`, `scan_result_any_merge_request`, or `scan_result_policies_block_force_push`. See the `approval_settings` section below for more information.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default the `approval_settings` field is available. To hide the feature, an administrator can [disable the feature flags](../../../administration/feature_flags.md) named `scan_result_policies_block_unprotecting_branches`, `scan_result_any_merge_request` and `scan_result_policies_block_force_push`. See the `approval_settings` section below for more information. On GitLab.com, the `approval_settings` field is available.
|
||||
|
||||
| Field | Type | Required | Possible values | Description |
|
||||
|---------------------|--------------------|----------|-----------------|----------------------------------------------------------|
|
||||
| `name` | `string` | true | | Name of the policy. Maximum of 255 characters. |
|
||||
@ -195,7 +192,6 @@ the defined policy.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default the `block_branch_modification` field is available. To hide the feature, an administrator can [disable the feature flag](../../../administration/feature_flags.md) named `scan_result_policies_block_unprotecting_branches`. On GitLab.com, this feature is available.
|
||||
On self-managed GitLab, by default the `prevent_approval_by_author`, `prevent_approval_by_commit_author`, `remove_approvals_with_new_commit`, and `require_password_to_approve` fields are available. To hide the feature, an administrator can [disable the feature flag](../../../administration/feature_flags.md) named `scan_result_any_merge_request`. On GitLab.com, this feature is available.
|
||||
On self-managed GitLab, by default the `prevent_pushing_and_force_pushing` field is available. To hide the feature, an administrator can [disable the feature flag](../../../administration/feature_flags.md) named `scan_result_policies_block_force_push`. On GitLab.com, this feature is available.
|
||||
|
||||
The settings set in the policy overwrite settings in the project.
|
||||
|
@ -143,7 +143,8 @@ then
|
||||
ruby -r './tooling/lib/tooling/find_changes' -e "Tooling::FindChanges.new(
|
||||
from: :api,
|
||||
changed_files_pathname: '${DOC_CHANGES_FILE}',
|
||||
file_filter: ->(file) { !file['deleted_file'] && file['new_path'] =~ %r{doc/.*\.md|lint-doc\.sh|docs\.gitlab-ci\.yml} }
|
||||
file_filter: ->(file) { !file['deleted_file'] && file['new_path'] =~ %r{doc/.*\.md|\.vale|\.markdownlint|lint-doc\.sh|docs\.gitlab-ci\.yml} },
|
||||
only_new_paths: true
|
||||
).execute"
|
||||
if grep -E "\.vale|\.markdownlint|lint-doc\.sh|docs\.gitlab-ci\.yml" < $DOC_CHANGES_FILE
|
||||
then
|
||||
|
@ -0,0 +1,51 @@
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import NamespaceStorageApp from '~/usage_quotas/storage/components/namespace_storage_app.vue';
|
||||
import StorageUsageStatistics from '~/usage_quotas/storage/components/storage_usage_statistics.vue';
|
||||
import { defaultNamespaceProvideValues } from '../mock_data';
|
||||
|
||||
const defaultProps = {
|
||||
namespaceLoadingError: false,
|
||||
projectsLoadingError: false,
|
||||
isNamespaceStorageStatisticsLoading: false,
|
||||
// hardcoding object until we move test_fixtures from ee/ to here
|
||||
namespace: {
|
||||
rootStorageStatistics: {
|
||||
storageSize: 1234,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
describe('NamespaceStorageApp', () => {
|
||||
/** @type {import('helpers/vue_test_utils_helper').ExtendedWrapper} */
|
||||
let wrapper;
|
||||
|
||||
const findStorageUsageStatistics = () => wrapper.findComponent(StorageUsageStatistics);
|
||||
|
||||
const createComponent = ({ provide = {}, props = {} } = {}) => {
|
||||
wrapper = shallowMountExtended(NamespaceStorageApp, {
|
||||
provide: {
|
||||
...defaultNamespaceProvideValues,
|
||||
...provide,
|
||||
},
|
||||
propsData: {
|
||||
...defaultProps,
|
||||
...props,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
describe('Namespace usage overview', () => {
|
||||
describe('StorageUsageStatistics', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('passes the correct props to StorageUsageStatistics', () => {
|
||||
expect(findStorageUsageStatistics().props()).toMatchObject({
|
||||
usedStorage: defaultProps.namespace.rootStorageStatistics.storageSize,
|
||||
loading: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,44 @@
|
||||
import { GlSkeletonLoader } from '@gitlab/ui';
|
||||
import { numberToHumanSize } from '~/lib/utils/number_utils';
|
||||
import StorageUsageOverviewCard from '~/usage_quotas/storage/components/storage_usage_overview_card.vue';
|
||||
import NumberToHumanSize from '~/vue_shared/components/number_to_human_size/number_to_human_size.vue';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
|
||||
describe('StorageUsageOverviewCard', () => {
|
||||
/** @type {import('helpers/vue_test_utils_helper').ExtendedWrapper} */
|
||||
let wrapper;
|
||||
const defaultProps = {
|
||||
purchasedStorage: 0,
|
||||
// hardcoding value until we move test_fixtures from ee/ to here
|
||||
usedStorage: 1234,
|
||||
loading: false,
|
||||
};
|
||||
|
||||
const createComponent = ({ props = {} } = {}) => {
|
||||
wrapper = shallowMountExtended(StorageUsageOverviewCard, {
|
||||
propsData: { ...defaultProps, ...props },
|
||||
stubs: {
|
||||
NumberToHumanSize,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
|
||||
|
||||
it('displays the used storage value', () => {
|
||||
createComponent();
|
||||
expect(wrapper.text()).toContain(numberToHumanSize(defaultProps.usedStorage, 1));
|
||||
});
|
||||
|
||||
describe('skeleton loader', () => {
|
||||
it('renders skeleton loader when loading prop is true', () => {
|
||||
createComponent({ props: { loading: true } });
|
||||
expect(findSkeletonLoader().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('does not render skeleton loader when loading prop is false', () => {
|
||||
createComponent({ props: { loading: false } });
|
||||
expect(findSkeletonLoader().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,43 @@
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import StorageUsageStatistics from '~/usage_quotas/storage/components/storage_usage_statistics.vue';
|
||||
import StorageUsageOverviewCard from '~/usage_quotas/storage/components/storage_usage_overview_card.vue';
|
||||
|
||||
const defaultProps = {
|
||||
// hardcoding value until we move test_fixtures from ee/ to here
|
||||
usedStorage: 1234,
|
||||
loading: false,
|
||||
};
|
||||
|
||||
describe('StorageUsageStatistics', () => {
|
||||
/** @type {import('helpers/vue_test_utils_helper').ExtendedWrapper} */
|
||||
let wrapper;
|
||||
|
||||
const createComponent = ({ props = {} } = {}) => {
|
||||
wrapper = shallowMountExtended(StorageUsageStatistics, {
|
||||
propsData: {
|
||||
...defaultProps,
|
||||
...props,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const findOverviewSubtitle = () => wrapper.findByTestId('overview-subtitle');
|
||||
const findStorageUsageOverviewCard = () => wrapper.findComponent(StorageUsageOverviewCard);
|
||||
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('shows the namespace storage overview subtitle', () => {
|
||||
expect(findOverviewSubtitle().text()).toBe('Namespace overview');
|
||||
});
|
||||
|
||||
describe('StorageStatisticsCard', () => {
|
||||
it('passes the correct props to StorageUsageOverviewCard', () => {
|
||||
expect(findStorageUsageOverviewCard().props()).toEqual({
|
||||
usedStorage: defaultProps.usedStorage,
|
||||
loading: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -6,3 +6,5 @@ export const mockEmptyResponse = { data: { project: null } };
|
||||
export const defaultProjectProvideValues = {
|
||||
projectPath: '/project-path',
|
||||
};
|
||||
|
||||
export const defaultNamespaceProvideValues = {};
|
||||
|
@ -16,7 +16,8 @@ RSpec.describe Tooling::FindChanges, feature_category: :tooling do
|
||||
predictive_tests_pathname: predictive_tests_pathname,
|
||||
frontend_fixtures_mapping_pathname: frontend_fixtures_mapping_pathname,
|
||||
from: from,
|
||||
file_filter: file_filter)
|
||||
file_filter: file_filter,
|
||||
only_new_paths: only_new_paths)
|
||||
end
|
||||
|
||||
let(:changed_files_pathname) { changed_files_file.path }
|
||||
@ -25,6 +26,7 @@ RSpec.describe Tooling::FindChanges, feature_category: :tooling do
|
||||
let(:from) { :api }
|
||||
let(:gitlab_client) { double('GitLab') } # rubocop:disable RSpec/VerifiedDoubles
|
||||
let(:file_filter) { ->(_) { true } }
|
||||
let(:only_new_paths) { false }
|
||||
|
||||
around do |example|
|
||||
self.changed_files_file = Tempfile.new('changed_files_file')
|
||||
@ -122,6 +124,37 @@ RSpec.describe Tooling::FindChanges, feature_category: :tooling do
|
||||
expect(File.read(changed_files_file)).to eq('doc/index.md')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when used with only_new_paths' do
|
||||
let(:only_new_paths) { true }
|
||||
|
||||
let(:mr_changes_array) do
|
||||
[
|
||||
{
|
||||
"new_path" => "scripts/test.js",
|
||||
"old_path" => "scripts/test.js"
|
||||
},
|
||||
{
|
||||
"new_path" => "doc/renamed_index.md",
|
||||
"old_path" => "doc/index.md"
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
before do
|
||||
# rubocop:disable RSpec/VerifiedDoubles -- The class from the GitLab gem isn't public, so we cannot use verified doubles for it.
|
||||
allow(gitlab_client).to receive(:merge_request_changes)
|
||||
.with('dummy-project', '1234')
|
||||
.and_return(double(changes: mr_changes_array))
|
||||
# rubocop:enable RSpec/VerifiedDoubles
|
||||
end
|
||||
|
||||
it 'only writes new file paths to output' do
|
||||
subject
|
||||
|
||||
expect(File.read(changed_files_file)).to eq('doc/renamed_index.md scripts/test.js')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when fetching changes from changed files' do
|
||||
|
@ -15,7 +15,8 @@ module Tooling
|
||||
changed_files_pathname: nil,
|
||||
predictive_tests_pathname: nil,
|
||||
frontend_fixtures_mapping_pathname: nil,
|
||||
file_filter: ->(_) { true }
|
||||
file_filter: ->(_) { true },
|
||||
only_new_paths: false
|
||||
)
|
||||
|
||||
raise ArgumentError, ':from can only be :api or :changed_files' unless
|
||||
@ -30,6 +31,7 @@ module Tooling
|
||||
@frontend_fixtures_mapping_pathname = frontend_fixtures_mapping_pathname
|
||||
@from = from
|
||||
@file_filter = file_filter
|
||||
@api_path_attributes = only_new_paths ? %w[new_path] : %w[new_path old_path]
|
||||
end
|
||||
|
||||
def execute
|
||||
@ -53,7 +55,7 @@ module Tooling
|
||||
|
||||
attr_reader :gitlab_token, :gitlab_endpoint, :mr_project_path,
|
||||
:mr_iid, :changed_files_pathname, :predictive_tests_pathname,
|
||||
:frontend_fixtures_mapping_pathname, :file_filter
|
||||
:frontend_fixtures_mapping_pathname, :file_filter, :api_path_attributes
|
||||
|
||||
def gitlab
|
||||
@gitlab ||= begin
|
||||
@ -86,7 +88,7 @@ module Tooling
|
||||
case @from
|
||||
when :api
|
||||
mr_changes.changes.select(&file_filter).flat_map do |change|
|
||||
change.to_h.values_at('old_path', 'new_path')
|
||||
change.to_h.values_at(*api_path_attributes)
|
||||
end.uniq
|
||||
else
|
||||
read_array_from_file(changed_files_pathname)
|
||||
|
Reference in New Issue
Block a user