Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-04-01 15:08:40 +00:00
parent e4a0b94a64
commit cdd826bc3a
63 changed files with 445 additions and 249 deletions

View File

@ -7,6 +7,26 @@
* feature development should use the Feature Request template.
-->
If you are a community contributor:
1. To work on an issue, type `@gl-docsteam I would like to work on this issue.`
in a comment. A technical writer
will assign the issue to you. Do not work on the issue before it is assigned to you.
If someone has already chosen the issue, pick another or view docs [in the docs directory](https://gitlab.com/gitlab-org/gitlab/-/tree/master/doc)
and open a merge request for any page you feel can be improved.
1. Create a merge request for the issue. If this is for a Hackathon, do not create the merge request
before the Hackathon has started or it will not be counted towards the Hackathon. If you were not
assigned the issue, do not create a merge request. It will not be accepted.
1. Copy the link to this issue and add it to the merge request's description, which will link
the merge request and the issue together.
1. After your merge request is accepted and merged, close this issue.
If you notice things you'd like to fix that are not part of the issue, open separate merge requests for those issues.
We're sorry for all the rules but we want everyone to have a good experience, and it can be hard when we get an influx of contributions.
Thank you again for contributing to the GitLab documentation!
## Identified documentation issue
<!--
@ -19,19 +39,6 @@
* the opportunities for contributors.
-->
## Process
If you, as a contributor, decide to take this work on, assign this issue to yourself, and create one or more linked
merge requests that resolve this issue. Be sure to close this issue after all linked merge requests are completed.
The work for this issue should involve only what's listed in the previous section. If you identify other work that
needs to be done, create separate, unlinked MRs as needed to address those items.
When using automated test results for identified work, use this issue to work only on the listed lines. For
example, if the tests list several lines that show the word "admin" as needing to possibly be "administrator,"
do not modify other parts of the page that may also include "admin," as the testing may have excluded those lines
(for example, they may be part of the **Admin Area** of GitLab).
## Additional information
<!--

View File

@ -146,25 +146,6 @@ Performance/CollectionLiteralInLoop:
Performance/ConstantRegexp:
Enabled: false
# Offense count: 14
# Cop supports --auto-correct.
# Configuration parameters: SafeMultiline.
Performance/DeletePrefix:
Exclude:
- 'app/helpers/submodule_helper.rb'
- 'app/workers/concerns/application_worker.rb'
- 'ee/lib/gitlab/geo/git_ssh_proxy.rb'
- 'lib/banzai/filter/repository_link_filter.rb'
- 'lib/gitlab/auth/ldap/dn.rb'
- 'lib/gitlab/gfm/uploads_rewriter.rb'
- 'lib/gitlab/git/ref.rb'
- 'lib/gitlab/project_template.rb'
- 'lib/gitlab/setup_helper.rb'
- 'lib/gitlab/time_tracking_formatter.rb'
- 'spec/controllers/projects/artifacts_controller_spec.rb'
- 'spec/lib/gitlab/gfm/uploads_rewriter_spec.rb'
- 'spec/support/helpers/test_env.rb'
# Offense count: 121
Performance/MethodObjectAsBlock:
Enabled: false
@ -398,22 +379,6 @@ Rails/WhereExists:
Style/AccessorGrouping:
Enabled: false
# Offense count: 11
# Cop supports --auto-correct.
Style/ArrayCoercion:
Exclude:
- 'app/controllers/admin/ci/variables_controller.rb'
- 'app/controllers/groups/variables_controller.rb'
- 'app/controllers/projects/variables_controller.rb'
- 'db/migrate/20190620105427_change_null_private_profile_to_false.rb'
- 'db/post_migrate/20190812070645_migrate_private_profile_nulls.rb'
- 'db/post_migrate/20200311130802_schedule_populate_user_highest_roles_table.rb'
- 'db/post_migrate/20200805152108_migrate_null_external_diff_store_to_local_value.rb'
- 'db/post_migrate/20200806173633_migrate_null_package_files_file_store_to_local_value.rb'
- 'ee/app/services/geo/repository_verification_secondary_service.rb'
- 'ee/lib/ee/banzai/pipeline/gfm_pipeline.rb'
- 'spec/support/helpers/lfs_http_helpers.rb'
# Offense count: 188
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
@ -433,20 +398,6 @@ Style/BisectedAttrAccessor:
Style/CaseLikeIf:
Enabled: false
# Offense count: 13
Style/CombinableLoops:
Exclude:
- 'ee/db/fixtures/development/30_customizable_cycle_analytics.rb'
- 'ee/lib/gitlab/audit/events/preloader.rb'
- 'ee/spec/finders/snippets_finder_spec.rb'
- 'ee/spec/lib/ee/gitlab/background_migration/remove_duplicate_cs_findings_spec.rb'
- 'spec/features/merge_request/user_suggests_changes_on_diff_spec.rb'
- 'spec/finders/packages/group_packages_finder_spec.rb'
- 'spec/migrations/cleanup_optimistic_locking_nulls_pt2_fixed_spec.rb'
- 'spec/migrations/cleanup_optimistic_locking_nulls_spec.rb'
- 'spec/requests/api/members_spec.rb'
- 'spec/support/shared_examples/features/protected_branches_access_control_ce_shared_examples.rb'
# Offense count: 5
# Cop supports --auto-correct.
Style/EachWithObject:
@ -471,13 +422,6 @@ Style/EmptyElse:
Style/EmptyMethod:
Enabled: false
# Offense count: 2
# Cop supports --auto-correct.
Style/ExpandPathArguments:
Exclude:
- 'cable/config.ru'
- 'config.ru'
# Offense count: 118
# Cop supports --auto-correct.
Style/ExplicitBlockArgument:

View File

@ -878,7 +878,6 @@ RSpec/VerifiedDoubles:
- spec/models/design_management/design_at_version_spec.rb
- spec/models/diff_viewer/image_spec.rb
- spec/models/environment_spec.rb
- spec/models/error_tracking/project_error_tracking_setting_spec.rb
- spec/models/event_spec.rb
- spec/models/external_issue_spec.rb
- spec/models/hooks/web_hook_spec.rb

View File

@ -0,0 +1,10 @@
---
# Cop supports --auto-correct.
Style/ArrayCoercion:
Exclude:
- 'app/controllers/admin/ci/variables_controller.rb'
- 'app/controllers/groups/variables_controller.rb'
- 'app/controllers/projects/variables_controller.rb'
- 'ee/app/services/geo/repository_verification_secondary_service.rb'
- 'ee/lib/ee/banzai/pipeline/gfm_pipeline.rb'
- 'spec/support/helpers/lfs_http_helpers.rb'

View File

@ -0,0 +1,10 @@
---
Style/CombinableLoops:
Exclude:
- 'ee/db/fixtures/development/30_customizable_cycle_analytics.rb'
- 'ee/lib/gitlab/audit/events/preloader.rb'
- 'ee/spec/finders/snippets_finder_spec.rb'
- 'spec/features/merge_request/user_suggests_changes_on_diff_spec.rb'
- 'spec/finders/packages/group_packages_finder_spec.rb'
- 'spec/requests/api/members_spec.rb'
- 'spec/support/shared_examples/features/protected_branches_access_control_ce_shared_examples.rb'

View File

@ -8,7 +8,6 @@ Style/OpenStructUse:
- ee/spec/lib/gitlab/auth/group_saml/failure_handler_spec.rb
- ee/spec/lib/gitlab/legacy_github_import/project_creator_spec.rb
- lib/gitlab/testing/request_inspector_middleware.rb
- spec/factories/go_module_versions.rb
- spec/factories/wiki_pages.rb
- spec/graphql/mutations/branches/create_spec.rb
- spec/graphql/mutations/clusters/agent_tokens/create_spec.rb

View File

@ -37,7 +37,7 @@ export default {
anchor: 'update-the-agent-version',
}),
configHelpLink: helpPagePath('user/clusters/agent/install/index', {
anchor: 'create-an-agent-without-configuration-file',
anchor: 'create-an-agent-configuration-file',
}),
inject: ['gitlabVersion'],
props: {

View File

@ -31,7 +31,7 @@ export default {
EVENT_LABEL_MODAL,
enableKasPath: helpPagePath('administration/clusters/kas'),
registerAgentPath: helpPagePath('user/clusters/agent/install/index', {
anchor: 'register-an-agent-with-gitlab',
anchor: 'register-the-agent-with-gitlab',
}),
components: {
AvailableAgentsDropdown,

View File

@ -2,6 +2,7 @@
import {
GlCollapse,
GlDropdown,
GlBadge,
GlButton,
GlLink,
GlSprintf,
@ -26,6 +27,7 @@ export default {
components: {
GlCollapse,
GlDropdown,
GlBadge,
GlButton,
GlLink,
GlSprintf,
@ -74,6 +76,7 @@ export default {
'Environments|There are no deployments for this environment yet. %{linkStart}Learn more about setting up deployments.%{linkEnd}',
),
autoStopIn: s__('Environment|Auto stop %{time}'),
tierTooltip: s__('Environment|Deployment tier'),
},
data() {
return { visible: false };
@ -100,6 +103,9 @@ export default {
hasDeployment() {
return Boolean(this.environment?.upcomingDeployment || this.environment?.lastDeployment);
},
tier() {
return this.lastDeployment?.tierInYaml;
},
hasOpenedAlert() {
return this.environment?.hasOpenedAlert;
},
@ -206,6 +212,13 @@ export default {
>
{{ displayName }}
</gl-link>
<gl-badge
v-if="tier"
v-gl-tooltip
:title="$options.i18n.tierTooltip"
class="gl-ml-3 gl-font-monospace"
>{{ tier }}</gl-badge
>
</div>
<div class="gl-display-flex gl-align-items-center">
<p v-if="canShowAutoStopDate" class="gl-font-sm gl-text-gray-700 gl-mr-5 gl-mb-0">

View File

@ -24,7 +24,7 @@ const mapNestedEnvironment = (env) => ({
__typename: 'NestedLocalEnvironment',
});
const mapEnvironment = (env) => ({
...convertObjectPropsToCamelCase(env),
...convertObjectPropsToCamelCase(env, { deep: true }),
__typename: 'LocalEnvironment',
});

View File

@ -1,5 +1,6 @@
<script>
import { GlLink, GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { IssuableStatus } from '~/issues/constants';
import {
dateInWords,
getTimeRemainingInWords,
@ -41,7 +42,10 @@ export default {
return this.issue.dueDate && dateInWords(newDateAsLocaleTime(this.issue.dueDate), true);
},
showDueDateInRed() {
return isInPast(newDateAsLocaleTime(this.issue.dueDate)) && !this.issue.closedAt;
return (
isInPast(newDateAsLocaleTime(this.issue.dueDate)) &&
this.issue.state !== IssuableStatus.Closed
);
},
timeEstimate() {
return this.issue.humanTimeEstimate || this.issue.timeStats?.humanTimeEstimate;

View File

@ -19,6 +19,7 @@ import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import { ITEM_TYPE } from '~/groups/constants';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
import { IssuableStatus } from '~/issues/constants';
import axios from '~/lib/utils/axios_utils';
import { scrollUp } from '~/lib/utils/scroll_utils';
import { getParameterByName, joinPaths } from '~/lib/utils/url_utility';
@ -480,10 +481,10 @@ export default {
return `${this.exportCsvPath}${window.location.search}`;
},
getStatus(issue) {
if (issue.closedAt && issue.moved) {
if (issue.state === IssuableStatus.Closed && issue.moved) {
return this.$options.i18n.closedMoved;
}
if (issue.closedAt) {
if (issue.state === IssuableStatus.Closed) {
return this.$options.i18n.closed;
}
return undefined;

View File

@ -2,7 +2,6 @@ fragment IssueFragment on Issue {
__typename
id
iid
closedAt
confidential
createdAt
downvotes
@ -11,6 +10,7 @@ fragment IssueFragment on Issue {
humanTimeEstimate
mergeRequestsCount
moved
state
title
updatedAt
upvotes

View File

@ -124,7 +124,7 @@ MergeRequest.prototype.submitNoteForm = function (form, $button) {
MergeRequest.decreaseCounter = function (by = 1) {
const $el = $('.js-merge-counter');
const count = Math.max(parseInt($el.text().replace(/[^\d]/, ''), 10) - by, 0);
const count = Math.max(parseInt($el.first().text().replace(/[^\d]/, ''), 10) - by, 0);
$el.text(addDelimiter(count));
};

View File

@ -29,6 +29,8 @@ module IssuableLink
validate :check_self_relation
validate :check_opposite_relation
scope :for_source_or_target, ->(issuable) { where(source: issuable).or(where(target: issuable)) }
enum link_type: { TYPE_RELATES_TO => 0, TYPE_BLOCKS => 1 }
private

View File

@ -380,6 +380,12 @@ class Deployment < ApplicationRecord
status == params[:status]
end
def tier_in_yaml
return unless deployable
deployable.environment_deployment_tier
end
private
def update_status!(status)

View File

@ -135,7 +135,7 @@ module ErrorTracking
end
end
def update_issue(opts = {} )
def update_issue(opts = {})
handle_exceptions do
{ updated: sentry_client.update_issue(opts) }
end

View File

@ -23,6 +23,7 @@ class DeploymentEntity < Grape::Entity
expose :tag
expose :last?
expose :last?, as: :is_last
expose :tier_in_yaml
expose :deployed_by, as: :user, using: UserEntity

View File

@ -41,6 +41,8 @@ module ContainerRegistry
Gitlab::ErrorTracking.log_exception(e, next_aborted_repository_id: next_aborted_repository&.id)
true
ensure
log_repository_migration_state(next_aborted_repository)
end
def handle_next_migration
@ -59,6 +61,8 @@ module ContainerRegistry
next_repository&.abort_import
false
ensure
log_repository_migration_state(next_repository)
end
def tag_count_too_high?
@ -151,6 +155,12 @@ module ContainerRegistry
log_extra_metadata_on_done(:container_repository_path, repository&.path)
end
def log_repository_migration_state(repository)
return unless repository
log_extra_metadata_on_done(:container_repository_migration_state, repository.migration_state)
end
# used by ExclusiveLeaseGuard
def lease_key
'container_registry:migration:enqueuer_worker'

View File

@ -2,7 +2,7 @@
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
require ::File.expand_path('config/environment', __dir__)
warmup do |app|
client = Rack::MockRequest.new(app)

View File

@ -2484,8 +2484,10 @@ Use `changes` in pipelines with the following refs:
- Paths to files.
- Wildcard paths for single directories, for example `path/to/directory/*`, or a directory
and all its subdirectories, for example `path/to/directory/**/*`.
- Wildcard ([glob](https://en.wikipedia.org/wiki/Glob_(programming))) paths for all
- Wildcard [glob](https://en.wikipedia.org/wiki/Glob_(programming)) paths for all
files with the same extension or multiple extensions, for example `*.md` or `path/to/directory/*.{rb,py,sh}`.
See the [Ruby `fnmatch` documentation](https://docs.ruby-lang.org/en/master/File.html#method-c-fnmatch)
for the supported syntax list.
- Wildcard paths to files in the root directory, or all directories, wrapped in double quotes.
For example `"*.json"` or `"**/*.json"`.

View File

@ -91,20 +91,25 @@ The API fuzzing configuration form helps you create or modify your project's API
configuration. The form lets you choose values for the most common API fuzzing options and builds
a YAML snippet that you can paste in your GitLab CI/CD configuration.
#### Configure Web API fuzzing with the configuration form
#### Configure Web API fuzzing in the UI
To generate an API Fuzzing configuration snippet:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Configuration**.
1. In the **API Fuzzing** row, select **Configure**.
1. Complete the form as needed. Read below for more information on available configuration options.
1. In the **API Fuzzing** row, select **Enable API Fuzzing**.
1. Complete the fields. For details see [Available CI/CD variables](#available-cicd-variables).
1. Select **Generate code snippet**.
A modal opens with the YAML snippet corresponding to the options you've selected in the form.
1. Choose one of the following actions:
1. To copy the snippet to your clipboard and be redirected to your project's `.gitlab-ci.yml` file,
where you can paste the YAML configuration, select **Copy code and open `.gitlab-ci.yml` file**.
1. To copy the snippet to your clipboard and close the modal, select **Copy code only**.
1. Do one of the following:
1. To copy the snippet to your clipboard, select **Copy code only**.
1. To add the snippet to your project's `.gitlab-ci.yml` file, select
**Copy code and open `.gitlab-ci.yml` file**. The Pipeline Editor opens.
1. Paste the snippet into the `.gitlab-ci.yml` file.
1. Select the **Lint** tab to confirm the edited `.gitlab-ci.yml` file is valid.
1. Select the **Edit** tab, then select **Commit changes**.
When the snippet is committed to the `.gitlab-ci.yml` file, pipelines include an API Fuzzing job.
### OpenAPI Specification

View File

@ -278,7 +278,8 @@ page.
You can enable or configure DAST settings using the UI. The generated settings are formatted so they
can be conveniently pasted into the `.gitlab-ci.yml` file.
1. From the project's home page, go to **Security & Compliance > Configuration**.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Configuration**.
1. In the **Dynamic Application Security Testing (DAST)** section, select **Enable DAST** or
**Configure DAST**.
1. Select the desired **Scanner profile**, or select **Create scanner profile** and save a
@ -288,12 +289,14 @@ can be conveniently pasted into the `.gitlab-ci.yml` file.
1. Select **Generate code snippet**. A modal opens with the YAML snippet corresponding to the
options you selected.
1. Do one of the following:
1. Select **Copy code only** to copy the snippet to your clipboard.
1. Select **Copy code and open `.gitlab-ci.yml` file** to copy the snippet to your clipboard. The
CI/CD Editor then opens.
1. To copy the snippet to your clipboard, select **Copy code only**.
1. To add the snippet to your project's `.gitlab-ci.yml` file, select
**Copy code and open `.gitlab-ci.yml` file**. The Pipeline Editor opens.
1. Paste the snippet into the `.gitlab-ci.yml` file.
1. Select the **Lint** tab to confirm the edited `.gitlab-ci.yml` file is valid.
1. Select **Commit changes**.
1. Select the **Edit** tab, then select **Commit changes**.
When the snippet is committed to the `.gitlab-ci.yml` file, pipelines include a DAST job.
#### Crawling web applications dependent on JavaScript

View File

@ -84,9 +84,9 @@ the body generation is limited to these body types:
- `application/json`
- `application/xml`
Follow these steps to configure DAST API in GitLab with an OpenAPI specification:
To configure DAST API scanning with an OpenAPI specification:
1. To use DAST API, you must [include](../../../ci/yaml/index.md#includetemplate)
1. To use DAST API scanning, [include](../../../ci/yaml/index.md#includetemplate)
the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml)
that's provided as part of your GitLab installation. Add the following to your
`.gitlab-ci.yml` file:
@ -182,8 +182,7 @@ WARNING:
HAR files may contain sensitive information such as authentication tokens, API keys, and session
cookies. We recommend that you review the HAR file contents before adding them to a repository.
Follow these steps to configure DAST API to use a HAR file that provides information about the
target API to test:
To configure DAST API scanning to use a HAR file:
1. To use DAST API, you must [include](../../../ci/yaml/index.md#includetemplate)
the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml)
@ -282,8 +281,7 @@ Postman Collection files may contain sensitive information such as authenticatio
and session cookies. We recommend that you review the Postman Collection file contents before adding
them to a repository.
Follow these steps to configure DAST API to use a Postman Collection file that provides
information about the target API to test:
To configure DAST API scanning to use a Postman Collection file:
1. To use DAST API, you must [include](../../../ci/yaml/index.md#includetemplate)
the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml)

View File

@ -508,19 +508,18 @@ always take the latest dependency scanning artifact available.
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/282533) in GitLab 14.1.
> - [Feature flag sec_dependency_scanning_ui_enable removed](https://gitlab.com/gitlab-org/gitlab/-/issues/326005) in GitLab 14.2.
To enable Dependency Scanning in a project, you can create a merge request
from the Security Configuration page.
To enable Dependency Scanning in a project, you can create a merge request:
1. In the project where you want to enable Dependency Scanning, navigate to
**Security & Compliance > Configuration**.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Configuration**.
1. In the **Dependency Scanning** row, select **Configure with a merge request**.
1. Review and merge the merge request to enable Dependency Scanning.
This automatically creates a merge request with the changes necessary to enable Dependency Scanning
that you can review and merge to complete the configuration.
Pipelines now include a dependency scanning job.
### Customizing the dependency scanning settings
The dependency scanning settings can be changed through [CI/CD variables](#available-cicd-variables) by using the
The Dependency Scanning settings can be changed through [CI/CD variables](#available-cicd-variables) by using the
[`variables`](../../../ci/yaml/index.md#variables) parameter in `.gitlab-ci.yml`.
For example:

View File

@ -93,15 +93,14 @@ that you can download and analyze.
### Enable IaC Scanning via an automatic merge request
To enable IaC Scanning in a project, you can create a merge request
from the Security Configuration page:
To enable IaC Scanning in a project, you can create a merge request:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Configuration**.
1. In the **Infrastructure as Code (IaC) Scanning** row, select **Configure with a merge request**.
1. Review and merge the merge request to enable IaC Scanning.
This automatically creates a merge request with the changes necessary to enable IaC Scanning
that you can review and merge to complete the configuration.
Pipelines now include an IaC job.
## Reports JSON format

View File

@ -190,56 +190,57 @@ always take the latest SAST artifact available.
### Configure SAST in the UI
You can enable and configure SAST in the UI, either with default settings, or with customizations.
Use the method that best meets your needs.
The method you can use depends on your GitLab license tier.
- [Configure SAST in the UI with default settings](#configure-sast-in-the-ui-with-default-settings)
- [Configure SAST in the UI with customizations](#configure-sast-in-the-ui-with-customizations)
- [Configure SAST in the UI with default settings](#configure-sast-in-the-ui-with-default-settings).
- [Configure SAST in the UI with customizations](#configure-sast-in-the-ui-with-customizations). **(ULTIMATE)**
### Configure SAST in the UI with default settings
> [Introduced](https://about.gitlab.com/releases/2021/02/22/gitlab-13-9-released/#security-configuration-page-for-all-users) in GitLab 13.9
To enable and configure SAST with default settings:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance** > **Configuration**.
1. In the SAST section, select `Enable via MR`.
1. Review the draft MR that enables SAST with the default recommended settings in the
`.gitlab-ci.yml` file.
1. Merge the MR to enable SAST. You should see SAST jobs run in that MR's pipeline.
NOTE:
The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal
configuration file. If you have a complex GitLab configuration file it may not be parsed
successfully, and an error may occur.
To enable and configure SAST with default settings:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance** > **Configuration**.
1. In the SAST section, select **Configure with a merge request**.
1. Review and merge the merge request to enable SAST.
Pipelines now include a SAST job.
### Configure SAST in the UI with customizations **(ULTIMATE)**
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3659) in GitLab 13.3.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/232862) in GitLab 13.4.
> - [Improved](https://gitlab.com/groups/gitlab-org/-/epics/3635) in GitLab 13.5.
NOTE:
The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal
configuration file. If you have a complex GitLab configuration file it may not be parsed
successfully, and an error may occur.
To enable and configure SAST with customizations:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Configuration**.
1. If the project does not have a `.gitlab-ci.yml` file, select **Enable** in the Static Application
Security Testing (SAST) row, otherwise select **Configure**.
1. If the project does not have a `.gitlab-ci.yml` file, select **Enable SAST** in the Static
Application Security Testing (SAST) row, otherwise select **Configure SAST**.
1. Enter the custom SAST values.
Custom values are stored in the `.gitlab-ci.yml` file. For CI/CD variables not in the SAST
Configuration page, their values are left unchanged. Default values are inherited from the GitLab
SAST template.
Configuration page, their values are inherited from the GitLab SAST template.
1. Optionally, expand the **SAST analyzers** section, select individual
[SAST analyzers](analyzers.md) and enter custom analyzer values.
1. Select **Create Merge Request**.
1. Review and merge the merge request.
NOTE:
The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal
configuration file. If you have a complex GitLab configuration file it may not be parsed
successfully, and an error may occur.
Pipelines now include a SAST job.
### Overriding SAST jobs

View File

@ -112,20 +112,19 @@ always take the latest Secret Detection artifact available.
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4496) in GitLab 13.11, deployed behind a feature flag, enabled by default.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/329886) in GitLab 14.1.
To enable Secret Detection in a project, you can create a merge request
from the Security Configuration page.
1. In the project where you want to enable Secret Detection, go to
**Security & Compliance > Configuration**.
1. In the **Secret Detection** row, select **Configure with a merge request**.
This automatically creates a merge request with the changes necessary to enable Secret Detection
that you can review and merge to complete the configuration.
NOTE:
The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal
configuration file. If you have a complex GitLab configuration file it may not be parsed
successfully, and an error may occur.
This method works best with no existing `.gitlab-ci.yml` file, or with a minimal configuration
file. If you have a complex GitLab configuration file it may not be parsed successfully, and an
error may occur.
To enable Secret Detection in a project, you can create a merge request:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Configuration**.
1. In the **Secret Detection** row, select **Configure with a merge request**.
1. Review and merge the merge request to enable Secret Detection.
Pipelines now include a Secret Detection job.
### Customizing settings

View File

@ -69,6 +69,8 @@ Creating a file is optional but is needed if:
- You use [a GitOps workflow](../gitops.md#gitops-configuration-reference) and you want a more advanced configuration.
- You use a GitLab CI/CD workflow. In that workflow, you must [authorize the agent](../ci_cd_tunnel.md#authorize-the-agent).
If you do not create an agent configuration file, you can use the CI/CD workflow in the project where the agent is registered only.
To create an agent configuration file, go to the GitLab project. In the repository, create a file called `config.yaml` at this path:
```plaintext

View File

@ -67,14 +67,16 @@ module API
requires :issue_link_id, type: Integer, desc: 'The ID of an issue link'
end
delete ':id/issues/:issue_iid/links/:issue_link_id' do
issue_link = IssueLink.find(declared_params[:issue_link_id])
issue = find_project_issue(params[:issue_iid])
issue_link = IssueLink
.for_source_or_target(issue)
.find(declared_params[:issue_link_id])
find_project_issue(params[:issue_iid])
find_project_issue(issue_link.target.iid.to_s, issue_link.target.project_id.to_s)
result = ::IssueLinks::DestroyService
.new(issue_link, current_user)
.execute
.new(issue_link, current_user)
.execute
if result[:status] == :success
present issue_link, with: Entities::IssueLink

View File

@ -52,9 +52,9 @@ module Gitlab
WHERE cte_id = id
SQL
end
mark_job_as_succeeded(start_id, end_id)
end
mark_job_as_succeeded(start_id, end_id)
end
private

View File

@ -4,11 +4,13 @@ module Gitlab
module Database
module EachDatabase
class << self
def each_database_connection(only: nil)
def each_database_connection(only: nil, include_shared: true)
selected_names = Array.wrap(only)
base_models = select_base_models(selected_names)
base_models.each_pair do |connection_name, model|
next if !include_shared && Gitlab::Database.db_config_share_with(model.connection_db_config)
connection = model.connection
with_shared_connection(connection, connection_name) do

View File

@ -20,7 +20,7 @@ namespace :gitlab do
begin
ActiveRecord::Base.establish_connection(db_config) # rubocop: disable Database/EstablishConnection
ActiveRecord::Base.connection.select_one("SELECT system_identifier, current_database() FROM pg_control_system()")
rescue ActiveRecord::NoDatabaseError, PG::ConnectionBad
rescue ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished, PG::ConnectionBad
end
{

View File

@ -53,7 +53,7 @@ namespace :gitlab do
AND pid <> pg_backend_pid();
SQL
Gitlab::Database::EachDatabase.each_database_connection do |connection|
Gitlab::Database::EachDatabase.each_database_connection(include_shared: false) do |connection|
connection.execute(cmd)
rescue ActiveRecord::NoDatabaseError
end

View File

@ -7402,6 +7402,9 @@ msgstr ""
msgid "Child epic doesn't exist."
msgstr ""
msgid "Child issues and epics"
msgstr ""
msgid "Chinese language support using"
msgstr ""
@ -14395,6 +14398,9 @@ msgstr ""
msgid "Environment|Auto stop %{time}"
msgstr ""
msgid "Environment|Deployment tier"
msgstr ""
msgid "Epic"
msgstr ""
@ -14419,9 +14425,6 @@ msgstr ""
msgid "Epics Roadmap"
msgstr ""
msgid "Epics and Issues"
msgstr ""
msgid "Epics let you manage your portfolio of projects more efficiently and with less effort"
msgstr ""
@ -15413,6 +15416,9 @@ msgstr ""
msgid "Failed to load"
msgstr ""
msgid "Failed to load Roadmap"
msgstr ""
msgid "Failed to load assignees."
msgstr ""
@ -32148,6 +32154,9 @@ msgstr ""
msgid "Roadmap settings"
msgstr ""
msgid "Roadmap view"
msgstr ""
msgid "Role"
msgstr ""

View File

@ -75,11 +75,10 @@ module QA
# @return [Boolean]
def has_imported_project?(gh_project_name, wait: QA::Support::WaitForRequests::DEFAULT_MAX_WAIT_TIME)
within_element(:project_import_row, source_project: gh_project_name, skip_finished_loading_check: true) do
# TODO: remove retrier with reload:true once https://gitlab.com/gitlab-org/gitlab/-/issues/292861 is fixed
wait_until(
max_duration: wait,
sleep_interval: 5,
reload: true,
reload: false,
skip_finished_loading_check_on_refresh: true
) do
has_element?(:import_status_indicator, text: "Complete")

View File

@ -3,6 +3,8 @@
module QA
RSpec.describe 'Package', :orchestrated, :skip_live_env do
describe 'Self-managed Container Registry' do
include Support::Helpers::MaskToken
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'project-with-registry'
@ -110,9 +112,9 @@ module QA
let(:auth_token) do
case authentication_token_type
when :personal_access_token
"\"#{personal_access_token}\""
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project)
when :project_deploy_token
"\"#{project_deploy_token.token}\""
use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
when :ci_job_token
'$CI_JOB_TOKEN'
end

View File

@ -5,6 +5,7 @@ module QA
describe 'Helm Registry' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
include Support::Helpers::MaskToken
include_context 'packages registry qa scenario'
let(:package_name) { "gitlab_qa_helm-#{SecureRandom.hex(8)}" }
@ -32,11 +33,13 @@ module QA
let(:access_token) do
case authentication_token_type
when :personal_access_token
personal_access_token
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: package_project)
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: client_project)
when :ci_job_token
'${CI_JOB_TOKEN}'
when :project_deploy_token
project_deploy_token.token
use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: package_project)
use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: client_project)
end
end

View File

@ -5,6 +5,7 @@ module QA
describe 'npm instance level endpoint' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
include Support::Helpers::MaskToken
let!(:registry_scope) { Runtime::Namespace.sandbox_name }
let!(:personal_access_token) do
@ -78,11 +79,13 @@ module QA
let(:auth_token) do
case authentication_token_type
when :personal_access_token
"\"#{personal_access_token}\""
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project)
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: another_project)
when :ci_job_token
'${CI_JOB_TOKEN}'
when :project_deploy_token
"\"#{project_deploy_token.token}\""
use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: another_project)
end
end

View File

@ -5,6 +5,7 @@ module QA
describe 'npm project level endpoint' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
include Support::Helpers::MaskToken
let!(:registry_scope) { Runtime::Namespace.sandbox_name }
let!(:personal_access_token) do
@ -69,11 +70,11 @@ module QA
let(:auth_token) do
case authentication_token_type
when :personal_access_token
"\"#{personal_access_token}\""
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project)
when :ci_job_token
'${CI_JOB_TOKEN}'
when :project_deploy_token
"\"#{project_deploy_token.token}\""
use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
end
end

View File

@ -5,6 +5,7 @@ module QA
describe 'NuGet group level endpoint' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
include Support::Helpers::MaskToken
let(:project) do
Resource::Project.fabricate_via_api! do |project|
@ -61,6 +62,8 @@ module QA
after do
runner.remove_via_api!
package.remove_via_api!
project.remove_via_api!
another_project.remove_via_api!
end
where(:case_name, :authentication_token_type, :token_name, :testcase) do
@ -73,11 +76,13 @@ module QA
let(:auth_token_password) do
case authentication_token_type
when :personal_access_token
"\"#{personal_access_token.token}\""
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token.token, project: project)
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token.token, project: another_project)
when :ci_job_token
'${CI_JOB_TOKEN}'
when :group_deploy_token
"\"#{group_deploy_token.token}\""
use_ci_variable(name: 'GROUP_DEPLOY_TOKEN', value: group_deploy_token.token, project: project)
use_ci_variable(name: 'GROUP_DEPLOY_TOKEN', value: group_deploy_token.token, project: another_project)
end
end

View File

@ -3,6 +3,8 @@
module QA
RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
describe 'NuGet project level endpoint' do
include Support::Helpers::MaskToken
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'nuget-package-project'
@ -77,11 +79,11 @@ module QA
let(:auth_token_password) do
case authentication_token_type
when :personal_access_token
"\"#{personal_access_token.token}\""
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token.token, project: project)
when :ci_job_token
'${CI_JOB_TOKEN}'
when :project_deploy_token
"\"#{project_deploy_token.token}\""
use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
end
end

View File

@ -4,6 +4,7 @@ module QA
RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
describe 'PyPI Repository' do
include Runtime::Fixtures
include Support::Helpers::MaskToken
let(:project) do
Resource::Project.fabricate_via_api! do |project|
@ -30,7 +31,7 @@ module QA
let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) }
let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" }
let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" }
let(:personal_access_token) { Runtime::Env.personal_access_token }
let(:personal_access_token) { use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: Runtime::Env.personal_access_token, project: project) }
before do
Flow::Login.sign_in

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
module QA
module Support
module Helpers
module MaskToken
def use_ci_variable(name:, value:, project:)
Resource::CiVariable.fabricate_via_api! do |ci_variable|
ci_variable.project = project
ci_variable.key = name
ci_variable.value = value
ci_variable.protected = true
end
"$#{name}"
end
end
end
end
end

View File

@ -5,12 +5,10 @@ FactoryBot.define do
skip_create
initialize_with do
p = attributes[:params]
s = Packages::SemVer.parse(p.semver, prefixed: true)
s = Packages::SemVer.parse(semver, prefixed: true)
raise ArgumentError, "invalid sematic version: #{semver.inspect}" if !s && semver
raise ArgumentError, "invalid sematic version: '#{p.semver}'" if !s && p.semver
new(p.mod, p.type, p.commit, name: p.name, semver: s, ref: p.ref)
new(mod, type, commit, name: name, semver: s, ref: ref)
end
mod { association(:go_module) }
@ -20,8 +18,6 @@ FactoryBot.define do
semver { nil }
ref { nil }
params { OpenStruct.new(mod: mod, type: type, commit: commit, name: name, semver: semver, ref: ref) }
trait :tagged do
ref { mod.project.repository.find_tag(name) }
commit { ref.dereferenced_target }
@ -36,8 +32,8 @@ FactoryBot.define do
.max_by(&:to_s)
.to_s
end
params { OpenStruct.new(mod: mod, type: :ref, commit: commit, semver: name, ref: ref) }
type { :ref }
semver { name }
end
end
end

View File

@ -10,7 +10,7 @@ RSpec.describe "User merges a merge request", :js do
end
shared_examples "fast forward merge a merge request" do
it "merges a merge request", :sidekiq_might_not_need_inline do
it "merges a merge request", :sidekiq_inline do
expect(page).to have_content("Fast-forward merge without a merge commit").and have_button("Merge")
page.within(".mr-state-widget") do
@ -42,4 +42,23 @@ RSpec.describe "User merges a merge request", :js do
it_behaves_like "fast forward merge a merge request"
end
end
context 'sidebar merge requests counter' do
let(:project) { create(:project, :public, :repository) }
let!(:merge_request) { create(:merge_request, source_project: project) }
it 'decrements the open MR count', :sidekiq_inline do
create(:merge_request, source_project: project, source_branch: 'branch-1')
visit(merge_request_path(merge_request))
expect(page).to have_css('.js-merge-counter', text: '2')
page.within(".mr-state-widget") do
click_button("Merge")
end
expect(page).to have_css('.js-merge-counter', text: '1')
end
end
end

View File

@ -9,7 +9,7 @@ import timeagoMixin from '~/vue_shared/mixins/timeago';
import { clusterAgents, connectedTimeNow, connectedTimeInactive } from './mock_data';
const defaultConfigHelpUrl =
'/help/user/clusters/agent/install/index#create-an-agent-without-configuration-file';
'/help/user/clusters/agent/install/index#create-an-agent-configuration-file';
const provideData = {
gitlabVersion: '14.8',

View File

@ -543,6 +543,7 @@ export const resolvedEnvironment = {
externalUrl: 'https://example.org',
environmentType: 'review',
nameWithoutType: 'hello',
tier: 'development',
lastDeployment: {
id: 78,
iid: 24,
@ -551,6 +552,7 @@ export const resolvedEnvironment = {
status: 'success',
createdAt: '2022-01-07T15:47:27.415Z',
deployedAt: '2022-01-07T15:47:32.450Z',
tierInYaml: 'staging',
tag: false,
isLast: true,
user: {

View File

@ -73,6 +73,34 @@ describe('~/environments/components/new_environment_item.vue', () => {
expect(name.text()).toHaveLength(80);
});
describe('tier', () => {
it('displays the tier of the environment when defined in yaml', () => {
wrapper = createWrapper({ apolloProvider: createApolloProvider() });
const tier = wrapper.findByTitle(s__('Environment|Deployment tier'));
expect(tier.text()).toBe(resolvedEnvironment.lastDeployment.tierInYaml);
});
it('does not display the tier if not defined in yaml', () => {
const environment = {
...resolvedEnvironment,
lastDeployment: {
...resolvedEnvironment.lastDeployment,
tierInYaml: null,
},
};
wrapper = createWrapper({
propsData: { environment },
apolloProvider: createApolloProvider(),
});
const tier = wrapper.findByTitle(s__('Environment|Deployment tier'));
expect(tier.exists()).toBe(false);
});
});
describe('url', () => {
it('shows a link for the url if one is present', () => {
wrapper = createWrapper({ apolloProvider: createApolloProvider() });

View File

@ -1,6 +1,7 @@
import { GlIcon, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { useFakeDate } from 'helpers/fake_date';
import { IssuableStatus } from '~/issues/constants';
import IssueCardTimeInfo from '~/issues/list/components/issue_card_time_info.vue';
describe('CE IssueCardTimeInfo component', () => {
@ -24,7 +25,7 @@ describe('CE IssueCardTimeInfo component', () => {
const findDueDate = () => wrapper.find('[data-testid="issuable-due-date"]');
const mountComponent = ({
closedAt = null,
state = IssuableStatus.Open,
dueDate = issue.dueDate,
milestoneDueDate = issue.milestone.dueDate,
milestoneStartDate = issue.milestone.startDate,
@ -38,7 +39,7 @@ describe('CE IssueCardTimeInfo component', () => {
dueDate: milestoneDueDate,
startDate: milestoneStartDate,
},
closedAt,
state,
dueDate,
},
},
@ -101,7 +102,7 @@ describe('CE IssueCardTimeInfo component', () => {
it('does not render in red', () => {
wrapper = mountComponent({
dueDate: '2020-10-10',
closedAt: '2020-09-05T13:06:25Z',
state: IssuableStatus.Closed,
});
expect(findDueDate().classes()).not.toContain('gl-text-red-500');

View File

@ -21,7 +21,6 @@ export const getIssuesQueryResponse = {
__typename: 'Issue',
id: 'gid://gitlab/Issue/123456',
iid: '789',
closedAt: null,
confidential: false,
createdAt: '2021-05-22T04:08:01Z',
downvotes: 2,
@ -30,6 +29,7 @@ export const getIssuesQueryResponse = {
humanTimeEstimate: null,
mergeRequestsCount: false,
moved: false,
state: 'opened',
title: 'Issue title',
updatedAt: '2021-05-22T04:08:01Z',
upvotes: 3,

View File

@ -39,6 +39,14 @@ RSpec.describe Gitlab::BackgroundMigration::EncryptStaticObjectToken do
expect(new_state[user_with_encrypted_token.id]).to match_array([nil, 'encrypted'])
end
context 'when id range does not include existing user ids' do
let(:arguments) { [non_existing_record_id, non_existing_record_id.succ] }
it_behaves_like 'marks background migration job records' do
subject { described_class.new }
end
end
private
def create_user!(name:, token: nil, encrypted_token: nil)

View File

@ -58,6 +58,15 @@ RSpec.describe Gitlab::Database::EachDatabase do
end
end
end
context 'when shared connections are not included' do
it 'only yields the unshared connections' do
expect(Gitlab::Database).to receive(:db_config_share_with).twice.and_return(nil, 'main')
expect { |b| described_class.each_database_connection(include_shared: false, &b) }
.to yield_successive_args([ActiveRecord::Base.connection, 'main'])
end
end
end
describe '.each_model_connection' do

View File

@ -1055,6 +1055,40 @@ RSpec.describe Deployment do
end
end
describe '#tier_in_yaml' do
context 'when deployable is nil' do
before do
subject.deployable = nil
end
it 'returns nil' do
expect(subject.tier_in_yaml).to be_nil
end
end
context 'when deployable is present' do
context 'when tier is specified' do
let(:deployable) { create(:ci_build, :success, :environment_with_deployment_tier) }
before do
subject.deployable = deployable
end
it 'returns the tier' do
expect(subject.tier_in_yaml).to eq('testing')
end
context 'when tier is not specified' do
let(:deployable) { create(:ci_build, :success) }
it 'returns nil' do
expect(subject.tier_in_yaml).to be_nil
end
end
end
end
end
describe '.fast_destroy_all' do
it 'cleans path_refs for destroyed environments' do
project = create(:project, :repository)

View File

@ -8,6 +8,8 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
let_it_be(:project) { create(:project) }
let(:sentry_client) { instance_double(ErrorTracking::SentryClient) }
subject(:setting) { build(:project_error_tracking_setting, project: project) }
describe 'Associations' do
@ -48,7 +50,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
expect(subject.errors.messages[:project]).to include('is a required field')
end
context 'presence validations' do
describe 'presence validations' do
using RSpec::Parameterized::TableSyntax
valid_api_url = 'http://example.com/api/0/projects/org-slug/proj-slug/'
@ -83,12 +85,12 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
describe 'after_save :create_client_key!' do
subject { build(:project_error_tracking_setting, :integrated, project: project) }
context 'no client key yet' do
context 'without client key' do
it 'creates a new client key' do
expect { subject.save! }.to change { ErrorTracking::ClientKey.count }.by(1)
end
context 'sentry backend' do
context 'with sentry backend' do
before do
subject.integrated = false
end
@ -98,7 +100,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
end
context 'feature disabled' do
context 'when feature disabled' do
before do
subject.enabled = false
end
@ -109,7 +111,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
end
context 'client key already exists' do
context 'when client key already exists' do
let!(:client_key) { create(:error_tracking_client_key, project: project) }
it 'does not create a new client key' do
@ -122,13 +124,13 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
describe '.extract_sentry_external_url' do
subject { described_class.extract_sentry_external_url(sentry_url) }
describe 'when passing a URL' do
context 'when passing a URL' do
let(:sentry_url) { 'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project' }
it { is_expected.to eq('https://sentrytest.gitlab.com/sentry-org/sentry-project') }
end
describe 'when passing nil' do
context 'when passing nil' do
let(:sentry_url) { nil }
it { is_expected.to be_nil }
@ -159,23 +161,15 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
describe '#list_sentry_issues' do
let(:issues) { [:list, :of, :issues] }
let(:opts) do
{ issue_status: 'unresolved', limit: 10 }
end
let(:result) do
subject.list_sentry_issues(**opts)
end
let(:result) { subject.list_sentry_issues(**opts) }
let(:opts) { { issue_status: 'unresolved', limit: 10 } }
context 'when cached' do
let(:sentry_client) { spy(:sentry_client) }
before do
stub_reactive_cache(subject, issues, opts)
synchronous_reactive_cache(subject)
expect(subject).to receive(:sentry_client).and_return(sentry_client)
allow(subject).to receive(:sentry_client).and_return(sentry_client)
end
it 'returns cached issues' do
@ -195,8 +189,6 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
context 'when sentry client raises ErrorTracking::SentryClient::Error' do
let(:sentry_client) { spy(:sentry_client) }
before do
synchronous_reactive_cache(subject)
@ -214,14 +206,13 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
context 'when sentry client raises ErrorTracking::SentryClient::MissingKeysError' do
let(:sentry_client) { spy(:sentry_client) }
before do
synchronous_reactive_cache(subject)
allow(subject).to receive(:sentry_client).and_return(sentry_client)
allow(sentry_client).to receive(:list_issues).with(opts)
.and_raise(ErrorTracking::SentryClient::MissingKeysError, 'Sentry API response is missing keys. key not found: "id"')
.and_raise(ErrorTracking::SentryClient::MissingKeysError,
'Sentry API response is missing keys. key not found: "id"')
end
it 'returns error' do
@ -233,8 +224,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
context 'when sentry client raises ErrorTracking::SentryClient::ResponseInvalidSizeError' do
let(:sentry_client) { spy(:sentry_client) }
let(:error_msg) {"Sentry API response is too big. Limit is #{Gitlab::Utils::DeepSize.human_default_max_size}."}
let(:error_msg) { "Sentry API response is too big. Limit is #{Gitlab::Utils::DeepSize.human_default_max_size}." }
before do
synchronous_reactive_cache(subject)
@ -253,8 +243,6 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
context 'when sentry client raises StandardError' do
let(:sentry_client) { spy(:sentry_client) }
before do
synchronous_reactive_cache(subject)
@ -270,7 +258,6 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
describe '#list_sentry_projects' do
let(:projects) { [:list, :of, :projects] }
let(:sentry_client) { spy(:sentry_client) }
it 'calls sentry client' do
expect(subject).to receive(:sentry_client).and_return(sentry_client)
@ -284,19 +271,17 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
describe '#issue_details' do
let(:issue) { build(:error_tracking_sentry_detailed_error) }
let(:sentry_client) { double('sentry_client', issue_details: issue) }
let(:commit_id) { issue.first_release_version }
let(:result) do
subject.issue_details
end
let(:result) { subject.issue_details(opts) }
let(:opts) { { issue_id: 1 } }
context 'when cached' do
before do
stub_reactive_cache(subject, issue, {})
synchronous_reactive_cache(subject)
expect(subject).to receive(:sentry_client).and_return(sentry_client)
allow(subject).to receive(:sentry_client).and_return(sentry_client)
allow(sentry_client).to receive(:issue_details).with(opts).and_return(issue)
end
it { expect(result).to eq(issue: issue) }
@ -314,15 +299,15 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
context 'when repo commit matches first relase version' do
let(:commit) { double('commit', id: commit_id) }
let(:repository) { double('repository', commit: commit) }
let(:commit) { instance_double(Commit, id: commit_id) }
let(:repository) { instance_double(Repository, commit: commit) }
before do
expect(project).to receive(:repository).and_return(repository)
allow(project).to receive(:repository).and_return(repository)
end
it { expect(result[:issue].gitlab_commit).to eq(commit_id) }
it { expect(result[:issue].gitlab_commit_path).to eq("/#{project.namespace.path}/#{project.path}/-/commit/#{commit_id}") }
it { expect(result[:issue].gitlab_commit_path).to eq(project_commit_path(project, commit_id)) }
end
end
@ -333,19 +318,15 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
describe '#update_issue' do
let(:opts) do
{ status: 'resolved' }
let(:result) { subject.update_issue(**opts) }
let(:opts) { { issue_id: 1, params: {} } }
before do
allow(subject).to receive(:sentry_client).and_return(sentry_client)
end
let(:result) do
subject.update_issue(**opts)
end
let(:sentry_client) { spy(:sentry_client) }
context 'successful call to sentry' do
context 'when sentry response is successful' do
before do
allow(subject).to receive(:sentry_client).and_return(sentry_client)
allow(sentry_client).to receive(:update_issue).with(opts).and_return(true)
end
@ -354,9 +335,8 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
end
context 'sentry raises an error' do
context 'when sentry raises an error' do
before do
allow(subject).to receive(:sentry_client).and_return(sentry_client)
allow(sentry_client).to receive(:update_issue).with(opts).and_raise(StandardError)
end
@ -366,7 +346,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
end
context 'slugs' do
describe 'slugs' do
shared_examples_for 'slug from api_url' do |method, slug|
context 'when api_url is correct' do
before do
@ -393,9 +373,9 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
it_behaves_like 'slug from api_url', :organization_slug, 'org-slug'
end
context 'names from api_url' do
describe 'names from api_url' do
shared_examples_for 'name from api_url' do |name, titleized_slug|
context 'name is present in DB' do
context 'when name is present in DB' do
it 'returns name from DB' do
subject[name] = 'Sentry name'
subject.api_url = 'http://gitlab.com/api/0/projects/org-slug/project-slug'
@ -404,7 +384,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
end
context 'name is null in DB' do
context 'when name is null in DB' do
it 'titleizes and returns slug from api_url' do
subject[name] = nil
subject.api_url = 'http://gitlab.com/api/0/projects/org-slug/project-slug'

View File

@ -205,16 +205,30 @@ RSpec.describe API::IssueLinks do
end
context 'when user has ability to delete the issue link' do
it 'returns 200' do
target_issue = create(:issue, project: project)
issue_link = create(:issue_link, source: issue, target: target_issue)
let_it_be(:target_issue) { create(:issue, project: project) }
before do
project.add_reporter(user)
end
it 'returns 200' do
issue_link = create(:issue_link, source: issue, target: target_issue)
delete api("/projects/#{project.id}/issues/#{issue.iid}/links/#{issue_link.id}", user)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/issue_link')
end
it 'returns 404 when the issue link does not belong to the specified issue' do
other_issue = create(:issue, project: project)
issue_link = create(:issue_link, source: other_issue, target: target_issue)
delete api("/projects/#{project.id}/issues/#{issue.iid}/links/#{issue_link.id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not found')
end
end
end
end

View File

@ -9,7 +9,7 @@ RSpec.describe DeploymentEntity do
let(:project) { create(:project, :repository) }
let(:request) { double('request') }
let(:deployment) { create(:deployment, deployable: build, project: project) }
let(:build) { create(:ci_build, :manual, pipeline: pipeline) }
let(:build) { create(:ci_build, :manual, :environment_with_deployment_tier, pipeline: pipeline) }
let(:pipeline) { create(:ci_pipeline, project: project, user: user) }
let(:entity) { described_class.new(deployment, request: request) }
@ -46,6 +46,10 @@ RSpec.describe DeploymentEntity do
expect(subject).to include(:is_last)
end
it 'exposes deployment tier in yaml' do
expect(subject).to include(:tier_in_yaml)
end
context 'when deployable is nil' do
let(:entity) { described_class.new(deployment, request: request, deployment_details: false) }
let(:deployment) { create(:deployment, deployable: nil, project: project) }

View File

@ -237,6 +237,7 @@ RSpec.configure do |config|
# Enable all features by default for testing
# Reset any changes in after hook.
stub_all_feature_flags
stub_feature_flags(main_branch_over_master: false)
TestEnv.seed_db
end

View File

@ -55,6 +55,19 @@ RSpec.shared_examples 'issuable link' do
end
end
describe 'scopes' do
describe '.for_source_or_target' do
it 'returns only links where id is either source or target id' do
link1 = create(issuable_link_factory, source: issuable_link.source)
link2 = create(issuable_link_factory, target: issuable_link.source)
# unrelated link, should not be included in result list
create(issuable_link_factory) # rubocop: disable Rails/SaveBang
expect(described_class.for_source_or_target(issuable_link.source_id)).to match_array([issuable_link, link1, link2])
end
end
end
describe '.link_type' do
it { is_expected.to define_enum_for(:link_type).with_values(relates_to: 0, blocks: 1) }

View File

@ -53,6 +53,18 @@ RSpec.describe 'gitlab:db:validate_config', :silence_stdout do
expect { run_rake_task('gitlab:db:validate_config') }.not_to output(/Database config validation failure/).to_stderr
expect { run_rake_task('gitlab:db:validate_config') }.not_to raise_error
end
context 'when finding the initializer fails' do
where(:raised_error) { [ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished, PG::ConnectionBad] }
with_them do
it "does not raise an error for #{params[:raised_error]}" do
allow(ActiveRecord::Base.connection).to receive(:select_one).and_raise(raised_error) # rubocop: disable Database/MultipleDatabases
expect { run_rake_task('gitlab:db:validate_config') }.not_to output(/Database config validation failure/).to_stderr
expect { run_rake_task('gitlab:db:validate_config') }.not_to raise_error
end
end
end
end
shared_examples 'raises an error' do |match|

View File

@ -22,7 +22,11 @@ RSpec.describe 'gitlab:setup namespace rake tasks', :silence_stdout do
let(:server_service1) { double(:server_service) }
let(:server_service2) { double(:server_service) }
let(:connections) { Gitlab::Database.database_base_models.values.map(&:connection) }
let(:connections) do
Gitlab::Database.database_base_models.values.filter_map do |model|
model.connection if Gitlab::Database.db_config_share_with(model.connection_db_config).nil?
end
end
before do
allow(Gitlab).to receive_message_chain('config.repositories.storages').and_return(storages)
@ -119,6 +123,10 @@ RSpec.describe 'gitlab:setup namespace rake tasks', :silence_stdout do
end
def expect_connections_to_be_terminated
expect(Gitlab::Database::EachDatabase).to receive(:each_database_connection)
.with(include_shared: false)
.and_call_original
expect(connections).to all(receive(:execute).with(/SELECT pg_terminate_backend/))
end

View File

@ -64,7 +64,8 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures
expect_log_extra_metadata(
import_type: 'next',
container_repository_id: container_repository.id,
container_repository_path: container_repository.path
container_repository_path: container_repository.path,
container_repository_migration_state: 'pre_importing'
)
subject
@ -135,7 +136,8 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures
expect_log_extra_metadata(
import_type: 'retry',
container_repository_id: aborted_repository.id,
container_repository_path: aborted_repository.path
container_repository_path: aborted_repository.path,
container_repository_migration_state: 'importing'
)
subject
@ -158,7 +160,8 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures
expect_log_extra_metadata(
import_type: 'retry',
container_repository_id: aborted_repository.id,
container_repository_path: aborted_repository.path
container_repository_path: aborted_repository.path,
container_repository_migration_state: 'import_aborted'
)
subject
@ -189,6 +192,7 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures
import_type: 'next',
container_repository_id: container_repository.id,
container_repository_path: container_repository.path,
container_repository_migration_state: 'import_skipped',
tags_count_too_high: true,
max_tags_count_setting: 2
)
@ -212,7 +216,8 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures
expect_log_extra_metadata(
import_type: 'next',
container_repository_id: container_repository.id,
container_repository_path: container_repository.path
container_repository_path: container_repository.path,
container_repository_migration_state: 'import_aborted'
)
expect(Gitlab::ErrorTracking).to receive(:log_exception).with(