Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
eac5706a07
commit
da2b829418
|
|
@ -15,7 +15,7 @@ include:
|
|||
gitlab_auth_token_variable_name: "PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE"
|
||||
allure_job_name: "${QA_RUN_TYPE}"
|
||||
- project: gitlab-org/quality/pipeline-common
|
||||
ref: 8.5.0
|
||||
ref: 8.5.1
|
||||
file:
|
||||
- /ci/base.gitlab-ci.yml
|
||||
- /ci/knapsack-report.yml
|
||||
|
|
|
|||
|
|
@ -120,8 +120,6 @@ Lint/EmptyBlock:
|
|||
- 'spec/lib/gitlab/github_import/importer/protected_branches_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/gpg_spec.rb'
|
||||
- 'spec/lib/gitlab/graphql/negatable_arguments_spec.rb'
|
||||
- 'spec/lib/gitlab/http_io_spec.rb'
|
||||
|
|
|
|||
|
|
@ -442,7 +442,6 @@ Lint/UnusedMethodArgument:
|
|||
- 'lib/gitlab/gitaly_client/commit_service.rb'
|
||||
- 'lib/gitlab/gitaly_client/operation_service.rb'
|
||||
- 'lib/gitlab/github_gists_import/representation/gist.rb'
|
||||
- 'lib/gitlab/github_import/importer/pull_requests/review_requests_importer.rb'
|
||||
- 'lib/gitlab/github_import/representation/diff_note.rb'
|
||||
- 'lib/gitlab/github_import/representation/issue_event.rb'
|
||||
- 'lib/gitlab/github_import/representation/lfs_object.rb'
|
||||
|
|
|
|||
|
|
@ -3406,8 +3406,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/lib/gitlab/github_import/importer/repository_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_issue_events_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/label_finder_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/logger_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/markdown_text_spec.rb'
|
||||
|
|
|
|||
|
|
@ -2174,14 +2174,10 @@ RSpec/NamedSubject:
|
|||
- 'spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/protected_branches_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/pull_requests/all_merged_by_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/pull_requests/merged_by_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/pull_requests/review_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/pull_requests/reviews_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_issue_events_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/representation/note_text_spec.rb'
|
||||
- 'spec/lib/gitlab/gl_repository/repo_type_spec.rb'
|
||||
- 'spec/lib/gitlab/grape_logging/loggers/cloudflare_logger_spec.rb'
|
||||
|
|
|
|||
|
|
@ -526,8 +526,6 @@ RSpec/VerifiedDoubles:
|
|||
- 'spec/lib/gitlab/github_import/importer/releases_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/repository_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/issuable_finder_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/markdown_text_spec.rb'
|
||||
- 'spec/lib/gitlab/github_import/milestone_finder_spec.rb'
|
||||
|
|
@ -970,9 +968,6 @@ RSpec/VerifiedDoubles:
|
|||
- 'spec/workers/gitlab/github_import/stage/finish_import_worker_spec.rb'
|
||||
- 'spec/workers/gitlab/github_import/stage/import_base_data_worker_spec.rb'
|
||||
- 'spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb'
|
||||
- 'spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb'
|
||||
- 'spec/workers/gitlab/github_import/stage/import_pull_requests_merged_by_worker_spec.rb'
|
||||
- 'spec/workers/gitlab/github_import/stage/import_pull_requests_reviews_worker_spec.rb'
|
||||
- 'spec/workers/gitlab/github_import/stage/import_pull_requests_worker_spec.rb'
|
||||
- 'spec/workers/gitlab/github_import/stage/import_repository_worker_spec.rb'
|
||||
- 'spec/workers/gitlab_performance_bar_stats_worker_spec.rb'
|
||||
|
|
|
|||
|
|
@ -2427,13 +2427,10 @@ Style/InlineDisableAnnotation:
|
|||
- 'lib/gitlab/github_import/importer/labels_importer.rb'
|
||||
- 'lib/gitlab/github_import/importer/milestones_importer.rb'
|
||||
- 'lib/gitlab/github_import/importer/note_importer.rb'
|
||||
- 'lib/gitlab/github_import/importer/pull_requests/review_requests_importer.rb'
|
||||
- 'lib/gitlab/github_import/importer/releases_importer.rb'
|
||||
- 'lib/gitlab/github_import/importer/repository_importer.rb'
|
||||
- 'lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer.rb'
|
||||
- 'lib/gitlab/github_import/importer/single_endpoint_issue_events_importer.rb'
|
||||
- 'lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer.rb'
|
||||
- 'lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer.rb'
|
||||
- 'lib/gitlab/github_import/label_finder.rb'
|
||||
- 'lib/gitlab/github_import/markdown_text.rb'
|
||||
- 'lib/gitlab/github_import/milestone_finder.rb'
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
import { GlAccordion, GlAccordionItem, GlSkeletonLoader } from '@gitlab/ui';
|
||||
import { isLoggedIn } from '~/lib/utils/common_utils';
|
||||
|
||||
import { s__ } from '~/locale';
|
||||
import Participants from '~/sidebar/components/participants/participants.vue';
|
||||
import { s__, n__ } from '~/locale';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../constants';
|
||||
import updateActiveDiscussionMutation from '../graphql/mutations/update_active_discussion.mutation.graphql';
|
||||
|
|
@ -17,7 +16,6 @@ export default {
|
|||
components: {
|
||||
DesignDiscussion,
|
||||
DesignNoteSignedOut,
|
||||
Participants,
|
||||
GlAccordion,
|
||||
GlAccordionItem,
|
||||
GlSkeletonLoader,
|
||||
|
|
@ -96,6 +94,9 @@ export default {
|
|||
unresolvedDiscussions() {
|
||||
return this.discussions.filter((discussion) => !discussion.resolved);
|
||||
},
|
||||
unresolvedDiscussionsCount() {
|
||||
return n__('%d Thread', '%d Threads', this.unresolvedDiscussions.length);
|
||||
},
|
||||
isResolvedDiscussionsExpanded: {
|
||||
get() {
|
||||
return this.resolvedDiscussionsExpanded;
|
||||
|
|
@ -148,13 +149,11 @@ export default {
|
|||
:markdown-preview-path="markdownPreviewPath"
|
||||
class="gl-mt-4"
|
||||
/>
|
||||
<participants
|
||||
:participants="discussionParticipants"
|
||||
:show-participant-label="false"
|
||||
class="gl-mb-4"
|
||||
/>
|
||||
<gl-skeleton-loader v-if="isLoading" />
|
||||
<template v-else>
|
||||
<h3 data-testid="unresolved-discussion-count" class="gl-line-height-20! gl-font-lg">
|
||||
{{ unresolvedDiscussionsCount }}
|
||||
</h3>
|
||||
<h2
|
||||
v-if="isLoggedIn && unresolvedDiscussions.length === 0"
|
||||
class="new-discussion-disclaimer gl-font-base gl-m-0 gl-mb-4"
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@ export default {
|
|||
i18n: {
|
||||
private: __('Private'),
|
||||
inherited: __('Inherited'),
|
||||
indirect: __('Indirect'),
|
||||
directMember: __('Direct member'),
|
||||
directMemberWithCreatedBy: s__('Members|Direct member by %{createdBy}'),
|
||||
inheritedMemberWithCreatedBy: s__('Members|%{group} by %{createdBy}'),
|
||||
indirectMemberWithCreatedBy: s__('Members|%{group} by %{createdBy}'),
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
|
|
@ -43,10 +44,15 @@ export default {
|
|||
showCreatedBy() {
|
||||
return this.createdBy?.name && this.createdBy?.webUrl;
|
||||
},
|
||||
tooltipHover() {
|
||||
return gon.features?.webuiMembersInheritedUsers
|
||||
? this.$options.i18n.indirect
|
||||
: this.$options.i18n.inherited;
|
||||
},
|
||||
messageWithCreatedBy() {
|
||||
return this.isDirectMember
|
||||
? this.$options.i18n.directMemberWithCreatedBy
|
||||
: this.$options.i18n.inheritedMemberWithCreatedBy;
|
||||
: this.$options.i18n.indirectMemberWithCreatedBy;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -60,7 +66,7 @@ export default {
|
|||
<span v-else-if="showCreatedBy">
|
||||
<gl-sprintf :message="messageWithCreatedBy">
|
||||
<template #group>
|
||||
<a v-gl-tooltip.hover="$options.i18n.inherited" :href="memberSource.webUrl">{{
|
||||
<a v-gl-tooltip.hover="tooltipHover" :href="memberSource.webUrl">{{
|
||||
memberSource.fullName
|
||||
}}</a>
|
||||
</template>
|
||||
|
|
@ -70,7 +76,7 @@ export default {
|
|||
</gl-sprintf>
|
||||
</span>
|
||||
<span v-else-if="isDirectMember">{{ $options.i18n.directMember }}</span>
|
||||
<a v-else v-gl-tooltip.hover="$options.i18n.inherited" :href="memberSource.webUrl">{{
|
||||
<a v-else v-gl-tooltip.hover="tooltipHover" :href="memberSource.webUrl">{{
|
||||
memberSource.fullName
|
||||
}}</a>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -173,8 +173,7 @@ module Import
|
|||
.new(project)
|
||||
.write(
|
||||
timeout_strategy: params[:timeout_strategy] || ProjectImportData::PESSIMISTIC_TIMEOUT,
|
||||
optional_stages: params[:optional_stages],
|
||||
extended_events: Feature.enabled?(:github_import_extended_events, current_user)
|
||||
optional_stages: params[:optional_stages]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,12 +25,8 @@ module Gitlab
|
|||
base_data: Stage::ImportBaseDataWorker,
|
||||
pull_requests: Stage::ImportPullRequestsWorker,
|
||||
collaborators: Stage::ImportCollaboratorsWorker,
|
||||
pull_requests_merged_by: Stage::ImportPullRequestsMergedByWorker, # Skipped on extended_events
|
||||
pull_request_review_requests: Stage::ImportPullRequestsReviewRequestsWorker, # Skipped on extended_events
|
||||
pull_request_reviews: Stage::ImportPullRequestsReviewsWorker, # Skipped on extended_events
|
||||
issues_and_diff_notes: Stage::ImportIssuesAndDiffNotesWorker,
|
||||
issue_events: Stage::ImportIssueEventsWorker,
|
||||
notes: Stage::ImportNotesWorker, # Skipped on extended_events
|
||||
attachments: Stage::ImportAttachmentsWorker,
|
||||
protected_branches: Stage::ImportProtectedBranchesWorker,
|
||||
lfs_objects: Stage::ImportLfsObjectsWorker,
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def increment_object_counter(object, project)
|
||||
counter_type = importer_class::EVENT_COUNTER_MAP[object[:event]] if import_settings.extended_events?
|
||||
counter_type ||= object_type
|
||||
counter_type = importer_class::EVENT_COUNTER_MAP[object[:event]] || object_type
|
||||
Gitlab::GithubImport::ObjectCounter.increment(project, counter_type, :imported)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -42,15 +42,9 @@ module Gitlab
|
|||
|
||||
def move_to_next_stage(project, waiters = {})
|
||||
AdvanceStageWorker.perform_async(
|
||||
project.id, waiters.deep_stringify_keys, next_stage(project)
|
||||
project.id, waiters.deep_stringify_keys, 'issues_and_diff_notes'
|
||||
)
|
||||
end
|
||||
|
||||
def next_stage(project)
|
||||
return 'issues_and_diff_notes' if import_settings(project).extended_events?
|
||||
|
||||
'pull_requests_merged_by'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,36 +15,11 @@ module Gitlab
|
|||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
return skip_to_next_stage(project) if skip_to_next_stage?(project)
|
||||
|
||||
importer = ::Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter
|
||||
info(project.id, message: "starting importer", importer: importer.name)
|
||||
waiter = importer.new(project, client).execute
|
||||
move_to_next_stage(project, { waiter.key => waiter.jobs_remaining })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def skip_to_next_stage?(project)
|
||||
# This stage is mandatory when using extended_events
|
||||
return false if import_settings(project).extended_events?
|
||||
|
||||
import_settings(project).disabled?(:single_endpoint_issue_events_import)
|
||||
end
|
||||
|
||||
def skip_to_next_stage(project)
|
||||
info(project.id, message: "skipping importer", importer: "IssueEventsImporter")
|
||||
move_to_next_stage(project)
|
||||
end
|
||||
|
||||
def move_to_next_stage(project, waiters = {})
|
||||
AdvanceStageWorker.perform_async(project.id, waiters.deep_stringify_keys, next_stage(project))
|
||||
end
|
||||
|
||||
def next_stage(project)
|
||||
return "attachments" if import_settings(project).extended_events?
|
||||
|
||||
"notes"
|
||||
AdvanceStageWorker.perform_async(project.id, { waiter.key => waiter.jobs_remaining }, 'attachments')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,32 +10,7 @@ module Gitlab
|
|||
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
waiters = importers(project).each_with_object({}) do |klass, hash|
|
||||
info(project.id, message: "starting importer", importer: klass.name)
|
||||
waiter = klass.new(project, client).execute
|
||||
hash[waiter.key] = waiter.jobs_remaining
|
||||
end
|
||||
|
||||
AdvanceStageWorker.perform_async(project.id, waiters.deep_stringify_keys, 'attachments')
|
||||
end
|
||||
|
||||
def importers(project)
|
||||
if import_settings(project).enabled?(:single_endpoint_notes_import)
|
||||
[
|
||||
Importer::SingleEndpointMergeRequestNotesImporter,
|
||||
Importer::SingleEndpointIssueNotesImporter
|
||||
]
|
||||
else
|
||||
[
|
||||
Importer::NotesImporter
|
||||
]
|
||||
end
|
||||
end
|
||||
def perform(_project_id); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,21 +10,7 @@ module Gitlab
|
|||
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
waiter = Importer::PullRequests::AllMergedByImporter
|
||||
.new(project, client)
|
||||
.execute
|
||||
|
||||
AdvanceStageWorker.perform_async(
|
||||
project.id,
|
||||
{ waiter.key => waiter.jobs_remaining },
|
||||
'pull_request_review_requests'
|
||||
)
|
||||
end
|
||||
def perform(_project_id); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,21 +10,7 @@ module Gitlab
|
|||
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
waiter = Importer::PullRequests::ReviewRequestsImporter
|
||||
.new(project, client)
|
||||
.execute
|
||||
|
||||
AdvanceStageWorker.perform_async(
|
||||
project.id,
|
||||
{ waiter.key => waiter.jobs_remaining },
|
||||
'pull_request_reviews'
|
||||
)
|
||||
end
|
||||
def perform(project_id); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,21 +10,7 @@ module Gitlab
|
|||
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
waiter = Importer::PullRequests::ReviewsImporter
|
||||
.new(project, client)
|
||||
.execute
|
||||
|
||||
AdvanceStageWorker.perform_async(
|
||||
project.id,
|
||||
{ waiter.key => waiter.jobs_remaining },
|
||||
'issues_and_diff_notes'
|
||||
)
|
||||
end
|
||||
def perform(_project_id); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: github_import_extended_events
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139410
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/435089
|
||||
milestone: '16.8'
|
||||
type: development
|
||||
group: group::import and integrate
|
||||
default_enabled: true
|
||||
|
|
@ -5,4 +5,5 @@ Rails.backtrace_cleaner.remove_silencers!
|
|||
# This allows us to see the proper caller of SQL calls in {development,test}.log
|
||||
if Rails.env.development? || Rails.env.test?
|
||||
Rails.backtrace_cleaner.add_silencer { |line| %r{^lib/gitlab/database/load_balancing}.match?(line) }
|
||||
ActiveRecord::LogSubscriber.backtrace_cleaner = Gitlab::BacktraceCleaner.backtrace_cleaner
|
||||
end
|
||||
|
|
|
|||
|
|
@ -168,6 +168,12 @@ class Gitlab::Seeder::Projects
|
|||
end
|
||||
|
||||
project_path.gsub!(".git", "")
|
||||
project = Project.find_by_name(project_path.titleize)
|
||||
|
||||
if project
|
||||
puts "Project #{project.full_path} already exists, skipping"
|
||||
return
|
||||
end
|
||||
|
||||
params = {
|
||||
import_url: url,
|
||||
|
|
@ -182,8 +188,6 @@ class Gitlab::Seeder::Projects
|
|||
params[:storage_version] = Project::LATEST_STORAGE_VERSION
|
||||
end
|
||||
|
||||
project = nil
|
||||
|
||||
Gitlab::ExclusiveLease.skipping_transaction_check do
|
||||
Sidekiq::Worker.skipping_transaction_check do
|
||||
project = ::Projects::CreateService.new(User.first, params).execute
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require './db/fixtures/development/03_project'
|
||||
|
||||
class Gitlab::Seeder::UserProjects
|
||||
def seed!
|
||||
create_user_projects!
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require './db/fixtures/development/03_project'
|
||||
|
||||
class Gitlab::Seeder::GroupProjects
|
||||
def seed!
|
||||
create_projects!
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ Use the Import API to import repositories from GitHub or Bitbucket Server.
|
|||
> - `collaborators_import` key in `optional_stages` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398154) in GitLab 16.0.
|
||||
> - Feature flag `github_import_extended_events` was introduced in GitLab 16.8. Disabled by default. This flag improves the performance of imports but disables the `single_endpoint_issue_events_import` optional stage.
|
||||
> - Feature flag `github_import_extended_events` was [enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/435089) in GitLab 16.9.
|
||||
> - Improved import performance made [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/435089) in GitLab 16.11. Feature flag `github_import_extended_events` removed.
|
||||
|
||||
Import your projects from GitHub to GitLab using the API.
|
||||
|
||||
|
|
@ -54,7 +55,6 @@ curl --request POST \
|
|||
"new_name": "NEW-NAME",
|
||||
"github_hostname": "https://github.example.com",
|
||||
"optional_stages": {
|
||||
"single_endpoint_issue_events_import": true,
|
||||
"single_endpoint_notes_import": true,
|
||||
"attachments_import": true,
|
||||
"collaborators_import": true
|
||||
|
|
@ -64,8 +64,7 @@ curl --request POST \
|
|||
|
||||
The following keys are available for `optional_stages`:
|
||||
|
||||
- `single_endpoint_issue_events_import`, for issue and pull request events import. If the `github_import_extended_events` feature flag is enabled, this optional stage
|
||||
is unavailable.
|
||||
- `single_endpoint_issue_events_import`, for issue and pull request events import. This optional stage was removed in GitLab 16.9.
|
||||
- `single_endpoint_notes_import`, for an alternative and more thorough comments import.
|
||||
- `attachments_import`, for Markdown attachments import.
|
||||
- `collaborators_import`, for importing direct repository collaborators who are not outside collaborators.
|
||||
|
|
|
|||
|
|
@ -114,6 +114,12 @@ Example response:
|
|||
|
||||
## List all members of a group or project including inherited and invited members
|
||||
|
||||
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) to return members of the invited private group if the current user is a member of the shared group or project in GitLab 16.10 [with a flag](../administration/feature_flags.md) named `webui_members_inherited_users`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available per user, an administrator can [enable the feature flag](../administration/feature_flags.md) named `webui_members_inherited_users`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is not available.
|
||||
|
||||
Gets a list of group or project members viewable by the authenticated user, including inherited members, invited users, and permissions through ancestor groups.
|
||||
|
||||
If a user is a member of this group or project and also of one or more ancestor groups,
|
||||
|
|
@ -125,6 +131,12 @@ Members from an invited group are returned if either:
|
|||
|
||||
- The invited group is public.
|
||||
- The requester is also a member of the invited group.
|
||||
- The requester is a member of the shared group or project.
|
||||
|
||||
NOTE:
|
||||
The invited group members have shared membership in the shared group or project.
|
||||
This means that if the requester is a member of a shared group or project, but not a member of an invited private group,
|
||||
then using this endpoint the requester can get all the shared group or project members, including the invited private group members.
|
||||
|
||||
This function takes pagination parameters `page` and `per_page` to restrict the list of users.
|
||||
|
||||
|
|
@ -266,9 +278,19 @@ Example response:
|
|||
## Get a member of a group or project, including inherited and invited members
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17744) in GitLab 12.4.
|
||||
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) to return members of the invited private group if the current user is a member of the shared group or project in GitLab 16.10 [with a flag](../administration/feature_flags.md) named `webui_members_inherited_users`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available per user, an administrator can [enable the feature flag](../administration/feature_flags.md) named `webui_members_inherited_users`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is not available.
|
||||
|
||||
Gets a member of a group or project, including members inherited or invited through ancestor groups. See the corresponding [endpoint to list all inherited members](#list-all-members-of-a-group-or-project-including-inherited-and-invited-members) for details.
|
||||
|
||||
NOTE:
|
||||
The invited group members have shared membership in the shared group or project.
|
||||
This means that if the requester is a member of a shared group or project, but not a member of an invited private group,
|
||||
then using this endpoint the requester can get all the shared group or project members, including the invited private group members.
|
||||
|
||||
```plaintext
|
||||
GET /groups/:id/members/all/:user_id
|
||||
GET /projects/:id/members/all/:user_id
|
||||
|
|
|
|||
|
|
@ -95,43 +95,7 @@ For every collaborator, we schedule a job for the `Gitlab::GithubImport::ImportC
|
|||
NOTE:
|
||||
This stage is optional (controlled by `Gitlab::GithubImport::Settings`) and is selected by default.
|
||||
|
||||
### 6. Stage::ImportPullRequestsMergedByWorker (deprecated)
|
||||
|
||||
This worker imports the pull requests' _merged-by_ user information. The
|
||||
[_List pull requests_](https://docs.github.com/en/rest/pulls#list-pull-requests)
|
||||
API doesn't provide this information. Therefore, this stage must fetch each merged pull request
|
||||
individually to import this information. A
|
||||
`Gitlab::GithubImport::PullRequests::ImportMergedByWorker` job is scheduled for each fetched pull
|
||||
request.
|
||||
|
||||
NOTE:
|
||||
This stage is skipped when `github_import_extended_events` feature flag is enabled as pull requests merged by information
|
||||
is imported in the `10. Stage::ImportIssueEventsWorker` stage. This stage will be removed along with the feature flag.
|
||||
|
||||
### 7. Stage::ImportPullRequestsReviewRequestsWorker (deprecated)
|
||||
|
||||
This worker imports assigned reviewers of pull requests. For each pull request, this worker:
|
||||
|
||||
- Fetches all assigned review requests.
|
||||
- Schedules a `Gitlab::GithubImport::PullRequests::ImportReviewRequestWorker` job for each fetched review request.
|
||||
|
||||
NOTE:
|
||||
This stage is skipped when `github_import_extended_events` feature flag is enabled as pull requests review requests
|
||||
information is imported in the `10. Stage::ImportIssueEventsWorker` stage. This stage will be removed along with the
|
||||
feature flag.
|
||||
|
||||
### 8. Stage::ImportPullRequestsReviewsWorker (deprecated)
|
||||
|
||||
This worker imports reviews of pull requests. For each pull request, this worker:
|
||||
|
||||
- Fetches all the pages of reviews.
|
||||
- Schedules a `Gitlab::GithubImport::PullRequests::ImportReviewWorker` job for each fetched review.
|
||||
|
||||
NOTE:
|
||||
This stage is skipped when `github_import_extended_events` feature flag is enabled as pull requests reviews information
|
||||
is imported in the`10. Stage::ImportIssueEventsWorker` stage. This stage will be removed along with the feature flag.
|
||||
|
||||
### 9. Stage::ImportIssuesAndDiffNotesWorker
|
||||
### 6. Stage::ImportIssuesAndDiffNotesWorker
|
||||
|
||||
This worker imports all issues and pull request comments. For every issue, we
|
||||
schedule a job for the `Gitlab::GithubImport::ImportIssueWorker` worker. For
|
||||
|
|
@ -147,7 +111,7 @@ label links in the same worker removes the need for performing a separate crawl
|
|||
through the API data, reducing the number of API calls necessary to import a
|
||||
project.
|
||||
|
||||
### 10. Stage::ImportIssueEventsWorker
|
||||
### 7. Stage::ImportIssueEventsWorker
|
||||
|
||||
This worker imports all issues and pull request events. For every event, we
|
||||
schedule a job for the `Gitlab::GithubImport::ImportIssueEventWorker` worker.
|
||||
|
|
@ -160,36 +124,12 @@ GitHub are stored in a single table. Therefore, they have globally-unique IDs an
|
|||
|
||||
Therefore, both issues and pull requests have a common API for most related things.
|
||||
|
||||
When the feature flag `github_import_extended_events` is enabled, this stage is used to import
|
||||
`pull request merged by`, `pull request reviews`, `pull request review requests` and `notes`. This is possible because
|
||||
[timeline events endpoint](https://docs.github.com/en/rest/issues/timeline?apiVersion=2022-11-28#list-timeline-events-for-an-issue)
|
||||
also contains such information.
|
||||
|
||||
To facilitate the import of `pull request review requests` using the timeline events endpoint,
|
||||
events must be processed sequentially. Given that import workers do not execute in a guaranteed order,
|
||||
the `pull request review requests` events are initially placed in a Redis ordered list. Subsequently, they are consumed
|
||||
in sequence by the `Gitlab::GithubImport::ReplayEventsWorker`.
|
||||
|
||||
NOTE:
|
||||
This stage is mandatory when `github_import_extended_events` feature flag is enabled. Otherwise the stage is optional
|
||||
and can executed using the [import options](../user/project/import/github.md#select-additional-items-to-import).
|
||||
|
||||
### 11. Stage::ImportNotesWorker (deprecated)
|
||||
|
||||
This worker imports regular comments for both issues and pull requests. For
|
||||
every comment, we schedule a job for the
|
||||
`Gitlab::GithubImport::ImportNoteWorker` worker.
|
||||
|
||||
Regular comments have to be imported at the end because the GitHub API used
|
||||
returns comments for both issues and pull requests. This means we have to wait
|
||||
for all issues and pull requests to be imported before we can import regular
|
||||
comments.
|
||||
|
||||
NOTE:
|
||||
This stage is skipped when `github_import_extended_events` feature flag is enabled as notes are imported in the
|
||||
`10. Stage::ImportIssueEventsWorker` stage. This stage will be removed along with the feature flag.
|
||||
|
||||
### 12. Stage::ImportAttachmentsWorker
|
||||
### 8. Stage::ImportAttachmentsWorker
|
||||
|
||||
This worker imports note attachments that are linked inside Markdown.
|
||||
For each entity with Markdown text in the project, we schedule a job of:
|
||||
|
|
@ -208,7 +148,7 @@ Each job:
|
|||
NOTE:
|
||||
It's an optional stage that could consume significant extra import time (controlled by `Gitlab::GithubImport::Settings`).
|
||||
|
||||
### 13. Stage::ImportProtectedBranchesWorker
|
||||
### 9. Stage::ImportProtectedBranchesWorker
|
||||
|
||||
This worker imports protected branch rules.
|
||||
For every rule that exists on GitHub, we schedule a job of
|
||||
|
|
@ -217,7 +157,7 @@ For every rule that exists on GitHub, we schedule a job of
|
|||
Each job compares the branch protection rules from GitHub and GitLab and applies
|
||||
the strictest of the rules to the branches in GitLab.
|
||||
|
||||
### 14. Stage::FinishImportWorker
|
||||
### 10. Stage::FinishImportWorker
|
||||
|
||||
This worker completes the import process by performing some housekeeping
|
||||
(such as flushing any caches) and by marking the import as completed.
|
||||
|
|
|
|||
|
|
@ -120,6 +120,12 @@ For more information, view the [permissions table](../../permissions.md#group-me
|
|||
|
||||
## Subgroup membership
|
||||
|
||||
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) to display invited group members on the Members tab of the Members page in GitLab 16.10 [with a flag](../../../administration/feature_flags.md) named `webui_members_inherited_users`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available per user, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `webui_members_inherited_users`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is not available.
|
||||
|
||||
When you add a member to a group, that member is also added to all subgroups of that group.
|
||||
The member's permissions are inherited from the group into all subgroups.
|
||||
|
||||
|
|
@ -128,6 +134,7 @@ Subgroup members can be:
|
|||
1. [Direct members](../../project/members/index.md#add-users-to-a-project) of the subgroup.
|
||||
1. [Inherited members](../../project/members/index.md#inherited-membership) of the subgroup from the subgroup's parent group.
|
||||
1. Members of a group that was [shared with the subgroup's top-level group](../manage.md#share-a-group-with-another-group).
|
||||
1. [Indirect members](../../project/members/index.md#indirect-membership) include [inherited members](../../project/members/index.md#inherited-membership) and members of a group that was [invited to the subgroup or its ancestors](../manage.md#share-a-group-with-another-group).
|
||||
|
||||
```mermaid
|
||||
flowchart RL
|
||||
|
|
|
|||
|
|
@ -176,17 +176,16 @@ When the **Organization** tab is selected, you can further narrow down your sear
|
|||
> - Importing collaborators as an additional item was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398154) in GitLab 16.0.
|
||||
> - Feature flag `github_import_extended_events` was introduced in GitLab 16.8. Disabled by default. This flag improves the performance of imports but removes the **Import issue and pull request events** option.
|
||||
> - Feature flag `github_import_extended_events` was [enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/435089) in GitLab 16.9.
|
||||
> - Improved import performance made [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/435089) in GitLab 16.11. Feature flag `github_import_extended_events` removed.
|
||||
|
||||
To make imports as fast as possible, the following items aren't imported from GitHub by default:
|
||||
|
||||
- Issue and pull request events. For example, _opened_ or _closed_, _renamed_, and _labeled_ or _unlabeled_.
|
||||
- More than approximately 30,000 comments because of a [limitation of the GitHub API](#missing-comments).
|
||||
- Markdown attachments from repository comments, release posts, issue descriptions, and pull request descriptions. These can include
|
||||
images, text, or binary attachments. If not imported, links in Markdown to attachments break after you remove the attachments from GitHub.
|
||||
|
||||
You can choose to import these items, but this could significantly increase import time. To import these items, select the appropriate fields in the UI:
|
||||
|
||||
- **Import issue and pull request events**. If the `github_import_extended_events` feature flag is enabled, this option is unavailable.
|
||||
- **Use alternative comments import method**. If importing GitHub projects with more than approximately 30,000 comments across all issues and pull requests, you should enable this method because of a
|
||||
[limitation of the GitHub API](#missing-comments).
|
||||
- **Import Markdown attachments**.
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
|
|
@ -16,6 +16,12 @@ Each member gets a role, which determines what they can do in the project.
|
|||
|
||||
## Membership types
|
||||
|
||||
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) to display invited group members on the Members tab of the Members page in GitLab 16.10 behind `webui_members_inherited_users` feature flag. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available per user, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `webui_members_inherited_users`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is not available.
|
||||
|
||||
Users can become members of a group or project in different ways, which define their membership type.
|
||||
|
||||
| Membership type | Membership process |
|
||||
|
|
@ -24,6 +30,7 @@ Users can become members of a group or project in different ways, which define t
|
|||
| [Inherited](#inherited-membership) | The user is a member of a parent group that contains the current group or project. |
|
||||
| [Direct shared](share_project_with_groups.md) | The user is a member of a group or project that is shared into the current group or project. |
|
||||
| [Inherited shared](../../group/manage.md#share-a-group-with-another-group) | The user is a member of a parent of a group or project that is shared into the current group or project. |
|
||||
| [Indirect](#indirect-membership) | The user is not directly added to the current group or project. Instead, they gain membership to the group or project through either inheritance from a parent group, or through sharing the current group or project with another group. |
|
||||
|
||||
```mermaid
|
||||
flowchart RL
|
||||
|
|
@ -128,6 +135,29 @@ If a user is:
|
|||
- A direct member of a project, the **Expiration** and **Max role** fields can be updated directly on the project.
|
||||
- An inherited member from a parent group, the **Expiration** and **Max role** fields must be updated on the parent group that the member originates from.
|
||||
|
||||
## Indirect membership
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/444476) in GitLab 16.10 [with a flag](../../feature_flags.md) named `webui_members_inherited_users`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available per user, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `webui_members_inherited_users`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is not available.
|
||||
|
||||
If your project belongs to a group, the users gain membership to the project through either inheritance from a parent group or through sharing the project or the project's parent group with another group.
|
||||
|
||||

|
||||
|
||||
In this example:
|
||||
|
||||
- Three members have access to the project.
|
||||
- **User 0** and **User 1** have the Guest role in the project. They have indirect membership through **Twitter** group, which contains the project.
|
||||
- **Administrator** is the [Owner](../../permissions.md) of the group.
|
||||
|
||||
If a user is:
|
||||
|
||||
- A direct member of a project, the **Expiration** and **Max role** fields can be updated directly in the project.
|
||||
- An indirect member from a parent group or shared group, the **Expiration** and **Max role** fields must be updated in the group that the member originates from.
|
||||
|
||||
## Add groups to a project
|
||||
|
||||
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 13.11 from a form to a modal window [with a flag](../../feature_flags.md). Disabled by default.
|
||||
|
|
|
|||
|
|
@ -15,6 +15,15 @@ You can share by invitation:
|
|||
- [A project with a group](share_project_with_groups.md).
|
||||
- [A group with another group](../../group/manage.md#share-a-group-with-another-group).
|
||||
|
||||
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) to display invited group members on the Members tab of the Members page in GitLab 16.10 behind `webui_members_inherited_users` feature flag. Disabled by default.
|
||||
|
||||
[In GitLab 16.6 and later](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134623),
|
||||
the invited group's name and membership source are masked unless one of the following applies:
|
||||
|
||||
- The invited group is public.
|
||||
- The current user is a member of the invited group.
|
||||
- The current user is an owner of the current group or the maintainer/owner of the current project.
|
||||
|
||||
## Sharing a project with a group
|
||||
|
||||
When you want a group to have access to your project,
|
||||
|
|
@ -48,13 +57,6 @@ If the project's top-level group [does not allow the project to be shared outsid
|
|||
|
||||
If a group in the project's hierarchy [does not allow projects to be shared with groups](../../group/access_and_permissions.md#prevent-a-project-from-being-shared-with-groups), the option to **Invite a group** is not available.
|
||||
|
||||
[In GitLab 16.6 and later](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134623),
|
||||
the invited group's name and membership source are masked unless one of the following applies:
|
||||
|
||||
- The invited group is public.
|
||||
- The current user is a member of the invited group.
|
||||
- The current user is a member of the current group.
|
||||
|
||||
### Member access and roles
|
||||
|
||||
When you share a project, the following members get access to the project:
|
||||
|
|
@ -66,10 +68,16 @@ When you share a project, the following members get access to the project:
|
|||
In addition:
|
||||
|
||||
- On the group's page, the project is listed on the **Shared projects** tab.
|
||||
- On the project's **Members** page, the group is listed on the **Groups** tab.
|
||||
- On the project's **Members** page, the group is listed on the **Groups** tab. This list includes both public and private groups.
|
||||
- On the project's **Members** page, the members of the invited group are listed on the **Members** tab.
|
||||
- Each user is assigned a maximum role.
|
||||
- On the usage quota page, members who have the **Project Invite** badge next to their profile count towards the billable members of the shared project's top-level group.
|
||||
|
||||
NOTE:
|
||||
The invited group's name and membership source are masked from members who do not have access to the invited group.
|
||||
However, even if project maintainers and owners cannot access the private invited group, they can see the source of private invited group members.
|
||||
This behavior is intended to help project maintainers and owners to better manage the memberships of the projects they own.
|
||||
|
||||
### Examples
|
||||
|
||||
A project in the namespace `group/subgroup01/project`:
|
||||
|
|
@ -87,13 +95,19 @@ For a project that was created by `Group 1`:
|
|||
|
||||
After you invite a group to your group:
|
||||
|
||||
- The **Groups** tab lists the invited group. This list includes both public and private groups. The invited group's name and membership source are masked from members who do not have access to the invited group.
|
||||
- The **Groups** tab of the group's **Members** page lists the invited group. This list includes both public and private groups.
|
||||
- The **Members** tab of the group's **Members** page lists the members of the invited group.
|
||||
- All direct members of the invited group have access to the inviting group.
|
||||
The least access is granted between the access in the invited group and the access in the inviting group.
|
||||
- Inherited members of the invited group do not gain access to the inviting group.
|
||||
- On the group's usage quota page, direct members of the invited group who have the **Group Invite** badge
|
||||
next to their profile count towards the billable members of the inviting group.
|
||||
|
||||
NOTE:
|
||||
The invited group's name and membership source are masked from members who do not have access to the invited group.
|
||||
However, even if group owners cannot access the private invited group, they can see the source of private invited group members.
|
||||
This behavior is intended to help group owners to better manage the memberships of the groups they own.
|
||||
|
||||
### Examples
|
||||
|
||||
`User A` is a direct member of `Group 1` and has the Maintainer role in the group.
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ module Gitlab
|
|||
module Events
|
||||
class Commented < BaseImporter
|
||||
def execute(issue_event)
|
||||
return true unless import_settings.extended_events?
|
||||
|
||||
note = Representation::Note.from_json_hash(
|
||||
noteable_id: issue_event.issuable_id,
|
||||
noteable_type: issue_event.issuable_type,
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ module Gitlab
|
|||
module Events
|
||||
class Merged < BaseImporter
|
||||
def execute(issue_event)
|
||||
create_note(issue_event) if import_settings.extended_events?
|
||||
|
||||
create_note(issue_event)
|
||||
create_event(issue_event)
|
||||
create_state_event(issue_event)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ module Gitlab
|
|||
module Events
|
||||
class Reviewed < BaseImporter
|
||||
def execute(issue_event)
|
||||
return true unless import_settings.extended_events?
|
||||
|
||||
review = Representation::PullRequestReview.from_json_hash(
|
||||
merge_request_iid: issue_event.issuable_id,
|
||||
author: issue_event.actor&.to_hash,
|
||||
|
|
|
|||
|
|
@ -20,9 +20,6 @@ module Gitlab
|
|||
review_requested
|
||||
unassigned
|
||||
unlabeled
|
||||
].freeze
|
||||
|
||||
EXTENDED_SUPPORTED_EVENTS = SUPPORTED_EVENTS + %w[
|
||||
commented
|
||||
reviewed
|
||||
].freeze
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module GithubImport
|
||||
module Importer
|
||||
class IssueEventsImporter
|
||||
include ParallelScheduling
|
||||
|
||||
def importer_class
|
||||
IssueEventImporter
|
||||
end
|
||||
|
||||
def representation_class
|
||||
Representation::IssueEvent
|
||||
end
|
||||
|
||||
def sidekiq_worker_class
|
||||
ImportIssueEventWorker
|
||||
end
|
||||
|
||||
def object_type
|
||||
:issue_event
|
||||
end
|
||||
|
||||
def collection_method
|
||||
:repository_issue_events
|
||||
end
|
||||
|
||||
def id_for_already_imported_cache(event)
|
||||
event[:id]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module GithubImport
|
||||
module Importer
|
||||
module PullRequests
|
||||
class AllMergedByImporter
|
||||
include ParallelScheduling
|
||||
|
||||
def importer_class
|
||||
MergedByImporter
|
||||
end
|
||||
|
||||
def representation_class
|
||||
Gitlab::GithubImport::Representation::PullRequest
|
||||
end
|
||||
|
||||
def sidekiq_worker_class
|
||||
Gitlab::GithubImport::PullRequests::ImportMergedByWorker
|
||||
end
|
||||
|
||||
def collection_method
|
||||
:pull_requests_merged_by
|
||||
end
|
||||
|
||||
def object_type
|
||||
:pull_request_merged_by
|
||||
end
|
||||
|
||||
def id_for_already_imported_cache(merge_request)
|
||||
merge_request.id
|
||||
end
|
||||
|
||||
def each_object_to_import
|
||||
merge_requests_to_import.find_each do |merge_request|
|
||||
Gitlab::GithubImport::ObjectCounter.increment(project, object_type, :fetched)
|
||||
|
||||
pull_request = client.pull_request(project.import_source, merge_request.iid)
|
||||
yield(pull_request)
|
||||
|
||||
mark_as_imported(merge_request)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Returns only the merge requests that still have merged_by to be imported.
|
||||
def merge_requests_to_import
|
||||
project.merge_requests.id_not_in(already_imported_objects).with_state(:merged)
|
||||
end
|
||||
|
||||
def already_imported_objects
|
||||
Gitlab::Cache::Import::Caching.values_from_set(already_imported_cache_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module GithubImport
|
||||
module Importer
|
||||
module PullRequests
|
||||
class ReviewRequestsImporter
|
||||
include ParallelScheduling
|
||||
|
||||
BATCH_SIZE = 100
|
||||
|
||||
private
|
||||
|
||||
def each_object_to_import(&block)
|
||||
merge_request_collection.each_batch(of: BATCH_SIZE, column: :iid) do |batch|
|
||||
batch.each do |merge_request|
|
||||
repo = project.import_source
|
||||
|
||||
review_requests = client.pull_request_review_requests(repo, merge_request.iid)
|
||||
review_requests[:merge_request_id] = merge_request.id
|
||||
review_requests[:merge_request_iid] = merge_request.iid
|
||||
|
||||
Gitlab::GithubImport::ObjectCounter.increment(project, object_type, :fetched)
|
||||
|
||||
yield review_requests
|
||||
|
||||
mark_merge_request_imported(merge_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def importer_class
|
||||
ReviewRequestImporter
|
||||
end
|
||||
|
||||
def representation_class
|
||||
Gitlab::GithubImport::Representation::PullRequests::ReviewRequests
|
||||
end
|
||||
|
||||
def sidekiq_worker_class
|
||||
Gitlab::GithubImport::PullRequests::ImportReviewRequestWorker
|
||||
end
|
||||
|
||||
def collection_method
|
||||
:pull_request_review_requests
|
||||
end
|
||||
|
||||
def object_type
|
||||
:pull_request_review_request
|
||||
end
|
||||
|
||||
# rubocop:disable CodeReuse/ActiveRecord
|
||||
def merge_request_collection
|
||||
project.merge_requests
|
||||
.where.not(iid: already_imported_merge_requests)
|
||||
.select(:id, :iid)
|
||||
end
|
||||
# rubocop:enable CodeReuse/ActiveRecord
|
||||
|
||||
def merge_request_imported_cache_key
|
||||
"github-importer/pull_requests/#{collection_method}/already-imported/#{project.id}"
|
||||
end
|
||||
|
||||
def already_imported_merge_requests
|
||||
Gitlab::Cache::Import::Caching.values_from_set(merge_request_imported_cache_key)
|
||||
end
|
||||
|
||||
def mark_merge_request_imported(merge_request)
|
||||
Gitlab::Cache::Import::Caching.set_add(
|
||||
merge_request_imported_cache_key,
|
||||
merge_request.iid
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module GithubImport
|
||||
module Importer
|
||||
module PullRequests
|
||||
class ReviewsImporter
|
||||
include ParallelScheduling
|
||||
|
||||
def initialize(...)
|
||||
super
|
||||
|
||||
@merge_requests_already_imported_cache_key =
|
||||
"github-importer/merge_request/already-imported/#{project.id}"
|
||||
end
|
||||
|
||||
def importer_class
|
||||
ReviewImporter
|
||||
end
|
||||
|
||||
def representation_class
|
||||
Gitlab::GithubImport::Representation::PullRequestReview
|
||||
end
|
||||
|
||||
def sidekiq_worker_class
|
||||
Gitlab::GithubImport::PullRequests::ImportReviewWorker
|
||||
end
|
||||
|
||||
def collection_method
|
||||
:pull_request_reviews
|
||||
end
|
||||
|
||||
def object_type
|
||||
:pull_request_review
|
||||
end
|
||||
|
||||
def id_for_already_imported_cache(review)
|
||||
review[:id]
|
||||
end
|
||||
|
||||
# The worker can be interrupted, by rate limit for instance,
|
||||
# in different situations. To avoid requesting already imported data,
|
||||
# if the worker is interrupted:
|
||||
# - before importing all reviews of a merge request
|
||||
# The reviews page is cached with the `PageCounter`, by merge request.
|
||||
# - before importing all merge requests reviews
|
||||
# Merge requests that had all the reviews imported are cached with
|
||||
# `mark_merge_request_reviews_imported`
|
||||
def each_object_to_import(&_block)
|
||||
each_review_page do |page, merge_request|
|
||||
page.objects.each do |review|
|
||||
review = review.to_h
|
||||
|
||||
next if already_imported?(review)
|
||||
|
||||
Gitlab::GithubImport::ObjectCounter.increment(project, object_type, :fetched)
|
||||
|
||||
review[:merge_request_id] = merge_request.id
|
||||
review[:merge_request_iid] = merge_request.iid
|
||||
yield(review)
|
||||
|
||||
mark_as_imported(review)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :merge_requests_already_imported_cache_key
|
||||
|
||||
def each_review_page
|
||||
merge_requests_to_import.find_each do |merge_request|
|
||||
# The page counter needs to be scoped by merge request to avoid skipping
|
||||
# pages of reviews from already imported merge requests.
|
||||
page_counter = Gitlab::Import::PageCounter.new(project, page_counter_id(merge_request))
|
||||
repo = project.import_source
|
||||
options = collection_options.merge(page: page_counter.current)
|
||||
|
||||
client.each_page(collection_method, repo, merge_request.iid, options) do |page|
|
||||
next unless page_counter.set(page.number)
|
||||
|
||||
yield(page, merge_request)
|
||||
end
|
||||
|
||||
# Avoid unnecessary Redis cache keys after the work is done.
|
||||
page_counter.expire!
|
||||
mark_merge_request_reviews_imported(merge_request)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns only the merge requests that still have reviews to be imported.
|
||||
def merge_requests_to_import
|
||||
project.merge_requests.id_not_in(already_imported_merge_requests)
|
||||
end
|
||||
|
||||
def already_imported_merge_requests
|
||||
Gitlab::Cache::Import::Caching.values_from_set(merge_requests_already_imported_cache_key)
|
||||
end
|
||||
|
||||
def page_counter_id(merge_request)
|
||||
"merge_request/#{merge_request.id}/#{collection_method}"
|
||||
end
|
||||
|
||||
def mark_merge_request_reviews_imported(merge_request)
|
||||
Gitlab::Cache::Import::Caching.set_add(
|
||||
merge_requests_already_imported_cache_key,
|
||||
merge_request.id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -30,7 +30,7 @@ module Gitlab
|
|||
|
||||
compose_associated_id!(parent_record, associated)
|
||||
|
||||
return if already_imported?(associated) || supported_events.exclude?(associated[:event])
|
||||
return if already_imported?(associated) || importer_class::SUPPORTED_EVENTS.exclude?(associated[:event])
|
||||
|
||||
cache_event(parent_record, associated)
|
||||
|
||||
|
|
@ -67,8 +67,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def increment_object_counter(event_name)
|
||||
counter_type = importer_class::EVENT_COUNTER_MAP[event_name] if import_settings.extended_events?
|
||||
counter_type ||= object_type
|
||||
counter_type = importer_class::EVENT_COUNTER_MAP[event_name] || object_type
|
||||
Gitlab::GithubImport::ObjectCounter.increment(project, counter_type, :fetched)
|
||||
end
|
||||
|
||||
|
|
@ -112,8 +111,6 @@ module Gitlab
|
|||
end
|
||||
|
||||
def after_batch_processed(parent)
|
||||
return unless import_settings.extended_events?
|
||||
|
||||
events = events_cache.events(parent)
|
||||
|
||||
return if events.empty?
|
||||
|
|
@ -124,15 +121,7 @@ module Gitlab
|
|||
job_waiter.jobs_remaining = Gitlab::Cache::Import::Caching.increment(job_waiter_remaining_cache_key)
|
||||
end
|
||||
|
||||
def supported_events
|
||||
return importer_class::EXTENDED_SUPPORTED_EVENTS if import_settings.extended_events?
|
||||
|
||||
importer_class::SUPPORTED_EVENTS
|
||||
end
|
||||
|
||||
def cache_event(parent_record, associated)
|
||||
return unless import_settings.extended_events?
|
||||
|
||||
return if Importer::ReplayEventsImporter::SUPPORTED_EVENTS.exclude?(associated[:event])
|
||||
|
||||
representation = representation_class.from_api_response(associated)
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This importer is used when `github_importer_single_endpoint_notes_import`
|
||||
# feature flag is on and replaces `IssuesImporter` issue notes import.
|
||||
#
|
||||
# It fetches 1 issue's comments at a time using `issue_comments` endpoint, which is
|
||||
# slower than `NotesImporter` but it makes sure all notes are imported,
|
||||
# as it can sometimes not be the case for `NotesImporter`, because
|
||||
# `issues_comments` endpoint it uses can be limited by GitHub API
|
||||
# to not return all available pages.
|
||||
module Gitlab
|
||||
module GithubImport
|
||||
module Importer
|
||||
class SingleEndpointIssueNotesImporter
|
||||
include ParallelScheduling
|
||||
include SingleEndpointNotesImporting
|
||||
|
||||
def importer_class
|
||||
NoteImporter
|
||||
end
|
||||
|
||||
def representation_class
|
||||
Representation::Note
|
||||
end
|
||||
|
||||
def sidekiq_worker_class
|
||||
ImportNoteWorker
|
||||
end
|
||||
|
||||
def object_type
|
||||
:note
|
||||
end
|
||||
|
||||
def collection_method
|
||||
:issue_comments
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parent_collection
|
||||
project.issues.where.not(iid: already_imported_parents) # rubocop: disable CodeReuse/ActiveRecord
|
||||
end
|
||||
|
||||
def page_counter_id(issue)
|
||||
"issue/#{issue.id}/#{collection_method}"
|
||||
end
|
||||
|
||||
def parent_imported_cache_key
|
||||
"github-importer/issue/notes/already-imported/#{project.id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This importer is used when `github_importer_single_endpoint_notes_import`
|
||||
# feature flag is on and replaces `NotesImporter` MR notes import.
|
||||
#
|
||||
# It fetches 1 PR's comments at a time using `issue_comments` endpoint, which is
|
||||
# slower than `NotesImporter` but it makes sure all notes are imported,
|
||||
# as it can sometimes not be the case for `NotesImporter`, because
|
||||
# `issues_comments` endpoint it uses can be limited by GitHub API
|
||||
# to not return all available pages.
|
||||
module Gitlab
|
||||
module GithubImport
|
||||
module Importer
|
||||
class SingleEndpointMergeRequestNotesImporter
|
||||
include ParallelScheduling
|
||||
include SingleEndpointNotesImporting
|
||||
|
||||
def importer_class
|
||||
NoteImporter
|
||||
end
|
||||
|
||||
def representation_class
|
||||
Representation::Note
|
||||
end
|
||||
|
||||
def sidekiq_worker_class
|
||||
ImportNoteWorker
|
||||
end
|
||||
|
||||
def object_type
|
||||
:note
|
||||
end
|
||||
|
||||
def collection_method
|
||||
:issue_comments
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parent_collection
|
||||
project.merge_requests.where.not(iid: already_imported_parents) # rubocop: disable CodeReuse/ActiveRecord
|
||||
end
|
||||
|
||||
def page_counter_id(merge_request)
|
||||
"merge_request/#{merge_request.id}/#{collection_method}"
|
||||
end
|
||||
|
||||
def parent_imported_cache_key
|
||||
"github-importer/merge_request/notes/already-imported/#{project.id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,14 +4,6 @@ module Gitlab
|
|||
module GithubImport
|
||||
class Settings
|
||||
OPTIONAL_STAGES = {
|
||||
single_endpoint_issue_events_import: {
|
||||
label: 'Import issue and pull request events',
|
||||
selected: false,
|
||||
details: <<-TEXT.split("\n").map(&:strip).join(' ')
|
||||
For example, opened or closed, renamed, and labeled or unlabeled.
|
||||
Time required to import these events depends on how many issues or pull requests your project has.
|
||||
TEXT
|
||||
},
|
||||
single_endpoint_notes_import: {
|
||||
label: 'Use alternative comments import method',
|
||||
selected: false,
|
||||
|
|
@ -38,13 +30,8 @@ module Gitlab
|
|||
}
|
||||
}.freeze
|
||||
|
||||
def self.stages_array(current_user)
|
||||
deprecated_options = %i[single_endpoint_issue_events_import]
|
||||
|
||||
OPTIONAL_STAGES.filter_map do |stage_name, data|
|
||||
next if deprecated_options.include?(stage_name) &&
|
||||
Feature.enabled?(:github_import_extended_events, current_user)
|
||||
|
||||
def self.stages_array(_current_user)
|
||||
OPTIONAL_STAGES.map do |stage_name, data|
|
||||
{
|
||||
name: stage_name.to_s,
|
||||
label: s_(format("GitHubImport|%{text}", text: data[:label])),
|
||||
|
|
@ -66,8 +53,7 @@ module Gitlab
|
|||
import_data = project.build_or_assign_import_data(
|
||||
data: {
|
||||
optional_stages: optional_stages,
|
||||
timeout_strategy: user_settings[:timeout_strategy],
|
||||
extended_events: user_settings[:extended_events]
|
||||
timeout_strategy: user_settings[:timeout_strategy]
|
||||
},
|
||||
credentials: project.import_data&.credentials
|
||||
)
|
||||
|
|
@ -83,10 +69,6 @@ module Gitlab
|
|||
!enabled?(stage_name)
|
||||
end
|
||||
|
||||
def extended_events?
|
||||
!!project.import_data&.data&.dig('extended_events')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :project
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
# This module is used in:
|
||||
# - SingleEndpointDiffNotesImporter
|
||||
# - SingleEndpointIssueNotesImporter
|
||||
# - SingleEndpointMergeRequestNotesImporter
|
||||
# if enabled by Gitlab::GithubImport::Settings
|
||||
#
|
||||
# - SingleEndpointIssueEventsImporter
|
||||
|
|
|
|||
|
|
@ -117,6 +117,11 @@ msgid_plural "%d Scanned URLs"
|
|||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "%d Thread"
|
||||
msgid_plural "%d Threads"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "%d URL scanned"
|
||||
msgid_plural "%d URLs scanned"
|
||||
msgstr[0] ""
|
||||
|
|
@ -26683,6 +26688,9 @@ msgstr ""
|
|||
msgid "Indicates whether this runner can pick jobs without tags"
|
||||
msgstr ""
|
||||
|
||||
msgid "Indirect"
|
||||
msgstr ""
|
||||
|
||||
msgid "Inform users without uploaded SSH keys that they can't push over SSH until one is added"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG GDK_SHA=f5fe336da712a403253cb5ee7dcbba45eb51dd69
|
||||
ARG GDK_SHA=0fa1edeb5f1e5e280ddeaf639ffaa892f6cde9e7
|
||||
# Use tag prefix when running on 'stable' branch to make sure 'protected' image is used which is not deleted by registry cleanup
|
||||
ARG GDK_BASE_TAG_PREFIX
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,6 @@ RSpec.describe '.gitlab/ci/rules.gitlab-ci.yml', feature_category: :tooling do
|
|||
'.byebug_history',
|
||||
'.editorconfig',
|
||||
'.eslintcache',
|
||||
'.foreman',
|
||||
'.git-blame-ignore-revs',
|
||||
'.gitlab_kas_secret',
|
||||
'.gitlab_shell_secret',
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import { GlAccordionItem } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { nextTick } from 'vue';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
|
||||
import DesignNoteSignedOut from '~/design_management/components/design_notes/design_note_signed_out.vue';
|
||||
import DesignSidebar from '~/design_management/components/design_sidebar.vue';
|
||||
import DesignDisclosure from '~/design_management/components/design_disclosure.vue';
|
||||
import updateActiveDiscussionMutation from '~/design_management/graphql/mutations/update_active_discussion.mutation.graphql';
|
||||
import Participants from '~/sidebar/components/participants/participants.vue';
|
||||
import design from '../mock_data/design';
|
||||
|
||||
const scrollIntoViewMock = jest.fn();
|
||||
|
|
@ -41,15 +40,14 @@ describe('Design management design sidebar component', () => {
|
|||
const findDiscussions = () => wrapper.findAllComponents(DesignDiscussion);
|
||||
const findDisclosure = () => wrapper.findAllComponents(DesignDisclosure);
|
||||
const findFirstDiscussion = () => findDiscussions().at(0);
|
||||
const findUnresolvedDiscussions = () => wrapper.findAll('[data-testid="unresolved-discussion"]');
|
||||
const findResolvedDiscussions = () => wrapper.findAll('[data-testid="resolved-discussion"]');
|
||||
const findParticipants = () => wrapper.findComponent(Participants);
|
||||
const findUnresolvedDiscussions = () => wrapper.findAllByTestId('unresolved-discussion');
|
||||
const findResolvedDiscussions = () => wrapper.findAllByTestId('resolved-discussion');
|
||||
const findResolvedCommentsToggle = () => wrapper.findComponent(GlAccordionItem);
|
||||
const findNewDiscussionDisclaimer = () =>
|
||||
wrapper.find('[data-testid="new-discussion-disclaimer"]');
|
||||
const findNewDiscussionDisclaimer = () => wrapper.findByTestId('new-discussion-disclaimer');
|
||||
const findUnresolvedDiscussionsCount = () => wrapper.findByTestId('unresolved-discussion-count');
|
||||
|
||||
function createComponent(props = {}) {
|
||||
wrapper = shallowMount(DesignSidebar, {
|
||||
wrapper = shallowMountExtended(DesignSidebar, {
|
||||
propsData: {
|
||||
design,
|
||||
resolvedDiscussionsExpanded: false,
|
||||
|
|
@ -81,18 +79,6 @@ describe('Design management design sidebar component', () => {
|
|||
expect(findDisclosure().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders participants', () => {
|
||||
createComponent();
|
||||
|
||||
expect(findParticipants().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('passes the correct amount of participants to the Participants component', () => {
|
||||
createComponent();
|
||||
|
||||
expect(findParticipants().props('participants')).toHaveLength(1);
|
||||
});
|
||||
|
||||
describe('when has no discussions', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
|
|
@ -112,6 +98,11 @@ describe('Design management design sidebar component', () => {
|
|||
it('renders a message about possibility to create a new discussion', () => {
|
||||
expect(findNewDiscussionDisclaimer().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders 0 Threads for unresolved discussions', () => {
|
||||
expect(findUnresolvedDiscussionsCount().exists()).toBe(true);
|
||||
expect(findUnresolvedDiscussionsCount().text()).toBe('0 Threads');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when has discussions', () => {
|
||||
|
|
@ -127,6 +118,54 @@ describe('Design management design sidebar component', () => {
|
|||
expect(findResolvedDiscussions()).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders 1 Thread for unresolved discussions', () => {
|
||||
expect(findUnresolvedDiscussionsCount().exists()).toBe(true);
|
||||
expect(findUnresolvedDiscussionsCount().text()).toBe('1 Thread');
|
||||
});
|
||||
|
||||
it('renders 2 Threads for unresolved discussions', () => {
|
||||
createComponent({
|
||||
design: {
|
||||
...design,
|
||||
discussions: {
|
||||
nodes: [
|
||||
{
|
||||
id: 'discussion-id-1',
|
||||
resolved: false,
|
||||
notes: {
|
||||
nodes: [
|
||||
{
|
||||
id: 'note-id-1',
|
||||
author: {
|
||||
id: 'gid://gitlab/User/1',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'discussion-id-2',
|
||||
resolved: false,
|
||||
notes: {
|
||||
nodes: [
|
||||
{
|
||||
id: 'note-id-2',
|
||||
author: {
|
||||
id: 'gid://gitlab/User/1',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(findUnresolvedDiscussionsCount().exists()).toBe(true);
|
||||
expect(findUnresolvedDiscussionsCount().text()).toBe('2 Threads');
|
||||
});
|
||||
|
||||
it('has resolved comments accordion item collapsed', () => {
|
||||
expect(findResolvedCommentsToggle().props('visible')).toBe(false);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -109,6 +109,21 @@ describe('MemberSource', () => {
|
|||
expect(tooltipDirective).not.toBeUndefined();
|
||||
expect(tooltipDirective.value).toBe('Inherited');
|
||||
});
|
||||
describe('when `webuiMembersInheritedUsers` FF is on', () => {
|
||||
beforeEach(() => {
|
||||
gon.features = { webuiMembersInheritedUsers: true };
|
||||
createComponent({
|
||||
isDirectMember: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('displays tooltip with "Indirect"', () => {
|
||||
const tooltipDirective = getTooltipDirective(wrapper);
|
||||
|
||||
expect(tooltipDirective).not.toBeUndefined();
|
||||
expect(tooltipDirective.value).toBe('Indirect');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::EventsCache, :clean_gitlab_redis_cache, feature_category: :importers do
|
||||
RSpec.describe Gitlab::GithubImport::EventsCache, :clean_gitlab_redis_shared_state, feature_category: :importers do
|
||||
let(:project) { build_stubbed(:project, id: 1) }
|
||||
let(:issue) { build_stubbed(:issue, iid: 2) }
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Commented, feature_catego
|
|||
)
|
||||
end
|
||||
|
||||
let(:extended_events) { true }
|
||||
|
||||
before do
|
||||
allow_next_instance_of(Gitlab::GithubImport::IssuableFinder) do |finder|
|
||||
allow(finder).to receive(:database_id).and_return(issuable.id)
|
||||
|
|
@ -32,9 +30,6 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Commented, feature_catego
|
|||
allow_next_instance_of(Gitlab::GithubImport::UserFinder) do |finder|
|
||||
allow(finder).to receive(:find).with(user.id, user.username).and_return(user.id)
|
||||
end
|
||||
allow_next_instance_of(Gitlab::GithubImport::Settings) do |setting|
|
||||
allow(setting).to receive(:extended_events?).and_return(extended_events)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'new note' do
|
||||
|
|
@ -47,14 +42,6 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Commented, feature_catego
|
|||
noteable_type: issuable.class.name.to_s
|
||||
)
|
||||
end
|
||||
|
||||
context 'when extended_events is disabled' do
|
||||
let(:extended_events) { false }
|
||||
|
||||
it 'does not create a note' do
|
||||
expect { importer.execute(issue_event) }.not_to change { Note.count }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with Issue' do
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Merged, feature_category:
|
|||
let(:client) { instance_double('Gitlab::GithubImport::Client') }
|
||||
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
|
||||
let(:commit_id) { nil }
|
||||
let(:extended_events) { false }
|
||||
|
||||
let(:issue_event) do
|
||||
Gitlab::GithubImport::Representation::IssueEvent.from_json_hash(
|
||||
|
|
@ -33,9 +32,6 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Merged, feature_category:
|
|||
allow_next_instance_of(Gitlab::GithubImport::UserFinder) do |finder|
|
||||
allow(finder).to receive(:find).with(user.id, user.username).and_return(user.id)
|
||||
end
|
||||
allow_next_instance_of(Gitlab::GithubImport::Settings) do |setting|
|
||||
allow(setting).to receive(:extended_events?).and_return(extended_events)
|
||||
end
|
||||
end
|
||||
|
||||
it 'creates expected event and state event' do
|
||||
|
|
@ -63,6 +59,15 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Merged, feature_category:
|
|||
)
|
||||
end
|
||||
|
||||
it 'creates a merged by note' do
|
||||
expect { importer.execute(issue_event) }.to change { Note.count }.by(1)
|
||||
|
||||
last_note = merge_request.notes.last
|
||||
expect(last_note.created_at).to eq(issue_event.created_at)
|
||||
expect(last_note.author).to eq(project.owner)
|
||||
expect(last_note.note).to eq("*Merged by: #{user.username} at #{issue_event.created_at}*")
|
||||
end
|
||||
|
||||
context 'when commit ID is present' do
|
||||
let!(:commit) { create(:commit, project: project) }
|
||||
let(:commit_id) { commit.id }
|
||||
|
|
@ -75,27 +80,4 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Merged, feature_category:
|
|||
expect(state_event.source_commit).to eq commit_id[0..40]
|
||||
end
|
||||
end
|
||||
|
||||
describe 'extended events' do
|
||||
context 'when using extended events' do
|
||||
let(:extended_events) { true }
|
||||
|
||||
it 'creates a merged by note' do
|
||||
expect { importer.execute(issue_event) }.to change { Note.count }.by(1)
|
||||
|
||||
last_note = merge_request.notes.last
|
||||
expect(last_note.created_at).to eq(issue_event.created_at)
|
||||
expect(last_note.author).to eq(project.owner)
|
||||
expect(last_note.note).to eq("*Merged by: #{user.username} at #{issue_event.created_at}*")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not using extended events' do
|
||||
let(:extended_events) { false }
|
||||
|
||||
it 'does not create a merged by note' do
|
||||
expect { importer.execute(issue_event) }.not_to change { Note.count }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Reviewed, feature_categor
|
|||
|
||||
let(:client) { instance_double('Gitlab::GithubImport::Client') }
|
||||
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
|
||||
let(:extended_events) { true }
|
||||
|
||||
let(:issue_event) do
|
||||
Gitlab::GithubImport::Representation::IssueEvent.from_json_hash(
|
||||
|
|
@ -33,9 +32,6 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Reviewed, feature_categor
|
|||
allow_next_instance_of(Gitlab::GithubImport::UserFinder) do |finder|
|
||||
allow(finder).to receive(:find).with(user.id, user.username).and_return(user.id)
|
||||
end
|
||||
allow_next_instance_of(Gitlab::GithubImport::Settings) do |setting|
|
||||
allow(setting).to receive(:extended_events?).and_return(extended_events)
|
||||
end
|
||||
end
|
||||
|
||||
it 'creates a review note', :aggregate_failures do
|
||||
|
|
@ -72,14 +68,4 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::Reviewed, feature_categor
|
|||
expect(system_note.system_note_metadata.action).to eq('approved')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when extended events is false' do
|
||||
let(:extended_events) { false }
|
||||
|
||||
it 'does nothing' do
|
||||
expect { importer.execute(issue_event) }
|
||||
.to not_change { Note.count }
|
||||
.and not_change { Approval.count }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,120 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Importer::IssueEventsImporter, feature_category: :importers do
|
||||
subject(:importer) { described_class.new(project, client, parallel: parallel) }
|
||||
|
||||
let(:project) { build(:project, id: 4, import_source: 'foo/bar') }
|
||||
let(:client) { instance_double(Gitlab::GithubImport::Client) }
|
||||
|
||||
let(:parallel) { true }
|
||||
let(:issue_event) do
|
||||
struct = Struct.new(
|
||||
:id, :node_id, :url, :actor, :user, :event, :commit_id, :commit_url, :label, :rename, :milestone, :source,
|
||||
:assignee, :assigner, :review_requester, :requested_reviewer, :issue, :created_at, :performed_via_github_app,
|
||||
:body, :updated_at, :submitted_at, :state, keyword_init: true
|
||||
)
|
||||
struct.new(id: rand(10), event: 'closed', created_at: '2022-04-26 18:30:53 UTC')
|
||||
end
|
||||
|
||||
describe '#parallel?' do
|
||||
context 'when running in parallel mode' do
|
||||
it { expect(importer).to be_parallel }
|
||||
end
|
||||
|
||||
context 'when running in sequential mode' do
|
||||
let(:parallel) { false }
|
||||
|
||||
it { expect(importer).not_to be_parallel }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#execute' do
|
||||
context 'when running in parallel mode' do
|
||||
it 'imports events in parallel' do
|
||||
expect(importer).to receive(:parallel_import)
|
||||
|
||||
importer.execute
|
||||
end
|
||||
end
|
||||
|
||||
context 'when running in sequential mode' do
|
||||
let(:parallel) { false }
|
||||
|
||||
it 'imports notes in sequence' do
|
||||
expect(importer).to receive(:sequential_import)
|
||||
|
||||
importer.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#sequential_import' do
|
||||
let(:parallel) { false }
|
||||
|
||||
it 'imports each event in sequence' do
|
||||
event_importer = instance_double(Gitlab::GithubImport::Importer::IssueEventImporter)
|
||||
|
||||
allow(importer).to receive(:each_object_to_import).and_yield(issue_event)
|
||||
|
||||
expect(Gitlab::GithubImport::Importer::IssueEventImporter)
|
||||
.to receive(:new)
|
||||
.with(
|
||||
an_instance_of(Gitlab::GithubImport::Representation::IssueEvent),
|
||||
project,
|
||||
client
|
||||
)
|
||||
.and_return(event_importer)
|
||||
|
||||
expect(event_importer).to receive(:execute)
|
||||
|
||||
importer.sequential_import
|
||||
end
|
||||
end
|
||||
|
||||
describe '#parallel_import', :clean_gitlab_redis_shared_state do
|
||||
it 'imports each note in parallel' do
|
||||
allow(importer).to receive(:each_object_to_import).and_yield(issue_event)
|
||||
|
||||
expect(Gitlab::GithubImport::ImportIssueEventWorker).to receive(:perform_in).with(
|
||||
an_instance_of(Float), project.id, an_instance_of(Hash), an_instance_of(String)
|
||||
)
|
||||
|
||||
waiter = importer.parallel_import
|
||||
|
||||
expect(waiter).to be_an_instance_of(Gitlab::JobWaiter)
|
||||
expect(waiter.jobs_remaining).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#importer_class' do
|
||||
it { expect(importer.importer_class).to eq Gitlab::GithubImport::Importer::IssueEventImporter }
|
||||
end
|
||||
|
||||
describe '#representation_class' do
|
||||
it { expect(importer.representation_class).to eq Gitlab::GithubImport::Representation::IssueEvent }
|
||||
end
|
||||
|
||||
describe '#sidekiq_worker_class' do
|
||||
it { expect(importer.sidekiq_worker_class).to eq Gitlab::GithubImport::ImportIssueEventWorker }
|
||||
end
|
||||
|
||||
describe '#object_type' do
|
||||
it { expect(importer.object_type).to eq :issue_event }
|
||||
end
|
||||
|
||||
describe '#collection_method' do
|
||||
it { expect(importer.collection_method).to eq :repository_issue_events }
|
||||
end
|
||||
|
||||
describe '#id_for_already_imported_cache' do
|
||||
it 'returns the ID of the given note' do
|
||||
expect(importer.id_for_already_imported_cache(issue_event)).to eq(issue_event.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#collection_options' do
|
||||
it { expect(importer.collection_options).to eq({}) }
|
||||
end
|
||||
end
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Importer::PullRequests::AllMergedByImporter, feature_category: :importers do
|
||||
let(:client) { double }
|
||||
|
||||
let_it_be(:project) { create(:project, import_source: 'http://somegithub.com') }
|
||||
|
||||
subject { described_class.new(project, client) }
|
||||
|
||||
it { is_expected.to include_module(Gitlab::GithubImport::ParallelScheduling) }
|
||||
|
||||
describe '#representation_class' do
|
||||
it { expect(subject.representation_class).to eq(Gitlab::GithubImport::Representation::PullRequest) }
|
||||
end
|
||||
|
||||
describe '#importer_class' do
|
||||
it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::PullRequests::MergedByImporter) }
|
||||
end
|
||||
|
||||
describe '#sidekiq_worker_class' do
|
||||
it { expect(subject.sidekiq_worker_class).to eq(Gitlab::GithubImport::PullRequests::ImportMergedByWorker) }
|
||||
end
|
||||
|
||||
describe '#collection_method' do
|
||||
it { expect(subject.collection_method).to eq(:pull_requests_merged_by) }
|
||||
end
|
||||
|
||||
describe '#id_for_already_imported_cache' do
|
||||
it { expect(subject.id_for_already_imported_cache(instance_double(MergeRequest, id: 1))).to eq(1) }
|
||||
end
|
||||
|
||||
describe '#each_object_to_import', :clean_gitlab_redis_cache do
|
||||
let!(:merge_request) do
|
||||
create(:merged_merge_request, iid: 999, source_project: project, target_project: project)
|
||||
end
|
||||
|
||||
it 'fetches the merged pull requests data' do
|
||||
pull_request = double
|
||||
|
||||
allow(client)
|
||||
.to receive(:pull_request)
|
||||
.exactly(:once) # ensure to be cached on the second call
|
||||
.with('http://somegithub.com', 999)
|
||||
.and_return(pull_request)
|
||||
|
||||
expect { |b| subject.each_object_to_import(&b) }
|
||||
.to yield_with_args(pull_request)
|
||||
|
||||
subject.each_object_to_import
|
||||
end
|
||||
|
||||
it 'skips cached merge requests' do
|
||||
Gitlab::Cache::Import::Caching.set_add(
|
||||
"github-importer/already-imported/#{project.id}/pull_requests_merged_by",
|
||||
merge_request.id
|
||||
)
|
||||
|
||||
expect(client).not_to receive(:pull_request)
|
||||
|
||||
subject.each_object_to_import
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Importer::PullRequests::ReviewRequestsImporter, :clean_gitlab_redis_cache,
|
||||
feature_category: :importers do
|
||||
subject(:importer) { described_class.new(project, client) }
|
||||
|
||||
let_it_be(:project) { create(:project, import_source: 'foo') }
|
||||
|
||||
let(:client) { instance_double(Gitlab::GithubImport::Client) }
|
||||
let(:review_request_struct) { Struct.new(:merge_request_id, :users, keyword_init: true) }
|
||||
let(:user_struct) { Struct.new(:id, :login, keyword_init: true) }
|
||||
|
||||
shared_context 'when project with merge requests' do
|
||||
let_it_be(:merge_request_1) { create(:merge_request, source_project: project, target_branch: 'feature1') }
|
||||
let_it_be(:merge_request_2) { create(:merge_request, source_project: project, target_branch: 'feature2') }
|
||||
|
||||
let(:importer_stub) { instance_double('Gitlab::GithubImport::Importer::NoteAttachmentsImporter') }
|
||||
let(:importer_attrs) do
|
||||
[instance_of(Gitlab::GithubImport::Representation::PullRequests::ReviewRequests), project, client]
|
||||
end
|
||||
|
||||
let(:review_requests_1) do
|
||||
{
|
||||
users: [
|
||||
{ id: 4, login: 'alice' },
|
||||
{ id: 5, login: 'bob' }
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
let(:review_requests_2) do
|
||||
{
|
||||
users: [{ id: 4, login: 'alice' }]
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(client).to receive(:pull_request_review_requests)
|
||||
.with(project.import_source, merge_request_1.iid).and_return(review_requests_1)
|
||||
allow(client).to receive(:pull_request_review_requests)
|
||||
.with(project.import_source, merge_request_2.iid).and_return(review_requests_2)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#sequential_import' do
|
||||
include_context 'when project with merge requests'
|
||||
|
||||
it 'imports each project merge request reviewers' do
|
||||
expect_next_instances_of(
|
||||
Gitlab::GithubImport::Importer::PullRequests::ReviewRequestImporter, 2, false, *importer_attrs
|
||||
) do |note_attachments_importer|
|
||||
expect(note_attachments_importer).to receive(:execute)
|
||||
end
|
||||
|
||||
expect(Gitlab::GithubImport::ObjectCounter)
|
||||
.to receive(:increment).twice.with(project, :pull_request_review_request, :fetched)
|
||||
|
||||
importer.sequential_import
|
||||
end
|
||||
|
||||
context 'when merge request is already processed' do
|
||||
before do
|
||||
Gitlab::Cache::Import::Caching.set_add(
|
||||
"github-importer/pull_requests/pull_request_review_requests/already-imported/#{project.id}",
|
||||
merge_request_1.iid
|
||||
)
|
||||
end
|
||||
|
||||
it "doesn't import this merge request reviewers" do
|
||||
expect_next_instance_of(
|
||||
Gitlab::GithubImport::Importer::PullRequests::ReviewRequestImporter, *importer_attrs
|
||||
) do |note_attachments_importer|
|
||||
expect(note_attachments_importer).to receive(:execute)
|
||||
end
|
||||
|
||||
expect(Gitlab::GithubImport::ObjectCounter)
|
||||
.to receive(:increment).once.with(project, :pull_request_review_request, :fetched)
|
||||
|
||||
importer.sequential_import
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#parallel_import' do
|
||||
include_context 'when project with merge requests'
|
||||
|
||||
let(:expected_worker_payload) do
|
||||
[
|
||||
[
|
||||
project.id,
|
||||
{
|
||||
merge_request_id: merge_request_1.id,
|
||||
merge_request_iid: merge_request_1.iid,
|
||||
users: [
|
||||
{ id: 4, login: 'alice' },
|
||||
{ id: 5, login: 'bob' }
|
||||
]
|
||||
}.deep_stringify_keys,
|
||||
instance_of(String)
|
||||
],
|
||||
[
|
||||
project.id,
|
||||
{
|
||||
merge_request_id: merge_request_2.id,
|
||||
merge_request_iid: merge_request_2.iid,
|
||||
users: [
|
||||
{ id: 4, login: 'alice' }
|
||||
]
|
||||
}.deep_stringify_keys,
|
||||
instance_of(String)
|
||||
]
|
||||
]
|
||||
end
|
||||
|
||||
it 'schedule import for each merge request reviewers' do
|
||||
expect(Gitlab::GithubImport::PullRequests::ImportReviewRequestWorker)
|
||||
.to receive(:perform_in).with(an_instance_of(Float), *expected_worker_payload.first)
|
||||
|
||||
expect(Gitlab::GithubImport::PullRequests::ImportReviewRequestWorker)
|
||||
.to receive(:perform_in).with(an_instance_of(Float), *expected_worker_payload.second)
|
||||
|
||||
expect(Gitlab::GithubImport::ObjectCounter)
|
||||
.to receive(:increment).twice.with(project, :pull_request_review_request, :fetched)
|
||||
|
||||
importer.parallel_import
|
||||
end
|
||||
|
||||
context 'when merge request is already processed' do
|
||||
before do
|
||||
Gitlab::Cache::Import::Caching.set_add(
|
||||
"github-importer/pull_requests/pull_request_review_requests/already-imported/#{project.id}",
|
||||
merge_request_1.iid
|
||||
)
|
||||
end
|
||||
|
||||
it "doesn't schedule import this merge request reviewers" do
|
||||
expect(Gitlab::GithubImport::PullRequests::ImportReviewRequestWorker)
|
||||
.to receive(:perform_in).with(an_instance_of(Float), *expected_worker_payload.second)
|
||||
|
||||
expect(Gitlab::GithubImport::ObjectCounter)
|
||||
.to receive(:increment).once.with(project, :pull_request_review_request, :fetched)
|
||||
|
||||
importer.parallel_import
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Importer::PullRequests::ReviewsImporter, feature_category: :importers do
|
||||
let(:client) { double }
|
||||
let(:project) { create(:project, import_source: 'github/repo') }
|
||||
|
||||
subject { described_class.new(project, client) }
|
||||
|
||||
it { is_expected.to include_module(Gitlab::GithubImport::ParallelScheduling) }
|
||||
|
||||
describe '#representation_class' do
|
||||
it { expect(subject.representation_class).to eq(Gitlab::GithubImport::Representation::PullRequestReview) }
|
||||
end
|
||||
|
||||
describe '#importer_class' do
|
||||
it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::PullRequests::ReviewImporter) }
|
||||
end
|
||||
|
||||
describe '#sidekiq_worker_class' do
|
||||
it { expect(subject.sidekiq_worker_class).to eq(Gitlab::GithubImport::PullRequests::ImportReviewWorker) }
|
||||
end
|
||||
|
||||
describe '#collection_method' do
|
||||
it { expect(subject.collection_method).to eq(:pull_request_reviews) }
|
||||
end
|
||||
|
||||
describe '#object_type' do
|
||||
it { expect(subject.object_type).to eq(:pull_request_review) }
|
||||
end
|
||||
|
||||
describe '#id_for_already_imported_cache' do
|
||||
it { expect(subject.id_for_already_imported_cache({ id: 1 })).to eq(1) }
|
||||
end
|
||||
|
||||
describe '#each_object_to_import', :clean_gitlab_redis_shared_state do
|
||||
let(:merge_request) do
|
||||
create(
|
||||
:merged_merge_request,
|
||||
iid: 999,
|
||||
source_project: project,
|
||||
target_project: project
|
||||
)
|
||||
end
|
||||
|
||||
let(:review) { { id: 1 } }
|
||||
|
||||
it 'fetches the pull requests reviews data' do
|
||||
page = Struct.new(:objects, :number).new([review], 1)
|
||||
|
||||
expect(client)
|
||||
.to receive(:each_page)
|
||||
.exactly(:once) # ensure to be cached on the second call
|
||||
.with(:pull_request_reviews, 'github/repo', merge_request.iid, { page: 1 })
|
||||
.and_yield(page)
|
||||
|
||||
expect { |b| subject.each_object_to_import(&b) }
|
||||
.to yield_with_args(review)
|
||||
|
||||
subject.each_object_to_import
|
||||
|
||||
expect(review[:merge_request_id]).to eq(merge_request.id)
|
||||
expect(review[:merge_request_iid]).to eq(merge_request.iid)
|
||||
end
|
||||
|
||||
it 'skips cached pages' do
|
||||
Gitlab::Import::PageCounter
|
||||
.new(project, "merge_request/#{merge_request.id}/pull_request_reviews")
|
||||
.set(2)
|
||||
|
||||
expect(review).not_to receive(:merge_request_id=)
|
||||
|
||||
expect(client)
|
||||
.to receive(:each_page)
|
||||
.exactly(:once) # ensure to be cached on the second call
|
||||
.with(:pull_request_reviews, 'github/repo', merge_request.iid, { page: 2 })
|
||||
|
||||
subject.each_object_to_import
|
||||
end
|
||||
|
||||
it 'skips cached merge requests' do
|
||||
Gitlab::Cache::Import::Caching.set_add(
|
||||
"github-importer/merge_request/already-imported/#{project.id}",
|
||||
merge_request.id
|
||||
)
|
||||
|
||||
expect(review).not_to receive(:merge_request_id=)
|
||||
|
||||
expect(client).not_to receive(:each_page)
|
||||
|
||||
subject.each_object_to_import
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -104,15 +104,10 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter
|
|||
|
||||
let(:page_counter) { instance_double(Gitlab::Import::PageCounter) }
|
||||
|
||||
let(:extended_events) { true }
|
||||
|
||||
before do
|
||||
allow(client).to receive(:each_page).once.with(:issue_timeline,
|
||||
project.import_source, issuable.iid, { state: 'all', sort: 'created', direction: 'asc', page: 1 }
|
||||
).and_yield(page)
|
||||
allow_next_instance_of(Gitlab::GithubImport::Settings) do |setting|
|
||||
allow(setting).to receive(:extended_events?).and_return(extended_events)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with issues' do
|
||||
|
|
@ -226,16 +221,6 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter
|
|||
|
||||
subject.each_object_to_import { |event| event }
|
||||
end
|
||||
|
||||
context 'when extended_events is disabled' do
|
||||
let(:extended_events) { false }
|
||||
|
||||
it 'increments the issue_event fetched counter' do
|
||||
expect(Gitlab::GithubImport::ObjectCounter).to receive(:increment).with(project, :issue_event, :fetched)
|
||||
|
||||
subject.each_object_to_import { |event| event }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -279,17 +264,6 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter
|
|||
subject.each_object_to_import { |event| event }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when extended_events is disabled' do
|
||||
let(:event_name) { 'review_requested' }
|
||||
let(:extended_events) { false }
|
||||
|
||||
it 'does not save event' do
|
||||
expect(Gitlab::GithubImport::EventsCache).not_to receive(:new)
|
||||
|
||||
subject.each_object_to_import { |event| event }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'after batch processed' do
|
||||
|
|
@ -319,27 +293,11 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter
|
|||
subject.each_object_to_import { |event| event }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when extended_events is disabled' do
|
||||
let(:extended_events) { false }
|
||||
|
||||
it 'does not replay events' do
|
||||
expect(Gitlab::GithubImport::ReplayEventsWorker).not_to receive(:perform_async)
|
||||
|
||||
subject.each_object_to_import { |event| event }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#execute', :clean_gitlab_redis_cache do
|
||||
let(:extended_events) { false }
|
||||
|
||||
describe '#execute', :clean_gitlab_redis_shared_state do
|
||||
before do
|
||||
allow_next_instance_of(Gitlab::GithubImport::Settings) do |setting|
|
||||
allow(setting).to receive(:extended_events?).and_return(extended_events)
|
||||
end
|
||||
|
||||
stub_request(:get, 'https://api.github.com/rate_limit')
|
||||
.to_return(status: 200, headers: { 'X-RateLimit-Limit' => 5000, 'X-RateLimit-Remaining' => 5000 })
|
||||
|
||||
|
|
@ -362,32 +320,15 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter
|
|||
.to_return(status: 200, body: events.to_json, headers: { 'Content-Type' => 'application/json' })
|
||||
end
|
||||
|
||||
context 'when extended_events is disabled' do
|
||||
it 'enqueues importer worker' do
|
||||
expect { subject.execute }.to change { Gitlab::GithubImport::ReplayEventsWorker.jobs.size }.by(0)
|
||||
.and change { Gitlab::GithubImport::ImportIssueEventWorker.jobs.size }.by(1)
|
||||
end
|
||||
|
||||
it 'returns job waiter with the correct remaining jobs count' do
|
||||
job_waiter = subject.execute
|
||||
|
||||
expect(job_waiter.jobs_remaining).to eq(1)
|
||||
end
|
||||
it 'enqueues importer worker and replay worker' do
|
||||
expect { subject.execute }.to change { Gitlab::GithubImport::ReplayEventsWorker.jobs.size }.by(1)
|
||||
.and change { Gitlab::GithubImport::ImportIssueEventWorker.jobs.size }.by(1)
|
||||
end
|
||||
|
||||
context 'when extended_events is enabled' do
|
||||
let(:extended_events) { true }
|
||||
it 'returns job waiter with the correct remaining jobs count' do
|
||||
job_waiter = subject.execute
|
||||
|
||||
it 'enqueues importer worker and replay worker' do
|
||||
expect { subject.execute }.to change { Gitlab::GithubImport::ReplayEventsWorker.jobs.size }.by(1)
|
||||
.and change { Gitlab::GithubImport::ImportIssueEventWorker.jobs.size }.by(1)
|
||||
end
|
||||
|
||||
it 'returns job waiter with the correct remaining jobs count' do
|
||||
job_waiter = subject.execute
|
||||
|
||||
expect(job_waiter.jobs_remaining).to eq(2)
|
||||
end
|
||||
expect(job_waiter.jobs_remaining).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueNotesImporter do
|
||||
let(:client) { double }
|
||||
let(:project) { create(:project, import_source: 'github/repo') }
|
||||
|
||||
subject { described_class.new(project, client) }
|
||||
|
||||
it { is_expected.to include_module(Gitlab::GithubImport::ParallelScheduling) }
|
||||
it { is_expected.to include_module(Gitlab::GithubImport::SingleEndpointNotesImporting) }
|
||||
it { expect(subject.representation_class).to eq(Gitlab::GithubImport::Representation::Note) }
|
||||
it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::NoteImporter) }
|
||||
it { expect(subject.collection_method).to eq(:issue_comments) }
|
||||
it { expect(subject.object_type).to eq(:note) }
|
||||
it { expect(subject.id_for_already_imported_cache({ id: 1 })).to eq(1) }
|
||||
|
||||
describe '#each_object_to_import', :clean_gitlab_redis_shared_state do
|
||||
let(:issue) do
|
||||
create(
|
||||
:issue,
|
||||
iid: 999,
|
||||
project: project
|
||||
)
|
||||
end
|
||||
|
||||
let(:note) { { id: 1 } }
|
||||
let(:page) { double(objects: [note], number: 1) }
|
||||
|
||||
it 'fetches data' do
|
||||
expect(client)
|
||||
.to receive(:each_page)
|
||||
.exactly(:once) # ensure to be cached on the second call
|
||||
.with(:issue_comments, 'github/repo', issue.iid, { page: 1 })
|
||||
.and_yield(page)
|
||||
|
||||
expect { |b| subject.each_object_to_import(&b) }.to yield_with_args(note)
|
||||
|
||||
subject.each_object_to_import {}
|
||||
|
||||
expect(
|
||||
Gitlab::Cache::Import::Caching.set_includes?(
|
||||
"github-importer/issue/notes/already-imported/#{project.id}",
|
||||
issue.iid
|
||||
)
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it 'skips cached pages' do
|
||||
Gitlab::Import::PageCounter
|
||||
.new(project, "issue/#{issue.id}/issue_comments")
|
||||
.set(2)
|
||||
|
||||
expect(client)
|
||||
.to receive(:each_page)
|
||||
.exactly(:once) # ensure to be cached on the second call
|
||||
.with(:issue_comments, 'github/repo', issue.iid, { page: 2 })
|
||||
|
||||
subject.each_object_to_import {}
|
||||
end
|
||||
|
||||
it 'skips cached merge requests' do
|
||||
Gitlab::Cache::Import::Caching.set_add(
|
||||
"github-importer/issue/notes/already-imported/#{project.id}",
|
||||
issue.iid
|
||||
)
|
||||
|
||||
expect(client).not_to receive(:each_page)
|
||||
|
||||
subject.each_object_to_import {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointMergeRequestNotesImporter do
|
||||
let(:client) { double }
|
||||
let(:project) { create(:project, import_source: 'github/repo') }
|
||||
|
||||
subject { described_class.new(project, client) }
|
||||
|
||||
it { is_expected.to include_module(Gitlab::GithubImport::ParallelScheduling) }
|
||||
it { is_expected.to include_module(Gitlab::GithubImport::SingleEndpointNotesImporting) }
|
||||
it { expect(subject.representation_class).to eq(Gitlab::GithubImport::Representation::Note) }
|
||||
it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::NoteImporter) }
|
||||
it { expect(subject.collection_method).to eq(:issue_comments) }
|
||||
it { expect(subject.object_type).to eq(:note) }
|
||||
it { expect(subject.id_for_already_imported_cache({ id: 1 })).to eq(1) }
|
||||
|
||||
describe '#each_object_to_import', :clean_gitlab_redis_shared_state do
|
||||
let(:merge_request) do
|
||||
create(
|
||||
:merge_request,
|
||||
iid: 999,
|
||||
source_project: project,
|
||||
target_project: project
|
||||
)
|
||||
end
|
||||
|
||||
let(:note) { { id: 1 } }
|
||||
let(:page) { double(objects: [note], number: 1) }
|
||||
|
||||
it 'fetches data' do
|
||||
expect(client)
|
||||
.to receive(:each_page)
|
||||
.exactly(:once) # ensure to be cached on the second call
|
||||
.with(:issue_comments, 'github/repo', merge_request.iid, { page: 1 })
|
||||
.and_yield(page)
|
||||
|
||||
expect { |b| subject.each_object_to_import(&b) }.to yield_with_args(note)
|
||||
|
||||
subject.each_object_to_import {}
|
||||
|
||||
expect(
|
||||
Gitlab::Cache::Import::Caching.set_includes?(
|
||||
"github-importer/merge_request/notes/already-imported/#{project.id}",
|
||||
merge_request.iid
|
||||
)
|
||||
).to eq(true)
|
||||
end
|
||||
|
||||
it 'skips cached pages' do
|
||||
Gitlab::Import::PageCounter
|
||||
.new(project, "merge_request/#{merge_request.id}/issue_comments")
|
||||
.set(2)
|
||||
|
||||
expect(client)
|
||||
.to receive(:each_page)
|
||||
.exactly(:once) # ensure to be cached on the second call
|
||||
.with(:issue_comments, 'github/repo', merge_request.iid, { page: 2 })
|
||||
|
||||
subject.each_object_to_import {}
|
||||
end
|
||||
|
||||
it 'skips cached merge requests' do
|
||||
Gitlab::Cache::Import::Caching.set_add(
|
||||
"github-importer/merge_request/notes/already-imported/#{project.id}",
|
||||
merge_request.iid
|
||||
)
|
||||
|
||||
expect(client).not_to receive(:each_page)
|
||||
|
||||
subject.each_object_to_import {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -9,7 +9,6 @@ RSpec.describe Gitlab::GithubImport::Settings, feature_category: :importers do
|
|||
|
||||
let(:optional_stages) do
|
||||
{
|
||||
single_endpoint_issue_events_import: true,
|
||||
single_endpoint_notes_import: false,
|
||||
attachments_import: false,
|
||||
collaborators_import: false
|
||||
|
|
@ -44,37 +43,12 @@ RSpec.describe Gitlab::GithubImport::Settings, feature_category: :importers do
|
|||
it 'returns stages list as array' do
|
||||
expect(described_class.stages_array(project.owner)).to match_array(expected_list)
|
||||
end
|
||||
|
||||
context 'when `github_import_extended_events` feature flag is disabled' do
|
||||
let(:expected_list_with_deprecated_options) do
|
||||
stages = described_class::OPTIONAL_STAGES
|
||||
|
||||
expected_list.concat(
|
||||
[
|
||||
{
|
||||
name: 'single_endpoint_issue_events_import',
|
||||
label: stages[:single_endpoint_issue_events_import][:label],
|
||||
selected: false,
|
||||
details: stages[:single_endpoint_issue_events_import][:details]
|
||||
}
|
||||
])
|
||||
end
|
||||
|
||||
before do
|
||||
stub_feature_flags(github_import_extended_events: false)
|
||||
end
|
||||
|
||||
it 'returns stages list as array' do
|
||||
expect(described_class.stages_array(project.owner)).to match_array(expected_list_with_deprecated_options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#write' do
|
||||
let(:data_input) do
|
||||
{
|
||||
optional_stages: {
|
||||
single_endpoint_issue_events_import: true,
|
||||
single_endpoint_notes_import: 'false',
|
||||
attachments_import: nil,
|
||||
collaborators_import: false,
|
||||
|
|
@ -100,7 +74,6 @@ RSpec.describe Gitlab::GithubImport::Settings, feature_category: :importers do
|
|||
it 'returns is enabled or not specific optional stage' do
|
||||
project.build_or_assign_import_data(data: { optional_stages: optional_stages })
|
||||
|
||||
expect(settings.enabled?(:single_endpoint_issue_events_import)).to eq true
|
||||
expect(settings.enabled?(:single_endpoint_notes_import)).to eq false
|
||||
expect(settings.enabled?(:attachments_import)).to eq false
|
||||
expect(settings.enabled?(:collaborators_import)).to eq false
|
||||
|
|
@ -111,30 +84,9 @@ RSpec.describe Gitlab::GithubImport::Settings, feature_category: :importers do
|
|||
it 'returns is disabled or not specific optional stage' do
|
||||
project.build_or_assign_import_data(data: { optional_stages: optional_stages })
|
||||
|
||||
expect(settings.disabled?(:single_endpoint_issue_events_import)).to eq false
|
||||
expect(settings.disabled?(:single_endpoint_notes_import)).to eq true
|
||||
expect(settings.disabled?(:attachments_import)).to eq true
|
||||
expect(settings.disabled?(:collaborators_import)).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#extended_events?' do
|
||||
it 'when extended_events is set to true' do
|
||||
project.build_or_assign_import_data(data: { extended_events: true })
|
||||
|
||||
expect(settings.extended_events?).to eq(true)
|
||||
end
|
||||
|
||||
it 'when extended_events is set to false' do
|
||||
project.build_or_assign_import_data(data: { extended_events: false })
|
||||
|
||||
expect(settings.extended_events?).to eq(false)
|
||||
end
|
||||
|
||||
it 'when extended_events is not present' do
|
||||
project.build_or_assign_import_data(data: {})
|
||||
|
||||
expect(settings.extended_events?).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache, feature_category: :importers do
|
||||
RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_shared_state, feature_category: :importers do
|
||||
let(:project) do
|
||||
create(
|
||||
:project,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ RSpec.describe Gitlab::GithubImport, feature_category: :importers do
|
|||
described_class.new_client_for(project)
|
||||
end
|
||||
|
||||
it 'returns the ID of the ghost user', :clean_gitlab_redis_cache do
|
||||
it 'returns the ID of the ghost user', :clean_gitlab_redis_shared_state do
|
||||
expect(described_class.ghost_user_id).to eq(Users::Internal.ghost.id)
|
||||
end
|
||||
|
||||
|
|
@ -73,11 +73,11 @@ RSpec.describe Gitlab::GithubImport, feature_category: :importers do
|
|||
described_class.new_client_for(project)
|
||||
end
|
||||
|
||||
it 'returns the ID of the ghost user', :clean_gitlab_redis_cache do
|
||||
it 'returns the ID of the ghost user', :clean_gitlab_redis_shared_state do
|
||||
expect(described_class.ghost_user_id).to eq(Users::Internal.ghost.id)
|
||||
end
|
||||
|
||||
it 'caches the ghost user ID', :clean_gitlab_redis_cache do
|
||||
it 'caches the ghost user ID', :clean_gitlab_redis_shared_state do
|
||||
expect(Gitlab::Cache::Import::Caching)
|
||||
.to receive(:write)
|
||||
.once
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ RSpec.describe Import::GithubService, feature_category: :importers do
|
|||
allow(settings)
|
||||
.to receive(:write)
|
||||
.with(
|
||||
extended_events: true,
|
||||
optional_stages: optional_stages,
|
||||
timeout_strategy: timeout_strategy
|
||||
)
|
||||
|
|
@ -98,7 +97,6 @@ RSpec.describe Import::GithubService, feature_category: :importers do
|
|||
expect(settings)
|
||||
.to have_received(:write)
|
||||
.with(optional_stages: nil,
|
||||
extended_events: true,
|
||||
timeout_strategy: timeout_strategy
|
||||
)
|
||||
expect_snowplow_event(
|
||||
|
|
@ -124,7 +122,6 @@ RSpec.describe Import::GithubService, feature_category: :importers do
|
|||
.to have_received(:write)
|
||||
.with(
|
||||
optional_stages: nil,
|
||||
extended_events: true,
|
||||
timeout_strategy: timeout_strategy
|
||||
)
|
||||
expect_snowplow_event(
|
||||
|
|
@ -160,7 +157,6 @@ RSpec.describe Import::GithubService, feature_category: :importers do
|
|||
.to have_received(:write)
|
||||
.with(
|
||||
optional_stages: nil,
|
||||
extended_events: true,
|
||||
timeout_strategy: timeout_strategy
|
||||
)
|
||||
expect_snowplow_event(
|
||||
|
|
@ -185,7 +181,6 @@ RSpec.describe Import::GithubService, feature_category: :importers do
|
|||
context 'when optional stages params present' do
|
||||
let(:optional_stages) do
|
||||
{
|
||||
single_endpoint_issue_events_import: true,
|
||||
single_endpoint_notes_import: 'false',
|
||||
attachments_import: false,
|
||||
collaborators_import: true
|
||||
|
|
@ -199,7 +194,6 @@ RSpec.describe Import::GithubService, feature_category: :importers do
|
|||
.to have_received(:write)
|
||||
.with(
|
||||
optional_stages: optional_stages,
|
||||
extended_events: true,
|
||||
timeout_strategy: timeout_strategy
|
||||
)
|
||||
end
|
||||
|
|
@ -215,7 +209,6 @@ RSpec.describe Import::GithubService, feature_category: :importers do
|
|||
.to have_received(:write)
|
||||
.with(
|
||||
optional_stages: optional_stages,
|
||||
extended_events: true,
|
||||
timeout_strategy: timeout_strategy
|
||||
)
|
||||
end
|
||||
|
|
@ -229,25 +222,10 @@ RSpec.describe Import::GithubService, feature_category: :importers do
|
|||
.to have_received(:write)
|
||||
.with(
|
||||
optional_stages: optional_stages,
|
||||
extended_events: true,
|
||||
timeout_strategy: timeout_strategy
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when `github_import_extended_events` feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(github_import_extended_events: false)
|
||||
end
|
||||
|
||||
it 'saves extend_events to import_data' do
|
||||
expect(settings)
|
||||
.to receive(:write)
|
||||
.with(a_hash_including(extended_events: false))
|
||||
|
||||
subject.execute(access_params, :github)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using personal access tokens' do
|
||||
|
|
|
|||
|
|
@ -6006,7 +6006,6 @@
|
|||
- './spec/lib/gitlab/github_import/importer/events/renamed_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/events/reopened_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/issue_and_label_links_importer_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/issue_events_importer_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/issue_importer_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/issues_importer_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb'
|
||||
|
|
@ -6022,8 +6021,6 @@
|
|||
- './spec/lib/gitlab/github_import/importer/repository_importer_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/single_endpoint_issue_events_importer_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/issuable_finder_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/label_finder_spec.rb'
|
||||
- './spec/lib/gitlab/github_import/logger_spec.rb'
|
||||
|
|
@ -9424,9 +9421,6 @@
|
|||
- './spec/workers/gitlab/github_import/stage/import_issue_events_worker_spec.rb'
|
||||
- './spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb'
|
||||
- './spec/workers/gitlab/github_import/stage/import_lfs_objects_worker_spec.rb'
|
||||
- './spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb'
|
||||
- './spec/workers/gitlab/github_import/stage/import_pull_requests_merged_by_worker_spec.rb'
|
||||
- './spec/workers/gitlab/github_import/stage/import_pull_requests_reviews_worker_spec.rb'
|
||||
- './spec/workers/gitlab/github_import/stage/import_pull_requests_worker_spec.rb'
|
||||
- './spec/workers/gitlab/github_import/stage/import_repository_worker_spec.rb'
|
||||
- './spec/workers/gitlab/import/stuck_import_job_spec.rb'
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ RSpec.describe Gitlab::GithubImport::ImportIssueEventWorker, feature_category: :
|
|||
end
|
||||
|
||||
let(:client) { instance_double(Gitlab::GithubImport::Client) }
|
||||
let(:extended_events) { true }
|
||||
let(:event_hash) do
|
||||
{
|
||||
'id' => 6501124486,
|
||||
|
|
@ -26,12 +25,6 @@ RSpec.describe Gitlab::GithubImport::ImportIssueEventWorker, feature_category: :
|
|||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow_next_instance_of(Gitlab::GithubImport::Settings) do |setting|
|
||||
allow(setting).to receive(:extended_events?).and_return(extended_events)
|
||||
end
|
||||
end
|
||||
|
||||
it 'imports an issue event and increase importer counter' do
|
||||
expect_next_instance_of(Gitlab::GithubImport::Importer::IssueEventImporter,
|
||||
an_instance_of(Gitlab::GithubImport::Representation::IssueEvent),
|
||||
|
|
@ -65,16 +58,6 @@ RSpec.describe Gitlab::GithubImport::ImportIssueEventWorker, feature_category: :
|
|||
|
||||
worker.import(project, client, event_hash)
|
||||
end
|
||||
|
||||
context 'when extended_events is disabled' do
|
||||
let(:extended_events) { false }
|
||||
|
||||
it 'increments the issue_event importer counter' do
|
||||
expect(Gitlab::GithubImport::ObjectCounter).to receive(:increment).with(project, :issue_event, :imported)
|
||||
|
||||
worker.import(project, client, event_hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportCollaboratorsWorker, feature_c
|
|||
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, { '123' => 2 }, 'pull_requests_merged_by')
|
||||
.with(project.id, { '123' => 2 }, 'issues_and_diff_notes')
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
|
|
@ -49,7 +49,7 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportCollaboratorsWorker, feature_c
|
|||
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, {}, 'pull_requests_merged_by')
|
||||
.with(project.id, {}, 'issues_and_diff_notes')
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
|
|
@ -63,7 +63,7 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportCollaboratorsWorker, feature_c
|
|||
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, {}, 'pull_requests_merged_by')
|
||||
.with(project.id, {}, 'issues_and_diff_notes')
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,62 +8,30 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportIssueEventsWorker, feature_cat
|
|||
let!(:group) { create(:group, projects: [project]) }
|
||||
let(:settings) { ::Gitlab::GithubImport::Settings.new(project.reload) }
|
||||
let(:stage_enabled) { true }
|
||||
let(:extended_events) { false }
|
||||
|
||||
subject(:worker) { described_class.new }
|
||||
|
||||
before do
|
||||
settings.write({
|
||||
optional_stages: { single_endpoint_issue_events_import: stage_enabled }, extended_events: extended_events
|
||||
})
|
||||
end
|
||||
|
||||
it_behaves_like Gitlab::GithubImport::StageMethods
|
||||
|
||||
describe '#import' do
|
||||
let(:importer) { instance_double('Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter') }
|
||||
let(:client) { instance_double('Gitlab::GithubImport::Client') }
|
||||
|
||||
context 'when stage is enabled' do
|
||||
it 'imports issue events' do
|
||||
waiter = Gitlab::JobWaiter.new(2, '123')
|
||||
it 'imports issue events' do
|
||||
waiter = Gitlab::JobWaiter.new(2, '123')
|
||||
|
||||
expect(Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter)
|
||||
.to receive(:new)
|
||||
.with(project, client)
|
||||
.and_return(importer)
|
||||
expect(Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter)
|
||||
.to receive(:new)
|
||||
.with(project, client)
|
||||
.and_return(importer)
|
||||
|
||||
expect(importer).to receive(:execute).and_return(waiter)
|
||||
expect(importer).to receive(:execute).and_return(waiter)
|
||||
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, { '123' => 2 }, 'notes')
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, { '123' => 2 }, 'attachments')
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when stage is disabled' do
|
||||
let(:stage_enabled) { false }
|
||||
|
||||
it 'skips issue events import and calls next stage' do
|
||||
expect(Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter).not_to receive(:new)
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker).to receive(:perform_async).with(project.id, {}, 'notes')
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
|
||||
context 'when extended_events is enabled' do
|
||||
let(:extended_events) { true }
|
||||
|
||||
it 'does not skip the stage' do
|
||||
expect_next_instance_of(Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter) do |importer|
|
||||
expect(importer).to receive(:execute).and_return(Gitlab::JobWaiter.new)
|
||||
end
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
end
|
||||
worker.import(client, project)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Stage::ImportNotesWorker, feature_category: :importers do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let(:settings) { ::Gitlab::GithubImport::Settings.new(project.reload) }
|
||||
let(:single_endpoint_optional_stage) { true }
|
||||
|
||||
subject(:worker) { described_class.new }
|
||||
|
||||
before do
|
||||
settings.write({ optional_stages: { single_endpoint_notes_import: single_endpoint_optional_stage } })
|
||||
end
|
||||
|
||||
it_behaves_like Gitlab::GithubImport::StageMethods
|
||||
|
||||
describe '#import' do
|
||||
it 'imports all the notes' do
|
||||
client = double(:client)
|
||||
|
||||
worker.importers(project).each do |klass|
|
||||
importer = double(:importer)
|
||||
waiter = Gitlab::JobWaiter.new(2, '123')
|
||||
|
||||
expect(klass)
|
||||
.to receive(:new)
|
||||
.with(project, client)
|
||||
.and_return(importer)
|
||||
|
||||
expect(importer)
|
||||
.to receive(:execute)
|
||||
.and_return(waiter)
|
||||
end
|
||||
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, { '123' => 2 }, 'attachments')
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#importers' do
|
||||
context 'when settings single_endpoint_notes_import is enabled' do
|
||||
it 'includes single endpoint mr and issue notes importers' do
|
||||
expect(worker.importers(project)).to contain_exactly(
|
||||
Gitlab::GithubImport::Importer::SingleEndpointMergeRequestNotesImporter,
|
||||
Gitlab::GithubImport::Importer::SingleEndpointIssueNotesImporter
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when settings single_endpoint_notes_import is disabled' do
|
||||
let(:single_endpoint_optional_stage) { false }
|
||||
|
||||
it 'includes default notes importer' do
|
||||
expect(worker.importers(project)).to contain_exactly(
|
||||
Gitlab::GithubImport::Importer::NotesImporter
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Stage::ImportPullRequestsMergedByWorker, feature_category: :importers do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
subject(:worker) { described_class.new }
|
||||
|
||||
it_behaves_like Gitlab::GithubImport::StageMethods
|
||||
|
||||
describe '#import' do
|
||||
it 'imports all the pull requests' do
|
||||
importer = double(:importer)
|
||||
client = double(:client)
|
||||
waiter = Gitlab::JobWaiter.new(2, '123')
|
||||
|
||||
expect(Gitlab::GithubImport::Importer::PullRequests::AllMergedByImporter)
|
||||
.to receive(:new)
|
||||
.with(project, client)
|
||||
.and_return(importer)
|
||||
|
||||
expect(importer)
|
||||
.to receive(:execute)
|
||||
.and_return(waiter)
|
||||
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, { '123' => 2 }, 'pull_request_review_requests')
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Stage::ImportPullRequestsReviewRequestsWorker, feature_category: :importers do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let(:client) { instance_double(Gitlab::GithubImport::Client) }
|
||||
let(:importer) { instance_double(Gitlab::GithubImport::Importer::PullRequests::ReviewRequestsImporter) }
|
||||
let(:waiter) { Gitlab::JobWaiter.new(2, '123') }
|
||||
|
||||
subject(:worker) { described_class.new }
|
||||
|
||||
it_behaves_like Gitlab::GithubImport::StageMethods
|
||||
|
||||
describe '#import' do
|
||||
it 'imports all PR review requests' do
|
||||
expect(Gitlab::GithubImport::Importer::PullRequests::ReviewRequestsImporter)
|
||||
.to receive(:new)
|
||||
.with(project, client)
|
||||
.and_return(importer)
|
||||
|
||||
expect(importer).to receive(:execute).and_return(waiter)
|
||||
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, { '123' => 2 }, 'pull_request_reviews')
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GithubImport::Stage::ImportPullRequestsReviewsWorker, feature_category: :importers do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let(:client) { double(:client) }
|
||||
|
||||
subject(:worker) { described_class.new }
|
||||
|
||||
it_behaves_like Gitlab::GithubImport::StageMethods
|
||||
|
||||
describe '#import' do
|
||||
it 'imports all the pull request reviews' do
|
||||
importer = double(:importer)
|
||||
|
||||
waiter = Gitlab::JobWaiter.new(2, '123')
|
||||
|
||||
expect(Gitlab::GithubImport::Importer::PullRequests::ReviewsImporter)
|
||||
.to receive(:new)
|
||||
.with(project, client)
|
||||
.and_return(importer)
|
||||
|
||||
expect(importer)
|
||||
.to receive(:execute)
|
||||
.and_return(waiter)
|
||||
|
||||
expect(Gitlab::GithubImport::AdvanceStageWorker)
|
||||
.to receive(:perform_async)
|
||||
.with(project.id, { '123' => 2 }, 'issues_and_diff_notes')
|
||||
|
||||
worker.import(client, project)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue