Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
226c5810c9
commit
a9f214d421
18 changed files with 198 additions and 22 deletions
|
@ -117,6 +117,7 @@ export default {
|
|||
'autocompleteAwardEmojisPath',
|
||||
'calendarPath',
|
||||
'canBulkUpdate',
|
||||
'canCreateProjects',
|
||||
'canReadCrmContact',
|
||||
'canReadCrmOrganization',
|
||||
'emptyStateSvgPath',
|
||||
|
@ -136,6 +137,7 @@ export default {
|
|||
'isSignedIn',
|
||||
'jiraIntegrationPath',
|
||||
'newIssuePath',
|
||||
'newProjectPath',
|
||||
'releasesPath',
|
||||
'rssPath',
|
||||
'showNewIssueLink',
|
||||
|
@ -844,12 +846,17 @@ export default {
|
|||
</issuable-list>
|
||||
|
||||
<template v-else-if="isSignedIn">
|
||||
<gl-empty-state
|
||||
:description="$options.i18n.noIssuesSignedInDescription"
|
||||
:title="$options.i18n.noIssuesSignedInTitle"
|
||||
:svg-path="emptyStateSvgPath"
|
||||
>
|
||||
<gl-empty-state :title="$options.i18n.noIssuesSignedInTitle" :svg-path="emptyStateSvgPath">
|
||||
<template #description>
|
||||
<p>{{ $options.i18n.noIssuesSignedInDescription }}</p>
|
||||
<p v-if="canCreateProjects">
|
||||
<strong>{{ $options.i18n.noGroupIssuesSignedInDescription }}</strong>
|
||||
</p>
|
||||
</template>
|
||||
<template #actions>
|
||||
<gl-button v-if="canCreateProjects" :href="newProjectPath" variant="confirm">
|
||||
{{ $options.i18n.newProjectLabel }}
|
||||
</gl-button>
|
||||
<gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
|
||||
{{ $options.i18n.newIssueLabel }}
|
||||
</gl-button>
|
||||
|
|
|
@ -29,7 +29,11 @@ export const i18n = {
|
|||
jiraIntegrationSecondaryMessage: s__('JiraService|This feature requires a Premium plan.'),
|
||||
jiraIntegrationTitle: s__('JiraService|Using Jira for issue tracking?'),
|
||||
newIssueLabel: __('New issue'),
|
||||
newProjectLabel: __('New project'),
|
||||
noClosedIssuesTitle: __('There are no closed issues'),
|
||||
noGroupIssuesSignedInDescription: __(
|
||||
'Issues exist in projects, so to create an issue, first create a project.',
|
||||
),
|
||||
noOpenIssuesDescription: __('To keep this project going, create a new issue'),
|
||||
noOpenIssuesTitle: __('There are no open issues'),
|
||||
noIssuesSignedInDescription: __(
|
||||
|
|
|
@ -80,6 +80,7 @@ export function mountIssuesListApp() {
|
|||
autocompleteAwardEmojisPath,
|
||||
calendarPath,
|
||||
canBulkUpdate,
|
||||
canCreateProjects,
|
||||
canEdit,
|
||||
canImportIssues,
|
||||
canReadCrmContact,
|
||||
|
@ -109,6 +110,7 @@ export function mountIssuesListApp() {
|
|||
markdownHelpPath,
|
||||
maxAttachmentSize,
|
||||
newIssuePath,
|
||||
newProjectPath,
|
||||
projectImportJiraPath,
|
||||
quickActionsHelpPath,
|
||||
releasesPath,
|
||||
|
@ -133,6 +135,7 @@ export function mountIssuesListApp() {
|
|||
autocompleteAwardEmojisPath,
|
||||
calendarPath,
|
||||
canBulkUpdate: parseBoolean(canBulkUpdate),
|
||||
canCreateProjects: parseBoolean(canCreateProjects),
|
||||
canReadCrmContact: parseBoolean(canReadCrmContact),
|
||||
canReadCrmOrganization: parseBoolean(canReadCrmOrganization),
|
||||
emptyStateSvgPath,
|
||||
|
@ -153,6 +156,7 @@ export function mountIssuesListApp() {
|
|||
isSignedIn: parseBoolean(isSignedIn),
|
||||
jiraIntegrationPath,
|
||||
newIssuePath,
|
||||
newProjectPath,
|
||||
releasesPath,
|
||||
rssPath,
|
||||
showNewIssueLink: parseBoolean(showNewIssueLink),
|
||||
|
|
|
@ -238,10 +238,12 @@ module IssuesHelper
|
|||
|
||||
def group_issues_list_data(group, current_user)
|
||||
common_issues_list_data(group, current_user).merge(
|
||||
can_create_projects: can?(current_user, :create_projects, group).to_s,
|
||||
can_read_crm_contact: can?(current_user, :read_crm_contact, group).to_s,
|
||||
can_read_crm_organization: can?(current_user, :read_crm_organization, group).to_s,
|
||||
has_any_issues: @has_issues.to_s,
|
||||
has_any_projects: @has_projects.to_s
|
||||
has_any_projects: @has_projects.to_s,
|
||||
new_project_path: new_project_path(namespace_id: group.id)
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -56,8 +56,7 @@ class DiffFileEntity < DiffFileBaseEntity
|
|||
|
||||
# Used for inline diffs
|
||||
expose :highlighted_diff_lines, using: DiffLineEntity, if: -> (diff_file, options) { inline_diff_view?(options) && diff_file.text? } do |diff_file|
|
||||
file = conflict_file(options, diff_file) || diff_file
|
||||
file.diff_lines_for_serializer
|
||||
highlighted_diff_lines_for(diff_file, options)
|
||||
end
|
||||
|
||||
expose :is_fully_expanded do |diff_file|
|
||||
|
@ -89,6 +88,15 @@ class DiffFileEntity < DiffFileBaseEntity
|
|||
# If nothing is present, inline will be the default.
|
||||
options.fetch(:diff_view, :inline).to_sym
|
||||
end
|
||||
|
||||
def highlighted_diff_lines_for(diff_file, options)
|
||||
file = conflict_file(options, diff_file) || diff_file
|
||||
|
||||
file.diff_lines_for_serializer
|
||||
rescue Gitlab::Git::Conflict::Parser::UnmergeableFile
|
||||
# Fallback to diff_file as it means that conflict lines can't be parsed due to limit
|
||||
diff_file.diff_lines_for_serializer
|
||||
end
|
||||
end
|
||||
|
||||
DiffFileEntity.prepend_mod
|
||||
|
|
|
@ -55,7 +55,10 @@ module AutoMerge
|
|||
def available_for?(merge_request)
|
||||
strong_memoize("available_for_#{merge_request.id}") do
|
||||
merge_request.can_be_merged_by?(current_user) &&
|
||||
merge_request.mergeable_state?(skip_ci_check: true) &&
|
||||
merge_request.open? &&
|
||||
!merge_request.broken? &&
|
||||
!merge_request.draft? &&
|
||||
merge_request.mergeable_discussions_state? &&
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CleanupBackfillIntegrationsEnableSslVerification < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
MIGRATION = 'BackfillIntegrationsEnableSslVerification'
|
||||
|
||||
def up
|
||||
finalize_background_migration(MIGRATION)
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropTemporaryIndexForBackfillIntegrationsEnableSslVerification < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'tmp_index_integrations_on_id_where_type_droneci_or_teamcity'
|
||||
INDEX_CONDITION = "type_new IN ('Integrations::DroneCi', 'Integrations::Teamcity') " \
|
||||
"AND encrypted_properties IS NOT NULL"
|
||||
|
||||
def up
|
||||
remove_concurrent_index_by_name :integrations, INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
# this index is used in 20220209121435_backfill_integrations_enable_ssl_verification
|
||||
add_concurrent_index :integrations, :id, where: INDEX_CONDITION, name: INDEX_NAME
|
||||
end
|
||||
end
|
1
db/schema_migrations/20220525131557
Normal file
1
db/schema_migrations/20220525131557
Normal file
|
@ -0,0 +1 @@
|
|||
fe0e9acc39c2408853ea3fc35574c553172ad381a5b6f243578f44ed77dc75f8
|
1
db/schema_migrations/20220525131624
Normal file
1
db/schema_migrations/20220525131624
Normal file
|
@ -0,0 +1 @@
|
|||
f34c6e7b75d375342f5c88a9c7b98e15031a6dcdadf7e7dad862ef5f32a54e68
|
|
@ -29975,8 +29975,6 @@ CREATE INDEX tmp_index_for_null_project_namespace_id ON projects USING btree (id
|
|||
|
||||
CREATE INDEX tmp_index_for_project_namespace_id_migration_on_routes ON routes USING btree (id) WHERE ((namespace_id IS NULL) AND ((source_type)::text = 'Project'::text));
|
||||
|
||||
CREATE INDEX tmp_index_integrations_on_id_where_type_droneci_or_teamcity ON integrations USING btree (id) WHERE ((type_new = ANY (ARRAY['Integrations::DroneCi'::text, 'Integrations::Teamcity'::text])) AND (encrypted_properties IS NOT NULL));
|
||||
|
||||
CREATE INDEX tmp_index_issues_on_issue_type_and_id ON issues USING btree (issue_type, id);
|
||||
|
||||
CREATE INDEX tmp_index_members_on_state ON members USING btree (state) WHERE (state = 2);
|
||||
|
|
|
@ -175,6 +175,8 @@ To configure streaming audit events for Git operations, see [Add a new event str
|
|||
|
||||
### Headers
|
||||
|
||||
> `X-Gitlab-Audit-Event-Type` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86881) in GitLab 15.0.
|
||||
|
||||
Headers are formatted as follows:
|
||||
|
||||
```plaintext
|
||||
|
@ -182,6 +184,7 @@ POST /logs HTTP/1.1
|
|||
Host: <DESTINATION_HOST>
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>
|
||||
X-Gitlab-Audit-Event-Type: repository_git_operation
|
||||
```
|
||||
|
||||
### Example payloads for SSH events
|
||||
|
@ -212,7 +215,8 @@ Fetch:
|
|||
"target_details": "example-project",
|
||||
"created_at": "2022-02-23T06:21:05.283Z",
|
||||
"target_type": "Project",
|
||||
"target_id": 29
|
||||
"target_id": 29,
|
||||
"event_type": "repository_git_operation"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -242,7 +246,8 @@ Push:
|
|||
"target_details": "example-project",
|
||||
"created_at": "2022-02-23T06:23:08.746Z",
|
||||
"target_type": "Project",
|
||||
"target_id": 29
|
||||
"target_id": 29,
|
||||
"event_type": "repository_git_operation"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -274,7 +279,8 @@ Fetch:
|
|||
"target_details": "example-project",
|
||||
"created_at": "2022-02-23T06:25:43.938Z",
|
||||
"target_type": "Project",
|
||||
"target_id": 29
|
||||
"target_id": 29,
|
||||
"event_type": "repository_git_operation"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -304,7 +310,8 @@ Push:
|
|||
"target_details": "example-project",
|
||||
"created_at": "2022-02-23T06:26:29.294Z",
|
||||
"target_type": "Project",
|
||||
"target_id": 29
|
||||
"target_id": 29,
|
||||
"event_type": "repository_git_operation"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -333,7 +340,8 @@ Fetch:
|
|||
"target_details": "example-group/example-project",
|
||||
"created_at": "2022-02-23T06:27:17.873Z",
|
||||
"target_type": "Project",
|
||||
"target_id": 29
|
||||
"target_id": 29,
|
||||
"event_type": "repository_git_operation"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -352,6 +360,7 @@ POST /logs HTTP/1.1
|
|||
Host: <DESTINATION_HOST>
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>
|
||||
X-Gitlab-Audit-Event-Type: audit_operation
|
||||
```
|
||||
|
||||
### Example payload
|
||||
|
@ -377,6 +386,7 @@ X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>
|
|||
"target_details": "merge request title",
|
||||
"created_at": "2022-03-09T06:53:11.181Z",
|
||||
"target_type": "MergeRequest",
|
||||
"target_id": 20
|
||||
"target_id": 20,
|
||||
"event_type": "audit_operation"
|
||||
}
|
||||
```
|
||||
|
|
|
@ -21324,6 +21324,9 @@ msgstr ""
|
|||
msgid "Issues closed"
|
||||
msgstr ""
|
||||
|
||||
msgid "Issues exist in projects, so to create an issue, first create a project."
|
||||
msgstr ""
|
||||
|
||||
msgid "Issues must match this scope to appear in this list."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
RSpec.describe 'Create' do
|
||||
RSpec.describe 'Create', quarantine: {
|
||||
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/363807',
|
||||
type: :stale
|
||||
} do
|
||||
describe 'Create a new merge request' do
|
||||
let(:project) do
|
||||
Resource::Project.fabricate_via_api! do |project|
|
||||
|
|
|
@ -67,6 +67,7 @@ describe('CE IssuesListApp component', () => {
|
|||
autocompleteAwardEmojisPath: 'autocomplete/award/emojis/path',
|
||||
calendarPath: 'calendar/path',
|
||||
canBulkUpdate: false,
|
||||
canCreateProjects: false,
|
||||
canReadCrmContact: false,
|
||||
canReadCrmOrganization: false,
|
||||
emptyStateSvgPath: 'empty-state.svg',
|
||||
|
@ -88,6 +89,7 @@ describe('CE IssuesListApp component', () => {
|
|||
isSignedIn: true,
|
||||
jiraIntegrationPath: 'jira/integration/path',
|
||||
newIssuePath: 'new/issue/path',
|
||||
newProjectPath: 'new/project/path',
|
||||
releasesPath: 'releases/path',
|
||||
rssPath: 'rss/path',
|
||||
showNewIssueLink: true,
|
||||
|
@ -118,6 +120,7 @@ describe('CE IssuesListApp component', () => {
|
|||
issuesQueryResponse = jest.fn().mockResolvedValue(defaultQueryResponse),
|
||||
issuesCountsQueryResponse = jest.fn().mockResolvedValue(getIssuesCountsQueryResponse),
|
||||
sortPreferenceMutationResponse = jest.fn().mockResolvedValue(setSortPreferenceMutationResponse),
|
||||
stubs = {},
|
||||
mountFn = shallowMount,
|
||||
} = {}) => {
|
||||
const requestHandlers = [
|
||||
|
@ -136,6 +139,7 @@ describe('CE IssuesListApp component', () => {
|
|||
data() {
|
||||
return data;
|
||||
},
|
||||
stubs,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -521,10 +525,12 @@ describe('CE IssuesListApp component', () => {
|
|||
|
||||
it('shows empty state', () => {
|
||||
expect(findGlEmptyState().props()).toMatchObject({
|
||||
description: IssuesListApp.i18n.noIssuesSignedInDescription,
|
||||
title: IssuesListApp.i18n.noIssuesSignedInTitle,
|
||||
svgPath: defaultProvide.emptyStateSvgPath,
|
||||
});
|
||||
expect(findGlEmptyState().text()).toContain(
|
||||
IssuesListApp.i18n.noIssuesSignedInDescription,
|
||||
);
|
||||
});
|
||||
|
||||
it('shows "New issue" and import/export buttons', () => {
|
||||
|
@ -538,11 +544,11 @@ describe('CE IssuesListApp component', () => {
|
|||
|
||||
it('shows Jira integration information', () => {
|
||||
const paragraphs = wrapper.findAll('p');
|
||||
expect(paragraphs.at(1).text()).toContain(IssuesListApp.i18n.jiraIntegrationTitle);
|
||||
expect(paragraphs.at(2).text()).toContain(
|
||||
expect(paragraphs.at(2).text()).toContain(IssuesListApp.i18n.jiraIntegrationTitle);
|
||||
expect(paragraphs.at(3).text()).toContain(
|
||||
'Enable the Jira integration to view your Jira issues in GitLab.',
|
||||
);
|
||||
expect(paragraphs.at(3).text()).toContain(
|
||||
expect(paragraphs.at(4).text()).toContain(
|
||||
IssuesListApp.i18n.jiraIntegrationSecondaryMessage,
|
||||
);
|
||||
expect(findGlLink().text()).toBe('Enable the Jira integration');
|
||||
|
@ -550,6 +556,29 @@ describe('CE IssuesListApp component', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when user is logged in and can create projects', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = mountComponent({
|
||||
provide: { canCreateProjects: true, hasAnyIssues: false, isSignedIn: true },
|
||||
stubs: { GlEmptyState },
|
||||
});
|
||||
});
|
||||
|
||||
it('shows empty state with additional description about creating projects', () => {
|
||||
expect(findGlEmptyState().text()).toContain(
|
||||
IssuesListApp.i18n.noIssuesSignedInDescription,
|
||||
);
|
||||
expect(findGlEmptyState().text()).toContain(
|
||||
IssuesListApp.i18n.noGroupIssuesSignedInDescription,
|
||||
);
|
||||
});
|
||||
|
||||
it('shows "New project" button', () => {
|
||||
expect(findGlButton().text()).toBe(IssuesListApp.i18n.newProjectLabel);
|
||||
expect(findGlButton().attributes('href')).toBe(defaultProvide.newProjectPath);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when user is logged out', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = mountComponent({
|
||||
|
|
|
@ -355,12 +355,14 @@ RSpec.describe IssuesHelper do
|
|||
expected = {
|
||||
autocomplete_award_emojis_path: autocomplete_award_emojis_path,
|
||||
calendar_path: '#',
|
||||
can_create_projects: 'true',
|
||||
empty_state_svg_path: '#',
|
||||
full_path: group.full_path,
|
||||
has_any_issues: false.to_s,
|
||||
has_any_projects: true.to_s,
|
||||
is_signed_in: current_user.present?.to_s,
|
||||
jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),
|
||||
new_project_path: new_project_path(namespace_id: group.id),
|
||||
rss_path: '#',
|
||||
sign_in_path: new_user_session_path
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe CleanupBackfillIntegrationsEnableSslVerification, :migration do
|
||||
let(:job_class_name) { 'BackfillIntegrationsEnableSslVerification' }
|
||||
|
||||
before do
|
||||
# Jobs enqueued in Sidekiq.
|
||||
Sidekiq::Testing.disable! do
|
||||
BackgroundMigrationWorker.perform_in(10, job_class_name, [1, 2])
|
||||
BackgroundMigrationWorker.perform_in(20, job_class_name, [3, 4])
|
||||
end
|
||||
|
||||
# Jobs tracked in the database.
|
||||
Gitlab::Database::BackgroundMigrationJob.create!(
|
||||
class_name: job_class_name,
|
||||
arguments: [5, 6],
|
||||
status: Gitlab::Database::BackgroundMigrationJob.statuses['pending']
|
||||
)
|
||||
Gitlab::Database::BackgroundMigrationJob.create!(
|
||||
class_name: job_class_name,
|
||||
arguments: [7, 8],
|
||||
status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
|
||||
)
|
||||
|
||||
migrate!
|
||||
end
|
||||
|
||||
it_behaves_like(
|
||||
'finalized tracked background migration',
|
||||
Gitlab::BackgroundMigration::BackfillIntegrationsEnableSslVerification
|
||||
)
|
||||
end
|
|
@ -91,5 +91,38 @@ RSpec.describe DiffFileEntity do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#highlighted_diff_lines' do
|
||||
context 'file without a conflict' do
|
||||
let(:options) { { conflicts: {} } }
|
||||
|
||||
it 'calls diff_lines_for_serializer on diff_file' do
|
||||
# #diff_lines_for_serializer gets called in #fully_expanded? as well so we expect twice
|
||||
expect(diff_file).to receive(:diff_lines_for_serializer).twice.and_return([])
|
||||
expect(subject[:highlighted_diff_lines]).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
context 'file with a conflict' do
|
||||
let(:conflict_file) { instance_double(Gitlab::Conflict::File, conflict_type: :both_modified) }
|
||||
let(:options) { { conflicts: { diff_file.new_path => conflict_file } } }
|
||||
|
||||
it 'calls diff_lines_for_serializer on matching conflict file' do
|
||||
expect(conflict_file).to receive(:diff_lines_for_serializer).and_return([])
|
||||
expect(subject[:highlighted_diff_lines]).to eq([])
|
||||
end
|
||||
|
||||
context 'when Gitlab::Git::Conflict::Parser::UnmergeableFile gets raised' do
|
||||
before do
|
||||
allow(conflict_file).to receive(:diff_lines_for_serializer).and_raise(Gitlab::Git::Conflict::Parser::UnmergeableFile)
|
||||
end
|
||||
|
||||
it 'falls back to diff_file diff_lines_for_serializer' do
|
||||
expect(diff_file).to receive(:diff_lines_for_serializer).and_return([])
|
||||
expect(subject[:highlighted_diff_lines]).to eq([])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'diff file with conflict_type'
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue