Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
e4a0b94a64
commit
cdd826bc3a
|
@ -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
|
||||
|
||||
<!--
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
|
@ -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'
|
|
@ -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
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -24,7 +24,7 @@ const mapNestedEnvironment = (env) => ({
|
|||
__typename: 'NestedLocalEnvironment',
|
||||
});
|
||||
const mapEnvironment = (env) => ({
|
||||
...convertObjectPropsToCamelCase(env),
|
||||
...convertObjectPropsToCamelCase(env, { deep: true }),
|
||||
__typename: 'LocalEnvironment',
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"`.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ""
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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() });
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue