Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
8015f09545
commit
e09f6bdfd1
|
@ -38,8 +38,8 @@ export const toggleContainerClasses = (containerEl, classList) => {
|
|||
/**
|
||||
* Return a object mapping element dataset names to booleans.
|
||||
*
|
||||
* This is useful for data- attributes whose presence represent
|
||||
* a truthiness, no matter the value of the attribute. The absence of the
|
||||
* This is useful for data- attributes whose presense represent
|
||||
* a truthiness, no matter the value of the attribute. The absense of the
|
||||
* attribute represents falsiness.
|
||||
*
|
||||
* This can be useful when Rails-provided boolean-like values are passed
|
||||
|
|
|
@ -4,9 +4,10 @@ import { __, s__ } from '~/locale';
|
|||
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
|
||||
import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
|
||||
import SectionLayout from '~/vue_shared/security_configuration/components/section_layout.vue';
|
||||
import currentLicenseQuery from '~/security_configuration/graphql/current_license.query.graphql';
|
||||
import AutoDevOpsAlert from './auto_dev_ops_alert.vue';
|
||||
import AutoDevOpsEnabledAlert from './auto_dev_ops_enabled_alert.vue';
|
||||
import { AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY } from './constants';
|
||||
import { AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY, LICENSE_ULTIMATE } from './constants';
|
||||
import FeatureCard from './feature_card.vue';
|
||||
import TrainingProviderList from './training_provider_list.vue';
|
||||
import UpgradeBanner from './upgrade_banner.vue';
|
||||
|
@ -50,6 +51,17 @@ export default {
|
|||
TrainingProviderList,
|
||||
},
|
||||
inject: ['projectFullPath', 'vulnerabilityTrainingDocsPath'],
|
||||
apollo: {
|
||||
currentLicensePlan: {
|
||||
query: currentLicenseQuery,
|
||||
update({ currentLicense }) {
|
||||
return currentLicense?.plan;
|
||||
},
|
||||
error() {
|
||||
this.hasCurrentLicenseFetchError = true;
|
||||
},
|
||||
},
|
||||
},
|
||||
props: {
|
||||
augmentedSecurityFeatures: {
|
||||
type: Array,
|
||||
|
@ -84,15 +96,13 @@ export default {
|
|||
required: false,
|
||||
default: '',
|
||||
},
|
||||
securityTrainingEnabled: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
autoDevopsEnabledAlertDismissedProjects: [],
|
||||
errorMessage: '',
|
||||
currentLicensePlan: '',
|
||||
hasCurrentLicenseFetchError: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -113,6 +123,12 @@ export default {
|
|||
!this.autoDevopsEnabledAlertDismissedProjects.includes(this.projectFullPath)
|
||||
);
|
||||
},
|
||||
shouldShowVulnerabilityManagementTab() {
|
||||
// if the query fails (if the plan is `null` also means an error has occurred) we still want to show the feature
|
||||
const hasQueryError = this.hasCurrentLicenseFetchError || this.currentLicensePlan === null;
|
||||
|
||||
return hasQueryError || this.currentLicensePlan === LICENSE_ULTIMATE;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
dismissAutoDevopsEnabledAlert() {
|
||||
|
@ -237,9 +253,9 @@ export default {
|
|||
{{ $options.i18n.description }}
|
||||
</p>
|
||||
<p v-if="canViewCiHistory">
|
||||
<gl-link data-testid="compliance-view-history-link" :href="gitlabCiHistoryPath">
|
||||
{{ $options.i18n.configurationHistory }}
|
||||
</gl-link>
|
||||
<gl-link data-testid="compliance-view-history-link" :href="gitlabCiHistoryPath">{{
|
||||
$options.i18n.configurationHistory
|
||||
}}</gl-link>
|
||||
</p>
|
||||
</template>
|
||||
<template #features>
|
||||
|
@ -254,18 +270,20 @@ export default {
|
|||
</section-layout>
|
||||
</gl-tab>
|
||||
<gl-tab
|
||||
v-if="securityTrainingEnabled"
|
||||
v-if="shouldShowVulnerabilityManagementTab"
|
||||
data-testid="vulnerability-management-tab"
|
||||
:title="$options.i18n.vulnerabilityManagement"
|
||||
query-param-value="vulnerability-management"
|
||||
>
|
||||
<section-layout :heading="$options.i18n.securityTraining">
|
||||
<template #description>
|
||||
<p>{{ $options.i18n.securityTrainingDescription }}</p>
|
||||
<p>
|
||||
<gl-link :href="vulnerabilityTrainingDocsPath">
|
||||
{{ $options.i18n.securityTrainingDoc }}
|
||||
</gl-link>
|
||||
{{ $options.i18n.securityTrainingDescription }}
|
||||
</p>
|
||||
<p>
|
||||
<gl-link :href="vulnerabilityTrainingDocsPath">{{
|
||||
$options.i18n.securityTrainingDoc
|
||||
}}</gl-link>
|
||||
</p>
|
||||
</template>
|
||||
<template #features>
|
||||
|
|
|
@ -310,3 +310,7 @@ export const TEMP_PROVIDER_URLS = {
|
|||
Kontra: 'https://application.security/',
|
||||
[__('Secure Code Warrior')]: 'https://www.securecodewarrior.com/',
|
||||
};
|
||||
|
||||
export const LICENSE_ULTIMATE = 'ultimate';
|
||||
export const LICENSE_FREE = 'free';
|
||||
export const LICENSE_PREMIUM = 'premium';
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
query getCurrentLicensePlan {
|
||||
currentLicense {
|
||||
id
|
||||
plan
|
||||
}
|
||||
}
|
|
@ -56,7 +56,6 @@ export const initSecurityConfiguration = (el) => {
|
|||
'gitlabCiPresent',
|
||||
'autoDevopsEnabled',
|
||||
'canEnableAutoDevops',
|
||||
'securityTrainingEnabled',
|
||||
]),
|
||||
},
|
||||
});
|
||||
|
|
|
@ -155,7 +155,7 @@ export default {
|
|||
requests.forEach((request) => {
|
||||
const poll = new Poll({
|
||||
resource: {
|
||||
fetchData: () => request(this.$props),
|
||||
fetchData: () => request(this),
|
||||
},
|
||||
method: 'fetchData',
|
||||
successCallback: (response) => {
|
||||
|
@ -180,7 +180,7 @@ export default {
|
|||
initExtensionPolling() {
|
||||
const poll = new Poll({
|
||||
resource: {
|
||||
fetchData: () => this.fetchCollapsedData(this.$props),
|
||||
fetchData: () => this.fetchCollapsedData(this),
|
||||
},
|
||||
method: 'fetchData',
|
||||
successCallback: ({ data }) => {
|
||||
|
@ -208,7 +208,7 @@ export default {
|
|||
this.initExtensionPolling();
|
||||
}
|
||||
} else {
|
||||
this.fetchCollapsedData(this.$props)
|
||||
this.fetchCollapsedData(this)
|
||||
.then((data) => {
|
||||
this.setCollapsedData(data);
|
||||
})
|
||||
|
@ -231,7 +231,7 @@ export default {
|
|||
|
||||
this.loadingState = LOADING_STATES.expandedLoading;
|
||||
|
||||
this.fetchFullData(this.$props)
|
||||
this.fetchFullData(this)
|
||||
.then((data) => {
|
||||
this.loadingState = null;
|
||||
this.fullData = data.map((x, i) => ({ id: i, ...x }));
|
||||
|
|
|
@ -34,13 +34,7 @@ export default {
|
|||
{ ...extension },
|
||||
{
|
||||
props: {
|
||||
...extension.props.reduce(
|
||||
(acc, key) => ({
|
||||
...acc,
|
||||
[key]: this.mr[key],
|
||||
}),
|
||||
{},
|
||||
),
|
||||
mr: this.mr,
|
||||
},
|
||||
},
|
||||
),
|
||||
|
|
|
@ -10,12 +10,26 @@ export const registerExtension = (extension) => {
|
|||
registeredExtensions.extensions.push({
|
||||
extends: ExtensionBase,
|
||||
name: extension.name,
|
||||
props: extension.props,
|
||||
props: {
|
||||
mr: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
i18n: extension.i18n,
|
||||
expandEvent: extension.expandEvent,
|
||||
enablePolling: extension.enablePolling,
|
||||
modalComponent: extension.modalComponent,
|
||||
computed: {
|
||||
...extension.props.reduce(
|
||||
(acc, propKey) => ({
|
||||
...acc,
|
||||
[propKey]() {
|
||||
return this.mr[propKey];
|
||||
},
|
||||
}),
|
||||
{},
|
||||
),
|
||||
...Object.keys(extension.computed).reduce(
|
||||
(acc, computedKey) => ({
|
||||
...acc,
|
||||
|
|
|
@ -49,7 +49,7 @@ export default {
|
|||
]"
|
||||
class="gl-rounded-full gl-mr-3 gl-relative gl-p-2"
|
||||
>
|
||||
<gl-loading-icon v-if="isLoading" size="lg" inline class="gl-display-block" />
|
||||
<gl-loading-icon v-if="isLoading" size="sm" inline class="gl-display-block" />
|
||||
<gl-icon
|
||||
v-else
|
||||
:name="$options.EXTENSION_ICON_NAMES[iconName]"
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
a {
|
||||
color: $gl-text-color;
|
||||
|
||||
&.link,
|
||||
&.gl-link {
|
||||
&.link {
|
||||
color: $blue-600;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,13 +246,13 @@ module MergeRequestsHelper
|
|||
''
|
||||
end
|
||||
|
||||
link_to branch, branch_path, title: branch, class: 'gl-link gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-px-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n2'
|
||||
link_to branch, branch_path, title: branch, class: 'gl-text-blue-500! gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-px-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n2'
|
||||
end
|
||||
|
||||
def merge_request_header(project, merge_request)
|
||||
link_to_author = link_to_member(project, merge_request.author, size: 24, extra_class: 'gl-font-weight-bold', avatar: false)
|
||||
copy_button = clipboard_button(text: merge_request.source_branch, title: _('Copy branch name'), class: 'btn btn-default btn-sm gl-button btn-default-tertiary btn-icon gl-display-none! gl-md-display-inline-block! js-source-branch-copy')
|
||||
target_branch = link_to merge_request.target_branch, project_tree_path(merge_request.target_project, merge_request.target_branch), title: merge_request.target_branch, class: 'gl-link gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-px-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n2'
|
||||
target_branch = link_to merge_request.target_branch, project_tree_path(merge_request.target_project, merge_request.target_branch), title: merge_request.target_branch, class: 'gl-text-blue-500! gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-px-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n2'
|
||||
|
||||
_('%{author} requested to merge %{source_branch} %{copy_button} into %{target_branch} %{created_at}').html_safe % { author: link_to_author.html_safe, source_branch: merge_request_source_branch(merge_request).html_safe, copy_button: copy_button.html_safe, target_branch: target_branch.html_safe, created_at: time_ago_with_tooltip(merge_request.created_at, html_class: 'gl-display-inline-block').html_safe }
|
||||
end
|
||||
|
|
|
@ -118,7 +118,7 @@ class Label < ApplicationRecord
|
|||
| # Integer-based label ID, or
|
||||
(?<label_name>
|
||||
# String-based single-word label title, or
|
||||
[A-Za-z0-9_\-\?\.&]+
|
||||
#{Gitlab::Regex.sep_by_1(/:{1,2}/, /[A-Za-z0-9_\-\?\.&]+/)}
|
||||
(?<!\.|\?)
|
||||
|
|
||||
# String-based multi-word label surrounded in quotes
|
||||
|
|
|
@ -2906,10 +2906,6 @@ class Project < ApplicationRecord
|
|||
build_artifacts_size_refresh&.started?
|
||||
end
|
||||
|
||||
def security_training_available?
|
||||
licensed_feature_available?(:security_training)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# overridden in EE
|
||||
|
|
|
@ -24,8 +24,7 @@ module Projects
|
|||
gitlab_ci_history_path: gitlab_ci_history_path,
|
||||
auto_fix_enabled: autofix_enabled,
|
||||
can_toggle_auto_fix_settings: can_toggle_autofix,
|
||||
auto_fix_user_path: auto_fix_user_path,
|
||||
security_training_enabled: project.security_training_available?
|
||||
auto_fix_user_path: auto_fix_user_path
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ instance of the [GraphiQL explorer](https://gitlab.com/-/graphql-explorer):
|
|||
|
||||
1. Open the [GraphiQL Explorer](https://gitlab.com/-/graphql-explorer) page.
|
||||
1. Paste the `query` listed above into the left window of your GraphiQL explorer tool.
|
||||
1. Click Play to get the result shown here:
|
||||
1. Select Play to get the result shown here:
|
||||
|
||||
![GraphiQL explorer search for boards](img/sample_issue_boards_v13_2.png)
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ GET /runners?tag_list=tag1,tag2
|
|||
|------------|--------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online` and `offline`; showing all runners if none provided |
|
||||
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
|
||||
| `status` | string | no | The status of runners to show, one of: `online`, `offline` and `never_contacted`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `status` | string | no | The status of runners to show, one of: `online`, `offline`, `stale`, and `never_contacted`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
|
||||
| `tag_list` | string array | no | List of the runner's tags |
|
||||
|
||||
|
@ -113,7 +113,7 @@ GET /runners/all?tag_list=tag1,tag2
|
|||
|------------|--------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online` and `offline`; showing all runners if none provided |
|
||||
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
|
||||
| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `status` | string | no | The status of runners to show, one of: `online`, `offline`, `stale`, and `never_contacted`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
|
||||
| `tag_list` | string array | no | List of the runner's tags |
|
||||
|
||||
|
@ -464,7 +464,7 @@ GET /projects/:id/runners?tag_list=tag1,tag2
|
|||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online` and `offline`; showing all runners if none provided |
|
||||
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
|
||||
| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `status` | string | no | The status of runners to show, one of: `online`, `offline`, `stale`, and `never_contacted`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
|
||||
| `tag_list` | string array | no | List of the runner's tags |
|
||||
|
||||
|
@ -580,7 +580,7 @@ GET /groups/:id/runners?tag_list=tag1,tag2
|
|||
|------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `id` | integer | yes | The ID of the group owned by the authenticated user |
|
||||
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type`. The `project_type` value is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/351466) and will be removed in GitLab 15.0 |
|
||||
| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `status` | string | no | The status of runners to show, one of: `online`, `offline`, `stale`, and `never_contacted`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
|
||||
| `tag_list` | string array | no | List of the runner's tags |
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ environments are not displayed.
|
|||
|
||||
To add a project to the dashboard:
|
||||
|
||||
1. Click the **Add projects** button in the home screen of the dashboard.
|
||||
1. Select **Add projects** in the home screen of the dashboard.
|
||||
1. Search and add one or more projects using the **Search your projects** field.
|
||||
1. Click the **Add projects** button.
|
||||
1. Select **Add projects**.
|
||||
|
||||
Once added, you can see a summary of each project's environment operational
|
||||
health, including the latest commit, pipeline status, and deployment time.
|
||||
|
|
|
@ -63,7 +63,7 @@ rollout 10%:
|
|||
ROLLOUT_PERCENTAGE: 10
|
||||
```
|
||||
|
||||
When the jobs are built, a **play** button appears next to the job's name. Click the **play** button
|
||||
When the jobs are built, a **play** button appears next to the job's name. Select **play**
|
||||
to release each stage of pods. You can also rollback by running a lower percentage job. Once 100%
|
||||
is reached, you cannot roll back using this method. It is still possible to roll back by redeploying
|
||||
the old version using the **Rollback** button on the environment page.
|
||||
|
|
|
@ -92,7 +92,7 @@ For more information, see [Deployment safety](../environments/deployment_safety.
|
|||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211339) in GitLab 13.6.
|
||||
|
||||
A deployment job can fail because a newer one has run. If you retry the failed deployment job, the
|
||||
environment could be overwritten with older source code. If you click **Retry**, a modal warns you
|
||||
environment could be overwritten with older source code. If you select **Retry**, a modal warns you
|
||||
about this and asks for confirmation.
|
||||
|
||||
For more information, see [Deployment safety](../environments/deployment_safety.md).
|
||||
|
|
|
@ -85,9 +85,9 @@ To protect or unprotect a runner:
|
|||
|
||||
1. Go to the project's **Settings > CI/CD** and expand the **Runners** section.
|
||||
1. Find the runner you want to protect or unprotect. Make sure it's enabled.
|
||||
1. Click the pencil button.
|
||||
1. Select the pencil button.
|
||||
1. Check the **Protected** option.
|
||||
1. Click **Save changes**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
![specific runners edit icon](img/protected_runners_check_box_v14_1.png)
|
||||
|
||||
|
@ -113,7 +113,7 @@ To reset the registration token:
|
|||
|
||||
1. Go to the project's **Settings > CI/CD**.
|
||||
1. Expand the **General pipelines settings** section.
|
||||
1. Find the **Runner token** form field and click the **Reveal value** button.
|
||||
1. Find the **Runner token** form field and select **Reveal value**.
|
||||
1. Delete the value and save the form.
|
||||
1. After the page is refreshed, expand the **Runners settings** section
|
||||
and check the registration token - it should be changed.
|
||||
|
@ -193,9 +193,9 @@ To make a runner pick untagged jobs:
|
|||
|
||||
1. Go to the project's **Settings > CI/CD** and expand the **Runners** section.
|
||||
1. Find the runner you want to pick untagged jobs and make sure it's enabled.
|
||||
1. Click the pencil button.
|
||||
1. Select the pencil button.
|
||||
1. Check the **Run untagged jobs** option.
|
||||
1. Click the **Save changes** button for the changes to take effect.
|
||||
1. Select **Save changes** for the changes to take effect.
|
||||
|
||||
NOTE:
|
||||
The runner tags list can not be empty when it's not allowed to pick untagged jobs.
|
||||
|
|
|
@ -84,7 +84,7 @@ To disable shared runners for a group:
|
|||
1. Go to the group's **Settings > CI/CD** and expand the **Runners** section.
|
||||
1. In the **Shared runners** area, turn off the **Enable shared runners for this group** toggle.
|
||||
1. Optionally, to allow shared runners to be enabled for individual projects or subgroups,
|
||||
click **Allow projects and subgroups to override the group setting**.
|
||||
select **Allow projects and subgroups to override the group setting**.
|
||||
|
||||
NOTE:
|
||||
To re-enable the shared runners for a group, turn on the
|
||||
|
@ -200,11 +200,11 @@ You must have the Owner role for the group.
|
|||
|
||||
1. Go to the group you want to remove or pause the runner for.
|
||||
1. On the left sidebar, select **CI/CD > Runners**.
|
||||
1. Click **Pause** or **Remove runner**.
|
||||
1. Select **Pause** or **Remove runner**.
|
||||
- If you pause a group runner that is used by multiple projects, the runner pauses for all projects.
|
||||
- From the group view, you cannot remove a runner that is assigned to more than one project.
|
||||
You must remove it from each project first.
|
||||
1. On the confirmation dialog, click **OK**.
|
||||
1. On the confirmation dialog, select **OK**.
|
||||
|
||||
## Specific runners
|
||||
|
||||
|
|
|
@ -226,9 +226,9 @@ Download Ruby and compile it:
|
|||
|
||||
```shell
|
||||
mkdir /tmp/ruby && cd /tmp/ruby
|
||||
curl --remote-name --location --progress-bar "https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.5.tar.gz"
|
||||
echo '2755b900a21235b443bb16dadd9032f784d4a88f143d852bc5d154f22b8781f1 ruby-2.7.5.tar.gz' | sha256sum -c - && tar xzf ruby-2.7.5.tar.gz
|
||||
cd ruby-2.7.5
|
||||
curl --remote-name --location --progress-bar "https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.6.tar.gz"
|
||||
echo 'e7203b0cc09442ed2c08936d483f8ac140ec1c72e37bb5c401646b7866cb5d10 ruby-2.7.6.tar.gz' | sha256sum -c - && tar xzf ruby-2.7.6.tar.gz
|
||||
cd ruby-2.7.6
|
||||
|
||||
./configure --disable-install-rdoc --enable-shared
|
||||
make
|
||||
|
|
|
@ -97,6 +97,6 @@ application.
|
|||
[restart GitLab](../administration/restart_gitlab.md#installations-from-source).
|
||||
|
||||
On the sign-in page there should now be an Auth0 icon below the regular sign-in
|
||||
form. Click the icon to begin the authentication process. Auth0 asks the
|
||||
form. Select the icon to begin the authentication process. Auth0 asks the
|
||||
user to sign in and authorize the GitLab application. If the user authenticates
|
||||
successfully, the user is returned to GitLab and signed in.
|
||||
|
|
|
@ -261,7 +261,7 @@ To enable languages support:
|
|||
1. On the left sidebar, select **Settings > Advanced Search**.
|
||||
1. Locate **Custom analyzers: language support**.
|
||||
1. Enable plugins support for **Indexing**.
|
||||
1. Click **Save changes** for the changes to take effect.
|
||||
1. Select **Save changes** for the changes to take effect.
|
||||
1. Trigger [Zero downtime reindexing](#zero-downtime-reindexing) or reindex everything from scratch to create a new index with updated mappings.
|
||||
1. Enable plugins support for **Searching** after the previous step is completed.
|
||||
|
||||
|
@ -435,7 +435,7 @@ Some migrations are built with a retry limit. If the migration cannot finish wit
|
|||
it is halted and a notification is displayed in the Advanced Search integration settings.
|
||||
It is recommended to check the [`elasticsearch.log` file](../administration/logs.md#elasticsearchlog) to
|
||||
debug why the migration was halted and make any changes before retrying the migration. Once you believe you've
|
||||
fixed the cause of the failure, click "Retry migration", and the migration is scheduled to be retried
|
||||
fixed the cause of the failure, select "Retry migration", and the migration is scheduled to be retried
|
||||
in the background.
|
||||
|
||||
If you cannot get the migration to succeed, you may
|
||||
|
@ -611,7 +611,7 @@ Sidekiq processes](../administration/operations/extra_sidekiq_processes.md).
|
|||
|
||||
This enqueues a Sidekiq job for each project that needs to be indexed.
|
||||
You can view the jobs in **Menu > Admin > Monitoring > Background Jobs > Queues Tab**
|
||||
and click `elastic_commit_indexer`, or you can query indexing status using a Rake task:
|
||||
and select `elastic_commit_indexer`, or you can query indexing status using a Rake task:
|
||||
|
||||
```shell
|
||||
# Omnibus installations
|
||||
|
|
|
@ -91,7 +91,7 @@ To change your personal details, including name, billing address, and email addr
|
|||
1. Select **My account > Account details**.
|
||||
1. Expand the **Personal details** section.
|
||||
1. Edit your personal details.
|
||||
1. Click **Save changes**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
### Change your company details
|
||||
|
||||
|
@ -101,7 +101,7 @@ To change your company details, including company name and VAT number:
|
|||
1. Select **My account > Account details**.
|
||||
1. Expand the **Company details** section.
|
||||
1. Edit the company details.
|
||||
1. Click **Save changes**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
### Change your payment method
|
||||
|
||||
|
@ -117,7 +117,7 @@ To change your payment method:
|
|||
1. Log in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in).
|
||||
1. Select **My account > Payment methods**.
|
||||
1. **Edit** an existing payment method's information or **Add new payment method**.
|
||||
1. Click **Save Changes**.
|
||||
1. Select **Save Changes**.
|
||||
|
||||
#### Set a default payment method
|
||||
|
||||
|
@ -127,7 +127,7 @@ method as the default:
|
|||
1. Log in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in).
|
||||
1. Select **My account > Payment methods**.
|
||||
1. **Edit** the selected payment method and check the **Make default payment method** checkbox.
|
||||
1. Click **Save Changes**.
|
||||
1. Select **Save Changes**.
|
||||
|
||||
### Change the linked account
|
||||
|
||||
|
@ -137,8 +137,8 @@ To change the GitLab.com account linked to your Customers Portal account:
|
|||
[Customers Portal](https://customers.gitlab.com/customers/sign_in).
|
||||
1. In a separate browser tab, go to [GitLab SaaS](https://gitlab.com) and ensure you
|
||||
are not logged in.
|
||||
1. On the Customers Portal page, click **My account > Account details**.
|
||||
1. Under **Your GitLab.com account**, click **Change linked account**.
|
||||
1. On the Customers Portal page, select **My account > Account details**.
|
||||
1. Under **Your GitLab.com account**, select **Change linked account**.
|
||||
1. Log in to the [GitLab SaaS](https://gitlab.com) account you want to link to the Customers Portal
|
||||
account.
|
||||
|
||||
|
@ -164,9 +164,9 @@ Only one namespace can be linked to a subscription.
|
|||
To change the password for this customers portal account:
|
||||
|
||||
1. Log in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in).
|
||||
1. Select the **My account** drop-down and click on **Account details**.
|
||||
1. Select the **My account** drop-down and select on **Account details**.
|
||||
1. Make the required changes to the **Your password** section.
|
||||
1. Click **Save changes**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
## Community program subscriptions
|
||||
|
||||
|
|
|
@ -69,9 +69,9 @@ Download Ruby and compile it:
|
|||
|
||||
```shell
|
||||
mkdir /tmp/ruby && cd /tmp/ruby
|
||||
curl --remote-name --location --progress-bar "https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.5.tar.gz"
|
||||
echo '2755b900a21235b443bb16dadd9032f784d4a88f143d852bc5d154f22b8781f1 ruby-2.7.5.tar.gz' | sha256sum -c - && tar xzf ruby-2.7.5.tar.gz
|
||||
cd ruby-2.7.5
|
||||
curl --remote-name --location --progress-bar "https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.6.tar.gz"
|
||||
echo 'e7203b0cc09442ed2c08936d483f8ac140ec1c72e37bb5c401646b7866cb5d10 ruby-2.7.6.tar.gz' | sha256sum -c - && tar xzf ruby-2.7.6.tar.gz
|
||||
cd ruby-2.7.6
|
||||
|
||||
./configure --disable-install-rdoc --enable-shared
|
||||
make
|
||||
|
|
|
@ -49,7 +49,7 @@ In order to:
|
|||
After you have successful deployments to your group-level or instance-level cluster:
|
||||
|
||||
1. Navigate to your group's **Kubernetes** page.
|
||||
1. Click on the **Environments** tab.
|
||||
1. Select the **Environments** tab.
|
||||
|
||||
Only successful deployments to the cluster are included in this page.
|
||||
Non-cluster environments aren't included.
|
||||
|
|
|
@ -98,7 +98,7 @@ To enable the Prometheus integration for your cluster:
|
|||
**Kubernetes** page.
|
||||
1. Select the **Integrations** tab.
|
||||
1. Check the **Enable Prometheus integration** checkbox.
|
||||
1. Click **Save changes**.
|
||||
1. Select **Save changes**.
|
||||
1. Go to the **Health** tab to see your cluster's metrics.
|
||||
|
||||
## Elastic Stack cluster integration **(FREE SELF)**
|
||||
|
@ -165,5 +165,5 @@ To enable the Elastic Stack integration for your cluster:
|
|||
**Kubernetes** page.
|
||||
1. Select the **Integrations** tab.
|
||||
1. Check the **Enable Elastic Stack integration** checkbox.
|
||||
1. Click **Save changes**.
|
||||
1. Select **Save changes**.
|
||||
1. Go to the **Health** tab to see your cluster's metrics.
|
||||
|
|
|
@ -49,7 +49,7 @@ Select the desired period from the calendar dropdown.
|
|||
|
||||
## Sorting by different factors
|
||||
|
||||
Contributions per group member are also presented in tabular format. Click a column header to sort the table by that column:
|
||||
Contributions per group member are also presented in tabular format. Select a column header to sort the table by that column:
|
||||
|
||||
- Member name
|
||||
- Number of pushed events
|
||||
|
|
|
@ -115,7 +115,7 @@ To set a limit on how long personal access tokens are valid for users in a group
|
|||
1. Navigate to the **Settings > General** page in your group's sidebar.
|
||||
1. Expand the **Permissions and group features** section.
|
||||
1. Fill in the **Maximum allowable lifetime for access tokens (days)** field.
|
||||
1. Click **Save changes**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
Once a lifetime for personal access tokens is set:
|
||||
|
||||
|
|
|
@ -577,7 +577,7 @@ To generate a SAML Response:
|
|||
- [SAML-tracer](https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/) for Firefox.
|
||||
1. Open a new browser tab.
|
||||
1. Open the SAML tracer console:
|
||||
- Chrome: Right click on the page, select **Inspect**, then click on the SAML tab in the opened developer console.
|
||||
- Chrome: Right click on the page, select **Inspect**, then select the SAML tab in the opened developer console.
|
||||
- Firefox: Select the SAML-tracer icon located on the browser toolbar.
|
||||
1. Go to the GitLab single sign-on URL for the group in the same browser tab with the SAML tracer open.
|
||||
1. Select **Authorize** or attempt to log in. A SAML response is displayed in the tracer console that resembles this
|
||||
|
|
|
@ -82,7 +82,7 @@ table, use the Azure defaults. For a list of required attributes, refer to the [
|
|||
|
||||
For guidance, you can view [an example configuration in the troubleshooting reference](../../../administration/troubleshooting/group_saml_scim.md#azure-active-directory).
|
||||
|
||||
1. Below the mapping list click on **Show advanced options > Edit attribute list for AppName**.
|
||||
1. Below the mapping list select **Show advanced options > Edit attribute list for AppName**.
|
||||
1. Ensure the `id` is the primary and required field, and `externalId` is also required.
|
||||
|
||||
NOTE:
|
||||
|
|
|
@ -23,9 +23,9 @@ To add a project to the dashboard:
|
|||
1. Ensure your alerts populate the `gitlab_environment_name` label on the alerts you set up in Prometheus.
|
||||
The value of this should match the name of your environment in GitLab.
|
||||
In GitLab 13.9, you can display alerts for the `production` environment only.
|
||||
1. Click the **Add projects** button in the home screen of the dashboard.
|
||||
1. Select **Add projects** in the home screen of the dashboard.
|
||||
1. Search and add one or more projects using the **Search your projects** field.
|
||||
1. Click the **Add projects** button.
|
||||
1. Select **Add projects**.
|
||||
|
||||
Once added, the dashboard displays the project's number of active alerts,
|
||||
last commit, pipeline status, and when it was last deployed.
|
||||
|
|
|
@ -57,7 +57,7 @@ To download and run a container image hosted in the GitLab Container Registry:
|
|||
1. Copy the link to your container image:
|
||||
- Go to your project or group's **Packages & Registries > Container Registry**
|
||||
and find the image you want.
|
||||
- Next to the image name, click the **Copy** button.
|
||||
- Next to the image name, select **Copy**.
|
||||
|
||||
![Container Registry image URL](img/container_registry_hover_path_13_4.png)
|
||||
|
||||
|
@ -404,7 +404,7 @@ To delete images from within GitLab:
|
|||
by clicking the red **{remove}** **Trash** icon next to the tag you want
|
||||
to delete.
|
||||
|
||||
1. In the dialog box, click **Remove tag**.
|
||||
1. In the dialog box, select **Remove tag**.
|
||||
|
||||
### Delete images using the API
|
||||
|
||||
|
@ -506,7 +506,7 @@ You can, however, remove the Container Registry for a project:
|
|||
1. Go to your project's **Settings > General** page.
|
||||
1. Expand the **Visibility, project features, permissions** section
|
||||
and disable **Container Registry**.
|
||||
1. Click **Save changes**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
The **Packages & Registries > Container Registry** entry is removed from the project's sidebar.
|
||||
|
||||
|
|
|
@ -109,12 +109,12 @@ To create a cleanup policy in the UI:
|
|||
| **Remove tags older than** | Remove only tags older than X days. |
|
||||
| **Remove tags matching** | The regex pattern that determines which tags to remove. This value cannot be blank. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
|
||||
|
||||
1. Click **Save**.
|
||||
1. Select **Save**.
|
||||
|
||||
Depending on the interval you chose, the policy is scheduled to run.
|
||||
|
||||
NOTE:
|
||||
If you edit the policy and click **Save** again, the interval is reset.
|
||||
If you edit the policy and select **Save** again, the interval is reset.
|
||||
|
||||
### Regex pattern examples
|
||||
|
||||
|
|
|
@ -701,7 +701,7 @@ dependencies {
|
|||
|
||||
For your project, go to **Packages & Registries > Package Registry**.
|
||||
|
||||
To remove a package, click the red trash icon or, from the package details, the **Delete** button.
|
||||
To remove a package, select the red trash icon or, from the package details, the **Delete** button.
|
||||
|
||||
## Create Maven packages with GitLab CI/CD
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ To use the [project-level](#use-the-gitlab-endpoint-for-nuget-packages) NuGet en
|
|||
|
||||
![Visual Studio Adding a NuGet source](img/visual_studio_adding_nuget_source.png)
|
||||
|
||||
1. Click **Save**.
|
||||
1. Select **Save**.
|
||||
|
||||
The source is displayed in your list.
|
||||
|
||||
|
@ -200,7 +200,7 @@ To use the [group-level](#use-the-gitlab-endpoint-for-nuget-packages) NuGet endp
|
|||
|
||||
![Visual Studio Adding a NuGet source](img/visual_studio_adding_nuget_source.png)
|
||||
|
||||
1. Click **Save**.
|
||||
1. Select **Save**.
|
||||
|
||||
The source is displayed in your list.
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ To delete a package in the UI, from your group or project:
|
|||
|
||||
1. Go to **Packages & Registries > Package Registry**.
|
||||
1. Find the name of the package you want to delete.
|
||||
1. Click **Delete**.
|
||||
1. Select **Delete**.
|
||||
|
||||
The package is permanently deleted.
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ Search history is available for issues and merge requests, and is stored locally
|
|||
in your browser. To run a search from history:
|
||||
|
||||
1. In the top menu, select **Issues** or **Merge requests**.
|
||||
1. To the left of the search bar, click **Recent searches**, and select a search from the list.
|
||||
1. To the left of the search bar, select **Recent searches**, and select a search from the list.
|
||||
|
||||
## Removing search filters
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ sent within five minutes, with a link for users to re-confirm the subject email
|
|||
|
||||
## Do the confirmation emails expire?
|
||||
|
||||
The links in these re-confirmation emails expire after one day by default. Users who click an expired link are asked to request a new re-confirmation email. Any user can request a new re-confirmation email from `http://gitlab.example.com/users/confirmation/new`.
|
||||
The links in these re-confirmation emails expire after one day by default. Users who select an expired link are asked to request a new re-confirmation email. Any user can request a new re-confirmation email from `http://gitlab.example.com/users/confirmation/new`.
|
||||
|
||||
## Generate a list of affected users
|
||||
|
||||
|
|
|
@ -481,6 +481,11 @@ module Gitlab
|
|||
"can contain only lowercase letters, digits, '_' and '-'. " \
|
||||
"Must start with a letter, and cannot end with '-' or '_'"
|
||||
end
|
||||
|
||||
# One or more `part`s, separated by separator
|
||||
def sep_by_1(separator, part)
|
||||
%r(#{part} (#{separator} #{part})*)x
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ module Sidebars
|
|||
::Sidebars::MenuItem.new(
|
||||
title: _('Contacts'),
|
||||
link: group_crm_contacts_path(context.group),
|
||||
active_routes: { path: 'groups/crm#contacts' },
|
||||
active_routes: { controller: 'groups/crm/contacts' },
|
||||
item_id: :crm_contacts
|
||||
)
|
||||
end
|
||||
|
@ -44,7 +44,7 @@ module Sidebars
|
|||
::Sidebars::MenuItem.new(
|
||||
title: _('Organizations'),
|
||||
link: group_crm_organizations_path(context.group),
|
||||
active_routes: { path: 'groups/crm#organizations' },
|
||||
active_routes: { controller: 'groups/crm/organizations' },
|
||||
item_id: :crm_organizations
|
||||
)
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ import Vue, { nextTick } from 'vue';
|
|||
import VueApollo from 'vue-apollo';
|
||||
import { GlTab, GlTabs, GlLink } from '@gitlab/ui';
|
||||
import { mount } from '@vue/test-utils';
|
||||
|
||||
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
|
||||
import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser';
|
||||
import stubChildren from 'helpers/stub_children';
|
||||
|
@ -19,14 +20,22 @@ import {
|
|||
LICENSE_COMPLIANCE_DESCRIPTION,
|
||||
LICENSE_COMPLIANCE_HELP_PATH,
|
||||
AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY,
|
||||
LICENSE_ULTIMATE,
|
||||
LICENSE_PREMIUM,
|
||||
LICENSE_FREE,
|
||||
} from '~/security_configuration/components/constants';
|
||||
import FeatureCard from '~/security_configuration/components/feature_card.vue';
|
||||
import TrainingProviderList from '~/security_configuration/components/training_provider_list.vue';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import currentLicenseQuery from '~/security_configuration/graphql/current_license.query.graphql';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
|
||||
import UpgradeBanner from '~/security_configuration/components/upgrade_banner.vue';
|
||||
import {
|
||||
REPORT_TYPE_LICENSE_COMPLIANCE,
|
||||
REPORT_TYPE_SAST,
|
||||
} from '~/vue_shared/security_reports/constants';
|
||||
import { getCurrentLicensePlanResponse } from '../mock_data';
|
||||
|
||||
const upgradePath = '/upgrade';
|
||||
const autoDevopsHelpPagePath = '/autoDevopsHelpPagePath';
|
||||
|
@ -41,40 +50,31 @@ Vue.use(VueApollo);
|
|||
describe('App component', () => {
|
||||
let wrapper;
|
||||
let userCalloutDismissSpy;
|
||||
let mockApollo;
|
||||
|
||||
const securityFeaturesMock = [
|
||||
{
|
||||
name: SAST_NAME,
|
||||
shortName: SAST_SHORT_NAME,
|
||||
description: SAST_DESCRIPTION,
|
||||
helpPath: SAST_HELP_PATH,
|
||||
configurationHelpPath: SAST_CONFIG_HELP_PATH,
|
||||
type: REPORT_TYPE_SAST,
|
||||
available: true,
|
||||
},
|
||||
];
|
||||
|
||||
const complianceFeaturesMock = [
|
||||
{
|
||||
name: LICENSE_COMPLIANCE_NAME,
|
||||
description: LICENSE_COMPLIANCE_DESCRIPTION,
|
||||
helpPath: LICENSE_COMPLIANCE_HELP_PATH,
|
||||
type: REPORT_TYPE_LICENSE_COMPLIANCE,
|
||||
configurationHelpPath: LICENSE_COMPLIANCE_HELP_PATH,
|
||||
},
|
||||
];
|
||||
|
||||
const createComponent = ({ shouldShowCallout = true, ...propsData } = {}) => {
|
||||
const createComponent = ({
|
||||
shouldShowCallout = true,
|
||||
licenseQueryResponse = LICENSE_ULTIMATE,
|
||||
...propsData
|
||||
}) => {
|
||||
userCalloutDismissSpy = jest.fn();
|
||||
|
||||
mockApollo = createMockApollo([
|
||||
[
|
||||
currentLicenseQuery,
|
||||
jest
|
||||
.fn()
|
||||
.mockResolvedValue(
|
||||
licenseQueryResponse instanceof Error
|
||||
? licenseQueryResponse
|
||||
: getCurrentLicensePlanResponse(licenseQueryResponse),
|
||||
),
|
||||
],
|
||||
]);
|
||||
|
||||
wrapper = extendedWrapper(
|
||||
mount(SecurityConfigurationApp, {
|
||||
propsData: {
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
securityTrainingEnabled: true,
|
||||
...propsData,
|
||||
},
|
||||
propsData,
|
||||
provide: {
|
||||
upgradePath,
|
||||
autoDevopsHelpPagePath,
|
||||
|
@ -82,6 +82,7 @@ describe('App component', () => {
|
|||
projectFullPath,
|
||||
vulnerabilityTrainingDocsPath,
|
||||
},
|
||||
apolloProvider: mockApollo,
|
||||
stubs: {
|
||||
...stubChildren(SecurityConfigurationApp),
|
||||
GlLink: false,
|
||||
|
@ -132,13 +133,40 @@ describe('App component', () => {
|
|||
const findAutoDevopsEnabledAlert = () => wrapper.findComponent(AutoDevopsEnabledAlert);
|
||||
const findVulnerabilityManagementTab = () => wrapper.findByTestId('vulnerability-management-tab');
|
||||
|
||||
const securityFeaturesMock = [
|
||||
{
|
||||
name: SAST_NAME,
|
||||
shortName: SAST_SHORT_NAME,
|
||||
description: SAST_DESCRIPTION,
|
||||
helpPath: SAST_HELP_PATH,
|
||||
configurationHelpPath: SAST_CONFIG_HELP_PATH,
|
||||
type: REPORT_TYPE_SAST,
|
||||
available: true,
|
||||
},
|
||||
];
|
||||
|
||||
const complianceFeaturesMock = [
|
||||
{
|
||||
name: LICENSE_COMPLIANCE_NAME,
|
||||
description: LICENSE_COMPLIANCE_DESCRIPTION,
|
||||
helpPath: LICENSE_COMPLIANCE_HELP_PATH,
|
||||
type: REPORT_TYPE_LICENSE_COMPLIANCE,
|
||||
configurationHelpPath: LICENSE_COMPLIANCE_HELP_PATH,
|
||||
},
|
||||
];
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
mockApollo = null;
|
||||
});
|
||||
|
||||
describe('basic structure', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
beforeEach(async () => {
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
});
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('renders main-heading with correct text', () => {
|
||||
|
@ -198,7 +226,10 @@ describe('App component', () => {
|
|||
|
||||
describe('Manage via MR Error Alert', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
});
|
||||
});
|
||||
|
||||
describe('on initial load', () => {
|
||||
|
@ -234,6 +265,8 @@ describe('App component', () => {
|
|||
describe('given the right props', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
autoDevopsEnabled: false,
|
||||
gitlabCiPresent: false,
|
||||
canEnableAutoDevops: true,
|
||||
|
@ -255,7 +288,10 @@ describe('App component', () => {
|
|||
|
||||
describe('given the wrong props', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
});
|
||||
});
|
||||
it('should not show AutoDevopsAlert', () => {
|
||||
expect(findAutoDevopsAlert().exists()).toBe(false);
|
||||
|
@ -279,7 +315,11 @@ describe('App component', () => {
|
|||
);
|
||||
}
|
||||
|
||||
createComponent({ autoDevopsEnabled });
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
autoDevopsEnabled,
|
||||
});
|
||||
});
|
||||
|
||||
it(shouldRender ? 'renders' : 'does not render', () => {
|
||||
|
@ -305,7 +345,12 @@ describe('App component', () => {
|
|||
);
|
||||
}
|
||||
|
||||
createComponent({ autoDevopsEnabled: true });
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
autoDevopsEnabled: true,
|
||||
});
|
||||
|
||||
findAutoDevopsEnabledAlert().vm.$emit('dismiss');
|
||||
});
|
||||
|
||||
|
@ -330,6 +375,7 @@ describe('App component', () => {
|
|||
describe('given at least one unavailable feature', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock.map(makeAvailable(false)),
|
||||
});
|
||||
});
|
||||
|
@ -350,6 +396,7 @@ describe('App component', () => {
|
|||
describe('given at least one unavailable feature, but banner is already dismissed', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock.map(makeAvailable(false)),
|
||||
shouldShowCallout: false,
|
||||
});
|
||||
|
@ -376,7 +423,11 @@ describe('App component', () => {
|
|||
|
||||
describe('when given latestPipelinePath props', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ latestPipelinePath: 'test/path' });
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
latestPipelinePath: 'test/path',
|
||||
});
|
||||
});
|
||||
|
||||
it('should show latest pipeline info on the security tab with correct link when latestPipelinePath is defined', () => {
|
||||
|
@ -401,6 +452,8 @@ describe('App component', () => {
|
|||
describe('given gitlabCiPresent & gitlabCiHistoryPath props', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
gitlabCiPresent: true,
|
||||
gitlabCiHistoryPath,
|
||||
});
|
||||
|
@ -415,20 +468,13 @@ describe('App component', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('Vulnerability management tab', () => {
|
||||
it('does not show tab if security training is disabled', () => {
|
||||
createComponent({ securityTrainingEnabled: false });
|
||||
|
||||
expect(findVulnerabilityManagementTab().exists()).toBe(false);
|
||||
describe('Vulnerability management', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
});
|
||||
|
||||
describe('security training enabled', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('shows the tab if security training is enabled', () => {
|
||||
expect(findVulnerabilityManagementTab().exists()).toBe(true);
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('renders TrainingProviderList component', () => {
|
||||
|
@ -445,6 +491,25 @@ describe('App component', () => {
|
|||
expect(trainingLink.text()).toBe('Learn more about vulnerability training');
|
||||
expect(trainingLink.attributes('href')).toBe(vulnerabilityTrainingDocsPath);
|
||||
});
|
||||
});
|
||||
|
||||
it.each`
|
||||
licenseQueryResponse | display
|
||||
${LICENSE_ULTIMATE} | ${true}
|
||||
${LICENSE_PREMIUM} | ${false}
|
||||
${LICENSE_FREE} | ${false}
|
||||
${null} | ${true}
|
||||
${new Error()} | ${true}
|
||||
`(
|
||||
'displays $display for license $licenseQueryResponse',
|
||||
async ({ licenseQueryResponse, display }) => {
|
||||
createComponent({
|
||||
licenseQueryResponse,
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
});
|
||||
await waitForPromises();
|
||||
expect(findVulnerabilityManagementTab().exists()).toBe(display);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -111,3 +111,12 @@ export const tempProviderLogos = {
|
|||
svg: `<svg>${[testProviderName[1]]}</svg>`,
|
||||
},
|
||||
};
|
||||
|
||||
export const getCurrentLicensePlanResponse = (plan) => ({
|
||||
data: {
|
||||
currentLicense: {
|
||||
id: 'gid://gitlab/License/1',
|
||||
plan,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -21,8 +21,8 @@ describe('MR widget extension registering', () => {
|
|||
expect.objectContaining({
|
||||
extends: ExtensionBase,
|
||||
name: 'Test',
|
||||
props: ['helloWorld'],
|
||||
computed: {
|
||||
helloWorld: expect.any(Function),
|
||||
test: expect.any(Function),
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -8323,14 +8323,6 @@ RSpec.describe Project, factory_default: :keep do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#security_training_available?' do
|
||||
subject { build(:project) }
|
||||
|
||||
it 'returns false' do
|
||||
expect(subject.security_training_available?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def finish_job(export_job)
|
||||
|
|
|
@ -122,7 +122,7 @@ RSpec.describe QuickActions::InterpretService do
|
|||
inprogress # populate the label
|
||||
_, updates, _ = service.execute(content, issuable)
|
||||
|
||||
expect(updates).to eq(add_label_ids: [bug.id, inprogress.id])
|
||||
expect(updates).to match(add_label_ids: contain_exactly(bug.id, inprogress.id))
|
||||
end
|
||||
|
||||
it 'returns the label message' do
|
||||
|
@ -130,7 +130,10 @@ RSpec.describe QuickActions::InterpretService do
|
|||
inprogress # populate the label
|
||||
_, _, message = service.execute(content, issuable)
|
||||
|
||||
expect(message).to eq("Added #{bug.to_reference(format: :name)} #{inprogress.to_reference(format: :name)} labels.")
|
||||
# Compare message without making assumptions about ordering.
|
||||
expect(message).to match %r{Added ~".*" ~".*" labels.}
|
||||
expect(message).to include(bug.to_reference(format: :name))
|
||||
expect(message).to include(inprogress.to_reference(format: :name))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1196,6 +1199,64 @@ RSpec.describe QuickActions::InterpretService do
|
|||
let(:issuable) { merge_request }
|
||||
end
|
||||
|
||||
context 'with a colon label' do
|
||||
let(:bug) { create(:label, project: project, title: 'Category:Bug') }
|
||||
let(:inprogress) { create(:label, project: project, title: 'status:in:progress') }
|
||||
|
||||
context 'when quoted' do
|
||||
let(:content) { %(/label ~"#{inprogress.title}" ~"#{bug.title}" ~unknown) }
|
||||
|
||||
it_behaves_like 'label command' do
|
||||
let(:issuable) { merge_request }
|
||||
end
|
||||
|
||||
it_behaves_like 'label command' do
|
||||
let(:issuable) { issue }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when unquoted' do
|
||||
let(:content) { %(/label ~#{inprogress.title} ~#{bug.title} ~unknown) }
|
||||
|
||||
it_behaves_like 'label command' do
|
||||
let(:issuable) { merge_request }
|
||||
end
|
||||
|
||||
it_behaves_like 'label command' do
|
||||
let(:issuable) { issue }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a scoped label' do
|
||||
let(:bug) { create(:label, :scoped, project: project) }
|
||||
let(:inprogress) { create(:label, project: project, title: 'three::part::label') }
|
||||
|
||||
context 'when quoted' do
|
||||
let(:content) { %(/label ~"#{inprogress.title}" ~"#{bug.title}" ~unknown) }
|
||||
|
||||
it_behaves_like 'label command' do
|
||||
let(:issuable) { merge_request }
|
||||
end
|
||||
|
||||
it_behaves_like 'label command' do
|
||||
let(:issuable) { issue }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when unquoted' do
|
||||
let(:content) { %(/label ~#{inprogress.title} ~#{bug.title} ~unknown) }
|
||||
|
||||
it_behaves_like 'label command' do
|
||||
let(:issuable) { merge_request }
|
||||
end
|
||||
|
||||
it_behaves_like 'label command' do
|
||||
let(:issuable) { issue }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'multiple label command' do
|
||||
let(:content) { %(/label ~"#{inprogress.title}" \n/label ~#{bug.title}) }
|
||||
let(:issuable) { issue }
|
||||
|
|
Loading…
Reference in New Issue