diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index cd95105a893..b7b535e70df 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -13,6 +13,7 @@ class Admin::DashboardController < Admin::ApplicationController @users = User.order_id_desc.limit(10) @groups = Group.order_id_desc.with_route.limit(10) @notices = Gitlab::ConfigChecker::PumaRuggedChecker.check + @notices += Gitlab::ConfigChecker::ExternalDatabaseChecker.check end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index 522d171b5bf..dc75d37fb01 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -3,7 +3,12 @@ class GraphqlController < ApplicationController # Unauthenticated users have access to the API for public data skip_before_action :authenticate_user! - skip_around_action :set_session_storage + + # If a user is using their session to access GraphQL, we need to have session + # storage, since the admin-mode check is session wide. + # We can't enable this for anonymous users because that would cause users using + # enforced SSO from using an auth token to access the API. + skip_around_action :set_session_storage, unless: :current_user # Allow missing CSRF tokens, this would mean that if a CSRF is invalid or missing, # the user won't be authenticated but can proceed as an anonymous user. diff --git a/changelogs/unreleased/display-db-deprecation-notice.yml b/changelogs/unreleased/display-db-deprecation-notice.yml new file mode 100644 index 00000000000..b402beba0d2 --- /dev/null +++ b/changelogs/unreleased/display-db-deprecation-notice.yml @@ -0,0 +1,5 @@ +--- +title: Implement external database checker in dashboard controller +merge_request: 30389 +author: +type: deprecated diff --git a/changelogs/unreleased/e2300-cs-template.yml b/changelogs/unreleased/e2300-cs-template.yml new file mode 100644 index 00000000000..39f792370d6 --- /dev/null +++ b/changelogs/unreleased/e2300-cs-template.yml @@ -0,0 +1,5 @@ +--- +title: Migrate Container-Scanning template to rules syntax +merge_request: 30775 +author: +type: changed diff --git a/changelogs/unreleased/e2300-dast-template.yml b/changelogs/unreleased/e2300-dast-template.yml new file mode 100644 index 00000000000..2d06deed7bd --- /dev/null +++ b/changelogs/unreleased/e2300-dast-template.yml @@ -0,0 +1,5 @@ +--- +title: Migrate DAST CI template to rules syntax +merge_request: 30776 +author: +type: changed diff --git a/changelogs/unreleased/e2300-ds-template.yml b/changelogs/unreleased/e2300-ds-template.yml new file mode 100644 index 00000000000..cfa6a3cbb7c --- /dev/null +++ b/changelogs/unreleased/e2300-ds-template.yml @@ -0,0 +1,5 @@ +--- +title: Migrate Dependency-Scanning CI template to rules syntax +merge_request: 30907 +author: +type: changed diff --git a/changelogs/unreleased/e2300-lm-template.yml b/changelogs/unreleased/e2300-lm-template.yml new file mode 100644 index 00000000000..26f133f24f4 --- /dev/null +++ b/changelogs/unreleased/e2300-lm-template.yml @@ -0,0 +1,5 @@ +--- +title: Migrate License-Scanning CI template to rules syntax +merge_request: 30784 +author: +type: changed diff --git a/changelogs/unreleased/e2300-sast-template.yml b/changelogs/unreleased/e2300-sast-template.yml new file mode 100644 index 00000000000..fe8ed585d4c --- /dev/null +++ b/changelogs/unreleased/e2300-sast-template.yml @@ -0,0 +1,5 @@ +--- +title: Migrate SAST CI template to rules syntax +merge_request: 31127 +author: +type: changed diff --git a/changelogs/unreleased/fix-admin-mode-graphiql-explorer.yml b/changelogs/unreleased/fix-admin-mode-graphiql-explorer.yml new file mode 100644 index 00000000000..e4c5091b59d --- /dev/null +++ b/changelogs/unreleased/fix-admin-mode-graphiql-explorer.yml @@ -0,0 +1,5 @@ +--- +title: Fix admin mode access on GraphiQL controller +merge_request: 29845 +author: Diego Louzán +type: fixed diff --git a/doc/api/metrics_dashboard_annotations.md b/doc/api/metrics_dashboard_annotations.md index 8cfd4dc8eed..a4d5985803f 100644 --- a/doc/api/metrics_dashboard_annotations.md +++ b/doc/api/metrics_dashboard_annotations.md @@ -4,16 +4,6 @@ Metrics dashboard annotations allow you to indicate events on your graphs at a single point in time or over a timespan. -## Enable the metrics dashboard annotations API - -The `:metrics_dashboard_annotations` feature flag is disabled by default. -To turn on this API, ask a GitLab administrator with Rails console -access to run the following command: - -```ruby -Feature.enable(:metrics_dashboard_annotations) -``` - ## Create a new annotation ```plaintext diff --git a/doc/api/projects.md b/doc/api/projects.md index 48df539ed88..ec35eef0dcc 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -9,10 +9,8 @@ Values for the project visibility level are: - `private`: Project access must be granted explicitly for each user. - - `internal`: The project can be cloned by any logged in user. - - `public`: The project can be accessed without any authentication. @@ -22,11 +20,9 @@ There are currently three options for `merge_method` to choose from: - `merge`: A merge commit is created for every merge, and merging is allowed as long as there are no conflicts. - - `rebase_merge`: A merge commit is created for every merge, but merging is only allowed if fast-forward merge is possible. This way you could make sure that if this merge request would build, after merging to target branch it would also build. - - `ff`: No merge commits are created and all merges are fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded. diff --git a/doc/development/fe_guide/vue.md b/doc/development/fe_guide/vue.md index ce5e14bfe87..972c2ded9c9 100644 --- a/doc/development/fe_guide/vue.md +++ b/doc/development/fe_guide/vue.md @@ -189,92 +189,97 @@ Each Vue component has a unique output. This output is always present in the ren Although we can test each method of a Vue component individually, our goal must be to test the output of the render/template function, which represents the state at all times. -Make use of the [axios mock adapter](axios.md#mock-axios-response-in-tests) to mock data returned. - -Here's how we would test the Todo App above: +Here's an example of a well structured unit test for [this Vue component](#appendix---vue-component-subject-under-test): ```javascript -import Vue from 'vue'; -import axios from '~/lib/utils/axios_utils'; +import { shallowMount } from '@vue/test-utils'; +import { GlLoadingIcon } from '@gitlab/ui'; import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import App from '~/todos/app.vue'; -describe('Todos App', () => { - let vm; +const TEST_TODOS = [ + { text: 'Lorem ipsum test text' }, + { text: 'Lorem ipsum 2' }, +]; +const TEST_NEW_TODO = 'New todo title'; +const TEST_TODO_PATH = '/todos'; + +describe('~/todos/app.vue', () => { + let wrapper; let mock; beforeEach(() => { - // Create a mock adapter for stubbing axios API requests + // IMPORTANT: Use axios-mock-adapter for stubbing axios API requests mock = new MockAdapter(axios); - - const Component = Vue.extend(component); - - // Mount the Component - vm = new Component().$mount(); + mock.onGet(TEST_TODO_PATH).reply(200, TEST_TODOS); + mock.onPost(TEST_TODO_PATH).reply(200); }); afterEach(() => { - // Reset the mock adapter + // IMPORTANT: Clean up the component instance and axios mock adapter + wrapper.destroy(); + wrapper = null; + mock.restore(); - // Destroy the mounted component - vm.$destroy(); }); - it('should render the loading state while the request is being made', () => { - expect(vm.$el.querySelector('i.fa-spin')).toBeDefined(); - }); - - it('should render todos returned by the endpoint', done => { - // Mock the get request on the API endpoint to return data - mock.onGet('/todos').replyOnce(200, [ - { - title: 'This is a todo', - text: 'This is the text', + // NOTE: It is very helpful to separate setting up the component from + // its collaborators (i.e. Vuex, axios, etc.) + const createWrapper = (props = {}) => { + wrapper = shallowMount(App, { + propsData: { + path: TEST_TODO_PATH, + ...props, }, - ]); + }); + }; + // NOTE: Helper methods greatly help test maintainability and readability. + const findLoader = () => wrapper.find(GlLoadingIcon); + const findAddButton = () => wrapper.find('[data-testid="add-button"]'); + const findTextInput = () => wrapper.find('[data-testid="text-input"]'); + const findTodoData = () => wrapper.findAll('[data-testid="todo-item"]').wrappers.map(wrapper => ({ text: wrapper.text() })); - Vue.nextTick(() => { - const items = vm.$el.querySelectorAll('.js-todo-list div') - expect(items.length).toBe(1); - expect(items[0].textContent).toContain('This is the text'); - done(); + describe('when mounted and loading', () => { + beforeEach(() => { + // Create request which will never resolve + mock.onGet(TEST_TODO_PATH).reply(() => new Promise(() => {})); + createWrapper(); + }); + + it('should render the loading state', () => { + expect(findLoader().exists()).toBe(true); }); }); - it('should add a todos on button click', (done) => { - - // Mock the put request and check that the sent data object is correct - mock.onPut('/todos').replyOnce((req) => { - expect(req.data).toContain('text'); - expect(req.data).toContain('title'); - - return [201, {}]; + describe('when todos are loaded', () => { + beforeEach(() => { + createWrapper(); + // IMPORTANT: This component fetches data asynchronously on mount, so let's wait for the Vue template to update + return wrapper.vm.$nextTick(); }); - vm.$el.querySelector('.js-add-todo').click(); + it('should not show loading', () => { + expect(findLoader().exists()).toBe(false); + }); - // Add a new interceptor to mock the add Todo request - Vue.nextTick(() => { - expect(vm.$el.querySelectorAll('.js-todo-list div').length).toBe(2); - done(); + it('should render todos', () => { + expect(findTodoData()).toEqual(TEST_TODOS); + }); + + it('when todo is added, should post new todo', () => { + findTextInput().vm.$emit('update', TEST_NEW_TODO) + findAddButton().vm.$emit('click'); + + return wrapper.vm.$nextTick() + .then(() => { + expect(mock.history.post.map(x => JSON.parse(x.data))).toEqual([{ text: TEST_NEW_TODO }]); + }); }); }); }); ``` -### `mountComponent` helper - -There is a helper in `spec/javascripts/helpers/vue_mount_component_helper.js` that allows you to mount a component with the given props: - -```javascript -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper' -import component from 'component.vue' - -const Component = Vue.extend(component); -const data = {prop: 'foo'}; -const vm = mountComponent(Component, data); -``` - ### Test the component's output The main return value of a Vue component is the rendered output. In order to test the component we @@ -336,3 +341,35 @@ Currently, we recommend to minimize adding certain features to the codebase to p - `slot` attributes You can find more details on [Migration to Vue 3](vue3_migration.md) + +## Appendix - Vue component subject under test + +This is the template for the example component which is tested in the [Testing Vue components](#testing-vue-components) section: + +```html + +``` diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md index a956a054a8c..52d538c7159 100644 --- a/doc/development/testing_guide/frontend_testing.md +++ b/doc/development/testing_guide/frontend_testing.md @@ -832,43 +832,6 @@ testAction( Check an example in [spec/javascripts/ide/stores/actions_spec.jsspec/javascripts/ide/stores/actions_spec.js](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/javascripts/ide/stores/actions_spec.js). -### Vue Helper: `mountComponent` - -To make mounting a Vue component easier and more readable, we have a few helpers available in `spec/helpers/vue_mount_component_helper`: - -- `createComponentWithStore` -- `mountComponentWithStore` - -Examples of usage: - -```javascript -beforeEach(() => { - vm = createComponentWithStore(Component, store); - - vm.$store.state.currentBranchId = 'master'; - - vm.$mount(); -}); -``` - -```javascript -beforeEach(() => { - vm = mountComponentWithStore(Component, { - el: '#dummy-element', - store, - props: { badge }, - }); -}); -``` - -Don't forget to clean up: - -```javascript -afterEach(() => { - vm.$destroy(); -}); -``` - ### Wait until axios requests finish The axios utils mock module located in `spec/frontend/mocks/ce/lib/utils/axios_utils.js` contains two helper methods for Jest tests that spawn HTTP requests. diff --git a/doc/install/requirements.md b/doc/install/requirements.md index 27a65fe8181..e4af18ebf93 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -139,9 +139,12 @@ MySQL/MariaDB are advised to [migrate to PostgreSQL](../update/mysql_to_postgres ### PostgreSQL Requirements -As of GitLab 10.0, PostgreSQL 9.6 or newer is required, and earlier versions are -not supported. We highly recommend users to use PostgreSQL 9.6 as this -is the PostgreSQL version used for development and testing. +We highly recommend users to use the minimum PostgreSQL versions specified below as these are the versions used for development and testing. + +GitLab version | Minimum PostgreSQL version +-|- +10.0 | 9.6 +12.10 | 11 Users using PostgreSQL must ensure the `pg_trgm` extension is loaded into every GitLab database. This extension can be enabled (using a PostgreSQL super user) diff --git a/doc/telemetry/snowplow.md b/doc/telemetry/snowplow.md index 02e161b8662..4961f4f0938 100644 --- a/doc/telemetry/snowplow.md +++ b/doc/telemetry/snowplow.md @@ -153,11 +153,16 @@ describe('my component', () => { let trackingSpy; beforeEach(() => { - const vm = mountComponent(MyComponent); trackingSpy = mockTracking('_category_', vm.$el, spyOn); }); + const triggerEvent = () => { + // action which should trigger a event + }; + it('tracks an event when toggled', () => { + expect(trackingSpy).not.toHaveBeenCalled(); + triggerEvent('a.toggle'); expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_edit_button', { diff --git a/doc/tools/email.md b/doc/tools/email.md index e9ff88152ba..eacf63ecdcd 100644 --- a/doc/tools/email.md +++ b/doc/tools/email.md @@ -26,6 +26,9 @@ at their primary email address. ![compose an email](email2.png) +NOTE: **Note:** +[Starting with GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/31509), email notifications can be sent only once every 10 minutes. This helps minimize performance issues. + ## Unsubscribing from emails Users can choose to unsubscribe from receiving emails from GitLab by following diff --git a/doc/user/permissions.md b/doc/user/permissions.md index e54063e3eed..3f34695d011 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -87,10 +87,8 @@ The following table depicts the various user permission levels in a project. | Create new merge request | | ✓ | ✓ | ✓ | ✓ | | View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ | | Create/edit requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | -| Pull [packages](packages/index.md) | | ✓ | ✓ | ✓ | ✓ | -| Publish [packages](packages/index.md) | | | ✓ | ✓ | ✓ | -| Pull from [Conan repository](packages/conan_repository/index.md), [Maven repository](packages/maven_repository/index.md), or [NPM registry](packages/npm_registry/index.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ | -| Publish to [Conan repository](packages/conan_repository/index.md), [Maven repository](packages/maven_repository/index.md), or [NPM registry](packages/npm_registry/index.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ | +| Pull [packages](packages/index.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ | +| Publish [packages](packages/index.md) **(PREMIUM)**| | | ✓ | ✓ | ✓ | | Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ | | Create/edit/delete [Releases](project/releases/index.md)| | | ✓ | ✓ | ✓ | | Create new branches | | | ✓ | ✓ | ✓ | @@ -235,6 +233,8 @@ group. | Create/edit group epic **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | | Manage group labels | | ✓ | ✓ | ✓ | ✓ | | See a container registry | | ✓ | ✓ | ✓ | ✓ | +| Pull [packages](packages/index.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ | +| Publish [packages](packages/index.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ | | View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ | | Create project in group | | | ✓ (3) | ✓ (3) | ✓ (3) | | Create/edit/delete group milestones | | | ✓ | ✓ | ✓ | diff --git a/doc/user/project/integrations/img/metrics_dashboard_annotations_ui_v13.0.png b/doc/user/project/integrations/img/metrics_dashboard_annotations_ui_v13.0.png new file mode 100644 index 00000000000..a042fbbcf4e Binary files /dev/null and b/doc/user/project/integrations/img/metrics_dashboard_annotations_ui_v13.0.png differ diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md index 4b7d634a293..30f24a5cf3e 100644 --- a/doc/user/project/integrations/prometheus.md +++ b/doc/user/project/integrations/prometheus.md @@ -673,7 +673,8 @@ The options are: ### Dashboard Annotations -> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/211330) in GitLab 12.10 (enabled by feature flag `metrics_dashboard_annotations`). +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/211330) in GitLab 12.10 (enabled by feature flag `metrics_dashboard_annotations`). +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/215224) in GitLab 13.0. You can use **Metrics Dashboard Annotations** to mark any important events on every metrics dashboard by adding annotations to it. While viewing a dashboard, @@ -685,6 +686,8 @@ its description. You can create annotations by making requests to the [Metrics dashboard annotations API](../../../api/metrics_dashboard_annotations.md) +![Annotations UI](img/metrics_dashboard_annotations_ui_v13.0.png) + ### View Logs **(ULTIMATE)** > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/122013) in GitLab 12.8. diff --git a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml index 3cf4910fe86..ad858eab962 100644 --- a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml @@ -18,17 +18,16 @@ dast_environment_deploy: on_stop: stop_dast_environment artifacts: paths: [environment_url.txt] - only: - refs: - - branches - variables: - - $GITLAB_FEATURES =~ /\bdast\b/ - kubernetes: active - except: - variables: - - $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME - - $DAST_DISABLED || $DAST_DISABLED_FOR_DEFAULT_BRANCH - - $DAST_WEBSITE # we don't need to create a review app if a URL is already given + rules: + - if: $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME + when: never + - if: $DAST_DISABLED || $DAST_DISABLED_FOR_DEFAULT_BRANCH + when: never + - if: $DAST_WEBSITE # we don't need to create a review app if a URL is already given + when: never + - if: $CI_COMMIT_BRANCH && + $CI_KUBERNETES_ACTIVE && + $GITLAB_FEATURES =~ /\bdast\b/ stop_dast_environment: extends: .dast-auto-deploy @@ -42,14 +41,13 @@ stop_dast_environment: name: dast-default action: stop needs: ["dast"] - only: - refs: - - branches - variables: - - $GITLAB_FEATURES =~ /\bdast\b/ - kubernetes: active - except: - variables: - - $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME - - $DAST_DISABLED || $DAST_DISABLED_FOR_DEFAULT_BRANCH - - $DAST_WEBSITE + rules: + - if: $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME + when: never + - if: $DAST_DISABLED || $DAST_DISABLED_FOR_DEFAULT_BRANCH + when: never + - if: $DAST_WEBSITE # we don't need to create a review app if a URL is already given + when: never + - if: $CI_COMMIT_BRANCH && + $CI_KUBERNETES_ACTIVE && + $GITLAB_FEATURES =~ /\bdast\b/ diff --git a/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml index 7075cb28a2c..21bcdd8d9b5 100644 --- a/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml @@ -29,11 +29,8 @@ container_scanning: reports: container_scanning: gl-container-scanning-report.json dependencies: [] - only: - refs: - - branches - variables: - - $GITLAB_FEATURES =~ /\bcontainer_scanning\b/ - except: - variables: - - $CONTAINER_SCANNING_DISABLED + rules: + - if: $CONTAINER_SCANNING_DISABLED + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bcontainer_scanning\b/ diff --git a/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml index a2fb604cb87..07399216597 100644 --- a/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml @@ -30,13 +30,15 @@ dast: artifacts: reports: dast: gl-dast-report.json - only: - refs: - - branches - variables: - - $GITLAB_FEATURES =~ /\bdast\b/ - except: - variables: - - $DAST_DISABLED - - $DAST_DISABLED_FOR_DEFAULT_BRANCH && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME - - $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME && $REVIEW_DISABLED && $DAST_WEBSITE == null && $DAST_API_SPECIFICATION == null + rules: + - if: $DAST_DISABLED + when: never + - if: $DAST_DISABLED_FOR_DEFAULT_BRANCH && + $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME + when: never + - if: $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME && + $REVIEW_DISABLED && $DAST_WEBSITE == null && + $DAST_API_SPECIFICATION == null + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bdast\b/ diff --git a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml index 401be1aa7bf..24c5d73f8d1 100644 --- a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml @@ -77,23 +77,20 @@ dependency_scanning: reports: dependency_scanning: gl-dependency-scanning-report.json dependencies: [] - only: - refs: - - branches - variables: - - $GITLAB_FEATURES =~ /\bdependency_scanning\b/ - except: - variables: - - $DEPENDENCY_SCANNING_DISABLED - - $DS_DISABLE_DIND == 'true' + rules: + - if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'true' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bdependency_scanning\b/ .ds-analyzer: extends: dependency_scanning services: [] - except: - variables: - - $DEPENDENCY_SCANNING_DISABLED - - $DS_DISABLE_DIND == 'false' + rules: + - if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bdependency_scanning\b/ script: - /analyzer run @@ -101,48 +98,82 @@ gemnasium-dependency_scanning: extends: .ds-analyzer image: name: "$DS_ANALYZER_IMAGE_PREFIX/gemnasium:$DS_MAJOR_VERSION" - only: - variables: - - $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && - $DS_DEFAULT_ANALYZERS =~ /gemnasium([^-]|$)/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /ruby|javascript|php|\bgo\b/ + rules: + - if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && + $DS_DEFAULT_ANALYZERS =~ /gemnasium([^-]|$)/ + exists: + - 'Gemfile.lock' + - 'Pipfile.lock' + - 'composer.lock' + - 'gems.locked' + - 'go.sum' + - 'npm-shrinkwrap.json' + - 'package-lock.json' + - 'yarn.lock' gemnasium-maven-dependency_scanning: extends: .ds-analyzer image: name: "$DS_ANALYZER_IMAGE_PREFIX/gemnasium-maven:$DS_MAJOR_VERSION" - only: - variables: - - $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && - $DS_DEFAULT_ANALYZERS =~ /gemnasium-maven/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\b(java|scala)\b/ + rules: + - if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && + $DS_DEFAULT_ANALYZERS =~ /gemnasium-maven/ + exists: + - 'build.gradle' + - 'build.sbt' + - 'pom.xml' gemnasium-python-dependency_scanning: extends: .ds-analyzer image: name: "$DS_ANALYZER_IMAGE_PREFIX/gemnasium-python:$DS_MAJOR_VERSION" - only: - variables: - - $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && - $DS_DEFAULT_ANALYZERS =~ /gemnasium-python/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /python/ + rules: + - if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && + $DS_DEFAULT_ANALYZERS =~ /gemnasium-python/ + exists: + - 'requirements.txt' + - 'requirements.pip' + - 'Pipfile' + - 'requires.txt' + - 'setup.py' + # Support passing of $PIP_REQUIREMENTS_FILE + # See https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#configuring-specific-analyzers-used-by-dependency-scanning + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && + $DS_DEFAULT_ANALYZERS =~ /gemnasium-python/ && + $PIP_REQUIREMENTS_FILE bundler-audit-dependency_scanning: extends: .ds-analyzer image: name: "$DS_ANALYZER_IMAGE_PREFIX/bundler-audit:$DS_MAJOR_VERSION" - only: - variables: - - $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && - $DS_DEFAULT_ANALYZERS =~ /bundler-audit/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /ruby/ + rules: + - if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && + $DS_DEFAULT_ANALYZERS =~ /bundler-audit/ + exists: + - 'Gemfile.lock' retire-js-dependency_scanning: extends: .ds-analyzer image: name: "$DS_ANALYZER_IMAGE_PREFIX/retire.js:$DS_MAJOR_VERSION" - only: - variables: - - $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && - $DS_DEFAULT_ANALYZERS =~ /retire.js/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /javascript/ + rules: + - if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && + $DS_DEFAULT_ANALYZERS =~ /retire.js/ + exists: + - 'package.json' diff --git a/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml index 9259abcd849..b86014c1ebc 100644 --- a/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml @@ -27,11 +27,8 @@ license_scanning: reports: license_scanning: $LM_REPORT_FILE dependencies: [] - only: - refs: - - branches - variables: - - $GITLAB_FEATURES =~ /\blicense_scanning\b/ - except: - variables: - - $LICENSE_MANAGEMENT_DISABLED + rules: + - if: $LICENSE_MANAGEMENT_DISABLED + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\blicense_scanning\b/ diff --git a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml index 894fcfd75be..a5830700d12 100644 --- a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml @@ -23,11 +23,10 @@ sast: artifacts: reports: sast: gl-sast-report.json - only: - refs: - - branches - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'true' + when: never + - if: $CI_COMMIT_BRANCH && $GITLAB_FEATURES =~ /\bsast\b/ image: docker:stable variables: SEARCH_MAX_DEPTH: 4 @@ -48,18 +47,15 @@ sast: --volume "$PWD:/code" \ --volume /var/run/docker.sock:/var/run/docker.sock \ "registry.gitlab.com/gitlab-org/security-products/sast:$SAST_ANALYZER_IMAGE_TAG" /app/bin/run /code - except: - variables: - - $SAST_DISABLED - - $SAST_DISABLE_DIND == 'true' .sast-analyzer: extends: sast services: [] - except: - variables: - - $SAST_DISABLED - - $SAST_DISABLE_DIND == 'false' + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ script: - /analyzer run @@ -67,49 +63,65 @@ bandit-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/bandit:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /bandit/&& - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\bpython\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /bandit/ + exists: + - '**/*.py' brakeman-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/brakeman:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /brakeman/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\bruby\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /brakeman/ + exists: + - '**/*.rb' eslint-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /eslint/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\bjavascript\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /eslint/ + exists: + - '**/*.html' + - '**/*.js' flawfinder-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/flawfinder:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /flawfinder/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /(c(\+\+)?,)|(c(\+\+)?$)/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /flawfinder/ + exists: + - '**/*.c' + - '**/*.cpp' kubesec-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/kubesec:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && $SAST_DEFAULT_ANALYZERS =~ /kubesec/ && $SCAN_KUBERNETES_MANIFESTS == 'true' @@ -117,87 +129,117 @@ gosec-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/gosec:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /gosec/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\bgo\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /gosec/ + exists: + - '**/*.go' nodejs-scan-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/nodejs-scan:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /nodejs-scan/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\bjavascript\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /nodejs-scan/ + exists: + - '**/*.js' phpcs-security-audit-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/phpcs-security-audit:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /phpcs-security-audit/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\bphp\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /phpcs-security-audit/ + exists: + - '**/*.php' pmd-apex-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/pmd-apex:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /pmd-apex/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\bapex\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /pmd-apex/ + exists: + - '**/*.cls' secrets-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/secrets:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && $SAST_DEFAULT_ANALYZERS =~ /secrets/ security-code-scan-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/security-code-scan:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /security-code-scan/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\b(c\#|visual basic\b)/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /security-code-scan/ + exists: + - '**/*.csproj' + - '**/*.vbproj' sobelow-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/sobelow:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /sobelow/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\belixir\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /sobelow/ + exists: + - '**/*.ex' + - '**/*.exs' spotbugs-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/spotbugs:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /spotbugs/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\b(groovy|java|scala)\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /spotbugs/ + exists: + - '**/*.groovy' + - '**/*.java' + - '**/*.scala' tslint-sast: extends: .sast-analyzer image: name: "$SAST_ANALYZER_IMAGE_PREFIX/tslint:$SAST_ANALYZER_IMAGE_TAG" - only: - variables: - - $GITLAB_FEATURES =~ /\bsast\b/ && - $SAST_DEFAULT_ANALYZERS =~ /tslint/ && - $CI_PROJECT_REPOSITORY_LANGUAGES =~ /\btypescript\b/ + rules: + - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false' + when: never + - if: $CI_COMMIT_BRANCH && + $GITLAB_FEATURES =~ /\bsast\b/ && + $SAST_DEFAULT_ANALYZERS =~ /tslint/ + exists: + - '**/*.ts' diff --git a/lib/gitlab/config_checker/external_database_checker.rb b/lib/gitlab/config_checker/external_database_checker.rb new file mode 100644 index 00000000000..795082a10a0 --- /dev/null +++ b/lib/gitlab/config_checker/external_database_checker.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Gitlab + module ConfigChecker + module ExternalDatabaseChecker + extend self + + # DB is considered deprecated if it is below version 11 + def db_version_deprecated? + Gitlab::Database.version.to_f < 11 + end + + def check + return [] unless db_version_deprecated? + + [ + { + type: 'warning', + message: _('Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). '\ + 'PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. '\ + 'Please consider upgrading your PostgreSQL version (%{db_version}) soon.') % { db_version: Gitlab::Database.version.to_s } + } + ] + end + end + end +end diff --git a/lib/gitlab/database/count/reltuples_count_strategy.rb b/lib/gitlab/database/count/reltuples_count_strategy.rb index 6cd90c01ab2..e226ed7613a 100644 --- a/lib/gitlab/database/count/reltuples_count_strategy.rb +++ b/lib/gitlab/database/count/reltuples_count_strategy.rb @@ -72,7 +72,7 @@ module Gitlab # @param [Array] table names # @returns [Hash] Table name to count mapping (e.g. { 'projects' => 5, 'users' => 100 }) def get_statistics(table_names, check_statistics: true) - time = 1.hour.ago + time = 6.hours.ago query = PgClass.joins("LEFT JOIN pg_stat_user_tables USING (relname)") .where(relname: table_names) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ccd972a7037..328dd73fd30 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -8,6 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-04-24 17:33-0400\n" +"PO-Revision-Date: 2020-04-24 17:33-0400\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" @@ -1973,6 +1975,9 @@ msgstr "" msgid "An application called %{link_to_client} is requesting access to your GitLab account." msgstr "" +msgid "An email notification was recently sent from the admin panel. Please wait %{wait_time_in_words} before attempting to send another message." +msgstr "" + msgid "An empty GitLab User field will add the FogBugz user's full name (e.g. \"By John Smith\") in the description of all issues and comments. It will also associate and/or assign these issues and comments with the project creator." msgstr "" @@ -6504,9 +6509,6 @@ msgstr "" msgid "Customize your pipeline configuration." msgstr "" -msgid "Cycle Time" -msgstr "" - msgid "CycleAnalyticsEvent|Issue closed" msgstr "" @@ -7781,6 +7783,9 @@ msgstr "" msgid "Email address" msgstr "" +msgid "Email could not be sent" +msgstr "" + msgid "Email display name" msgstr "" @@ -7796,6 +7801,9 @@ msgstr "" msgid "Email restrictions for sign-ups" msgstr "" +msgid "Email sent" +msgstr "" + msgid "Email the pipelines status to a list of recipients." msgstr "" @@ -14174,6 +14182,9 @@ msgstr "" msgid "Note parameters are invalid: %{errors}" msgstr "" +msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon." +msgstr "" + msgid "Note that this invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}." msgstr "" @@ -18855,6 +18866,12 @@ msgstr "" msgid "Send email" msgstr "" +msgid "Send email notification" +msgstr "" + +msgid "Send message" +msgstr "" + msgid "Send report" msgstr "" @@ -24249,6 +24266,9 @@ msgstr "" msgid "You can move around the graph by using the arrow keys." msgstr "" +msgid "You can notify the app / group or a project by sending them an email notification" +msgstr "" + msgid "You can now export your security dashboard to a CSV report." msgstr "" diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb index 06a949471a7..fcfda61f0dd 100644 --- a/spec/controllers/graphql_controller_spec.rb +++ b/spec/controllers/graphql_controller_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe GraphqlController do + include GraphqlHelpers + before do stub_feature_flags(graphql: true) end @@ -64,4 +66,52 @@ describe GraphqlController do end end end + + describe 'Admin Mode' do + let(:admin) { create(:admin) } + let(:project) { create(:project) } + let(:graphql_query) { graphql_query_for('project', { 'fullPath' => project.full_path }, %w(id name)) } + + before do + sign_in(admin) + end + + context 'when admin mode enabled' do + before do + Gitlab::Session.with_session(controller.session) do + controller.current_user_mode.request_admin_mode! + controller.current_user_mode.enable_admin_mode!(password: admin.password) + end + end + + it 'can query project data' do + post :execute, params: { query: graphql_query } + + expect(controller.current_user_mode.admin_mode?).to be(true) + expect(json_response['data']['project']['name']).to eq(project.name) + end + end + + context 'when admin mode disabled' do + it 'cannot query project data' do + post :execute, params: { query: graphql_query } + + expect(controller.current_user_mode.admin_mode?).to be(false) + expect(json_response['data']['project']).to be_nil + end + + context 'when admin is member of the project' do + before do + project.add_developer(admin) + end + + it 'can query project data' do + post :execute, params: { query: graphql_query } + + expect(controller.current_user_mode.admin_mode?).to be(false) + expect(json_response['data']['project']['name']).to eq(project.name) + end + end + end + end end diff --git a/spec/lib/gitlab/config_checker/external_database_checker_spec.rb b/spec/lib/gitlab/config_checker/external_database_checker_spec.rb new file mode 100644 index 00000000000..d86d132c237 --- /dev/null +++ b/spec/lib/gitlab/config_checker/external_database_checker_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::ConfigChecker::ExternalDatabaseChecker do + describe '#check' do + subject { described_class.check } + + context 'database version is not deprecated' do + before do + allow(described_class).to receive(:db_version_deprecated?).and_return(false) + end + + it { is_expected.to be_empty } + end + + context 'database version is deprecated' do + before do + allow(described_class).to receive(:db_version_deprecated?).and_return(true) + end + + let(:notice_deprecated_database) do + { + type: 'warning', + message: _('Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). '\ + 'PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. '\ + 'Please consider upgrading your PostgreSQL version (%{db_version}) soon.') % { db_version: Gitlab::Database.version.to_s } + } + end + + it 'reports deprecated database notices' do + is_expected.to contain_exactly(notice_deprecated_database) + end + end + end + + describe '#db_version_deprecated' do + subject { described_class.db_version_deprecated? } + + context 'database version is not deprecated' do + before do + allow(Gitlab::Database).to receive(:version).and_return(11) + end + + it { is_expected.to be false } + end + + context 'database version is deprecated' do + before do + allow(Gitlab::Database).to receive(:version).and_return(10) + end + + it { is_expected.to be true } + end + end +end diff --git a/spec/support/helpers/exclusive_lease_helpers.rb b/spec/support/helpers/exclusive_lease_helpers.rb index 076e3cc3851..95cfc56c273 100644 --- a/spec/support/helpers/exclusive_lease_helpers.rb +++ b/spec/support/helpers/exclusive_lease_helpers.rb @@ -10,7 +10,8 @@ module ExclusiveLeaseHelpers try_obtain: uuid, exists?: true, renew: renew, - cancel: nil + cancel: nil, + ttl: timeout ) allow(Gitlab::ExclusiveLease) diff --git a/vendor/gitignore/C++.gitignore b/vendor/gitignore/C++.gitignore old mode 100644 new mode 100755 diff --git a/vendor/gitignore/Java.gitignore b/vendor/gitignore/Java.gitignore old mode 100644 new mode 100755