Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
250bb2bd86
commit
2c5d8a0436
|
|
@ -127,7 +127,7 @@ export default {
|
|||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
inject: {
|
||||
autocompleteAwardEmojisPat: { default: '' },
|
||||
autocompleteAwardEmojisPath: { default: '' },
|
||||
fullPath: { default: '' },
|
||||
hasAnyMergeRequests: { default: false },
|
||||
hasScopedLabelsFeature: { default: false },
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export default {
|
|||
default: '',
|
||||
},
|
||||
},
|
||||
safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
|
||||
safeHtmlConfig: { ADD_TAGS: ['gl-emoji', 'copy-code'] },
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ export const TOKEN_TITLE_JOBS_RUNNER_TYPE = s__('Job|Runner type');
|
|||
export const TOKEN_TITLE_TARGET_BRANCH = __('Target Branch');
|
||||
export const TOKEN_TITLE_TYPE = __('Type');
|
||||
export const TOKEN_TITLE_VERSION = __('Version');
|
||||
export const TOKEN_TITLE_SEARCH_WITHIN = __('Search Within');
|
||||
export const TOKEN_TITLE_SEARCH_WITHIN = __('Search within');
|
||||
export const TOKEN_TITLE_CREATED = __('Created date');
|
||||
export const TOKEN_TITLE_CLOSED = __('Closed date');
|
||||
export const TOKEN_TITLE_DEPLOYED_BEFORE = __('Deployed-before');
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ module Issues
|
|||
handle_move_between_ids(issue)
|
||||
|
||||
change_issue_duplicate(issue)
|
||||
move_issue_to_new_project(issue) || clone_issue(issue) || update_task_event(issue) || update(issue)
|
||||
move_issue_to_new_container(issue) || clone_issue(issue) || update_task_event(issue) || update(issue)
|
||||
end
|
||||
|
||||
def update(issue)
|
||||
|
|
@ -94,23 +94,24 @@ module Issues
|
|||
end
|
||||
end
|
||||
|
||||
def move_issue_to_new_project(issue)
|
||||
target_project = params.delete(:target_project)
|
||||
def move_issue_to_new_container(issue)
|
||||
target_container = params.delete(:target_container)
|
||||
|
||||
return unless target_project &&
|
||||
issue.can_move?(current_user, target_project) &&
|
||||
target_project != issue.project
|
||||
return unless target_container &&
|
||||
issue.can_move?(current_user, target_container) &&
|
||||
!move_to_same_container?(issue, target_container)
|
||||
|
||||
update(issue)
|
||||
|
||||
if Feature.enabled?(:work_item_move_and_clone, project)
|
||||
if Feature.enabled?(:work_item_move_and_clone, container)
|
||||
move_service_container = target_container.is_a?(Project) ? target_container.project_namespace : target_container
|
||||
::WorkItems::DataSync::MoveService.new(
|
||||
work_item: issue, current_user: current_user, target_namespace: target_project.project_namespace
|
||||
work_item: issue, current_user: current_user, target_namespace: move_service_container
|
||||
).execute[:work_item]
|
||||
else
|
||||
::Issues::MoveService.new(
|
||||
container: project, current_user: current_user
|
||||
).execute(issue, target_project)
|
||||
).execute(issue, target_container)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -147,23 +148,24 @@ module Issues
|
|||
end
|
||||
|
||||
def clone_issue(issue)
|
||||
target_project = params.delete(:target_clone_project)
|
||||
target_container = params.delete(:target_clone_container)
|
||||
with_notes = params.delete(:clone_with_notes)
|
||||
|
||||
return unless target_project &&
|
||||
issue.can_clone?(current_user, target_project)
|
||||
return unless target_container &&
|
||||
issue.can_clone?(current_user, target_container)
|
||||
|
||||
# we've pre-empted this from running in #execute, so let's go ahead and update the Issue now.
|
||||
update(issue)
|
||||
|
||||
if Feature.enabled?(:work_item_move_and_clone, project)
|
||||
if Feature.enabled?(:work_item_move_and_clone, container)
|
||||
clone_service_container = target_container.is_a?(Project) ? target_container.project_namespace : target_container
|
||||
::WorkItems::DataSync::CloneService.new(
|
||||
work_item: issue, current_user: current_user, target_namespace: target_project.project_namespace,
|
||||
work_item: issue, current_user: current_user, target_namespace: clone_service_container,
|
||||
params: { clone_with_notes: with_notes }
|
||||
).execute[:work_item]
|
||||
else
|
||||
elsif target_container.is_a?(Project)
|
||||
Issues::CloneService.new(container: project, current_user: current_user).execute(
|
||||
issue, target_project, with_notes: with_notes
|
||||
issue, target_container, with_notes: with_notes
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -223,6 +225,14 @@ module Issues
|
|||
::IncidentManagement::IssuableEscalationStatuses::CreateService.new(issue).execute if issue.supports_escalation?
|
||||
end
|
||||
|
||||
def move_to_same_container?(issue, target_container)
|
||||
target_container_identifier = target_container.id
|
||||
|
||||
target_container_identifier = target_container.project_namespace_id if target_container.is_a?(Project)
|
||||
|
||||
issue.namespace_id == target_container_identifier
|
||||
end
|
||||
|
||||
override :allowed_update_params
|
||||
def allowed_update_params(params)
|
||||
super.except(:issue_type)
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ module SystemNotes
|
|||
raise ArgumentError, "Invalid direction `#{direction}`"
|
||||
end
|
||||
|
||||
cross_reference = noteable_ref.to_reference(project)
|
||||
cross_reference = noteable_ref.to_reference(container)
|
||||
body = "moved #{direction} #{cross_reference}"
|
||||
|
||||
track_issue_event(:track_issue_moved_action)
|
||||
|
|
@ -342,7 +342,7 @@ module SystemNotes
|
|||
raise ArgumentError, "Invalid direction `#{direction}`"
|
||||
end
|
||||
|
||||
cross_reference = noteable_ref.to_reference(project)
|
||||
cross_reference = noteable_ref.to_reference(container)
|
||||
body = "cloned #{direction} #{cross_reference}"
|
||||
|
||||
track_issue_event(:track_issue_cloned_action) if direction == :to
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module WorkItems
|
|||
def clone_system_notes(current_user, new_work_item, work_item)
|
||||
SystemNoteService.noteable_cloned(
|
||||
new_work_item,
|
||||
new_work_item.project,
|
||||
new_work_item.resource_parent,
|
||||
work_item,
|
||||
current_user,
|
||||
direction: :from,
|
||||
|
|
@ -22,7 +22,7 @@ module WorkItems
|
|||
|
||||
SystemNoteService.noteable_cloned(
|
||||
work_item,
|
||||
work_item.project,
|
||||
work_item.resource_parent,
|
||||
new_work_item,
|
||||
current_user,
|
||||
direction: :to
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ module WorkItems
|
|||
def move_system_notes(current_user, new_work_item, original_work_item)
|
||||
SystemNoteService.noteable_moved(
|
||||
new_work_item,
|
||||
new_work_item.project,
|
||||
new_work_item.resource_parent,
|
||||
original_work_item,
|
||||
current_user,
|
||||
direction: :from
|
||||
|
|
@ -24,7 +24,7 @@ module WorkItems
|
|||
|
||||
SystemNoteService.noteable_moved(
|
||||
original_work_item,
|
||||
original_work_item.project,
|
||||
original_work_item.resource_parent,
|
||||
new_work_item,
|
||||
current_user,
|
||||
direction: :to
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ if Gitlab.ee?
|
|||
Search::Zoekt::Task,
|
||||
Ai::CodeSuggestionEvent,
|
||||
Ai::DuoChatEvent,
|
||||
Vulnerabilities::Archive,
|
||||
Vulnerabilities::ArchivedRecord,
|
||||
Vulnerabilities::ArchiveExport
|
||||
])
|
||||
else
|
||||
|
|
|
|||
|
|
@ -549,6 +549,8 @@
|
|||
- 2
|
||||
- - mailers
|
||||
- 2
|
||||
- - members_delete_pending_members
|
||||
- 1
|
||||
- - members_destroyer_clean_up_group_protected_branch_rules
|
||||
- 1
|
||||
- - members_expiring_email_notification
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
- name: Duo Code Review available in beta
|
||||
description: |
|
||||
Code review is an essential activity of software development. It ensures that contributions to a project maintain and improve code quality and security, and is an avenue of mentorship and feedback for engineers. It's also one of the most time-consuming activities in the software development process. Duo Code Review is the next evolution of the code review process. Duo Code Review can accelerate your development process. When it performs an initial review on your merge request, it can help identify potential bugs and suggest further improvements - some of which you can apply directly from your browser. Use it to iterate on and improve your changes before you add another human to the loop.
|
||||
stage: create
|
||||
self-managed: true
|
||||
gitlab-com: true
|
||||
available_in: [Ultimate]
|
||||
documentation_link: https://docs.gitlab.com/user/project/merge_requests/duo_in_merge_requests/#have-gitlab-duo-review-your-code
|
||||
image_url: https://img.youtube.com/vi/FlHqfMMfbzQ/hqdefault.jpg
|
||||
published_at: 2025-03-20
|
||||
release: 17.10
|
||||
- name: Root Cause Analysis available on Gitlab Duo Self-Hosted
|
||||
description: |
|
||||
You can now use [GitLab Duo Root Cause Analysis](https://about.gitlab.com/blog/2024/06/06/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd/) on GitLab Duo Self-Hosted. This feature is in beta for GitLab Self-Managed instances using GitLab Duo Self-Hosted, with support for Mistral, Anthropic, and OpenAI GPT model families. With Root Cause Analysis on GitLab Duo Self-Hosted, you can troubleshoot failed jobs in CI/CD pipelines faster without compromising data sovereignty. Root Cause Analysis analyzes the failed job log, quickly determines the root cause of the job failure, and suggests a fix for you.
|
||||
stage: ai-powered
|
||||
self-managed: true
|
||||
gitlab-com: false
|
||||
available_in: [Ultimate]
|
||||
documentation_link: https://docs.gitlab.com/administration/gitlab_duo_self_hosted/#supported-gitlab-duo-features
|
||||
image_url: https://about.gitlab.com/images/17_10/RCA_beta_17.10_min.png
|
||||
published_at: 2025-03-20
|
||||
release: 17.10
|
||||
- name: GitLab Query Language Views Beta
|
||||
description: |
|
||||
Tracking and understanding work in progress across GitLab previously required navigating multiple locations, reducing team efficiency and consuming valuable time. This release introduces GitLab Query Language (GLQL) Views Beta so you can create dynamic, real-time work tracking directly in your existing workflows. GLQL Views embed live data queries in Markdown code blocks throughout Wiki pages, epic descriptions, issue comments, and merge requests. Previously available as an experiment, GLQL Views now enter beta with support for sophisticated filtering using logical expressions and operators across key fields, including assignee, author, label, and milestone. You can customize your view's presentation as tables or lists, control which fields appear, and set result limits to create focused, actionable insights for your team. Teams can now maintain context while accessing the information they need, creating shared understanding, and improving collaboration — all without leaving their current workflow.
|
||||
stage: plan
|
||||
self-managed: true
|
||||
gitlab-com: true
|
||||
available_in: [Free, Premium, Ultimate]
|
||||
documentation_link: https://docs.gitlab.com/user/glql/#glql-views
|
||||
image_url: https://img.youtube.com/vi/CML0hefVwSA/hqdefault.jpg
|
||||
published_at: 2025-03-20
|
||||
release: 17.10
|
||||
- name: Enhanced markdown experience
|
||||
description: |
|
||||
GitLab Flavored Markdown has been enhanced with several powerful improvements:
|
||||
|
||||
- **Improved math and image handling**:
|
||||
- Disable [math rendering](https://docs.gitlab.com/user/markdown/#math-equations) limits in your group or self-hosted instance to handle more complex mathematical expressions.
|
||||
- Control [image dimensions](https://docs.gitlab.com/user/markdown/#change-image-or-video-dimensions) precisely using pixel values or percentages to better manage content layout.
|
||||
- **Enhanced editor experience**:
|
||||
- Continue lists automatically when pressing Enter/Return.
|
||||
- Shift text left or right using keyboard shortcuts.
|
||||
- Create clear term-definition pairs using description list syntax.
|
||||
- Adjust video widths flexibly.
|
||||
- **Better content organization**:
|
||||
- Navigate content more easily with auto-expanding [summary quick views](https://docs.gitlab.com/user/markdown/#show-item-summary) (add `+s` to URLs).
|
||||
- See referenced [issue titles](https://docs.gitlab.com/user/markdown/#show-item-title) render automatically (add `+` to URLs).
|
||||
- Organize content modularly using [`include` syntax](https://docs.gitlab.com/user/markdown/#includes).
|
||||
- Create visually distinct callouts and warnings using [alert boxes](https://docs.gitlab.com/user/markdown/#alerts).
|
||||
These improvements make GitLab Flavored Markdown more powerful for teams creating and maintaining documentation while offering greater flexibility in how content is presented and organized.
|
||||
stage: plan
|
||||
self-managed: true
|
||||
gitlab-com: true
|
||||
available_in: [Free, Premium, Ultimate]
|
||||
documentation_link: https://docs.gitlab.com/ee/user/markdown.html
|
||||
image_url: https://about.gitlab.com/images/17_10/enhanced_markdown_experience.png
|
||||
published_at: 2025-03-20
|
||||
release: 17.10
|
||||
- name: New visualization of DevOps performance with DORA metrics across projects
|
||||
description: |
|
||||
We are excited to introduce the **Projects by DORA metric** panel, a new addition to the [Value Streams Dashboard](https://www.youtube.com/watch?v=EA9Sbks27g4). This table lists all projects in the top-level group, with breakdown into the [four DORA metrics](https://about.gitlab.com/solutions/value-stream-management/dora/#overview). Managers can use this table to identify high, medium, and low-performing projects. This information can also help make data-driven decisions, allocate resources effectively, and focus on initiatives that enhance software delivery speed, stability, and reliability. The [DORA metrics](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html) are available out-of-the-box in GitLab, and now together with the [**DORA Performers score** panel](https://about.gitlab.com/blog/2024/01/18/inside-dora-performers-score-in-gitlab-value-streams-dashboard/) executives have a complete view into their organization's DevOps health top to bottom.
|
||||
stage: plan
|
||||
self-managed: true
|
||||
gitlab-com: true
|
||||
available_in: [Ultimate]
|
||||
documentation_link: https://docs.gitlab.com/ee/user/analytics/value_streams_dashboard.html#projects-by-dora-categories
|
||||
image_url: https://about.gitlab.com/images/17_10/17.7_vsd_dora_table2.png
|
||||
published_at: 2025-03-20
|
||||
release: 17.10
|
||||
- name: Redesigned issues interface now in Beta
|
||||
description: |
|
||||
Issues now share a common framework with epics and tasks, featuring real-time updates and workflow improvements:
|
||||
* **Drawer view:** Open items from lists or boards in a drawer for quick viewing without leaving your current context. A button at the top lets you expand to full page view.
|
||||
* **Change type:** Convert types between epics, issues, and tasks using the "Change type" action (replaces "Promote to epic")
|
||||
* **Start date:** Issues now support start dates, aligning their functionality with epics and tasks.
|
||||
* **Ancestry:** The complete hierarchy is above the title and the Parent field in the sidebar. To manage relationships, use the new commands `/set_parent`, `/remove_parent`, `/set_child`, and `/remove_child`.
|
||||
* **Controls:** All actions are now accessible from the top menu (vertical ellipsis), which remains visible in the sticky header when scrolling.
|
||||
* **Development:** All development items (merge requests, branches, and feature flags) related to an issue or task are now consolidated in a single, convenient list.
|
||||
* **Layout:** UI improvements create a more seamless experience between issues, epics, tasks, and merge requests, helping you navigate your workflow more efficiently.
|
||||
* **Linked items:** Create relationships between tasks, issues, and epics with improved linking options. Drag and drop to change link types and toggle the visibility of labels and closed items.
|
||||
stage: plan
|
||||
self-managed: true
|
||||
gitlab-com: true
|
||||
available_in: [Free, Premium, Ultimate]
|
||||
documentation_link: https://docs.gitlab.com/user/project/issues/issue_work_items/
|
||||
image_url: https://about.gitlab.com/images/17_10/focused-drawer-new-issues.png
|
||||
published_at: 2025-03-20
|
||||
release: 17.10
|
||||
- name: Change the severity of a vulnerability
|
||||
description: |
|
||||
When triaging vulnerabilities, you need the flexibility to adjust severity levels based on your organization's unique security context and risk tolerance. Until now, you had to rely on the default severity levels assigned by security scanners, which might not accurately reflect the risk level for your specific environment. Now you can manually change the severity of specific vulnerability occurrences to better align with your organization's security needs. This allows you to:
|
||||
- Adjust the severity level of any vulnerability to **Critical**, **High**, **Medium**, **Low**, **Info**, or **Unknown**.
|
||||
- Change multiple vulnerabilities' severity at once from the vulnerability report.
|
||||
- Easily identify which vulnerabilities have custom severity levels through visual indicators.
|
||||
All severity changes are tracked in the vulnerability history and audit events and can only be overridden by your team members who have at least the Maintainer role for the project, or a custom role with the `admin_vulnerability` permission. This feature gives security teams more flexibility and control over vulnerability prioritization.
|
||||
stage: security_risk_management
|
||||
self-managed: true
|
||||
gitlab-com: true
|
||||
available_in: [Ultimate]
|
||||
documentation_link: https://docs.gitlab.com/user/application_security/vulnerability_report/#change-or-override-vulnerability-severity
|
||||
image_url: https://about.gitlab.com/images/17_10/severity-override.png
|
||||
published_at: 2025-03-20
|
||||
release: 17.10
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PartitionVulnerabilityArchivedRecords < Gitlab::Database::Migration[2.2]
|
||||
VULNERABILITY_ID_INDEX_NAME = 'index_vulnerability_archived_records_on_vulnerability_id'
|
||||
NEW_VULNERABILITY_ID_INDEX_NAME = 'index_vulnerability_archived_records_on_unique_attributes'
|
||||
ARCHIVE_ID_INDEX_NAME = 'index_vulnerability_archived_records_on_archive_id_and_id'
|
||||
PARTITIONED_TABLE_OPTIONS = {
|
||||
primary_key: %i[id date],
|
||||
options: 'PARTITION BY RANGE (date)'
|
||||
}.freeze
|
||||
|
||||
milestone '17.11'
|
||||
|
||||
def up
|
||||
drop_table :vulnerability_archived_records # rubocop:disable Migration/DropTable -- We are temporarily dropping the table
|
||||
|
||||
create_table :vulnerability_archived_records, **PARTITIONED_TABLE_OPTIONS do |t| # rubocop:disable Migration/EnsureFactoryForTable -- false positive
|
||||
t.timestamps_with_timezone null: false
|
||||
|
||||
t.bigserial :id, null: false
|
||||
t.date :date, null: false
|
||||
t.bigint :project_id, null: false, index: true
|
||||
t.references :archive,
|
||||
null: false, foreign_key: { on_delete: :cascade, to_table: 'vulnerability_archives' }, index: false
|
||||
|
||||
t.bigint :vulnerability_identifier, null: false
|
||||
t.jsonb :data, null: false, default: {}
|
||||
|
||||
t.index %i[vulnerability_identifier date], name: NEW_VULNERABILITY_ID_INDEX_NAME, unique: true
|
||||
t.index %i[archive_id id], name: ARCHIVE_ID_INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :vulnerability_archived_records
|
||||
|
||||
create_table :vulnerability_archived_records do |t| # rubocop:disable Migration/EnsureFactoryForTable -- false positive
|
||||
t.timestamps_with_timezone null: false
|
||||
|
||||
t.bigint :project_id, null: false, index: true
|
||||
t.references :archive,
|
||||
null: false, foreign_key: { on_delete: :cascade, to_table: 'vulnerability_archives' }, index: false
|
||||
|
||||
t.bigint :vulnerability_identifier, null: false, index: { name: VULNERABILITY_ID_INDEX_NAME, unique: true }
|
||||
t.jsonb :data, null: false, default: {}
|
||||
|
||||
t.index %i[archive_id id], name: ARCHIVE_ID_INDEX_NAME
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PartitionVulnerabilityArchives < Gitlab::Database::Migration[2.2]
|
||||
INDEX_NAME_ON_FK = 'index_vulnerability_archived_records_on_archive_id_and_date'
|
||||
PARTITIONED_TABLE_OPTIONS = {
|
||||
primary_key: %i[id date],
|
||||
options: 'PARTITION BY RANGE (date)'
|
||||
}.freeze
|
||||
|
||||
milestone '17.11'
|
||||
|
||||
def up
|
||||
remove_foreign_key :vulnerability_archived_records, column: :archive_id
|
||||
|
||||
drop_table :vulnerability_archives # rubocop:disable Migration/DropTable -- We are temporarily dropping the table
|
||||
|
||||
create_table :vulnerability_archives, **PARTITIONED_TABLE_OPTIONS do |t| # rubocop:disable Migration/EnsureFactoryForTable -- false positive
|
||||
t.timestamps_with_timezone null: false
|
||||
|
||||
t.bigserial :id, null: false
|
||||
t.bigint :project_id, null: false
|
||||
t.integer :archived_records_count, null: false, default: 0
|
||||
t.date :date, null: false
|
||||
|
||||
t.index %i[project_id date], unique: true
|
||||
|
||||
t.check_constraint 'archived_records_count >= 0'
|
||||
end
|
||||
|
||||
add_index :vulnerability_archived_records, %i[archive_id date], name: INDEX_NAME_ON_FK
|
||||
|
||||
connection.execute(<<~SQL)
|
||||
ALTER TABLE vulnerability_archived_records
|
||||
ADD CONSTRAINT fk_rails_601e008d4b FOREIGN KEY (archive_id, date) REFERENCES vulnerability_archives(id, date) ON DELETE CASCADE;
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
connection.execute(<<~SQL)
|
||||
ALTER TABLE vulnerability_archived_records DROP CONSTRAINT fk_rails_601e008d4b;
|
||||
SQL
|
||||
|
||||
drop_table :vulnerability_archives
|
||||
|
||||
create_table :vulnerability_archives do |t| # rubocop:disable Migration/EnsureFactoryForTable -- false positive
|
||||
t.timestamps_with_timezone null: false
|
||||
|
||||
t.bigint :project_id, null: false
|
||||
t.integer :archived_records_count, null: false, default: 0
|
||||
t.date :date, null: false
|
||||
|
||||
t.index %i[project_id date], unique: true
|
||||
|
||||
t.check_constraint 'archived_records_count >= 0'
|
||||
end
|
||||
|
||||
remove_index :vulnerability_archived_records, name: INDEX_NAME_ON_FK # rubocop:disable Migration/RemoveIndex -- Table is empty
|
||||
|
||||
add_foreign_key :vulnerability_archived_records, :vulnerability_archives, column: :archive_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey -- Table is empty
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
4e2a767f205add82ecb463915d42fff3ac31fd43b553261246f145e72da80537
|
||||
|
|
@ -0,0 +1 @@
|
|||
b4721228f4c9839f861a544056e3ae7ffbb02a655338f869c031a0cc3310a0c9
|
||||
|
|
@ -4819,6 +4819,29 @@ CREATE TABLE vulnerability_archive_exports (
|
|||
)
|
||||
PARTITION BY LIST (partition_number);
|
||||
|
||||
CREATE TABLE vulnerability_archived_records (
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
id bigint NOT NULL,
|
||||
date date NOT NULL,
|
||||
project_id bigint NOT NULL,
|
||||
archive_id bigint NOT NULL,
|
||||
vulnerability_identifier bigint NOT NULL,
|
||||
data jsonb DEFAULT '{}'::jsonb NOT NULL
|
||||
)
|
||||
PARTITION BY RANGE (date);
|
||||
|
||||
CREATE TABLE vulnerability_archives (
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
id bigint NOT NULL,
|
||||
project_id bigint NOT NULL,
|
||||
archived_records_count integer DEFAULT 0 NOT NULL,
|
||||
date date NOT NULL,
|
||||
CONSTRAINT chk_rails_6b9e2d707f CHECK ((archived_records_count >= 0))
|
||||
)
|
||||
PARTITION BY RANGE (date);
|
||||
|
||||
CREATE TABLE web_hook_logs (
|
||||
id bigint NOT NULL,
|
||||
web_hook_id bigint NOT NULL,
|
||||
|
|
@ -23806,16 +23829,6 @@ CREATE SEQUENCE vulnerability_archive_exports_id_seq
|
|||
|
||||
ALTER SEQUENCE vulnerability_archive_exports_id_seq OWNED BY vulnerability_archive_exports.id;
|
||||
|
||||
CREATE TABLE vulnerability_archived_records (
|
||||
id bigint NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
project_id bigint NOT NULL,
|
||||
archive_id bigint NOT NULL,
|
||||
vulnerability_identifier bigint NOT NULL,
|
||||
data jsonb DEFAULT '{}'::jsonb NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE vulnerability_archived_records_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
|
|
@ -23825,16 +23838,6 @@ CREATE SEQUENCE vulnerability_archived_records_id_seq
|
|||
|
||||
ALTER SEQUENCE vulnerability_archived_records_id_seq OWNED BY vulnerability_archived_records.id;
|
||||
|
||||
CREATE TABLE vulnerability_archives (
|
||||
id bigint NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
project_id bigint NOT NULL,
|
||||
archived_records_count integer DEFAULT 0 NOT NULL,
|
||||
date date NOT NULL,
|
||||
CONSTRAINT chk_rails_6b9e2d707f CHECK ((archived_records_count >= 0))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE vulnerability_archives_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
|
|
@ -29942,10 +29945,10 @@ ALTER TABLE ONLY vulnerability_archive_exports
|
|||
ADD CONSTRAINT vulnerability_archive_exports_pkey PRIMARY KEY (id, partition_number);
|
||||
|
||||
ALTER TABLE ONLY vulnerability_archived_records
|
||||
ADD CONSTRAINT vulnerability_archived_records_pkey PRIMARY KEY (id);
|
||||
ADD CONSTRAINT vulnerability_archived_records_pkey PRIMARY KEY (id, date);
|
||||
|
||||
ALTER TABLE ONLY vulnerability_archives
|
||||
ADD CONSTRAINT vulnerability_archives_pkey PRIMARY KEY (id);
|
||||
ADD CONSTRAINT vulnerability_archives_pkey PRIMARY KEY (id, date);
|
||||
|
||||
ALTER TABLE ONLY vulnerability_export_parts
|
||||
ADD CONSTRAINT vulnerability_export_parts_pkey PRIMARY KEY (id);
|
||||
|
|
@ -36378,13 +36381,15 @@ CREATE INDEX index_vulnerability_archive_exports_on_project_id ON ONLY vulnerabi
|
|||
|
||||
CREATE INDEX index_vulnerability_archive_exports_on_status ON ONLY vulnerability_archive_exports USING btree (status);
|
||||
|
||||
CREATE INDEX index_vulnerability_archived_records_on_archive_id_and_id ON vulnerability_archived_records USING btree (archive_id, id);
|
||||
CREATE INDEX index_vulnerability_archived_records_on_archive_id_and_date ON ONLY vulnerability_archived_records USING btree (archive_id, date);
|
||||
|
||||
CREATE INDEX index_vulnerability_archived_records_on_project_id ON vulnerability_archived_records USING btree (project_id);
|
||||
CREATE INDEX index_vulnerability_archived_records_on_archive_id_and_id ON ONLY vulnerability_archived_records USING btree (archive_id, id);
|
||||
|
||||
CREATE UNIQUE INDEX index_vulnerability_archived_records_on_vulnerability_id ON vulnerability_archived_records USING btree (vulnerability_identifier);
|
||||
CREATE INDEX index_vulnerability_archived_records_on_project_id ON ONLY vulnerability_archived_records USING btree (project_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_vulnerability_archives_on_project_id_and_date ON vulnerability_archives USING btree (project_id, date);
|
||||
CREATE UNIQUE INDEX index_vulnerability_archived_records_on_unique_attributes ON ONLY vulnerability_archived_records USING btree (vulnerability_identifier, date);
|
||||
|
||||
CREATE UNIQUE INDEX index_vulnerability_archives_on_project_id_and_date ON ONLY vulnerability_archives USING btree (project_id, date);
|
||||
|
||||
CREATE INDEX index_vulnerability_export_parts_on_organization_id ON vulnerability_export_parts USING btree (organization_id);
|
||||
|
||||
|
|
@ -42483,8 +42488,8 @@ ALTER TABLE ONLY incident_management_oncall_participants
|
|||
ALTER TABLE ONLY work_item_parent_links
|
||||
ADD CONSTRAINT fk_rails_601d5bec3a FOREIGN KEY (work_item_id) REFERENCES issues(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY vulnerability_archived_records
|
||||
ADD CONSTRAINT fk_rails_601e008d4b FOREIGN KEY (archive_id) REFERENCES vulnerability_archives(id) ON DELETE CASCADE;
|
||||
ALTER TABLE vulnerability_archived_records
|
||||
ADD CONSTRAINT fk_rails_601e008d4b FOREIGN KEY (archive_id, date) REFERENCES vulnerability_archives(id, date) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY system_access_microsoft_graph_access_tokens
|
||||
ADD CONSTRAINT fk_rails_604908851f FOREIGN KEY (system_access_microsoft_application_id) REFERENCES system_access_microsoft_applications(id) ON DELETE CASCADE;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,12 @@ ClickHouse::Client.select('SELECT 1', :main)
|
|||
|
||||
## Database schema and migrations
|
||||
|
||||
To generate a ClickHouse database migration, execute:
|
||||
|
||||
``` shell
|
||||
bundle exec rails generate gitlab:click_house:migration MIGRATION_CLASS_NAME
|
||||
```
|
||||
|
||||
To run database migrations, execute:
|
||||
|
||||
```shell
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ You can use whichever tools you're most comfortable with.
|
|||
Use this guidance to help ensure you have the tools you need.
|
||||
|
||||
- Install a code editor, like VS Code or Sublime Text, to work with Markdown files.
|
||||
- [Install Git](../../topics/git/how_to_install_git/_index.md)
|
||||
and [add an SSH key to your GitLab profile](../../user/ssh.md#add-an-ssh-key-to-your-gitlab-account).
|
||||
- [Install Git](../../topics/git/how_to_install_git/_index.md) and
|
||||
[add an SSH key to your GitLab profile](../../user/ssh.md#add-an-ssh-key-to-your-gitlab-account).
|
||||
- Install documentation [linters](../documentation/testing/_index.md) and configure them in your code editor:
|
||||
- [markdownlint](../documentation/testing/markdownlint.md)
|
||||
- [Vale](../documentation/testing/vale.md)
|
||||
|
|
@ -20,7 +20,7 @@ and [add an SSH key to your GitLab profile](../../user/ssh.md#add-an-ssh-key-to-
|
|||
- Optional. Install the [Conventional Comments](https://gitlab.com/conventionalcomments/conventional-comments-button) extension for Chrome.
|
||||
The plugin adds **Conventional Comment** buttons to GitLab comments.
|
||||
|
||||
After you've comfortable with your toolset, you can [install the GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/index.md), a fully functional self-managed version of GitLab.
|
||||
After you're comfortable with your toolset, you can [install the GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/index.md), a fully functional self-managed version of GitLab.
|
||||
|
||||
You can use GDK to:
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ GitLab Python experts are professionals with Python expertise who contribute to
|
|||
To become one:
|
||||
|
||||
1. Create a merge request to add `python: maintainer` competency under `projects` to your [team](https://gitlab.com/gitlab-com/www-gitlab-com/-/tree/master/data/team_members/person?ref_type=heads) file.
|
||||
1. Use [this](https://gitlab.com/gitlab-org/python/code-review-templates/-/tree/main/merge_request_templates/Python_expert.md) template and follow the described process.
|
||||
1. Use [this](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/.gitlab/merge_request_templates/Python%20expert.md) template and follow the described process.
|
||||
|
||||
Once your merge request is merged, you'll be added to the Python maintainers group.
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,20 @@ method as the default:
|
|||
1. **Edit** the selected payment method and check the **Make default payment method** checkbox.
|
||||
1. Select **Save Changes**.
|
||||
|
||||
## Pay for an invoice
|
||||
|
||||
You can pay for your invoices in the Customers Portal with a credit card.
|
||||
|
||||
To pay for an invoice:
|
||||
|
||||
1. Sign in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in).
|
||||
1. On the left sidebar, select **Invoices**.
|
||||
1. On the invoice you want to pay for, select **Pay for invoice**.
|
||||
1. Complete the payment form.
|
||||
|
||||
If you would like to use an alternative payment method,
|
||||
[contact our Billing team](https://customers.gitlab.com/contact_us#contact-billing-team).
|
||||
|
||||
## Link a GitLab.com account
|
||||
|
||||
Follow this guideline if you have a legacy Customers Portal profile to sign in.
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ This page lists fields available to use as filters when querying issues or work
|
|||
**Allowed value types**:
|
||||
|
||||
- `Enum` (one of `Issue`, `Incident`, `TestCase`, `Requirement`, `Task`, `Ticket`, `Objective`,
|
||||
`KeyResult`, `Epic`, or `MergeRequest`)
|
||||
`KeyResult`, or `MergeRequest`)
|
||||
- `List` (containing one or more `enum` values above)
|
||||
|
||||
**Allowed in columns of a GLQL view**: Only for issue and work item types.
|
||||
|
|
@ -595,8 +595,8 @@ This page lists fields available to use as filters when querying issues or work
|
|||
- If omitted when using inside a GLQL view in a group object (like an epic), `group` is assumed to
|
||||
be the current group.
|
||||
- Using the `group` field queries all objects in that group, all its subgroups, and child projects.
|
||||
- By default, issues or merge requests are searched only in direct descendant projects in a group.
|
||||
To query in the entire hierarchy of a project use the [`includeSubgroups` field](#include-subgroups).
|
||||
- By default, issues or merge requests are searched in all descendant projects across all subgroups.
|
||||
To query only the direct child projects of the group, set the [`includeSubgroups` field](#include-subgroups) to `false`.
|
||||
|
||||
**Examples**:
|
||||
|
||||
|
|
|
|||
|
|
@ -70,10 +70,9 @@ To auto-format this table, use the VS Code Markdown Table formatter: `https://do
|
|||
| `/assign me` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Assign yourself. |
|
||||
| `/assign_reviewer @user1 @user2` or `/reviewer @user1 @user2` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Assign one or more users as reviewers. |
|
||||
| `/assign_reviewer me` or `/reviewer me` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Assign yourself as a reviewer. |
|
||||
| `/blocked_by <item1> <item2>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Mark the item as blocked by other items. The `<item>` value should be in the format of `#item`, `group/project#item`, or the full URL. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214232) in GitLab 16.0). |
|
||||
| `/blocks <item1> <item2>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Mark the item as blocking other items. The `<item>` value should be in the format of `#item`, `group/project#item`, or the full URL. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214232) in GitLab 16.0). |
|
||||
| `/blocked_by <item1> <item2>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Mark the item as blocked by other items. The `<item>` value should be in the format of `#item`, `group/project#item`, or the full URL. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214232) in GitLab 16.0). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/blocks <item1> <item2>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Mark the item as blocking other items. The `<item>` value should be in the format of `#item`, `group/project#item`, or the full URL. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214232) in GitLab 16.0). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/cc @user` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Mention a user. This command performs no action. You can instead type `CC @user` or only `@user`. |
|
||||
| `/child_epic <epic>` | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Add child epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. |
|
||||
| `/clear_health_status` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Clear [health status](issues/managing_issues.md#health-status). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/clear_weight` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Clear weight. |
|
||||
| `/clone <path/to/project> [--with_notes]` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Clone the issue to given project, or the current one if no arguments are given. Copies as much data as possible as long as the target project contains equivalent objects like labels, milestones, or epics. Does not copy comments or system notes unless `--with_notes` is provided as an argument. |
|
||||
|
|
@ -81,13 +80,13 @@ To auto-format this table, use the VS Code Markdown Table formatter: `https://do
|
|||
| `/confidential` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Mark issue or epic as confidential. Support for epics [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213741) in GitLab 15.6. |
|
||||
| `/convert_to_ticket <email address>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | [Convert an issue into a Service Desk ticket](service_desk/using_service_desk.md#convert-a-regular-issue-to-a-service-desk-ticket). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/433376) in GitLab 16.9 |
|
||||
| `/copy_metadata <!merge_request>` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Copy labels and milestone from another merge request in the project. |
|
||||
| `/copy_metadata <#issue>` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Copy labels and milestone from another issue in the project. |
|
||||
| `/copy_metadata <#item>` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes| Copy labels and milestone from another issue in the project. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/create_merge_request <branch name>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Create a new merge request starting from the current issue. |
|
||||
| `/done` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Mark to-do item as done. |
|
||||
| `/done` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes| Mark to-do item as done. |
|
||||
| `/draft` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Set the [draft status](merge_requests/drafts.md). |
|
||||
| `/due <date>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Set due date. Examples of valid `<date>` include `in 2 days`, `this Friday` and `December 31st`. See [Chronic](https://gitlab.com/gitlab-org/ruby/gems/gitlab-chronic#examples) for more examples. |
|
||||
| `/duplicate <item>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Close this <work item type>. Marks as related to, and a duplicate of, <#item>. |
|
||||
| `/epic <epic>` or `/set_parent <epic>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Add to epic `<epic>` as a child item. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. Alias `/set_parent` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/514942) in GitLab 17.10. |
|
||||
| `/due <date>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Set due date. Examples of valid `<date>` include `in 2 days`, `this Friday` and `December 31st`. See [Chronic](https://gitlab.com/gitlab-org/ruby/gems/gitlab-chronic#examples) for more examples. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/duplicate <item>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Close this <work item type>. Marks as related to, and a duplicate of, <#item>. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/epic <epic>` or `/set_parent <epic>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No |{{< icon name="check-circle" >}} Yes| Add to epic `<epic>` as a child item. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). Alias `/set_parent` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/514942) in GitLab 17.10. |
|
||||
| `/estimate <time>` or `/estimate_time <time>` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Set time estimate. For example, `/estimate 1mo 2w 3d 4h 5m`. For more information, see [Time tracking](time_tracking.md). Alias `/estimate_time` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16501) in GitLab 15.6. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/health_status <value>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Set [health status](issues/managing_issues.md#health-status). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). Valid options for `<value>` are `on_track`, `needs_attention`, and `at_risk`. |
|
||||
| `/iteration *iteration:<iteration ID> or <iteration name>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Set iteration. For example, to set the `Late in July` iteration: `/iteration *iteration:"Late in July"`. |
|
||||
|
|
@ -95,14 +94,14 @@ To auto-format this table, use the VS Code Markdown Table formatter: `https://do
|
|||
| `/iteration <--current or --next>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Set iteration to the current or next upcoming iteration when a group has one iteration cadence. For example, `/iteration --current` sets the iteration to the current iteration of the iteration cadence. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/384885) in GitLab 16.9. |
|
||||
| `/label ~label1 ~label2` or `/labels ~label1 ~label2` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Add one or more labels. Label names can also start without a tilde (`~`), but mixed syntax is not supported. |
|
||||
| `/link` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Add a link and description to [linked resources](../../operations/incident_management/linked_resources.md) in an incident ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/374964) in GitLab 15.5). |
|
||||
| `/lock` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Lock the discussions. |
|
||||
| `/lock` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Lock the discussions. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/merge` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Merge changes. Depending on the project setting, this may be [when the pipeline succeeds](merge_requests/auto_merge.md), or adding to a [Merge Train](../../ci/pipelines/merge_trains.md). |
|
||||
| `/milestone %milestone` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Set milestone. |
|
||||
| `/move <path/to/project>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Move this issue to another project. Be careful when moving an issue to a project with different access rules. Before moving the issue, make sure it does not contain sensitive data. |
|
||||
| `/page <policy name>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Start escalations for the incident. |
|
||||
| `/parent_epic <epic>` | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Set parent epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. |
|
||||
| `/parent_epic <epic>` | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Set parent epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. If your administrator [enabled the new look for epics](../group/epics/epic_work_items.md), use `/set_parent` instead. |
|
||||
| `/promote_to_incident` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Promote issue to incident. In [GitLab 15.8 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/376760), you can also use the quick action when creating a new issue. |
|
||||
| `/promote` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Promote issue to epic. |
|
||||
| `/promote` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Promote issue to epic. If your administrator [enabled the new look for issues](../project/issues/issue_work_items.md), use `/promote_to epic` instead. |
|
||||
| `/publish` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Publish issue to an associated [Status Page](../../operations/incident_management/status_page.md). |
|
||||
| `/react :emoji:` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Toggle an emoji reaction. [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/409884) from `/award` in GitLab 16.7. `/award` is still available as an aliased command. |
|
||||
| `/ready` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Set the [ready status](merge_requests/drafts.md#mark-merge-requests-as-ready) ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90361) in GitLab 15.1). |
|
||||
|
|
@ -110,26 +109,27 @@ To auto-format this table, use the VS Code Markdown Table formatter: `https://do
|
|||
| `/reassign_reviewer @user1 @user2` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Replace current reviewers with those specified. |
|
||||
| `/rebase` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Rebase source branch on the latest commit of the target branch. For help, see [troubleshooting information](../../topics/git/troubleshooting_git.md). |
|
||||
| `/relabel ~label1 ~label2` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Replace current labels with those specified. |
|
||||
| `/relate <item1> <item2>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Mark items as related. The `<item>` value should be in the format of `#item`, `group/project#item`, or the full URL. |
|
||||
| `/relate <item1> <item2>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Mark items as related. The `<item>` value should be in the format of `#item`, `group/project#item`, or the full URL. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/remove_child <item>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove `<item>` as child. The `<item>` value should be in the format of `#item`, `group/project#item`, or a URL to the item. For issues, your administrator must have [enabled the new look for issues](../project/issues/issue_work_items.md). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/remove_child_epic <epic>` | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove child epic from `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. |
|
||||
| `/remove_child_epic <epic>` | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove child epic from `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. If your administrator [enabled the new look for epics](../group/epics/epic_work_items.md), use `/remove_child` instead. |
|
||||
| `/remove_contacts [contact:email1@example.com] [contact:email2@example.com]` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove one or more [CRM contacts](../crm/_index.md) |
|
||||
| `/remove_due_date` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove due date. |
|
||||
| `/remove_email email1 email2` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove up to six [email participants](service_desk/external_participants.md). This action is behind the feature flag `issue_email_participants`. Not supported in issue templates, merge requests, or epics. |
|
||||
| `/remove_epic` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove from epic. |
|
||||
| `/remove_estimate` or `/remove_time_estimate` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Remove time estimate. Alias `/remove_time_estimate` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16501) in GitLab 15.6. |
|
||||
| `/remove_epic` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove epic as parent item. If your administrator [enabled the new look for epics](../group/epics/epic_work_items.md), use `/remove_parent` instead. |
|
||||
| `/remove_estimate` or `/remove_time_estimate` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Remove time estimate. Alias `/remove_time_estimate` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16501) in GitLab 15.6. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/remove_iteration` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove iteration. |
|
||||
| `/remove_milestone` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Remove milestone. |
|
||||
| `/remove_parent` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove the parent from item. For issues, your administrator must have [enabled the new look for issues](../project/issues/issue_work_items.md). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/remove_parent_epic` | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove parent epic from epic. |
|
||||
| `/remove_time_spent` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Remove time spent. |
|
||||
| `/remove_parent_epic` | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove parent epic from epic. If your administrator [enabled the new look for epics](../group/epics/epic_work_items.md), use `/remove_parent` instead. |
|
||||
| `/remove_time_spent` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes |{{< icon name="check-circle" >}} Yes | Remove time spent. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/remove_zoom` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove Zoom meeting from this issue. |
|
||||
| `/reopen` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Reopen. |
|
||||
| `/request_review @user1 @user2` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Assigns or requests a new review from one or more users. |
|
||||
| `/request_review me` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Assigns or requests a new review from one or more users. |
|
||||
| `/set_parent <item>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Set parent item. The `<item>` value should be in the format of `#IID`, reference, or a URL to an item. For issues, your administrator must have [enabled the new look for issues](../project/issues/issue_work_items.md). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/severity <severity>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Set the severity. Issue type must be `Incident`. Options for `<severity>` are `S1` ... `S4`, `critical`, `high`, `medium`, `low`, `unknown`. |
|
||||
| `/shrug` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Add `¯\_(ツ)_/¯`. |
|
||||
| `/spend <time> [<date>]` or `/spend_time <time> [<date>]` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Add or subtract spent time. Optionally, specify the date that time was spent on. For example, `/spend 1mo 2w 3d 4h 5m 2018-08-26` or `/spend -1h 30m`. For more information, see [Time tracking](time_tracking.md). Alias `/spend_time` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16501) in GitLab 15.6. |
|
||||
| `/spend <time> [<date>]` or `/spend_time <time> [<date>]` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes| Add or subtract spent time. Optionally, specify the date that time was spent on. For example, `/spend 1mo 2w 3d 4h 5m 2018-08-26` or `/spend -1h 30m`. For more information, see [Time tracking](time_tracking.md). Alias `/spend_time` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16501) in GitLab 15.6. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/submit_review` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Submit a pending review. |
|
||||
| `/subscribe` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Subscribe to notifications. |
|
||||
| `/tableflip` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Add `(╯°□°)╯︵ ┻━┻`. |
|
||||
|
|
@ -145,8 +145,8 @@ To auto-format this table, use the VS Code Markdown Table formatter: `https://do
|
|||
| `/unassign` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Remove all assignees. |
|
||||
| `/unlabel ~label1 ~label2` or `/remove_label ~label1 ~label2` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Remove specified labels. |
|
||||
| `/unlabel` or `/remove_label` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Remove all labels. |
|
||||
| `/unlink <item>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove link with to the provided issue. The `<item>` value should be in the format of `#item`, `group/project#item`, or the full URL. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/414400) in GitLab 16.1). |
|
||||
| `/unlock` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Unlock the discussions. |
|
||||
| `/unlink <item>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No |{{< icon name="check-circle" >}} Yes| Remove link with to the provided issue. The `<item>` value should be in the format of `#item`, `group/project#item`, or the full URL. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/414400) in GitLab 16.1). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/unlock` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes |{{< icon name="check-circle" >}} Yes| Unlock the discussions. For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md).|
|
||||
| `/unsubscribe` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Unsubscribe from notifications. |
|
||||
| `/weight <value>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Set weight. Valid values are integers like `0`, `1`, or `2`. |
|
||||
| `/zoom <Zoom URL>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Add a Zoom meeting to this issue or incident. In [GitLab 15.3 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/230853) users on GitLab Premium can add a short description when [adding a Zoom link to an incident](../../operations/incident_management/linked_resources.md#link-zoom-meetings-from-an-incident). |
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ module API
|
|||
not_found!('Project') unless target_project
|
||||
|
||||
begin
|
||||
issue = if Feature.enabled?(:work_item_move_and_clone, target_project)
|
||||
issue = if Feature.enabled?(:work_item_move_and_clone, user_project)
|
||||
response = ::WorkItems::DataSync::CloneService.new(
|
||||
work_item: issue, current_user: current_user, target_namespace: target_project.project_namespace,
|
||||
params: { clone_with_notes: params[:with_notes] }
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ module Gitlab
|
|||
end
|
||||
|
||||
def action_title
|
||||
'Run again'
|
||||
s_('Job|Run again')
|
||||
end
|
||||
|
||||
def action_button_title
|
||||
_('Run this job again')
|
||||
s_('Job|Run this job again')
|
||||
end
|
||||
|
||||
def action_path
|
||||
|
|
|
|||
|
|
@ -163,3 +163,5 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
Gitlab::DataBuilder::Pipeline.prepend_mod
|
||||
|
|
|
|||
|
|
@ -101,15 +101,16 @@ module Gitlab
|
|||
@execution_message[:duplicate] = message
|
||||
end
|
||||
|
||||
desc { _('Clone this issue') }
|
||||
explanation do |project = quick_action_target.project.full_path|
|
||||
_("Clones this issue, without comments, to %{project}.") % { project: project }
|
||||
desc { _('Clone this item') }
|
||||
explanation do |target_container_path = quick_action_target.namespace.full_path|
|
||||
_("Clones this item, without comments, to %{group_or_project}.") % { group_or_project: target_container_path }
|
||||
end
|
||||
params 'path/to/project [--with_notes]'
|
||||
types Issue
|
||||
params 'path/to/group_or_project [--with_notes]'
|
||||
types Issue, WorkItem
|
||||
condition do
|
||||
quick_action_target.persisted? &&
|
||||
current_user.can?(:"clone_#{quick_action_target.to_ability_name}", quick_action_target)
|
||||
current_user.can?(:"clone_#{quick_action_target.to_ability_name}", quick_action_target) &&
|
||||
can_be_moved_or_cloned?
|
||||
end
|
||||
command :clone do |params = ''|
|
||||
params = params.split(' ')
|
||||
|
|
@ -117,45 +118,50 @@ module Gitlab
|
|||
|
||||
# If we have more than 1 param, then the user supplied too many spaces, or mistyped `--with_notes`
|
||||
if params.size > 1
|
||||
@execution_message[:clone] = _('Failed to clone this issue: wrong parameters.')
|
||||
@execution_message[:clone] = _('Failed to clone this item: wrong parameters.')
|
||||
next
|
||||
end
|
||||
|
||||
target_project_path = params[0]
|
||||
target_project = target_project_path.present? ? Project.find_by_full_path(target_project_path) : quick_action_target.project
|
||||
target_container_path = params[0]
|
||||
target_container = fetch_target_container(target_container_path)
|
||||
|
||||
if target_project.present?
|
||||
@updates[:target_clone_project] = target_project
|
||||
@updates[:clone_with_notes] = with_notes
|
||||
|
||||
message = _("Cloned this issue to %{path_to_project}.") % { path_to_project: target_project_path || quick_action_target.project.full_path }
|
||||
else
|
||||
message = _("Failed to clone this issue because target project doesn't exist.")
|
||||
end
|
||||
message =
|
||||
if target_container.nil?
|
||||
_("Unable to clone. Target project or group doesn't exist or doesn't support this item type.")
|
||||
elsif current_user.can?(:admin_issue, target_container)
|
||||
@updates[:target_clone_container] = target_container
|
||||
@updates[:clone_with_notes] = with_notes
|
||||
_("Cloned this item to %{path_to_group_or_project}.") % { path_to_group_or_project: target_container_path || target_container.full_path }
|
||||
else
|
||||
_("Unable to clone. Insufficient permissions.")
|
||||
end
|
||||
|
||||
@execution_message[:clone] = message
|
||||
end
|
||||
|
||||
desc { _('Move this issue to another project') }
|
||||
explanation do |path_to_project|
|
||||
_("Moves this issue to %{path_to_project}.") % { path_to_project: path_to_project }
|
||||
desc { _('Move this item to another group or project') }
|
||||
explanation do |path_to_container|
|
||||
_("Moves this item to %{group_or_project}.") % { group_or_project: path_to_container }
|
||||
end
|
||||
params 'path/to/project'
|
||||
types Issue
|
||||
params 'path/to/group_or_project'
|
||||
types Issue, WorkItem
|
||||
condition do
|
||||
quick_action_target.persisted? &&
|
||||
current_user.can?(:"move_#{quick_action_target.to_ability_name}", quick_action_target)
|
||||
current_user.can?(:"move_#{quick_action_target.to_ability_name}", quick_action_target) &&
|
||||
can_be_moved_or_cloned?
|
||||
end
|
||||
command :move do |target_project_path|
|
||||
target_project = Project.find_by_full_path(target_project_path)
|
||||
command :move do |target_container_path|
|
||||
target_container = fetch_target_container(target_container_path)
|
||||
|
||||
if target_project.present?
|
||||
@updates[:target_project] = target_project
|
||||
|
||||
message = _("Moved this issue to %{path_to_project}.") % { path_to_project: target_project_path }
|
||||
else
|
||||
message = _("Failed to move this issue because target project doesn't exist.")
|
||||
end
|
||||
message =
|
||||
if target_container.nil?
|
||||
_("Unable to move. Target project or group doesn't exist or doesn't support this item type.")
|
||||
elsif current_user.can?(:admin_issue, target_container)
|
||||
@updates[:target_container] = target_container
|
||||
_("Moved this item to %{path_to_container}.") % { path_to_container: target_container_path }
|
||||
else
|
||||
_("Unable to move. Insufficient permissions.")
|
||||
end
|
||||
|
||||
@execution_message[:move] = message
|
||||
end
|
||||
|
|
@ -432,6 +438,22 @@ module Gitlab
|
|||
def timeline_event_create_service(event_text, event_date_time)
|
||||
::IncidentManagement::TimelineEvents::CreateService.new(quick_action_target, current_user, { note: event_text, occurred_at: event_date_time, editable: true })
|
||||
end
|
||||
|
||||
def fetch_target_container(target_container_path)
|
||||
return quick_action_target.namespace unless target_container_path
|
||||
|
||||
if quick_action_target.namespace.is_a?(Namespaces::ProjectNamespace)
|
||||
Project.find_by_full_path(target_container_path)
|
||||
else
|
||||
Group.find_by_full_path(target_container_path)
|
||||
end
|
||||
end
|
||||
|
||||
def can_be_moved_or_cloned?
|
||||
return true unless quick_action_target.is_a?(WorkItem) && quick_action_target.work_item_type.epic?
|
||||
|
||||
::Feature.enabled?(:work_item_move_and_clone, container)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12937,7 +12937,7 @@ msgstr ""
|
|||
msgid "Clone repository"
|
||||
msgstr ""
|
||||
|
||||
msgid "Clone this issue"
|
||||
msgid "Clone this item"
|
||||
msgstr ""
|
||||
|
||||
msgid "Clone with %{protocol}"
|
||||
|
|
@ -12970,10 +12970,10 @@ msgstr ""
|
|||
msgid "CloneWorkItem|Unable to clone. You have insufficient permissions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Cloned this issue to %{path_to_project}."
|
||||
msgid "Cloned this item to %{path_to_group_or_project}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clones this issue, without comments, to %{project}."
|
||||
msgid "Clones this item, without comments, to %{group_or_project}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Close"
|
||||
|
|
@ -24790,10 +24790,7 @@ msgstr ""
|
|||
msgid "Failed to check related branches."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to clone this issue because target project doesn't exist."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to clone this issue: wrong parameters."
|
||||
msgid "Failed to clone this item: wrong parameters."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to create a branch for this issue. Please try again."
|
||||
|
|
@ -24970,9 +24967,6 @@ msgstr ""
|
|||
msgid "Failed to move this issue because only a single label can be provided."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to move this issue because target project doesn't exist."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to promote label due to internal error. Please contact administrators."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -33559,6 +33553,9 @@ msgstr ""
|
|||
msgid "Job|Run again"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Run this job again"
|
||||
msgstr ""
|
||||
|
||||
msgid "Job|Runner type"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -37873,7 +37870,7 @@ msgstr ""
|
|||
msgid "Move test case"
|
||||
msgstr ""
|
||||
|
||||
msgid "Move this issue to another project"
|
||||
msgid "Move this item to another group or project"
|
||||
msgstr ""
|
||||
|
||||
msgid "Move up"
|
||||
|
|
@ -37903,13 +37900,13 @@ msgstr ""
|
|||
msgid "Moved issue to %{label} column in the board."
|
||||
msgstr ""
|
||||
|
||||
msgid "Moved this issue to %{path_to_project}."
|
||||
msgid "Moved this item to %{path_to_container}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Moves issue to %{label} column in the board."
|
||||
msgstr ""
|
||||
|
||||
msgid "Moves this issue to %{path_to_project}."
|
||||
msgid "Moves this item to %{group_or_project}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Moving issue"
|
||||
|
|
@ -49949,9 +49946,6 @@ msgstr ""
|
|||
msgid "Run tests against your code live using the Web Terminal"
|
||||
msgstr ""
|
||||
|
||||
msgid "Run this job again"
|
||||
msgstr ""
|
||||
|
||||
msgid "Run this job again in order to create the necessary resources."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -51973,9 +51967,6 @@ msgstr ""
|
|||
msgid "Search (3 character minimum)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Search Within"
|
||||
msgstr ""
|
||||
|
||||
msgid "Search a group"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -52105,6 +52096,9 @@ msgstr ""
|
|||
msgid "Search users"
|
||||
msgstr ""
|
||||
|
||||
msgid "Search within"
|
||||
msgstr ""
|
||||
|
||||
msgid "Search your projects"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -62389,6 +62383,12 @@ msgstr ""
|
|||
msgid "Unable to build Slack link."
|
||||
msgstr ""
|
||||
|
||||
msgid "Unable to clone. Insufficient permissions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Unable to clone. Target project or group doesn't exist or doesn't support this item type."
|
||||
msgstr ""
|
||||
|
||||
msgid "Unable to collect CPU information"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -62458,6 +62458,12 @@ msgstr ""
|
|||
msgid "Unable to load user list. Reload the page and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "Unable to move. Insufficient permissions."
|
||||
msgstr ""
|
||||
|
||||
msgid "Unable to move. Target project or group doesn't exist or doesn't support this item type."
|
||||
msgstr ""
|
||||
|
||||
msgid "Unable to parse JSON"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@
|
|||
module QA
|
||||
RSpec.describe 'Create' do
|
||||
describe 'Settings Sync in Web IDE',
|
||||
:requires_admin,
|
||||
:skip_live_env,
|
||||
:orchestrated,
|
||||
:mtls, # The extension marketplace requires running Web IDE in a secure context.
|
||||
feature_flag: { name: :web_ide_extensions_marketplace },
|
||||
product_group: :remote_development,
|
||||
feature_category: :web_ide do
|
||||
include_context 'Web IDE test prep'
|
||||
|
|
@ -29,8 +30,9 @@ module QA
|
|||
end
|
||||
|
||||
before do
|
||||
Runtime::Feature.enable(:web_ide_extensions_marketplace)
|
||||
|
||||
Runtime::ApplicationSettings.set_application_settings(
|
||||
vscode_extension_marketplace_enabled: true
|
||||
)
|
||||
load_web_ide(with_extensions_marketplace: true)
|
||||
settings_context_hash = get_settings_context_hash
|
||||
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ RSpec.describe 'Work items list filters', :js, feature_category: :team_planning
|
|||
|
||||
describe 'search within' do
|
||||
it 'filters', :aggregate_failures do
|
||||
select_tokens 'Search Within', 'Titles'
|
||||
select_tokens 'Search within', 'Titles'
|
||||
send_keys 'eee', :enter, :enter
|
||||
|
||||
expect(page).to have_css('.issue', count: 1)
|
||||
|
|
@ -260,7 +260,7 @@ RSpec.describe 'Work items list filters', :js, feature_category: :team_planning
|
|||
|
||||
click_button 'Clear'
|
||||
|
||||
select_tokens 'Search Within', 'Descriptions'
|
||||
select_tokens 'Search within', 'Descriptions'
|
||||
send_keys 'aaa', :enter, :enter
|
||||
|
||||
expect(page).to have_css('.issue', count: 1)
|
||||
|
|
|
|||
|
|
@ -6,18 +6,15 @@ RSpec.describe Import::SourceUsersFinder, feature_category: :importers do
|
|||
let_it_be(:user) { build_stubbed(:user) }
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:source_user_1) do
|
||||
create(:import_source_user, :pending_reassignment, namespace: group, source_name: 'b',
|
||||
created_at: '2025-01-08T23:07:13.000Z')
|
||||
create(:import_source_user, :pending_reassignment, namespace: group, source_name: 'b')
|
||||
end
|
||||
|
||||
let_it_be(:source_user_2) do
|
||||
create(:import_source_user, :awaiting_approval, namespace: group, source_name: 'c',
|
||||
created_at: '2024-03-08T23:07:13.000Z')
|
||||
create(:import_source_user, :awaiting_approval, namespace: group, source_name: 'c')
|
||||
end
|
||||
|
||||
let_it_be(:source_user_3) do
|
||||
create(:import_source_user, :reassignment_in_progress, namespace: group, source_name: 'a',
|
||||
created_at: '2025-01-30T04:07:13.000Z')
|
||||
create(:import_source_user, :reassignment_in_progress, namespace: group, source_name: 'a')
|
||||
end
|
||||
|
||||
let_it_be(:import_source_users) { [source_user_1, source_user_2, source_user_3] }
|
||||
|
|
|
|||
|
|
@ -277,13 +277,11 @@ RSpec.describe Import::SourceUser, type: :model, feature_category: :importers do
|
|||
let_it_be(:namespace) { create(:namespace) }
|
||||
|
||||
let_it_be(:source_user_1) do
|
||||
create(:import_source_user, namespace: namespace, status: 4, source_name: 'd',
|
||||
created_at: '2024-12-03T10:42:20.000Z')
|
||||
create(:import_source_user, namespace: namespace, status: 4, source_name: 'd')
|
||||
end
|
||||
|
||||
let_it_be(:source_user_2) do
|
||||
create(:import_source_user, namespace: namespace, status: 3, source_name: 'c',
|
||||
created_at: '2024-12-03T22:42:20.000Z')
|
||||
create(:import_source_user, namespace: namespace, status: 3, source_name: 'c')
|
||||
end
|
||||
|
||||
let_it_be(:source_user_3) do
|
||||
|
|
@ -293,14 +291,12 @@ RSpec.describe Import::SourceUser, type: :model, feature_category: :importers do
|
|||
namespace: namespace,
|
||||
status: 1,
|
||||
source_name: 'a',
|
||||
created_at: '2025-01-23T19:42:20.000Z',
|
||||
reassignment_token: SecureRandom.hex
|
||||
)
|
||||
end
|
||||
|
||||
let_it_be(:source_user_4) do
|
||||
create(:import_source_user, :with_reassign_to_user, namespace: namespace, status: 2, source_name: 'b',
|
||||
created_at: '2025-01-20T19:42:20.000Z')
|
||||
create(:import_source_user, :with_reassign_to_user, namespace: namespace, status: 2, source_name: 'b')
|
||||
end
|
||||
|
||||
let(:sort_by_attribute) { described_class.sort_by_attribute(method).pluck(attribute) }
|
||||
|
|
|
|||
|
|
@ -1428,7 +1428,7 @@ RSpec.describe Issues::UpdateService, :mailer, feature_category: :team_planning
|
|||
end
|
||||
end
|
||||
|
||||
context 'move issue to another project' do
|
||||
context 'move issue to another project or group' do
|
||||
shared_examples 'move issue to another project' do
|
||||
let_it_be(:target_project) { create(:project) }
|
||||
|
||||
|
|
@ -1442,7 +1442,7 @@ RSpec.describe Issues::UpdateService, :mailer, feature_category: :team_planning
|
|||
expect(service).to receive(:execute).and_call_original
|
||||
end
|
||||
|
||||
new_issue = update_issue(target_project: target_project)
|
||||
new_issue = update_issue(target_container: target_project)
|
||||
|
||||
expect(new_issue.project).to eq(target_project)
|
||||
expect(new_issue.title).to eq(issue.title)
|
||||
|
|
@ -1469,6 +1469,19 @@ RSpec.describe Issues::UpdateService, :mailer, feature_category: :team_planning
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when target container is a group' do
|
||||
context 'without access to the group' do
|
||||
let_it_be(:target_container) { create(:group) }
|
||||
|
||||
it 'does not call any clone service' do
|
||||
expect(WorkItems::DataSync::MoveService).not_to receive(:new)
|
||||
expect(Issues::MoveService).not_to receive(:new)
|
||||
|
||||
update_issue(target_container: target_container)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'clone an issue' do
|
||||
|
|
@ -1485,7 +1498,7 @@ RSpec.describe Issues::UpdateService, :mailer, feature_category: :team_planning
|
|||
expect(service).to receive(:execute).and_call_original
|
||||
end
|
||||
|
||||
new_issue = update_issue(target_clone_project: target_project)
|
||||
new_issue = update_issue(target_clone_container: target_project)
|
||||
|
||||
expect(new_issue.project).to eq(target_project)
|
||||
expect(new_issue.title).to eq(issue.title)
|
||||
|
|
@ -1497,7 +1510,7 @@ RSpec.describe Issues::UpdateService, :mailer, feature_category: :team_planning
|
|||
expect(service).to receive(:execute).and_call_original
|
||||
end
|
||||
|
||||
new_issue = update_issue(target_clone_project: target_project, clone_with_notes: true)
|
||||
new_issue = update_issue(target_clone_container: target_project, clone_with_notes: true)
|
||||
|
||||
expect(new_issue.project).to eq(target_project)
|
||||
expect(new_issue.title).to eq(issue.title)
|
||||
|
|
@ -1526,6 +1539,36 @@ RSpec.describe Issues::UpdateService, :mailer, feature_category: :team_planning
|
|||
let(:clone_service_class) { ::WorkItems::DataSync::CloneService }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when target container is a group' do
|
||||
context 'without access to the group' do
|
||||
let_it_be(:target_container) { create(:group) }
|
||||
|
||||
it 'does not call any clone service' do
|
||||
expect(WorkItems::DataSync::CloneService).not_to receive(:new)
|
||||
expect(Issues::CloneService).not_to receive(:new)
|
||||
|
||||
update_issue(target_clone_container: target_container, clone_with_notes: true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user has access to the group' do
|
||||
let_it_be(:target_container) { group }
|
||||
|
||||
context 'with work_item_move_and_clone disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_item_move_and_clone: false)
|
||||
end
|
||||
|
||||
it 'does not call any clone service' do
|
||||
expect(WorkItems::DataSync::CloneService).not_to receive(:new)
|
||||
expect(Issues::CloneService).not_to receive(:new)
|
||||
|
||||
update_issue(target_clone_container: target_container, clone_with_notes: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when changing relative position of an issue ' do
|
||||
|
|
|
|||
|
|
@ -633,16 +633,22 @@ RSpec.describe QuickActions::InterpretService, feature_category: :text_editors d
|
|||
describe 'move issue command' do
|
||||
it 'returns the move issue message' do
|
||||
_, _, message = service.execute("/move #{project.full_path}", issue)
|
||||
translated_string = _("Moved this issue to %{project_full_path}.")
|
||||
translated_string = _("Moved this item to %{project_full_path}.")
|
||||
formatted_message = format(translated_string, project_full_path: project.full_path.to_s)
|
||||
|
||||
expect(message).to eq(formatted_message)
|
||||
end
|
||||
|
||||
it 'returns move issue failure message when the referenced issue is not found' do
|
||||
it 'returns move issue failure message when the referenced project is not found' do
|
||||
_, _, message = service.execute('/move invalid', issue)
|
||||
|
||||
expect(message).to eq(_("Failed to move this issue because target project doesn't exist."))
|
||||
expect(message).to eq(_("Unable to move. Target project or group doesn't exist or doesn't support this item type."))
|
||||
end
|
||||
|
||||
it 'returns move issue failure message when the path provided is to a group' do
|
||||
_, _, message = service.execute("/move #{group.full_path}", issue)
|
||||
|
||||
expect(message).to eq(_("Unable to move. Target project or group doesn't exist or doesn't support this item type."))
|
||||
end
|
||||
|
||||
context "when we pass a work_item" do
|
||||
|
|
@ -652,7 +658,7 @@ RSpec.describe QuickActions::InterpretService, feature_category: :text_editors d
|
|||
it '/move execution method message' do
|
||||
_, _, message = service.execute(move_command, work_item)
|
||||
|
||||
expect(message).to eq("Moved this issue to #{project.full_path}.")
|
||||
expect(message).to eq("Moved this item to #{project.full_path}.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -660,16 +666,22 @@ RSpec.describe QuickActions::InterpretService, feature_category: :text_editors d
|
|||
describe 'clone issue command' do
|
||||
it 'returns the clone issue message' do
|
||||
_, _, message = service.execute("/clone #{project.full_path}", issue)
|
||||
translated_string = _("Cloned this issue to %{project_full_path}.")
|
||||
translated_string = _("Cloned this item to %{project_full_path}.")
|
||||
formatted_message = format(translated_string, project_full_path: project.full_path.to_s)
|
||||
|
||||
expect(message).to eq(formatted_message)
|
||||
end
|
||||
|
||||
it 'returns clone issue failure message when the referenced issue is not found' do
|
||||
it 'returns clone issue failure message when the referenced project is not found' do
|
||||
_, _, message = service.execute('/clone invalid', issue)
|
||||
|
||||
expect(message).to eq(_("Failed to clone this issue because target project doesn't exist."))
|
||||
expect(message).to eq(_("Unable to clone. Target project or group doesn't exist or doesn't support this item type."))
|
||||
end
|
||||
|
||||
it 'returns clone issue failure message when the path provided is to a group' do
|
||||
_, _, message = service.execute("/clone #{group.full_path}", issue)
|
||||
|
||||
expect(message).to eq(_("Unable to clone. Target project or group doesn't exist or doesn't support this item type."))
|
||||
end
|
||||
|
||||
context "when we pass a work_item" do
|
||||
|
|
@ -678,7 +690,7 @@ RSpec.describe QuickActions::InterpretService, feature_category: :text_editors d
|
|||
it '/clone execution method message' do
|
||||
_, _, message = service.execute("/clone #{project.full_path}", work_item)
|
||||
|
||||
expect(message).to eq("Cloned this issue to #{project.full_path}.")
|
||||
expect(message).to eq("Cloned this item to #{project.full_path}.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3831,7 +3843,7 @@ RSpec.describe QuickActions::InterpretService, feature_category: :text_editors d
|
|||
it 'includes the project name' do
|
||||
_, explanations = service.explain(content, issue)
|
||||
|
||||
expect(explanations).to eq([_("Moves this issue to test/project.")])
|
||||
expect(explanations).to eq([_("Moves this item to test/project.")])
|
||||
end
|
||||
|
||||
context "when work item type is an issue" do
|
||||
|
|
@ -3841,7 +3853,7 @@ RSpec.describe QuickActions::InterpretService, feature_category: :text_editors d
|
|||
it "/move is available" do
|
||||
_, explanations = service.explain(move_command, work_item)
|
||||
|
||||
expect(explanations).to match_array(["Moves this issue to test/project."])
|
||||
expect(explanations).to match_array(["Moves this item to test/project."])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3852,7 +3864,7 @@ RSpec.describe QuickActions::InterpretService, feature_category: :text_editors d
|
|||
it 'includes the project name' do
|
||||
_, explanations = service.explain(content, issue)
|
||||
|
||||
expect(explanations).to match_array([_("Clones this issue, without comments, to test/project.")])
|
||||
expect(explanations).to match_array([_("Clones this item, without comments, to test/project.")])
|
||||
end
|
||||
|
||||
context "when work item type is an issue" do
|
||||
|
|
@ -3861,7 +3873,7 @@ RSpec.describe QuickActions::InterpretService, feature_category: :text_editors d
|
|||
it "/clone is available" do
|
||||
_, explanations = service.explain("/clone test/project", work_item)
|
||||
|
||||
expect(explanations).to match_array(["Clones this issue, without comments, to test/project."])
|
||||
expect(explanations).to match_array(["Clones this item, without comments, to test/project."])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ RSpec.shared_examples 'clone quick action' do
|
|||
it 'clones the issue in the current project' do
|
||||
add_note("/clone")
|
||||
|
||||
expect(page).to have_content "Cloned this issue to #{project.full_path}."
|
||||
expect(page).to have_content "Cloned this item to #{project.full_path}."
|
||||
expect(issue.reload).to be_open
|
||||
|
||||
visit project_issue_path(project, issue)
|
||||
|
|
@ -25,7 +25,7 @@ RSpec.shared_examples 'clone quick action' do
|
|||
it 'clones the issue' do
|
||||
add_note("/clone #{target_project.full_path}")
|
||||
|
||||
expect(page).to have_content "Cloned this issue to #{target_project.full_path}."
|
||||
expect(page).to have_content "Cloned this item to #{target_project.full_path}."
|
||||
expect(issue.reload).to be_open
|
||||
|
||||
visit project_issue_path(target_project, issue)
|
||||
|
|
@ -40,7 +40,7 @@ RSpec.shared_examples 'clone quick action' do
|
|||
|
||||
add_note("/clone --with_notes #{target_project.full_path}")
|
||||
|
||||
expect(page).to have_content "Cloned this issue to #{target_project.full_path}."
|
||||
expect(page).to have_content "Cloned this item to #{target_project.full_path}."
|
||||
expect(issue.reload).to be_open
|
||||
|
||||
visit project_issue_path(target_project, issue)
|
||||
|
|
@ -54,7 +54,7 @@ RSpec.shared_examples 'clone quick action' do
|
|||
# Note that this is missing one `-`
|
||||
add_note("/clone -with_notes #{target_project.full_path}")
|
||||
|
||||
expect(page).to have_content 'Failed to clone this issue: wrong parameters.'
|
||||
expect(page).to have_content 'Failed to clone this item: wrong parameters.'
|
||||
expect(issue.reload).to be_open
|
||||
end
|
||||
end
|
||||
|
|
@ -66,7 +66,7 @@ RSpec.shared_examples 'clone quick action' do
|
|||
it 'does not clone the issue' do
|
||||
add_note("/clone #{project_unauthorized.full_path}")
|
||||
|
||||
expect(page).to have_content "Cloned this issue to #{project_unauthorized.full_path}."
|
||||
expect(page).to have_content "Unable to clone. Insufficient permissions."
|
||||
expect(issue.reload).to be_open
|
||||
|
||||
visit project_issue_path(target_project, issue)
|
||||
|
|
@ -79,7 +79,7 @@ RSpec.shared_examples 'clone quick action' do
|
|||
it 'does not clone the issue' do
|
||||
add_note("/clone not/valid")
|
||||
|
||||
expect(page).to have_content "Failed to clone this issue because target project doesn't exist."
|
||||
expect(page).to have_content "Unable to clone. Target project or group doesn't exist or doesn't support this item type."
|
||||
expect(issue.reload).to be_open
|
||||
end
|
||||
end
|
||||
|
|
@ -100,7 +100,7 @@ RSpec.shared_examples 'clone quick action' do
|
|||
|
||||
shared_examples 'applies the commands to issues in both projects, target and source' do
|
||||
it "applies quick actions" do
|
||||
expect(page).to have_content "Cloned this issue to #{target_project.full_path}."
|
||||
expect(page).to have_content "Cloned this item to #{target_project.full_path}."
|
||||
expect(issue.reload).to be_open
|
||||
|
||||
visit project_issue_path(target_project, issue)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ RSpec.shared_examples 'move quick action' do
|
|||
it 'moves the issue' do
|
||||
add_note("/move #{target_project.full_path}")
|
||||
|
||||
expect(page).to have_content "Moved this issue to #{target_project.full_path}."
|
||||
expect(page).to have_content "Moved this item to #{target_project.full_path}."
|
||||
expect(issue.reload).to be_closed
|
||||
|
||||
visit project_issue_path(target_project, issue)
|
||||
|
|
@ -31,7 +31,7 @@ RSpec.shared_examples 'move quick action' do
|
|||
it 'does not move the issue' do
|
||||
add_note("/move #{project_unauthorized.full_path}")
|
||||
|
||||
expect(page).to have_content "Moved this issue to #{project_unauthorized.full_path}."
|
||||
expect(page).to have_content "Unable to move. Insufficient permissions"
|
||||
expect(issue.reload).to be_open
|
||||
end
|
||||
end
|
||||
|
|
@ -40,7 +40,7 @@ RSpec.shared_examples 'move quick action' do
|
|||
it 'does not move the issue' do
|
||||
add_note("/move not/valid")
|
||||
|
||||
expect(page).to have_content "Failed to move this issue because target project doesn't exist."
|
||||
expect(page).to have_content "Unable to move. Target project or group doesn't exist or doesn't support this item type."
|
||||
expect(issue.reload).to be_open
|
||||
end
|
||||
end
|
||||
|
|
@ -58,7 +58,7 @@ RSpec.shared_examples 'move quick action' do
|
|||
|
||||
shared_examples 'applies the commands to issues in both projects, target and source' do
|
||||
it "applies quick actions" do
|
||||
expect(page).to have_content "Moved this issue to #{target_project.full_path}."
|
||||
expect(page).to have_content "Moved this item to #{target_project.full_path}."
|
||||
expect(issue.reload).to be_closed
|
||||
|
||||
visit project_issue_path(target_project, issue)
|
||||
|
|
|
|||
Loading…
Reference in New Issue