Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-06-08 00:10:34 +00:00
parent c98df6ecba
commit 6aead03bb3
31 changed files with 399 additions and 94 deletions

View File

@ -151,6 +151,9 @@
- "vendor/assets/**/*"
- "{,ee/,jh/}{app/assets,app/helpers,app/presenters,app/views,locale,public,symbol}/**/*"
.startup-css-patterns: &startup-css-patterns
- "{,ee/,jh/}app/assets/stylesheets/startup/**/*"
.backend-patterns: &backend-patterns
- "Gemfile{,.lock}"
- "Rakefile"
@ -440,6 +443,8 @@
changes: *code-backstage-patterns
- <<: *if-merge-request-title-as-if-foss
- <<: *if-merge-request-title-run-all-rspec
- <<: *if-merge-request
changes: *startup-css-patterns
- <<: *if-merge-request
changes: *ci-patterns
@ -1126,6 +1131,7 @@
changes: *ci-review-patterns
- <<: *if-dot-com-gitlab-org-merge-request
changes: *frontend-patterns
allow_failure: true
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-qa-patterns

View File

@ -1,13 +1,16 @@
<script>
import { GlButton, GlButtonGroup, GlTooltipDirective } from '@gitlab/ui';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { __ } from '~/locale';
import { __, s__ } from '~/locale';
import deleteRunnerMutation from '~/runner/graphql/delete_runner.mutation.graphql';
import updateRunnerMutation from '~/runner/graphql/update_runner.mutation.graphql';
const i18n = {
I18N_EDIT: __('Edit'),
I18N_PAUSE: __('Pause'),
I18N_RESUME: __('Resume'),
I18N_REMOVE: __('Remove'),
I18N_REMOVE_CONFIRMATION: s__('Runners|Are you sure you want to delete this runner?'),
};
export default {
@ -27,6 +30,7 @@ export default {
data() {
return {
updating: false,
deleting: false,
};
},
computed: {
@ -46,12 +50,16 @@ export default {
toggleActiveTitle() {
if (this.updating) {
// Prevent a "sticky" tooltip: If this button is disabled,
// mouseout listeners will not run and the tooltip will
// stay stuck on the button.
// mouseout listeners don't run leaving the tooltip stuck
return '';
}
return this.isActive ? i18n.I18N_PAUSE : i18n.I18N_RESUME;
},
deleteTitle() {
// Prevent a "sticky" tooltip: If element gets removed,
// mouseout listeners don't run and leaving the tooltip stuck
return this.deleting ? '' : i18n.I18N_REMOVE;
},
},
methods: {
async onToggleActive() {
@ -87,6 +95,39 @@ export default {
}
},
async onDelete() {
// TODO Replace confirmation with gl-modal
// eslint-disable-next-line no-alert
if (!window.confirm(i18n.I18N_REMOVE_CONFIRMATION)) {
return;
}
this.deleting = true;
try {
const {
data: {
runnerDelete: { errors },
},
} = await this.$apollo.mutate({
mutation: deleteRunnerMutation,
variables: {
input: {
id: this.runner.id,
},
},
awaitRefetchQueries: true,
refetchQueries: ['getRunners'],
});
if (errors && errors.length) {
this.onError(new Error(errors[0]));
}
} catch (e) {
this.onError(e);
} finally {
this.deleting = false;
}
},
onError(error) {
// TODO Render errors when "delete" action is done
// `active` toggle would not fail due to user input.
@ -116,6 +157,15 @@ export default {
data-testid="toggle-active-runner"
@click="onToggleActive"
/>
<!-- TODO add delete action to update runners -->
<gl-button
v-gl-tooltip.hover.viewport
:title="deleteTitle"
:aria-label="deleteTitle"
icon="close"
:loading="deleting"
variant="danger"
data-testid="delete-runner"
@click="onDelete"
/>
</gl-button-group>
</template>

View File

@ -0,0 +1,5 @@
mutation runnerDelete($input: RunnerDeleteInput!) {
runnerDelete(input: $input) {
errors
}
}

View File

@ -24,7 +24,7 @@ module Nav
if explore_nav_link?(:projects)
builder.add_primary_menu_item_with_shortcut(
href: explore_root_path,
active: active_nav_link?(path: %w[dashboard#show root#show projects#trending projects#starred projects#index]),
active: nav == 'project' || active_nav_link?(path: %w[dashboard#show root#show projects#trending projects#starred projects#index]),
**projects_menu_item_attrs
)
end
@ -32,7 +32,7 @@ module Nav
if explore_nav_link?(:groups)
builder.add_primary_menu_item_with_shortcut(
href: explore_groups_path,
active: active_nav_link?(controller: [:groups, 'groups/milestones', 'groups/group_members']),
active: nav == 'group' || active_nav_link?(controller: [:groups, 'groups/milestones', 'groups/group_members']),
**groups_menu_item_attrs
)
end
@ -59,7 +59,7 @@ module Nav
current_item = project ? current_project(project: project) : {}
builder.add_primary_menu_item_with_shortcut(
active: active_nav_link?(path: %w[root#index projects#trending projects#starred dashboard/projects#index]),
active: nav == 'project' || active_nav_link?(path: %w[root#index projects#trending projects#starred dashboard/projects#index]),
css_class: 'qa-projects-dropdown',
data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" },
view: PROJECTS_VIEW,
@ -73,7 +73,7 @@ module Nav
current_item = group ? current_group(group: group) : {}
builder.add_primary_menu_item_with_shortcut(
active: active_nav_link?(path: %w[dashboard/groups explore/groups]),
active: nav == 'group' || active_nav_link?(path: %w[dashboard/groups explore/groups]),
css_class: 'qa-groups-dropdown',
data: { track_label: "groups_dropdown", track_event: "click_dropdown" },
view: GROUPS_VIEW,

View File

@ -595,6 +595,8 @@ module Ci
variables.concat(persisted_environment.predefined_variables)
variables.append(key: 'CI_ENVIRONMENT_ACTION', value: environment_action)
# Here we're passing unexpanded environment_url for runner to expand,
# and we need to make sure that CI_ENVIRONMENT_NAME and
# CI_ENVIRONMENT_SLUG so on are available for the URL be expanded.

View File

@ -27,7 +27,7 @@ class BaseCountService
end
def delete_cache
Rails.cache.delete(cache_key)
::Gitlab::Cache.delete(cache_key)
end
def raw?
@ -49,4 +49,4 @@ class BaseCountService
end
end
BaseCountService.prepend_mod_with('BaseCountService')
BaseCountService.prepend_mod

View File

@ -4,13 +4,15 @@
%div
- if @user.errors.any?
.gl-alert.gl-alert-danger.gl-my-5
%button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
= sprite_icon('close', css_class: 'gl-icon')
= sprite_icon('error', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
.gl-alert-body
%ul
- @user.errors.full_messages.each do |msg|
%li= msg
.gl-alert-container
%button.js-close.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon{ type: 'button', 'aria-label' => _('Dismiss') }
= sprite_icon('close', css_class: 'gl-icon')
= sprite_icon('error', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
.gl-alert-content
.gl-alert-body
%ul
- @user.errors.full_messages.each do |msg|
%li= msg
= hidden_field_tag :notification_type, 'global'
.row.gl-mt-3

View File

@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/325787
milestone: '13.11'
type: development
group: group::source code
default_enabled: false
default_enabled: true

View File

@ -192,6 +192,22 @@ This shows you which user has this email address. One of two steps must be taken
The user can do either of these steps [in their
profile](../../../user/profile/index.md#access-your-user-profile) or an administrator can do it.
#### Projects limit errors
The following errors indicate that a limit or restriction is activated, but an associated data
field contains no data:
- `Projects limit can't be blank`.
- `Projects limit is not a number`.
To resolve this:
1. Go to both of the following in the Admin Area (**{admin}**):
- **Settings > General > Account and limit**
- **Settings > General > Sign-up restrictions**.
1. Check, for example, the **Default projects limit** or **Allowed domains for sign-ups**
fields and ensure that a relevant value is configured.
#### Debug LDAP user filter
[`ldapsearch`](#ldapsearch) allows you to test your configured

View File

@ -34,10 +34,11 @@ exactly which repositories are causing the trouble.
- Receiving an error when trying to push code - `remote: error: cannot lock ref`
- A 500 error when viewing the GitLab dashboard or when accessing a specific project.
### Check all GitLab repositories
### Check project code repositories
This task loops through all repositories on the GitLab server and runs the
integrity check described previously.
This task loops through the project code repositories and runs the integrity check
described previously. If a project uses a pool repository, that will also be checked.
Other types of Git repositories [are not checked](https://gitlab.com/gitlab-org/gitaly/-/issues/3643).
**Omnibus Installation**

View File

@ -2083,7 +2083,8 @@ the format in `markdown` is used.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57250) in GitLab 13.11.
GitLab 13.11 added enforcement of the [maximum attachment size limit](../user/admin_area/settings/account_and_limit_settings.md#max-attachment-size) behind the `enforce_max_attachment_size_upload_api` feature flag. GitLab 14.0 will enable this by default.
GitLab 13.11 added enforcement of the [maximum attachment size limit](../user/admin_area/settings/account_and_limit_settings.md#max-attachment-size) behind the `enforce_max_attachment_size_upload_api` feature flag. GitLab 14.0 enables this by default.
To disable this enforcement:
**In Omnibus installations:**
@ -2093,10 +2094,10 @@ GitLab 13.11 added enforcement of the [maximum attachment size limit](../user/ad
sudo gitlab-rails console
```
1. Enable the feature flag:
1. Disable the feature flag:
```ruby
Feature.enable(:enforce_max_attachment_size_upload_api)
Feature.disable(:enforce_max_attachment_size_upload_api)
```
**In installations from source:**
@ -2108,10 +2109,10 @@ GitLab 13.11 added enforcement of the [maximum attachment size limit](../user/ad
sudo -u git -H bundle exec rails console -e production
```
1. Enable the feature flag to disable the validation:
1. Disable the feature flag:
```ruby
Feature.enable(:enforce_max_attachment_size_upload_api)
Feature.disable(:enforce_max_attachment_size_upload_api)
```
## Upload a project avatar

View File

@ -1,12 +1,13 @@
---
stage: Manage
group: Compilance
group: Compliance
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Resource label events API
# Resource label events API **(FREE)**
Resource label events keep track about who, when, and which label was added to, or removed from, an issuable.
Resource label events keep track about who, when, and which label was added to (or removed from)
an issue, merge request, or epic.
## Issues

View File

@ -52,6 +52,7 @@ There are also [Kubernetes-specific deployment variables](../../user/project/clu
| `CI_ENVIRONMENT_NAME` | 8.15 | all | The name of the environment for this job. Available if [`environment:name`](../yaml/README.md#environmentname) is set. |
| `CI_ENVIRONMENT_SLUG` | 8.15 | all | The simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, and so on. Available if [`environment:name`](../yaml/README.md#environmentname) is set. The slug is [truncated to 24 characters](https://gitlab.com/gitlab-org/gitlab/-/issues/20941). |
| `CI_ENVIRONMENT_URL` | 9.3 | all | The URL of the environment for this job. Available if [`environment:url`](../yaml/README.md#environmenturl) is set. |
| `CI_ENVIRONMENT_ACTION` | 13.11 | all | The action annotation specified for this job's environment. Available if [`environment:action`](../yaml/README.md#environmentaction) is set. Can be `start`, `prepare`, or `stop`. |
| `CI_HAS_OPEN_REQUIREMENTS` | 13.1 | all | Only available if the pipeline's project has an open [requirement](../../user/project/requirements/index.md). `true` when available. |
| `CI_JOB_ID` | 9.0 | all | The internal ID of the job, unique across all jobs in the GitLab instance. |
| `CI_JOB_IMAGE` | 12.9 | 12.9 | The name of the Docker image running the job. |

View File

@ -39,7 +39,15 @@ To remove the alert, click back on the alert icon for the desired metric, and cl
### Link runbooks to alerts
> Runbook URLs [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39315) in GitLab 13.3.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39315) in GitLab 13.3.
> - [Deprecated](https://gitlab.com/groups/gitlab-org/-/epics/5877) in GitLab 13.11.
> - [Removed](https://gitlab.com/groups/gitlab-org/-/epics/4280) in GitLab 14.0.
WARNING:
Linking runbooks to alerts through the alerts UI is [deprecated](https://gitlab.com/groups/gitlab-org/-/epics/5877)
and scheduled for [removal in GitLab 14.0](https://gitlab.com/groups/gitlab-org/-/epics/4280).
However, you can still add runbooks to your alert payload. They show up in the alert UI when the
alert is triggered.
When creating alerts from the metrics dashboard for [managed Prometheus instances](#managed-prometheus-instances),
you can also link a runbook. When the alert triggers, the

View File

@ -7,10 +7,19 @@ type: reference
# Password storage **(FREE)**
GitLab stores user passwords in a hashed format, to prevent passwords from being visible.
GitLab stores user passwords in a hashed format to prevent passwords from being
stored as plain text.
GitLab uses the [Devise](https://github.com/heartcombo/devise) authentication library, which handles the hashing of user passwords. Password hashes are created with the following attributes:
GitLab uses the [Devise](https://github.com/heartcombo/devise) authentication
library to hash user passwords. Created password hashes have these attributes:
- **Hashing**: the [`bcrypt`](https://en.wikipedia.org/wiki/Bcrypt) hashing function is used to generate the hash of the provided password. This is a strong, industry-standard cryptographic hashing function.
- **Stretching**: Password hashes are [stretched](https://en.wikipedia.org/wiki/Key_stretching) to harden against brute-force attacks. GitLab uses a stretching factor of 10 by default.
- **Salting**: A [cryptographic salt](https://en.wikipedia.org/wiki/Salt_(cryptography)) is added to each password to harden against pre-computed hash and dictionary attacks. Each salt is randomly generated for each password, so that no two passwords share a salt, to further increase security.
- **Hashing**: The [`bcrypt`](https://en.wikipedia.org/wiki/Bcrypt) hashing
function is used to generate the hash of the provided password. This is a
strong, industry-standard cryptographic hashing function.
- **Stretching**: Password hashes are [stretched](https://en.wikipedia.org/wiki/Key_stretching)
to harden against brute-force attacks. By default, GitLab uses a stretching
factor of 10.
- **Salting**: A [cryptographic salt](https://en.wikipedia.org/wiki/Salt_(cryptography))
is added to each password to harden against pre-computed hash and dictionary
attacks. To increase security, each salt is randomly generated for each
password, with no two passwords sharing a salt.

View File

@ -192,30 +192,32 @@ This feature is being re-evaluated in favor of a different
We recommend that users who haven't yet implemented this feature wait for
the new solution.
GitLab administrators can force a pipeline configuration to run on every
pipeline.
You can set a [CI/CD template](../../../ci/examples/README.md#cicd-templates)
as a required pipeline configuration for all projects on a GitLab instance. You can
use a template from:
The configuration applies to all pipelines for a GitLab instance and is
sourced from:
- The default CI/CD templates.
- A custom template stored in an [instance template repository](instance_template_repository.md).
- The [instance template repository](instance_template_repository.md).
- GitLab-supplied configuration.
NOTE:
When you use a configuration defined in an instance template repository,
nested [`include:`](../../../ci/yaml/README.md#include) keywords
(including `include:file`, `include:local`, `include:remote`, and `include:template`)
[do not work](https://gitlab.com/gitlab-org/gitlab/-/issues/35345).
NOTE:
When you use a configuration defined in an instance template repository,
nested [`include:`](../../../ci/yaml/README.md#include) keywords
(including `include:file`, `include:local`, `include:remote`, and `include:template`)
[do not work](https://gitlab.com/gitlab-org/gitlab/-/issues/35345).
The project CI/CD configuration merges into the required pipeline configuration when
a pipeline runs. The merged configuration is the same as if the required pipeline configuration
added the project configuration with the [`include` keyword](../../../ci/yaml/README.md#include).
To view a project's full merged configuration, [View the merged YAML](../../../ci/pipeline_editor/index.md#view-expanded-configuration)
in the pipeline editor.
To set required pipeline configuration:
To select a CI/CD template for the required pipeline configuration:
1. Go to **Admin Area > Settings > CI/CD**.
1. Expand the **Required pipeline configuration** section.
1. Select the required configuration from the provided dropdown.
1. Select a CI/CD template from the dropdown.
1. Click **Save changes**.
![Required pipeline](img/admin_required_pipeline.png)
## Package Registry configuration
### npm Forwarding **(PREMIUM SELF)**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,6 +1,6 @@
---
stage: secure
group: secure
stage: Secure
group: Static Analysis
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: reference, howto
---

View File

@ -68,7 +68,7 @@ The following table lists project permissions available for each role:
| View requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| View Issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| View Merge Request analytics **(STARTER)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| View Merge Request analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| View Value Stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
| Manage user-starred metrics dashboards (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ |
| View confidential issues | (*2*) | ✓ | ✓ | ✓ | ✓ |
@ -89,7 +89,7 @@ The following table lists project permissions available for each role:
| See [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
| See a list of merge requests | | ✓ | ✓ | ✓ | ✓ |
| View CI/CD analytics | | ✓ | ✓ | ✓ | ✓ |
| View Code Review analytics **(STARTER)** | | ✓ | ✓ | ✓ | ✓ |
| View Code Review analytics **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
| View Repository analytics | | ✓ | ✓ | ✓ | ✓ |
| View Error Tracking list | | ✓ | ✓ | ✓ | ✓ |
| View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |

View File

@ -61,7 +61,7 @@ module API
# Temporarily introduced for upload API: https://gitlab.com/gitlab-org/gitlab/-/issues/325788
def project_attachment_size(user_project)
return PROJECT_ATTACHMENT_SIZE_EXEMPT if exempt_from_global_attachment_size?(user_project)
return user_project.max_attachment_size if Feature.enabled?(:enforce_max_attachment_size_upload_api, user_project)
return user_project.max_attachment_size if Feature.enabled?(:enforce_max_attachment_size_upload_api, user_project, default_enabled: :yaml)
PROJECT_ATTACHMENT_SIZE_EXEMPT
end

View File

@ -13,6 +13,13 @@ module Gitlab
end
end
end
# Hook for EE
def delete(key)
Rails.cache.delete(key)
end
end
end
end
Gitlab::Cache.prepend_mod

View File

@ -2359,10 +2359,7 @@ msgstr ""
msgid "AdminSettings|See affected service templates"
msgstr ""
msgid "AdminSettings|Select a pipeline configuration file"
msgstr ""
msgid "AdminSettings|Select a template"
msgid "AdminSettings|Select a CI/CD template"
msgstr ""
msgid "AdminSettings|Service template allows you to set default values for integrations"
@ -2374,7 +2371,7 @@ msgstr ""
msgid "AdminSettings|Session duration for Git operations when 2FA is enabled (minutes)"
msgstr ""
msgid "AdminSettings|Set an instance-wide auto included %{link_start}pipeline configuration%{link_end}. This pipeline configuration will be run after the project's own configuration."
msgid "AdminSettings|Set a CI/CD template as the required pipeline configuration for all projects in the instance. Project CI/CD configuration merges into the required pipeline configuration when the pipeline runs. %{link_start}What is a required pipeline configuration?%{link_end}"
msgstr ""
msgid "AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages."
@ -2383,7 +2380,7 @@ msgstr ""
msgid "AdminSettings|The latest artifacts for all jobs in the most recent successful pipelines in each project are stored and do not expire."
msgstr ""
msgid "AdminSettings|The required pipeline configuration can be selected from the %{code_start}gitlab-ci%{code_end} directory inside of the configured %{link_start}instance template repository%{link_end} or from GitLab provided configurations."
msgid "AdminSettings|The template for the required pipeline configuration can be one of the GitLab-provided templates, or a custom template added to an instance template repository. %{link_start}How do I create an instance template repository?%{link_end}"
msgstr ""
msgid "AdminSettings|When creating a new environment variable it will be protected by default."
@ -28342,6 +28339,9 @@ msgstr ""
msgid "Runners|Architecture"
msgstr ""
msgid "Runners|Are you sure you want to delete this runner?"
msgstr ""
msgid "Runners|Can run untagged jobs"
msgstr ""

View File

@ -56,7 +56,7 @@
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "1.199.0",
"@gitlab/tributejs": "1.0.0",
"@gitlab/ui": "29.32.0",
"@gitlab/ui": "29.33.0",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "6.1.3-2",
"@rails/ujs": "6.1.3-2",

View File

@ -94,13 +94,13 @@ module QA
import_page.import_group(source_group.path, sandbox.path)
aggregate_failures do
expect(import_page).to have_imported_group(source_group.path, wait: 120)
expect(import_page).to have_imported_group(source_group.path, wait: 180)
expect { imported_group.reload! }.to eventually_eq(source_group).within(duration: 10)
expect { imported_subgroup.reload! }.to eventually_eq(subgroup).within(duration: 10)
expect { imported_subgroup.reload! }.to eventually_eq(subgroup).within(duration: 30)
expect { imported_group.labels }.to eventually_include(*source_group.labels).within(duration: 10)
expect { imported_subgroup.labels }.to eventually_include(*subgroup.labels).within(duration: 10)
expect { imported_subgroup.labels }.to eventually_include(*subgroup.labels).within(duration: 30)
end
end
end

View File

@ -109,6 +109,6 @@ describe('RemoveGroupLinkModal', () => {
it('modal does not show when `removeGroupLinkModalVisible` is `false`', () => {
createComponent({ removeGroupLinkModalVisible: false });
expect(findModal().vm.$attrs.visible).toBe(false);
expect(findModal().props().visible).toBe(false);
});
});

View File

@ -2,16 +2,21 @@ import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import RunnerActionCell from '~/runner/components/cells/runner_actions_cell.vue';
import deleteRunnerMutation from '~/runner/graphql/delete_runner.mutation.graphql';
import getRunnersQuery from '~/runner/graphql/get_runners.query.graphql';
import updateRunnerMutation from '~/runner/graphql/update_runner.mutation.graphql';
const mockId = '1';
const getRunnersQueryName = getRunnersQuery.definitions[0].name.value;
describe('RunnerTypeCell', () => {
let wrapper;
let mutate;
const findEditBtn = () => wrapper.findByTestId('edit-runner');
const findToggleActiveBtn = () => wrapper.findByTestId('toggle-active-runner');
const findDeleteBtn = () => wrapper.findByTestId('delete-runner');
const createComponent = ({ active = true } = {}, options) => {
wrapper = extendedWrapper(
@ -78,6 +83,11 @@ describe('RunnerTypeCell', () => {
await findToggleActiveBtn().vm.$emit('click');
expect(findToggleActiveBtn().props('loading')).toBe(true);
});
it(`After the ${icon} button is clicked, stale tooltip is removed`, async () => {
await findToggleActiveBtn().vm.$emit('click');
expect(findToggleActiveBtn().attributes('title')).toBe('');
expect(findToggleActiveBtn().attributes('aria-label')).toBe('');
});
@ -106,4 +116,86 @@ describe('RunnerTypeCell', () => {
});
});
});
describe('When the user clicks a runner', () => {
beforeEach(() => {
createComponent();
mutate.mockResolvedValue({
data: {
runnerDelete: {
runner: {
id: `gid://gitlab/Ci::Runner/1`,
__typename: 'CiRunner',
},
},
},
});
jest.spyOn(window, 'confirm');
});
describe('When the user confirms deletion', () => {
beforeEach(async () => {
window.confirm.mockReturnValue(true);
await findDeleteBtn().vm.$emit('click');
});
it('The user sees a confirmation alert', async () => {
expect(window.confirm).toHaveBeenCalledTimes(1);
expect(window.confirm).toHaveBeenCalledWith(expect.any(String));
});
it('The delete mutation is called correctly', () => {
expect(mutate).toHaveBeenCalledTimes(1);
expect(mutate).toHaveBeenCalledWith({
mutation: deleteRunnerMutation,
variables: {
input: {
id: `gid://gitlab/Ci::Runner/${mockId}`,
},
},
awaitRefetchQueries: true,
refetchQueries: [getRunnersQueryName],
});
});
it('The delete button does not have a loading state', () => {
expect(findDeleteBtn().props('loading')).toBe(false);
expect(findDeleteBtn().attributes('title')).toBe('Remove');
});
it('After the delete button is clicked, loading state is shown', async () => {
await findDeleteBtn().vm.$emit('click');
expect(findDeleteBtn().props('loading')).toBe(true);
});
it('After the delete button is clicked, stale tooltip is removed', async () => {
await findDeleteBtn().vm.$emit('click');
expect(findDeleteBtn().attributes('title')).toBe('');
});
});
describe('When the user does not confirm deletion', () => {
beforeEach(async () => {
window.confirm.mockReturnValue(false);
await findDeleteBtn().vm.$emit('click');
});
it('The user sees a confirmation alert', () => {
expect(window.confirm).toHaveBeenCalledTimes(1);
});
it('The delete mutation is not called', () => {
expect(mutate).toHaveBeenCalledTimes(0);
});
it('The delete button does not have a loading state', () => {
expect(findDeleteBtn().props('loading')).toBe(false);
expect(findDeleteBtn().attributes('title')).toBe('Remove');
});
});
});
});

View File

@ -106,6 +106,16 @@ RSpec.describe Nav::TopNavHelper do
]
expect(subject[:secondary]).to eq(expected_secondary)
end
context 'with current nav as project' do
before do
helper.nav('project')
end
it 'has expected :active' do
expect(subject[:primary].detect { |entry| entry[:id] == 'project' }[:active]).to eq(true)
end
end
end
context 'when current_user is non-admin' do
@ -190,6 +200,16 @@ RSpec.describe Nav::TopNavHelper do
expect(projects_view[:linksSecondary]).to eq(expected_links_secondary)
end
context 'with current nav as project' do
before do
helper.nav('project')
end
it 'has expected :active' do
expect(subject[:primary].detect { |entry| entry[:id] == 'project' }[:active]).to eq(true)
end
end
context 'with persisted project' do
let_it_be(:project) { build_stubbed(:project) }
@ -281,6 +301,16 @@ RSpec.describe Nav::TopNavHelper do
expect(groups_view[:linksSecondary]).to eq(expected_links_secondary)
end
context 'with current nav as group' do
before do
helper.nav('group')
end
it 'has expected :active' do
expect(subject[:primary].detect { |entry| entry[:id] == 'groups' }[:active]).to eq(true)
end
end
context 'with persisted group' do
let_it_be(:group) { build_stubbed(:group) }

View File

@ -26,4 +26,16 @@ RSpec.describe Gitlab::Cache, :request_store do
expect(subject.call).to eq("return value")
end
end
describe '.delete' do
let(:key) { %w{a cache key} }
subject(:delete) { described_class.delete(key) }
it 'calls Rails.cache.delete' do
expect(Rails.cache).to receive(:delete).with(key)
delete
end
end
end

View File

@ -2640,6 +2640,17 @@ RSpec.describe Ci::Build do
it { is_expected.to be_instance_of(Gitlab::Ci::Variables::Collection) }
it { expect(subject.to_runner_variables).to eq(predefined_variables) }
it 'excludes variables that require an environment or user' do
environment_based_variables_collection = subject.filter do |variable|
%w[
YAML_VARIABLE CI_ENVIRONMENT_NAME CI_ENVIRONMENT_SLUG
CI_ENVIRONMENT_ACTION CI_ENVIRONMENT_URL
].include?(variable[:key])
end
expect(environment_based_variables_collection).to be_empty
end
context 'when ci_job_jwt feature flag is disabled' do
before do
stub_feature_flags(ci_job_jwt: false)
@ -2709,7 +2720,7 @@ RSpec.describe Ci::Build do
let(:expected_variables) do
predefined_variables.map { |variable| variable.fetch(:key) } +
%w[YAML_VARIABLE CI_ENVIRONMENT_NAME CI_ENVIRONMENT_SLUG
CI_ENVIRONMENT_URL]
CI_ENVIRONMENT_ACTION CI_ENVIRONMENT_URL]
end
before do
@ -2727,6 +2738,50 @@ RSpec.describe Ci::Build do
expect(received_variables).to eq expected_variables
end
describe 'CI_ENVIRONMENT_ACTION' do
let(:enviroment_action_variable) { subject.find { |variable| variable[:key] == 'CI_ENVIRONMENT_ACTION' } }
shared_examples 'defaults value' do
it 'value matches start' do
expect(enviroment_action_variable[:value]).to eq('start')
end
end
it_behaves_like 'defaults value'
context 'when options is set' do
before do
build.update!(options: options)
end
context 'when options is empty' do
let(:options) { {} }
it_behaves_like 'defaults value'
end
context 'when options is nil' do
let(:options) { nil }
it_behaves_like 'defaults value'
end
context 'when options environment is specified' do
let(:options) { { environment: {} } }
it_behaves_like 'defaults value'
end
context 'when options environment action specified' do
let(:options) { { environment: { action: 'stop' } } }
it 'matches the specified action' do
expect(enviroment_action_variable[:value]).to eq('stop')
end
end
end
end
end
end
end

View File

@ -222,7 +222,7 @@ RSpec.describe Issues::CloseService do
it 'verifies the number of queries' do
recorded = ActiveRecord::QueryRecorder.new { close_issue }
expected_queries = 23
expected_queries = 24
expect(recorded.count).to be <= expected_queries
expect(recorded.cached_count).to eq(0)

View File

@ -908,16 +908,16 @@
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
"@gitlab/ui@29.32.0":
version "29.32.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.32.0.tgz#efcb078f68c65991ab33f43cdf21984467c012d6"
integrity sha512-epWZSbopeDjrkbF+obWk7nUx7HMfK8VKBk36xMV46fWmJVJSwhvg3kX9MzPlburaEURMNS1ucxCvH5bnGef6og==
"@gitlab/ui@29.33.0":
version "29.33.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.33.0.tgz#2fb06dfe95f86dff6840bcb097ab1a2fd640a0ce"
integrity sha512-WhmJu3vaacBzIPOtKS0uD8htp8L6gjKXfqgWedu/Ukncs02OvlhAGy9CC4SHSTMhjYSMkQIGHrFvBPIW2DPEOg==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0"
bootstrap-vue "2.17.3"
bootstrap-vue "2.18.1"
copy-to-clipboard "^3.0.8"
dompurify "^2.2.8"
dompurify "^2.2.9"
echarts "^4.9.0"
highlight.js "^10.6.0"
js-beautify "^1.8.8"
@ -1157,14 +1157,14 @@
dependencies:
mkdirp "^1.0.4"
"@nuxt/opencollective@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@nuxt/opencollective/-/opencollective-0.3.0.tgz#11d8944dcf2d526e31660bb69570be03f8fb72b7"
integrity sha512-Vf09BxCdj1iT2IRqVwX5snaY2WCTkvM0O4cWWSO1ThCFuc4if0Q/nNwAgCxRU0FeYHJ7DdyMUNSdswCLKlVqeg==
"@nuxt/opencollective@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@nuxt/opencollective/-/opencollective-0.3.2.tgz#83cb70cdb2bac5fad6f8c93529e7b11187d49c02"
integrity sha512-XG7rUdXG9fcafu9KTDIYjJSkRO38EwjlKYIb5TQ/0WDbiTUTtUtgncMscKOYzfsY86kGs05pAuMOR+3Fi0aN3A==
dependencies:
chalk "^2.4.2"
consola "^2.10.1"
node-fetch "^2.6.0"
chalk "^4.1.0"
consola "^2.15.0"
node-fetch "^2.6.1"
"@polka/url@^1.0.0-next.9":
version "1.0.0-next.12"
@ -2746,22 +2746,27 @@ boolbase@^1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
bootstrap-vue@2.17.3:
version "2.17.3"
resolved "https://registry.yarnpkg.com/bootstrap-vue/-/bootstrap-vue-2.17.3.tgz#3d78b7b4ff992a8ad69d2ed1c7413fcfdcefaec7"
integrity sha512-upX5LktvsecbBsLnjwaSQoDCsYfneToOweOaERt+Cc/cT6P44zODzpxZa54HZEAbE5gSE5mJmDacUrs02qAR8g==
bootstrap-vue@2.18.1:
version "2.18.1"
resolved "https://registry.yarnpkg.com/bootstrap-vue/-/bootstrap-vue-2.18.1.tgz#4378d26b713d4255b45b42b3f852f6fa0a11d400"
integrity sha512-oYKAhEnNuCxtF4gxsdLzijhQpFk7UYPvzhwZvUbnPbZ1eWu2dsc3+fRkY9PMowt5OJRtuVb7ov3lpsI2fraYsA==
dependencies:
"@nuxt/opencollective" "^0.3.0"
bootstrap ">=4.5.2 <5.0.0"
"@nuxt/opencollective" "^0.3.2"
bootstrap ">=4.5.3 <5.0.0"
popper.js "^1.16.1"
portal-vue "^2.1.7"
vue-functional-data-merge "^3.1.0"
bootstrap@4.5.3, "bootstrap@>=4.5.2 <5.0.0":
bootstrap@4.5.3:
version "4.5.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6"
integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ==
"bootstrap@>=4.5.3 <5.0.0":
version "4.6.0"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7"
integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==
boxen@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64"
@ -3518,10 +3523,10 @@ connect@^3.6.0:
parseurl "~1.3.2"
utils-merge "1.0.1"
consola@^2.10.1:
version "2.10.1"
resolved "https://registry.yarnpkg.com/consola/-/consola-2.10.1.tgz#4693edba714677c878d520e4c7e4f69306b4b927"
integrity sha512-4sxpH6SGFYLADfUip4vuY65f/gEogrzJoniVhNUYkJHtng0l8ZjnDCqxxrSVRHOHwKxsy8Vm5ONZh1wOR3/l/w==
consola@^2.15.0:
version "2.15.3"
resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550"
integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==
console-browserify@^1.1.0:
version "1.1.0"
@ -4523,7 +4528,7 @@ domhandler@^4.0.0, domhandler@^4.2.0:
dependencies:
domelementtype "^2.2.0"
dompurify@^2.2.8, dompurify@^2.2.9:
dompurify@^2.2.9:
version "2.2.9"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.9.tgz#4b42e244238032d9286a0d2c87b51313581d9624"
integrity sha512-+9MqacuigMIZ+1+EwoEltogyWGFTJZWU3258Rupxs+2CGs4H914G9er6pZbsme/bvb5L67o2rade9n21e4RW/w==
@ -8686,7 +8691,7 @@ node-ensure@^0.0.0:
resolved "https://registry.yarnpkg.com/node-ensure/-/node-ensure-0.0.0.tgz#ecae764150de99861ec5c810fd5d096b183932a7"
integrity sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc=
node-fetch@^2.6.0:
node-fetch@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==