Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b1238272e1
commit
e1d9989e67
2
Gemfile
2
Gemfile
|
|
@ -540,7 +540,7 @@ gem 'spamcheck', '~> 1.3.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
|||
gem 'gitaly', '~> 16.5.0.pre.rc1' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
# KAS GRPC protocol definitions
|
||||
gem 'kas-grpc', '~> 0.2.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
gem 'kas-grpc', '~> 0.3.0', feature_category: :deployment_management
|
||||
|
||||
gem 'grpc', '~> 1.58.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@
|
|||
{"name":"kaminari-actionview","version":"1.2.2","platform":"ruby","checksum":"1330f6fc8b59a4a4ef6a549ff8a224797289ebf7a3a503e8c1652535287cc909"},
|
||||
{"name":"kaminari-activerecord","version":"1.2.2","platform":"ruby","checksum":"0dd3a67bab356a356f36b3b7236bcb81cef313095365befe8e98057dd2472430"},
|
||||
{"name":"kaminari-core","version":"1.2.2","platform":"ruby","checksum":"3bd26fec7370645af40ca73b9426a448d09b8a8ba7afa9ba3c3e0d39cdbb83ff"},
|
||||
{"name":"kas-grpc","version":"0.2.0","platform":"ruby","checksum":"b9a3f787ec9198819034ec358d73b9a3f374d4dd001d673fdaa650eb5ec99a1e"},
|
||||
{"name":"kas-grpc","version":"0.3.0","platform":"ruby","checksum":"78dfc454e6725e6354e66e9e65ea87b6ad0888f52d20bf41775e5400d74dad8a"},
|
||||
{"name":"knapsack","version":"1.21.1","platform":"ruby","checksum":"82f70422adebcacec1b514f6ebff65265fc85d836e3c320718a160d8ac41cf14"},
|
||||
{"name":"kramdown","version":"2.3.2","platform":"ruby","checksum":"cb4530c2e9d16481591df2c9336723683c354e5416a5dd3e447fa48215a6a71c"},
|
||||
{"name":"kramdown-parser-gfm","version":"1.1.0","platform":"ruby","checksum":"fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729"},
|
||||
|
|
|
|||
|
|
@ -954,7 +954,7 @@ GEM
|
|||
activerecord
|
||||
kaminari-core (= 1.2.2)
|
||||
kaminari-core (1.2.2)
|
||||
kas-grpc (0.2.0)
|
||||
kas-grpc (0.3.0)
|
||||
grpc (~> 1.0)
|
||||
knapsack (1.21.1)
|
||||
rake
|
||||
|
|
@ -1925,7 +1925,7 @@ DEPENDENCIES
|
|||
jsonb_accessor (~> 1.3.10)
|
||||
jwt (~> 2.5)
|
||||
kaminari (~> 1.2.2)
|
||||
kas-grpc (~> 0.2.0)
|
||||
kas-grpc (~> 0.3.0)
|
||||
knapsack (~> 1.21.1)
|
||||
kramdown (~> 2.3.1)
|
||||
kubeclient (~> 4.11.0)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<history-item icon="warning">
|
||||
<div class="gl-display-flex gl-xs-flex-direction-column">
|
||||
<div class="gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row">
|
||||
<gl-sprintf :message="$options.i18n.reportedByForCategory">
|
||||
<template #name>{{ reporterName }}</template>
|
||||
<template #category>{{ report.category }}</template>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<header
|
||||
class="gl-py-4 gl-border-b gl-display-flex gl-justify-content-space-between gl-xs-flex-direction-column"
|
||||
class="gl-py-4 gl-border-b gl-display-flex gl-justify-content-space-between gl-flex-direction-column gl-sm-flex-direction-row"
|
||||
>
|
||||
<div class="gl-display-flex gl-align-items-center gl-gap-3">
|
||||
<gl-badge :variant="badgeVariant" :aria-label="badgeText">
|
||||
|
|
@ -67,7 +67,7 @@ export default {
|
|||
<gl-link :href="user.path"> @{{ user.username }} </gl-link>
|
||||
</div>
|
||||
<nav
|
||||
class="gl-display-flex gl-sm-align-items-center gl-mt-4 gl-sm-mt-0 gl-xs-flex-direction-column"
|
||||
class="gl-display-flex gl-sm-align-items-center gl-mt-4 gl-sm-mt-0 gl-flex-direction-column gl-sm-flex-direction-row"
|
||||
>
|
||||
<gl-button :href="user.adminPath">
|
||||
{{ $options.i18n.adminProfile }}
|
||||
|
|
|
|||
|
|
@ -65,14 +65,14 @@ export default {
|
|||
<template>
|
||||
<div class="gl-pt-6">
|
||||
<div
|
||||
class="gl-pb-3 gl-display-flex gl-justify-content-space-between gl-xs-flex-direction-column gl-align-items-center"
|
||||
class="gl-pb-3 gl-display-flex gl-justify-content-space-between gl-flex-direction-column gl-sm-flex-direction-row gl-align-items-center"
|
||||
>
|
||||
<h2 class="gl-font-size-h1 gl-mt-2 gl-mb-2">
|
||||
{{ $options.i18n.reportTypes[reportType] }}
|
||||
</h2>
|
||||
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-stretch gl-xs-flex-direction-column gl-mt-3 gl-sm-mt-0"
|
||||
class="gl-display-flex gl-align-items-stretch gl-flex-direction-column gl-sm-flex-direction-row gl-mt-3 gl-sm-mt-0"
|
||||
>
|
||||
<template v-if="report.screenshot">
|
||||
<gl-button data-testid="screenshot-button" @click="toggleScreenshotModal">
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ export default {
|
|||
|
||||
<template #modal-footer>
|
||||
<div
|
||||
class="gl-m-0 gl-w-full gl-display-flex gl-xs-flex-direction-column! gl-flex-direction-row-reverse"
|
||||
class="gl-m-0 gl-w-full gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row-reverse"
|
||||
>
|
||||
<gl-button
|
||||
class="gl-w-full gl-sm-w-auto gl-xs-mb-3! gl-sm-ml-3!"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export default {
|
|||
<template>
|
||||
<div
|
||||
v-show="showHighlightBar"
|
||||
class="gl-border-solid gl-border-1 gl-border-gray-100 gl-p-5 gl-mb-3 gl-rounded-base gl-display-flex gl-justify-content-space-between gl-xs-flex-direction-column"
|
||||
class="gl-border-solid gl-border-1 gl-border-gray-100 gl-p-5 gl-mb-3 gl-rounded-base gl-display-flex gl-justify-content-space-between gl-flex-direction-column gl-sm-flex-direction-row"
|
||||
>
|
||||
<div v-if="alert" class="gl-mr-3">
|
||||
<span class="gl-font-weight-bold">{{ s__('HighlightBar|Original alert:') }}</span>
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ export default {
|
|||
<slot name="left-action"></slot>
|
||||
</div>
|
||||
<div
|
||||
class="gl-display-flex gl-xs-flex-direction-column gl-justify-content-space-between gl-align-items-stretch gl-flex-grow-1"
|
||||
class="gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row gl-justify-content-space-between gl-align-items-stretch gl-flex-grow-1"
|
||||
>
|
||||
<div class="gl-display-flex gl-flex-direction-column gl-xs-mb-3 gl-min-w-0 gl-flex-grow-1">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export default {
|
|||
<div class="gl-display-flex gl-flex-direction-column">
|
||||
<div class="gl-display-flex gl-align-items-center gl-py-3">
|
||||
<div
|
||||
class="gl-display-flex gl-xs-flex-direction-column gl-justify-content-space-between gl-align-items-stretch gl-flex-grow-1"
|
||||
class="gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row gl-justify-content-space-between gl-align-items-stretch gl-flex-grow-1"
|
||||
>
|
||||
<div class="gl-display-flex gl-flex-direction-column gl-xs-mb-3 gl-min-w-0 gl-flex-grow-1">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -30,3 +30,9 @@
|
|||
width: 75%;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-sm-flex-direction-row-reverse {
|
||||
@include gl-media-breakpoint-up(sm) {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
}
|
||||
|
|
@ -461,7 +461,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
@update_current_user_path = expose_path(api_v4_user_preferences_path)
|
||||
@endpoint_metadata_url = endpoint_metadata_url(@project, @merge_request)
|
||||
@endpoint_diff_batch_url = endpoint_diff_batch_url(@project, @merge_request)
|
||||
@diffs_batch_cache_key = @merge_request.merge_head_diff&.id if merge_request.diffs_batch_cache_with_max_age?
|
||||
|
||||
if merge_request.diffs_batch_cache_with_max_age?
|
||||
@diffs_batch_cache_key = @merge_request.merge_head_diff&.patch_id_sha
|
||||
end
|
||||
|
||||
set_pipeline_variables
|
||||
|
||||
|
|
@ -629,7 +632,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
params = request
|
||||
.query_parameters
|
||||
.merge(view: 'inline', diff_head: true, w: show_whitespace, page: '0', per_page: per_page)
|
||||
params[:ck] = merge_request.merge_head_diff&.id if merge_request.diffs_batch_cache_with_max_age?
|
||||
params[:ck] = merge_request.merge_head_diff&.patch_id_sha if merge_request.diffs_batch_cache_with_max_age?
|
||||
|
||||
diffs_batch_project_json_merge_request_path(project, merge_request, 'json', params)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ module Resolvers
|
|||
def resolve
|
||||
return [] unless can_read_connected_agents?
|
||||
|
||||
BatchLoader::GraphQL.for(agent.id).batch(key: project, default_value: []) do |agent_ids, loader|
|
||||
agents = get_connected_agents.group_by(&:agent_id).slice(*agent_ids)
|
||||
BatchLoader::GraphQL.for(agent.id).batch(default_value: []) do |agent_ids, loader|
|
||||
agents = get_connected_agents(agent_ids).group_by(&:agent_id)
|
||||
|
||||
agents.each do |agent_id, connections|
|
||||
loader.call(agent_id, connections)
|
||||
|
|
@ -27,8 +27,8 @@ module Resolvers
|
|||
current_user.can?(:admin_cluster, project)
|
||||
end
|
||||
|
||||
def get_connected_agents
|
||||
kas_client.get_connected_agents(project: project)
|
||||
def get_connected_agents(agent_ids)
|
||||
kas_client.get_connected_agents_by_agent_ids(agent_ids: agent_ids)
|
||||
rescue GRPC::BadStatus, Gitlab::Kas::Client::ConfigurationError => e
|
||||
raise Gitlab::Graphql::Errors::ResourceNotAvailable, e.class.name
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ module ImportCsv
|
|||
attr_reader :user, :project, :provided_titles, :results, :milestone_errors
|
||||
|
||||
def execute
|
||||
available_milestones = find_milestones_by_titles
|
||||
return ServiceResponse.success if provided_titles.sort == available_milestones.sort
|
||||
result = find_milestones_by_titles
|
||||
available_milestones = result.map(&:title).uniq.sort
|
||||
return ServiceResponse.success(payload: result) if provided_titles.sort == available_milestones
|
||||
|
||||
milestone_errors[:missing][:header] = 'Milestone'
|
||||
milestone_errors[:missing][:titles] = provided_titles.difference(available_milestones) || []
|
||||
|
|
@ -29,7 +30,7 @@ module ImportCsv
|
|||
title: provided_titles
|
||||
}
|
||||
finder_params[:group_ids] = project.group.self_and_ancestors.select(:id) if project.group
|
||||
MilestonesFinder.new(finder_params).execute.map(&:title).uniq
|
||||
MilestonesFinder.new(finder_params).execute
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ module Issuable
|
|||
{
|
||||
title: row[:title],
|
||||
description: row[:description],
|
||||
due_date: row[:due_date]
|
||||
due_date: row[:due_date],
|
||||
milestone_id: find_milestone_by_title(row[:milestone])
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -34,13 +35,20 @@ module Issuable
|
|||
# Pre-Process Milestone if header is present
|
||||
return unless csv_data.lines.first.downcase.include?('milestone')
|
||||
|
||||
provided_titles = with_csv_lines.filter_map { |row| row[:milestone]&.strip&.downcase }.uniq
|
||||
provided_titles = with_csv_lines.filter_map { |row| row[:milestone]&.strip }.uniq
|
||||
result = ::ImportCsv::PreprocessMilestonesService.new(user, project, provided_titles).execute
|
||||
@available_milestones = result.payload
|
||||
return if result.success?
|
||||
|
||||
# collate errors here and throw errors
|
||||
results[:preprocess_errors][:milestone_errors] = result.payload
|
||||
end
|
||||
|
||||
def find_milestone_by_title(title)
|
||||
return unless title
|
||||
|
||||
@available_milestones.find { |milestone| milestone.title == title.to_s.strip } if @available_milestones
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
- if project.licensed_feature_available?(:code_owners)
|
||||
#js-code-owners{ data: { branch: @ref, can_view_branch_rules: can_view_branch_rules?, branch_rules_path: branch_rules_path } }
|
||||
|
||||
.nav-block.gl-display-flex.gl-xs-flex-direction-column.gl-align-items-stretch
|
||||
.nav-block.gl-display-flex.gl-flex-direction-column.gl-sm-flex-direction-row.gl-align-items-stretch
|
||||
= render 'projects/tree/tree_header', tree: @tree
|
||||
|
||||
- if project.forked?
|
||||
|
|
|
|||
|
|
@ -2481,7 +2481,7 @@ This endpoint:
|
|||
merge requests).
|
||||
- In [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) and later, on
|
||||
[Premium or Ultimate](https://about.gitlab.com/pricing/) tiers,
|
||||
[delayed project deletion](../user/project/settings/index.md#delayed-project-deletion)
|
||||
[delayed project deletion](../user/project/working_with_projects.md#delayed-project-deletion)
|
||||
is applied if enabled.
|
||||
- From [GitLab 15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/396500) on
|
||||
[Premium or Ultimate](https://about.gitlab.com/pricing/) tiers, deletes a project immediately if the project is already
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ To set a project as a catalog resource:
|
|||
1. Expand **Visibility, project features, permissions**.
|
||||
1. Scroll down to **CI/CD Catalog resource** and select the toggle to mark the project as a catalog resource.
|
||||
|
||||
Ensure the project has a clear [description](../../user/project/settings/index.md#edit-project-name-and-description),
|
||||
Ensure the project has a clear [description](../../user/project/working_with_projects.md#edit-project-name-and-description),
|
||||
as the project description is displayed in the component list in the catalog.
|
||||
|
||||
NOTE:
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ Prerequisites:
|
|||
- The agent for Kubernetes must be shared with the environment's project, or its parent group, using the [`user_access`](../../user/clusters/agent/user_access.md) keyword.
|
||||
- Self-managed only. KAS is running on the GitLab subdomain. For example, `kas.example.com` and `example.com`.
|
||||
|
||||
### The environment already exists
|
||||
::Tabs
|
||||
|
||||
:::TabTitle The environment already exists
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Operate > Environments**.
|
||||
|
|
@ -42,7 +44,7 @@ Prerequisites:
|
|||
1. Optional. From the **Flux resource** dropdown list, select a Flux resource.
|
||||
1. Select **Save**.
|
||||
|
||||
### The environment doesn't exist
|
||||
:::TabTitle The environment doesn't exist
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Operate > Environments**.
|
||||
|
|
@ -53,6 +55,8 @@ Prerequisites:
|
|||
1. Optional. From the **Flux resource** dropdown list, select a Flux resource.
|
||||
1. Select **Save**.
|
||||
|
||||
::EndTabs
|
||||
|
||||
## View a dashboard
|
||||
|
||||
> Kubernetes watch API integration [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/422945) in GitLab 16.6 [with a flag](../../administration/feature_flags.md) named `k8s_watch_api`. Disabled by default.
|
||||
|
|
|
|||
|
|
@ -529,3 +529,27 @@ migration has failed with NoMethodError:undefined method `<<' for nil:NilClass,
|
|||
```
|
||||
|
||||
If `BackfillProjectPermissionsInBlobs` is the only halted migration, you can upgrade to the latest patch version of GitLab 16.0, which includes [the fix](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118494). Otherwise, you can ignore the error as it will not affect the current functionality of advanced search.
|
||||
|
||||
## `ElasticIndexInitialBulkCronWorker` and `ElasticIndexBulkCronWorker` jobs stuck in deduplication
|
||||
|
||||
In GitLab 16.5 and earlier, the `ElasticIndexInitialBulkCronWorker` and `ElasticIndexBulkCronWorker` jobs might get stuck in deduplication. This issue might prevent advanced search from properly indexing documents even after creating a new index. In GitLab 16.6, `idempotent!` was [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135817) for bulk cron workers that perform indexing.
|
||||
|
||||
The Sidekiq log might have the following entries:
|
||||
|
||||
```shell
|
||||
{"severity":"INFO","time":"2023-10-31T10:33:06.998Z","retry":0,"queue":"default","version":0,"queue_namespace":"cronjob","args":[],"class":"ElasticIndexInitialBulkCronWorker",
|
||||
...
|
||||
"idempotency_key":"resque:gitlab:duplicate:default:<value>","duplicate-of":"91e8673347d4dc84fbad5319","job_size_bytes":2,"pid":12047,"job_status":"deduplicated","message":"ElasticIndexInitialBulkCronWorker JID-5e1af9180d6e8f991fc773c6: deduplicated: until executing","deduplication.type":"until executing"}
|
||||
```
|
||||
|
||||
To resolve this issue:
|
||||
|
||||
1. In a [Rails console session](../../administration/operations/rails_console.md#starting-a-rails-console-session), run this command:
|
||||
|
||||
```shell
|
||||
idempotency_key = "<idempotency_key_from_log_entry>"
|
||||
duplicate_key = "resque:gitlab:#{idempotency_key}:cookie:v2"
|
||||
Gitlab::Redis::Queues.with { |c| c.del(duplicate_key) }
|
||||
```
|
||||
|
||||
1. Replace `<idempotency_key_from_log_entry>` with the actual entry in your log.
|
||||
|
|
|
|||
|
|
@ -124,5 +124,5 @@ current Bitbucket public name, and reconnect if there's a mismatch:
|
|||
1. Following reconnection, the user should use the API again to verify that their `extern_uid` in
|
||||
the GitLab database now matches their current Bitbucket public name.
|
||||
|
||||
The importer must then [delete the imported project](../../project/settings/index.md#delete-a-project)
|
||||
The importer must then [delete the imported project](../../project/working_with_projects.md#delete-a-project)
|
||||
and import again.
|
||||
|
|
|
|||
|
|
@ -20,20 +20,6 @@ Prerequisite:
|
|||
1. To display all settings in a section, select **Expand**.
|
||||
1. Optional. Use the search box to find a setting.
|
||||
|
||||
## Edit project name and description
|
||||
|
||||
Use the project general settings to edit your project details.
|
||||
|
||||
Prerequisite:
|
||||
|
||||
- You must have at least the Maintainer role for the project.
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Settings > General**.
|
||||
1. In the **Project name** text box, enter your project name.
|
||||
1. In the **Project description** text box, enter your project description.
|
||||
1. Under **Project avatar**, to change your project avatar, select **Choose file**.
|
||||
|
||||
## Assign topics to a project
|
||||
|
||||
Use [topics](../working_with_projects.md#organizing-projects-with-topics) to categorize projects and find similar new projects.
|
||||
|
|
@ -217,83 +203,12 @@ Prerequisite:
|
|||
1. In the **Unarchive project** section, select **Unarchive project**.
|
||||
1. To confirm, select **OK**.
|
||||
|
||||
## Delete a project
|
||||
|
||||
> - Default deletion behavior for projects changed to [delayed project deletion](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) in GitLab 12.6.
|
||||
> - Default deletion behavior for projects changed to [immediate deletion](https://gitlab.com/gitlab-org/gitlab/-/issues/220382) in GitLab 13.2.
|
||||
> - Default deletion behavior for projects on the Premium and Ultimate tier changed to [delayed project deletion](https://gitlab.com/gitlab-org/gitlab/-/issues/389557) in GitLab 16.0.
|
||||
> - Default deletion behavior changed to delayed deletion on the Premium and Ultimate tier [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/393622) and [on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119606) in GitLab 16.0.
|
||||
|
||||
You can mark a project to be deleted.
|
||||
After you delete a project:
|
||||
|
||||
- Projects in personal namespaces are deleted immediately.
|
||||
- Projects in groups are deleted after a retention period.
|
||||
|
||||
Prerequisite:
|
||||
|
||||
- You must have the Owner role for a project.
|
||||
|
||||
To delete a project:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Advanced**.
|
||||
1. In the **Delete this project** section, select **Delete project**.
|
||||
1. On the confirmation dialog, enter the project name and select **Yes, delete project**.
|
||||
|
||||
This action deletes the project and all associated resources (such as issues and merge requests).
|
||||
|
||||
You can also [delete projects using the Rails console](../working_with_projects.md#delete-a-project-using-console).
|
||||
|
||||
### Delayed project deletion **(PREMIUM ALL)**
|
||||
|
||||
> - [Enabled for projects in personal namespaces](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89466) in GitLab 15.1.
|
||||
> - [Disabled for projects in personal namespaces](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95495) in GitLab 15.3.
|
||||
> - Enabled delayed deletion by default and removed the option to delete immediately [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/393622) and [on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119606) in GitLab 16.0.
|
||||
|
||||
Prerequisite:
|
||||
|
||||
- You must have the Owner role for the project.
|
||||
|
||||
Projects in a group (not a personal namespace) can be deleted after a delay period.
|
||||
|
||||
On self-managed instances, group administrators can define a deletion delay period of between 1 and 90 days.
|
||||
On SaaS, there is a non-adjustable default retention period of seven days.
|
||||
|
||||
You can [view projects that are pending deletion](../working_with_projects.md#view-projects-pending-deletion),
|
||||
and use the Rails console to
|
||||
[find projects that are pending deletion](../working_with_projects.md#find-projects-that-are-pending-deletion).
|
||||
|
||||
### Delete a project immediately
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/191367) in GitLab 14.1.
|
||||
> - Option to delete projects immediately from the Admin Area and as a group setting removed [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/393622) and [on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119606) in GitLab 16.0.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have the Owner role for the project.
|
||||
- The project must be [marked for deletion](#delete-a-project).
|
||||
|
||||
If you don't want to wait for delayed deletion, you can delete a project immediately. To do this, perform the steps for [deleting a projects](#delete-a-project) again.
|
||||
|
||||
In the first cycle of deleting a project, the project is moved to the delayed deletion queue and automatically deleted after the retention period has passed.
|
||||
If during this delayed deletion time you run a second deletion cycle, the project is deleted immediately.
|
||||
|
||||
To immediately delete a project marked for deletion:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Advanced**.
|
||||
1. In the **Delete this project** section, select **Delete project**.
|
||||
1. On the confirmation dialog, enter the project name and select **Yes, delete project**.
|
||||
|
||||
## Restore a project **(PREMIUM ALL)**
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have the Owner role for the project.
|
||||
- The project must be [marked for deletion](#delete-a-project).
|
||||
- The project must be [marked for deletion](../working_with_projects.md#delete-a-project).
|
||||
|
||||
To restore a project marked for deletion:
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,20 @@ To view projects you have [starred](#star-a-project):
|
|||
1. On the left sidebar, select your avatar and then your username.
|
||||
1. On the left sidebar, select **Starred projects**.
|
||||
|
||||
## Edit project name and description
|
||||
|
||||
Use the project general settings to edit your project details.
|
||||
|
||||
Prerequisite:
|
||||
|
||||
- You must have at least the Maintainer role for the project.
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Settings > General**.
|
||||
1. In the **Project name** text box, enter your project name.
|
||||
1. In the **Project description** text box, enter your project description.
|
||||
1. Under **Project avatar**, to change your project avatar, select **Choose file**.
|
||||
|
||||
## Organizing projects with topics
|
||||
|
||||
Topics are labels that you can assign to projects to help you organize and find them.
|
||||
|
|
@ -135,7 +149,78 @@ To add a star to a project:
|
|||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. In the upper-right corner of the page, select **Star**.
|
||||
|
||||
## View projects pending deletion **(PREMIUM ALL)**
|
||||
## Delete a project
|
||||
|
||||
> - Default deletion behavior for projects changed to [delayed project deletion](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) in GitLab 12.6.
|
||||
> - Default deletion behavior for projects changed to [immediate deletion](https://gitlab.com/gitlab-org/gitlab/-/issues/220382) in GitLab 13.2.
|
||||
> - Default deletion behavior for projects on the Premium and Ultimate tier changed to [delayed project deletion](https://gitlab.com/gitlab-org/gitlab/-/issues/389557) in GitLab 16.0.
|
||||
> - Default deletion behavior changed to delayed deletion on the Premium and Ultimate tier [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/393622) and [on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119606) in GitLab 16.0.
|
||||
|
||||
You can mark a project to be deleted.
|
||||
After you delete a project:
|
||||
|
||||
- Projects in personal namespaces are deleted immediately.
|
||||
- Projects in groups are deleted after a retention period.
|
||||
|
||||
Prerequisite:
|
||||
|
||||
- You must have the Owner role for a project.
|
||||
|
||||
To delete a project:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Advanced**.
|
||||
1. In the **Delete this project** section, select **Delete project**.
|
||||
1. On the confirmation dialog, enter the project name and select **Yes, delete project**.
|
||||
|
||||
This action deletes the project and all associated resources (such as issues and merge requests).
|
||||
|
||||
You can also [delete projects using the Rails console](#delete-a-project-using-console).
|
||||
|
||||
### Delayed project deletion **(PREMIUM ALL)**
|
||||
|
||||
> - [Enabled for projects in personal namespaces](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89466) in GitLab 15.1.
|
||||
> - [Disabled for projects in personal namespaces](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95495) in GitLab 15.3.
|
||||
> - Enabled delayed deletion by default and removed the option to delete immediately [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/393622) and [on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119606) in GitLab 16.0.
|
||||
|
||||
Prerequisite:
|
||||
|
||||
- You must have the Owner role for the project.
|
||||
|
||||
Projects in a group (not a personal namespace) can be deleted after a delay period.
|
||||
|
||||
On self-managed instances, group administrators can define a deletion delay period of between 1 and 90 days.
|
||||
On SaaS, there is a non-adjustable default retention period of seven days.
|
||||
|
||||
You can [view projects that are pending deletion](#view-projects-pending-deletion),
|
||||
and use the Rails console to
|
||||
[find projects that are pending deletion](#find-projects-that-are-pending-deletion).
|
||||
|
||||
### Delete a project immediately
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/191367) in GitLab 14.1.
|
||||
> - Option to delete projects immediately from the Admin Area and as a group setting removed [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/393622) and [on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119606) in GitLab 16.0.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have the Owner role for the project.
|
||||
- The project must be [marked for deletion](#delete-a-project).
|
||||
|
||||
If you don't want to wait for delayed deletion, you can delete a project immediately. To do this, perform the steps for [deleting a projects](#delete-a-project) again.
|
||||
|
||||
In the first cycle of deleting a project, the project is moved to the delayed deletion queue and automatically deleted after the retention period has passed.
|
||||
If during this delayed deletion time you run a second deletion cycle, the project is deleted immediately.
|
||||
|
||||
To immediately delete a project marked for deletion:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Advanced**.
|
||||
1. In the **Delete this project** section, select **Delete project**.
|
||||
1. On the confirmation dialog, enter the project name and select **Yes, delete project**.
|
||||
|
||||
### View projects pending deletion
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37014) in GitLab 13.3 for Administrators.
|
||||
> - [Tab renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/347468) from **Deleted projects** in GitLab 14.6.
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ module Gitlab
|
|||
raise ConfigurationError, 'KAS internal URL is not configured' unless Gitlab::Kas.internal_url.present?
|
||||
end
|
||||
|
||||
def get_connected_agents(project:)
|
||||
request = Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsRequest.new(project_id: project.id)
|
||||
def get_connected_agents_by_agent_ids(agent_ids:)
|
||||
request = Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIdsRequest.new(agent_ids: agent_ids)
|
||||
|
||||
stub_for(:agent_tracker)
|
||||
.get_connected_agents(request, metadata: metadata)
|
||||
.agents
|
||||
.to_a
|
||||
.get_connected_agents_by_agent_ids(request, metadata: metadata)
|
||||
.agents
|
||||
.to_a
|
||||
end
|
||||
|
||||
def list_agent_config_files(project:)
|
||||
|
|
|
|||
|
|
@ -46009,7 +46009,7 @@ msgstr ""
|
|||
msgid "SortOptions|Size"
|
||||
msgstr ""
|
||||
|
||||
msgid "SortOptions|Sort by:"
|
||||
msgid "SortOptions|Sort by"
|
||||
msgstr ""
|
||||
|
||||
msgid "SortOptions|Sort direction"
|
||||
|
|
|
|||
|
|
@ -625,7 +625,7 @@ RSpec.describe Projects::MergeRequests::DiffsController, feature_category: :code
|
|||
end
|
||||
|
||||
context 'when ck param is present' do
|
||||
let(:cache_key) { merge_request.merge_head_diff.id }
|
||||
let(:cache_key) { 'abc123' }
|
||||
|
||||
before do
|
||||
create(:merge_request_diff, :merge_head, merge_request: merge_request)
|
||||
|
|
|
|||
|
|
@ -100,13 +100,13 @@ RSpec.describe Projects::MergeRequestsController, feature_category: :code_review
|
|||
w: '0',
|
||||
page: '0',
|
||||
per_page: '5',
|
||||
ck: merge_request.merge_head_diff.id))
|
||||
ck: merge_request.merge_head_diff.patch_id_sha))
|
||||
end
|
||||
|
||||
it 'sets diffs_batch_cache_key' do
|
||||
go
|
||||
|
||||
expect(assigns['diffs_batch_cache_key']).to eq(merge_request.merge_head_diff.id)
|
||||
expect(assigns['diffs_batch_cache_key']).to eq(merge_request.merge_head_diff.patch_id_sha)
|
||||
end
|
||||
|
||||
context 'when diffs_batch_cache_with_max_age feature flag is disabled' do
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ RSpec.describe 'Cluster agent registration', :js, feature_category: :deployment_
|
|||
double(agent_name: 'example-agent-1', path: '.gitlab/agents/example-agent-1/config.yaml'),
|
||||
double(agent_name: 'example-agent-2', path: '.gitlab/agents/example-agent-2/config.yaml')
|
||||
])
|
||||
allow(client).to receive(:get_connected_agents).and_return([])
|
||||
allow(client).to receive(:get_connected_agents_by_agent_ids).and_return([])
|
||||
end
|
||||
|
||||
allow(Devise).to receive(:friendly_token).and_return(token)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ RSpec.describe 'ClusterAgents', :js, feature_category: :groups_and_projects do
|
|||
before do
|
||||
allow(Gitlab::Kas).to receive(:enabled?).and_return(true)
|
||||
allow_next_instance_of(Gitlab::Kas::Client) do |client|
|
||||
allow(client).to receive(:get_connected_agents).and_return([])
|
||||
allow(client).to receive(:get_connected_agents_by_agent_ids).and_return([])
|
||||
end
|
||||
|
||||
gitlab_sign_in(user)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
title,description,due date
|
||||
title,description,due date,milestone
|
||||
Issue in 中文,Test description,
|
||||
"Hello","World",
|
||||
"Title with quote""","Description
|
||||
/assign @csv_assignee
|
||||
/estimate 1h",2022-06-28
|
||||
/estimate 1h",2022-06-28,15.10
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
|
@ -2,4 +2,4 @@ Issue ID,URL,Title,State,Description,Author,Author Username,Assignee,Assignee Us
|
|||
1,http://localhost:3000/jashkenas/underscore/issues/1,Title,Open,,Elva Jerde,jamel,Tierra Effertz,aurora_hahn,No,No,,2020-01-17 10:36:26,2020-02-19 10:36:26,,v1.0,,"Brene,Cutlass,Escort,GVM",0,0,,
|
||||
3,http://localhost:3000/jashkenas/underscore/issues/3,Nihil impedit neque quos totam ut aut enim cupiditate doloribus molestiae.,Open,Omnis aliquid sint laudantium quam.,Marybeth Goodwin,rocio.blanda,Annemarie Von,reynalda_howe,No,No,,2020-01-23 10:36:26,2020-02-19 10:36:27,,v1.0,,"Brene,Cutlass,Escort,GVM",0,0,,
|
||||
34,http://localhost:3000/jashkenas/underscore/issues/34,Dismiss Cipher with no integrity,Open,,Marybeth Goodwin,rocio.blanda,"","",No,No,,2020-02-19 10:38:49,2020-02-19 10:38:49,,,,,0,0,,
|
||||
35,http://localhost:3000/jashkenas/underscore/issues/35,Test Title,Open,Test Description,Marybeth Goodwin,rocio.blanda,"","",No,No,,2020-02-19 10:38:49,2020-02-19 10:38:49,,,,,0,0,,
|
||||
35,http://localhost:3000/jashkenas/underscore/issues/35,Test Title,Open,Test Description,Marybeth Goodwin,rocio.blanda,"","",No,No,,2020-02-19 10:38:49,2020-02-19 10:38:49,,v1.0,,,0,0,,
|
||||
|
|
|
|||
|
|
|
@ -9,7 +9,7 @@ exports[`packages_list_row renders 1`] = `
|
|||
class="gl-align-items-center gl-display-flex gl-py-3"
|
||||
>
|
||||
<div
|
||||
class="gl-align-items-stretch gl-display-flex gl-flex-grow-1 gl-justify-content-space-between gl-xs-flex-direction-column"
|
||||
class="gl-align-items-stretch gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-justify-content-space-between gl-sm-flex-direction-row"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-min-w-0 gl-xs-mb-3"
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ exports[`packages_list_row renders 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="gl-align-items-stretch gl-display-flex gl-flex-grow-1 gl-justify-content-space-between gl-xs-flex-direction-column"
|
||||
class="gl-align-items-stretch gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-justify-content-space-between gl-sm-flex-direction-row"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-min-w-0 gl-xs-mb-3"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ RSpec.describe Resolvers::Kas::AgentConnectionsResolver do
|
|||
let(:connection2) { double(agent_id: agent1.id) }
|
||||
let(:connection3) { double(agent_id: agent2.id) }
|
||||
let(:connected_agents) { [connection1, connection2, connection3] }
|
||||
let(:kas_client) { instance_double(Gitlab::Kas::Client, get_connected_agents: connected_agents) }
|
||||
let(:kas_client) { instance_double(Gitlab::Kas::Client, get_connected_agents_by_agent_ids: connected_agents) }
|
||||
|
||||
subject do
|
||||
batch_sync do
|
||||
|
|
@ -37,7 +37,7 @@ RSpec.describe Resolvers::Kas::AgentConnectionsResolver do
|
|||
end
|
||||
|
||||
it 'queries KAS once when multiple agents are requested' do
|
||||
expect(kas_client).to receive(:get_connected_agents).once
|
||||
expect(kas_client).to receive(:get_connected_agents_by_agent_ids).once
|
||||
|
||||
response = batch_sync do
|
||||
resolve(described_class, obj: agent1, ctx: ctx)
|
||||
|
|
@ -49,7 +49,7 @@ RSpec.describe Resolvers::Kas::AgentConnectionsResolver do
|
|||
|
||||
context 'an error is returned from the KAS client' do
|
||||
before do
|
||||
allow(kas_client).to receive(:get_connected_agents).and_raise(GRPC::DeadlineExceeded)
|
||||
allow(kas_client).to receive(:get_connected_agents_by_agent_ids).and_raise(GRPC::DeadlineExceeded)
|
||||
end
|
||||
|
||||
it 'raises a graphql error' do
|
||||
|
|
|
|||
|
|
@ -45,25 +45,25 @@ RSpec.describe Gitlab::Kas::Client do
|
|||
expect(token).to receive(:audience=).with(described_class::JWT_AUDIENCE)
|
||||
end
|
||||
|
||||
describe '#get_connected_agents' do
|
||||
describe '#get_connected_agents_by_agent_ids' do
|
||||
let(:stub) { instance_double(Gitlab::Agent::AgentTracker::Rpc::AgentTracker::Stub) }
|
||||
let(:request) { instance_double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsRequest) }
|
||||
let(:response) { double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsResponse, agents: connected_agents) }
|
||||
let(:request) { instance_double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIdsRequest) }
|
||||
let(:response) { double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIdsResponse, agents: connected_agents) }
|
||||
|
||||
let(:connected_agents) { [double] }
|
||||
|
||||
subject { described_class.new.get_connected_agents(project: project) }
|
||||
subject { described_class.new.get_connected_agents_by_agent_ids(agent_ids: [agent.id]) }
|
||||
|
||||
before do
|
||||
expect(Gitlab::Agent::AgentTracker::Rpc::AgentTracker::Stub).to receive(:new)
|
||||
.with('example.kas.internal', :this_channel_is_insecure, timeout: described_class::TIMEOUT)
|
||||
.and_return(stub)
|
||||
|
||||
expect(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsRequest).to receive(:new)
|
||||
.with(project_id: project.id)
|
||||
expect(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIdsRequest).to receive(:new)
|
||||
.with(agent_ids: [agent.id])
|
||||
.and_return(request)
|
||||
|
||||
expect(stub).to receive(:get_connected_agents)
|
||||
expect(stub).to receive(:get_connected_agents_by_agent_ids)
|
||||
.with(request, metadata: { 'authorization' => 'bearer test-token' })
|
||||
.and_return(response)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ RSpec.describe 'Project.cluster_agents', feature_category: :deployment_managemen
|
|||
end
|
||||
|
||||
before do
|
||||
allow(Gitlab::Kas::Client).to receive(:new).and_return(double(get_connected_agents: []))
|
||||
allow(Gitlab::Kas::Client).to receive(:new).and_return(double(get_connected_agents_by_agent_ids: []))
|
||||
end
|
||||
|
||||
it 'can retrieve cluster agents' do
|
||||
|
|
@ -87,7 +87,7 @@ RSpec.describe 'Project.cluster_agents', feature_category: :deployment_managemen
|
|||
let(:cluster_agents_fields) { [:id, query_nodes(:connections, [:connection_id, :connected_at, metadata_fields])] }
|
||||
|
||||
before do
|
||||
allow(Gitlab::Kas::Client).to receive(:new).and_return(double(get_connected_agents: [connected_agent]))
|
||||
allow(Gitlab::Kas::Client).to receive(:new).and_return(double(get_connected_agents_by_agent_ids: [connected_agent]))
|
||||
end
|
||||
|
||||
it 'can retrieve connections and agent metadata' do
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ RSpec.describe Issues::ImportCsvService, feature_category: :team_planning do
|
|||
described_class.new(user, project, uploader)
|
||||
end
|
||||
|
||||
let!(:test_milestone) { create(:milestone, project: project, title: '15.10') }
|
||||
|
||||
include_examples 'issuable import csv service', 'issue' do
|
||||
let(:issuables) { project.issues }
|
||||
let(:email_method) { :import_issues_csv_email }
|
||||
|
|
@ -36,7 +38,8 @@ RSpec.describe Issues::ImportCsvService, feature_category: :team_planning do
|
|||
description: 'Description',
|
||||
time_estimate: 3600,
|
||||
assignees: include(assignee),
|
||||
due_date: Date.new(2022, 6, 28)
|
||||
due_date: Date.new(2022, 6, 28),
|
||||
milestone_id: test_milestone.id
|
||||
)
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ RSpec.shared_examples 'tracking unique visits' do |method|
|
|||
.to receive(:track_event).with(id, values: anything)
|
||||
end
|
||||
|
||||
# allow other method calls in addition to the expected one
|
||||
allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event)
|
||||
|
||||
get method, params: request_params, format: :html
|
||||
end
|
||||
|
||||
|
|
@ -24,6 +27,9 @@ RSpec.shared_examples 'tracking unique visits' do |method|
|
|||
.to receive(:track_event).with(id, values: anything)
|
||||
end
|
||||
|
||||
# allow other method calls in addition to the expected one
|
||||
allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event)
|
||||
|
||||
stub_do_not_track('0')
|
||||
|
||||
get method, params: request_params, format: :html
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ RSpec.shared_examples 'issuable import csv service' do |issuable_type|
|
|||
|
||||
context 'with a file generated by Gitlab CSV export' do
|
||||
let(:file) { fixture_file_upload('spec/fixtures/csv_gitlab_export.csv') }
|
||||
let!(:test_milestone) { create(:milestone, project: project, title: 'v1.0') }
|
||||
let_it_be(:test_milestone) { create(:milestone, project: project, title: 'v1.0') }
|
||||
|
||||
it 'imports the CSV without errors' do
|
||||
expect(subject[:success]).to eq(4)
|
||||
|
|
@ -41,7 +41,19 @@ RSpec.shared_examples 'issuable import csv service' do |issuable_type|
|
|||
it 'correctly sets the issuable attributes' do
|
||||
expect { subject }.to change { issuables.count }.by 4
|
||||
|
||||
expect(issuables.reload).to include(have_attributes({ title: 'Test Title', description: 'Test Description' }))
|
||||
if issuable_type == 'issue'
|
||||
expect(issuables.reload).to include(
|
||||
have_attributes({ title: 'Test Title', description: 'Test Description', milestone_id: test_milestone.id }),
|
||||
have_attributes({ title: 'Title', milestone_id: test_milestone.id }),
|
||||
have_attributes(
|
||||
{ title: 'Nihil impedit neque quos totam ut aut enim cupiditate doloribus molestiae.',
|
||||
description: 'Omnis aliquid sint laudantium quam.',
|
||||
milestone_id: test_milestone.id })
|
||||
)
|
||||
|
||||
else
|
||||
expect(issuables.reload).to include(have_attributes({ title: 'Test Title', description: 'Test Description' }))
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'importer with email notification'
|
||||
|
|
|
|||
Loading…
Reference in New Issue