From 2194dac7530ff4efa1e12051522e79ac761af1f4 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 29 Mar 2022 18:08:06 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .../deprecated_project_avatar/default.vue | 47 -------- .../deprecated_project_avatar/image.vue | 81 ------------- .../vue_shared/components/identicon.vue | 35 ------ .../project_selector/project_list_item.vue | 11 +- .../projects/static_site_editor_controller.rb | 24 +--- doc/.vale/gitlab/spelling-exceptions.txt | 1 - doc/administration/auth/index.md | 1 - doc/administration/gitaly/configure_gitaly.md | 5 +- doc/api/runners.md | 4 +- doc/install/installation.md | 2 +- doc/integration/index.md | 4 +- doc/integration/omniauth.md | 3 +- doc/user/project/merge_requests/index.md | 3 +- doc/user/project/quick_actions.md | 1 + lib/gitlab/setup_helper.rb | 6 +- locale/gitlab.pot | 3 - qa/qa/tools/test_resources_handler.rb | 1 + .../static_site_editor_controller_spec.rb | 65 +--------- spec/features/static_site_editor_spec.rb | 113 ------------------ .../__snapshots__/identicon_spec.js.snap | 21 ---- .../vue_shared/components/identicon_spec.js | 50 -------- .../components/project_avatar/default_spec.js | 50 -------- .../project_list_item_spec.js | 9 +- spec/support/helpers/gitaly_setup.rb | 2 +- 24 files changed, 37 insertions(+), 505 deletions(-) delete mode 100644 app/assets/javascripts/vue_shared/components/deprecated_project_avatar/default.vue delete mode 100644 app/assets/javascripts/vue_shared/components/deprecated_project_avatar/image.vue delete mode 100644 app/assets/javascripts/vue_shared/components/identicon.vue delete mode 100644 spec/features/static_site_editor_spec.rb delete mode 100644 spec/frontend/vue_shared/components/__snapshots__/identicon_spec.js.snap delete mode 100644 spec/frontend/vue_shared/components/identicon_spec.js delete mode 100644 spec/frontend/vue_shared/components/project_avatar/default_spec.js diff --git a/app/assets/javascripts/vue_shared/components/deprecated_project_avatar/default.vue b/app/assets/javascripts/vue_shared/components/deprecated_project_avatar/default.vue deleted file mode 100644 index 733accdff44..00000000000 --- a/app/assets/javascripts/vue_shared/components/deprecated_project_avatar/default.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - diff --git a/app/assets/javascripts/vue_shared/components/deprecated_project_avatar/image.vue b/app/assets/javascripts/vue_shared/components/deprecated_project_avatar/image.vue deleted file mode 100644 index 269736c799c..00000000000 --- a/app/assets/javascripts/vue_shared/components/deprecated_project_avatar/image.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - diff --git a/app/assets/javascripts/vue_shared/components/identicon.vue b/app/assets/javascripts/vue_shared/components/identicon.vue deleted file mode 100644 index 87a995464fa..00000000000 --- a/app/assets/javascripts/vue_shared/components/identicon.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - diff --git a/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue b/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue index 0bd57c84018..19ffbe37ce7 100644 --- a/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue +++ b/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue @@ -3,7 +3,7 @@ import { GlButton, GlIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui'; import { isString } from 'lodash'; import highlight from '~/lib/utils/highlight'; import { truncateNamespace } from '~/lib/utils/text_utility'; -import ProjectAvatar from '~/vue_shared/components/deprecated_project_avatar/default.vue'; +import ProjectAvatar from '~/vue_shared/components/project_avatar.vue'; export default { name: 'ProjectListItem', @@ -22,6 +22,9 @@ export default { matcher: { type: String, required: false, default: '' }, }, computed: { + projectAvatarUrl() { + return this.project.avatar_url || this.project.avatarUrl; + }, projectNameWithNamespace() { return this.project.nameWithNamespace || this.project.name_with_namespace; }, @@ -49,7 +52,11 @@ export default { class="gl-display-flex gl-align-items-center gl-flex-wrap project-namespace-name-container" > - +
" \ # --or-- -# Deprecated: removal planned in 15.0 +# Deprecated: removal planned in 16.0 curl --request PUT --header "PRIVATE-TOKEN: " \ --form "active=false" "https://gitlab.example.com/api/v4/runners/6" ``` diff --git a/doc/install/installation.md b/doc/install/installation.md index 21d1ee84722..733a0344d51 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -1121,7 +1121,7 @@ host localhost # Give your setup a name (here: override localhost) hostname 127.0.0.1; # Your server name or IP ``` -You also need to change the corresponding options (for example, `ssh_user`, `ssh_host`, `admin_uri`) in the `config\gitlab.yml` file. +You also need to change the corresponding options (for example, `ssh_user`, `ssh_host`, `admin_uri`) in the `config/gitlab.yml` file. ### Additional Markup Styles diff --git a/doc/integration/index.md b/doc/integration/index.md index 61d8547aaf7..e7f6e01eea1 100644 --- a/doc/integration/index.md +++ b/doc/integration/index.md @@ -24,8 +24,8 @@ GitLab can be configured to authenticate access requests with the following auth - Integrate with [Kerberos](kerberos.md). - Enable sign in via [LDAP](../administration/auth/ldap/index.md). - Enable [OAuth2 provider](oauth_provider.md) application creation. -- Use [OmniAuth](omniauth.md) to enable sign in via Twitter, GitHub, GitLab.com, Google, - Bitbucket, Facebook, Shibboleth, SAML, Crowd, Azure, or Authentiq ID. +- Use [OmniAuth](omniauth.md) to enable sign in through Twitter, GitHub, GitLab.com, Google, + Bitbucket, Facebook, SAML, Crowd, Azure, or Authentiq ID. - Use GitLab as an [OpenID Connect](openid_connect_provider.md) identity provider. - Authenticate to [Vault](vault.md) through GitLab OpenID Connect. - Configure GitLab as a [SAML](saml.md) 2.0 Service Provider. diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md index cba07e505de..41722778410 100644 --- a/doc/integration/omniauth.md +++ b/doc/integration/omniauth.md @@ -41,7 +41,6 @@ GitLab supports the following OmniAuth providers. | [OpenID Connect](../administration/auth/oidc.md) | `openid_connect` | | [Salesforce](salesforce.md) | `salesforce` | | [SAML](saml.md) | `saml` | -| [Shibboleth](saml.md) | `shibboleth` | | [Twitter](twitter.md) | `twitter` | ## Configure initial settings @@ -53,7 +52,7 @@ Setting | Description | Default value ---------------------------|-------------|-------------- `allow_single_sign_on` | Enables you to list the providers that automatically create a GitLab account. The provider names are available in the **OmniAuth provider name** column in the [supported providers table](#supported-providers). | The default is `false`. If `false`, users must be created manually, or they can't sign in using OmniAuth. `auto_link_ldap_user` | If enabled, creates an LDAP identity in GitLab for users that are created through an OmniAuth provider. You can enable this setting if you have the [LDAP (ActiveDirectory)](../administration/auth/ldap/index.md) integration enabled. Requires the `uid` of the user to be the same in both LDAP and the OmniAuth provider. | The default is `false`. -`block_auto_created_users` | If enabled, blocks users that are automatically created from signing in until they are approved by an administrator. | The default is `true`. If you set the value to `false`, make sure you only define providers for `allow_single_sign_on` that you can control, like SAML, Shibboleth, Crowd, or Google. Otherwise, any user on the internet can sign in to GitLab without an administrator's approval. +`block_auto_created_users` | If enabled, blocks users that are automatically created from signing in until they are approved by an administrator. | The default is `true`. If you set the value to `false`, make sure you only define providers for `allow_single_sign_on` that you can control, like SAML, Crowd, or Google. Otherwise, any user on the internet can sign in to GitLab without an administrator's approval. To change these settings: diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md index 6f204792e59..a3b9fb52f0d 100644 --- a/doc/user/project/merge_requests/index.md +++ b/doc/user/project/merge_requests/index.md @@ -91,7 +91,8 @@ To view a list of merge requests that need your attention: 1. On the top bar, select **Merge requests** (**{merge-request}**). 1. Select **Attention requests**. -To request attention from another user: +To request attention from another user, use the `/attention @user` +[quick action](../quick_actions.md) or: 1. Go to the merge request. 1. On the right sidebar, identify the user you want to request attention from. diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md index ae42d90af06..b73b381ffcd 100644 --- a/doc/user/project/quick_actions.md +++ b/doc/user/project/quick_actions.md @@ -55,6 +55,7 @@ threads. Some quick actions might not be available to all subscription tiers. | `/assign me` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Assign yourself. | | `/assign_reviewer @user1 @user2` or `/reviewer @user1 @user2` or `/request_review @user1 @user2` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Assign one or more users as reviewers. | | `/assign_reviewer me` or `/reviewer me` or `/request_review me` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Assign yourself as a reviewer. | +| `/attention @user1` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | [Request attention](merge_requests/index.md#request-attention-to-a-merge-request) to a merge request from a user. | | `/award :emoji:` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Toggle emoji award. | | `/child_epic ` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Add child epic to ``. The `` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7330) in GitLab 12.0). | | `/clear_health_status` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Clear [health status](issues/managing_issues.md#health-status) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213814) in GitLab 14.7). | diff --git a/lib/gitlab/setup_helper.rb b/lib/gitlab/setup_helper.rb index a498e329c3f..1389939f28b 100644 --- a/lib/gitlab/setup_helper.rb +++ b/lib/gitlab/setup_helper.rb @@ -124,9 +124,9 @@ module Gitlab config[:storage] = storages - runtime_dir = options[:runtime_dir] || File.join(gitaly_dir, 'run') - FileUtils.mkdir(runtime_dir) unless File.exist?(runtime_dir) - config[:runtime_dir] = runtime_dir + internal_socket_dir = options[:internal_socket_dir] || File.join(gitaly_dir, 'internal_sockets') + FileUtils.mkdir(internal_socket_dir) unless File.exist?(internal_socket_dir) + config[:internal_socket_dir] = internal_socket_dir config[:'gitaly-ruby'] = { dir: File.join(gitaly_dir, 'ruby') } if gitaly_ruby config[:'gitlab-shell'] = { dir: Gitlab.config.gitlab_shell.path } diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 4055d53af07..39fa905bdda 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -45052,9 +45052,6 @@ msgstr "" msgid "project access tokens" msgstr "" -msgid "project avatar" -msgstr "" - msgid "project bots cannot be added to other groups / projects" msgstr "" diff --git a/qa/qa/tools/test_resources_handler.rb b/qa/qa/tools/test_resources_handler.rb index 476f87fff6b..d90e11a1681 100644 --- a/qa/qa/tools/test_resources_handler.rb +++ b/qa/qa/tools/test_resources_handler.rb @@ -81,6 +81,7 @@ module QA return puts "\nNothing to download!" if files_list.empty? + FileUtils.mkdir_p('tmp/') files_list.each do |file_name| local_path = "tmp/#{file_name.split('/').last}" Runtime::Logger.info("Downloading #{file_name} to #{local_path}") diff --git a/spec/controllers/projects/static_site_editor_controller_spec.rb b/spec/controllers/projects/static_site_editor_controller_spec.rb index 26161b5fb5c..e1f25589eeb 100644 --- a/spec/controllers/projects/static_site_editor_controller_spec.rb +++ b/spec/controllers/projects/static_site_editor_controller_spec.rb @@ -76,12 +76,11 @@ RSpec.describe Projects::StaticSiteEditorController do get :show, params: default_params end - it 'increases the views counter' do - expect(Gitlab::UsageDataCounters::StaticSiteEditorCounter).to have_received(:increment_views_count) - end + it 'redirects to the Web IDE' do + get :show, params: default_params - it 'renders the edit page' do - expect(response).to render_template(:show) + expected_path_regex = %r[-/ide/project/#{project.full_path}/edit/master/-/README.md] + expect(response).to redirect_to(expected_path_regex) end it 'assigns ref and path variables' do @@ -96,62 +95,6 @@ RSpec.describe Projects::StaticSiteEditorController do expect(response).to have_gitlab_http_status(:not_found) end end - - context 'when invalid config file' do - let(:service_response) { ServiceResponse.error(message: 'invalid') } - - it 'redirects to project page and flashes error message' do - expect(response).to redirect_to(project_path(project)) - expect(controller).to set_flash[:alert].to('invalid') - end - end - - context 'with a service response payload containing multiple data types' do - let(:data) do - { - a_string: 'string', - an_array: [ - { - foo: 'bar' - } - ], - an_integer: 123, - a_hash: { - a_deeper_hash: { - foo: 'bar' - } - }, - a_boolean: true, - a_nil: nil - } - end - - let(:assigns_data) { assigns(:data) } - - it 'leaves data values which are strings as strings' do - expect(assigns_data[:a_string]).to eq('string') - end - - it 'leaves data values which are integers as integers' do - expect(assigns_data[:an_integer]).to eq(123) - end - - it 'serializes data values which are booleans to JSON' do - expect(assigns_data[:a_boolean]).to eq('true') - end - - it 'serializes data values which are arrays to JSON' do - expect(assigns_data[:an_array]).to eq('[{"foo":"bar"}]') - end - - it 'serializes data values which are hashes to JSON' do - expect(assigns_data[:a_hash]).to eq('{"a_deeper_hash":{"foo":"bar"}}') - end - - it 'serializes data values which are nil to an empty string' do - expect(assigns_data[:a_nil]).to eq('') - end - end end end end diff --git a/spec/features/static_site_editor_spec.rb b/spec/features/static_site_editor_spec.rb deleted file mode 100644 index 98313905a33..00000000000 --- a/spec/features/static_site_editor_spec.rb +++ /dev/null @@ -1,113 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'Static Site Editor' do - include ContentSecurityPolicyHelpers - - let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project, :public, :repository) } - - let(:sse_path) { project_show_sse_path(project, 'master/README.md') } - - before_all do - project.add_developer(user) - end - - before do - sign_in(user) - end - - context "when no config file is present" do - before do - visit sse_path - end - - it 'renders SSE page with all generated config values and default config file values' do - node = page.find('#static-site-editor') - - # assert generated config values are present - expect(node['data-base-url']).to eq("/#{project.full_path}/-/sse/master%2FREADME.md") - expect(node['data-branch']).to eq('master') - expect(node['data-commit-id']).to match(/\A[0-9a-f]{40}\z/) - expect(node['data-is-supported-content']).to eq('true') - expect(node['data-merge-requests-illustration-path']) - .to match(%r{/assets/illustrations/merge_requests-.*\.svg}) - expect(node['data-namespace']).to eq(project.namespace.full_path) - expect(node['data-project']).to eq(project.path) - expect(node['data-project-id']).to eq(project.id.to_s) - - # assert default config file values are present - expect(node['data-image-upload-path']).to eq('source/images') - expect(node['data-mounts']).to eq('[{"source":"source","target":""}]') - expect(node['data-static-site-generator']).to eq('middleman') - end - end - - context "when a config file is present" do - let(:config_file_yml) do - <<~YAML - image_upload_path: custom-image-upload-path - mounts: - - source: source1 - target: "" - - source: source2 - target: target2 - static_site_generator: middleman - YAML - end - - before do - allow_next_instance_of(Repository) do |repository| - allow(repository).to receive(:blob_data_at).and_return(config_file_yml) - end - - visit sse_path - end - - it 'renders Static Site Editor page values read from config file' do - node = page.find('#static-site-editor') - - # assert user-specified config file values are present - expected_mounts = '[{"source":"source1","target":""},{"source":"source2","target":"target2"}]' - expect(node['data-image-upload-path']).to eq('custom-image-upload-path') - expect(node['data-mounts']).to eq(expected_mounts) - expect(node['data-static-site-generator']).to eq('middleman') - end - end - - describe 'Static Site Editor Content Security Policy' do - subject { response_headers['Content-Security-Policy'] } - - context 'when no global CSP config exists' do - before do - setup_csp_for_controller(Projects::StaticSiteEditorController) - end - - it 'does not add CSP directives' do - visit sse_path - - is_expected.to be_blank - end - end - - context 'when a global CSP config exists' do - let_it_be(:cdn_url) { 'https://some-cdn.test' } - let_it_be(:youtube_url) { 'https://www.youtube.com' } - - before do - csp = ActionDispatch::ContentSecurityPolicy.new do |p| - p.frame_src :self, cdn_url - end - - setup_existing_csp_for_controller(Projects::StaticSiteEditorController, csp) - end - - it 'appends youtube to the CSP frame-src policy' do - visit sse_path - - is_expected.to eql("frame-src 'self' #{cdn_url} #{youtube_url}") - end - end - end -end diff --git a/spec/frontend/vue_shared/components/__snapshots__/identicon_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/identicon_spec.js.snap deleted file mode 100644 index 1d8e04b83a3..00000000000 --- a/spec/frontend/vue_shared/components/__snapshots__/identicon_spec.js.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Identicon entity id is a GraphQL id matches snapshot 1`] = ` -
- - E - -
-`; - -exports[`Identicon entity id is a number matches snapshot 1`] = ` -
- - E - -
-`; diff --git a/spec/frontend/vue_shared/components/identicon_spec.js b/spec/frontend/vue_shared/components/identicon_spec.js deleted file mode 100644 index 24fc3713e2b..00000000000 --- a/spec/frontend/vue_shared/components/identicon_spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import IdenticonComponent from '~/vue_shared/components/identicon.vue'; - -describe('Identicon', () => { - let wrapper; - - const defaultProps = { - entityId: 1, - entityName: 'entity-name', - sizeClass: 's40', - }; - - const createComponent = (props = {}) => { - wrapper = shallowMount(IdenticonComponent, { - propsData: { - ...defaultProps, - ...props, - }, - }); - }; - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - describe('entity id is a number', () => { - beforeEach(() => createComponent()); - - it('matches snapshot', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - it('adds a correct class to identicon', () => { - expect(wrapper.find({ ref: 'identicon' }).classes()).toContain('bg2'); - }); - }); - - describe('entity id is a GraphQL id', () => { - beforeEach(() => createComponent({ entityId: 'gid://gitlab/Project/8' })); - - it('matches snapshot', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - it('adds a correct class to identicon', () => { - expect(wrapper.find({ ref: 'identicon' }).classes()).toContain('bg2'); - }); - }); -}); diff --git a/spec/frontend/vue_shared/components/project_avatar/default_spec.js b/spec/frontend/vue_shared/components/project_avatar/default_spec.js deleted file mode 100644 index d042db6051c..00000000000 --- a/spec/frontend/vue_shared/components/project_avatar/default_spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import Vue, { nextTick } from 'vue'; -import mountComponent from 'helpers/vue_mount_component_helper'; -import { projectData } from 'jest/ide/mock_data'; -import { TEST_HOST } from 'spec/test_constants'; -import { getFirstCharacterCapitalized } from '~/lib/utils/text_utility'; -import ProjectAvatarDefault from '~/vue_shared/components/deprecated_project_avatar/default.vue'; - -describe('ProjectAvatarDefault component', () => { - const Component = Vue.extend(ProjectAvatarDefault); - let vm; - - beforeEach(() => { - vm = mountComponent(Component, { - project: projectData, - }); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('renders identicon if project has no avatar_url', async () => { - const expectedText = getFirstCharacterCapitalized(projectData.name); - - vm.project = { - ...vm.project, - avatar_url: null, - }; - - await nextTick(); - const identiconEl = vm.$el.querySelector('.identicon'); - - expect(identiconEl).not.toBe(null); - expect(identiconEl.textContent.trim()).toEqual(expectedText); - }); - - it('renders avatar image if project has avatar_url', async () => { - const avatarUrl = `${TEST_HOST}/images/home/nasa.svg`; - - vm.project = { - ...vm.project, - avatar_url: avatarUrl, - }; - - await nextTick(); - expect(vm.$el.querySelector('.avatar')).not.toBeNull(); - expect(vm.$el.querySelector('.identicon')).toBeNull(); - expect(vm.$el.querySelector('img')).toHaveAttr('src', avatarUrl); - }); -}); diff --git a/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js b/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js index 5afa017aa76..397ab2254b9 100644 --- a/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js +++ b/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js @@ -2,7 +2,7 @@ import { shallowMount } from '@vue/test-utils'; import Vue from 'vue'; import mockProjects from 'test_fixtures_static/projects.json'; import { trimText } from 'helpers/text_helper'; -import ProjectAvatar from '~/vue_shared/components/deprecated_project_avatar/default.vue'; +import ProjectAvatar from '~/vue_shared/components/project_avatar.vue'; import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue'; describe('ProjectListItem component', () => { @@ -52,8 +52,13 @@ describe('ProjectListItem component', () => { it(`renders the project avatar`, () => { wrapper = shallowMount(Component, options); + const avatar = wrapper.findComponent(ProjectAvatar); - expect(wrapper.findComponent(ProjectAvatar).exists()).toBe(true); + expect(avatar.exists()).toBe(true); + expect(avatar.props()).toMatchObject({ + projectAvatarUrl: '', + projectName: project.name_with_namespace, + }); }); it(`renders a simple namespace name with a trailing slash`, () => { diff --git a/spec/support/helpers/gitaly_setup.rb b/spec/support/helpers/gitaly_setup.rb index 0ad83bdeeb2..a4ee618457d 100644 --- a/spec/support/helpers/gitaly_setup.rb +++ b/spec/support/helpers/gitaly_setup.rb @@ -267,7 +267,7 @@ module GitalySetup { 'default' => repos_path }, force: true, options: { - runtime_dir: File.join(gitaly_dir, "run2"), + internal_socket_dir: File.join(gitaly_dir, "internal_gitaly2"), gitaly_socket: "gitaly2.socket", config_filename: "gitaly2.config.toml" }