Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-01-05 12:10:36 +00:00
parent a060caf3db
commit 797182cd82
59 changed files with 716 additions and 253 deletions

View File

@ -64,7 +64,7 @@ variables:
BUILD_ASSETS_IMAGE: "false"
ES_JAVA_OPTS: "-Xms256m -Xmx256m"
ELASTIC_URL: "http://elastic:changeme@elasticsearch:9200"
DOCKER_VERSION: "19.03.0"
DOCKER_VERSION: "20.10.1"
CACHE_CLASSES: "true"
# Preparing custom clone path to reduce space used by all random forks

View File

@ -311,6 +311,14 @@ db:check-schema:
script:
- source scripts/schema_changed.sh
db:check-migrations:
extends:
- .db-job-base
- .rails:rules:ee-and-foss-mr-with-migration
script:
- scripts/validate_migration_schema
allow_failure: true
db:migrate-from-v12.10.0:
extends: .db-job-base
variables:

View File

@ -507,6 +507,12 @@
- <<: *if-merge-request
changes: *db-patterns
.rails:rules:ee-and-foss-mr-with-migration:
rules:
- <<: *if-merge-request
changes: *db-patterns
- <<: *if-merge-request-title-run-all-rspec
.rails:rules:ee-and-foss-unit:
rules:
- changes: *backend-patterns

View File

@ -5,59 +5,59 @@ GEM
abstract_type (0.0.7)
acme-client (2.0.6)
faraday (>= 0.17, < 2.0.0)
actioncable (6.0.3.3)
actionpack (= 6.0.3.3)
actioncable (6.0.3.4)
actionpack (= 6.0.3.4)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (6.0.3.3)
actionpack (= 6.0.3.3)
activejob (= 6.0.3.3)
activerecord (= 6.0.3.3)
activestorage (= 6.0.3.3)
activesupport (= 6.0.3.3)
actionmailbox (6.0.3.4)
actionpack (= 6.0.3.4)
activejob (= 6.0.3.4)
activerecord (= 6.0.3.4)
activestorage (= 6.0.3.4)
activesupport (= 6.0.3.4)
mail (>= 2.7.1)
actionmailer (6.0.3.3)
actionpack (= 6.0.3.3)
actionview (= 6.0.3.3)
activejob (= 6.0.3.3)
actionmailer (6.0.3.4)
actionpack (= 6.0.3.4)
actionview (= 6.0.3.4)
activejob (= 6.0.3.4)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (6.0.3.3)
actionview (= 6.0.3.3)
activesupport (= 6.0.3.3)
actionpack (6.0.3.4)
actionview (= 6.0.3.4)
activesupport (= 6.0.3.4)
rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (6.0.3.3)
actionpack (= 6.0.3.3)
activerecord (= 6.0.3.3)
activestorage (= 6.0.3.3)
activesupport (= 6.0.3.3)
actiontext (6.0.3.4)
actionpack (= 6.0.3.4)
activerecord (= 6.0.3.4)
activestorage (= 6.0.3.4)
activesupport (= 6.0.3.4)
nokogiri (>= 1.8.5)
actionview (6.0.3.3)
activesupport (= 6.0.3.3)
actionview (6.0.3.4)
activesupport (= 6.0.3.4)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (6.0.3.3)
activesupport (= 6.0.3.3)
activejob (6.0.3.4)
activesupport (= 6.0.3.4)
globalid (>= 0.3.6)
activemodel (6.0.3.3)
activesupport (= 6.0.3.3)
activerecord (6.0.3.3)
activemodel (= 6.0.3.3)
activesupport (= 6.0.3.3)
activemodel (6.0.3.4)
activesupport (= 6.0.3.4)
activerecord (6.0.3.4)
activemodel (= 6.0.3.4)
activesupport (= 6.0.3.4)
activerecord-explain-analyze (0.1.0)
activerecord (>= 4)
pg
activestorage (6.0.3.3)
actionpack (= 6.0.3.3)
activejob (= 6.0.3.3)
activerecord (= 6.0.3.3)
activestorage (6.0.3.4)
actionpack (= 6.0.3.4)
activejob (= 6.0.3.4)
activerecord (= 6.0.3.4)
marcel (~> 0.3.1)
activesupport (6.0.3.3)
activesupport (6.0.3.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@ -686,7 +686,7 @@ GEM
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
loofah (2.7.0)
loofah (2.8.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lru_redux (1.1.0)
@ -895,20 +895,20 @@ GEM
rack-test (1.1.0)
rack (>= 1.0, < 3)
rack-timeout (0.5.2)
rails (6.0.3.3)
actioncable (= 6.0.3.3)
actionmailbox (= 6.0.3.3)
actionmailer (= 6.0.3.3)
actionpack (= 6.0.3.3)
actiontext (= 6.0.3.3)
actionview (= 6.0.3.3)
activejob (= 6.0.3.3)
activemodel (= 6.0.3.3)
activerecord (= 6.0.3.3)
activestorage (= 6.0.3.3)
activesupport (= 6.0.3.3)
rails (6.0.3.4)
actioncable (= 6.0.3.4)
actionmailbox (= 6.0.3.4)
actionmailer (= 6.0.3.4)
actionpack (= 6.0.3.4)
actiontext (= 6.0.3.4)
actionview (= 6.0.3.4)
activejob (= 6.0.3.4)
activemodel (= 6.0.3.4)
activerecord (= 6.0.3.4)
activestorage (= 6.0.3.4)
activesupport (= 6.0.3.4)
bundler (>= 1.3.0)
railties (= 6.0.3.3)
railties (= 6.0.3.4)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
@ -922,15 +922,15 @@ GEM
rails-i18n (6.0.0)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 7)
railties (6.0.3.3)
actionpack (= 6.0.3.3)
activesupport (= 6.0.3.3)
railties (6.0.3.4)
actionpack (= 6.0.3.4)
activesupport (= 6.0.3.4)
method_source
rake (>= 0.8.7)
thor (>= 0.20.3, < 2.0)
rainbow (3.0.0)
raindrops (0.19.1)
rake (13.0.1)
rake (13.0.3)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
@ -1186,7 +1186,7 @@ GEM
truncato (0.7.11)
htmlentities (~> 4.3.1)
nokogiri (>= 1.7.0, <= 2.0)
tzinfo (1.2.8)
tzinfo (1.2.9)
thread_safe (~> 0.1)
u2f (0.2.1)
uber (0.1.0)
@ -1261,7 +1261,7 @@ GEM
xpath (3.2.0)
nokogiri (~> 1.8)
yajl-ruby (1.4.1)
zeitwerk (2.4.1)
zeitwerk (2.4.2)
PLATFORMS
ruby

View File

@ -11,7 +11,7 @@
* @typedef {String} UUIDv4
*/
import MersenneTwister from 'mersenne-twister';
import { MersenneTwister } from 'fast-mersenne-twister';
import stringHash from 'string-hash';
import { isString } from 'lodash';
import { v4 } from 'uuid';
@ -49,7 +49,7 @@ function randomValuesForUuid(prng) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, prng.random_int());
view.setUint32(0, prng.randomNumber());
randomValues.push(view.getUint8(0), view.getUint8(1), view.getUint8(2), view.getUint8(3));
}

View File

@ -0,0 +1,24 @@
import axios from 'axios';
const getJwt = async () => {
return AP.context.getToken();
};
export const addSubscription = async (addPath, namespace) => {
const jwt = await getJwt();
return axios.post(addPath, {
jwt,
namespace_path: namespace,
});
};
export const removeSubscription = async (removePath) => {
const jwt = await getJwt();
return axios.delete(removePath, {
params: {
jwt,
},
});
};

View File

@ -1,6 +1,9 @@
<script>
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
name: 'JiraConnectApp',
mixins: [glFeatureFlagsMixin()],
computed: {
state() {
return this.$root.$data.state || {};
@ -8,9 +11,17 @@ export default {
error() {
return this.state.error;
},
showNewUi() {
return this.glFeatures.newJiraConnectUi;
},
},
};
</script>
<template>
<div></div>
<div>
<div v-if="showNewUi">
<h3>{{ s__('Integrations|Linked namespaces') }}</h3>
</div>
</div>
</template>

View File

@ -1,6 +1,11 @@
import Vue from 'vue';
import $ from 'jquery';
import setConfigs from '@gitlab/ui/dist/config';
import Translate from '~/vue_shared/translate';
import GlFeatureFlagsPlugin from '~/vue_shared/gl_feature_flags_plugin';
import App from './components/app.vue';
import { addSubscription, removeSubscription } from '~/jira_connect/api';
const store = {
state: {
@ -27,46 +32,35 @@ const initJiraFormHandlers = () => {
alert(error);
};
AP.getLocation((location) => {
$('.js-jira-connect-sign-in').each(function updateSignInLink() {
const updatedLink = `${$(this).attr('href')}?return_to=${location}`;
$(this).attr('href', updatedLink);
if (typeof AP.getLocation === 'function') {
AP.getLocation((location) => {
$('.js-jira-connect-sign-in').each(function updateSignInLink() {
const updatedLink = `${$(this).attr('href')}?return_to=${location}`;
$(this).attr('href', updatedLink);
});
});
});
}
$('#add-subscription-form').on('submit', function onAddSubscriptionForm(e) {
const actionUrl = $(this).attr('action');
const addPath = $(this).attr('action');
const namespace = $('#namespace-input').val();
e.preventDefault();
AP.context.getToken((token) => {
// eslint-disable-next-line no-jquery/no-ajax
$.post(actionUrl, {
jwt: token,
namespace_path: $('#namespace-input').val(),
format: 'json',
})
.done(reqComplete)
.fail((err) => reqFailed(err, 'Failed to add namespace. Please try again.'));
});
addSubscription(addPath, namespace)
.then(reqComplete)
.catch((err) => reqFailed(err.response.data, 'Failed to add namespace. Please try again.'));
});
$('.remove-subscription').on('click', function onRemoveSubscriptionClick(e) {
const href = $(this).attr('href');
const removePath = $(this).attr('href');
e.preventDefault();
AP.context.getToken((token) => {
// eslint-disable-next-line no-jquery/no-ajax
$.ajax({
url: href,
method: 'DELETE',
data: {
jwt: token,
format: 'json',
},
})
.done(reqComplete)
.fail((err) => reqFailed(err, 'Failed to remove namespace. Please try again.'));
});
removeSubscription(removePath)
.then(reqComplete)
.catch((err) =>
reqFailed(err.response.data, 'Failed to remove namespace. Please try again.'),
);
});
};
@ -75,6 +69,14 @@ function initJiraConnect() {
initJiraFormHandlers();
if (!el) {
return null;
}
setConfigs();
Vue.use(Translate);
Vue.use(GlFeatureFlagsPlugin);
return new Vue({
el,
data: {

View File

@ -2,6 +2,11 @@
// We should only import styles that we actually use.
// @import '@gitlab/ui/src/scss/gitlab_ui';
@import '@gitlab/ui/src/scss/bootstrap';
@import 'bootstrap-vue/src/index';
@import '@gitlab/ui/src/scss/utilities';
$atlaskit-border-color: #dfe1e6;
.ac-content {
@ -40,14 +45,16 @@ $header-height: 40px;
}
.jira-connect-user {
float: right;
position: relative;
top: -30px;
font-size: $gl-font-size;
position: fixed;
top: 10px;
right: 20px;
}
.jira-connect-app {
margin-top: $header-height;
max-width: 600px;
min-height: 95vh;
padding-top: 48px;
padding-left: 16px;
padding-right: 16px;
@ -108,5 +115,6 @@ svg {
}
.browser-limitations-notice {
font-size: $gl-font-size;
margin-top: 32px;
}

View File

@ -15,11 +15,6 @@
padding: 11px 0;
}
.wiki-page-title {
margin: 0;
font-size: 22px;
}
.wiki-last-edit-by {
display: block;
color: var(--gray-500, $gray-500);

View File

@ -19,6 +19,9 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
before_action :allow_rendering_in_iframe, only: :index
before_action :verify_qsh_claim!, only: :index
before_action :authenticate_user!, only: :create
before_action do
push_frontend_feature_flag(:new_jira_connect_ui, type: :development, default_enabled: :yaml)
end
def index
@subscriptions = current_jira_installation.subscriptions.preload_namespace_route

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
module JiraConnectHelper
def new_jira_connect_ui?
Feature.enabled?(:new_jira_connect_ui, type: :development, default_enabled: :yaml)
end
end

View File

@ -196,6 +196,10 @@ module Issuable
is_a?(Issue)
end
def supports_assignee?
false
end
def severity
return IssuableSeverity::DEFAULT unless supports_severity?

View File

@ -9,7 +9,9 @@ module IssueAvailableFeatures
class_methods do
# EE only features are listed on EE::IssueAvailableFeatures
def available_features_for_issue_types
{}.with_indifferent_access
{
assignee: %w(issue incident)
}.with_indifferent_access
end
end

View File

@ -405,6 +405,11 @@ class Environment < ApplicationRecord
deployment_platform.patch_ingress(deployment_namespace, ingress, data)
end
def clear_all_caches
expire_etag_cache
clear_reactive_cache!
end
private
def rollout_status_available?

View File

@ -434,6 +434,10 @@ class Issue < ApplicationRecord
moved_to || duplicated_to
end
def supports_assignee?
issue_type_supports?(:assignee)
end
private
def ensure_metrics

View File

@ -1774,6 +1774,10 @@ class MergeRequest < ApplicationRecord
false
end
def supports_assignee?
true
end
private
def with_rebase_lock

View File

@ -104,6 +104,16 @@ class MergeRequestPollCachedWidgetEntity < IssuableEntity
presenter(merge_request).api_unapprove_path
end
expose :blob_path do
expose :head_path, if: -> (mr, _) { mr.source_branch_sha } do |merge_request|
project_blob_path(merge_request.project, merge_request.source_branch_sha)
end
expose :base_path, if: -> (mr, _) { mr.diff_base_sha } do |merge_request|
project_blob_path(merge_request.project, merge_request.diff_base_sha)
end
end
private
delegate :current_user, to: :request

View File

@ -115,16 +115,6 @@ class MergeRequestWidgetEntity < Grape::Entity
end
end
expose :blob_path do
expose :head_path, if: -> (mr, _) { mr.source_branch_sha } do |merge_request|
project_blob_path(merge_request.project, merge_request.source_branch_sha)
end
expose :base_path, if: -> (mr, _) { mr.diff_base_sha } do |merge_request|
project_blob_path(merge_request.project, merge_request.diff_base_sha)
end
end
expose :codeclimate, if: -> (mr, _) { head_pipeline_downloadable_path_for_report_type(:codequality) } do
expose :head_path do |merge_request|
head_pipeline_downloadable_path_for_report_type(:codequality)

View File

@ -24,6 +24,7 @@ module Environments
end
if environment.patch_ingress(canary_ingress, patch_data)
environment.clear_all_caches
success
else
error(_('Failed to update the Canary Ingress.'), :bad_request)

View File

@ -29,17 +29,32 @@ module Groups
group.chat_team&.remove_mattermost_team(current_user)
user_ids_for_project_authorizations_refresh = group.user_ids_for_project_authorizations
# If any other groups are shared with the group that is being destroyed,
# we should specifically trigger update of all project authorizations
# for users that are the members of this group.
# If not, the project authorization records of these users to projects within the shared groups
# will never be removed, causing inconsistencies with access permissions.
if any_other_groups_are_shared_with_this_group?
user_ids_for_project_authorizations_refresh = group.user_ids_for_project_authorizations
end
group.destroy
UserProjectAccessChangedService
.new(user_ids_for_project_authorizations_refresh)
.execute(blocking: true)
if user_ids_for_project_authorizations_refresh.present?
UserProjectAccessChangedService
.new(user_ids_for_project_authorizations_refresh)
.execute(blocking: true)
end
group
end
# rubocop: enable CodeReuse/ActiveRecord
private
def any_other_groups_are_shared_with_this_group?
group.shared_group_links.any?
end
end
end

View File

@ -3,7 +3,7 @@
.container
.gl-mt-3
- if Gitlab.ee? && Feature.enabled?(:devops_adoption_feature, default_enabled: true) && License.feature_available?(:devops_adoption)
- if Gitlab.ee? && License.feature_available?(:devops_adoption)
= render_if_exists 'admin/dev_ops_report/devops_tabs'
- else
= render 'report'

View File

@ -23,15 +23,16 @@
- else
.js-jira-connect-app
%form#add-subscription-form.subscription-form{ action: jira_connect_subscriptions_path }
.ak-field-group
%label
GitLab namespace
- unless new_jira_connect_ui?
%form#add-subscription-form.subscription-form{ action: jira_connect_subscriptions_path }
.ak-field-group
%label
GitLab namespace
.ak-field-group.field-group-input
%input#namespace-input.ak-field-text{ type: 'text', required: true, placeholder: 'e.g. "MyCompany" or "MyCompany/GroupName"' }
%button.ak-button.ak-button__appearance-primary{ type: 'submit' }
Link namespace to Jira
.ak-field-group.field-group-input
%input#namespace-input.ak-field-text{ type: 'text', required: true, placeholder: 'e.g. "MyCompany" or "MyCompany/GroupName"' }
%button.ak-button.ak-button__appearance-primary{ type: 'submit' }
Link namespace to Jira
- if @subscriptions.present?
%table.subscriptions
@ -49,6 +50,7 @@
- else
%h4.empty-subscriptions
No linked namespaces
%p= s_('Integrations|Namespaces are your GitLab groups and subgroups that will be linked to this Jira instance.')
%p.browser-limitations-notice
%strong Browser limitations:

View File

@ -3,8 +3,9 @@
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
%title
GitLab
= stylesheet_link_tag 'https://unpkg.com/@atlaskit/css-reset@3.0.6/dist/bundle.css'
= stylesheet_link_tag 'https://unpkg.com/@atlaskit/reduced-ui-pack@10.5.5/dist/bundle.css'
- unless new_jira_connect_ui?
= stylesheet_link_tag 'https://unpkg.com/@atlaskit/css-reset@3.0.6/dist/bundle.css'
= stylesheet_link_tag 'https://unpkg.com/@atlaskit/reduced-ui-pack@10.5.5/dist/bundle.css'
= yield :page_specific_styles
= javascript_include_tag 'https://connect-cdn.atl-paas.net/all.js'

View File

@ -16,7 +16,7 @@
%code v*
or
%code *-release
are supported
are supported.
.form-group.row
%label.col-md-2.text-right{ for: 'create_access_levels_attributes' }
Allowed to create:

View File

@ -7,16 +7,14 @@
%button.btn.js-settings-toggle{ type: 'button' }
= expanded ? 'Collapse' : 'Expand'
%p
Limit access to creating and updating tags.
Limit access to creating and updating tags. #{link_to "What are protected tags?", help_page_path("user/project/protected_tags")}
.settings-content
%p
By default, protected tags are designed to:
By default, protected tags protect your code and:
%ul
%li Prevent tag creation by everybody except Maintainers
%li Prevent <strong>anyone</strong> from updating the tag
%li Prevent <strong>anyone</strong> from deleting the tag
%p Read more about #{link_to "protected tags", help_page_path("user/project/protected_tags")}.
%li Allow only users with Maintainer #{link_to "permissions", help_page_path("user/permissions")} to create tags.
%li Prevent <strong>anyone</strong> from updating tags.
%li Prevent <strong>anyone</strong> from deleting tags.
- if can? current_user, :admin_project, @project
= yield :create_protected_tag

View File

@ -1,9 +1,9 @@
.protected-tags-list.js-protected-tags-list
- if @protected_tags.empty?
.card-header
Protected tag (#{@protected_tags_count})
Protected tags (#{@protected_tags_count})
%p.settings-message.text-center
There are currently no protected tags, protect a tag with the form above.
No tags are protected.
- else
- can_admin_project = can?(current_user, :admin_project, @project)
@ -16,7 +16,7 @@
%col
%thead
%tr
%th Protected tag (#{@protected_tags_count})
%th Protected tags (#{@protected_tags_count})
%th Last commit
%th Allowed to create
- if can_admin_project

View File

@ -5,12 +5,11 @@
.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
= wiki_sidebar_toggle_button
.nav-text
%h2.wiki-page-title
= link_to_wiki_page @page
%span.light
&middot;
= _('Changes')
%h3.page-title.gl-flex-fill-1
= link_to_wiki_page @page
%span.light
&middot;
= _('Changes')
.nav-controls.pb-md-3.pb-lg-0
= link_to wiki_page_path(@wiki, @page, action: :history), class: 'btn gl-button', role: 'button', data: { qa_selector: 'page_history_button' } do

View File

@ -6,15 +6,14 @@
.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
= wiki_sidebar_toggle_button
.nav-text
%h2.wiki-page-title
- if @page.persisted?
= link_to_wiki_page @page
%span.light
&middot;
= s_("Wiki|Edit Page")
- else
= s_("Wiki|Create New Page")
%h3.page-title.gl-flex-fill-1
- if @page.persisted?
= link_to_wiki_page @page
%span.light
&middot;
= s_("Wiki|Edit Page")
- else
= s_("Wiki|Create New Page")
.nav-controls.pb-md-3.pb-lg-0
- if @page.persisted?

View File

@ -4,12 +4,11 @@
.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
= wiki_sidebar_toggle_button
.nav-text
%h2.wiki-page-title
= link_to_wiki_page @page
%span.light
&middot;
= _('History')
%h3.page-title
= link_to_wiki_page @page
%span.light
&middot;
= _('History')
.prepend-top-default.gl-mb-3
.table-holder

View File

@ -6,9 +6,9 @@
.wiki-page-header.top-area.flex-column.flex-lg-row
.nav-text.flex-fill
%h2.wiki-page-title
= s_("Wiki|Wiki Pages")
%h3.page-title.gl-flex-fill-1
= s_("Wiki|Wiki Pages")
.nav-controls.pb-md-3.pb-lg-0
= link_to wiki_path(@wiki, action: :git_access), class: 'btn gl-button' do

View File

@ -0,0 +1,6 @@
---
title: During group deletion, only enqueue jobs for project_authorizations refresh
if the group being deleted has other groups shared with it
merge_request: 50617
author:
type: performance

View File

@ -0,0 +1,5 @@
---
title: Update Docker from 19.03.0 to 20.10.1 on CI/CD
merge_request: 50732
author: Takuya Noguchi
type: other

View File

@ -0,0 +1,5 @@
---
title: Updated UI text to match style guidelines
merge_request: 50476
author:
type: other

View File

@ -0,0 +1,5 @@
---
title: Fix Canary Ingress weight is not reflected on UI immediately
merge_request: 50246
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Switch to 2x faster PRNG
merge_request: 50811
author:
type: performance

View File

@ -0,0 +1,5 @@
---
title: Standardize page title styles on all wiki pages
merge_request: 49777
author:
type: changed

View File

@ -1,8 +1,8 @@
---
name: devops_adoption_feature
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46005
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/271568
milestone: '13.6'
name: new_jira_connect_ui
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50692
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/295647
milestone: '13.8'
type: development
group: group::analytics
default_enabled: true
group: group::ecosystem
default_enabled: false

View File

@ -7,12 +7,12 @@ NO_SPECS_LABELS = [
'documentation',
'QA'
].freeze
NO_NEW_SPEC_MESSAGE = <<~MSG
NO_NEW_SPEC_MESSAGE = <<~MSG.freeze
You've made some app changes, but didn't add any tests.
That's OK as long as you're refactoring existing code,
but please consider adding any of the %<labels>s labels.
MSG
EE_CHANGE_WITH_FOSS_SPEC_CHANGE_MESSAGE = <<~MSG
EE_CHANGE_WITH_FOSS_SPEC_CHANGE_MESSAGE = <<~MSG.freeze
You've made some EE-specific changes, but only made changes to FOSS tests.
This could be a sign that you're testing an EE-specific behavior in a FOSS test.
@ -24,6 +24,14 @@ Please make sure the spec files pass in AS-IF-FOSS mode either:
MSG
CONTROLLER_SPEC_DEPRECATION_MESSAGE = <<~MSG.freeze
Do not add new controller specs. We are moving from controller specs to
request specs (and/or feature specs). Please add request specs under
`/spec/requests` and/or `/ee/spec/requests` instead.
See https://gitlab.com/groups/gitlab-org/-/epics/5076 for information.
MSG
has_app_changes = helper.all_changed_files.grep(%r{\A(app|lib|db/(geo/)?(post_)?migrate)/}).any?
has_ee_app_changes = helper.all_changed_files.grep(%r{\Aee/(app|lib|db/(geo/)?(post_)?migrate)/}).any?
spec_changes = helper.all_changed_files.grep(%r{\Aspec/})
@ -39,3 +47,8 @@ end
if has_ee_app_changes && has_spec_changes && !(has_app_changes || has_ee_spec_changes)
warn format(EE_CHANGE_WITH_FOSS_SPEC_CHANGE_MESSAGE, spec_files: spec_changes.join(" "), mr_title: gitlab.mr_json['title']), sticky: false
end
# Forbidding a new file addition under `/spec/controllers` or `/ee/spec/controllers`
if git.added_files.grep(%r{^(ee/)?spec/controllers/}).any?
warn CONTROLLER_SPEC_DEPRECATION_MESSAGE
end

View File

@ -59,21 +59,3 @@ DevOps Adoption allows you to:
- Find the groups that have adopted certain features and can provide guidance to other groups on how to use those features.
![DevOps Report](img/dev_ops_adoption_v13_7.png)
### Disable or enable DevOps Adoption
DevOps Adoption is deployed behind a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
can opt to disable it.
To disable it:
```ruby
Feature.disable(:devops_adoption_feature)
```
To enable it:
```ruby
Feature.enable(:devops_adoption_feature)
```

View File

@ -91,7 +91,7 @@ module.exports = (path) => {
'^.+\\.(md|zip|png)$': 'jest-raw-loader',
},
transformIgnorePatterns: [
'node_modules/(?!(@gitlab/ui|bootstrap-vue|three|monaco-editor|monaco-yaml)/)',
'node_modules/(?!(@gitlab/ui|bootstrap-vue|three|monaco-editor|monaco-yaml|fast-mersenne-twister)/)',
],
timers: 'fake',
testEnvironment: '<rootDir>/spec/frontend/environment.js',

View File

@ -26,7 +26,7 @@ module Gitlab
end
types Issue, MergeRequest
condition do
current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project)
quick_action_target.supports_assignee? && current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project)
end
parse_params do |assignee_param|
extract_users(assignee_param)

View File

@ -15135,6 +15135,12 @@ msgstr ""
msgid "Integrations|Issues created in Jira are shown here once you have created the issues in project setup in Jira."
msgstr ""
msgid "Integrations|Linked namespaces"
msgstr ""
msgid "Integrations|Namespaces are your GitLab groups and subgroups that will be linked to this Jira instance."
msgstr ""
msgid "Integrations|Projects using custom settings will not be affected."
msgstr ""

View File

@ -46,8 +46,8 @@
"@gitlab/tributejs": "1.0.0",
"@gitlab/ui": "25.2.1",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "^6.0.3-3",
"@rails/ujs": "^6.0.3-2",
"@rails/actioncable": "^6.0.3-4",
"@rails/ujs": "^6.0.3-4",
"@sourcegraph/code-host-integration": "0.0.52",
"@toast-ui/editor": "^2.5.1",
"@toast-ui/vue-editor": "^2.5.1",
@ -87,6 +87,7 @@
"emoji-regex": "^7.0.3",
"emoji-unicode-version": "^0.2.1",
"exports-loader": "^0.7.0",
"fast-mersenne-twister": "1.0.2",
"file-loader": "^5.1.0",
"font-awesome": "4.7.0",
"fuzzaldrin-plus": "^0.6.0",
@ -110,7 +111,6 @@
"marked": "^0.3.12",
"mathjax": "3",
"mermaid": "^8.5.2",
"mersenne-twister": "1.1.0",
"minimatch": "^3.0.4",
"miragejs": "^0.1.40",
"mock-apollo-client": "^0.5.0",

View File

@ -2,7 +2,7 @@ GEM
remote: https://rubygems.org/
specs:
abstract_type (0.0.7)
activesupport (6.0.3.3)
activesupport (6.0.3.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@ -127,7 +127,7 @@ GEM
rubyzip (>= 1.2.2)
thread_safe (0.3.6)
timecop (0.9.1)
tzinfo (1.2.7)
tzinfo (1.2.9)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
@ -142,7 +142,7 @@ GEM
procto (~> 0.0.2)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.4.0)
zeitwerk (2.4.2)
PLATFORMS
ruby

119
scripts/validate_migration_schema Executable file
View File

@ -0,0 +1,119 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'open3'
class MigrationSchemaValidator
FILENAME = 'db/structure.sql'
MIGRATION_DIRS = %w[db/migrate db/post_migrate].freeze
SCHEMA_VERSION_DIR = 'db/schema_migrations'
VERSION_DIGITS = 14
def validate!
if committed_migrations.empty?
puts "\e[32m No migrations found, skipping schema validation\e[0m"
return
end
validate_schema_on_rollback!
validate_schema_on_migrate!
validate_schema_version_files!
end
private
def validate_schema_on_rollback!
committed_migrations.each do |filename|
version = find_migration_version(filename)
run("bin/rails db:migrate:down VERSION=#{version}")
end
git_command = "git diff #{diff_target} -- #{FILENAME}"
base_message = "rollback of added migrations does not revert #{FILENAME} to previous state"
validate_clean_output!(git_command, base_message)
end
def validate_schema_on_migrate!
run('bin/rails db:migrate')
git_command = "git diff -- #{FILENAME}"
base_message = "the committed #{FILENAME} does not match the one generated by running added migrations"
validate_clean_output!(git_command, base_message)
end
def validate_schema_version_files!
git_command = "git add -A -n #{SCHEMA_VERSION_DIR}"
base_message = "the committed files in #{SCHEMA_VERSION_DIR} do not match those expected by the added migrations"
validate_clean_output!(git_command, base_message)
end
def committed_migrations
@committed_migrations ||= begin
git_command = "git diff --name-only --diff-filter=A #{diff_target} -- #{MIGRATION_DIRS.join(' ')}"
run(git_command).split("\n")
end
end
def diff_target
@diff_target ||= pipeline_for_merged_results? ? target_branch : merge_base
end
def merge_base
run("git merge-base #{target_branch} #{source_ref}")
end
def target_branch
ENV['CI_MERGE_REQUEST_TARGET_BRANCH_NAME'] || ENV['TARGET'] || 'master'
end
def source_ref
ENV['CI_COMMIT_SHA'] || 'HEAD'
end
def pipeline_for_merged_results?
ENV.key?('CI_MERGE_REQUEST_SOURCE_BRANCH_SHA')
end
def find_migration_version(filename)
file_basename = File.basename(filename)
version_match = /\A(?<version>\d{#{VERSION_DIGITS}})_/.match(file_basename)
die "#{filename} has an invalid migration version" if version_match.nil?
version_match[:version]
end
def validate_clean_output!(command, base_message)
command_output = run(command)
return if command_output.empty?
die "#{base_message}:\n#{command_output}"
end
def die(message, error_code: 1)
puts "\e[31mError: #{message}\e[0m"
exit error_code
end
def run(cmd)
puts "\e[32m$ #{cmd}\e[37m"
stdout_str, stderr_str, status = Open3.capture3(cmd)
puts "#{stdout_str}#{stderr_str}\e[0m"
die "command failed: #{stderr_str}" unless status.success?
stdout_str.chomp
end
end
MigrationSchemaValidator.new.validate!

View File

@ -68,7 +68,7 @@ RSpec.describe 'Protected Tags', :js do
click_on "Protect"
within(".protected-tags-list") do
expect(page).to have_content("Protected tag (2)")
expect(page).to have_content("Protected tags (2)")
expect(page).to have_content("2 matching tags")
end
end

View File

@ -0,0 +1,75 @@
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import httpStatus from '~/lib/utils/http_status';
import { addSubscription, removeSubscription } from '~/jira_connect/api';
describe('JiraConnect API', () => {
let mock;
let response;
const mockAddPath = 'addPath';
const mockRemovePath = 'removePath';
const mockNamespace = 'namespace';
const mockJwt = 'jwt';
const mockResponse = { success: true };
const tokenSpy = jest.fn().mockReturnValue(mockJwt);
window.AP = {
context: {
getToken: tokenSpy,
},
};
beforeEach(() => {
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
response = null;
});
describe('addSubscription', () => {
const makeRequest = () => addSubscription(mockAddPath, mockNamespace);
it('returns success response', async () => {
jest.spyOn(axios, 'post');
mock
.onPost(mockAddPath, {
jwt: mockJwt,
namespace_path: mockNamespace,
})
.replyOnce(httpStatus.OK, mockResponse);
response = await makeRequest();
expect(tokenSpy).toHaveBeenCalled();
expect(axios.post).toHaveBeenCalledWith(mockAddPath, {
jwt: mockJwt,
namespace_path: mockNamespace,
});
expect(response.data).toEqual(mockResponse);
});
});
describe('removeSubscription', () => {
const makeRequest = () => removeSubscription(mockRemovePath);
it('returns success response', async () => {
jest.spyOn(axios, 'delete');
mock.onDelete(mockRemovePath).replyOnce(httpStatus.OK, mockResponse);
response = await makeRequest();
expect(tokenSpy).toHaveBeenCalled();
expect(axios.delete).toHaveBeenCalledWith(mockRemovePath, {
params: {
jwt: mockJwt,
},
});
expect(response.data).toEqual(mockResponse);
});
});
});

View File

@ -0,0 +1,45 @@
import { shallowMount } from '@vue/test-utils';
import JiraConnectApp from '~/jira_connect/components/app.vue';
describe('JiraConnectApp', () => {
let wrapper;
const createComponent = (options = {}) => {
wrapper = shallowMount(JiraConnectApp, {
provide: {
glFeatures: { newJiraConnectUi: true },
},
...options,
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findHeader = () => wrapper.find('h3');
const findHeaderText = () => findHeader().text();
describe('template', () => {
it('renders new UI', () => {
createComponent();
expect(findHeader().exists()).toBe(true);
expect(findHeaderText()).toBe('Linked namespaces');
});
describe('newJiraConnectUi is false', () => {
it('does not render new UI', () => {
createComponent({
provide: {
glFeatures: { newJiraConnectUi: false },
},
});
expect(findHeader().exists()).toBe(false);
});
});
});
});

View File

@ -1547,4 +1547,18 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
end
end
describe '#clear_all_caches' do
subject { environment.clear_all_caches }
it 'clears all caches on the environment' do
expect_next_instance_of(Gitlab::EtagCaching::Store) do |store|
expect(store).to receive(:touch).with(environment.etag_cache_key)
end
expect(environment).to receive(:clear_reactive_cache!)
subject
end
end
end

View File

@ -8,6 +8,7 @@ RSpec.describe MergeRequestPollCachedWidgetEntity do
let_it_be(:project, refind: true) { create :project, :repository }
let_it_be(:resource, refind: true) { create(:merge_request, source_project: project, target_project: project) }
let_it_be(:user) { create(:user) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:request) { double('request', current_user: user, project: project) }
@ -25,6 +26,17 @@ RSpec.describe MergeRequestPollCachedWidgetEntity do
expect(subject[:merge_status]).to eq 'checking'
end
it 'has blob path data' do
allow(resource).to receive_messages(
base_pipeline: pipeline,
head_pipeline: pipeline
)
expect(subject).to include(:blob_path)
expect(subject[:blob_path]).to include(:base_path)
expect(subject[:blob_path]).to include(:head_path)
end
describe 'diverged_commits_count' do
context 'when MR open and its diverging' do
it 'returns diverged commits count' do

View File

@ -76,17 +76,6 @@ RSpec.describe MergeRequestWidgetEntity do
.to eq("/#{resource.project.full_path}/-/merge_requests/#{resource.iid}.diff")
end
it 'has blob path data' do
allow(resource).to receive_messages(
base_pipeline: pipeline,
head_pipeline: pipeline
)
expect(subject).to include(:blob_path)
expect(subject[:blob_path]).to include(:base_path)
expect(subject[:blob_path]).to include(:head_path)
end
describe 'codequality report artifacts', :request_store do
let(:merge_base_pipeline) { create(:ci_pipeline, :with_codequality_report, project: project) }

View File

@ -117,6 +117,12 @@ RSpec.describe Environments::CanaryIngress::UpdateService, :clean_gitlab_redis_c
expect(subject[:status]).to eq(:success)
expect(subject[:message]).to be_nil
end
it 'clears all caches' do
expect(environment).to receive(:clear_all_caches)
subject
end
end
context 'when patch request does not succeed' do

View File

@ -135,51 +135,120 @@ RSpec.describe Groups::DestroyService do
end
describe 'authorization updates', :sidekiq_inline do
context 'shared groups' do
context 'for solo groups' do
context 'group is deleted' do
it 'updates project authorization' do
expect { destroy_group(group, user, false) }.to(
change { user.can?(:read_project, project) }.from(true).to(false))
end
it 'does not make use of a specific service to update project_authorizations records' do
expect(UserProjectAccessChangedService)
.not_to receive(:new).with(group.user_ids_for_project_authorizations)
destroy_group(group, user, false)
end
end
end
context 'for shared groups within different hierarchies' do
let(:shared_with_group) { group }
let!(:shared_group) { create(:group, :private) }
let!(:shared_group_child) { create(:group, :private, parent: shared_group) }
let!(:shared_group_user) { create(:user) }
let!(:project) { create(:project, group: shared_group) }
let!(:project_child) { create(:project, group: shared_group_child) }
before do
create(:group_group_link, shared_group: shared_group, shared_with_group: group)
group.refresh_members_authorized_projects
shared_group.add_user(shared_group_user, Gitlab::Access::OWNER)
create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_group)
shared_with_group.refresh_members_authorized_projects
end
it 'updates project authorization' do
expect(user.can?(:read_project, project)).to eq(true)
expect(user.can?(:read_project, project_child)).to eq(true)
destroy_group(group, user, false)
expect(user.can?(:read_project, project)).to eq(false)
expect(user.can?(:read_project, project_child)).to eq(false)
end
end
context 'shared groups in the same group hierarchy' do
let!(:subgroup) { create(:group, :private, parent: group) }
let!(:subgroup_user) { create(:user) }
before do
subgroup.add_user(subgroup_user, Gitlab::Access::MAINTAINER)
create(:group_group_link, shared_group: group, shared_with_group: subgroup)
subgroup.refresh_members_authorized_projects
end
context 'group is deleted' do
context 'the shared group is deleted' do
it 'updates project authorization' do
expect { destroy_group(group, user, false) }.to(
change { subgroup_user.can?(:read_project, project) }.from(true).to(false))
expect(shared_group_user.can?(:read_project, project)).to eq(true)
expect(shared_group_user.can?(:read_project, project_child)).to eq(true)
destroy_group(shared_group, shared_group_user, false)
expect(shared_group_user.can?(:read_project, project)).to eq(false)
expect(shared_group_user.can?(:read_project, project_child)).to eq(false)
end
it 'does not make use of specific service to update project_authorizations records' do
expect(UserProjectAccessChangedService)
.not_to receive(:new).with(shared_group.user_ids_for_project_authorizations).and_call_original
destroy_group(shared_group, shared_group_user, false)
end
end
context 'subgroup is deleted' do
context 'the shared_with group is deleted' do
it 'updates project authorization' do
expect { destroy_group(subgroup, user, false) }.to(
change { subgroup_user.can?(:read_project, project) }.from(true).to(false))
expect(user.can?(:read_project, project)).to eq(true)
expect(user.can?(:read_project, project_child)).to eq(true)
destroy_group(shared_with_group, user, false)
expect(user.can?(:read_project, project)).to eq(false)
expect(user.can?(:read_project, project_child)).to eq(false)
end
it 'makes use of a specific service to update project_authorizations records' do
expect(UserProjectAccessChangedService)
.to receive(:new).with(shared_with_group.user_ids_for_project_authorizations).and_call_original
destroy_group(shared_with_group, user, false)
end
end
end
context 'for shared groups in the same group hierarchy' do
let(:shared_group) { group }
let(:shared_with_group) { nested_group }
let!(:shared_with_group_user) { create(:user) }
before do
shared_with_group.add_user(shared_with_group_user, Gitlab::Access::MAINTAINER)
create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_group)
shared_with_group.refresh_members_authorized_projects
end
context 'the shared group is deleted' do
it 'updates project authorization' do
expect { destroy_group(shared_group, user, false) }.to(
change { shared_with_group_user.can?(:read_project, project) }.from(true).to(false))
end
it 'does not make use of a specific service to update project authorizations' do
# Due to the recursive nature of `Groups::DestroyService`, `UserProjectAccessChangedService`
# will still be executed for the nested group as they fall under the same hierarchy
# and hence we need to account for this scenario.
expect(UserProjectAccessChangedService)
.to receive(:new).with(shared_with_group.user_ids_for_project_authorizations).and_call_original
expect(UserProjectAccessChangedService)
.not_to receive(:new).with(shared_group.user_ids_for_project_authorizations)
destroy_group(shared_group, user, false)
end
end
context 'the shared_with group is deleted' do
it 'updates project authorization' do
expect { destroy_group(shared_with_group, user, false) }.to(
change { shared_with_group_user.can?(:read_project, project) }.from(true).to(false))
end
it 'makes use of a specific service to update project authorizations' do
expect(UserProjectAccessChangedService)
.to receive(:new).with(shared_with_group.user_ids_for_project_authorizations).and_call_original
destroy_group(shared_with_group, user, false)
end
end
end

View File

@ -777,6 +777,11 @@ RSpec.describe QuickActions::InterpretService do
let(:issuable) { issue }
end
it_behaves_like 'assign command' do
let(:content) { "/assign @#{developer.username}" }
let(:issuable) { create(:incident, project: project) }
end
it_behaves_like 'assign command' do
let(:content) { "/assign @#{developer.username}" }
let(:issuable) { merge_request }

View File

@ -79,7 +79,7 @@ RSpec.shared_examples 'User creates wiki page' do
expect(current_path).to eq(wiki_page_path(wiki, "test"))
page.within(:css, ".nav-text") do
page.within(:css, ".wiki-page-header") do
expect(page).to have_content("Create New Page")
end
@ -91,7 +91,7 @@ RSpec.shared_examples 'User creates wiki page' do
expect(current_path).to eq(wiki_page_path(wiki, "api"))
page.within(:css, ".nav-text") do
page.within(:css, ".wiki-page-header") do
expect(page).to have_content("Create")
end
@ -103,7 +103,7 @@ RSpec.shared_examples 'User creates wiki page' do
expect(current_path).to eq(wiki_page_path(wiki, "raketasks"))
page.within(:css, ".nav-text") do
page.within(:css, ".wiki-page-header") do
expect(page).to have_content("Create")
end
end

View File

@ -15,6 +15,6 @@ RSpec.shared_examples 'User uses wiki shortcuts' do
it 'visit edit wiki page using "e" keyboard shortcut', :js do
find('body').native.send_key('e')
expect(find('.wiki-page-title')).to have_content('Edit Page')
expect(find('.page-title')).to have_content('Edit Page')
end
end

View File

@ -44,7 +44,7 @@ RSpec.shared_examples 'User views a wiki page' do
expect(current_path).to include('one/two/three-test')
page.within(:css, '.nav-text') do
page.within(:css, '.wiki-page-header') do
expect(page).to have_content('History')
end
end
@ -69,7 +69,7 @@ RSpec.shared_examples 'User views a wiki page' do
click_on('Page history')
within('.nav-text') do
within('.wiki-page-header') do
expect(page).to have_content('History')
end

View File

@ -1124,15 +1124,15 @@
consola "^2.10.1"
node-fetch "^2.6.0"
"@rails/actioncable@^6.0.3-3":
version "6.0.3-3"
resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-6.0.3-3.tgz#fb1a46d3d353512764d5fa3cea2f492391601b7a"
integrity sha512-+DEbtzvD2ITPKOGBAV0lLdUvImCsHtUYfxwW7TDKOrGNEFqgbVJij7aO6ZE8a3aDPQ7NnO/MlyrPwLVeiIZRSw==
"@rails/actioncable@^6.0.3-4":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-6.1.0.tgz#f336f25450b1bc43b99bc60557a70b6e6bb1d3d2"
integrity sha512-eDgy+vcKN9RIzxmMBfSAe77rTj2cp6kJALiVQyKrW2O9EK2MdostOmP+99At/Dit3ur5+77NVnruxD7y14ZYFA==
"@rails/ujs@^6.0.3-2":
version "6.0.3-2"
resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-6.0.3-2.tgz#e14c1f29086858215ce7ccd9ad6d8888c458b4a3"
integrity sha512-WcpIEftNCfGDEgk6KerOugiet75Mir5q/HT1yt3dDhpBI91BaZ15lfSQIsZwMw2nyeDz9A9QBz8dAFAd4gXIzg==
"@rails/ujs@^6.0.3-4":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-6.1.0.tgz#9a48df6511cb2b472c9f596c1f37dc0af022e751"
integrity sha512-kQNKyM4ePAc4u9eR1c4OqrbAHH+3SJXt++8izIjeaZeg+P7yBtgoF/dogMD/JPPowNC74ACFpM/4op0Ggp/fPw==
"@sindresorhus/is@^0.14.0":
version "0.14.0"
@ -5009,6 +5009,11 @@ fast-levenshtein@~2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
fast-mersenne-twister@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/fast-mersenne-twister/-/fast-mersenne-twister-1.0.2.tgz#5ead7caf3ace592a5789d11767732bd81cbaaa56"
integrity sha512-IaClPxsoBu3MxGpcURyjV8otT5Bj4ARoK0KBCJGnEVnD1A/qclL5eIeYiUuwG/WWJPxL1jlK61HTm2T6SBmvBQ==
fault@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.2.tgz#c3d0fec202f172a3a4d414042ad2bb5e2a3ffbaa"
@ -8190,11 +8195,6 @@ mermaid@^8.5.2:
moment-mini "^2.22.1"
scope-css "^1.2.1"
mersenne-twister@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a"
integrity sha1-+RZhjuQ9cXnvz2Qb7EUx65Zwl4o=
methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"