Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-09-22 13:39:34 +00:00
parent 2fa173410a
commit e23c409e66
112 changed files with 7748 additions and 570 deletions

View File

@ -1,4 +1,4 @@
<!-- Actionable insights must recommend an action that needs to take place. An actionable insight both defines the insight and clearly calls out action or next step required to improve based on the result of the research observation or data. Actionable insights are tracked over time and will include follow-up. Please follow the tasks outlined in this issue for best results. Learn more in the handbook here: https://about.gitlab.com/handbook/engineering/ux/ux-research-training/research-insights/#actionable-insights
<!-- Actionable insights must recommend an action that needs to take place. An actionable insight both defines the insight and clearly calls out action or next step required to improve based on the result of the research observation or data. Actionable insights are tracked over time and will include follow-up. Please follow the tasks outlined in this issue for best results. Learn more in the handbook here: https://about.gitlab.com/handbook/product/ux/ux-research-training/research-insights/#actionable-insights
This issue template is for an actionable insight that requires further exploration.-->

View File

@ -1,4 +1,4 @@
<!-- Actionable insights must recommend an action that needs to take place. An actionable insight both defines the insight and clearly calls out action or next step required to improve based on the result of the research observation or data. Actionable insights are tracked over time and will include follow-up. Please follow the tasks outlined in this issue for best results. Learn more in the handbook here: https://about.gitlab.com/handbook/engineering/ux/ux-research-training/research-insights/#actionable-insights
<!-- Actionable insights must recommend an action that needs to take place. An actionable insight both defines the insight and clearly calls out action or next step required to improve based on the result of the research observation or data. Actionable insights are tracked over time and will include follow-up. Please follow the tasks outlined in this issue for best results. Learn more in the handbook here: https://about.gitlab.com/handbook/product/ux/ux-research-training/research-insights/#actionable-insights
This issue template is for an actionable insight that requires a change in the product.-->

View File

@ -37,7 +37,7 @@ Personas are described at https://about.gitlab.com/handbook/marketing/product-ma
<!-- What is the single user experience workflow this problem addresses?
For example, "The user should be able to use the UI/API/.gitlab-ci.yml with GitLab to <perform a specific task>"
https://about.gitlab.com/handbook/engineering/ux/ux-research-training/user-story-mapping/ -->
https://about.gitlab.com/handbook/product/ux/ux-research-training/user-story-mapping/ -->
### Proposal

View File

@ -26,7 +26,7 @@
<!-- #### TODO Checklist
Consider adding a checklist in order to keep track of what stage the research is up to. Some possible checklist templates are here:
https://about.gitlab.com/handbook/engineering/ux/ux-research-training/templates-resources-for-research-studies/#checklists
https://about.gitlab.com/handbook/product/ux/ux-research-training/templates-resources-for-research-studies/#checklists
-->
/label ~"workflow::solution validation"

View File

@ -1,6 +1,6 @@
<!-- A majority of the work designers do will be on themes in the (Now) Next 1-3 milestone column. These themes are comprised of high-confidence outcomes and validated needs. The UX theme issue is where collaboration should occur, including plans and discussion on subthemes, research, and design feedback. Related issues for design exploration and solution validation should stem from the theme issue.
One of the advantages of working with UX themes is that it allows us to think and design holistically by designing the theme as a whole as opposed to a single issue at a time trying to piece them together as you go. For more details please refer to this section of the handbook when creating UX Themes: https://about.gitlab.com/handbook/engineering/ux/product-design/ux-roadmaps/#theme-structure -->
One of the advantages of working with UX themes is that it allows us to think and design holistically by designing the theme as a whole as opposed to a single issue at a time trying to piece them together as you go. For more details please refer to this section of the handbook when creating UX Themes: https://about.gitlab.com/handbook/product/ux/product-design/ux-roadmaps/#theme-structure -->
### UX Theme
<!-- A theme is written as a statement that combines the beneficiary, their need, and the expected outcome when the work is delivered. Well-defined statements are concise without sacrificing the substance of the theme so that anyone can understand it at a glance. (For instance; Reduce the effort for security teams to identify and escalate business-critical risks)
@ -37,7 +37,7 @@ One of the advantages of working with UX themes is that it allows us to think an
#### Confidence
<!-- How well do we understand the user's problem and their need? Refer to https://about.gitlab.com/handbook/engineering/ux/product-design/ux-roadmaps/#confidence to assess confidence -->
<!-- How well do we understand the user's problem and their need? Refer to https://about.gitlab.com/handbook/product/ux/product-design/ux-roadmaps/#confidence to assess confidence -->
| Confidence | Research |
@ -55,7 +55,7 @@ Note: This is not a backlog. If the subthemes can not be delivered in the theme
Note: if feature issues already exist then you can add them to this table. Keep in mind that subthemes require validation if they are assumptive
Refer to https://about.gitlab.com/handbook/engineering/ux/product-designer/#ux-issue-weights for calculating UX weights.
Refer to https://about.gitlab.com/handbook/product/ux/product-designer/#ux-issue-weights for calculating UX weights.
-->
| Issue | UX Weight |

View File

@ -26,7 +26,8 @@ inherit_mode:
- Exclude
AllCops:
TargetRubyVersion: 2.7
# Target the current Ruby version. For example, "2.7" or "3.0".
TargetRubyVersion: <%= RUBY_VERSION[/^\d+\.\d+/, 0] %>
TargetRailsVersion: 6.0
Exclude:
- 'vendor/**/*'

View File

@ -203,7 +203,7 @@ gem 'acts-as-taggable-on', '~> 9.0'
# Background jobs
gem 'sidekiq', '~> 6.4.0'
gem 'sidekiq-cron', '~> 1.4.0'
gem 'redis-namespace', '~> 1.8.1'
gem 'redis-namespace', '~> 1.9.0'
gem 'gitlab-sidekiq-fetcher', '0.8.0', require: 'sidekiq-reliable-fetch'
# Cron Parser

View File

@ -1132,8 +1132,8 @@ GEM
actionpack (>= 5, < 8)
redis-rack (>= 2.1.0, < 3)
redis-store (>= 1.1.0, < 2)
redis-namespace (1.8.1)
redis (>= 3.0.4)
redis-namespace (1.9.0)
redis (>= 4)
redis-rack (2.1.4)
rack (>= 2.0.8, < 3)
redis-store (>= 1.2, < 2)
@ -1736,7 +1736,7 @@ DEPENDENCIES
recaptcha (~> 4.11)
redis (~> 4.7.0)
redis-actionpack (~> 5.3.0)
redis-namespace (~> 1.8.1)
redis-namespace (~> 1.9.0)
request_store (~> 1.5)
responders (~> 3.0)
retriable (~> 3.1.2)

View File

@ -22,6 +22,7 @@ const updateLineNumbersOnBlobPermalinks = (linksToUpdate) => {
};
function BlobLinePermalinkUpdater(blobContentHolder, lineNumberSelector, elementsToUpdate) {
if (!blobContentHolder) return;
const updateBlameAndBlobPermalinkCb = () => {
// Wait for the hash to update from the LineHighlighter callback
setTimeout(() => {

View File

@ -1,4 +1,4 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { GlDropdown, GlDropdownItem, GlListbox } from '@gitlab/ui';
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
@ -31,6 +31,28 @@ export function initListbox(el, { onChange } = {}) {
},
},
render(h) {
if (gon.features?.glListboxForSortDropdowns) {
return h(GlListbox, {
props: {
items,
right,
selected: this.selected,
toggleText: this.text,
},
class: className,
on: {
select: (selectedValue) => {
this.selected = selectedValue;
const selectedItem = items.find(({ value }) => value === selectedValue);
if (typeof onChange === 'function') {
onChange(selectedItem);
}
},
},
});
}
return h(
GlDropdown,
{

View File

@ -4,6 +4,8 @@ import { __ } from '~/locale';
import createFlash from '~/flash';
import getRefMixin from '~/repository/mixins/get_ref';
import initSourcegraph from '~/sourcegraph';
import ShortcutsBlob from '~/behaviors/shortcuts/shortcuts_blob';
import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater';
import { updateElementsVisibility } from '../utils/dom';
import blobControlsQuery from '../queries/blob_controls.query.graphql';
@ -84,6 +86,33 @@ export default {
},
blobInfo() {
initSourcegraph();
this.$nextTick(() => {
this.initShortcuts();
this.initLinksUpdate();
});
},
},
methods: {
initShortcuts() {
const fileBlobPermalinkUrlElement = document.querySelector(
'.js-data-file-blob-permalink-url',
);
const fileBlobPermalinkUrl =
fileBlobPermalinkUrlElement && fileBlobPermalinkUrlElement.getAttribute('href');
// eslint-disable-next-line no-new
new ShortcutsBlob({
skipResetBindings: true,
fileBlobPermalinkUrl,
fileBlobPermalinkUrlElement,
});
},
initLinksUpdate() {
// eslint-disable-next-line no-new
new BlobLinePermalinkUpdater(
document.querySelector('.tree-holder'),
'.file-line-num[data-line-number], .file-line-num[data-line-number] *',
document.querySelectorAll('.js-data-file-blob-permalink-url, .js-blob-blame-link'),
);
},
},
};
@ -99,6 +128,7 @@ export default {
data-testid="blame"
:href="blobInfo.blamePath"
:class="$options.buttonClassList"
class="js-blob-blame-link"
>
{{ $options.i18n.blame }}
</gl-button>

View File

@ -3,6 +3,7 @@ import { GlBadge } from '@gitlab/ui';
import { s__ } from '~/locale';
import axios from '~/lib/utils/axios_utils';
import { joinPaths } from '~/lib/utils/url_utility';
import { helpPagePath } from '~/helpers/help_page_helper';
const STATUS_TYPES = {
SUCCESS: 'success',
@ -10,6 +11,8 @@ const STATUS_TYPES = {
DANGER: 'danger',
};
const UPGRADE_DOCS_URL = helpPagePath('update/index');
export default {
name: 'GitlabVersionCheck',
components: {
@ -58,11 +61,17 @@ export default {
});
},
},
UPGRADE_DOCS_URL,
};
</script>
<template>
<gl-badge v-if="status" class="version-check-badge" :variant="status" :size="size">{{
title
}}</gl-badge>
<gl-badge
v-if="status"
:href="$options.UPGRADE_DOCS_URL"
class="version-check-badge"
:variant="status"
:size="size"
>{{ title }}</gl-badge
>
</template>

View File

@ -25,6 +25,7 @@ import {
import workItemQuery from '../graphql/work_item.query.graphql';
import workItemDatesSubscription from '../graphql/work_item_dates.subscription.graphql';
import workItemTitleSubscription from '../graphql/work_item_title.subscription.graphql';
import workItemAssigneesSubscription from '../graphql/work_item_assignees.subscription.graphql';
import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
import updateWorkItemTaskMutation from '../graphql/update_work_item_task.mutation.graphql';
@ -130,6 +131,17 @@ export default {
return !this.workItemDueDate;
},
},
{
document: workItemAssigneesSubscription,
variables() {
return {
issuableId: this.workItemId,
};
},
skip() {
return !this.workItemAssignees;
},
},
],
},
},

View File

@ -0,0 +1,20 @@
subscription issuableAssignees($issuableId: IssuableID!) {
issuableAssigneesUpdated(issuableId: $issuableId) {
... on WorkItem {
id
widgets {
... on WorkItemWidgetAssignees {
assignees {
nodes {
avatarUrl
id
name
username
webUrl
}
}
}
}
}
}
}

View File

@ -25,7 +25,7 @@ module Registrations
members = current_user.members
if members.count == 1 && members.last.source.present?
if registering_from_invite?(members)
redirect_to members_activity_path(members), notice: helpers.invite_accepted_notice(members.last)
else
redirect_to path_for_signed_in_user(current_user)
@ -37,6 +37,10 @@ module Registrations
private
def registering_from_invite?(members)
members.count == 1 && members.last.source.present?
end
def require_current_user
return redirect_to new_user_registration_path unless current_user
end

View File

@ -183,7 +183,7 @@ class RegistrationsController < Devise::RegistrationsController
def resource
@resource ||= Users::RegistrationsBuildService
.new(current_user, sign_up_params.merge({ skip_confirmation: skip_email_confirmation? }))
.new(current_user, sign_up_params.merge({ skip_confirmation: registered_with_invite_email? }))
.execute
end
@ -191,7 +191,7 @@ class RegistrationsController < Devise::RegistrationsController
@devise_mapping ||= Devise.mappings[:user]
end
def skip_email_confirmation?
def registered_with_invite_email?
invite_email = session.delete(:invite_email)
sign_up_params[:email] == invite_email

View File

@ -1,60 +0,0 @@
# frozen_string_literal: true
module Mutations
module WorkItems
# TODO: Deprecate in favor of using WorkItemUpdate. See https://gitlab.com/gitlab-org/gitlab/-/issues/366300
class UpdateWidgets < BaseMutation
graphql_name 'WorkItemUpdateWidgets'
description "Updates the attributes of a work item's widgets by global ID." \
" Available only when feature flag `work_items` is enabled."
include Mutations::SpamProtection
authorize :update_work_item
argument :id, ::Types::GlobalIDType[::WorkItem],
required: true,
description: 'Global ID of the work item.'
argument :description_widget, ::Types::WorkItems::Widgets::DescriptionInputType,
required: false,
description: 'Input for description widget.'
field :work_item, Types::WorkItemType,
null: true,
description: 'Updated work item.'
def resolve(id:, **widget_attributes)
work_item = authorized_find!(id: id)
unless work_item.project.work_items_feature_flag_enabled?
return { errors: ['`work_items` feature flag disabled for this project'] }
end
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
::WorkItems::UpdateService.new(
project: work_item.project,
current_user: current_user,
# Cannot use prepare to use `.to_h` on each input due to
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87472#note_945199865
widget_params: widget_attributes.transform_values { |values| values.to_h },
spam_params: spam_params
).execute(work_item)
check_spam_action_response!(work_item)
{
work_item: work_item.valid? ? work_item : nil,
errors: errors_on_object(work_item)
}
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -146,7 +146,6 @@ module Types
mount_mutation Mutations::WorkItems::Delete, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::DeleteTask, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::Update, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::UpdateWidgets, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::UpdateTask, alpha: { milestone: '15.1' }
mount_mutation Mutations::SavedReplies::Create
mount_mutation Mutations::SavedReplies::Update

View File

@ -126,8 +126,8 @@ module GroupsHelper
group.root? && current_user.can?(:admin_setting_to_allow_project_access_token_creation, group)
end
def show_thanks_for_purchase_alert?
params.key?(:purchased_quantity) && params[:purchased_quantity].to_i > 0
def show_thanks_for_purchase_alert?(quantity)
quantity.to_i > 0
end
def project_list_sort_by

View File

@ -106,6 +106,8 @@ module Users
def build_user_params_for_non_admin
@user_params = params.slice(*signup_params)
# if skip_confirmation is set to `true`, devise will set confirmed_at
# see: https://github.com/heartcombo/devise/blob/8593801130f2df94a50863b5db535c272b00efe1/lib/devise/models/confirmable.rb#L156
@user_params[:skip_confirmation] = skip_user_confirmation_email_from_setting if assign_skip_confirmation_from_settings?
@user_params[:name] = fallback_name if use_fallback_name?
end

View File

@ -3,9 +3,6 @@
- @skip_current_level_breadcrumb = true
- add_page_specific_style 'page_bundles/group'
- if show_thanks_for_purchase_alert?
= render_if_exists 'shared/thanks_for_purchase_alert', plan_title: plan_title, quantity: params[:purchased_quantity].to_i
= render_if_exists 'shared/qrtly_reconciliation_alert', group: @group
= render_if_exists 'shared/free_user_cap_alert', source: @group

View File

@ -1,6 +1,6 @@
- return unless show_version_check?
.gl-display-flex.gl-flex-direction-column.gl-px-4.gl-py-3
%a{ class: 'gl-display-flex! gl-flex-direction-column gl-px-4! gl-py-3! gl-line-height-24!', href: help_page_path('update/index'), 'data-testid': 'gitlab-version-container' }
%span
= s_("VersionCheck|Your GitLab Version")
= emoji_icon('rocket')

View File

@ -1,6 +1,7 @@
%ul
- if current_user_menu?(:help)
= render 'layouts/header/gitlab_version'
%li
= render 'layouts/header/gitlab_version'
= render_if_exists 'layouts/header/help_dropdown/cross_stage_fdm'
= render 'layouts/header/whats_new_dropdown_item'
%li

View File

@ -134,10 +134,6 @@ module ApplicationWorker
@log_bulk_perform_async = true
end
def queue_size
Sidekiq::Queue.new(queue).size
end
def bulk_perform_async(args_list)
if log_bulk_perform_async?
Sidekiq.logger.info('class' => self.name, 'args_list' => args_list, 'args_list_count' => args_list.length, 'message' => 'Inserting multiple jobs')

View File

@ -276,6 +276,7 @@ module Gitlab
config.assets.precompile << "page_bundles/ide.css"
config.assets.precompile << "page_bundles/import.css"
config.assets.precompile << "page_bundles/incident_management_list.css"
config.assets.precompile << "page_bundles/issues_analytics.css"
config.assets.precompile << "page_bundles/issues_list.css"
config.assets.precompile << "page_bundles/issues_show.css"
config.assets.precompile << "page_bundles/jira_connect.css"

View File

@ -0,0 +1,8 @@
---
name: gl_listbox_for_sort_dropdowns
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98363
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/364715
milestone: '15.5'
type: development
group: group::foundations
default_enabled: false

View File

@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367570
milestone: '15.3'
type: development
group: group::authentication and authorization
default_enabled: false
default_enabled: true

View File

@ -0,0 +1,8 @@
---
name: present_groups_select_all
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93633
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/370306
milestone: '15.5'
type: development
group: group::workspace
default_enabled: false

View File

@ -5,7 +5,7 @@ def feature_mr?
end
DOCUMENTATION_UPDATE_MISSING = <<~MSG
~"feature::addition" and ~"feature::enhancement" merge requests normally have a documentation change. Consider adding a documentation update or confirming the documentation plan with the [Technical Writer counterpart](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments).
~"feature::addition" and ~"feature::enhancement" merge requests normally have a documentation change. Consider adding a documentation update or confirming the documentation plan with the [Technical Writer counterpart](https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments).
For more information, see:

View File

@ -1,7 +1,7 @@
---
stage: none
group: none
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-development-guidelines"
---
# Deprecations by version

View File

@ -1,7 +1,7 @@
---
stage: none
group: none
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-development-guidelines"
---
# Removals by version

View File

@ -38,9 +38,15 @@ full list of reference architectures, see
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->
@ -2319,9 +2325,15 @@ services where applicable):
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->

View File

@ -38,9 +38,15 @@ full list of reference architectures, see
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->
@ -2322,9 +2328,15 @@ services where applicable):
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->

View File

@ -31,9 +31,15 @@ For a full list of reference architectures, see
| NFS server (non-Gitaly) | 1 | 4 vCPU, 3.6 GB memory | `n1-highcpu-4` | `c5.xlarge` | `F4s v2` |
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run as reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run as reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
<!-- markdownlint-enable MD029 -->
@ -1026,8 +1032,13 @@ services where applicable):
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
<!-- markdownlint-enable MD029 -->

View File

@ -47,9 +47,15 @@ For a full list of reference architectures, see
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->
@ -2283,9 +2289,15 @@ services where applicable):
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->

View File

@ -38,9 +38,15 @@ full list of reference architectures, see
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->
@ -2339,9 +2345,15 @@ services where applicable):
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->

View File

@ -44,9 +44,15 @@ costly-to-operate environment by using the
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->
@ -2257,9 +2263,15 @@ services where applicable):
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
<!-- markdownlint-disable MD029 -->
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work. However, Amazon Aurora is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud Load Balancing](https://cloud.google.com/load-balancing) and [Amazon Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) are known to work.
4. Should be run on reputable Cloud Provider or Self Managed solutions. More information can be found in the [Configure the object storage](#configure-the-object-storage) section.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
<!-- markdownlint-enable MD029 -->

View File

@ -366,6 +366,7 @@ Additionally, the following cloud provider services are validated and supported
The following specific cloud provider services have been found to have issues in terms of either functionality or performance. As such, they either have caveats that should be considered or are not recommended:
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is incompatible. See [14.4.0](../../update/index.md#1440) for more details.
- [Azure Blob Storage](https://azure.microsoft.com/en-gb/services/storage/blobs/) has been found to have performance limits that can impact production use at certain times. For larger Reference Architectures the service may not be sufficient for production use and an alternative is recommended for use instead.
- [Azure Database for PostgreSQL Server](https://azure.microsoft.com/en-gb/services/postgresql/#overview) (Single / Flexible) is not recommended for use due to notable performance issues or missing functionality.

View File

@ -972,37 +972,7 @@ License.select(&TYPE).each(&:destroy!)
### Registry Disk Space Usage by Project
As a GitLab administrator, you may want to reduce disk space consumption.
A common culprit is Docker Registry images that are no longer in use. To find
the storage broken down by each project, run the following in the
[GitLab Rails console](../operations/rails_console.md):
```ruby
projects_and_size = [["project_id", "creator_id", "registry_size_bytes", "project path"]]
# You need to specify the projects that you want to look through. You can get these in any manner.
projects = Project.last(100)
projects.each do |p|
project_total_size = 0
container_repositories = p.container_repositories
container_repositories.each do |c|
c.tags.each do |t|
project_total_size = project_total_size + t.total_size unless t.total_size.nil?
end
end
if project_total_size > 0
projects_and_size << [p.project_id, p.creator.id, project_total_size, p.full_path]
end
end
# projects_and_size is filled out now
# maybe print it as comma separated output?
projects_and_size.each do |ps|
puts "%s,%s,%s,%s" % ps
end
```
Find this content in the [Container Registry troubleshooting documentation](../packages/container_registry.md#registry-disk-space-usage-by-project).
### Run the Cleanup policy now

View File

@ -1,7 +1,7 @@
---
stage: Ecosystem
group: Integrations
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# GraphQL API **(FREE)**

View File

@ -5859,32 +5859,6 @@ Input type: `WorkItemUpdateTaskInput`
| <a id="mutationworkitemupdatetasktask"></a>`task` | [`WorkItem`](#workitem) | Updated task. |
| <a id="mutationworkitemupdatetaskworkitem"></a>`workItem` | [`WorkItem`](#workitem) | Updated work item. |
### `Mutation.workItemUpdateWidgets`
Updates the attributes of a work item's widgets by global ID. Available only when feature flag `work_items` is enabled.
WARNING:
**Introduced** in 15.1.
This feature is in Alpha. It can be changed or removed at any time.
Input type: `WorkItemUpdateWidgetsInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationworkitemupdatewidgetsclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationworkitemupdatewidgetsdescriptionwidget"></a>`descriptionWidget` | [`WorkItemWidgetDescriptionInput`](#workitemwidgetdescriptioninput) | Input for description widget. |
| <a id="mutationworkitemupdatewidgetsid"></a>`id` | [`WorkItemID!`](#workitemid) | Global ID of the work item. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationworkitemupdatewidgetsclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationworkitemupdatewidgetserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationworkitemupdatewidgetsworkitem"></a>`workItem` | [`WorkItem`](#workitem) | Updated work item. |
## Connections
Some types in our schema are `Connection` types - they represent a paginated

View File

@ -100,7 +100,7 @@ When the design is ready, _before_ starting its implementation:
- Share design specifications in the related issue, preferably through a [Figma link](https://help.figma.com/hc/en-us/articles/360040531773-Share-Files-with-anyone-using-Link-Sharing#copy-link)
link or [GitLab Designs feature](../../user/project/issues/design_management.md).
See [when you should use each tool](https://about.gitlab.com/handbook/engineering/ux/product-designer/#deliver).
See [when you should use each tool](https://about.gitlab.com/handbook/product/ux/product-designer/#deliver).
- Document user flow and states (for example, using [Mermaid flowcharts in Markdown](../../user/markdown.md#mermaid)).
- Document animations and transitions.
- Document responsive behaviors.

View File

@ -79,7 +79,7 @@ In these cases, use the following workflow:
- [Frontend](https://about.gitlab.com/handbook/engineering/frontend/)
- [Backend](https://about.gitlab.com/handbook/engineering/)
- [Database](https://about.gitlab.com/handbook/engineering/development/database/)
- [User Experience (UX)](https://about.gitlab.com/handbook/engineering/ux/)
- [User Experience (UX)](https://about.gitlab.com/handbook/product/ux/)
- [Security](https://about.gitlab.com/handbook/engineering/security/)
- [Quality](https://about.gitlab.com/handbook/engineering/quality/)
- [Engineering Productivity](https://about.gitlab.com/handbook/engineering/quality/engineering-productivity/)

View File

@ -2,7 +2,7 @@
type: reference, dev
stage: none
group: Development
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-development-guidelines"
---
# GraphQL

View File

@ -2,7 +2,7 @@
type: reference, dev
stage: Create
group: Code Review
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-development-guidelines"
---
# Merge request concepts

View File

@ -62,6 +62,8 @@ The test mappings contain a map of each source files to a list of test files whi
In the `detect-tests` job, we use this mapping to identify the minimal tests needed for the current merge request.
Later on in [the `rspec fail-fast` job](#fail-fast-job-in-merge-request-pipelines), we run the minimal tests needed for the current merge request.
#### Exceptional cases
In addition, there are a few circumstances where we would always run the full RSpec tests:
@ -97,18 +99,6 @@ label is set on the MR. The goal is to reduce the CI/CD minutes consumed by fork
See the [experiment issue](https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1170).
## Faster feedback when reverting merge requests
When you need to revert a merge request, to get accelerated feedback, you can add the `~pipeline:revert` label to your merge request.
When this label is assigned, the following steps of the CI/CD pipeline are skipped:
- The `e2e:package-and-test` job.
- The `rspec:undercoverage` job.
- The entire [Review Apps process](testing_guide/review_apps.md).
Apply the label to the merge request, and run a new pipeline for the MR.
## Fail-fast job in merge request pipelines
To provide faster feedback when a merge request breaks existing tests, we are experimenting with a
@ -155,6 +145,18 @@ merge request. This prevents `rspec fail-fast` duration from exceeding the avera
This number can be overridden by setting a CI/CD variable named `RSPEC_FAIL_FAST_TEST_FILE_COUNT_THRESHOLD`.
## Faster feedback when reverting merge requests
When you need to revert a merge request, to get accelerated feedback, you can add the `~pipeline:revert` label to your merge request.
When this label is assigned, the following steps of the CI/CD pipeline are skipped:
- The `e2e:package-and-test` job.
- The `rspec:undercoverage` job.
- The entire [Review Apps process](testing_guide/review_apps.md).
Apply the label to the merge request, and run a new pipeline for the MR.
## Test jobs
We have dedicated jobs for each [testing level](testing_guide/testing_levels.md) and each job runs depending on the

View File

@ -2,7 +2,7 @@
type: reference, dev
stage: none
group: Development
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-development-guidelines"
description: "GitLab development guidelines - testing best practices."
---

View File

@ -150,8 +150,27 @@ of widgets.
In order to customize each WIT with corresponding active widgets we will need a data
structure to map each WIT to specific widgets.
The intent is for work item types to be highly configurable, both by GitLab for
implementing various work item schemes for customers (an opinionated GitLab
workflow, or SAFe 5, etc), and eventually for customers to customize their own
workflows.
In this case, a work item scheme would be defined as a set of types with
certain characteristics (some widgets enabled, others not), such as an Epic,
Story, Bug, and Task, etc.
As we're building a new work item architecture, we want to build the ability to
define these various types in a very flexible manner. Having GitLab use
this system first (without introducing customer customization) allows us to
better build out the initial system.
NOTE:
The exact structure of the WITs widgets metadata is still to be defined.
Currently work item's `base_type` is used to define static mapping of what
widgets are available for each type (current status), this definition should be
rather stored in database table. The exact structure of the WIT widgets
metadata is still to be defined. `base_type` was added to help converting other
types of resources (requirements and incidents) into work items. Eventually (when
these resources become regular work items), `base_type` will be removed.
### Custom work item types

View File

@ -3,7 +3,7 @@ comments: false
type: index, dev
stage: none
group: Development
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-development-guidelines"
description: "Development Guidelines: learn about workspace when developing GitLab."
---

View File

@ -1,7 +1,7 @@
---
stage: Data Stores
group: Global Search
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: drawer
source: /doc/user/search/global_search/advanced_search_syntax.md
---

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: howto
---

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
disqus_identifier: 'https://docs.gitlab.com/ee/workflow/workflow.html'
---

View File

@ -2,7 +2,7 @@
type: reference, how-to
stage: Create
group: Editor
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
---
# Gitpod integration **(FREE)**

View File

@ -1,7 +1,7 @@
---
stage: Manage
group: Authentication and Authorization
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
---
# Kerberos integration **(PREMIUM SELF)**

View File

@ -137,3 +137,17 @@ On self-managed GitLab, by default, this feature is not available. To make it av
On GitLab.com, this feature is not available.
By default, OAuth application secrets are stored as plain text in the database. When enabled, OAuth application secrets are stored in the database in hashed format and are only available to users immediately after creating OAuth applications.
## Hashed OAuth tokens
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/364110) in GitLab 15.3 [with a flag](../administration/feature_flags.md) named `hash_oauth_tokens`. Enabled on GitLab.com. Disabled by default for self-managed.
> - [Enabled by default on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 15.5.
FLAG:
On self-managed GitLab, by default, this feature is enabled. If you detect a problem, ask an administrator to
[disable the feature flag](../administration/feature_flags.md) named `hash_oauth_tokens`. If the feature flag is disabled, any tokens that were stored
in encrypted format are inaccessible. Users must reauthorize applications.
On GitLab.com, this feature is enabled.
By default, OAuth access tokens are stored in the database in PBKDF2+SHA512 format. GitLab administrators can disable this and OAuth access tokens are
then stored in plaintext in the database.

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: reference, how-to
---

View File

@ -8,7 +8,7 @@ type: index
# Security **(FREE)**
- [Password storage](password_storage.md)
- [Passwords and OAuth tokens storage](password_storage.md)
- [Password length limits](password_length_limits.md)
- [Generated passwords for users created through integrated authentication](passwords_for_integrated_authentication_methods.md)
- [Restrict SSH key technologies and minimum length](ssh_keys_restrictions.md)

View File

@ -5,7 +5,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
# Password storage **(FREE)**
# Password and OAuth token storage **(FREE)**
GitLab administrators can configure how passwords and OAuth tokens are stored.
## Password storage **(FREE)**
> PBKDF2 and SHA512 [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/360658) in GitLab 15.2 [with flags](../administration/feature_flags.md) named `pbkdf2_password_encryption` and `pbkdf2_password_encryption_write`. Disabled by default.
@ -37,3 +41,13 @@ library to hash user passwords. Created password hashes have these attributes:
is added to each password to harden against pre-computed hash and dictionary
attacks. To increase security, each salt is randomly generated for each
password, with no two passwords sharing a salt.
## OAuth access token storage
> - PBKDF2+SHA512 [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/364110) in GitLab 15.3 [with flag](../administration/feature_flags.md) named `hash_oauth_tokens`.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98242) in GitLab 15.5.
Depending on your version of GitLab and configuration, OAuth access tokens are stored in the database in PBKDF2+SHA512 format. For version information, see
the relevant [OAuth provider documentation](../integration/oauth_provider.md#hashed-oauth-tokens).
As with PBKDF2+SHA512 password storage, access token values are [stretched](https://en.wikipedia.org/wiki/Key_stretching) 20,000 times to harden against brute-force attacks.

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: how-tos
---

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: concepts, howto
description: "Introduction to Git rebase and force-push, methods to resolve merge conflicts through the command line."
---

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: index
---

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: reference, howto
disqus_identifier: 'https://docs.gitlab.com/ee/workflow/lfs/lfs/index.html'
---

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: reference, howto
---

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: howto
---

View File

@ -1,7 +1,7 @@
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
type: reference
---

View File

@ -1,7 +1,7 @@
---
stage: none
group: unassigned
info: For assistance with this tutorials page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects.
info: For assistance with this tutorials page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-other-projects-and-subjects.
---
# Learn GitLab with tutorials

View File

@ -1,7 +1,7 @@
---
stage: none
group: unassigned
info: For assistance with this tutorial, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects.
info: For assistance with this tutorial, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-other-projects-and-subjects.
---
# Make your first Git commit

View File

@ -1,7 +1,7 @@
---
stage: none
group: unassigned
info: For assistance with this tutorial, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects.
info: For assistance with this tutorial, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-other-projects-and-subjects.
---
# Move your personal project to a group **(FREE SAAS)**

View File

@ -1,7 +1,7 @@
---
stage: none
group: none
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-development-guidelines"
---
# Deprecations by version

View File

@ -1,7 +1,7 @@
---
stage: none
group: none
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-development-guidelines"
---
# Removals by version

View File

@ -8,12 +8,18 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41416) in GitLab 11.2.
Administrators have access to instance-wide analytics:
Instance-level analytics provide insights into the feature and data usage of your entire instance.
## View instance-level analytics
Prerequisite:
- You must have administrator access for your instance.
To view instance-level analytics:
1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Analytics**.
1. On the left sidebar, select **Analytics**, then one of the available analytics:
There are several kinds of statistics:
- [DevOps Reports](dev_ops_reports.md): Provides an overview of your entire instance's feature usage.
- [Usage Trends](usage_trends.md): Shows how much data your instance contains, and how that is changing.
- [DevOps Reports](dev_ops_reports.md): Provides an overview of your entire instance's feature usage.
- [Usage Trends](usage_trends.md): Shows how much data your instance contains, and how the data is changing.

View File

@ -70,7 +70,9 @@ runner settings:
To view the rendered details:
1. On the top bar, select **Main menu > Projects** or **Main menu > Groups** and find your project or group.
1. On the top bar, select **Main menu**, and:
- For a project, select ***Projects** and find your project.
- For a group, select **Groups** and find your group.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Runners**.

View File

@ -146,22 +146,22 @@ Below are the current settings regarding [GitLab CI/CD](../../ci/index.md).
Any settings or feature limits not listed here are using the defaults listed in
the related documentation.
| Setting | GitLab.com | Default (self-managed) |
|:-------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Artifacts maximum size (compressed) | 1 GB | See [Maximum artifacts size](../../user/admin_area/settings/continuous_integration.md#maximum-artifacts-size) |
| Artifacts [expiry time](../../ci/yaml/index.md#artifactsexpire_in) | From June 22, 2020, deleted after 30 days unless otherwise specified (artifacts created before that date have no expiry). | See [Default artifacts expiration](../admin_area/settings/continuous_integration.md#default-artifacts-expiration) |
| Scheduled Pipeline Cron | `*/5 * * * *` | See [Pipeline schedules advanced configuration](../../administration/cicd.md#change-maximum-scheduled-pipeline-frequency) |
| Maximum jobs in active pipelines | `500` for Free tier, `1000` for all trial tiers, and unlimited otherwise. | See [Number of jobs in active pipelines](../../administration/instance_limits.md#number-of-jobs-in-active-pipelines) |
| Maximum CI/CD subscriptions to a project | `2` | See [Number of CI/CD subscriptions to a project](../../administration/instance_limits.md#number-of-cicd-subscriptions-to-a-project) |
| Maximum number of pipeline triggers in a project | `25000` for Free tier, Unlimited for all paid tiers | See [Limit the number of pipeline triggers](../../administration/instance_limits.md#limit-the-number-of-pipeline-triggers) |
| Maximum pipeline schedules in projects | `10` for Free tier, `50` for all paid tiers | See [Number of pipeline schedules](../../administration/instance_limits.md#number-of-pipeline-schedules) |
| Maximum pipelines per schedule | `24` for Free tier, `288` for all paid tiers | See [Limit the number of pipelines created by a pipeline schedule per day](../../administration/instance_limits.md#limit-the-number-of-pipelines-created-by-a-pipeline-schedule-per-day) |
| Maximum number of schedule rules defined for each security policy project | Unlimited for all paid tiers | See [Number of schedule rules defined for each security policy project](../../administration/instance_limits.md#limit-the-number-of-schedule-rules-defined-for-security-policy-project) |
| Scheduled job archiving | 3 months (from June 22, 2020). Jobs created before that date were archived after September 22, 2020. | Never |
| Maximum test cases per [unit test report](../../ci/testing/unit_test_reports.md) | `500000` | Unlimited |
| Maximum registered runners | Free tier: `50` per-group / `50` per-project<br/>All paid tiers: `1000` per-group / `1000` per-project | See [Number of registered runners per scope](../../administration/instance_limits.md#number-of-registered-runners-per-scope) |
| Limit of dotenv variables | Free tier: `50` / Premium tier: `100` / Ultimate tier: `150` | See [Limit dotenv variables](../../administration/instance_limits.md#limit-dotenv-variables) |
| Authorization token duration (minutes) | `15` | To set a custom value, in the Rails console, run `ApplicationSetting.last.update(container_registry_token_expire_delay: <integer>)`, where `<integer>` is the desired number of minutes. |
| Setting | GitLab.com | Default (self-managed) |
|----------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|------------------------|
| Artifacts maximum size (compressed) | 1 GB | See [Maximum artifacts size](../../user/admin_area/settings/continuous_integration.md#maximum-artifacts-size). |
| Artifacts [expiry time](../../ci/yaml/index.md#artifactsexpire_in) | From June 22, 2020, deleted after 30 days unless otherwise specified (artifacts created before that date have no expiry). | See [Default artifacts expiration](../admin_area/settings/continuous_integration.md#default-artifacts-expiration). |
| Scheduled Pipeline Cron | `*/5 * * * *` | See [Pipeline schedules advanced configuration](../../administration/cicd.md#change-maximum-scheduled-pipeline-frequency). |
| Maximum jobs in active pipelines | `500` for Free tier, `1000` for all trial tiers, and unlimited otherwise. | See [Number of jobs in active pipelines](../../administration/instance_limits.md#number-of-jobs-in-active-pipelines). |
| Maximum CI/CD subscriptions to a project | `2` | See [Number of CI/CD subscriptions to a project](../../administration/instance_limits.md#number-of-cicd-subscriptions-to-a-project). |
| Maximum number of pipeline triggers in a project | `25000` for Free tier, Unlimited for all paid tiers | See [Limit the number of pipeline triggers](../../administration/instance_limits.md#limit-the-number-of-pipeline-triggers). |
| Maximum pipeline schedules in projects | `10` for Free tier, `50` for all paid tiers | See [Number of pipeline schedules](../../administration/instance_limits.md#number-of-pipeline-schedules). |
| Maximum pipelines per schedule | `24` for Free tier, `288` for all paid tiers | See [Limit the number of pipelines created by a pipeline schedule per day](../../administration/instance_limits.md#limit-the-number-of-pipelines-created-by-a-pipeline-schedule-per-day). |
| Maximum number of schedule rules defined for each security policy project | Unlimited for all paid tiers | See [Number of schedule rules defined for each security policy project](../../administration/instance_limits.md#limit-the-number-of-schedule-rules-defined-for-security-policy-project). |
| Scheduled job archiving | 3 months (from June 22, 2020). Jobs created before that date were archived after September 22, 2020. | Never. |
| Maximum test cases per [unit test report](../../ci/testing/unit_test_reports.md) | `500000` | Unlimited. |
| Maximum registered runners | Free tier: `50` per-group / `50` per-project<br/>All paid tiers: `1000` per-group / `1000` per-project | See [Number of registered runners per scope](../../administration/instance_limits.md#number-of-registered-runners-per-scope). |
| Limit of dotenv variables | Free tier: `50` / Premium tier: `100` / Ultimate tier: `150` | See [Limit dotenv variables](../../administration/instance_limits.md#limit-dotenv-variables). |
| Authorization token duration (minutes) | `15` | To set a custom value, in the Rails console, run `ApplicationSetting.last.update(container_registry_token_expire_delay: <integer>)`, where `<integer>` is the desired number of minutes. |
## Package registry limits

View File

@ -31,7 +31,9 @@ You can create as many deploy tokens as you need from the settings of your
project. Alternatively, you can also create [group-scoped deploy tokens](#group-deploy-token).
1. Sign in to your GitLab account.
1. On the top bar, select **Main menu > Projects** or **Main menu > Groups** to find your project or group.
1. On the top bar, select **Main menu**, and:
- For a project, select ***Projects** and find your project.
- For a group, select **Groups** and find your group.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Deploy tokens**.
1. Choose a name, and optionally, an expiration date and username for the token.
@ -51,7 +53,9 @@ Deploy tokens expire at midnight UTC on the date you define.
To revoke a deploy token:
1. On the top bar, select **Main menu > Projects** or **Main menu > Groups** to find your project or group.
1. On the top bar, select **Main menu**, and:
- For a project, select ***Projects** and find your project.
- For a group, select **Groups** and find your group.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Deploy tokens**.
1. In the **Active Deploy Tokens** section, by the token you want to revoke, select **Revoke**.

View File

@ -123,6 +123,12 @@ module API
end
def present_groups_with_pagination_strategies(params, groups)
# Prevent Rails from optimizing the count query and inadvertadly creating a poor performing databse query.
# https://gitlab.com/gitlab-org/gitlab/-/issues/368969
if Feature.enabled?(:present_groups_select_all)
groups = groups.select(groups.arel_table[Arel.star])
end
return present_groups(params, groups) if current_user.present?
options = {

View File

@ -7,14 +7,14 @@ module Gitlab
module Validators
class SchemaValidator
SUPPORTED_VERSIONS = {
cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1],
container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1],
coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1],
dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1],
api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1],
dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1],
sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1],
secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1]
cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1 15.0.2],
container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1 15.0.2],
coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1 15.0.2],
dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1 15.0.2],
api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1 15.0.2],
dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1 15.0.2],
sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1 15.0.2],
secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0 15.0.1 15.0.2]
}.freeze
VERSIONS_TO_REMOVE_IN_16_0 = [].freeze

View File

@ -0,0 +1,980 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/cluster-image-scanning-report-format.json",
"title": "Report format for GitLab Cluster Image Scanning",
"description": "This schema provides the the report format for Cluster Image Scanning (https://docs.gitlab.com/ee/user/application_security/cluster_image_scanning/).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "15.0.2"
},
"required": [
"scan",
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"analyzer",
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"cluster_image_scanning"
]
},
"primary_identifiers": {
"type": "array",
"description": "An array containing an exhaustive list of primary identifiers for which the analyzer may return results",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"pattern": "^https?://.+"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"id",
"identifiers",
"location"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"name": {
"type": "string",
"maxLength": 255,
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"description": {
"type": "string",
"maxLength": 1048576,
"description": "A long text section describing the vulnerability more fully."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"solution": {
"type": "string",
"maxLength": 7000,
"description": "Explanation of how to fix the vulnerability."
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"pattern": "^https?://.+"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"type": "object",
"description": "Identifies the vulnerability's location.",
"required": [
"dependency",
"image",
"kubernetes_resource"
],
"properties": {
"dependency": {
"type": "object",
"description": "Describes the dependency of a project where the vulnerability is located.",
"required": [
"package",
"version"
],
"properties": {
"package": {
"type": "object",
"description": "Provides information on the package where the vulnerability is located.",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the package where the vulnerability is located."
}
}
},
"version": {
"type": "string",
"description": "Version of the vulnerable package."
},
"iid": {
"description": "ID that identifies the dependency in the scope of a dependency file.",
"type": "number"
},
"direct": {
"type": "boolean",
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
},
"dependency_path": {
"type": "array",
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
"items": {
"type": "object",
"required": [
"iid"
],
"properties": {
"iid": {
"type": "number",
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
}
}
}
}
}
},
"operating_system": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The operating system that contains the vulnerable package."
},
"image": {
"type": "string",
"minLength": 1,
"description": "The analyzed Docker image.",
"examples": [
"index.docker.io/library/nginx:1.21"
]
},
"kubernetes_resource": {
"type": "object",
"description": "The specific Kubernetes resource that was scanned.",
"required": [
"namespace",
"kind",
"name",
"container_name"
],
"properties": {
"namespace": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The Kubernetes namespace the resource that had its image scanned.",
"examples": [
"default",
"staging",
"production"
]
},
"kind": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The Kubernetes kind the resource that had its image scanned.",
"examples": [
"Deployment",
"DaemonSet"
]
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The name of the resource that had its image scanned.",
"examples": [
"nginx-ingress"
]
},
"container_name": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The name of the container that had its image scanned.",
"examples": [
"nginx"
]
},
"agent_id": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The GitLab ID of the Kubernetes Agent which performed the scan.",
"examples": [
"1234"
]
},
"cluster_id": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The GitLab ID of the Kubernetes cluster when using cluster integration.",
"examples": [
"1234"
]
}
}
}
}
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

View File

@ -0,0 +1,912 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/container-scanning-report-format.json",
"title": "Report format for GitLab Container Scanning",
"description": "This schema provides the the report format for Container Scanning (https://docs.gitlab.com/ee/user/application_security/container_scanning).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "15.0.2"
},
"required": [
"scan",
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"analyzer",
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"container_scanning"
]
},
"primary_identifiers": {
"type": "array",
"description": "An array containing an exhaustive list of primary identifiers for which the analyzer may return results",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"pattern": "^https?://.+"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"id",
"identifiers",
"location"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"name": {
"type": "string",
"maxLength": 255,
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"description": {
"type": "string",
"maxLength": 1048576,
"description": "A long text section describing the vulnerability more fully."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"solution": {
"type": "string",
"maxLength": 7000,
"description": "Explanation of how to fix the vulnerability."
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"pattern": "^https?://.+"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"type": "object",
"description": "Identifies the vulnerability's location.",
"required": [
"dependency",
"operating_system",
"image"
],
"properties": {
"dependency": {
"type": "object",
"description": "Describes the dependency of a project where the vulnerability is located.",
"required": [
"package",
"version"
],
"properties": {
"package": {
"type": "object",
"description": "Provides information on the package where the vulnerability is located.",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the package where the vulnerability is located."
}
}
},
"version": {
"type": "string",
"description": "Version of the vulnerable package."
},
"iid": {
"description": "ID that identifies the dependency in the scope of a dependency file.",
"type": "number"
},
"direct": {
"type": "boolean",
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
},
"dependency_path": {
"type": "array",
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
"items": {
"type": "object",
"required": [
"iid"
],
"properties": {
"iid": {
"type": "number",
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
}
}
}
}
}
},
"operating_system": {
"type": "string",
"minLength": 1,
"description": "The operating system that contains the vulnerable package."
},
"image": {
"type": "string",
"minLength": 1,
"description": "The analyzed Docker image."
},
"default_branch_image": {
"type": "string",
"maxLength": 255,
"description": "The name of the image on the default branch."
}
}
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

View File

@ -0,0 +1,870 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/coverage-fuzzing-report-format.json",
"title": "Report format for GitLab Fuzz Testing",
"description": "This schema provides the report format for Coverage Guided Fuzz Testing (https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "15.0.2"
},
"required": [
"scan",
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"analyzer",
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"coverage_fuzzing"
]
},
"primary_identifiers": {
"type": "array",
"description": "An array containing an exhaustive list of primary identifiers for which the analyzer may return results",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"pattern": "^https?://.+"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"id",
"identifiers",
"location"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"name": {
"type": "string",
"maxLength": 255,
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"description": {
"type": "string",
"maxLength": 1048576,
"description": "A long text section describing the vulnerability more fully."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"solution": {
"type": "string",
"maxLength": 7000,
"description": "Explanation of how to fix the vulnerability."
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"pattern": "^https?://.+"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"description": "The location of the error",
"type": "object",
"properties": {
"crash_address": {
"type": "string",
"description": "The relative address in memory were the crash occurred.",
"examples": [
"0xabababab"
]
},
"stacktrace_snippet": {
"type": "string",
"description": "The stack trace recorded during fuzzing resulting the crash.",
"examples": [
"func_a+0xabcd\nfunc_b+0xabcc"
]
},
"crash_state": {
"type": "string",
"description": "Minimised and normalized crash stack-trace (called crash_state).",
"examples": [
"func_a+0xa\nfunc_b+0xb\nfunc_c+0xc"
]
},
"crash_type": {
"type": "string",
"description": "Type of the crash.",
"examples": [
"Heap-Buffer-overflow",
"Division-by-zero"
]
}
}
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,978 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/dependency-scanning-report-format.json",
"title": "Report format for GitLab Dependency Scanning",
"description": "This schema provides the the report format for Dependency Scanning analyzers (https://docs.gitlab.com/ee/user/application_security/dependency_scanning).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "15.0.2"
},
"required": [
"dependency_files",
"scan",
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"analyzer",
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"dependency_scanning"
]
},
"primary_identifiers": {
"type": "array",
"description": "An array containing an exhaustive list of primary identifiers for which the analyzer may return results",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"pattern": "^https?://.+"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"id",
"identifiers",
"location"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"name": {
"type": "string",
"maxLength": 255,
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"description": {
"type": "string",
"maxLength": 1048576,
"description": "A long text section describing the vulnerability more fully."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"solution": {
"type": "string",
"maxLength": 7000,
"description": "Explanation of how to fix the vulnerability."
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"pattern": "^https?://.+"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"type": "object",
"description": "Identifies the vulnerability's location.",
"required": [
"file",
"dependency"
],
"properties": {
"file": {
"type": "string",
"minLength": 1,
"description": "Path to the manifest or lock file where the dependency is declared (such as yarn.lock)."
},
"dependency": {
"type": "object",
"description": "Describes the dependency of a project where the vulnerability is located.",
"required": [
"package",
"version"
],
"properties": {
"package": {
"type": "object",
"description": "Provides information on the package where the vulnerability is located.",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the package where the vulnerability is located."
}
}
},
"version": {
"type": "string",
"description": "Version of the vulnerable package."
},
"iid": {
"description": "ID that identifies the dependency in the scope of a dependency file.",
"type": "number"
},
"direct": {
"type": "boolean",
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
},
"dependency_path": {
"type": "array",
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
"items": {
"type": "object",
"required": [
"iid"
],
"properties": {
"iid": {
"type": "number",
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
}
}
}
}
}
}
}
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
},
"dependency_files": {
"type": "array",
"description": "List of dependency files identified in the project.",
"items": {
"type": "object",
"required": [
"path",
"package_manager",
"dependencies"
],
"properties": {
"path": {
"type": "string",
"minLength": 1
},
"package_manager": {
"type": "string",
"minLength": 1
},
"dependencies": {
"type": "array",
"items": {
"type": "object",
"description": "Describes the dependency of a project where the vulnerability is located.",
"required": [
"package",
"version"
],
"properties": {
"package": {
"type": "object",
"description": "Provides information on the package where the vulnerability is located.",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the package where the vulnerability is located."
}
}
},
"version": {
"type": "string",
"description": "Version of the vulnerable package."
},
"iid": {
"description": "ID that identifies the dependency in the scope of a dependency file.",
"type": "number"
},
"direct": {
"type": "boolean",
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
},
"dependency_path": {
"type": "array",
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
"items": {
"type": "object",
"required": [
"iid"
],
"properties": {
"iid": {
"type": "number",
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
}
}
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,865 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/sast-report-format.json",
"title": "Report format for GitLab SAST",
"description": "This schema provides the report format for Static Application Security Testing analyzers (https://docs.gitlab.com/ee/user/application_security/sast).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "15.0.2"
},
"required": [
"scan",
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"analyzer",
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"sast"
]
},
"primary_identifiers": {
"type": "array",
"description": "An array containing an exhaustive list of primary identifiers for which the analyzer may return results",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"pattern": "^https?://.+"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"id",
"identifiers",
"location"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"name": {
"type": "string",
"maxLength": 255,
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"description": {
"type": "string",
"maxLength": 1048576,
"description": "A long text section describing the vulnerability more fully."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"solution": {
"type": "string",
"maxLength": 7000,
"description": "Explanation of how to fix the vulnerability."
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"pattern": "^https?://.+"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"type": "object",
"description": "Identifies the vulnerability's location.",
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the code affected by the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the code affected by the vulnerability."
},
"class": {
"type": "string",
"description": "Provides the name of the class where the vulnerability is located."
},
"method": {
"type": "string",
"description": "Provides the name of the method where the vulnerability is located."
}
}
},
"raw_source_code_extract": {
"type": "string",
"description": "Provides an unsanitized excerpt of the affected source code."
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

View File

@ -0,0 +1,888 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/secret-detection-report-format.json",
"title": "Report format for GitLab Secret Detection",
"description": "This schema provides the the report format for the Secret Detection analyzer (https://docs.gitlab.com/ee/user/application_security/secret_detection)",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "15.0.2"
},
"required": [
"scan",
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"analyzer",
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"secret_detection"
]
},
"primary_identifiers": {
"type": "array",
"description": "An array containing an exhaustive list of primary identifiers for which the analyzer may return results",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"pattern": "^https?://.+"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"id",
"identifiers",
"location"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"name": {
"type": "string",
"maxLength": 255,
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"description": {
"type": "string",
"maxLength": 1048576,
"description": "A long text section describing the vulnerability more fully."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"solution": {
"type": "string",
"maxLength": 7000,
"description": "Explanation of how to fix the vulnerability."
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"pattern": "^https?://.+"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"pattern": "^https?://.+"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"required": [
"commit"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located"
},
"commit": {
"type": "object",
"description": "Represents the commit in which the vulnerability was detected",
"required": [
"sha"
],
"properties": {
"author": {
"type": "string"
},
"date": {
"type": "string"
},
"message": {
"type": "string"
},
"sha": {
"type": "string",
"minLength": 1
}
}
},
"start_line": {
"type": "number",
"description": "The first line of the code affected by the vulnerability"
},
"end_line": {
"type": "number",
"description": "The last line of the code affected by the vulnerability"
},
"class": {
"type": "string",
"description": "Provides the name of the class where the vulnerability is located"
},
"method": {
"type": "string",
"description": "Provides the name of the method where the vulnerability is located"
}
}
},
"raw_source_code_extract": {
"type": "string",
"description": "Provides an unsanitized excerpt of the affected source code."
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

View File

@ -56,6 +56,7 @@ module Gitlab
push_frontend_feature_flag(:new_header_search)
push_frontend_feature_flag(:source_editor_toolbar)
push_frontend_feature_flag(:gl_avatar_for_all_user_avatars)
push_frontend_feature_flag(:gl_listbox_for_sort_dropdowns)
end
# Exposes the state of a feature flag to the frontend code.

View File

@ -45865,7 +45865,7 @@ msgstr ""
msgid "You have successfully purchased %{product}. You'll receive a receipt by email. Your purchase may take a minute to sync, so refresh the page if you don't see it yet."
msgstr ""
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. Youll receive a receipt via email. It might take a moment for GitLab.com to fully reflect your purchase."
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. Youll receive a receipt via email. Your purchase may take a minute to sync, so refresh the page if you don't see it yet."
msgstr ""
msgid "You have unsaved changes"

View File

@ -9,6 +9,8 @@ RSpec.describe 'Dashboard > User filters projects' do
let(:project2) { create(:project, name: 'Treasure', namespace: user2.namespace, created_at: 1.second.ago, updated_at: 1.second.ago) }
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
project.add_maintainer(user)
sign_in(user)

View File

@ -9,6 +9,8 @@ RSpec.describe 'Sort labels', :js do
let!(:label2) { create(:group_label, title: 'Bar', description: 'Fusce consequat', group: group) }
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
group.add_maintainer(user)
sign_in(user)

View File

@ -14,6 +14,7 @@ RSpec.describe 'Milestones sorting', :js do
let(:user) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
sign_in(user)
end

View File

@ -59,6 +59,10 @@ RSpec.describe "Help Dropdown", :js do
expect(page).to have_text('Your GitLab Version')
expect(page).to have_text("#{Gitlab.version_info.major}.#{Gitlab.version_info.minor}")
expect(page).to have_selector('.version-check-badge')
expect(page).to have_selector(
'a[data-testid="gitlab-version-container"][href="/help/update/index"]'
)
expect(page).to have_selector('.version-check-badge[href="/help/update/index"]')
expect(page).to have_text(ui_text)
end
end

View File

@ -3,8 +3,8 @@
require 'spec_helper'
RSpec.describe 'Branches' do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
let(:repository) { project.repository }
context 'logged in as developer' do
@ -175,7 +175,7 @@ RSpec.describe 'Branches' do
search_for_branch('fix')
expect(page).not_to have_content('fix')
expect(all('.all-branches').last).to have_selector('li', count: 0)
expect(all('.all-branches', wait: false).last).to have_selector('li', count: 0)
end
end
@ -233,7 +233,7 @@ RSpec.describe 'Branches' do
end
context 'with one or more pipeline', :js do
let(:project) { create(:project, :public, :empty_repo) }
let_it_be(:project) { create(:project, :public, :empty_repo) }
before do
sha = create_file(branch_name: "branch")

View File

@ -9,6 +9,8 @@ RSpec.describe 'Sort labels', :js do
let!(:label2) { create(:label, title: 'Bar', description: 'Fusce consequat', project: project) }
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
project.add_maintainer(user)
sign_in(user)

View File

@ -21,6 +21,7 @@ RSpec.describe 'Milestones sorting', :js do
end
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
create(:milestone, start_date: 7.days.from_now, due_date: 10.days.from_now, title: "a", project: project)
create(:milestone, start_date: 6.days.from_now, due_date: 11.days.from_now, title: "c", project: project)
create(:milestone, start_date: 5.days.from_now, due_date: 12.days.from_now, title: "b", project: project)

View File

@ -44,6 +44,7 @@ RSpec.describe 'User sorts projects and order persists' do
context "from explore projects" do
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
sign_in(user)
visit(explore_projects_path)
find('#sort-projects-dropdown').click
@ -55,6 +56,7 @@ RSpec.describe 'User sorts projects and order persists' do
context 'from dashboard projects' do
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
sign_in(user)
visit(dashboard_projects_path)
find('#sort-projects-dropdown').click
@ -66,6 +68,7 @@ RSpec.describe 'User sorts projects and order persists' do
context 'from group homepage', :js do
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
stub_feature_flags(group_overview_tabs_vue: false)
sign_in(user)
visit(group_canonical_path(group))
@ -80,6 +83,7 @@ RSpec.describe 'User sorts projects and order persists' do
context 'from group details', :js do
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
stub_feature_flags(group_overview_tabs_vue: false)
sign_in(user)
visit(details_group_path(group))

View File

@ -3,6 +3,10 @@
require "spec_helper"
RSpec.describe 'Project wikis', :js do
before do
stub_feature_flags(gl_listbox_for_sort_dropdowns: false)
end
let_it_be(:user) { create(:user) }
let(:wiki) { create(:project_wiki, user: user, project: project) }

View File

@ -30,7 +30,7 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.post_install_message = 'Installed, thank you!'
s.rdoc_options = ['--main', 'README.md']
s.required_ruby_version = '>= 2.7.0'
s.required_ruby_version = '>= 2.7.0' # rubocop:disable Gemspec/RequiredRubyVersion
s.required_rubygems_version = '>= 1.8.11'
s.requirements = 'A high powered server or calculator'
s.rubygems_version = '1.8.09'

View File

@ -1,6 +1,6 @@
import { nextTick } from 'vue';
import { getAllByRole, getByRole } from '@testing-library/dom';
import { GlDropdown } from '@gitlab/ui';
import { getAllByRole, getByRole, getByTestId } from '@testing-library/dom';
import { GlDropdown, GlListbox } from '@gitlab/ui';
import { createWrapper } from '@vue/test-utils';
import { initListbox, parseAttributes } from '~/listbox';
import { getFixture, setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
@ -28,20 +28,6 @@ describe('initListbox', () => {
instance = initListbox(...args);
};
// TODO: Rewrite these finders to use better semantics once the
// implementation is switched to GlListbox
// https://gitlab.com/gitlab-org/gitlab/-/issues/348738
const findToggleButton = () => document.body.querySelector('.gl-dropdown-toggle');
const findItem = (text) => getByRole(document.body, 'menuitem', { name: text });
const findItems = () => getAllByRole(document.body, 'menuitem');
const findSelectedItems = () =>
findItems().filter(
(menuitem) =>
!menuitem
.querySelector('.gl-new-dropdown-item-check-icon')
.classList.contains('gl-visibility-hidden'),
);
it('returns null given no element', () => {
setup();
@ -53,63 +39,141 @@ describe('initListbox', () => {
});
describe('given a valid element', () => {
let onChangeSpy;
describe('when `glListboxForSortDropdowns` FF is enabled', () => {
let onChangeSpy;
beforeEach(async () => {
setHTMLFixture(fixture);
onChangeSpy = jest.fn();
setup(document.querySelector('.js-redirect-listbox'), { onChange: onChangeSpy });
const listbox = () => createWrapper(instance).findComponent(GlListbox);
const findToggleButton = () => getByTestId(document.body, 'base-dropdown-toggle');
const findSelectedItems = () => getAllByRole(document.body, 'option', { selected: true });
await nextTick();
});
afterEach(() => {
resetHTMLFixture();
});
it('returns an instance', () => {
expect(instance).not.toBe(null);
});
it('renders button with selected item text', () => {
expect(findToggleButton().textContent.trim()).toBe('Bar');
});
it('has the correct item selected', () => {
const selectedItems = findSelectedItems();
expect(selectedItems).toHaveLength(1);
expect(selectedItems[0].textContent.trim()).toBe('Bar');
});
it('applies additional classes from the original element', () => {
expect(instance.$el.classList).toContain('test-class-1', 'test-class-2');
});
describe.each(parsedAttributes.items)('clicking on an item', (item) => {
beforeEach(async () => {
findItem(item.text).click();
window.gon.features = { glListboxForSortDropdowns: true };
setHTMLFixture(fixture);
onChangeSpy = jest.fn();
setup(document.querySelector('.js-redirect-listbox'), { onChange: onChangeSpy });
await nextTick();
});
it('calls the onChange callback with the item', () => {
expect(onChangeSpy).toHaveBeenCalledWith(item);
afterEach(() => {
resetHTMLFixture();
});
it('updates the toggle button text', () => {
expect(findToggleButton().textContent.trim()).toBe(item.text);
it('returns an instance', () => {
expect(instance).not.toBe(null);
});
it('marks the item as selected', () => {
it('renders button with selected item text', () => {
expect(findToggleButton().textContent.trim()).toBe('Bar');
});
it('has the correct item selected', () => {
const selectedItems = findSelectedItems();
expect(selectedItems).toHaveLength(1);
expect(selectedItems[0].textContent.trim()).toBe(item.text);
expect(selectedItems[0].textContent.trim()).toBe('Bar');
});
it('applies additional classes from the original element', () => {
expect(instance.$el.classList).toContain('test-class-1', 'test-class-2');
});
describe.each(parsedAttributes.items)('selecting an item', (item) => {
beforeEach(async () => {
listbox().vm.$emit('select', item.value);
await nextTick();
});
it('calls the onChange callback with the item', () => {
expect(onChangeSpy).toHaveBeenCalledWith(item);
});
it('updates the toggle button text', () => {
expect(findToggleButton().textContent.trim()).toBe(item.text);
});
it('marks the item as selected', () => {
const selectedItems = findSelectedItems();
expect(selectedItems).toHaveLength(1);
expect(selectedItems[0].textContent.trim()).toBe(item.text);
});
});
it('passes the "right" prop through to the underlying component', () => {
expect(listbox().props('right')).toBe(parsedAttributes.right);
});
});
it('passes the "right" prop through to the underlying component', () => {
const wrapper = createWrapper(instance).findComponent(GlDropdown);
expect(wrapper.props('right')).toBe(parsedAttributes.right);
describe('when `glListboxForSortDropdowns` FF is disabled', () => {
let onChangeSpy;
const ITEM_ROLE = 'menuitem';
const dropdown = () => createWrapper(instance).findComponent(GlDropdown);
const findToggleButton = () => document.body.querySelector('.gl-dropdown-toggle');
const findItem = (text) => getByRole(document.body, ITEM_ROLE, { name: text });
const findItems = () => getAllByRole(document.body, ITEM_ROLE);
const findSelectedItems = () =>
findItems().filter(
(item) =>
!item
.querySelector('.gl-new-dropdown-item-check-icon')
.classList.contains('gl-visibility-hidden'),
);
beforeEach(async () => {
window.gon.features = { glListboxForSortDropdowns: false };
setHTMLFixture(fixture);
onChangeSpy = jest.fn();
setup(document.querySelector('.js-redirect-listbox'), { onChange: onChangeSpy });
await nextTick();
});
afterEach(() => {
resetHTMLFixture();
});
it('returns an instance', () => {
expect(instance).not.toBe(null);
});
it('renders button with selected item text', () => {
expect(findToggleButton().textContent.trim()).toBe('Bar');
});
it('has the correct item selected', () => {
const selectedItems = findSelectedItems();
expect(selectedItems).toHaveLength(1);
expect(selectedItems[0].textContent.trim()).toBe('Bar');
});
it('applies additional classes from the original element', () => {
expect(instance.$el.classList).toContain('test-class-1', 'test-class-2');
});
describe.each(parsedAttributes.items)('selecting an item', (item) => {
beforeEach(async () => {
findItem(item.text).click();
await nextTick();
});
it('calls the onChange callback with the item', () => {
expect(onChangeSpy).toHaveBeenCalledWith(item);
});
it('updates the toggle button text', () => {
expect(findToggleButton().textContent.trim()).toBe(item.text);
});
it('marks the item as selected', () => {
const selectedItems = findSelectedItems();
expect(selectedItems).toHaveLength(1);
expect(selectedItems[0].textContent.trim()).toBe(item.text);
});
});
it('passes the "right" prop through to the underlying component', () => {
expect(dropdown().props('right')).toBe(parsedAttributes.right);
});
});
});
});

View File

@ -8,9 +8,13 @@ import blobControlsQuery from '~/repository/queries/blob_controls.query.graphql'
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createRouter from '~/repository/router';
import { updateElementsVisibility } from '~/repository/utils/dom';
import ShortcutsBlob from '~/behaviors/shortcuts/shortcuts_blob';
import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater';
import { blobControlsDataMock, refMock } from '../mock_data';
jest.mock('~/repository/utils/dom');
jest.mock('~/behaviors/shortcuts/shortcuts_blob');
jest.mock('~/blob/blob_line_permalink_updater');
let router;
let wrapper;
@ -82,4 +86,12 @@ describe('Blob controls component', () => {
expect(updateElementsVisibility).toHaveBeenCalledWith('.tree-controls', true);
},
);
it('loads the ShortcutsBlob', () => {
expect(ShortcutsBlob).toHaveBeenCalled();
});
it('loads the BlobLinePermalinkUpdater', () => {
expect(BlobLinePermalinkUpdater).toHaveBeenCalled();
});
});

View File

@ -2,6 +2,7 @@ import { GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import waitForPromises from 'helpers/wait_for_promises';
import { helpPagePath } from '~/helpers/help_page_helper';
import axios from '~/lib/utils/axios_utils';
import GitlabVersionCheck from '~/vue_shared/components/gitlab_version_check.vue';
@ -9,6 +10,8 @@ describe('GitlabVersionCheck', () => {
let wrapper;
let mock;
const UPGRADE_DOCS_URL = helpPagePath('update/index');
const defaultResponse = {
code: 200,
res: { severity: 'success' },
@ -102,6 +105,10 @@ describe('GitlabVersionCheck', () => {
it(`variant is ${expectedUI.variant}`, () => {
expect(findGlBadge().attributes('variant')).toBe(expectedUI.variant);
});
it(`link is ${UPGRADE_DOCS_URL}`, () => {
expect(findGlBadge().attributes('href')).toBe(UPGRADE_DOCS_URL);
});
});
});
});

View File

@ -19,6 +19,7 @@ import { i18n } from '~/work_items/constants';
import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
import workItemDatesSubscription from '~/work_items/graphql/work_item_dates.subscription.graphql';
import workItemTitleSubscription from '~/work_items/graphql/work_item_title.subscription.graphql';
import workItemAssigneesSubscription from '~/work_items/graphql/work_item_assignees.subscription.graphql';
import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
import updateWorkItemTaskMutation from '~/work_items/graphql/update_work_item_task.mutation.graphql';
import { temporaryConfig } from '~/graphql_shared/issuable_client';
@ -29,6 +30,7 @@ import {
workItemResponseFactory,
workItemTitleSubscriptionResponse,
workItemWeightSubscriptionResponse,
workItemAssigneesSubscriptionResponse,
} from '../mock_data';
describe('WorkItemDetail component', () => {
@ -46,6 +48,9 @@ describe('WorkItemDetail component', () => {
const successHandler = jest.fn().mockResolvedValue(workItemQueryResponse);
const datesSubscriptionHandler = jest.fn().mockResolvedValue(workItemDatesSubscriptionResponse);
const titleSubscriptionHandler = jest.fn().mockResolvedValue(workItemTitleSubscriptionResponse);
const assigneesSubscriptionHandler = jest
.fn()
.mockResolvedValue(workItemAssigneesSubscriptionResponse);
const weightSubscriptionHandler = jest.fn().mockResolvedValue(workItemWeightSubscriptionResponse);
const findAlert = () => wrapper.findComponent(GlAlert);
@ -80,6 +85,7 @@ describe('WorkItemDetail component', () => {
[workItemQuery, handler],
[workItemTitleSubscription, subscriptionHandler],
[workItemDatesSubscription, datesSubscriptionHandler],
[workItemAssigneesSubscription, assigneesSubscriptionHandler],
confidentialityMock,
];
@ -413,6 +419,30 @@ describe('WorkItemDetail component', () => {
});
});
describe('assignees subscription', () => {
describe('when the assignees widget exists', () => {
it('calls the assignees subscription', async () => {
createComponent();
await waitForPromises();
expect(assigneesSubscriptionHandler).toHaveBeenCalledWith({
issuableId: workItemQueryResponse.data.workItem.id,
});
});
});
describe('when the assignees widget does not exist', () => {
it('does not call the assignees subscription', async () => {
const response = workItemResponseFactory({ assigneesWidgetPresent: false });
const handler = jest.fn().mockResolvedValue(response);
createComponent({ handler, workItemsMvc2Enabled: true });
await waitForPromises();
expect(assigneesSubscriptionHandler).not.toHaveBeenCalled();
});
});
});
describe('dates subscription', () => {
describe('when the due date widget exists', () => {
it('calls the dates subscription', async () => {

View File

@ -444,6 +444,22 @@ export const workItemWeightSubscriptionResponse = {
},
};
export const workItemAssigneesSubscriptionResponse = {
data: {
issuableAssigneesUpdated: {
id: 'gid://gitlab/WorkItem/1',
widgets: [
{
__typename: 'WorkItemAssigneesWeight',
assignees: {
nodes: [mockAssignees[0]],
},
},
],
},
},
};
export const workItemHierarchyEmptyResponse = {
data: {
workItem: {

Some files were not shown because too many files have changed in this diff Show More