Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
e534c1d1ae
commit
03acdf2a1f
|
|
@ -1,12 +1,16 @@
|
|||
<script>
|
||||
import { GlIcon, GlLink } from '@gitlab/ui';
|
||||
import { GlIcon, GlLink, GlBadge } from '@gitlab/ui';
|
||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||
import mergeRequestsWidgetMetadataQuery from '../graphql/queries/merge_requests_widget_metadata.query.graphql';
|
||||
|
||||
export default {
|
||||
name: 'MergeRequestsWidget',
|
||||
components: {
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlBadge,
|
||||
},
|
||||
mixins: [timeagoMixin],
|
||||
props: {
|
||||
reviewRequestedPath: {
|
||||
type: String,
|
||||
|
|
@ -17,6 +21,36 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
metadata: {},
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
metadata: {
|
||||
query: mergeRequestsWidgetMetadataQuery,
|
||||
update({ currentUser }) {
|
||||
return currentUser;
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isLoadingMetadata() {
|
||||
return this.$apollo.queries.metadata.loading;
|
||||
},
|
||||
reviewRequestedCount() {
|
||||
return this.metadata?.reviewRequestedMergeRequests?.count ?? 0;
|
||||
},
|
||||
reviewRequestedLastUpdatedAt() {
|
||||
return this.metadata?.reviewRequestedMergeRequests?.nodes?.[0]?.updatedAt ?? null;
|
||||
},
|
||||
assignedCount() {
|
||||
return this.metadata?.assignedMergeRequests?.count ?? 0;
|
||||
},
|
||||
assignedLastUpdatedAt() {
|
||||
return this.metadata?.assignedMergeRequests?.nodes?.[0]?.updatedAt ?? null;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -26,11 +60,29 @@ export default {
|
|||
<gl-icon name="merge-request" :size="16" />{{ __('Merge requests') }}
|
||||
</h4>
|
||||
<ul class="gl-list-none gl-p-0">
|
||||
<li>
|
||||
<li class="gl-flex gl-items-center gl-gap-3">
|
||||
<gl-link :href="reviewRequestedPath">{{ __('Review requested') }}</gl-link>
|
||||
<template v-if="!isLoadingMetadata">
|
||||
<gl-badge data-testid="review-requested-count">{{ reviewRequestedCount }}</gl-badge>
|
||||
<span
|
||||
v-if="reviewRequestedLastUpdatedAt"
|
||||
data-testid="review-requested-last-updated-at"
|
||||
class="gl-ml-auto gl-text-subtle"
|
||||
>{{ timeFormatted(reviewRequestedLastUpdatedAt) }}</span
|
||||
>
|
||||
</template>
|
||||
</li>
|
||||
<li>
|
||||
<li class="gl-flex gl-items-center gl-gap-3">
|
||||
<gl-link :href="assignedToYouPath">{{ __('Assigned to you') }}</gl-link>
|
||||
<template v-if="!isLoadingMetadata">
|
||||
<gl-badge data-testid="assigned-count">{{ assignedCount }}</gl-badge>
|
||||
<span
|
||||
v-if="assignedLastUpdatedAt"
|
||||
data-testid="assigned-last-updated-at"
|
||||
class="gl-ml-auto gl-text-subtle"
|
||||
>{{ timeFormatted(assignedLastUpdatedAt) }}</span
|
||||
>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
query MergeRequestsWidgetMetadata {
|
||||
currentUser {
|
||||
id
|
||||
reviewRequestedMergeRequests(first: 1, sort: UPDATED_DESC, state: opened) {
|
||||
count
|
||||
nodes {
|
||||
id
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
assignedMergeRequests(first: 1, sort: UPDATED_DESC, state: opened) {
|
||||
count
|
||||
nodes {
|
||||
id
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,8 +7,20 @@ module HomepageData
|
|||
|
||||
def homepage_app_data(user)
|
||||
{
|
||||
review_requested_path: merge_requests_dashboard_path(reviewer_username: user.username),
|
||||
assigned_to_you_path: merge_requests_dashboard_path(assignee_username: user.username)
|
||||
review_requested_path: review_requested_path(user),
|
||||
assigned_to_you_path: assigned_to_you_path(user)
|
||||
}
|
||||
end
|
||||
|
||||
def review_requested_path(user)
|
||||
return merge_requests_dashboard_path if Feature.enabled?(:merge_request_dashboard, user)
|
||||
|
||||
merge_requests_dashboard_path(reviewer_username: user.username)
|
||||
end
|
||||
|
||||
def assigned_to_you_path(user)
|
||||
return merge_requests_dashboard_path if Feature.enabled?(:merge_request_dashboard, user)
|
||||
|
||||
merge_requests_dashboard_path(assignee_username: user.username)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class RootController < Dashboard::ProjectsController
|
|||
CACHE_CONTROL_HEADER = 'no-store'
|
||||
|
||||
def index
|
||||
@homepage_app_data = @current_user.nil? ? {} : homepage_app_data(@current_user)
|
||||
@homepage_app_data = homepage_app_data(current_user)
|
||||
render('root/index') && return if Feature.enabled?(:personal_homepage, current_user)
|
||||
|
||||
super
|
||||
|
|
|
|||
|
|
@ -496,8 +496,8 @@ module Ci
|
|||
end
|
||||
end
|
||||
|
||||
def archived?
|
||||
degenerated? || super
|
||||
def archived?(...)
|
||||
degenerated? || super(...)
|
||||
end
|
||||
|
||||
def playable?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ci
|
||||
class JobRedisState
|
||||
include ActiveModel::Model
|
||||
include ActiveModel::Attributes
|
||||
|
||||
class RedisBool < ::ActiveRecord::Type::Value
|
||||
def deserialize(value)
|
||||
::Gitlab::Redis::Boolean.decode(value)
|
||||
end
|
||||
|
||||
def serialize(value)
|
||||
::Gitlab::Redis::Boolean.encode(value)
|
||||
end
|
||||
end
|
||||
|
||||
UnpersistedJobError = Class.new(StandardError)
|
||||
|
||||
REDIS_TTL = 300
|
||||
REDIS_KEY = "ci_job_redis_state:{%{project_id}}:%{job_id}"
|
||||
|
||||
attribute :enqueue_immediately, RedisBool.new, default: false
|
||||
|
||||
def self.find_or_initialize_by(job:)
|
||||
with_redis do |redis|
|
||||
redis_attributes = redis.hgetall(redis_key(job.project_id, job.id))
|
||||
deserialized_attrs = redis_attributes.each.with_object({}) do |(key, value), result|
|
||||
result[key] = attribute_types[key].deserialize(value)
|
||||
end
|
||||
|
||||
new(deserialized_attrs.merge(job: job))
|
||||
end
|
||||
end
|
||||
|
||||
def self.redis_key(project_id, job_id)
|
||||
format(REDIS_KEY, project_id: project_id, job_id: job_id)
|
||||
end
|
||||
|
||||
def self.with_redis(&block)
|
||||
::Gitlab::Redis::SharedState.with(&block)
|
||||
end
|
||||
|
||||
def initialize(attributes = {})
|
||||
@job = attributes.delete(:job)
|
||||
super
|
||||
end
|
||||
|
||||
# We need a job_id to save the record in Redis
|
||||
def save
|
||||
raise UnpersistedJobError unless job.persisted?
|
||||
|
||||
with_redis do |redis|
|
||||
redis.multi do |transaction|
|
||||
transaction.hset(redis_key, attributes_for_redis)
|
||||
transaction.expire(redis_key, REDIS_TTL)
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def update(values = {})
|
||||
assign_attributes(values)
|
||||
save
|
||||
end
|
||||
|
||||
def enqueue_immediately?
|
||||
enqueue_immediately
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :job
|
||||
|
||||
delegate :with_redis, to: :class
|
||||
|
||||
def attributes_for_redis
|
||||
@attributes.values_for_database
|
||||
end
|
||||
|
||||
def redis_key
|
||||
@redis_key ||= self.class.redis_key(job.project_id, job.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -742,9 +742,17 @@ module Ci
|
|||
retryable_builds.any?
|
||||
end
|
||||
|
||||
def archived?
|
||||
def archived?(log: false)
|
||||
archive_builds_older_than = Gitlab::CurrentSettings.current_application_settings.archive_builds_older_than
|
||||
archive_builds_older_than.present? && created_at < archive_builds_older_than
|
||||
is_archived = archive_builds_older_than.present? && created_at < archive_builds_older_than
|
||||
|
||||
if log
|
||||
::Gitlab::Ci::Pipeline::AccessLogger
|
||||
.new(pipeline: self, archived: is_archived)
|
||||
.log
|
||||
end
|
||||
|
||||
is_archived
|
||||
end
|
||||
|
||||
def cancelable?
|
||||
|
|
|
|||
|
|
@ -46,6 +46,14 @@ module Ci
|
|||
)
|
||||
end
|
||||
|
||||
# The run after commit queue is processed LIFO
|
||||
# We need to ensure that the Redis data is persisted before any other callbacks the might depend on it.
|
||||
before_commit do |job|
|
||||
job.run_after_commit do
|
||||
redis_state.save if defined?(@redis_state)
|
||||
end
|
||||
end
|
||||
|
||||
state_machine :status do
|
||||
event :enqueue do
|
||||
transition [:created, :skipped, :manual, :scheduled] => :waiting_for_resource, if: :with_resource_group?
|
||||
|
|
@ -268,6 +276,12 @@ module Ci
|
|||
options[:manual_confirmation] if manual_job?
|
||||
end
|
||||
|
||||
def redis_state
|
||||
strong_memoize(:redis_state) do
|
||||
Ci::JobRedisState.find_or_initialize_by(job: self)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def dependencies
|
||||
|
|
|
|||
|
|
@ -301,8 +301,8 @@ class CommitStatus < Ci::ApplicationRecord
|
|||
false
|
||||
end
|
||||
|
||||
def archived?
|
||||
pipeline.archived?
|
||||
def archived?(...)
|
||||
pipeline.archived?(...)
|
||||
end
|
||||
|
||||
def stuck?
|
||||
|
|
|
|||
|
|
@ -90,13 +90,21 @@ module Ci
|
|||
end
|
||||
|
||||
def enqueue_immediately?
|
||||
!!options[:enqueue_immediately]
|
||||
if Feature.enabled?(:ci_redis_enqueue_immediately, project)
|
||||
redis_state.enqueue_immediately?
|
||||
else
|
||||
!!options[:enqueue_immediately]
|
||||
end
|
||||
end
|
||||
|
||||
def set_enqueue_immediately!
|
||||
# ensures that even if `config_options: nil` in the database we set the
|
||||
# new value correctly.
|
||||
self.options = options.merge(enqueue_immediately: true)
|
||||
if Feature.enabled?(:ci_redis_enqueue_immediately, project)
|
||||
redis_state.enqueue_immediately = true
|
||||
else
|
||||
# ensures that even if `config_options: nil` in the database we set the
|
||||
# new value correctly.
|
||||
self.options = options.merge(enqueue_immediately: true)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -7,8 +7,19 @@ module SemanticVersionable
|
|||
validates :semver,
|
||||
format: { with: ::Gitlab::Regex::SemVer.optional_prefixed, message: 'must follow semantic version' }
|
||||
|
||||
scope :order_by_semantic_version_desc, -> { order(semver_major: :desc, semver_minor: :desc, semver_patch: :desc) }
|
||||
scope :order_by_semantic_version_asc, -> { order(semver_major: :asc, semver_minor: :asc, semver_patch: :asc) }
|
||||
scope :order_by_semantic_version_desc, -> {
|
||||
order(semver_major: :desc, semver_minor: :desc, semver_patch: :desc)
|
||||
.order(Arel.sql("CASE WHEN semver_prerelease IS NULL THEN 0 ELSE 1 END"))
|
||||
.order(Arel.sql("REGEXP_REPLACE(semver_prerelease, '[0-9]+', '', 'g') DESC NULLS FIRST"))
|
||||
.order(Arel.sql("COALESCE(NULLIF(REGEXP_REPLACE(semver_prerelease, '[^0-9]', '', 'g'), '')::INTEGER, 0) DESC"))
|
||||
}
|
||||
|
||||
scope :order_by_semantic_version_asc, -> {
|
||||
order(semver_major: :asc, semver_minor: :asc, semver_patch: :asc)
|
||||
.order(Arel.sql("CASE WHEN semver_prerelease IS NULL THEN 0 ELSE 1 END"))
|
||||
.order(Arel.sql("REGEXP_REPLACE(semver_prerelease, '[0-9]+', '', 'g') ASC NULLS FIRST"))
|
||||
.order(Arel.sql("COALESCE(NULLIF(REGEXP_REPLACE(semver_prerelease, '[^0-9]', '', 'g'), '')::INTEGER, 0) ASC"))
|
||||
}
|
||||
|
||||
def semver
|
||||
return if [semver_major, semver_minor, semver_patch].any?(&:nil?)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ module Ci
|
|||
end
|
||||
|
||||
condition(:archived, scope: :subject) do
|
||||
@subject.archived?
|
||||
@subject.archived?(log: true)
|
||||
end
|
||||
|
||||
condition(:artifacts_public, scope: :subject) do
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ module Ci
|
|||
end
|
||||
|
||||
condition(:archived, scope: :subject) do
|
||||
@subject.archived?
|
||||
@subject.archived?(log: true)
|
||||
end
|
||||
|
||||
# Allow reading builds for external pipelines regardless of whether CI/CD is disabled
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
name: model_selection_feature_changed
|
||||
description: A model selection feature had its configuration changed
|
||||
introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/547982
|
||||
introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194862
|
||||
feature_category: self-hosted_models
|
||||
milestone: '18.2'
|
||||
saved_to_database: true
|
||||
streamed: true
|
||||
scope: [Instance, Group, Project, User]
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
name: ci_redis_enqueue_immediately
|
||||
description:
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/work_items/549077
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194746
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/550225
|
||||
milestone: '18.2'
|
||||
group: group::ci platform
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
name: ci_pipeline_archived_access
|
||||
description: |
|
||||
Tracks interactions with pipelines that are archived or will be archived (90+ days old).
|
||||
Helps assess impact of archival policies on user workflows before implementation.
|
||||
Primarily for GitLab.com data collection.
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/549512
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194452
|
||||
rollout_issue_url:
|
||||
milestone: '18.2'
|
||||
group: group::ci platform
|
||||
type: ops
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class UpdateWorkspacesAgentConfigsProxyNamespaceFromEmptyHashToDefault < Gitlab::Database::Migration[2.3]
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
disable_ddl_transaction!
|
||||
|
||||
milestone '18.2'
|
||||
|
||||
def up
|
||||
update_column_in_batches(
|
||||
:workspaces_agent_configs,
|
||||
:gitlab_workspaces_proxy_namespace,
|
||||
'gitlab-workspaces',
|
||||
batch_size: 500
|
||||
) do |table, query|
|
||||
query.where(table[:gitlab_workspaces_proxy_namespace].eq('{}'))
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
4ad4313f1ef94de4664362348f1eb926b50e5dda95b7f895b8cec528a8d04552
|
||||
|
|
@ -39,7 +39,9 @@ The top section shows important information about your tenant, including:
|
|||
- Current GitLab version
|
||||
- Reference architecture
|
||||
- Maintenance window
|
||||
- AWS regions for data storage and backup
|
||||
- Primary and secondary AWS regions for data storage, with their availability zone IDs
|
||||
- Backup AWS region
|
||||
- AWS account IDs for the tenant and hosted runners
|
||||
|
||||
## Maintenance windows
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ To configure a self-hosted model:
|
|||
|
||||
For more information about:
|
||||
|
||||
- Configuring the model identifier for models deployed through vLLM, see the [vLLM documentation](supported_llm_serving_platforms.md#finding-the-model-name).
|
||||
- Configuring the model identifier for models deployed through vLLM, see the [vLLM documentation](supported_llm_serving_platforms.md#find-the-model-name).
|
||||
- Configuring Amazon Bedrock models with cross-region inferencing, see the
|
||||
[Amazon supported regions and models for inference profiles documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ When configuring the endpoint URL for any OpenAI API compatible platforms (such
|
|||
- If using the default vLLM configuration, the endpoint URL would be `https://<hostname>:8000/v1`
|
||||
- If your server is configured behind a proxy or load balancer, you might not need to specify the port, in which case the URL would be `https://<hostname>/v1`
|
||||
|
||||
#### Finding the model name
|
||||
#### Find the model name
|
||||
|
||||
After the model has been deployed, you can obtain the model name for the model identifier field in GitLab by querying the vLLM server's `/v1/models` endpoint:
|
||||
After the model has been deployed, to get the model name for the model identifier field in GitLab, query the vLLM server's `/v1/models` endpoint:
|
||||
|
||||
```shell
|
||||
curl \
|
||||
|
|
@ -152,31 +152,56 @@ This change has been observed to notably improve response times in internal benc
|
|||
|
||||
## For cloud-hosted model deployments
|
||||
|
||||
1. [AWS Bedrock](https://aws.amazon.com/bedrock/).
|
||||
A fully managed service that allows developers to build and scale generative AI applications using pre-trained models from leading AI companies. It seamlessly integrates with other AWS services and offers a pay-as-you-go pricing model.
|
||||
### AWS Bedrock
|
||||
|
||||
You must configure IAM credentials to access Bedrock with the appropriate AWS IAM permissions before accessing Bedrock models. Make sure that the IAM role has the `AmazonBedrockFullAccess` policy to allow [access to Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/security-iam-awsmanpol.html#security-iam-awsmanpol-AmazonBedrockFullAccess). You cannot do this in the GitLab Duo Self-Hosted UI. You also need to [use the AWS console to request access to the models](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access-modify.html) that you want to use.
|
||||
[AWS Bedrock](https://aws.amazon.com/bedrock/) is a fully managed service that
|
||||
allows developers to build and scale generative AI applications using pre-trained
|
||||
models from leading AI companies. It seamlessly integrates with other AWS services
|
||||
and offers a pay-as-you-go pricing model.
|
||||
|
||||
To authenticate your AI Gateway instance export the appropriate AWS SDK environment variables such as [`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_REGION_NAME`](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) when starting the Docker container. For more information, see the [AWS Identity and Access Management (IAM) Guide](https://docs.aws.amazon.com/bedrock/latest/userguide/security-iam.html).
|
||||
To access AWS Bedrock models:
|
||||
|
||||
1. Configure IAM credentials to access Bedrock with the appropriate AWS IAM
|
||||
permissions:
|
||||
|
||||
- Make sure that the IAM role has the `AmazonBedrockFullAccess` policy to allow
|
||||
[access to Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/security-iam-awsmanpol.html#security-iam-awsmanpol-AmazonBedrockFullAccess). You cannot do this in
|
||||
the GitLab Duo Self-Hosted UI.
|
||||
|
||||
- [Use the AWS console to request access to the models](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access-modify.html) that you want to use.
|
||||
|
||||
1. Authenticate your AI gateway instance by exporting the appropriate AWS SDK
|
||||
environment variables such as [`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_REGION_NAME`](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) when starting
|
||||
the Docker container.
|
||||
|
||||
For more information, see the [AWS Identity and Access Management (IAM) Guide](https://docs.aws.amazon.com/bedrock/latest/userguide/security-iam.html).
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
Temporary credentials are not supported by AI Gateway at this time. For more information on adding support for Bedrock to use instance profile or temporary credentials, see [issue 542389](https://gitlab.com/gitlab-org/gitlab/-/issues/542389).
|
||||
Temporary credentials are not supported by AI gateway at this time. For more information on adding support for Bedrock to use instance profile or temporary credentials, see [issue 542389](https://gitlab.com/gitlab-org/gitlab/-/issues/542389).
|
||||
|
||||
{{</alert>}}
|
||||
|
||||
- [Supported foundation models in Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html)
|
||||
1. Optional. To set up a private Bedrock endpoint operating in a virtual private cloud (VPC),
|
||||
make sure the `AWS_BEDROCK_RUNTIME_ENDPOINT` environment variable is configured
|
||||
with your internal URL when launching the AI gateway container.
|
||||
|
||||
To set up the private Bedrock endpoint (operating in a VPC), ensure the `AWS_BEDROCK_RUNTIME_ENDPOINT` environment variable is configured with your internal URL when launching the AIGW container.
|
||||
An example configuration: `AWS_BEDROCK_RUNTIME_ENDPOINT = https://bedrock-runtime.{aws_region_name}.amazonaws.com`
|
||||
|
||||
**Example configuration**: `AWS_BEDROCK_RUNTIME_ENDPOINT = https://bedrock-runtime.{aws_region_name}.amazonaws.com`
|
||||
|
||||
For VPC endpoints, the URL format may be different, such as `https://vpce-{vpc-endpoint-id}-{service-name}.{aws_region_name}.vpce.amazonaws.com`
|
||||
|
||||
1. [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/).
|
||||
Provides access to OpenAI's powerful models, enabling developers to integrate advanced AI capabilities into their applications with robust security and scalable infrastructure.
|
||||
- [Working with Azure OpenAI models](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/working-with-models?tabs=powershell)
|
||||
- [Azure OpenAI Service models](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models?tabs=python-secure%2Cglobal-standard%2Cstandard-chat-completions)
|
||||
For more information, see [supported foundation models in Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html).
|
||||
|
||||
### Azure OpenAI
|
||||
|
||||
[Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/) provides
|
||||
access to OpenAI's powerful models, enabling developers to integrate advanced AI
|
||||
capabilities into their applications with robust security and scalable infrastructure.
|
||||
|
||||
For more information, see:
|
||||
|
||||
- [Working with Azure OpenAI models](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/working-with-models?tabs=powershell)
|
||||
- [Azure OpenAI Service models](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models?tabs=python-secure%2Cglobal-standard%2Cstandard-chat-completions)
|
||||
|
||||
## Use multiple models and platforms
|
||||
|
||||
|
|
|
|||
|
|
@ -5934,9 +5934,9 @@ successfully complete before starting.
|
|||
The downstream pipeline can complete successfully without running any optional manual jobs.
|
||||
- [Blocking manual jobs](../jobs/job_control.md#types-of-manual-jobs) in the downstream pipeline
|
||||
must run before the trigger job is marked as successful or failed. The trigger job
|
||||
shows **pending** ({{< icon name="status_pending" >}}) if the downstream pipeline status is
|
||||
**waiting for manual action** ({{< icon name="status_manual" >}}) due to manual jobs. By default,
|
||||
jobs in later stages do not start until the trigger job completes.
|
||||
shows **running** ({{< icon name="status_running" >}}) if the downstream pipeline status is
|
||||
**waiting for manual action** ({{< icon name="status_manual" >}}) due to manual jobs.
|
||||
By default, jobs in later stages do not start until the trigger job completes.
|
||||
- If the downstream pipeline has a failed job, but the job uses [`allow_failure: true`](#allow_failure),
|
||||
the downstream pipeline is considered successful and the trigger job shows **success**.
|
||||
|
||||
|
|
|
|||
|
|
@ -228,6 +228,16 @@ To change the GitLab.com account linked to your Customers Portal profile:
|
|||
1. Under **Your GitLab.com account**, select **Change linked account**.
|
||||
1. Sign in to the [GitLab.com](https://gitlab.com/users/sign_in) account you want to link to the Customers Portal profile.
|
||||
|
||||
## Tax ID for non-US customers
|
||||
|
||||
A Tax ID is a unique number assigned by tax authorities to businesses registered for Value Added Tax (VAT), Goods and Services Tax (GST), or similar indirect taxes.
|
||||
|
||||
Providing a valid Tax ID may reduce your tax burden by allowing us to apply reverse charge mechanisms instead of charging VAT/GST on your invoices. Without a valid Tax ID, we charge applicable VAT/GST rates based on your location.
|
||||
|
||||
If your business isn't registered for indirect taxes (due to size thresholds or other reasons), we apply the standard VAT/GST rate according to local regulations.
|
||||
|
||||
For detailed Tax ID formats by country and additional information, see our [complete Tax ID reference guide](https://handbook.gitlab.com/handbook/finance/tax/#frequently-asked-questions---tax-id-for-non-us-customers).
|
||||
|
||||
## Customers that purchased through a reseller
|
||||
|
||||
If you purchased a subscription through an authorized reseller (including GCP and AWS marketplaces), you have access to the Customers Portal to:
|
||||
|
|
|
|||
|
|
@ -545,6 +545,7 @@ Audit event types belong to the following product categories.
|
|||
|
||||
| Type name | Event triggered when | Saved to database | Introduced in | Scope |
|
||||
|:----------|:---------------------|:------------------|:--------------|:------|
|
||||
| [`model_selection_feature_changed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194862) | A model selection feature had its configuration changed | {{< icon name="check-circle" >}} Yes | GitLab [18.2](https://gitlab.com/gitlab-org/gitlab/-/issues/547982) | Instance, Group, Project, User |
|
||||
| [`self_hosted_model_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165303) | A new self-hosted model configuration was added | {{< icon name="check-circle" >}} Yes | GitLab [17.4](https://gitlab.com/gitlab-org/gitlab/-/issues/477999) | Instance |
|
||||
| [`self_hosted_model_destroyed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165321) | A new self-hosted model configuration was destroyed | {{< icon name="check-circle" >}} Yes | GitLab [17.4](https://gitlab.com/gitlab-org/gitlab/-/issues/477999) | Instance |
|
||||
| [`self_hosted_model_feature_changed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165489) | A self-hosted model feature had its configuration changed | {{< icon name="check-circle" >}} Yes | GitLab [17.4](https://gitlab.com/gitlab-org/gitlab/-/issues/463215) | Instance |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
module Pipeline
|
||||
class AccessLogger
|
||||
include ::Gitlab::Utils::StrongMemoize
|
||||
|
||||
PROVISIONAL_ARCHIVE_VALUE = 90.days
|
||||
|
||||
def initialize(pipeline:, archived:, destination: Gitlab::AppJsonLogger)
|
||||
@pipeline = pipeline
|
||||
@archived = archived
|
||||
@destination = destination
|
||||
end
|
||||
|
||||
def log
|
||||
return unless enabled?
|
||||
|
||||
log_access_entry if log_access?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :pipeline, :destination
|
||||
|
||||
delegate :project, to: :pipeline
|
||||
|
||||
def archived?
|
||||
@archived
|
||||
end
|
||||
|
||||
# Tracks interactions with pipelines that are archived or will be archived (90+ days old).
|
||||
# Helps assess impact of archival policies on user workflows before implementation.
|
||||
# Primarily for GitLab.com data collection.
|
||||
#
|
||||
def enabled?
|
||||
::Gitlab::SafeRequestStore.fetch(:ci_pipeline_archived_access) do
|
||||
::Feature.enabled?(:ci_pipeline_archived_access, :current_request, type: :ops)
|
||||
end
|
||||
end
|
||||
strong_memoize_attr :enabled?
|
||||
|
||||
def log_access_entry
|
||||
::Gitlab::ApplicationContext.with_context(project: project) do
|
||||
attributes = ::Gitlab::ApplicationContext.current.merge(
|
||||
class: self.class.name.to_s,
|
||||
project_id: project.id,
|
||||
pipeline_id: pipeline.id,
|
||||
pipeline_age: pipeline.age_in_minutes,
|
||||
archived: archived?
|
||||
)
|
||||
|
||||
attributes.stringify_keys!
|
||||
destination.info(attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def log_access?
|
||||
archived? || pipeline_will_be_archived?
|
||||
end
|
||||
|
||||
def pipeline_will_be_archived?
|
||||
pipeline.created_at.before?(PROVISIONAL_ARCHIVE_VALUE.ago)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
70
package.json
70
package.json
|
|
@ -83,41 +83,41 @@
|
|||
"@snowplow/browser-plugin-timezone": "^3.24.2",
|
||||
"@snowplow/browser-tracker": "^3.24.2",
|
||||
"@sourcegraph/code-host-integration": "0.0.95",
|
||||
"@tiptap/core": "^2.14.0",
|
||||
"@tiptap/extension-blockquote": "^2.14.0",
|
||||
"@tiptap/extension-bold": "^2.14.0",
|
||||
"@tiptap/extension-bubble-menu": "^2.14.0",
|
||||
"@tiptap/extension-bullet-list": "^2.14.0",
|
||||
"@tiptap/extension-code": "^2.14.0",
|
||||
"@tiptap/extension-code-block": "^2.14.0",
|
||||
"@tiptap/extension-code-block-lowlight": "^2.14.0",
|
||||
"@tiptap/extension-document": "^2.14.0",
|
||||
"@tiptap/extension-dropcursor": "^2.14.0",
|
||||
"@tiptap/extension-gapcursor": "^2.14.0",
|
||||
"@tiptap/extension-hard-break": "^2.14.0",
|
||||
"@tiptap/extension-heading": "^2.14.0",
|
||||
"@tiptap/extension-highlight": "^2.14.0",
|
||||
"@tiptap/extension-history": "^2.14.0",
|
||||
"@tiptap/extension-horizontal-rule": "^2.14.0",
|
||||
"@tiptap/extension-image": "^2.14.0",
|
||||
"@tiptap/extension-italic": "^2.14.0",
|
||||
"@tiptap/extension-link": "^2.14.0",
|
||||
"@tiptap/extension-list-item": "^2.14.0",
|
||||
"@tiptap/extension-ordered-list": "^2.14.0",
|
||||
"@tiptap/extension-paragraph": "^2.14.0",
|
||||
"@tiptap/extension-strike": "^2.14.0",
|
||||
"@tiptap/extension-subscript": "^2.14.0",
|
||||
"@tiptap/extension-superscript": "^2.14.0",
|
||||
"@tiptap/extension-table": "^2.14.0",
|
||||
"@tiptap/extension-table-cell": "^2.14.0",
|
||||
"@tiptap/extension-table-header": "^2.14.0",
|
||||
"@tiptap/extension-table-row": "^2.14.0",
|
||||
"@tiptap/extension-task-item": "^2.14.0",
|
||||
"@tiptap/extension-task-list": "^2.14.0",
|
||||
"@tiptap/extension-text": "^2.14.0",
|
||||
"@tiptap/pm": "^2.14.0",
|
||||
"@tiptap/suggestion": "^2.14.0",
|
||||
"@tiptap/vue-2": "^2.14.0",
|
||||
"@tiptap/core": "^2.14.1",
|
||||
"@tiptap/extension-blockquote": "^2.14.1",
|
||||
"@tiptap/extension-bold": "^2.14.1",
|
||||
"@tiptap/extension-bubble-menu": "^2.14.1",
|
||||
"@tiptap/extension-bullet-list": "^2.14.1",
|
||||
"@tiptap/extension-code": "^2.14.1",
|
||||
"@tiptap/extension-code-block": "^2.14.1",
|
||||
"@tiptap/extension-code-block-lowlight": "^2.14.1",
|
||||
"@tiptap/extension-document": "^2.14.1",
|
||||
"@tiptap/extension-dropcursor": "^2.14.1",
|
||||
"@tiptap/extension-gapcursor": "^2.14.1",
|
||||
"@tiptap/extension-hard-break": "^2.14.1",
|
||||
"@tiptap/extension-heading": "^2.14.1",
|
||||
"@tiptap/extension-highlight": "^2.14.1",
|
||||
"@tiptap/extension-history": "^2.14.1",
|
||||
"@tiptap/extension-horizontal-rule": "^2.14.1",
|
||||
"@tiptap/extension-image": "^2.14.1",
|
||||
"@tiptap/extension-italic": "^2.14.1",
|
||||
"@tiptap/extension-link": "^2.14.1",
|
||||
"@tiptap/extension-list-item": "^2.14.1",
|
||||
"@tiptap/extension-ordered-list": "^2.14.1",
|
||||
"@tiptap/extension-paragraph": "^2.14.1",
|
||||
"@tiptap/extension-strike": "^2.14.1",
|
||||
"@tiptap/extension-subscript": "^2.14.1",
|
||||
"@tiptap/extension-superscript": "^2.14.1",
|
||||
"@tiptap/extension-table": "^2.14.1",
|
||||
"@tiptap/extension-table-cell": "^2.14.1",
|
||||
"@tiptap/extension-table-header": "^2.14.1",
|
||||
"@tiptap/extension-table-row": "^2.14.1",
|
||||
"@tiptap/extension-task-item": "^2.14.1",
|
||||
"@tiptap/extension-task-list": "^2.14.1",
|
||||
"@tiptap/extension-text": "^2.14.1",
|
||||
"@tiptap/pm": "^2.14.1",
|
||||
"@tiptap/suggestion": "^2.14.1",
|
||||
"@tiptap/vue-2": "^2.14.1",
|
||||
"@vitejs/plugin-vue2": "^2.3.3",
|
||||
"@vue/apollo-components": "^4.0.0-beta.4",
|
||||
"@vue/apollo-option": "^4.0.0-beta.4",
|
||||
|
|
|
|||
|
|
@ -197,6 +197,36 @@ RSpec.describe RootController, feature_category: :shared do
|
|||
|
||||
expect(response).to render_template 'dashboard/projects/index'
|
||||
end
|
||||
|
||||
context 'when the `merge_request_dashboard` feature flag is enabled' do
|
||||
before do
|
||||
stub_feature_flags(merge_request_dashboard: true)
|
||||
end
|
||||
|
||||
it 'passes the correct data to the view' do
|
||||
get :index
|
||||
|
||||
expect(assigns[:homepage_app_data]).to eq({
|
||||
review_requested_path: "/dashboard/merge_requests",
|
||||
assigned_to_you_path: "/dashboard/merge_requests"
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the `merge_request_dashboard` feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(merge_request_dashboard: false)
|
||||
end
|
||||
|
||||
it 'passes the correct data to the view' do
|
||||
get :index
|
||||
|
||||
expect(assigns[:homepage_app_data]).to eq({
|
||||
review_requested_path: "/dashboard/merge_requests?reviewer_username=#{user.username}",
|
||||
assigned_to_you_path: "/dashboard/merge_requests?assignee_username=#{user.username}"
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with `personal_homepage` feature flag enabled' do
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ RSpec.describe Groups::UserGroupsFinder, feature_category: :groups_and_projects
|
|||
end
|
||||
end
|
||||
|
||||
it 'prioritizes exact matches first' do
|
||||
it 'prioritizes exact matches first', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/537365' do
|
||||
expect(result.first).to eq(private_maintainer_group)
|
||||
expect(result[1..]).to match_array(other_groups)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,17 +1,43 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { GlLink } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import { useFakeDate } from 'helpers/fake_date';
|
||||
import MergeRequestsWidget from '~/homepage/components/merge_requests_widget.vue';
|
||||
import mergeRequestsWidgetMetadataQuery from '~/homepage/graphql/queries/merge_requests_widget_metadata.query.graphql';
|
||||
import { withItems, withoutItems } from './mocks/merge_requests_widget_metadata_query_mocks';
|
||||
|
||||
describe('MergeRequestsWidget', () => {
|
||||
Vue.use(VueApollo);
|
||||
|
||||
const MOCK_REVIEW_REQUESTED_PATH = '/review/requested/path';
|
||||
const MOCK_ASSIGNED_TO_YOU_PATH = '/assigned/to/you/path';
|
||||
const MOCK_CURRENT_TIME = new Date('2025-06-12T18:13:25Z');
|
||||
|
||||
useFakeDate(MOCK_CURRENT_TIME);
|
||||
|
||||
const mergeRequestsWidgetMetadataQueryHandler = (data) => jest.fn().mockResolvedValue(data);
|
||||
|
||||
let wrapper;
|
||||
|
||||
const findGlLinks = () => wrapper.findAllComponents(GlLink);
|
||||
const findReviewRequestedCount = () => wrapper.findByTestId('review-requested-count');
|
||||
const findReviewRequestedLastUpdatedAt = () =>
|
||||
wrapper.findByTestId('review-requested-last-updated-at');
|
||||
const findAssignedCount = () => wrapper.findByTestId('assigned-count');
|
||||
const findAssignedLastUpdatedAt = () => wrapper.findByTestId('assigned-last-updated-at');
|
||||
|
||||
function createWrapper() {
|
||||
wrapper = shallowMount(MergeRequestsWidget, {
|
||||
function createWrapper({ mergeRequestsWidgetMetadataQueryMock = withItems } = {}) {
|
||||
const mockApollo = createMockApollo([
|
||||
[
|
||||
mergeRequestsWidgetMetadataQuery,
|
||||
mergeRequestsWidgetMetadataQueryHandler(mergeRequestsWidgetMetadataQueryMock),
|
||||
],
|
||||
]);
|
||||
wrapper = shallowMountExtended(MergeRequestsWidget, {
|
||||
apolloProvider: mockApollo,
|
||||
propsData: {
|
||||
reviewRequestedPath: MOCK_REVIEW_REQUESTED_PATH,
|
||||
assignedToYouPath: MOCK_ASSIGNED_TO_YOU_PATH,
|
||||
|
|
@ -19,15 +45,51 @@ describe('MergeRequestsWidget', () => {
|
|||
});
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
createWrapper();
|
||||
describe('links', () => {
|
||||
beforeEach(() => {
|
||||
createWrapper();
|
||||
});
|
||||
|
||||
it('renders the "Review requested" link', () => {
|
||||
expect(findGlLinks().at(0).props('href')).toBe(MOCK_REVIEW_REQUESTED_PATH);
|
||||
});
|
||||
|
||||
it('renders the "Assigned to you" link', () => {
|
||||
expect(findGlLinks().at(1).props('href')).toBe(MOCK_ASSIGNED_TO_YOU_PATH);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders the "Review requested" link', () => {
|
||||
expect(findGlLinks().at(0).props('href')).toBe(MOCK_REVIEW_REQUESTED_PATH);
|
||||
});
|
||||
describe('metadata', () => {
|
||||
it('does not show any metadata until the query has resolved', () => {
|
||||
createWrapper();
|
||||
|
||||
it('renders the "Assigned to you" link', () => {
|
||||
expect(findGlLinks().at(1).props('href')).toBe(MOCK_ASSIGNED_TO_YOU_PATH);
|
||||
expect(findReviewRequestedCount().exists()).toBe(false);
|
||||
expect(findReviewRequestedLastUpdatedAt().exists()).toBe(false);
|
||||
expect(findAssignedCount().exists()).toBe(false);
|
||||
expect(findAssignedLastUpdatedAt().exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('shows the metadata once the query has resolved', async () => {
|
||||
createWrapper();
|
||||
await waitForPromises();
|
||||
|
||||
expect(findReviewRequestedCount().text()).toBe('12');
|
||||
expect(findReviewRequestedLastUpdatedAt().text()).toBe('3 hours ago');
|
||||
expect(findAssignedCount().text()).toBe('4');
|
||||
expect(findAssignedLastUpdatedAt().text()).toBe('2 days ago');
|
||||
});
|
||||
|
||||
it('shows partial metadata when the user has no relevant items', async () => {
|
||||
createWrapper({ mergeRequestsWidgetMetadataQueryMock: withoutItems });
|
||||
await waitForPromises();
|
||||
|
||||
expect(findReviewRequestedCount().exists()).toBe(true);
|
||||
expect(findReviewRequestedLastUpdatedAt().exists()).toBe(false);
|
||||
expect(findAssignedCount().exists()).toBe(true);
|
||||
expect(findAssignedLastUpdatedAt().exists()).toBe(false);
|
||||
|
||||
expect(findReviewRequestedCount().text()).toBe('0');
|
||||
expect(findAssignedCount().text()).toBe('0');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
export const withItems = {
|
||||
data: {
|
||||
currentUser: {
|
||||
id: 'gid://gitlab/User/1',
|
||||
reviewRequestedMergeRequests: {
|
||||
count: 12,
|
||||
nodes: [
|
||||
{
|
||||
id: 'gid://gitlab/MergeRequest/1',
|
||||
updatedAt: '2025-06-12T15:13:25Z',
|
||||
__typename: 'MergeRequest',
|
||||
},
|
||||
],
|
||||
__typename: 'MergeRequestConnection',
|
||||
},
|
||||
assignedMergeRequests: {
|
||||
count: 4,
|
||||
nodes: [
|
||||
{
|
||||
id: 'gid://gitlab/MergeRequest/2',
|
||||
updatedAt: '2025-06-10T15:13:25Z',
|
||||
__typename: 'MergeRequest',
|
||||
},
|
||||
],
|
||||
__typename: 'MergeRequestConnection',
|
||||
},
|
||||
__typename: 'CurrentUser',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const withoutItems = {
|
||||
data: {
|
||||
currentUser: {
|
||||
id: 'gid://gitlab/User/1',
|
||||
reviewRequestedMergeRequests: {
|
||||
count: 0,
|
||||
nodes: [],
|
||||
__typename: 'MergeRequestConnection',
|
||||
},
|
||||
assignedMergeRequests: {
|
||||
count: 0,
|
||||
nodes: [],
|
||||
__typename: 'MergeRequestConnection',
|
||||
},
|
||||
__typename: 'CurrentUser',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Ci::Pipeline::AccessLogger, feature_category: :continuous_integration do
|
||||
let_it_be(:project) { build_stubbed(:project) }
|
||||
let_it_be(:pipeline) { build_stubbed(:ci_pipeline, project: project, created_at: 1.week.ago) }
|
||||
|
||||
let(:archived) { false }
|
||||
let(:logger) do
|
||||
described_class.new(pipeline: pipeline, archived: archived)
|
||||
end
|
||||
|
||||
describe '#log' do
|
||||
context 'when the pipeline is archived' do
|
||||
let(:expected_data) do
|
||||
{
|
||||
'correlation_id' => a_kind_of(String),
|
||||
'project_id' => project.id,
|
||||
'pipeline_id' => pipeline.id,
|
||||
'archived' => true
|
||||
}
|
||||
end
|
||||
|
||||
let(:archived) { true }
|
||||
|
||||
it 'creates a log entry' do
|
||||
expect(Gitlab::AppJsonLogger)
|
||||
.to receive(:info)
|
||||
.with(a_hash_including(expected_data))
|
||||
.and_call_original
|
||||
|
||||
logger.log
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the pipeline is tentatively archived' do
|
||||
let(:expected_data) do
|
||||
{
|
||||
'correlation_id' => a_kind_of(String),
|
||||
'project_id' => project.id,
|
||||
'pipeline_id' => pipeline.id,
|
||||
'archived' => false
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
stub_const("#{described_class}::PROVISIONAL_ARCHIVE_VALUE", 1.day)
|
||||
end
|
||||
|
||||
it 'creates a log entry' do
|
||||
expect(Gitlab::AppJsonLogger)
|
||||
.to receive(:info)
|
||||
.with(a_hash_including(expected_data))
|
||||
.and_call_original
|
||||
|
||||
logger.log
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the pipeline is not archived' do
|
||||
it 'does not log' do
|
||||
expect(Gitlab::AppJsonLogger).not_to receive(:info)
|
||||
|
||||
logger.log
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the feature flag is disabled' do
|
||||
let(:archived) { true }
|
||||
|
||||
before do
|
||||
stub_feature_flags(ci_pipeline_archived_access: false)
|
||||
end
|
||||
|
||||
it 'does not log' do
|
||||
expect(Gitlab::AppJsonLogger).not_to receive(:info)
|
||||
|
||||
logger.log
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe UpdateWorkspacesAgentConfigsProxyNamespaceFromEmptyHashToDefault, feature_category: :workspaces do
|
||||
let(:workspaces_agent_configs) { table(:workspaces_agent_configs) }
|
||||
let(:organization) { table(:organizations).create!(name: 'organization', path: 'organization') }
|
||||
let(:namespace) do
|
||||
table(:namespaces).create!(name: 'namespace', path: 'namespace', organization_id: organization.id)
|
||||
end
|
||||
|
||||
let(:project) do
|
||||
table(:projects).create!(name: 'project', path: 'project', project_namespace_id: namespace.id,
|
||||
namespace_id: namespace.id, organization_id: organization.id)
|
||||
end
|
||||
|
||||
let(:cluster_agent) { table(:cluster_agents).create!(name: 'cluster_agent', project_id: project.id) }
|
||||
let!(:workspaces_agent_config) do
|
||||
workspaces_agent_configs.create!(
|
||||
enabled: true,
|
||||
gitlab_workspaces_proxy_namespace: '{}',
|
||||
cluster_agent_id: cluster_agent.id,
|
||||
dns_zone: 'workspaces.localdev.me',
|
||||
project_id: project.id)
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
it 'updates proxy_namespace from empty hash to default' do
|
||||
expect { migrate! }.to change {
|
||||
workspaces_agent_config.reload.gitlab_workspaces_proxy_namespace
|
||||
}.from('{}').to('gitlab-workspaces')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::JobRedisState, :clean_gitlab_redis_shared_state, feature_category: :continuous_integration do
|
||||
let(:job) { build_stubbed(:ci_build) }
|
||||
|
||||
describe '.new' do
|
||||
it { expect(described_class.new(enqueue_immediately: true)).to have_attributes(enqueue_immediately: true) }
|
||||
it { expect(described_class.new(enqueue_immediately: false)).to have_attributes(enqueue_immediately: false) }
|
||||
it { expect(described_class.new).to have_attributes(enqueue_immediately: false) }
|
||||
end
|
||||
|
||||
describe '.find_or_initialize_by' do
|
||||
it 'returns a new record' do
|
||||
record = described_class.find_or_initialize_by(job: job)
|
||||
|
||||
expect(record).to be_an_instance_of(described_class)
|
||||
end
|
||||
|
||||
context 'when a record already exists in Redis' do
|
||||
it 'returns existing data' do
|
||||
record = described_class.new(job: job, enqueue_immediately: true)
|
||||
expect(record.save).to be(true)
|
||||
|
||||
found_record = described_class.find_or_initialize_by(job: job)
|
||||
|
||||
expect(found_record.attributes).to match(record.attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#save' do
|
||||
it 'persists the record' do
|
||||
record = described_class.new(job: job, enqueue_immediately: true)
|
||||
|
||||
expect(record.save).to be(true)
|
||||
|
||||
described_class.with_redis do |redis|
|
||||
key = described_class.redis_key(job.project_id, job.id)
|
||||
|
||||
expect(redis.hgetall(key)).to eq({ 'enqueue_immediately' => '_b:1' })
|
||||
expect(redis.ttl(key)).to be_between(0, described_class::REDIS_TTL)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when trying to save for a not persisted job' do
|
||||
it 'raises an error' do
|
||||
expect(job).to receive(:persisted?).and_return(false)
|
||||
record = described_class.new(job: job)
|
||||
|
||||
expect { record.save }.to raise_error(described_class::UnpersistedJobError) # rubocop:disable Rails/SaveBang -- Not Rails
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
it 'updates the record' do
|
||||
record = described_class.new(job: job, enqueue_immediately: true)
|
||||
key = described_class.redis_key(job.project_id, job.id)
|
||||
|
||||
expect(record.save).to be(true)
|
||||
|
||||
described_class.with_redis do |redis|
|
||||
expect(redis.hgetall(key)).to eq({ 'enqueue_immediately' => '_b:1' })
|
||||
end
|
||||
|
||||
expect(record.update(enqueue_immediately: false)).to be(true)
|
||||
|
||||
described_class.with_redis do |redis|
|
||||
expect(redis.hgetall(key)).to eq({ 'enqueue_immediately' => '_b:0' })
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not accept job argument' do
|
||||
expect { described_class.new.update(job: job) }.to raise_error(ActiveModel::UnknownAttributeError) # rubocop:disable Rails/SaveBang -- Not Rails
|
||||
end
|
||||
end
|
||||
|
||||
context 'when persisting processable records' do
|
||||
let(:job) { build(:ci_build) }
|
||||
|
||||
it 'auto saves after the job is persisted' do
|
||||
record = job.redis_state
|
||||
record.enqueue_immediately = true
|
||||
|
||||
expect(described_class.find_or_initialize_by(job: job).enqueue_immediately).to be(false)
|
||||
expect(job.save!).to be_truthy
|
||||
expect(described_class.find_or_initialize_by(job: job).enqueue_immediately).to be(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -6431,7 +6431,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category:
|
|||
end
|
||||
|
||||
describe '#archived?' do
|
||||
subject { build_stubbed(:ci_pipeline, created_at: 1.day.ago, project: project) }
|
||||
subject(:pipeline) { build_stubbed(:ci_pipeline, created_at: 1.day.ago, project: project) }
|
||||
|
||||
context 'when archive_builds_in is set' do
|
||||
before do
|
||||
|
|
@ -6439,6 +6439,23 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category:
|
|||
end
|
||||
|
||||
it { is_expected.to be_archived }
|
||||
|
||||
it 'does not log by default' do
|
||||
expect(::Gitlab::Ci::Pipeline::AccessLogger).not_to receive(:new)
|
||||
|
||||
expect(pipeline.archived?).to be_truthy
|
||||
end
|
||||
|
||||
context 'when logging is requested' do
|
||||
it 'calls access logger' do
|
||||
expect(::Gitlab::Ci::Pipeline::AccessLogger)
|
||||
.to receive(:new)
|
||||
.with(pipeline: pipeline, archived: true)
|
||||
.and_call_original
|
||||
|
||||
expect(pipeline.archived?(log: true)).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when archive_builds_in is not set' do
|
||||
|
|
@ -6447,6 +6464,17 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category:
|
|||
end
|
||||
|
||||
it { is_expected.not_to be_archived }
|
||||
|
||||
context 'when logging is requested' do
|
||||
it 'calls access logger' do
|
||||
expect(::Gitlab::Ci::Pipeline::AccessLogger)
|
||||
.to receive(:new)
|
||||
.with(pipeline: pipeline, archived: false)
|
||||
.and_call_original
|
||||
|
||||
expect(pipeline.archived?(log: true)).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -688,4 +688,13 @@ RSpec.describe Ci::Processable, feature_category: :continuous_integration do
|
|||
processable.trigger_short_token
|
||||
end
|
||||
end
|
||||
|
||||
describe '#redis_state' do
|
||||
let(:processable) { build_stubbed(:ci_processable, pipeline: pipeline) }
|
||||
|
||||
it 'is a memoized Ci::JobRedisState record' do
|
||||
expect(processable.redis_state).to be_an_instance_of(Ci::JobRedisState)
|
||||
expect(processable.strong_memoized?(:redis_state)).to be(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -113,6 +113,17 @@ RSpec.describe SemanticVersionable, feature_category: :mlops do
|
|||
let(:first_release) { model_class.create!(semver: '1.0.1') }
|
||||
let(:second_release) { model_class.create!(semver: '3.0.1') }
|
||||
let(:patch) { model_class.create!(semver: 'v2.0.1') }
|
||||
let(:first_beta) { model_class.create!(semver: '1.0.1-beta') }
|
||||
let(:first_alpha) { model_class.create!(semver: '1.0.1-alpha') }
|
||||
let(:second_rc) { model_class.create!(semver: '3.0.1-rc') }
|
||||
let(:first_beta2) { model_class.create!(semver: '1.0.1-beta2') }
|
||||
let(:first_beta1) { model_class.create!(semver: '1.0.1-beta1') }
|
||||
let(:first_beta10) { model_class.create!(semver: '1.0.1-beta10') }
|
||||
let(:first_beta12) { model_class.create!(semver: '1.0.1-beta.12') }
|
||||
let(:first_alpha2) { model_class.create!(semver: '1.0.1-alpha2') }
|
||||
let(:first_alpha1) { model_class.create!(semver: '1.0.1-alpha1') }
|
||||
let(:first_alpha10) { model_class.create!(semver: '1.0.1-alpha10') }
|
||||
let(:first_alpha_dot_10) { model_class.create!(semver: '1.0.1-alpha.10') }
|
||||
|
||||
describe '.order_by_semantic_version_asc' do
|
||||
it 'orders the versions by semantic order ascending' do
|
||||
|
|
@ -124,6 +135,49 @@ RSpec.describe SemanticVersionable, feature_category: :mlops do
|
|||
it 'orders the versions by semantic order descending' do
|
||||
expect(model_class.order_by_semantic_version_desc).to eq([second_release, patch, first_release])
|
||||
end
|
||||
|
||||
context 'with prerelease versions' do
|
||||
before do
|
||||
[first_release, second_release, patch, first_beta, first_beta1, first_beta2, first_beta10,
|
||||
first_beta12, first_alpha, first_alpha1, first_alpha2, first_alpha10, first_alpha_dot_10,
|
||||
second_rc].each(&:reload)
|
||||
end
|
||||
|
||||
it 'orders release versions before prerelease versions' do
|
||||
versions = model_class.order_by_semantic_version_desc.to_a
|
||||
|
||||
expect(versions.index(first_release)).to be < versions.index(first_beta)
|
||||
expect(versions.index(first_release)).to be < versions.index(first_alpha)
|
||||
expect(versions.index(second_release)).to be < versions.index(second_rc)
|
||||
end
|
||||
|
||||
it 'orders prerelease versions in descending order' do
|
||||
versions = model_class.order_by_semantic_version_desc.to_a
|
||||
|
||||
expect(versions.index(first_beta)).to be < versions.index(first_alpha)
|
||||
end
|
||||
|
||||
it 'returns the correct complete ordering' do
|
||||
expected_order = [
|
||||
second_release, # 3.0.1
|
||||
second_rc, # 3.0.1-rc
|
||||
patch, # v2.0.1
|
||||
first_release, # 1.0.1
|
||||
first_beta12, # 1.0.1-beta.12
|
||||
first_beta10, # 1.0.1-beta10
|
||||
first_beta2, # 1.0.1-beta2
|
||||
first_beta1, # 1.0.1-beta1
|
||||
first_beta, # 1.0.1-beta
|
||||
first_alpha_dot_10, # 1.0.1-alpha.10
|
||||
first_alpha10, # 1.0.1-alpha10
|
||||
first_alpha2, # 1.0.1-alpha2
|
||||
first_alpha1, # 1.0.1-alpha1
|
||||
first_alpha # 1.0.1-alpha
|
||||
]
|
||||
|
||||
expect(model_class.order_by_semantic_version_desc).to eq(expected_order)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::RetryJobService, feature_category: :continuous_integration do
|
||||
RSpec.describe Ci::RetryJobService, :clean_gitlab_redis_shared_state, feature_category: :continuous_integration do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
let_it_be(:reporter) { create(:user) }
|
||||
let_it_be(:developer) { create(:user) }
|
||||
|
|
@ -553,6 +553,37 @@ RSpec.describe Ci::RetryJobService, feature_category: :continuous_integration do
|
|||
|
||||
it_behaves_like 'checks enqueue_immediately?'
|
||||
end
|
||||
|
||||
context 'with ci_redis_enqueue_immediately disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_redis_enqueue_immediately: false)
|
||||
end
|
||||
|
||||
let!(:job) do
|
||||
create(:ci_build, *[trait].compact, :failed, pipeline: pipeline, ci_stage: stage)
|
||||
end
|
||||
|
||||
where(:trait, :enqueue_immediately) do
|
||||
nil | false
|
||||
:manual | true
|
||||
:expired_scheduled | true
|
||||
end
|
||||
|
||||
with_them do
|
||||
it 'retries the given job but not the other manual/scheduled jobs' do
|
||||
expect { subject }
|
||||
.to change { Ci::Build.count }.by(1)
|
||||
.and not_change { test_manual_build.reload.status }
|
||||
.and not_change { subsequent_manual_build.reload.status }
|
||||
.and not_change { test_scheduled_build.reload.status }
|
||||
.and not_change { subsequent_scheduled_build.reload.status }
|
||||
|
||||
expect(new_job).to be_pending
|
||||
end
|
||||
|
||||
it_behaves_like 'checks enqueue_immediately?'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
292
yarn.lock
292
yarn.lock
|
|
@ -3219,181 +3219,181 @@
|
|||
dom-accessibility-api "^0.5.1"
|
||||
pretty-format "^26.4.2"
|
||||
|
||||
"@tiptap/core@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.14.0.tgz#9a0ffd500cc720194916475506292006d2cb69c3"
|
||||
integrity sha512-MBSMzGYRFlwYCocvx3dU7zpCBSDQ0qWByNtStaEzuBUgzCJ6wn2DP/xG0cMcLmE3Ia0VLM4nwbLOAAvBXOtylA==
|
||||
"@tiptap/core@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.14.1.tgz#6f79f11b1053411e54eceb9ffcecf50eb80406fb"
|
||||
integrity sha512-rObIxRbT8dRGo9NGa/aMoKAKtoW2tSAaY4F+2g2JueNyD34Swi1Vg3kA3X+jor+nldPW6dQ4em05SauAy2EhfA==
|
||||
|
||||
"@tiptap/extension-blockquote@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.14.0.tgz#e5a660f0afc2b372da4c21545517e74d2c770b68"
|
||||
integrity sha512-AwqPP0jLYNioKxakiVw0vlfH/ceGFbV+SGoqBbPSGFPRdSbHhxHDNBlTtiThmT3N2PiVwXAD9xislJV+WY4GUA==
|
||||
"@tiptap/extension-blockquote@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.14.1.tgz#524a6528b03be03190624c29a22b55fd69878cd0"
|
||||
integrity sha512-IduWJHE5U2noK+z9JuzZ3wwrKBo9K2vdfW3O1drPBgPf5/QZRepspw6+GZIXG3HlYW2f8pom3CKJ7RKSGZgR+A==
|
||||
|
||||
"@tiptap/extension-bold@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.14.0.tgz#53655a81fd11304a83cc654fc4071e519170674d"
|
||||
integrity sha512-8DWwelH55H8KtLECSIv0wh8x/F/6lpagV/pMvT+Azujad0oqK+1iAPKU/kLgjXbFSkisrpV6KSwQts5neCtfRQ==
|
||||
"@tiptap/extension-bold@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.14.1.tgz#a3a696f9d09f4a5919bc598d5e524d4a2c2181c7"
|
||||
integrity sha512-CVVT25wDG5nQljQuNmm/AT5k+X619KzXXcvNwvZeR9kD4y14pB8LijSFpqUnOJ2jv1cbncc1/CUY+4Kv8lLIhA==
|
||||
|
||||
"@tiptap/extension-bubble-menu@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.14.0.tgz#d51752558323c89ed45ca0118265b9a9e4226166"
|
||||
integrity sha512-sN15n0RjPh+2Asvxs7l47hVEvX6c0aPempU8QQWcPUlHoGf1D/XkyHXy6GWVPSxZ5Rj5uAwgKvhHsG/FJ/YGKQ==
|
||||
"@tiptap/extension-bubble-menu@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.14.1.tgz#12d84e64750dc9f04967910fc1c2ba7e22dd01ac"
|
||||
integrity sha512-HF7xx6mxckvHpmfmVkAxUbU5GtdhL/+wY0todcZvC4h7AsZEbopMU6+46k48Mju79lPvdwwjrEljShdaeDRFhw==
|
||||
dependencies:
|
||||
tippy.js "^6.3.7"
|
||||
|
||||
"@tiptap/extension-bullet-list@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.14.0.tgz#9be7a09f792320a1baf33daf3dd88d149b9cd2c2"
|
||||
integrity sha512-SWnL4bP8Mm/mWN42AMQNoqYE0V6LgSBTVsHwwAki2wIUQdr9HyoAnohvHy3IME56NMwoyZyo+Mzl45wOqUxziA==
|
||||
"@tiptap/extension-bullet-list@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.14.1.tgz#e75cd51eb39df92716b6923ffe87eb794977e25c"
|
||||
integrity sha512-LEgyQodJkyAHgP9DUmlxXWkZSRkl668nYzWpk7si2A/rhk9GwftM2CQWifI6btKaFHrNh/RvLvT0mHb0Oa0INg==
|
||||
|
||||
"@tiptap/extension-code-block-lowlight@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.14.0.tgz#2ccf83471012d8b27b6002154c0b53802061858f"
|
||||
integrity sha512-jGcVOkcThwzLdXf56zYkmB0tcB8Xy3S+ImS3kDzaccdem6qCG05JeE33K8bfPqh99OU1QqO9XdHNO9x77A2jug==
|
||||
"@tiptap/extension-code-block-lowlight@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.14.1.tgz#3ffef64fff4514161f1f8ec666e36ef901e523cf"
|
||||
integrity sha512-Kl4zDq8yTu8EjWoc233DW5C6uz8sxRDFYnB8njKOm3dEQ9f5s+D1b38qwu1e+YcLrkBxRirkD58c2ojcZlS+HA==
|
||||
|
||||
"@tiptap/extension-code-block@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.14.0.tgz#7a1f85388bed7ab3f5e98f9121c7c9bebf7b7583"
|
||||
integrity sha512-LRYYZeh8U2XgfTsJ4houB9s9cVRt7PRfVa4MaCeOYKfowVOKQh67yV5oom8Azk9XrMPkPxDmMmdPAEPxeVYFvw==
|
||||
"@tiptap/extension-code-block@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.14.1.tgz#231e938202637ca998b17717c3ec7849d2c46122"
|
||||
integrity sha512-5sI4Dx3wizD9Q5MvJAlQZ/BFcBuRoRTHKuovg+zZCaPx+5+amONXPB9h6fAjwyZlJvnvY51xIPdSiqgcUuFR4w==
|
||||
|
||||
"@tiptap/extension-code@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.14.0.tgz#cbbc58f073478e70b2217e50fb7aad23b7ace88c"
|
||||
integrity sha512-kyo02mnzqgwXayMcyRA/fHQgb+nMmQQpIt1irZwjtEoFZshA7NnY/6b5SJmRcxQ4/X4r2Y2Ha2sWmOcEkLmt4A==
|
||||
"@tiptap/extension-code@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.14.1.tgz#8fb0cd127f58abcced189fb1938d1dca084e41e2"
|
||||
integrity sha512-JY2n5zOe5gtmx9wMmX2K8pJPLeDsCabOc0X7d/+pVlmgtGHvHQiqa7rsz1SvNspj03CuyeEqShi90I2PyheOyw==
|
||||
|
||||
"@tiptap/extension-document@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.14.0.tgz#9f631caa8b9a3d5cc448ffaf32e3a22326d87ef1"
|
||||
integrity sha512-qwEgpPIJ3AgXdEtRTr88hODbXRdt14VAwLj27PTSqexB5V7Ra1Jy7iQDhqRwBCoUomVywBsWYxkSuDisSRG+9w==
|
||||
"@tiptap/extension-document@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.14.1.tgz#30ef55a61ad27e51ea19ee8742d38d411c191dc9"
|
||||
integrity sha512-c6aQAi9jQ031ZLICi4nAsbU9pHGqccrupo6VsOXhzYWETOQ4LwHT7ABL/moH8FkskiyHnUJdBt87oHhOmGH+yw==
|
||||
|
||||
"@tiptap/extension-dropcursor@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.14.0.tgz#8036c782790fc96c17daa1def0e3f03279745058"
|
||||
integrity sha512-FIh5cdPuoPKvZ0GqSKhzMZGixm05ac3hSgqhMNCBZmXX459qBUI9CvDl/uzSnY9koBDeLVV3HYMthWQQLSXl9A==
|
||||
"@tiptap/extension-dropcursor@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.14.1.tgz#e1a49a9eccc908990ab6936f7f59a87d6a2fbde0"
|
||||
integrity sha512-YSQs0OIHFlJm0JEdoA1Rl/4ddlPHXHAscAJARlJnrpjy7L8GCkpljIpPT6YvlJZzCIOH3msqYytsTUjH5KO8Hg==
|
||||
|
||||
"@tiptap/extension-floating-menu@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.14.0.tgz#8fc400b0d47c2898552ef09bb0952bf3e6142ddb"
|
||||
integrity sha512-Khx7M7RfZlD1/T/PUlpJmao6FtEBa2L6td2hhaW1USflwGJGk0U/ud4UEqh+aZoJZrkot/EMhEvzmORF3nq+xw==
|
||||
"@tiptap/extension-floating-menu@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.14.1.tgz#f3d05f669ffc9d636021d1af8cefa17e4ceb0af6"
|
||||
integrity sha512-aQSDJ2TEdXa3/2i3GnBHVPuD3DUyvIifMq7zNkeQUmqCG73VS8xpuTLCODw68Z+efgpbWbh/szFSE+yZdAR8ZQ==
|
||||
dependencies:
|
||||
tippy.js "^6.3.7"
|
||||
|
||||
"@tiptap/extension-gapcursor@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.14.0.tgz#cc2a9296df36879816b8cb4121f58b0a0b3c415a"
|
||||
integrity sha512-as+SqC39FRshw4Fm1XVlrdSXveiusf5xiC4nuefLmXsUxO7Yx67x8jS0/VQbxWTLHZ6R1YEW8prLtnxGmVLCAQ==
|
||||
"@tiptap/extension-gapcursor@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.14.1.tgz#ac58084468f9fd9cc0119d76ac3da1d79144ac3d"
|
||||
integrity sha512-TutEKPNMUQ4sDD7ilrBxCWtp1IRu1tdTtQw3TgnFVqOuEhhl7pX/+lEJ0kir3hb2Dk5SQfAIAQDw468X8kYohw==
|
||||
|
||||
"@tiptap/extension-hard-break@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.14.0.tgz#ff1ac6be4c09b85fe01d1a3782360d994b570abc"
|
||||
integrity sha512-A8c8n8881iBq3AusNqibh6Hloybr+FgYdg4Lg4jNxbbEaL0WhyLFge1bWlGVpbHXFqdv5YldMUAu6Rop3FhNvw==
|
||||
"@tiptap/extension-hard-break@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.14.1.tgz#31a3aa68b828d5e58037dd014ad4189cccdddbf4"
|
||||
integrity sha512-VGE01d/nIW/8UnGLEFyF6NesGdFUHV6ekWjKWLYjVCqaUNSSIB8ju4SlGBun3NOzJ7q+AUYh0CqgWEcO4RV8eA==
|
||||
|
||||
"@tiptap/extension-heading@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.14.0.tgz#c5a9dc761712e9c87073ba8446548cbe4d403360"
|
||||
integrity sha512-vM//6G3Ox3mxPv9eilhrDqylELCc8kEP1aQ4xUuOw7vCidjNtGggOa1ERnnpV2dCa2A9E8y4FHtN4Xh29stXQg==
|
||||
"@tiptap/extension-heading@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.14.1.tgz#3f7284d396b210eec51c216e41467efb97821450"
|
||||
integrity sha512-nKpmkVEM2dTtALCDMbpQBjGCfgdQ1Fm6DT8kzskM9DD+rA2J2+pygkyjmgVCk3IgjXMqzs483vFZc1g74B9Viw==
|
||||
|
||||
"@tiptap/extension-highlight@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-highlight/-/extension-highlight-2.14.0.tgz#7a40ce7113d369e38d4dfa2d625deda386164b37"
|
||||
integrity sha512-21eouZEuCBFrpGeefnnU9yJ1SH32L9gSlT9MOJXBSXCX5HFskNLdN8Q4cQSyRXSt6r5kEz1GG5a4I805/U2TMQ==
|
||||
"@tiptap/extension-highlight@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-highlight/-/extension-highlight-2.14.1.tgz#d73485966e288ba8eb5a0ddcff2a45ff43a24d5b"
|
||||
integrity sha512-9dCzQvELUlPxVAXTaxrdUQHy+QIXYqY0rSBL73gQv4fjwWYClhxALHhfy+3+SZQGpiNU3aUhjUoQU6co4/soXw==
|
||||
|
||||
"@tiptap/extension-history@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.14.0.tgz#e7e29427c22845567c0fece8dffc32d2beeecfff"
|
||||
integrity sha512-/qnOHQFCEPfkb3caykqd+sqzEC2gx30EQB/mM7+5kIG7CQy7XXaGjFAEaqzE1xJ783Q2E7GVk4JxWM+3NhYSLw==
|
||||
"@tiptap/extension-history@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.14.1.tgz#4d5d6caec1526f164672373b7e0ea3d37aa73963"
|
||||
integrity sha512-aQFcN5v/dfEKEbhjH/X3Hz0CjBlhwcyG80v12PKGeYNdwT77I8H4iYzErAclK9tAVLZipnTFm0dqaXaC+ymkYA==
|
||||
|
||||
"@tiptap/extension-horizontal-rule@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.14.0.tgz#f777c8d9eb945ef50d865a37784fd0dc6c982674"
|
||||
integrity sha512-OrKWgHOhmJtVHjPYaEJetNLiNEvrI85lTrGxzeQa+a8ACb93h4svyHe9J+LHs5pKkXDQFcpYEXJntu0LVLLiDw==
|
||||
"@tiptap/extension-horizontal-rule@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.14.1.tgz#3adbdc3282cc1aa167ff2c080e65c81ca7427b43"
|
||||
integrity sha512-o2UWji9KWNnDPz8ojyumqwnkXaTbfiGtQSyX+d42/P5ICkwr9VmVReiffEftv58x9JuVjdFLyGqtqbfcGu/gxg==
|
||||
|
||||
"@tiptap/extension-image@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.14.0.tgz#151c96c302b0f30dd4fe90fb5ec637531264e40e"
|
||||
integrity sha512-pYCUzZBgsxIvVGTzuW03cPz6PIrAo26xpoxqq4W090uMVoK0SgY5W5y0IqCdw4QyLkJ2/oNSFNc2EP9jVi1CcQ==
|
||||
"@tiptap/extension-image@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.14.1.tgz#1684da02d4a86fc0da86ea9b9b2207d785ec246a"
|
||||
integrity sha512-81KJNjGgpkWNxCHuThI2iS+pLhIBLv9AYClVAsW+EQhH/ohsAB0CG3TXGTvg25yrnYI6v9n4VU5SWX4Fe5DLxQ==
|
||||
|
||||
"@tiptap/extension-italic@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.14.0.tgz#b250dc6d95ba15e73f37230f07bacb0946fc042d"
|
||||
integrity sha512-yEw2S+smoVR8DMYQMAWckVW2Sstf7z5+GBZ8zm8NMGhMKb1JFCPZUv5KTTIPnq7ZrKuuZHvjN9+Ef1dRYD8T2A==
|
||||
"@tiptap/extension-italic@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.14.1.tgz#1d7960f48c1af9c7069e23f823917dbfaf6b666c"
|
||||
integrity sha512-ou8pt9QhfkPu2hrKMJnmKKplkKBlOJ8qWBls2DtjB2HkLjY8YqC6eRsZc2pnYid54AkGP5IDWom8DteA0DdgBQ==
|
||||
|
||||
"@tiptap/extension-link@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.14.0.tgz#c858eb67eb9c651b804fae5d324f30431884e75f"
|
||||
integrity sha512-fsqW7eRD2xoD6xy7eFrNPAdIuZ3eicA4jKC45Vcft/Xky0DJoIehlVBLxsPbfmv3f27EBrtPkg5+msLXkLyzJA==
|
||||
"@tiptap/extension-link@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.14.1.tgz#4c1f1692e183d586206e4a5ff9190f7623cd8cff"
|
||||
integrity sha512-CTKAyl+23yG3jyFYQaQk/hQhzTF+Wjly2Skbs16a2ZCUkliu60c3uheBdYKqfo/HVJCBpT/TJgP7TrxvV8usuw==
|
||||
dependencies:
|
||||
linkifyjs "^4.2.0"
|
||||
|
||||
"@tiptap/extension-list-item@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.14.0.tgz#da5c9d1747ece9dcbf0abdb0f85ad18857f76d35"
|
||||
integrity sha512-t1jXDPEd82sC6vZVE/12/CB52uuiydCIcRfwdh21xNgBMckToKO9S0K6XEp4ROtrKQdlIH2JDVPfpUBvVrYN8Q==
|
||||
"@tiptap/extension-list-item@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.14.1.tgz#10ddd8db1fba69c6fcddafa1931547380281912f"
|
||||
integrity sha512-nt9KhLb9SrTCYVg7pEK0SaVFhilLQYQlWGAaXbSLE1P7B+WPHxNpZOdEBZ8oky4JX98LpF7BjsP9msw7mO2HiQ==
|
||||
|
||||
"@tiptap/extension-ordered-list@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.14.0.tgz#53e8fae14f40c19b0c72d1afa8a772285fe021dd"
|
||||
integrity sha512-QUZcyuW9AKvSfpFHcGmbyRCqxcpY0VNf0xipEtogxbA+JDDw3ZSPqU1dUgz9wk00RahPTwNDdY5aVjdQ5N4N9Q==
|
||||
"@tiptap/extension-ordered-list@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.14.1.tgz#5e269902606504516bed333b83ea3ae6c99ce284"
|
||||
integrity sha512-CtX2Md7OXRbvvjYomgwMfzT02aolG8cun1rK/7rtZyfqKCnloIE3lhUAJ2m8wsiFsIE2EJ0HiBr4e1Zlwypnvw==
|
||||
|
||||
"@tiptap/extension-paragraph@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.14.0.tgz#9116a961b618c27974bb95cbfc40f7630c9e20e7"
|
||||
integrity sha512-bsQesVpgvDS2e+wr2fp59QO7rWRp2FqcJvBafwXS3Br9U5Mx3eFYryx4wC7cUnhlhUwX5pmaoA7zISgV9dZDgg==
|
||||
"@tiptap/extension-paragraph@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.14.1.tgz#ea525482c453b6265c99838c20b02385556275f5"
|
||||
integrity sha512-lJpEnUL79Hc7HHOLVGYGwiq1WoM4noCVJvBx3q7PBrUIK/eRCB76zfzG+PTQArWKScqSypfqN7kKaP/QicGNdw==
|
||||
|
||||
"@tiptap/extension-strike@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.14.0.tgz#6c6c802b1e8ffbad22ee4aec9d8068664d4dc2ea"
|
||||
integrity sha512-rD5d/IL3XPfBOrHRHxt+b+0X1jbIbWONGiad/3sX0ZYQD3PandtCWboH40r/J5tFksebuY12dVYyYQKgLpDBOQ==
|
||||
"@tiptap/extension-strike@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.14.1.tgz#de2ed9b791e0a0a4745cd46638d7394c48714daa"
|
||||
integrity sha512-Atj7anQAd5rU2N532ByXFBsqBICOeCJkHHcAGRMMtvCPRlESXjqbWlU1A8RHGSi/XroWjvq6gO/45NDt2/nD1Q==
|
||||
|
||||
"@tiptap/extension-subscript@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.14.0.tgz#b38f4dea8744ff0c698c2917bba8a5f0541a8db6"
|
||||
integrity sha512-1gQucSZ6WqhKukc8YA7ZfQzBYaVY00F6G7+trD2iWSm6EpiabaUVP0vMjuonIiujTioEwe04KmZuC9ZLbEU9dQ==
|
||||
"@tiptap/extension-subscript@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.14.1.tgz#e8ace6ef382ac692aa7a5aecc29ea142e4a92450"
|
||||
integrity sha512-HPGDOyItlixCYsSQf/qCi4clJRFB/hODLfFKJBjzj+Jj1HzKYj1AlS4d3aRT3tpJMSzcgWL6YykVHgvSD5FK3w==
|
||||
|
||||
"@tiptap/extension-superscript@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.14.0.tgz#2e3121ef2c0df2fe5027a69160a107c993da1a47"
|
||||
integrity sha512-BnsqY9TxN15KxxoX1rulL0sV0Wu3umD4Un0E90LZ5G/QRrVUeohAuOiraqRJ4GnJPVJBR2H0+7Sg5sKqYuIpnQ==
|
||||
"@tiptap/extension-superscript@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.14.1.tgz#0a97002494964642c1db6b70984cbd530be79432"
|
||||
integrity sha512-RHIzNAm5fMgcJI+YBSgAzZmkusON66MA+TADzhGrfGzLeZIP7pSosWcJTRE1voAunzCYg7BlY6l9pFhgbX/5Ug==
|
||||
|
||||
"@tiptap/extension-table-cell@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.14.0.tgz#fb28edd5a9f498c7aba851e38dd6e4a7d8663a41"
|
||||
integrity sha512-DkSNAAkMI/ymPgO8y8Gv0MDVcbd2gk7xrSyicIDNoDFFXp15VasInGW8mvyM+CgvlurGB2N+PkYncPtfb4XNuQ==
|
||||
"@tiptap/extension-table-cell@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.14.1.tgz#1d3dd1419c0929f37d48e4aa243d708746f02193"
|
||||
integrity sha512-7KhzD37IJRiBvx4CfOGiPmFkFNeHi4u7pgsymId2AJ7ebokFl7KnnD4MzZlJYNZm0+IgELsZILb35rpKqII7pQ==
|
||||
|
||||
"@tiptap/extension-table-header@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.14.0.tgz#10cce2a4b3ace59ffb1734549a09fd13ecd5440d"
|
||||
integrity sha512-wX6/+t0iCo3KrqK2OjK0vbFeL76Pq+VpobGt+oM8lcxsENnsa6a0s3wdd1QEVLVPlj+WMFQggAG80Rf17+iDxA==
|
||||
"@tiptap/extension-table-header@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.14.1.tgz#d7c8ec6583d72889d3a1aa5d77e3d3b9f2c8d063"
|
||||
integrity sha512-Aa3TzbclQ+V00UrgWhQI5wlYFfGCruIJzV3V0V2ujAFMNswF+GP8E2Yjyhj8lcCRTunV5ucDpVDbw8gYFQWtXA==
|
||||
|
||||
"@tiptap/extension-table-row@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.14.0.tgz#5154a05d199c0728470a99079ca56aae74753a75"
|
||||
integrity sha512-a1GvCIju9xETIQu664lVQNftHqpPdRmwYp+1QzY82v3zHClso+tTLPeBSlbDdUscSmv3yZXgGML20IiOoR2l2Q==
|
||||
"@tiptap/extension-table-row@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.14.1.tgz#514f64fee6c67c99bc5454b087815b704cda7c6c"
|
||||
integrity sha512-zhnLu3hKpzafpjk8uxx8qlHKAnTx89fRO+3n1hWfVH5Dzh9rCsUE3OX/peCHLCg3HGn0OQPMqkKe3IKF/JB3FA==
|
||||
|
||||
"@tiptap/extension-table@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.14.0.tgz#b7541351518c2cf7d5bae72640d6d3375b29c677"
|
||||
integrity sha512-X/wH3XKxi5+G7cB+lHt3fPMWIJ30IBkzrJZYapJ8d4p2JxMNIU1Nyu+8K6204d0hF6SVWY8hvb/Jq/WgHtoCFA==
|
||||
"@tiptap/extension-table@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.14.1.tgz#261a9f31509276c299d1d45b0f634ad6830ecdd3"
|
||||
integrity sha512-CMwcO5ChLRPKZLG5RHKHoFFy3C4gB5gKePnfAvdrjZ47LoYECvb0iy5CTFdgQCkaHokwFNfjW6pKOHFymjbuhQ==
|
||||
|
||||
"@tiptap/extension-task-item@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.14.0.tgz#5d576c5486dba9d4475456a3f1dc4e614b6b3ac0"
|
||||
integrity sha512-MFE928s1J2ACyjOlkx52D/+r6aqz6c516C0tvnP2vzrkijFaSMNY4Xg7L1wTinzIdijh184AYQpyw7LezJa1ug==
|
||||
"@tiptap/extension-task-item@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.14.1.tgz#e4c351634ad9a6ef4a9603349ff7144fb527cf71"
|
||||
integrity sha512-goGyFcc98G5gLbg1cTtQXa2ZTkfz37hpQkuEsTcyV+ypfmiCtc04AX/azgqw+B0N6i4mO76jBCalR5upKCoZmQ==
|
||||
|
||||
"@tiptap/extension-task-list@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.14.0.tgz#a61ae92ac3e534ff192f57c88dd8bbb14ca9fc11"
|
||||
integrity sha512-o2VELXgkDIHS15pnF1W2OFfxZGvo9V6RcwjzCYUS0mqMF9TTbfHwddRcv4t3pifpMO3sWhspVARavJAGaP5zdQ==
|
||||
"@tiptap/extension-task-list@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.14.1.tgz#6c8ced6eea78ace96cf925083abdfa13bcb9a99b"
|
||||
integrity sha512-ljQ6eEu186i+tPlwPLE9riGRSSERjWEVHQMtJbWjJoAGftwErSw/oLeBd6K20Vrtu3G8YWLhQv/04WJEpLP+xw==
|
||||
|
||||
"@tiptap/extension-text@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.14.0.tgz#2b57f47917e97b6c06774b7eaf8598973536a29e"
|
||||
integrity sha512-rHny566nGZHq61zRLwQ9BPG55W/O+eDKwUJl+LhrLiVWwzpvAl9QQYixtoxJKOY48VK41PKwxe3bgDYgNs/Fhg==
|
||||
"@tiptap/extension-text@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.14.1.tgz#a4d4a6fa4d1b38e1949c9a7fc0823d761c09d17d"
|
||||
integrity sha512-rSqCHYFLj+bqOcAh4ufA4dqNf1DBp+WLTKCaDxDoo+XZhdh9ED6xpmXmvbm+76QxBS2JaAyyOazKMflBfpjPuw==
|
||||
|
||||
"@tiptap/pm@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.14.0.tgz#bc097936a6e4da90dbfe05ff55f8041ff6dda238"
|
||||
integrity sha512-cnsfaIlvTFCDtLP/A2Fd3LmpttgY0O/tuTM2fC71vetONz83wUTYT+aD9uvxdX0GkSocoh840b0TsEazbBxhpA==
|
||||
"@tiptap/pm@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.14.1.tgz#1ecce76f7156bef0a730a757351f922199438094"
|
||||
integrity sha512-hw/Z1Qsb1qbWkdH+c0SZv/Mr29tQrcda4vPhgY8KA0OXulu3rjb1NtMctcHFOSs5TofaVchd8MHvi4273fQPuA==
|
||||
dependencies:
|
||||
prosemirror-changeset "^2.3.0"
|
||||
prosemirror-collab "^1.3.1"
|
||||
|
|
@ -3414,18 +3414,18 @@
|
|||
prosemirror-transform "^1.10.2"
|
||||
prosemirror-view "^1.37.0"
|
||||
|
||||
"@tiptap/suggestion@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.14.0.tgz#3170dcf837f9261ecda7c55757ded6c99c977e7c"
|
||||
integrity sha512-AXzEw0KYIyg5id8gz5geIffnBtkZqan5MWe29rGo3gXTfKH+Ik8tWbZdnlMVheycsUCllrymDRei4zw9DqVqkQ==
|
||||
"@tiptap/suggestion@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.14.1.tgz#dd3fb2812c1eaa54f2978eb731e2c8de48bfed28"
|
||||
integrity sha512-u9GqK3mo/rihLb10D2FfLMZJBjVFYYr63cWFOAPZbFFQLxaxkiIHTYXN18a3pfPsgHH6ilVw2JkE7XKJS3UZTg==
|
||||
|
||||
"@tiptap/vue-2@^2.14.0":
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.14.0.tgz#c441eaf789848a2491d32265e2bcbb2f5f370170"
|
||||
integrity sha512-BD5cRLmQSuEQiMXQ4ngbytZa3D6y8ofc4tBRPHxXKU6bp2CA3Gec6g7LqSiIIeUv/i5r2xfWol7aajypZJL85g==
|
||||
"@tiptap/vue-2@^2.14.1":
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.14.1.tgz#2968b617ca5a31a662d014f322251030d8c795e3"
|
||||
integrity sha512-5iY6Hm5gHrX59l9nWrULh+W6fq208aWtxNOSCtTFR6yzwOSRSQIxlgYNpHDQmmdYPwVJ0EMCV8Fb5GgqPKWCAA==
|
||||
dependencies:
|
||||
"@tiptap/extension-bubble-menu" "^2.14.0"
|
||||
"@tiptap/extension-floating-menu" "^2.14.0"
|
||||
"@tiptap/extension-bubble-menu" "^2.14.1"
|
||||
"@tiptap/extension-floating-menu" "^2.14.1"
|
||||
vue-ts-types "1.6.2"
|
||||
|
||||
"@tootallnate/once@2":
|
||||
|
|
|
|||
Loading…
Reference in New Issue