diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-08-19 03:10:34 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-08-19 03:10:34 +0300 |
commit | 57a4861dd1841a53cb966b566b1eee4adb254675 (patch) | |
tree | 14f31aaf16966c72cb68a8434bee279877b701b3 | |
parent | bfce95a4c5e9d71ed523f48f3fb901d2b7af60f7 (diff) |
Add latest changes from gitlab-org/gitlab@master
40 files changed, 334 insertions, 196 deletions
diff --git a/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue b/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue index 5d73ac44bab..d8cffc6a7d5 100644 --- a/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue +++ b/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue @@ -86,15 +86,18 @@ export default { </a> </td> <td class="d-flex flex-wrap flex-lg-nowrap"> - <select2-select v-model="targetNamespaceSelect" :options="select2Options" /> - <span class="px-2 import-slash-divider d-flex justify-content-center align-items-center" - >/</span - > - <input - v-model="newNameInput" - type="text" - class="form-control import-project-name-input qa-project-path-field" - /> + <template v-if="repo.target">{{ repo.target }}</template> + <template v-else> + <select2-select v-model="targetNamespaceSelect" :options="select2Options" /> + <span class="px-2 import-slash-divider d-flex justify-content-center align-items-center" + >/</span + > + <input + v-model="newNameInput" + type="text" + class="form-control import-project-name-input qa-project-path-field" + /> + </template> </td> <td> <import-status :status="repo.importStatus" /> diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index a56470dd893..438522245e3 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -2,7 +2,7 @@ import { mapActions, mapState, mapGetters } from 'vuex'; import VueDraggable from 'vuedraggable'; import Mousetrap from 'mousetrap'; -import { GlIcon, GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui'; +import { GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui'; import DashboardHeader from './dashboard_header.vue'; import DashboardPanel from './dashboard_panel.vue'; import { s__ } from '~/locale'; @@ -34,7 +34,6 @@ export default { DashboardHeader, DashboardPanel, Icon, - GlIcon, GlButton, GraphGroup, EmptyState, @@ -389,7 +388,8 @@ export default { }, }, i18n: { - goBackLabel: s__('Metrics|Go back (Esc)'), + collapsePanelLabel: s__('Metrics|Collapse panel'), + collapsePanelTooltip: s__('Metrics|Collapse panel (Esc)'), }, }; </script> @@ -429,14 +429,10 @@ export default { ref="goBackBtn" v-gl-tooltip class="mr-3 my-3" - :title="$options.i18n.goBackLabel" + :title="$options.i18n.collapsePanelTooltip" @click="onGoBack" > - <gl-icon - name="arrow-left" - :aria-label="$options.i18n.goBackLabel" - class="text-secondary" - /> + {{ $options.i18n.collapsePanelLabel }} </gl-button> </template> </dashboard-panel> diff --git a/app/assets/javascripts/pages/import/manifest/status/index.js b/app/assets/javascripts/pages/import/manifest/status/index.js new file mode 100644 index 00000000000..dcd84f0faf9 --- /dev/null +++ b/app/assets/javascripts/pages/import/manifest/status/index.js @@ -0,0 +1,7 @@ +import mountImportProjectsTable from '~/import_projects'; + +document.addEventListener('DOMContentLoaded', () => { + const mountElement = document.getElementById('import-projects-mount-element'); + + mountImportProjectsTable(mountElement); +}); diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue index ea1379ee1d5..d932588bee1 100644 --- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue +++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue @@ -1,7 +1,7 @@ <script> import { GlIcon, - GlDeprecatedButton, + GlButton, GlDeprecatedDropdown, GlDeprecatedDropdownItem, GlFormGroup, @@ -28,7 +28,7 @@ const events = { export default { components: { GlIcon, - GlDeprecatedButton, + GlButton, GlDeprecatedDropdown, GlDeprecatedDropdownItem, GlFormGroup, @@ -250,10 +250,15 @@ export default { /> </div> <gl-form-group> - <gl-deprecated-button @click="closeDropdown">{{ __('Cancel') }}</gl-deprecated-button> - <gl-deprecated-button variant="success" :disabled="!isValid" @click="setFixedRange()"> + <gl-button @click="closeDropdown">{{ __('Cancel') }}</gl-button> + <gl-button + variant="success" + category="primary" + :disabled="!isValid" + @click="setFixedRange()" + > {{ __('Apply') }} - </gl-deprecated-button> + </gl-button> </gl-form-group> </gl-form-group> <gl-form-group diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 62cf3079c20..69e00f9b2c4 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -871,7 +871,7 @@ $popover-max-width: 384px; $popover-box-shadow: 0 2px 3px 1px $gray-100; /* -Issues Analytics +Issue Analytics */ $issues-analytics-popover-boarder-color: rgba(0, 0, 0, 0.15); diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb index bc05030f8af..8a7a4c92b37 100644 --- a/app/controllers/import/base_controller.rb +++ b/app/controllers/import/base_controller.rb @@ -41,6 +41,10 @@ class Import::BaseController < ApplicationController raise NotImplementedError end + def extra_representation_opts + {} + end + private def filter_attribute @@ -58,11 +62,11 @@ class Import::BaseController < ApplicationController end def serialized_provider_repos - Import::ProviderRepoSerializer.new(current_user: current_user).represent(importable_repos, provider: provider_name, provider_url: provider_url) + Import::ProviderRepoSerializer.new(current_user: current_user).represent(importable_repos, provider: provider_name, provider_url: provider_url, **extra_representation_opts) end def serialized_incompatible_repos - Import::ProviderRepoSerializer.new(current_user: current_user).represent(incompatible_repos, provider: provider_name, provider_url: provider_url) + Import::ProviderRepoSerializer.new(current_user: current_user).represent(incompatible_repos, provider: provider_name, provider_url: provider_url, **extra_representation_opts) end def serialized_imported_projects diff --git a/app/controllers/import/manifest_controller.rb b/app/controllers/import/manifest_controller.rb index 9aec870c6ea..9c47e6d4b0b 100644 --- a/app/controllers/import/manifest_controller.rb +++ b/app/controllers/import/manifest_controller.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class Import::ManifestController < Import::BaseController + extend ::Gitlab::Utils::Override + before_action :whitelist_query_limiting, only: [:create] before_action :verify_import_enabled before_action :ensure_import_vars, only: [:create, :status] @@ -8,16 +10,9 @@ class Import::ManifestController < Import::BaseController def new end - # rubocop: disable CodeReuse/ActiveRecord def status - @already_added_projects = find_already_added_projects - already_added_import_urls = @already_added_projects.pluck(:import_url) - - @pending_repositories = repositories.to_a.reject do |repository| - already_added_import_urls.include?(repository[:url]) - end + super end - # rubocop: enable CodeReuse/ActiveRecord def upload group = Group.find(params[:group_id]) @@ -42,8 +37,8 @@ class Import::ManifestController < Import::BaseController end end - def jobs - render json: find_jobs + def realtime_changes + super end def create @@ -54,12 +49,43 @@ class Import::ManifestController < Import::BaseController project = Gitlab::ManifestImport::ProjectCreator.new(repository, group, current_user).execute if project.persisted? - render json: ProjectSerializer.new.represent(project) + render json: ProjectSerializer.new.represent(project, serializer: :import) else render json: { errors: project_save_error(project) }, status: :unprocessable_entity end end + protected + + # rubocop: disable CodeReuse/ActiveRecord + override :importable_repos + def importable_repos + already_added_projects_names = already_added_projects.pluck(:import_url) + + repositories.reject { |repo| already_added_projects_names.include?(repo[:url]) } + end + # rubocop: enable CodeReuse/ActiveRecord + + override :incompatible_repos + def incompatible_repos + [] + end + + override :provider_name + def provider_name + :manifest + end + + override :provider_url + def provider_url + nil + end + + override :extra_representation_opts + def extra_representation_opts + { group_full_path: group.full_path } + end + private def ensure_import_vars @@ -82,15 +108,6 @@ class Import::ManifestController < Import::BaseController find_already_added_projects.to_json(only: [:id], methods: [:import_status]) end - # rubocop: disable CodeReuse/ActiveRecord - def find_already_added_projects - group.all_projects - .where(import_type: 'manifest') - .where(creator_id: current_user) - .with_import_state - end - # rubocop: enable CodeReuse/ActiveRecord - def verify_import_enabled render_404 unless manifest_import_enabled? end diff --git a/app/serializers/import/manifest_provider_repo_entity.rb b/app/serializers/import/manifest_provider_repo_entity.rb new file mode 100644 index 00000000000..5da9aae80a8 --- /dev/null +++ b/app/serializers/import/manifest_provider_repo_entity.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class Import::ManifestProviderRepoEntity < Import::BaseProviderRepoEntity + expose :id + expose :full_name, override: true do |repo| + repo[:url] + end + + expose :provider_link, override: true do |repo| + repo[:url] + end + + expose :target do |repo, options| + import_project_target(options[:group_full_path], repo[:path], options[:request].current_user) + end + + private + + def import_project_target(owner, name, user) + namespace = user.can_create_group? ? owner : user.namespace_path + "#{namespace}/#{name}" + end +end diff --git a/app/serializers/import/provider_repo_serializer.rb b/app/serializers/import/provider_repo_serializer.rb index 5a9549d79aa..edd1a260146 100644 --- a/app/serializers/import/provider_repo_serializer.rb +++ b/app/serializers/import/provider_repo_serializer.rb @@ -14,6 +14,8 @@ class Import::ProviderRepoSerializer < BaseSerializer Import::BitbucketServerProviderRepoEntity when :gitlab Import::GitlabProviderRepoEntity + when :manifest + Import::ManifestProviderRepoEntity else raise NotImplementedError end diff --git a/app/views/import/manifest/status.html.haml b/app/views/import/manifest/status.html.haml index e85162ad1b4..c3e77554b09 100644 --- a/app/views/import/manifest/status.html.haml +++ b/app/views/import/manifest/status.html.haml @@ -1,42 +1,7 @@ - page_title _("Manifest import") - header_title _("Projects"), root_path -- provider = 'manifest' %h3.page-title = _('Manifest file import') -%p - = button_tag class: "btn btn-import btn-success js-import-all" do - = _('Import all repositories') - = icon("spinner spin", class: "loading-icon") - -.table-responsive - %table.table.import-jobs - %thead - %tr - %th= _('Repository URL') - %th= _('To GitLab') - %th= _('Status') - %tbody - - @already_added_projects.each do |project| - %tr{ id: "project_#{project.id}", class: project_status_css_class(project.import_status) } - %td - = project.import_url - %td - = link_to_project project - %td.job-status - = render 'import/project_status', project: project - - - @pending_repositories.each do |repository| - %tr{ id: "repo_#{repository[:id]}" } - %td - = repository[:url] - %td.import-target - = import_project_target(@group.full_path, repository[:path]) - %td.import-actions.job-status - = button_tag class: "btn btn-import js-add-to-import" do - = _('Import') - = icon("spinner spin", class: "loading-icon") - -.js-importer-status{ data: { jobs_import_path: url_for([:jobs, :import, provider]), - import_path: url_for([:import, provider]) } } += render 'import/githubish_status', provider: 'manifest' diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml index fa7ab0666cc..a04ed87801a 100644 --- a/app/views/profiles/emails/index.html.haml +++ b/app/views/profiles/emails/index.html.haml @@ -60,4 +60,4 @@ = link_to profile_email_path(email), data: { confirm: _('Are you sure?'), qa_selector: 'delete_email_link'}, method: :delete, class: 'btn btn-sm btn-danger gl-ml-3' do %span.sr-only= _('Remove') - = icon('trash') + = sprite_icon('remove') diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml index 1755a88246b..ca71aa8a24d 100644 --- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml +++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml @@ -37,4 +37,4 @@ = sprite_icon('pencil') - if can?(current_user, :admin_pipeline_schedule, pipeline_schedule) = link_to pipeline_schedule_path(pipeline_schedule), title: _('Delete'), method: :delete, class: 'btn btn-remove', data: { confirm: _("Are you sure you want to delete this pipeline schedule?") } do - = icon('trash') + = sprite_icon('remove') diff --git a/app/views/shared/members/_group.html.haml b/app/views/shared/members/_group.html.haml index 1d7d18d2ab6..f59e0f92c60 100644 --- a/app/views/shared/members/_group.html.haml +++ b/app/views/shared/members/_group.html.haml @@ -46,4 +46,4 @@ class: 'btn btn-remove m-0 ml-sm-2 align-self-center' do %span.d-block.d-sm-none = _("Delete") - = icon('trash', class: 'd-none d-sm-block') + = sprite_icon('remove', css_class: 'd-none d-sm-block') diff --git a/changelogs/unreleased/225950-replace-fa-trash-and-fa-trash-o-icons-with-gitlab-svg-remove-icon-.yml b/changelogs/unreleased/225950-replace-fa-trash-and-fa-trash-o-icons-with-gitlab-svg-remove-icon-.yml new file mode 100644 index 00000000000..256515fc73c --- /dev/null +++ b/changelogs/unreleased/225950-replace-fa-trash-and-fa-trash-o-icons-with-gitlab-svg-remove-icon-.yml @@ -0,0 +1,5 @@ +--- +title: Replace some fa-trash icons with GitLab SVG remove icon +merge_request: 38964 +author: +type: other diff --git a/changelogs/unreleased/227020-replace-go-back--with-collapse.yml b/changelogs/unreleased/227020-replace-go-back--with-collapse.yml new file mode 100644 index 00000000000..8ca80df1c3b --- /dev/null +++ b/changelogs/unreleased/227020-replace-go-back--with-collapse.yml @@ -0,0 +1,5 @@ +--- +title: Replace Go Back with Collapse button for expanded Metric charts +merge_request: 39307 +author: +type: changed diff --git a/changelogs/unreleased/xanf-migrate-manifest-importer.yml b/changelogs/unreleased/xanf-migrate-manifest-importer.yml new file mode 100644 index 00000000000..2b8c614b0d3 --- /dev/null +++ b/changelogs/unreleased/xanf-migrate-manifest-importer.yml @@ -0,0 +1,5 @@ +--- +title: Switch manifest importer to new UI +merge_request: 38268 +author: +type: changed diff --git a/config/routes/import.rb b/config/routes/import.rb index 94c69b57e2d..0d3f202ba55 100644 --- a/config/routes/import.rb +++ b/config/routes/import.rb @@ -71,7 +71,7 @@ namespace :import do resource :manifest, only: [:create, :new], controller: :manifest do get :status - get :jobs + get :realtime_changes post :upload end diff --git a/config/webpack.config.js b/config/webpack.config.js index 374b8fdbbc3..49e865d668d 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -278,7 +278,7 @@ module.exports = { monaco: { priority: 15, name: 'monaco', - chunks: 'initial', + chunks: 'all', test: /[\\/]node_modules[\\/]monaco-editor[\\/]/, minChunks: 2, reuseExistingChunk: true, diff --git a/doc/README.md b/doc/README.md index 02a3e0981eb..b73300accab 100644 --- a/doc/README.md +++ b/doc/README.md @@ -156,7 +156,7 @@ The following documentation relates to the DevOps **Create** stage: | [File locking](user/project/file_lock.md) **(PREMIUM)** | Lock files to avoid merge conflicts. | | [GitLab Pages](user/project/pages/index.md) | Build, test, and deploy your static website with GitLab Pages. | | [Groups](user/group/index.md) and [Subgroups](user/group/subgroups/index.md) | Organize your projects in groups. | -| [Issues Analytics](user/group/issues_analytics/index.md) **(PREMIUM)** | Check how many issues were created per month. | +| [Issue Analytics](user/group/issues_analytics/index.md) **(PREMIUM)** | Check how many issues were created per month. | | [Merge Request Analytics](user/analytics/merge_request_analytics.md) **(PREMIUM)** | Check your throughput productivity - how many merge requests were merged per month. | | [Projects](user/project/index.md), including [project access](public_access/public_access.md)<br/>and [settings](user/project/settings/index.md) | Host source code, and control your project's visibility and set configuration. | | [Search through GitLab](user/search/index.md) | Search for issues, merge requests, projects, groups, and todos. | diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md index 485dddfce9d..f8ecc6bfaa1 100644 --- a/doc/administration/gitaly/praefect.md +++ b/doc/administration/gitaly/praefect.md @@ -1004,8 +1004,19 @@ Feature.enable(:gitaly_reference_transactions) Feature.disable(:gitaly_reference_transactions_primary_wins) ``` -To monitor strong consistency, use the `gitaly_praefect_transactions_total` and -`gitaly_praefect_transactions_delay_seconds` Prometheus counter metrics. +To monitor strong consistency, you can use the following Prometheus metrics: + +- `gitaly_praefect_transactions_total`: Number of transactions created and + voted on. +- `gitaly_praefect_subtransactions_per_transaction_total`: Number of times + nodes cast a vote for a single transaction. This can happen multiple times if + multiple references are getting updated in a single transaction. +- `gitaly_praefect_voters_per_transaction_total`: Number of Gitaly nodes taking + part in a transaction. +- `gitaly_praefect_transactions_delay_seconds`: Server-side delay introduced by + waiting for the transaction to be committed. +- `gitaly_hook_transaction_voting_delay_seconds`: Client-side delay introduced + by waiting for the transaction to be committed. ## Automatic failover and leader election diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md index 96aff919ccd..47852cb0498 100644 --- a/doc/user/analytics/index.md +++ b/doc/user/analytics/index.md @@ -24,7 +24,7 @@ The following analytics features are available at the group level: - [Contribution](../group/contribution_analytics/index.md). **(STARTER)** - [Insights](../group/insights/index.md). **(ULTIMATE)** -- [Issues](../group/issues_analytics/index.md). **(PREMIUM)** +- [Issue](../group/issues_analytics/index.md). **(PREMIUM)** - [Productivity](productivity_analytics.md), enabled with the `productivity_analytics` [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-locally-in-development). **(PREMIUM)** - [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics` @@ -37,7 +37,7 @@ The following analytics features are available at the project level: - [CI/CD](../../ci/pipelines/index.md#pipeline-success-and-duration-charts). **(STARTER)** - [Code Review](code_review_analytics.md). **(STARTER)** - [Insights](../group/insights/index.md). **(ULTIMATE)** -- [Issues](../group/issues_analytics/index.md). **(PREMIUM)** +- [Issue](../group/issues_analytics/index.md). **(PREMIUM)** - [Merge Request](merge_request_analytics.md). **(STARTER)** - [Repository](repository_analytics.md). - [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics` diff --git a/doc/user/group/index.md b/doc/user/group/index.md index 0d7d9bb2a7b..22ad311ab4f 100644 --- a/doc/user/group/index.md +++ b/doc/user/group/index.md @@ -743,9 +743,9 @@ With [GitLab Contribution Analytics](contribution_analytics/index.md), you have an overview of the contributions (pushes, merge requests, and issues) performed by your group members. -## Issues analytics **(PREMIUM)** +## Issue analytics **(PREMIUM)** -With [GitLab Issues Analytics](issues_analytics/index.md), you can see a bar chart of the number of issues created each month in your groups. +With [GitLab Issue Analytics](issues_analytics/index.md), you can see a bar chart of the number of issues created each month in your groups. ## Dependency Proxy **(PREMIUM)** diff --git a/doc/user/group/issues_analytics/index.md b/doc/user/group/issues_analytics/index.md index 01cee3d09b8..69512f90fca 100644 --- a/doc/user/group/issues_analytics/index.md +++ b/doc/user/group/issues_analytics/index.md @@ -5,16 +5,16 @@ group: Analytics info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers --- -# Issues Analytics **(PREMIUM)** +# Issue Analytics **(PREMIUM)** > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7478) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.5. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196561) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9 at the project level. -Issues Analytics is a bar graph which illustrates the number of issues created each month. +Issue Analytics is a bar graph which illustrates the number of issues created each month. The default timespan is 13 months, which includes the current month, and the 12 months prior. -To access the chart, navigate to your group or project sidebar and select **{chart}** **Analytics > Issues Analytics**. +To access the chart, navigate to your group or project sidebar and select **{chart}** **Analytics > Issue Analytics**. Hover over each bar to see the total number of issues. diff --git a/doc/user/permissions.md b/doc/user/permissions.md index 0b541eb248a..a89d534c782 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -167,7 +167,7 @@ The following table depicts the various user permission levels in a project. | View CI\CD analytics | | ✓ | ✓ | ✓ | ✓ | | View Code Review analytics **(STARTER)** | | ✓ | ✓ | ✓ | ✓ | | View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | -| View Issues analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | +| View Issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | | View Merge Request analytics **(STARTER)** | ✓ | ✓ | ✓ | ✓ | ✓ | | View Repository analytics | | ✓ | ✓ | ✓ | ✓ | | View Value Stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ | @@ -272,7 +272,7 @@ group. | Disable notification emails | | | | | ✓ | | View Contribution analytics | ✓ | ✓ | ✓ | ✓ | ✓ | | View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | -| View Issues analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | +| View Issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | | View Productivity analytics **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ | | View Value Stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ | | View Billing **(FREE ONLY)** | | | | | ✓ (4) | diff --git a/doc/user/project/import/img/manifest_status.png b/doc/user/project/import/img/manifest_status.png Binary files differdeleted file mode 100644 index b706116a2ac..00000000000 --- a/doc/user/project/import/img/manifest_status.png +++ /dev/null diff --git a/doc/user/project/import/img/manifest_status_v13_3.png b/doc/user/project/import/img/manifest_status_v13_3.png Binary files differnew file mode 100644 index 00000000000..3f0063e6715 --- /dev/null +++ b/doc/user/project/import/img/manifest_status_v13_3.png diff --git a/doc/user/project/import/manifest.md b/doc/user/project/import/manifest.md index 0374e0acf9a..60524f3cc69 100644 --- a/doc/user/project/import/manifest.md +++ b/doc/user/project/import/manifest.md @@ -62,4 +62,4 @@ You can start the import with: to the import status page with projects list based on the manifest file. 1. Check the list and click **Import all repositories** to start the import. - ![Manifest status](img/manifest_status.png) + ![Manifest status](img/manifest_status_v13_3.png) diff --git a/lib/api/composer_packages.rb b/lib/api/composer_packages.rb index fd37a4ff1ad..05887e58425 100644 --- a/lib/api/composer_packages.rb +++ b/lib/api/composer_packages.rb @@ -59,7 +59,7 @@ module API desc 'Composer packages endpoint at group level' - route_setting :authentication, job_token_allowed: true + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true get ':id/-/packages/composer/packages' do presenter.root @@ -71,7 +71,7 @@ module API requires :sha, type: String, desc: 'Shasum of current json' end - route_setting :authentication, job_token_allowed: true + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true get ':id/-/packages/composer/p/:sha' do presenter.provider @@ -83,7 +83,7 @@ module API requires :package_name, type: String, file_path: true, desc: 'The Composer package name' end - route_setting :authentication, job_token_allowed: true + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true get ':id/-/packages/composer/*package_name', requirements: COMPOSER_ENDPOINT_REQUIREMENTS, file_path: true do not_found! if packages.empty? @@ -104,7 +104,7 @@ module API desc 'Composer packages endpoint for registering packages' namespace ':id/packages/composer' do - route_setting :authentication, job_token_allowed: true + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true params do optional :branch, type: String, desc: 'The name of the branch' diff --git a/lib/api/conan_packages.rb b/lib/api/conan_packages.rb index 6888929874f..6923d252fbd 100644 --- a/lib/api/conan_packages.rb +++ b/lib/api/conan_packages.rb @@ -38,7 +38,9 @@ module API desc 'Ping the Conan API' do detail 'This feature was introduced in GitLab 12.2' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get 'ping' do header 'X-Conan-Server-Capabilities', [].join(',') end @@ -46,10 +48,13 @@ module API desc 'Search for packages' do detail 'This feature was introduced in GitLab 12.4' end + params do requires :q, type: String, desc: 'Search query' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get 'conans/search' do service = ::Packages::Conan::SearchService.new(current_user, query: params[:q]).execute service.payload @@ -61,7 +66,9 @@ module API desc 'Authenticate user against conan CLI' do detail 'This feature was introduced in GitLab 12.2' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get 'authenticate' do unauthorized! unless token @@ -71,7 +78,9 @@ module API desc 'Check for valid user credentials per conan CLI' do detail 'This feature was introduced in GitLab 12.4' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get 'check_credentials' do authenticate! :ok @@ -93,10 +102,13 @@ module API desc 'Package Snapshot' do detail 'This feature was introduced in GitLab 12.5' end + params do requires :conan_package_reference, type: String, desc: 'Conan package ID' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get 'packages/:conan_package_reference' do authorize!(:read_package, project) @@ -113,7 +125,9 @@ module API desc 'Recipe Snapshot' do detail 'This feature was introduced in GitLab 12.5' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get do authorize!(:read_package, project) @@ -133,7 +147,9 @@ module API params do requires :conan_package_reference, type: String, desc: 'Conan package ID' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get 'packages/:conan_package_reference/digest' do present_package_download_urls end @@ -141,7 +157,9 @@ module API desc 'Recipe Digest' do detail 'This feature was introduced in GitLab 12.5' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get 'digest' do present_recipe_download_urls end @@ -155,10 +173,13 @@ module API desc 'Package Download Urls' do detail 'This feature was introduced in GitLab 12.5' end + params do requires :conan_package_reference, type: String, desc: 'Conan package ID' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get 'packages/:conan_package_reference/download_urls' do present_package_download_urls end @@ -166,7 +187,9 @@ module API desc 'Recipe Download Urls' do detail 'This feature was introduced in GitLab 12.5' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get 'download_urls' do present_recipe_download_urls end @@ -181,10 +204,13 @@ module API desc 'Package Upload Urls' do detail 'This feature was introduced in GitLab 12.4' end + params do requires :conan_package_reference, type: String, desc: 'Conan package ID' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + post 'packages/:conan_package_reference/upload_urls' do authorize!(:read_package, project) @@ -195,7 +221,9 @@ module API desc 'Recipe Upload Urls' do detail 'This feature was introduced in GitLab 12.4' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + post 'upload_urls' do authorize!(:read_package, project) @@ -206,7 +234,9 @@ module API desc 'Delete Package' do detail 'This feature was introduced in GitLab 12.5' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + delete do authorize!(:destroy_package, project) @@ -235,7 +265,9 @@ module API desc 'Download recipe files' do detail 'This feature was introduced in GitLab 12.6' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get do download_package_file(:recipe_file) end @@ -243,10 +275,13 @@ module API desc 'Upload recipe package files' do detail 'This feature was introduced in GitLab 12.6' end + params do use :workhorse_upload_params end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + put do upload_package_file(:recipe_file) end @@ -254,7 +289,9 @@ module API desc 'Workhorse authorize the conan recipe file' do detail 'This feature was introduced in GitLab 12.6' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + put 'authorize' do authorize_workhorse!(subject: project) end @@ -269,7 +306,9 @@ module API desc 'Download package files' do detail 'This feature was introduced in GitLab 12.5' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + get do download_package_file(:package_file) end @@ -277,7 +316,9 @@ module API desc 'Workhorse authorize the conan package file' do detail 'This feature was introduced in GitLab 12.6' end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + put 'authorize' do authorize_workhorse!(subject: project) end @@ -285,10 +326,13 @@ module API desc 'Upload package files' do detail 'This feature was introduced in GitLab 12.6' end + params do use :workhorse_upload_params end - route_setting :authentication, job_token_allowed: true + + route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true + put do upload_package_file(:package_file) end diff --git a/lib/api/helpers/packages_manager_clients_helpers.rb b/lib/api/helpers/packages_manager_clients_helpers.rb index 7b5d0dd708d..ae16b65aaa8 100644 --- a/lib/api/helpers/packages_manager_clients_helpers.rb +++ b/lib/api/helpers/packages_manager_clients_helpers.rb @@ -16,16 +16,6 @@ module API optional 'file.sha256', type: String, desc: 'SHA256 checksum of the file (generated by Workhorse)' end - def find_personal_access_token_from_http_basic_auth - return unless headers - - token = decode_token - - return unless token - - PersonalAccessToken.find_by_token(token) - end - def find_job_from_http_basic_auth return unless headers diff --git a/lib/api/nuget_packages.rb b/lib/api/nuget_packages.rb index 0092a68266e..56c4de2071d 100644 --- a/lib/api/nuget_packages.rb +++ b/lib/api/nuget_packages.rb @@ -55,7 +55,7 @@ module API requires :id, type: String, desc: 'The ID of a project', regexp: POSITIVE_INTEGER_REGEX end - route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth + route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do before do @@ -68,7 +68,7 @@ module API detail 'This feature was introduced in GitLab 12.6' end - route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth + route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true get 'index', format: :json do authorize_read_package!(authorized_user_project) @@ -88,7 +88,7 @@ module API requires :package, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)' end - route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth + route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true put do authorize_upload!(authorized_user_project) @@ -115,7 +115,7 @@ module API forbidden! end - route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth + route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true put 'authorize' do authorize_workhorse!(subject: authorized_user_project, has_length: false) @@ -134,7 +134,7 @@ module API detail 'This feature was introduced in GitLab 12.8' end - route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth + route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true get 'index', format: :json do present ::Packages::Nuget::PackagesMetadataPresenter.new(find_packages), @@ -148,7 +148,7 @@ module API requires :package_version, type: String, desc: 'The NuGet package version', regexp: API::NO_SLASH_URL_PART_REGEX end - route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth + route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true get '*package_version', format: :json do present ::Packages::Nuget::PackageMetadataPresenter.new(find_package), @@ -169,7 +169,7 @@ module API detail 'This feature was introduced in GitLab 12.8' end - route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth + route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true get 'index', format: :json do present ::Packages::Nuget::PackagesVersionsPresenter.new(find_packages), @@ -184,7 +184,7 @@ module API requires :package_filename, type: String, desc: 'The NuGet package filename', regexp: API::NO_SLASH_URL_PART_REGEX end - route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth + route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true get '*package_version/*package_filename', format: :nupkg do filename = "#{params[:package_filename]}.#{params[:format]}" @@ -216,7 +216,7 @@ module API detail 'This feature was introduced in GitLab 12.8' end - route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth + route_setting :authentication, deploy_token_allowed: true, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true get format: :json do search_options = { diff --git a/lib/api/pypi_packages.rb b/lib/api/pypi_packages.rb index b743eed75fb..739928a61ed 100644 --- a/lib/api/pypi_packages.rb +++ b/lib/api/pypi_packages.rb @@ -64,7 +64,7 @@ module API requires :sha256, type: String, desc: 'The PyPi package sha256 check sum' end - route_setting :authentication, deploy_token_allowed: true + route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true get 'files/:sha256/*file_identifier' do project = unauthorized_user_project! @@ -87,7 +87,7 @@ module API # An Api entry point but returns an HTML file instead of JSON. # PyPi simple API returns the package descriptor as a simple HTML file. - route_setting :authentication, deploy_token_allowed: true + route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true get 'simple/*package_name', format: :txt do authorize_read_package!(authorized_user_project) @@ -117,7 +117,7 @@ module API optional :sha256_digest, type: String end - route_setting :authentication, deploy_token_allowed: true + route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true post do authorize_upload!(authorized_user_project) @@ -134,7 +134,7 @@ module API forbidden! end - route_setting :authentication, deploy_token_allowed: true + route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true post 'authorize' do authorize_workhorse!(subject: authorized_user_project, has_length: false) end diff --git a/lib/gitlab/manifest_import/project_creator.rb b/lib/gitlab/manifest_import/project_creator.rb index 837d65e5f7c..6637cbb9cc8 100644 --- a/lib/gitlab/manifest_import/project_creator.rb +++ b/lib/gitlab/manifest_import/project_creator.rb @@ -18,6 +18,7 @@ module Gitlab params = { import_url: repository[:url], + import_source: repository[:url], import_type: 'manifest', namespace_id: group.id, path: project_path, diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 64f705afa3d..f3237f7aea3 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -13381,6 +13381,9 @@ msgstr "" msgid "Issue %{issue_reference} has already been added to epic %{epic_reference}." msgstr "" +msgid "Issue Analytics" +msgstr "" + msgid "Issue Boards" msgstr "" @@ -13480,9 +13483,6 @@ msgstr "" msgid "Issues" msgstr "" -msgid "Issues Analytics" -msgstr "" - msgid "Issues Rate Limits" msgstr "" @@ -15344,6 +15344,12 @@ msgstr "" msgid "Metrics|Check out the CI/CD documentation on deploying to an environment" msgstr "" +msgid "Metrics|Collapse panel" +msgstr "" + +msgid "Metrics|Collapse panel (Esc)" +msgstr "" + msgid "Metrics|Copy YAML" msgstr "" @@ -15406,9 +15412,6 @@ msgstr "" msgid "Metrics|For grouping similar metrics" msgstr "" -msgid "Metrics|Go back (Esc)" -msgstr "" - msgid "Metrics|Invalid time range, please verify." msgstr "" @@ -20677,9 +20680,6 @@ msgstr "" msgid "Repository Settings" msgstr "" -msgid "Repository URL" -msgstr "" - msgid "Repository check" msgstr "" diff --git a/spec/controllers/import/manifest_controller_spec.rb b/spec/controllers/import/manifest_controller_spec.rb new file mode 100644 index 00000000000..ec8bd45b65c --- /dev/null +++ b/spec/controllers/import/manifest_controller_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Import::ManifestController do + include ImportSpecHelper + + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group)} + + before(:all) do + group.add_maintainer(user) + end + + before do + sign_in(user) + end + + def assign_session_group + session[:manifest_import_repositories] = [] + session[:manifest_import_group_id] = group.id + end + + describe 'GET status' do + let(:repo1) { OpenStruct.new(id: 'test1', url: 'http://demo.host/test1') } + let(:repo2) { OpenStruct.new(id: 'test2', url: 'http://demo.host/test2') } + let(:repos) { [repo1, repo2] } + + before do + assign_session_group + + session[:manifest_import_repositories] = repos + end + + it "returns variables for json request" do + project = create(:project, import_type: 'manifest', creator_id: user.id) + + get :status, format: :json + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response.dig("imported_projects", 0, "id")).to eq(project.id) + expect(json_response.dig("provider_repos", 0, "id")).to eq(repo1.id) + expect(json_response.dig("provider_repos", 1, "id")).to eq(repo2.id) + expect(json_response.dig("namespaces", 0, "id")).to eq(group.id) + end + + it "does not show already added project" do + project = create(:project, import_type: 'manifest', namespace: user.namespace, import_status: :finished, import_url: repo1.url) + + get :status, format: :json + + expect(json_response.dig("imported_projects", 0, "id")).to eq(project.id) + expect(json_response.dig("provider_repos").length).to eq(1) + expect(json_response.dig("provider_repos", 0, "id")).not_to eq(repo1.id) + end + end +end diff --git a/spec/features/import/manifest_import_spec.rb b/spec/features/import/manifest_import_spec.rb index 1efbc5642d4..9c359e932d5 100644 --- a/spec/features/import/manifest_import_spec.rb +++ b/spec/features/import/manifest_import_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'Import multiple repositories by uploading a manifest file', :js expect(page).to have_content('https://android-review.googlesource.com/platform/build/blueprint') end - it 'imports successfully imports a project', :sidekiq_inline do + it 'imports a project successfully', :sidekiq_inline, :js do visit new_import_manifest_path attach_file('manifest', Rails.root.join('spec/fixtures/aosp_manifest.xml')) @@ -32,7 +32,11 @@ RSpec.describe 'Import multiple repositories by uploading a manifest file', :js page.within(second_row) do click_on 'Import' + end + + wait_for_requests + page.within(second_row) do expect(page).to have_content 'Done' expect(page).to have_content("#{group.full_path}/build/blueprint") end @@ -48,6 +52,6 @@ RSpec.describe 'Import multiple repositories by uploading a manifest file', :js end def second_row - page.all('table.import-jobs tbody tr')[1] + page.all('table.import-table tbody tr')[1] end end diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb index 3526f6f75a5..4c079b98c90 100644 --- a/spec/features/merge_request/user_posts_notes_spec.rb +++ b/spec/features/merge_request/user_posts_notes_spec.rb @@ -108,15 +108,14 @@ RSpec.describe 'Merge request > User posts notes', :js do end context 'when comment is deleted' do - before do - note.delete - end - it 'shows an error message' do find('.js-reply-button').click page.within('.discussion-reply-holder') do fill_in 'note[note]', with: 'A reply' + + note.delete + click_button 'Add comment now' expect(page).to have_content('Your comment could not be submitted because discussion to reply to cannot be found') diff --git a/spec/lib/api/helpers/packages_manager_clients_helpers_spec.rb b/spec/lib/api/helpers/packages_manager_clients_helpers_spec.rb index 80be5f7d10a..832f4abe545 100644 --- a/spec/lib/api/helpers/packages_manager_clients_helpers_spec.rb +++ b/spec/lib/api/helpers/packages_manager_clients_helpers_spec.rb @@ -8,40 +8,6 @@ RSpec.describe API::Helpers::PackagesManagerClientsHelpers do let_it_be(:helper) { Class.new.include(described_class).new } let(:password) { personal_access_token.token } - describe '#find_personal_access_token_from_http_basic_auth' do - let(:headers) { { Authorization: basic_http_auth(username, password) } } - - subject { helper.find_personal_access_token_from_http_basic_auth } - - before do - allow(helper).to receive(:headers).and_return(headers&.with_indifferent_access) - end - - context 'with a valid Authorization header' do - it { is_expected.to eq personal_access_token } - end - - context 'with an invalid Authorization header' do - where(:headers) do - [ - [{ Authorization: 'Invalid' }], - [{}], - [nil] - ] - end - - with_them do - it { is_expected.to be nil } - end - end - - context 'with an unknown Authorization header' do - let(:password) { 'Unknown' } - - it { is_expected.to be nil } - end - end - describe '#find_job_from_http_basic_auth' do let_it_be(:user) { personal_access_token.user } diff --git a/spec/lib/gitlab/manifest_import/project_creator_spec.rb b/spec/lib/gitlab/manifest_import/project_creator_spec.rb index 354acf53b7a..0ab5b277552 100644 --- a/spec/lib/gitlab/manifest_import/project_creator_spec.rb +++ b/spec/lib/gitlab/manifest_import/project_creator_spec.rb @@ -23,13 +23,14 @@ RSpec.describe Gitlab::ManifestImport::ProjectCreator do it { expect { subject.execute }.to change { Project.count }.by(1) } it { expect { subject.execute }.to change { Group.count }.by(1) } - it 'creates project with valid full path and import url' do + it 'creates project with valid full path, import url and import source' do subject.execute project = Project.last expect(project.full_path).to eq(File.join(group.path, 'device/common')) expect(project.import_url).to eq('https://android-review.googlesource.com/device/common') + expect(project.import_source).to eq('https://android-review.googlesource.com/device/common') end end end diff --git a/spec/serializers/import/manifest_provider_repo_entity_spec.rb b/spec/serializers/import/manifest_provider_repo_entity_spec.rb new file mode 100644 index 00000000000..c11f8c42559 --- /dev/null +++ b/spec/serializers/import/manifest_provider_repo_entity_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Import::ManifestProviderRepoEntity do + let(:current_user) { create(:user) } + let(:request) { double(:request, current_user: current_user) } + let(:repo_data) do + { + id: 1, + url: 'http://demo.repo/url', + path: '/demo/path' + } + end + + subject { described_class.represent(repo_data, { group_full_path: 'group', request: request }).as_json } + + it_behaves_like 'exposes required fields for import entity' do + let(:expected_values) do + { + id: repo_data[:id], + full_name: repo_data[:url], + sanitized_name: nil, + provider_link: repo_data[:url] + } + end + end +end |