Commit 96bb773e authored by Craig Norris's avatar Craig Norris

Merge branch 'selhorn-nuget-packages' into 'master'

Docs: Edited NuGet topic

See merge request gitlab-org/gitlab!46936
parents 7e8f4fee 86f6c2a7
...@@ -7,9 +7,11 @@ require: ...@@ -7,9 +7,11 @@ require:
- rubocop-rspec - rubocop-rspec
inherit_from: inherit_from:
- .rubocop_manual_todo.yml
- .rubocop_todo.yml - .rubocop_todo.yml
- ./rubocop/rubocop-migrations.yml - ./rubocop/rubocop-migrations.yml
- ./rubocop/rubocop-usage-data.yml - ./rubocop/rubocop-usage-data.yml
- ./rubocop/rubocop-code_reuse.yml
inherit_mode: inherit_mode:
merge: merge:
......
This diff is collapsed.
This diff is collapsed.
...@@ -370,11 +370,7 @@ group :development, :test do ...@@ -370,11 +370,7 @@ group :development, :test do
gem 'spring', '~> 2.0.0' gem 'spring', '~> 2.0.0'
gem 'spring-commands-rspec', '~> 1.0.4' gem 'spring-commands-rspec', '~> 1.0.4'
gem 'gitlab-styles', '~> 4.3.0', require: false gem 'gitlab-styles', '~> 5.0.0', require: false
# Pin these dependencies, otherwise a new rule could break the CI pipelines
gem 'rubocop', '~> 0.82.0'
gem 'rubocop-performance', '~> 1.5.2'
gem 'rubocop-rspec', '~> 1.37.0'
gem 'scss_lint', '~> 0.56.0', require: false gem 'scss_lint', '~> 0.56.0', require: false
gem 'haml_lint', '~> 0.36.0', require: false gem 'haml_lint', '~> 0.36.0', require: false
......
...@@ -449,12 +449,12 @@ GEM ...@@ -449,12 +449,12 @@ GEM
gitlab-puma (>= 2.7, < 5) gitlab-puma (>= 2.7, < 5)
gitlab-sidekiq-fetcher (0.5.2) gitlab-sidekiq-fetcher (0.5.2)
sidekiq (~> 5) sidekiq (~> 5)
gitlab-styles (4.3.0) gitlab-styles (5.0.0)
rubocop (~> 0.82.0) rubocop (~> 0.89.1)
rubocop-gitlab-security (~> 0.1.0) rubocop-gitlab-security (~> 0.1.0)
rubocop-performance (~> 1.5.2) rubocop-performance (~> 1.8.1)
rubocop-rails (~> 2.5) rubocop-rails (~> 2.8)
rubocop-rspec (~> 1.36) rubocop-rspec (~> 1.44)
gitlab_chronic_duration (0.10.6.2) gitlab_chronic_duration (0.10.6.2)
numerizer (~> 0.2) numerizer (~> 0.2)
gitlab_omniauth-ldap (2.1.1) gitlab_omniauth-ldap (2.1.1)
...@@ -602,7 +602,6 @@ GEM ...@@ -602,7 +602,6 @@ GEM
jaeger-client (1.1.0) jaeger-client (1.1.0)
opentracing (~> 0.3) opentracing (~> 0.3)
thrift thrift
jaro_winkler (1.5.4)
jira-ruby (2.0.0) jira-ruby (2.0.0)
activesupport activesupport
atlassian-jwt atlassian-jwt
...@@ -834,7 +833,7 @@ GEM ...@@ -834,7 +833,7 @@ GEM
rubypants (~> 0.2) rubypants (~> 0.2)
orm_adapter (0.5.0) orm_adapter (0.5.0)
os (1.0.0) os (1.0.0)
parallel (1.19.1) parallel (1.19.2)
parser (2.7.2.0) parser (2.7.2.0)
ast (~> 2.4.1) ast (~> 2.4.1)
parslet (1.8.2) parslet (1.8.2)
...@@ -958,7 +957,7 @@ GEM ...@@ -958,7 +957,7 @@ GEM
redis-store (>= 1.2, < 2) redis-store (>= 1.2, < 2)
redis-store (1.8.1) redis-store (1.8.1)
redis (>= 4, < 5) redis (>= 4, < 5)
regexp_parser (1.5.1) regexp_parser (1.8.2)
regexp_property_values (0.3.5) regexp_property_values (0.3.5)
representable (3.0.4) representable (3.0.4)
declarative (< 0.1.0) declarative (< 0.1.0)
...@@ -1019,24 +1018,29 @@ GEM ...@@ -1019,24 +1018,29 @@ GEM
pg pg
rails rails
sqlite3 sqlite3
rubocop (0.82.0) rubocop (0.89.1)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 2.7.0.1) parser (>= 2.7.1.1)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml rexml
rubocop-ast (>= 0.3.0, < 1.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0) unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.8.0)
parser (>= 2.7.1.5)
rubocop-gitlab-security (0.1.1) rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51) rubocop (>= 0.51)
rubocop-performance (1.5.2) rubocop-performance (1.8.1)
rubocop (>= 0.71.0) rubocop (>= 0.87.0)
rubocop-rails (2.5.2) rubocop-ast (>= 0.4.0)
activesupport rubocop-rails (2.8.1)
activesupport (>= 4.2.0)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 0.72.0) rubocop (>= 0.87.0)
rubocop-rspec (1.37.0) rubocop-rspec (1.44.1)
rubocop (>= 0.68.1) rubocop (~> 0.87)
rubocop-ast (>= 0.7.1)
ruby-enum (0.7.2) ruby-enum (0.7.2)
i18n i18n
ruby-fogbugz (0.2.1) ruby-fogbugz (0.2.1)
...@@ -1249,7 +1253,7 @@ GEM ...@@ -1249,7 +1253,7 @@ GEM
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
yajl-ruby (1.4.1) yajl-ruby (1.4.1)
zeitwerk (2.4.0) zeitwerk (2.4.1)
PLATFORMS PLATFORMS
ruby ruby
...@@ -1353,7 +1357,7 @@ DEPENDENCIES ...@@ -1353,7 +1357,7 @@ DEPENDENCIES
gitlab-puma (~> 4.3.3.gitlab.2) gitlab-puma (~> 4.3.3.gitlab.2)
gitlab-puma_worker_killer (~> 0.1.1.gitlab.1) gitlab-puma_worker_killer (~> 0.1.1.gitlab.1)
gitlab-sidekiq-fetcher (= 0.5.2) gitlab-sidekiq-fetcher (= 0.5.2)
gitlab-styles (~> 4.3.0) gitlab-styles (~> 5.0.0)
gitlab_chronic_duration (~> 0.10.6.2) gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.1.1) gitlab_omniauth-ldap (~> 2.1.1)
gon (~> 6.2) gon (~> 6.2)
...@@ -1473,9 +1477,6 @@ DEPENDENCIES ...@@ -1473,9 +1477,6 @@ DEPENDENCIES
rspec-retry (~> 0.6.1) rspec-retry (~> 0.6.1)
rspec_junit_formatter rspec_junit_formatter
rspec_profiling (~> 0.0.6) rspec_profiling (~> 0.0.6)
rubocop (~> 0.82.0)
rubocop-performance (~> 1.5.2)
rubocop-rspec (~> 1.37.0)
ruby-fogbugz (~> 0.2.1) ruby-fogbugz (~> 0.2.1)
ruby-prof (~> 1.3.0) ruby-prof (~> 1.3.0)
ruby-progressbar ruby-progressbar
......
...@@ -4,10 +4,16 @@ class Analytics::DevopsAdoption::Segment < ApplicationRecord ...@@ -4,10 +4,16 @@ class Analytics::DevopsAdoption::Segment < ApplicationRecord
ALLOWED_SEGMENT_COUNT = 20 ALLOWED_SEGMENT_COUNT = 20
has_many :segment_selections has_many :segment_selections
has_many :groups, through: :segment_selections
validates :name, presence: true, uniqueness: true, length: { maximum: 255 } validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
validate :validate_segment_count validate :validate_segment_count
accepts_nested_attributes_for :segment_selections, allow_destroy: true
scope :ordered_by_name, -> { order(:name) }
scope :with_groups, -> { preload(:groups) }
private private
def validate_segment_count def validate_segment_count
......
---
name: security_on_demand_scans_http_header_validation
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42812
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/276403
milestone: '13.6'
type: development
group: group::dynamic analysis
default_enabled: false
...@@ -6025,6 +6025,81 @@ type DetailedStatus { ...@@ -6025,6 +6025,81 @@ type DetailedStatus {
tooltip: String tooltip: String
} }
"""
Segment
"""
type DevopsAdoptionSegment {
"""
Assigned groups
"""
groups(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): GroupConnection
"""
ID of the segment
"""
id: ID!
"""
Name of the segment
"""
name: String!
}
"""
The connection type for DevopsAdoptionSegment.
"""
type DevopsAdoptionSegmentConnection {
"""
A list of edges.
"""
edges: [DevopsAdoptionSegmentEdge]
"""
A list of nodes.
"""
nodes: [DevopsAdoptionSegment]
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type DevopsAdoptionSegmentEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: DevopsAdoptionSegment
}
input DiffImagePositionInput { input DiffImagePositionInput {
""" """
Merge base of the branch the comment was made on Merge base of the branch the comment was made on
...@@ -9165,6 +9240,41 @@ type Group { ...@@ -9165,6 +9240,41 @@ type Group {
webUrl: String! webUrl: String!
} }
"""
The connection type for Group.
"""
type GroupConnection {
"""
A list of edges.
"""
edges: [GroupEdge]
"""
A list of nodes.
"""
nodes: [Group]
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type GroupEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: Group
}
""" """
Identifier of Group Identifier of Group
""" """
...@@ -16540,6 +16650,31 @@ type Query { ...@@ -16540,6 +16650,31 @@ type Query {
""" """
designManagement: DesignManagement! designManagement: DesignManagement!
"""
Get configured DevOps adoption segments on the instance
"""
devopsAdoptionSegments(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): DevopsAdoptionSegmentConnection
""" """
Text to echo back Text to echo back
""" """
......
...@@ -1000,6 +1000,16 @@ Autogenerated return type of DestroySnippet. ...@@ -1000,6 +1000,16 @@ Autogenerated return type of DestroySnippet.
| `text` | String | Text of the status | | `text` | String | Text of the status |
| `tooltip` | String | Tooltip associated with the status | | `tooltip` | String | Tooltip associated with the status |
### DevopsAdoptionSegment
Segment.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `groups` | GroupConnection | Assigned groups |
| `id` | ID! | ID of the segment |
| `name` | String! | Name of the segment |
### DiffPosition ### DiffPosition
| Field | Type | Description | | Field | Type | Description |
......
...@@ -18,6 +18,12 @@ If you choose a size larger than what is currently configured for the web server ...@@ -18,6 +18,12 @@ If you choose a size larger than what is currently configured for the web server
you will likely get errors. See the [troubleshooting section](#troubleshooting) for more you will likely get errors. See the [troubleshooting section](#troubleshooting) for more
details. details.
## Max push size
You can change the maximum push size for your repository.
Navigate to **Admin Area (wrench icon) > Settings > General**, then expand **Account and Limit**.
From here, you can increase or decrease by changing the value in `Maximum push size (MB)`.
## Max import size ## Max import size
You can change the maximum file size for imports in GitLab. You can change the maximum file size for imports in GitLab.
......
...@@ -11,11 +11,16 @@ import { ...@@ -11,11 +11,16 @@ import {
GlInputGroupText, GlInputGroupText,
GlLoadingIcon, GlLoadingIcon,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { omit } from 'lodash';
import * as Sentry from '~/sentry/wrapper'; import * as Sentry from '~/sentry/wrapper';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import download from '~/lib/utils/downloader'; import download from '~/lib/utils/downloader';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { cleanLeadingSeparator, joinPaths, stripPathTail } from '~/lib/utils/url_utility'; import { cleanLeadingSeparator, joinPaths, stripPathTail } from '~/lib/utils/url_utility';
import { fetchPolicies } from '~/lib/graphql'; import { fetchPolicies } from '~/lib/graphql';
import { import {
DAST_SITE_VALIDATION_HTTP_HEADER_KEY,
DAST_SITE_VALIDATION_METHOD_HTTP_HEADER,
DAST_SITE_VALIDATION_METHOD_TEXT_FILE, DAST_SITE_VALIDATION_METHOD_TEXT_FILE,
DAST_SITE_VALIDATION_METHODS, DAST_SITE_VALIDATION_METHODS,
DAST_SITE_VALIDATION_STATUS, DAST_SITE_VALIDATION_STATUS,
...@@ -27,6 +32,7 @@ import dastSiteValidationQuery from '../graphql/dast_site_validation.query.graph ...@@ -27,6 +32,7 @@ import dastSiteValidationQuery from '../graphql/dast_site_validation.query.graph
export default { export default {
name: 'DastSiteValidation', name: 'DastSiteValidation',
components: { components: {
ClipboardButton,
GlAlert, GlAlert,
GlButton, GlButton,
GlCard, GlCard,
...@@ -38,6 +44,7 @@ export default { ...@@ -38,6 +44,7 @@ export default {
GlInputGroupText, GlInputGroupText,
GlLoadingIcon, GlLoadingIcon,
}, },
mixins: [glFeatureFlagsMixin()],
apollo: { apollo: {
dastSiteValidation: { dastSiteValidation: {
query: dastSiteValidationQuery, query: dastSiteValidationQuery,
...@@ -103,6 +110,16 @@ export default { ...@@ -103,6 +110,16 @@ export default {
}; };
}, },
computed: { computed: {
validationMethodOptions() {
const isHttpHeaderValidationEnabled = this.glFeatures
.securityOnDemandScansHttpHeaderValidation;
const enabledValidationMethods = omit(DAST_SITE_VALIDATION_METHODS, [
!isHttpHeaderValidationEnabled ? DAST_SITE_VALIDATION_METHOD_HTTP_HEADER : '',
]);
return Object.values(enabledValidationMethods);
},
urlObject() { urlObject() {
try { try {
return new URL(this.targetUrl); return new URL(this.targetUrl);
...@@ -119,12 +136,18 @@ export default { ...@@ -119,12 +136,18 @@ export default {
isTextFileValidation() { isTextFileValidation() {
return this.validationMethod === DAST_SITE_VALIDATION_METHOD_TEXT_FILE; return this.validationMethod === DAST_SITE_VALIDATION_METHOD_TEXT_FILE;
}, },
isHttpHeaderValidation() {
return this.validationMethod === DAST_SITE_VALIDATION_METHOD_HTTP_HEADER;
},
textFileName() { textFileName() {
return `GitLab-DAST-Site-Validation-${this.token}.txt`; return `GitLab-DAST-Site-Validation-${this.token}.txt`;
}, },
locationStepLabel() { locationStepLabel() {
return DAST_SITE_VALIDATION_METHODS[this.validationMethod].i18n.locationStepLabel; return DAST_SITE_VALIDATION_METHODS[this.validationMethod].i18n.locationStepLabel;
}, },
httpHeader() {
return `${DAST_SITE_VALIDATION_HTTP_HEADER_KEY}: uuid-code-${this.token}`;
},
}, },
watch: { watch: {
targetUrl() { targetUrl() {
...@@ -132,13 +155,22 @@ export default { ...@@ -132,13 +155,22 @@ export default {
}, },
}, },
created() { created() {
this.unsubscribe = this.$watch(() => this.token, this.updateValidationPath, { this.unsubscribe = this.$watch(
immediate: true, () => [this.token, this.validationMethod],
}); this.updateValidationPath,
{
immediate: true,
},
);
}, },
methods: { methods: {
updateValidationPath() { updateValidationPath() {
this.validationPath = joinPaths(stripPathTail(this.path), this.textFileName); this.validationPath = this.isTextFileValidation
? this.getTextFileValidationPath()
: this.path;
},
getTextFileValidationPath() {
return joinPaths(stripPathTail(this.path), this.textFileName);
}, },
onValidationPathInput() { onValidationPathInput() {
this.unsubscribe(); this.unsubscribe();
...@@ -189,7 +221,6 @@ export default { ...@@ -189,7 +221,6 @@ export default {
this.hasValidationError = true; this.hasValidationError = true;
}, },
}, },
validationMethodOptions: Object.values(DAST_SITE_VALIDATION_METHODS),
}; };
</script> </script>
...@@ -199,7 +230,7 @@ export default { ...@@ -199,7 +230,7 @@ export default {
{{ s__('DastProfiles|Site is not validated yet, please follow the steps.') }} {{ s__('DastProfiles|Site is not validated yet, please follow the steps.') }}
</gl-alert> </gl-alert>
<gl-form-group :label="s__('DastProfiles|Step 1 - Choose site validation method')"> <gl-form-group :label="s__('DastProfiles|Step 1 - Choose site validation method')">
<gl-form-radio-group v-model="validationMethod" :options="$options.validationMethodOptions" /> <gl-form-radio-group v-model="validationMethod" :options="validationMethodOptions" />
</gl-form-group> </gl-form-group>
<gl-form-group <gl-form-group
v-if="isTextFileValidation" v-if="isTextFileValidation"
...@@ -217,6 +248,16 @@ export default { ...@@ -217,6 +248,16 @@ export default {
{{ textFileName }} {{ textFileName }}
</gl-button> </gl-button>
</gl-form-group> </gl-form-group>
<gl-form-group
v-else-if="isHttpHeaderValidation"
:label="s__('DastProfiles|Step 2 - Add following HTTP header to your site')"
>
<code class="gl-p-3 gl-bg-black gl-text-white">{{ httpHeader }}</code>
<clipboard-button
:text="httpHeader"
:title="s__('DastProfiles|Copy HTTP header to clipboard')"
/>
</gl-form-group>
<gl-form-group :label="locationStepLabel" class="mw-460"> <gl-form-group :label="locationStepLabel" class="mw-460">
<gl-form-input-group> <gl-form-input-group>
<template #prepend> <template #prepend>
...@@ -255,7 +296,7 @@ export default { ...@@ -255,7 +296,7 @@ export default {
<gl-icon name="status_failed" /> <gl-icon name="status_failed" />
{{ {{
s__( s__(
'DastProfiles|Validation failed, please make sure that you follow the steps above with the choosen method.', 'DastProfiles|Validation failed, please make sure that you follow the steps above with the chosen method.',
) )
}} }}
</template> </template>
......
import { s__ } from '~/locale'; import { s__ } from '~/locale';
export const DAST_SITE_VALIDATION_METHOD_TEXT_FILE = 'TEXT_FILE'; export const DAST_SITE_VALIDATION_METHOD_TEXT_FILE = 'TEXT_FILE';
export const DAST_SITE_VALIDATION_METHOD_HTTP_HEADER = 'HTTP_HEADER';
export const DAST_SITE_VALIDATION_METHODS = { export const DAST_SITE_VALIDATION_METHODS = {
[DAST_SITE_VALIDATION_METHOD_TEXT_FILE]: { [DAST_SITE_VALIDATION_METHOD_TEXT_FILE]: {
value: DAST_SITE_VALIDATION_METHOD_TEXT_FILE, value: DAST_SITE_VALIDATION_METHOD_TEXT_FILE,
...@@ -9,6 +11,13 @@ export const DAST_SITE_VALIDATION_METHODS = { ...@@ -9,6 +11,13 @@ export const DAST_SITE_VALIDATION_METHODS = {
locationStepLabel: s__('DastProfiles|Step 3 - Confirm text file location and validate'), locationStepLabel: s__('DastProfiles|Step 3 - Confirm text file location and validate'),
}, },
}, },
[DAST_SITE_VALIDATION_METHOD_HTTP_HEADER]: {
value: DAST_SITE_VALIDATION_METHOD_HTTP_HEADER,
text: s__('DastProfiles|Header validation'),
i18n: {
locationStepLabel: s__('DastProfiles|Step 3 - Confirm header location and validate'),
},
},
}; };
export const DAST_SITE_VALIDATION_STATUS = { export const DAST_SITE_VALIDATION_STATUS = {
...@@ -19,3 +28,4 @@ export const DAST_SITE_VALIDATION_STATUS = { ...@@ -19,3 +28,4 @@ export const DAST_SITE_VALIDATION_STATUS = {
}; };
export const DAST_SITE_VALIDATION_POLL_INTERVAL = 1000; export const DAST_SITE_VALIDATION_POLL_INTERVAL = 1000;
export const DAST_SITE_VALIDATION_HTTP_HEADER_KEY = 'Gitlab-On-Demand-DAST';
...@@ -6,6 +6,7 @@ module Projects ...@@ -6,6 +6,7 @@ module Projects
before_action do before_action do
authorize_read_on_demand_scans! authorize_read_on_demand_scans!
push_frontend_feature_flag(:security_on_demand_scans_site_validation, @project) push_frontend_feature_flag(:security_on_demand_scans_site_validation, @project)
push_frontend_feature_flag(:security_on_demand_scans_http_header_validation, @project)
end end
feature_category :dynamic_application_security_testing feature_category :dynamic_application_security_testing
......
...@@ -51,6 +51,11 @@ module EE ...@@ -51,6 +51,11 @@ module EE
null: true, null: true,
resolver: ::Resolvers::InstanceSecurityDashboardResolver, resolver: ::Resolvers::InstanceSecurityDashboardResolver,
description: 'Fields related to Instance Security Dashboard' description: 'Fields related to Instance Security Dashboard'
field :devops_adoption_segments, ::Types::Admin::Analytics::DevopsAdoption::SegmentType.connection_type,
null: true,
description: 'Get configured DevOps adoption segments on the instance',
resolver: ::Resolvers::Admin::Analytics::DevopsAdoption::SegmentsResolver
end end
def vulnerability(id:) def vulnerability(id:)
......
# frozen_string_literal: true
module Resolvers
module Admin
module Analytics
module DevopsAdoption
class SegmentsResolver < BaseResolver
include Gitlab::Graphql::Authorize::AuthorizeResource
type Types::Admin::Analytics::DevopsAdoption::SegmentType, null: true
def resolve
authorize!
if segments_feature_available?
::Analytics::DevopsAdoption::Segment.with_groups.ordered_by_name
else
::Analytics::DevopsAdoption::Segment.none
end
end
private
def segments_feature_available?
License.feature_available?(:instance_level_devops_adoption)
end
def authorize!
admin? || raise_resource_not_available_error!
end
def admin?
context[:current_user].present? && context[:current_user].admin?
end
end
end
end
end
end
# frozen_string_literal: true
# rubocop:disable Graphql/AuthorizeTypes
module Types
module Admin
module Analytics
module DevopsAdoption
class SegmentType < BaseObject
graphql_name 'DevopsAdoptionSegment'
description 'Segment'
field :id, GraphQL::ID_TYPE, null: false,
description: "ID of the segment"
field :name, GraphQL::STRING_TYPE, null: false,
description: 'Name of the segment'
field :groups, Types::GroupType.connection_type, null: true,
description: 'Assigned groups'
end
end
end
end
end
...@@ -19,6 +19,7 @@ class License < ApplicationRecord ...@@ -19,6 +19,7 @@ class License < ApplicationRecord
group_activity_analytics group_activity_analytics
group_bulk_edit group_bulk_edit
group_webhooks group_webhooks
instance_level_devops_adoption
issuable_default_templates issuable_default_templates
issue_weights issue_weights
iterations iterations
......
---
title: Expose Devops Adoption segments via GraphQL
merge_request: 46879
author:
type: added
...@@ -3,8 +3,5 @@ ...@@ -3,8 +3,5 @@
--- ---
inherit_from: ../../../../../lib/gitlab/background_migration/.rubocop.yml inherit_from: ../../../../../lib/gitlab/background_migration/.rubocop.yml
CodeReuse/ActiveRecord:
Enabled: false
Style/Documentation: Style/Documentation:
Enabled: false Enabled: false
...@@ -14,7 +14,7 @@ export const dastSiteValidation = (status = DAST_SITE_VALIDATION_STATUS.PENDING) ...@@ -14,7 +14,7 @@ export const dastSiteValidation = (status = DAST_SITE_VALIDATION_STATUS.PENDING)
export const dastSiteValidationCreate = (errors = []) => ({ export const dastSiteValidationCreate = (errors = []) => ({
data: { data: {
dastSiteValidationCreate: { status: DAST_SITE_VALIDATION_STATUS.PASSED, id: '1', errors }, dastSiteValidationCreate: { status: DAST_SITE_VALIDATION_STATUS.PENDING, id: '1', errors },
}, },
}); });
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Resolvers::Admin::Analytics::DevopsAdoption::SegmentsResolver do
include GraphqlHelpers
let_it_be(:admin_user) { create(:user, :admin) }
let(:current_user) { admin_user }
def resolve_segments(args = {}, context = {})
resolve(described_class, args: args, ctx: context)
end
describe '#resolve' do
let_it_be(:user) { create(:user) }
let_it_be(:segment_1) { create(:devops_adoption_segment, name: 'bbb') }
let_it_be(:segment_2) { create(:devops_adoption_segment, name: 'aaa') }
subject { resolve_segments({}, { current_user: current_user }) }
before do
stub_licensed_features(instance_level_devops_adoption: true)
end
context 'when requesting project count measurements' do
context 'as an admin user' do
let(:current_user) { admin_user }
it 'returns the records, ordered by name' do
expect(subject).to eq([segment_2, segment_1])
end
end
context 'when the feature is not available' do
let(:current_user) { admin_user }
before do
stub_licensed_features(instance_level_devops_adoption: false)
end
it 'returns the records, ordered by name' do
expect(subject).to be_empty
end
end
context 'as a non-admin user' do
let(:current_user) { user }
it 'raises ResourceNotAvailable error' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'as an unauthenticated user' do
let(:current_user) { nil }
it 'raises ResourceNotAvailable error' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
end
end
...@@ -26,4 +26,15 @@ RSpec.describe Analytics::DevopsAdoption::Segment, type: :model do ...@@ -26,4 +26,15 @@ RSpec.describe Analytics::DevopsAdoption::Segment, type: :model do
end end
end end
end end
describe '.ordered_by_name' do
let(:segment_1) { create(:devops_adoption_segment, name: 'bbb') }
let(:segment_2) { create(:devops_adoption_segment, name: 'aaa') }
subject { described_class.ordered_by_name }
it 'orders segments by name' do
expect(subject).to eq([segment_2, segment_1])
end
end
end end
...@@ -190,7 +190,7 @@ module Gitlab ...@@ -190,7 +190,7 @@ module Gitlab
%r{\A(ee/)?vendor/} => :backend, %r{\A(ee/)?vendor/} => :backend,
%r{\A(Gemfile|Gemfile.lock|Rakefile)\z} => :backend, %r{\A(Gemfile|Gemfile.lock|Rakefile)\z} => :backend,
%r{\A[A-Z_]+_VERSION\z} => :backend, %r{\A[A-Z_]+_VERSION\z} => :backend,
%r{\A\.rubocop(_todo)?\.yml\z} => :backend, %r{\A\.rubocop((_manual)?_todo)?\.yml\z} => :backend,
%r{\Afile_hooks/} => :backend, %r{\Afile_hooks/} => :backend,
%r{\A(ee/)?qa/} => :qa, %r{\A(ee/)?qa/} => :qa,
......
...@@ -8319,6 +8319,9 @@ msgstr "" ...@@ -8319,6 +8319,9 @@ msgstr ""
msgid "DastProfiles|Authentication URL" msgid "DastProfiles|Authentication URL"
msgstr "" msgstr ""
msgid "DastProfiles|Copy HTTP header to clipboard"
msgstr ""
msgid "DastProfiles|Could not create site validation token. Please refresh the page, or try again later." msgid "DastProfiles|Could not create site validation token. Please refresh the page, or try again later."
msgstr "" msgstr ""
...@@ -8385,6 +8388,9 @@ msgstr "" ...@@ -8385,6 +8388,9 @@ msgstr ""
msgid "DastProfiles|Error Details" msgid "DastProfiles|Error Details"
msgstr "" msgstr ""
msgid "DastProfiles|Header validation"
msgstr ""
msgid "DastProfiles|Hide debug messages" msgid "DastProfiles|Hide debug messages"
msgstr "" msgstr ""
...@@ -8469,9 +8475,15 @@ msgstr "" ...@@ -8469,9 +8475,15 @@ msgstr ""
msgid "DastProfiles|Step 1 - Choose site validation method" msgid "DastProfiles|Step 1 - Choose site validation method"
msgstr "" msgstr ""
msgid "DastProfiles|Step 2 - Add following HTTP header to your site"
msgstr ""
msgid "DastProfiles|Step 2 - Add following text to the target site" msgid "DastProfiles|Step 2 - Add following text to the target site"
msgstr "" msgstr ""
msgid "DastProfiles|Step 3 - Confirm header location and validate"
msgstr ""
msgid "DastProfiles|Step 3 - Confirm text file location and validate" msgid "DastProfiles|Step 3 - Confirm text file location and validate"
msgstr "" msgstr ""
...@@ -8508,7 +8520,7 @@ msgstr "" ...@@ -8508,7 +8520,7 @@ msgstr ""
msgid "DastProfiles|Validating..." msgid "DastProfiles|Validating..."
msgstr "" msgstr ""
msgid "DastProfiles|Validation failed, please make sure that you follow the steps above with the choosen method." msgid "DastProfiles|Validation failed, please make sure that you follow the steps above with the chosen method."
msgstr "" msgstr ""
msgid "DastProfiles|Validation failed. Please try again." msgid "DastProfiles|Validation failed. Please try again."
......
# frozen_string_literal: true
require_relative '../../code_reuse_helpers'
module RuboCop
module Cop
module CodeReuse
# Cop that denies the use of ActiveRecord methods outside of models.
class ActiveRecord < RuboCop::Cop::Cop
include CodeReuseHelpers
MSG = 'This method can only be used inside an ActiveRecord model: ' \
'https://gitlab.com/gitlab-org/gitlab-foss/issues/49653'
# Various methods from ActiveRecord::Querying that are denied. We
# exclude some generic ones such as `any?` and `first`, as these may
# lead to too many false positives, since `Array` also supports these
# methods.
#
# The keys of this Hash are the denied method names. The values are
# booleans that indicate if the method should only be denied if any
# arguments are provided.
NOT_ALLOWED = {
average: true,
calculate: true,
count_by_sql: true,
create_with: true,
distinct: false,
eager_load: true,
exists?: true,
find_by: true,
find_by!: true,
find_by_sql: true,
find_each: true,
find_in_batches: true,
find_or_create_by: true,
find_or_create_by!: true,
find_or_initialize_by: true,
first!: false,
first_or_create: true,
first_or_create!: true,
first_or_initialize: true,
from: true,
group: true,
having: true,
ids: false,
includes: true,
joins: true,
limit: true,
lock: false,
many?: false,
offset: true,
order: true,
pluck: true,
preload: true,
readonly: false,
references: true,
reorder: true,
rewhere: true,
take: false,
take!: false,
unscope: false,
where: false,
with: true
}.freeze
# Directories that allow the use of the denied methods. These
# directories are checked relative to both . and ee/
ALLOWED_DIRECTORIES = %w[
app/models
config
danger
db
lib/backup
lib/banzai
lib/gitlab/background_migration
lib/gitlab/cycle_analytics
lib/gitlab/database
lib/gitlab/import_export
lib/gitlab/project_authorizations
lib/gitlab/sql
lib/system_check
lib/tasks
qa
rubocop
spec
].freeze
def on_send(node)
return if in_allowed_directory?(node)
receiver = node.children[0]
send_name = node.children[1]
first_arg = node.children[2]
if receiver && NOT_ALLOWED.key?(send_name)
# If the rule requires an argument to be given, but none are
# provided, we won't register an offense. This prevents us from
# adding offenses for `project.group`, while still covering
# `Project.group(:name)`.
return if NOT_ALLOWED[send_name] && !first_arg
add_offense(node, location: :selector)
end
end
# Returns true if the node resides in one of the allowed
# directories.
def in_allowed_directory?(node)
path = file_path_for_node(node)
ALLOWED_DIRECTORIES.any? do |directory|
path.start_with?(
File.join(rails_root, directory),
File.join(rails_root, 'ee', directory)
)
end
end
# We can not auto correct code like this, as it requires manual
# refactoring. Instead, we'll just allow the surrounding scope.
#
# Despite this method's presence, you should not use it. This method
# exists to make it possible to allow large chunks of offenses we
# can't fix in the short term. If you are writing new code, follow the
# code reuse guidelines, instead of allowing any new offenses.
def autocorrect(node)
scope = surrounding_scope_of(node)
indent = indentation_of(scope)
lambda do |corrector|
# This prevents us from inserting the same enable/disable comment
# for a method or block that has multiple offenses.
next if allowed_scopes.include?(scope)
corrector.insert_before(
scope.source_range,
"# rubocop: disable #{cop_name}\n#{indent}"
)
corrector.insert_after(
scope.source_range,
"\n#{indent}# rubocop: enable #{cop_name}"
)
allowed_scopes << scope
end
end
def indentation_of(node)
' ' * node.loc.expression.source_line[/\A */].length
end
def surrounding_scope_of(node)
%i[def defs block begin].each do |type|
if (found = node.each_ancestor(type).first)
return found
end
end
end
def allowed_scopes
@allowed_scopes ||= Set.new
end
end
end
end
end
...@@ -5,7 +5,7 @@ module RuboCop ...@@ -5,7 +5,7 @@ module RuboCop
def in_qa_file?(node) def in_qa_file?(node)
path = node.location.expression.source_buffer.name path = node.location.expression.source_buffer.name
path.start_with?(File.join(RuboCop::PathUtil.pwd, 'qa')) path.start_with?(File.join(Dir.pwd, 'qa'))
end end
end end
end end
# Denies the use of ActiveRecord methods outside of configured
# excluded directories
# Directories that allow the use of the denied methods.
# To start we provide a default configuration that matches
# a standard Rails app and enable.
# The default configuration can be overridden by
# providing your own Exclusion list as follows:
# CodeReuse/ActiveRecord:
# Enabled: true
# Exclude:
# - app/models/**/*.rb
# - config/**/*.rb
# - db/**/*.rb
# - lib/tasks/**/*.rb
# - spec/**/*.rb
# - lib/gitlab/**/*.rb
CodeReuse/ActiveRecord:
Exclude:
- app/models/**/*.rb
- config/**/*.rb
- db/**/*.rb
- lib/tasks/**/*.rake
- spec/**/*.rb
- danger/**/*.rb
- lib/backup/**/*.rb
- lib/banzai/**/*.rb
- lib/gitlab/background_migration/**/*.rb
- lib/gitlab/cycle_analytics/**/*.rb
- lib/gitlab/database/**/*.rb
- lib/gitlab/database_importers/common_metrics/importer.rb
- lib/gitlab/import_export/**/*.rb
- lib/gitlab/project_authorizations.rb
- lib/gitlab/sql/**/*.rb
- lib/system_check/**/*.rb
- qa/**/*.rb
- rubocop/**/*.rb
- ee/app/models/**/*.rb
- ee/spec/**/*.rb
- ee/db/fixtures/**/*.rb
- ee/lib/tasks/**/*.rake
- ee/lib/ee/gitlab/background_migration/**/*.rb
...@@ -236,13 +236,16 @@ RSpec.describe Gitlab::Danger::Helper do ...@@ -236,13 +236,16 @@ RSpec.describe Gitlab::Danger::Helper do
'.gitlab/ci/frontend.gitlab-ci.yml' | %i[frontend engineering_productivity] '.gitlab/ci/frontend.gitlab-ci.yml' | %i[frontend engineering_productivity]
'app/models/foo' | [:backend] 'app/models/foo' | [:backend]
'bin/foo' | [:backend] 'bin/foo' | [:backend]
'config/foo' | [:backend] 'config/foo' | [:backend]
'lib/foo' | [:backend] 'lib/foo' | [:backend]
'rubocop/foo' | [:backend] 'rubocop/foo' | [:backend]
'spec/foo' | [:backend] '.rubocop.yml' | [:backend]
'spec/foo/bar' | [:backend] '.rubocop_todo.yml' | [:backend]
'.rubocop_manual_todo.yml' | [:backend]
'spec/foo' | [:backend]
'spec/foo/bar' | [:backend]
'ee/app/foo' | [:backend] 'ee/app/foo' | [:backend]
'ee/bin/foo' | [:backend] 'ee/bin/foo' | [:backend]
......
...@@ -108,7 +108,7 @@ RSpec.describe Key, :mailer do ...@@ -108,7 +108,7 @@ RSpec.describe Key, :mailer do
expect(build(:key, key: 'ssh-rsa an-invalid-key==')).not_to be_valid expect(build(:key, key: 'ssh-rsa an-invalid-key==')).not_to be_valid
end end
where(:factory, :chars, :expected_sections) do where(:factory, :characters, :expected_sections) do
[ [
[:key, ["\n", "\r\n"], 3], [:key, ["\n", "\r\n"], 3],
[:key, [' ', ' '], 3], [:key, [' ', ' '], 3],
...@@ -122,7 +122,7 @@ RSpec.describe Key, :mailer do ...@@ -122,7 +122,7 @@ RSpec.describe Key, :mailer do
let!(:original_fingerprint_sha256) { key.fingerprint_sha256 } let!(:original_fingerprint_sha256) { key.fingerprint_sha256 }
it 'accepts a key with blank space characters after stripping them' do it 'accepts a key with blank space characters after stripping them' do
modified_key = key.key.insert(100, chars.first).insert(40, chars.last) modified_key = key.key.insert(100, characters.first).insert(40, characters.last)
_, content = modified_key.split _, content = modified_key.split
key.update!(key: modified_key) key.update!(key: modified_key)
......
# frozen_string_literal: true
require 'fast_spec_helper'
require 'rubocop'
require_relative '../../../../rubocop/cop/code_reuse/active_record'
RSpec.describe RuboCop::Cop::CodeReuse::ActiveRecord, type: :rubocop do
include CopHelper
subject(:cop) { described_class.new }
it 'flags the use of "where" without any arguments' do
expect_offense(<<~SOURCE)
def foo
User.where
^^^^^ This method can only be used inside an ActiveRecord model: https://gitlab.com/gitlab-org/gitlab-foss/issues/49653
end
SOURCE
end
it 'flags the use of "where" with arguments' do
expect_offense(<<~SOURCE)
def foo
User.where(id: 10)
^^^^^ This method can only be used inside an ActiveRecord model: https://gitlab.com/gitlab-org/gitlab-foss/issues/49653
end
SOURCE
end
it 'does not flag the use of "group" without any arguments' do
expect_no_offenses(<<~SOURCE)
def foo
project.group
end
SOURCE
end
it 'flags the use of "group" with arguments' do
expect_offense(<<~SOURCE)
def foo
project.group(:name)
^^^^^ This method can only be used inside an ActiveRecord model: https://gitlab.com/gitlab-org/gitlab-foss/issues/49653
end
SOURCE
end
it 'does not flag the use of ActiveRecord models in a model' do
path = rails_root_join('app', 'models', 'foo.rb').to_s
expect_no_offenses(<<~SOURCE, path)
def foo
project.group(:name)
end
SOURCE
end
it 'does not flag the use of ActiveRecord models in a spec' do
path = rails_root_join('spec', 'foo_spec.rb').to_s
expect_no_offenses(<<~SOURCE, path)
def foo
project.group(:name)
end
SOURCE
end
it 'does not flag the use of ActiveRecord models in a background migration' do
path = rails_root_join('lib', 'gitlab', 'background_migration', 'foo.rb').to_s
expect_no_offenses(<<~SOURCE, path)
def foo
project.group(:name)
end
SOURCE
end
it 'does not flag the use of ActiveRecord models in lib/gitlab/database' do
path = rails_root_join('lib', 'gitlab', 'database', 'foo.rb').to_s
expect_no_offenses(<<~SOURCE, path)
def foo
project.group(:name)
end
SOURCE
end
it 'autocorrects offenses in instance methods by allowing them' do
corrected = autocorrect_source(<<~SOURCE)
def foo
User.where
end
SOURCE
expect(corrected).to eq(<<~SOURCE)
# rubocop: disable CodeReuse/ActiveRecord
def foo
User.where
end
# rubocop: enable CodeReuse/ActiveRecord
SOURCE
end
it 'autocorrects offenses in class methods by allowing them' do
corrected = autocorrect_source(<<~SOURCE)
def self.foo
User.where
end
SOURCE
expect(corrected).to eq(<<~SOURCE)
# rubocop: disable CodeReuse/ActiveRecord
def self.foo
User.where
end
# rubocop: enable CodeReuse/ActiveRecord
SOURCE
end
it 'autocorrects offenses in blocks by allowing them' do
corrected = autocorrect_source(<<~SOURCE)
get '/' do
User.where
end
SOURCE
expect(corrected).to eq(<<~SOURCE)
# rubocop: disable CodeReuse/ActiveRecord
get '/' do
User.where
end
# rubocop: enable CodeReuse/ActiveRecord
SOURCE
end
end
# frozen_string_literal: true # frozen_string_literal: true
require 'fast_spec_helper' require 'fast_spec_helper'
require 'rubocop'
require_relative '../../../../rubocop/cop/rspec/be_success_matcher' require_relative '../../../../rubocop/cop/rspec/be_success_matcher'
RSpec.describe RuboCop::Cop::RSpec::BeSuccessMatcher, type: :rubocop do RSpec.describe RuboCop::Cop::RSpec::BeSuccessMatcher, type: :rubocop do
......
# frozen_string_literal: true
require 'tempfile'
# This module provides methods that make it easier to test Cops.
module CopHelper
extend RSpec::SharedContext
let(:ruby_version) { 2.4 }
let(:rails_version) { false }
def inspect_source_file(source)
Tempfile.open('tmp') { |f| inspect_source(source, f) }
end
def inspect_source(source, file = nil)
RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {}
RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {}
processed_source = parse_source(source, file)
raise 'Error parsing example code' unless processed_source.valid_syntax?
_investigate(cop, processed_source)
end
def parse_source(source, file = nil)
if file&.respond_to?(:write)
file.write(source)
file.rewind
file = file.path
end
RuboCop::ProcessedSource.new(source, ruby_version, file)
end
def autocorrect_source_file(source)
Tempfile.open('tmp') { |f| autocorrect_source(source, f) }
end
def autocorrect_source(source, file = nil)
RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {}
RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {}
cop.instance_variable_get(:@options)[:auto_correct] = true
processed_source = parse_source(source, file)
_investigate(cop, processed_source)
@last_corrector.rewrite
end
def _investigate(cop, processed_source)
team = RuboCop::Cop::Team.new([cop], nil, raise_error: true)
report = team.investigate(processed_source)
@last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source)
report.offenses
end
end
module RuboCop
module Cop
# Monkey-patch Cop for tests to provide easy access to messages and
# highlights.
# this file is an exact copy of source except for this line
# where we change to the new Base class defined in rubocop and skirt around our superclass mismatch for class Cop
# when running a rubocop spec.
class Base
def messages
offenses.sort.map(&:message)
end
def highlights
offenses.sort.map { |o| o.location.source }
end
end
end
end
...@@ -5,7 +5,8 @@ require_relative "helpers/stub_metrics" ...@@ -5,7 +5,8 @@ require_relative "helpers/stub_metrics"
require_relative "helpers/stub_object_storage" require_relative "helpers/stub_object_storage"
require_relative "helpers/stub_env" require_relative "helpers/stub_env"
require_relative "helpers/fast_rails_root" require_relative "helpers/fast_rails_root"
require 'rubocop/rspec/support'
require_relative 'rubocop_patch'
RSpec.configure do |config| RSpec.configure do |config|
config.mock_with :rspec config.mock_with :rspec
......
# frozen_string_literal: true
# There is an issue between rubocop versions 0.86 and 0.87 (verified by testing locally)
# where the monkey patching in cop_helper is referencing class Cop and should really be referencing class Base instead
# the gem's version of the cop_helper causes this issue when testing a rubocop cop locally and in CI
# The only difference in this file as compared to gem source file is that we include our own cop_helper instead
# which is a direct copy with a fix for the monkey patching part.
# Doing this, resolves the issue.
# Ideally we should move away from using the cop_helper at all as is the direction of rubocop as seen
# here - https://github.com/rubocop-hq/rubocop/issues/8003
# more info https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46477
require_relative 'helpers/cop_helper'
require 'rubocop/rspec/host_environment_simulation_helper'
require 'rubocop/rspec/shared_contexts'
require 'rubocop/rspec/expect_offense'
RSpec.configure do |config|
config.include CopHelper
config.include HostEnvironmentSimulatorHelper
end
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'overcommit' gem 'overcommit'
gem 'gitlab-styles', '~> 4.3.0', require: false gem 'gitlab-styles', '~> 5.0.0', require: false
gem 'scss_lint', '~> 0.56.0', require: false gem 'scss_lint', '~> 0.56.0', require: false
gem 'haml_lint', '~> 0.34.0', require: false gem 'haml_lint', '~> 0.34.0', require: false
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
activesupport (6.0.3) activesupport (6.0.3.4)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
minitest (~> 5.1) minitest (~> 5.1)
tzinfo (~> 1.1) tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2) zeitwerk (~> 2.2, >= 2.2.2)
ast (2.4.0) ast (2.4.1)
childprocess (3.0.0) childprocess (3.0.0)
concurrent-ruby (1.1.6) concurrent-ruby (1.1.7)
ffi (1.12.2) ffi (1.12.2)
gitlab-styles (4.3.0) gitlab-styles (5.0.0)
rubocop (~> 0.82.0) rubocop (~> 0.89.1)
rubocop-gitlab-security (~> 0.1.0) rubocop-gitlab-security (~> 0.1.0)
rubocop-performance (~> 1.5.2) rubocop-performance (~> 1.8.1)
rubocop-rails (~> 2.5) rubocop-rails (~> 2.8)
rubocop-rspec (~> 1.36) rubocop-rspec (~> 1.44)
haml (5.1.2) haml (5.1.2)
temple (>= 0.8.0) temple (>= 0.8.0)
tilt tilt
...@@ -25,42 +25,47 @@ GEM ...@@ -25,42 +25,47 @@ GEM
rainbow rainbow
rubocop (>= 0.50.0) rubocop (>= 0.50.0)
sysexits (~> 1.1) sysexits (~> 1.1)
i18n (1.8.2) i18n (1.8.5)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
iniparse (1.5.0) iniparse (1.5.0)
jaro_winkler (1.5.4) minitest (5.14.2)
minitest (5.11.3)
overcommit (0.53.0) overcommit (0.53.0)
childprocess (>= 0.6.3, < 4) childprocess (>= 0.6.3, < 4)
iniparse (~> 1.4) iniparse (~> 1.4)
parallel (1.19.1) parallel (1.19.2)
parser (2.7.1.2) parser (2.7.2.0)
ast (~> 2.4.0) ast (~> 2.4.1)
rack (2.0.9) rack (2.2.3)
rainbow (3.0.0) rainbow (3.0.0)
rake (12.3.3) rake (12.3.3)
rb-fsevent (0.10.2) rb-fsevent (0.10.2)
rb-inotify (0.9.10) rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2) ffi (>= 0.5.0, < 2)
regexp_parser (1.8.2)
rexml (3.2.4) rexml (3.2.4)
rubocop (0.82.0) rubocop (0.89.1)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 2.7.0.1) parser (>= 2.7.1.1)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml rexml
rubocop-ast (>= 0.3.0, < 1.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0) unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.8.0)
parser (>= 2.7.1.5)
rubocop-gitlab-security (0.1.1) rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51) rubocop (>= 0.51)
rubocop-performance (1.5.2) rubocop-performance (1.8.1)
rubocop (>= 0.71.0) rubocop (>= 0.87.0)
rubocop-rails (2.5.2) rubocop-ast (>= 0.4.0)
activesupport rubocop-rails (2.8.1)
activesupport (>= 4.2.0)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 0.72.0) rubocop (>= 0.87.0)
rubocop-rspec (1.37.0) rubocop-rspec (1.44.1)
rubocop (>= 0.68.1) rubocop (~> 0.87)
rubocop-ast (>= 0.7.1)
ruby-progressbar (1.10.1) ruby-progressbar (1.10.1)
sass (3.5.5) sass (3.5.5)
sass-listen (~> 4.0.0) sass-listen (~> 4.0.0)
...@@ -77,13 +82,13 @@ GEM ...@@ -77,13 +82,13 @@ GEM
tzinfo (1.2.7) tzinfo (1.2.7)
thread_safe (~> 0.1) thread_safe (~> 0.1)
unicode-display_width (1.7.0) unicode-display_width (1.7.0)
zeitwerk (2.3.0) zeitwerk (2.4.1)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
gitlab-styles (~> 4.3.0) gitlab-styles (~> 5.0.0)
haml_lint (~> 0.34.0) haml_lint (~> 0.34.0)
overcommit overcommit
scss_lint (~> 0.56.0) scss_lint (~> 0.56.0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment