Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-10-25 03:11:08 +00:00
parent 7162e84914
commit 01fbd09ea9
28 changed files with 395 additions and 375 deletions

View File

@ -113,11 +113,11 @@ review-deploy:
- echo "QA_GITLAB_URL=${CI_ENVIRONMENT_URL}" > environment.env
- *base-before_script
script:
- check_kube_domain
- download_chart
- deploy || (display_deployment_debug && exit 1)
- verify_deploy || exit 1
- disable_sign_ups || (delete_release && exit 1)
- run_timed_command "check_kube_domain"
- run_timed_command "download_chart"
- run_timed_command "deploy" || (display_deployment_debug && exit 1)
- run_timed_command "verify_deploy" || exit 1
- run_timed_command "disable_sign_ups" || (delete_release && exit 1)
after_script:
# Run seed-dast-test-data.sh only when DAST_RUN is set to true. This is to pupulate review app with data for DAST scan.
# Set DAST_RUN to true when jobs are manually scheduled.

View File

@ -18,7 +18,7 @@
# Tracking Details
- [json schema](https://gitlab.com/gitlab-org/iglu/-/blob/master/public/schemas/com.gitlab/gitlab_experiment/jsonschema/0-3-0) used in `gitlab-experiment` tracking.
- see [taxonomy](https://docs.gitlab.com/ee/development/snowplow/index.html#structured-event-taxonomy) for a guide.
- see [event schema](https://docs.gitlab.com/ee/development/snowplow/index.html#event-schema) for a guide.
| sequence | activity | category | action | label | property | value |
| -------- | -------- | ------ | ----- | ------- | -------- | ----- |

View File

@ -20,7 +20,12 @@ const MERGEREQUESTS_ALIAS = 'mergerequests';
const LABELS_ALIAS = 'labels';
const SNIPPETS_ALIAS = 'snippets';
const CONTACTS_ALIAS = 'contacts';
export const AT_WHO_ACTIVE_CLASS = 'at-who-active';
export const CONTACT_STATE_ACTIVE = 'active';
export const CONTACTS_ADD_COMMAND = '/add_contacts';
export const CONTACTS_REMOVE_COMMAND = '/remove_contacts';
/**
* Escapes user input before we pass it to at.js, which
* renders it as HTML in the autocomplete dropdown.
@ -666,6 +671,9 @@ class GfmAutoComplete {
}
setupContacts($input) {
const fetchData = this.fetchData.bind(this);
let command = '';
$input.atwho({
at: '[contact:',
suffix: ']',
@ -694,9 +702,44 @@ class GfmAutoComplete {
firstName: m.first_name,
lastName: m.last_name,
search: `${m.email}`,
state: m.state,
set: m.set,
};
});
},
matcher(flag, subtext) {
const subtextNodes = subtext.split(/\n+/g).pop().split(GfmAutoComplete.regexSubtext);
command = subtextNodes.find((node) => {
if (node === CONTACTS_ADD_COMMAND || node === CONTACTS_REMOVE_COMMAND) {
return node;
}
return null;
});
const match = GfmAutoComplete.defaultMatcher(flag, subtext, this.app.controllers);
return match?.length ? match[1] : null;
},
filter(query, data, searchKey) {
if (GfmAutoComplete.isLoading(data)) {
fetchData(this.$inputor, this.at);
return data;
}
if (data === GfmAutoComplete.defaultLoadingData) {
return $.fn.atwho.default.callbacks.filter(query, data, searchKey);
}
if (command === CONTACTS_ADD_COMMAND) {
// Return contacts that are active and not already on the issue
return data.filter((contact) => contact.state === CONTACT_STATE_ACTIVE && !contact.set);
} else if (command === CONTACTS_REMOVE_COMMAND) {
// Return contacts already on the issue
return data.filter((contact) => contact.set);
}
return data;
},
},
});
showAndHideHelper($input, CONTACTS_ALIAS);

View File

@ -39,8 +39,8 @@ export const Tracker = {
},
/**
* Dispatches a structured event per our taxonomy:
* https://docs.gitlab.com/ee/development/snowplow/index.html#structured-event-taxonomy.
* Dispatches a structured event:
* https://docs.gitlab.com/ee/development/snowplow/index.html#event-schema.
*
* If the library is not initialized and events are trying to be
* dispatched (data-attributes, load-events), they will be added
@ -49,7 +49,7 @@ export const Tracker = {
* If there is an error when using the library, it will return ´false´
* and ´true´ otherwise.
*
* @param {...any} eventData defined event taxonomy
* @param {...any} eventData defined event schema
* @returns {Boolean}
*/
event(...eventData) {

View File

@ -0,0 +1,23 @@
---
key_path: deactivate_dormant_users_enabled
description: Whether Dormant User Deactivation is enabled
product_section: fulfillment
product_stage: fulfillment
product_group: utilization
product_category: subscription_cost_management
value_type: boolean
status: active
milestone: "15.6"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/101125
time_frame: none
data_source: database
data_category: optional
instrumentation_class: DormantUserSettingEnabledMetric
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,23 @@
---
key_path: deactivate_dormant_users_period
description: The value of the dormant users period being used
product_section: fulfillment
product_stage: fulfillment
product_group: utilization
product_category: subscription_cost_management
value_type: boolean
status: active
milestone: "15.6"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/101125
time_frame: none
data_source: database
data_category: optional
instrumentation_class: DormantUserPeriodSettingMetric
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -1,29 +1,8 @@
# frozen_string_literal: true
class BackfillProjectsWithCoverage < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
MIGRATION = 'BackfillProjectsWithCoverage'
DELAY_INTERVAL = 2.minutes
BATCH_SIZE = 10_000
SUB_BATCH_SIZE = 1_000
disable_ddl_transaction!
class CiDailyBuildGroupReportResult < ActiveRecord::Base
include EachBatch
self.table_name = 'ci_daily_build_group_report_results'
end
def up
queue_background_migration_jobs_by_range_at_intervals(
CiDailyBuildGroupReportResult,
MIGRATION,
DELAY_INTERVAL,
batch_size: BATCH_SIZE,
other_job_arguments: [SUB_BATCH_SIZE]
)
# noop
end
def down

View File

@ -228,53 +228,6 @@ averaged.
To add test coverage results to a merge request using the project's `.gitlab-ci.yml` file, provide a regular expression
using the [`coverage`](../yaml/index.md#coverage) keyword.
<!-- start_remove The following content will be removed on remove_date: '2023-08-22' -->
### Add test coverage results using project settings (removed)
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 14.8. Replaced by [`coverage` keyword](../yaml/index.md#coverage).
> - [Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 15.0.
This feature is in its end-of-life process. It was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/17633)
in GitLab 14.8. The feature is [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 15.0.
To migrate from a project setting to the `coverage` keyword, add the [former project setting](#locate-former-project-setting)
to a CI/CD job. For example:
- A Go test coverage project setting: `coverage: \d+.\d+% of statements`.
- A CI/CD job with `coverage` keyword setting:
```yaml
unit-test:
stage: test
coverage: '/coverage: \d+.\d+% of statements/'
script:
- go test -cover
```
The `.gitlab-ci.yml` job [`coverage`](../yaml/index.md#coverage) keyword must be:
- A regular expression starts and ends with the `/` character.
- Defined as single-quoted string.
You can verify correct syntax using the [pipeline editor](../pipeline_editor/index.md).
#### Locate former project setting
To migrate from the project coverage setting to the `coverage` keyword, use the
regular expression displayed in the settings. Available in GitLab 14.10 and earlier:
1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **General pipelines**.
The regular expression you need is in the **Test coverage parsing** field.
If you need to retrieve the project coverage setting from many projects, you can
[use the API to programmatically retrieve the setting](https://gitlab.com/gitlab-org/gitlab/-/issues/17633#note_945941397).
<!-- end_remove -->
### Test coverage examples
Use this regex for commonly used test tools.

View File

@ -13,6 +13,9 @@ Cloud Seed is an open-source program led
by [GitLab Incubation Engineering](https://about.gitlab.com/handbook/engineering/incubation/) in collaboration with
[Google Cloud](https://cloud.google.com/).
Cloud Seed combines Heroku-like ease-of-use with hyper-cloud flexibility. We do this by using OAuth 2 to provision
services on a hyper-cloud based on a foundation of Terraform and infrastructure-as-code to enable day 2 operations.
## Purpose
We believe that it should be **trivial** to deploy web applications (and other workloads) from GitLab to major cloud

View File

@ -145,66 +145,41 @@ pages. You can safely remove the `type` metadata parameter and its values.
### Batch updates for TW metadata
NOTE:
This task is an MVC, and requires significant manual preparation of the output.
While the task can be time consuming, it is still faster than doing the work
entirely manually.
The [`CODEOWNERS`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/CODEOWNERS)
file contains a list of files and the associated technical writers.
It's important to keep the [`CODEOWNERS`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/CODEOWNERS)
file in the `gitlab` project up to date with the current Technical Writing team assignments.
This information is used in merge requests that contain documentation:
When a merge request contains documentation, the information in the `CODEOWNERS` file determines:
- To populate the eligible approvers section.
- By GitLab Bot to ping reviewers for community contributions.
- The list of users in the **Approvers** section.
- The technical writer that the GitLab Bot pings for community contributions.
GitLab cannot automatically associate the stage and group metadata in our documentation
pages with the technical writer assigned to that group, so we use a Rake task to
generate entries for the `CODEOWNERS` file. Declaring code owners for pages reduces
the number of times GitLab Bot pings the entire Technical Writing team.
You can use a Rake task to update the `CODEOWNERS` file.
The `tw:codeowners` Rake task, located in [`lib/tasks/gitlab/tw/codeowners.rake`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/tasks/gitlab/tw/codeowners.rake),
contains an array of groups and their assigned technical writer. This task:
#### Update the `CODEOWNERS` file
- Outputs a line for each doc with metadata that matches a group in `lib/tasks/gitlab/tw/codeowners.rake`.
Files not matching a group are skipped.
- Adds the full path to the page, and the assigned technical writer.
To update the `CODEOWNERS` file:
To prepare an update to the `CODEOWNERS` file:
1. Open a merge request to update
[the Rake task](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/tasks/gitlab/tw/codeowners.rake)
with the latest [TW team assignments](https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments).
1. Assign the merge request to a backend maintainer for review and merge.
1. After the MR is merged, go to the root of the `gitlab` repository.
1. Run the Rake task and save the output in a file:
1. Update `lib/tasks/gitlab/tw/codeowners.rake` with the latest [TW team assignments](https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments).
Make this update in a standalone merge request, as it runs a long pipeline and
requires backend maintainer review. Make sure this is merged before you update
`CODEOWNERS` in another merge request.
1. Run the task from the root directory of the `gitlab` repository, and save the output in a file:
```ruby
```shell
bundle exec rake tw:codeowners > ~/Desktop/updates.md
```
1. Open the file you just created (`~/Desktop/updates.md` in this example). Check
that the lines are in alphabetical (ascending) order. If you have to sort
the lines and you use VS Code, you can select everything, press <kbd>F1</kbd>,
type `sort`, and select **Sort lines (ascending, case insensitive)**.
1. In the output, look for changes that don't match your expectations:
- New pages, or newly moved pages, show up as added lines.
- Deleted pages, and pages that are now redirects, show up as deleted lines.
- If you see an unusual number of changes to pages that all seem related,
check the metadata for the pages. A group might have been renamed and the Rake task
must be updated to match.
- If all files in a single directory are assigned to the same
technical writer, simplify these entries. Remove all the lines for the individual
files, and leave a single entry for the directory, for example: `/doc/directory/ @tech.writer`.
1. When you are happy with the output, create a new branch to update the
[`CODEOWNERS`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/CODEOWNERS)
file. Replace the documentation-related lines in the `^[Documentation Pages]`
section with the output you prepared.
1. Open the file (for example, `~/Desktop/updates.md`) and copy
the lines in the `^[Documentation Pages]` section.
1. Open the [`CODEOWNERS`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/CODEOWNERS)
file and paste the lines into the `^[Documentation Pages]` section.
WARNING:
The documentation section is not the last section of the `CODEOWNERS` file. Don't
delete data that isn't ours!
1. Create a merge request from this branch with your changes to the `CODEOWNERS` file.
Assign it to a technical writing manager for review.
1. Create a merge request and assign it to a technical writing manager for review.
## Move, rename, or delete a page

View File

@ -1337,6 +1337,7 @@ It renders on the GitLab documentation site as:
> - Second item in the list
## Tabs
<!-- markdownlint-disable tabs-blank-lines -->
On the docs site, you can format text so it's displayed as tabs.
@ -1355,6 +1356,7 @@ Here's some other content in tab two.
::EndTabs
```
<!-- markdownlint-enable tabs-blank-lines -->
This code renders on the GitLab documentation site as:

View File

@ -22,24 +22,24 @@ All event definitions are stored in the following directories:
Each event is defined in a separate YAML file consisting of the following fields:
| Field | Required | Additional information |
|------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `description` | yes | A description of the event. |
| `category` | yes | The event category (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `action` | yes | The event action (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `label_description` | no | A description of the event label (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `property_description` | no | A description of the event property (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `value_description` | no | A description of the event value (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `extra_properties` | no | The type and description of each extra property sent with the event. |
| `identifiers` | no | A list of identifiers sent with the event. Can be set to one or more of `project`, `user`, or `namespace`. |
| `iglu_schema_url` | no | The URL to the custom schema sent with the event, for example, `iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0`. |
| `product_section` | yes | The [section](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/sections.yml). |
| `product_stage` | no | The [stage](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) for the event. |
| `product_group` | yes | The [group](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) that owns the event. |
| `product_category` | no | The [product category](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/categories.yml) for the event. |
| `milestone` | no | The milestone when the event is introduced. |
| `introduced_by_url` | no | The URL to the merge request that introduced the event. |
| `distributions` | yes | The [distributions](https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/#definitions) where the tracked feature is available. Can be set to one or more of `ce` or `ee`. |
| Field | Required | Additional information |
|------------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `description` | yes | A description of the event. |
| `category` | yes | The event category (see [Event schema](index.md#event-schema)). |
| `action` | yes | The event action (see [Event schema](index.md#event-schema)). |
| `label_description` | no | A description of the event label (see [Event schema](index.md#event-schema)). |
| `property_description` | no | A description of the event property (see [Event schema](index.md#event-schema)). |
| `value_description` | no | A description of the event value (see [Event schema](index.md#event-schema)). |
| `extra_properties` | no | The type and description of each extra property sent with the event. |
| `identifiers` | no | A list of identifiers sent with the event. Can be set to one or more of `project`, `user`, or `namespace`. |
| `iglu_schema_url` | no | The URL to the custom schema sent with the event, for example, `iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0`. |
| `product_section` | yes | The [section](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/sections.yml). |
| `product_stage` | no | The [stage](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) for the event. |
| `product_group` | yes | The [group](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) that owns the event. |
| `product_category` | no | The [product category](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/categories.yml) for the event. |
| `milestone` | no | The milestone when the event is introduced. |
| `introduced_by_url` | no | The URL to the merge request that introduced the event. |
| `distributions` | yes | The [distributions](https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/#definitions) where the tracked feature is available. Can be set to one or more of `ce` or `ee`. |
| `tiers` | yes | The [tiers]( https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/) where the tracked feature is available. Can be set to one or more of `free`, `premium`, or `ultimate`. |
### Example event definition

View File

@ -42,14 +42,14 @@ and the custom `extra` object. You can modify this object for any subsequent
structured event that fires, although this is not recommended.
Tracking implementations must have an `action` and a `category`. You can provide additional
properties from the [structured event taxonomy](index.md#structured-event-taxonomy), in
properties from the [event schema](index.md#event-schema), in
addition to an `extra` object that accepts key-value pairs.
| Property | Type | Default value | Description |
|:-----------|:-------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `category` | string | `document.body.dataset.page` | Page or subsection of a page in which events are captured. |
| Property | Type | Default value | Description |
|:-----------|:-------|:---------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `category` | string | `document.body.dataset.page` | Page or subsection of a page in which events are captured. |
| `action` | string | `'generic'` | Action the user is taking. Clicks must be `click` and activations must be `activate`. For example, focusing a form field is `activate_form_input`, and clicking a button is `click_button`. |
| `data` | object | `{}` | Additional data such as `label`, `property`, `value` as described in [Structured event taxonomy](index.md#structured-event-taxonomy), `context` for custom contexts, and `extra` (key-value pairs object). |
| `data` | object | `{}` | Additional data such as `label`, `property`, `value` as described in [Event schema](index.md#event-schema), `context` for custom contexts, and `extra` (key-value pairs object). |
### Usage recommendations

View File

@ -80,7 +80,7 @@ sequenceDiagram
For more details about the architecture, see [Snowplow infrastructure](infrastructure.md).
## Structured event taxonomy
## Event schema
Click events must be consistent. If each feature captures events differently, it can be difficult
to perform analysis.

View File

@ -35,7 +35,7 @@ events or touches Snowplow related files.
#### The Product Intelligence **reviewer** should
- Check that the [event taxonomy](index.md#structured-event-taxonomy) is correct.
- Check that the [event schema](index.md#event-schema) is correct.
- Check the [usage recommendations](implementation.md#usage-recommendations).
- Check that the [Event Dictionary](event_dictionary_guide.md) is up-to-date.
- If needed, check that the events are firing locally using one of the

View File

@ -259,18 +259,6 @@ Once a lifetime for access tokens is set, GitLab:
allowed lifetime. Three hours is given to allow administrators to change the allowed lifetime,
or remove it, before revocation takes place.
<!-- start_remove The following content will be removed on remove_date: '2022-08-22' -->
## Allow expired access tokens to be used (removed) **(ULTIMATE SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214723) in GitLab 13.1.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/296881) in GitLab 13.9.
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/351962) in GitLab 14.8.
> - [Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/351962) in GitLab 15.0.
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/351962) in GitLab 14.8.
This feature was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/351962) in GitLab 15.0.
<!-- end_remove -->
## Disable user profile name changes **(PREMIUM SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24605) in GitLab 12.7.

View File

@ -79,6 +79,21 @@ To edit an existing contact:
You can also [edit](../../api/graphql/reference/index.md#mutationcustomerrelationscontactupdate)
contacts using the GraphQL API.
#### Change the state of a contact
Each contact can be in one of two states:
- **Active**: contacts in this state can be added to an issue.
- **Inactive**: contacts in this state cannot be added to an issue.
To change the state of a contact:
1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Customer relations > Contacts**.
1. Next to the contact you wish to edit, select **Edit** (**{pencil}**).
1. Select or clear the **Active** checkbox.
1. Select **Save changes**.
## Organizations
### View organizations
@ -153,7 +168,7 @@ API.
### Add contacts to an issue
To add contacts to an issue use the `/add_contacts [contact:address@example.com]`
To add [active](#change-the-state-of-a-contact) contacts to an issue use the `/add_contacts [contact:address@example.com]`
[quick action](../project/quick_actions.md).
You can also add, remove, or replace issue contacts using the
@ -175,10 +190,15 @@ API.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/352123) in GitLab 15.0.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/352123) in GitLab 15.2. [Feature flag `contacts_autocomplete`](https://gitlab.com/gitlab-org/gitlab/-/issues/352123) removed.
When you use the `/add_contacts` or `/remove_contacts` quick actions, follow them with `[contact:` and an autocomplete list appears:
When you use the `/add_contacts` quick action, follow it with `[contact:` and an autocomplete list with the [active](#change-the-state-of-a-contact) contacts appears:
```plaintext
/add_contacts [contact:
```
When you use the `/remove_contacts` quick action, follow it with `[contact:` and an autocomplete list with the contacts added to the issue appears:
```plaintext
/remove_contacts [contact:
```

View File

@ -52,7 +52,7 @@ threads. Some quick actions might not be available to all subscription tiers.
| Command | Issue | Merge request | Epic | Action |
|:-------------------------------------------------------------------------------------------------|:-----------------------|:-----------------------|:-----------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/add_contacts [contact:email1@example.com] [contact:email2@example.com]` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Add one or more [CRM contacts](../crm/index.md) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73413) in GitLab 14.6). |
| `/add_contacts [contact:email1@example.com] [contact:email2@example.com]` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Add one or more active [CRM contacts](../crm/index.md) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73413) in GitLab 14.6). |
| `/approve` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Approve the merge request. |
| `/assign @user1 @user2` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Assign one or more users. |
| `/assign me` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Assign yourself. |

View File

@ -1,41 +0,0 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
# Backfill project_ci_feature_usages for a range of projects with coverage
class BackfillProjectsWithCoverage
class ProjectCiFeatureUsage < ActiveRecord::Base # rubocop:disable Style/Documentation
self.table_name = 'project_ci_feature_usages'
end
COVERAGE_ENUM_VALUE = 1
INSERT_DELAY_SECONDS = 0.1
def perform(start_id, end_id, sub_batch_size)
report_results = ActiveRecord::Base.connection.execute <<~SQL
SELECT DISTINCT project_id, default_branch
FROM ci_daily_build_group_report_results
WHERE id BETWEEN #{start_id} AND #{end_id}
SQL
report_results.to_a.in_groups_of(sub_batch_size, false) do |batch|
ProjectCiFeatureUsage.insert_all(build_values(batch))
sleep INSERT_DELAY_SECONDS
end
end
private
def build_values(batch)
batch.map do |data|
{
project_id: data['project_id'],
feature: COVERAGE_ENUM_VALUE,
default_branch: data['default_branch']
}
end
end
end
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
module Gitlab
module Usage
module Metrics
module Instrumentations
class DormantUserPeriodSettingMetric < GenericMetric
value do
::Gitlab::CurrentSettings.deactivate_dormant_users_period
end
end
end
end
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
module Gitlab
module Usage
module Metrics
module Instrumentations
class DormantUserSettingEnabledMetric < GenericMetric
value do
::Gitlab::CurrentSettings.deactivate_dormant_users
end
end
end
end
end
end

View File

@ -143,7 +143,7 @@ function run_task() {
local ruby_cmd="${1}"
local toolbox_pod=$(get_pod "toolbox")
kubectl exec --namespace "${namespace}" "${toolbox_pod}" -- gitlab-rails runner "${ruby_cmd}"
run_timed_command "kubectl exec --namespace \"${namespace}\" \"${toolbox_pod}\" -- gitlab-rails runner \"${ruby_cmd}\""
}
function disable_sign_ups() {
@ -363,7 +363,7 @@ EOF
echoinfo "Deploying with:"
echoinfo "${HELM_CMD}"
eval "${HELM_CMD}"
run_timed_command "eval \"${HELM_CMD}\""
}
function verify_deploy() {

View File

@ -32,3 +32,60 @@ export const eventlistenersMockDefaultMap = [
namespace: 'atwho',
},
];
export const crmContactsMock = [
{
id: 1,
email: 'contact.1@email.com',
firstName: 'Contact',
lastName: 'One',
search: 'contact.1@email.com',
state: 'active',
set: false,
},
{
id: 2,
email: 'contact.2@email.com',
firstName: 'Contact',
lastName: 'Two',
search: 'contact.2@email.com',
state: 'active',
set: false,
},
{
id: 3,
email: 'contact.3@email.com',
firstName: 'Contact',
lastName: 'Three',
search: 'contact.3@email.com',
state: 'inactive',
set: false,
},
{
id: 4,
email: 'contact.4@email.com',
firstName: 'Contact',
lastName: 'Four',
search: 'contact.4@email.com',
state: 'inactive',
set: true,
},
{
id: 5,
email: 'contact.5@email.com',
firstName: 'Contact',
lastName: 'Five',
search: 'contact.5@email.com',
state: 'active',
set: true,
},
{
id: 5,
email: 'contact.6@email.com',
firstName: 'Contact',
lastName: 'Six',
search: 'contact.6@email.com',
state: 'active',
set: undefined, // On purpose
},
];

View File

@ -3,14 +3,23 @@ import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
import labelsFixture from 'test_fixtures/autocomplete_sources/labels.json';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import GfmAutoComplete, { membersBeforeSave, highlighter } from 'ee_else_ce/gfm_auto_complete';
import GfmAutoComplete, {
membersBeforeSave,
highlighter,
CONTACT_STATE_ACTIVE,
CONTACTS_ADD_COMMAND,
CONTACTS_REMOVE_COMMAND,
} from 'ee_else_ce/gfm_auto_complete';
import { initEmojiMock, clearEmojiMock } from 'helpers/emoji';
import '~/lib/utils/jquery_at_who';
import { TEST_HOST } from 'helpers/test_constants';
import waitForPromises from 'helpers/wait_for_promises';
import AjaxCache from '~/lib/utils/ajax_cache';
import axios from '~/lib/utils/axios_utils';
import { eventlistenersMockDefaultMap } from 'ee_else_ce_jest/gfm_auto_complete/mock_data';
import {
eventlistenersMockDefaultMap,
crmContactsMock,
} from 'ee_else_ce_jest/gfm_auto_complete/mock_data';
describe('GfmAutoComplete', () => {
const fetchDataMock = { fetchData: jest.fn() };
@ -871,7 +880,87 @@ describe('GfmAutoComplete', () => {
});
});
describe('Contacts', () => {
describe('CRM Contacts', () => {
const dataSources = {
contacts: `${TEST_HOST}/autocomplete_sources/contacts`,
};
const allContacts = crmContactsMock;
const assignedContacts = allContacts.filter((contact) => contact.set);
const unassignedContacts = allContacts.filter(
(contact) => contact.state === CONTACT_STATE_ACTIVE && !contact.set,
);
let autocomplete;
let $textarea;
beforeEach(() => {
setHTMLFixture('<textarea></textarea>');
autocomplete = new GfmAutoComplete(dataSources);
$textarea = $('textarea');
autocomplete.setup($textarea, { contacts: true });
});
afterEach(() => {
autocomplete.destroy();
resetHTMLFixture();
});
const triggerDropdown = (text) => {
$textarea.trigger('focus').val(text).caret('pos', -1);
$textarea.trigger('keyup');
jest.runOnlyPendingTimers();
};
const getDropdownItems = () => {
const dropdown = document.getElementById('at-view-contacts');
const items = dropdown.getElementsByTagName('li');
return [].map.call(items, (item) => item.textContent.trim());
};
const expectContacts = ({ input, output }) => {
triggerDropdown(input);
expect(getDropdownItems()).toEqual(output.map((contact) => contact.email));
};
describe('with no contacts assigned', () => {
beforeEach(() => {
autocomplete.cachedData['[contact:'] = [...unassignedContacts];
});
it.each`
input | output
${`${CONTACTS_ADD_COMMAND} [contact:`} | ${unassignedContacts}
${`${CONTACTS_REMOVE_COMMAND} [contact:`} | ${[]}
`('$input shows $output.length contacts', expectContacts);
});
describe('with some contacts assigned', () => {
beforeEach(() => {
autocomplete.cachedData['[contact:'] = allContacts;
});
it.each`
input | output
${`${CONTACTS_ADD_COMMAND} [contact:`} | ${unassignedContacts}
${`${CONTACTS_REMOVE_COMMAND} [contact:`} | ${assignedContacts}
`('$input shows $output.length contacts', expectContacts);
});
describe('with all contacts assigned', () => {
beforeEach(() => {
autocomplete.cachedData['[contact:'] = [...assignedContacts];
});
it.each`
input | output
${`${CONTACTS_ADD_COMMAND} [contact:`} | ${[]}
${`${CONTACTS_REMOVE_COMMAND} [contact:`} | ${assignedContacts}
`('$input shows $output.length contacts', expectContacts);
});
it('escapes name and email correct', () => {
const xssPayload = '<script>alert(1)</script>';
const escapedPayload = '&lt;script&gt;alert(1)&lt;/script&gt;';

View File

@ -1,95 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillProjectsWithCoverage,
:suppress_gitlab_schemas_validate_connection, schema: 20210818185845 do
let(:projects) { table(:projects) }
let(:project_ci_feature_usages) { table(:project_ci_feature_usages) }
let(:ci_pipelines) { table(:ci_pipelines) }
let(:ci_daily_build_group_report_results) { table(:ci_daily_build_group_report_results) }
let(:group) { table(:namespaces).create!(name: 'user', path: 'user') }
let(:project_1) { projects.create!(namespace_id: group.id) }
let(:project_2) { projects.create!(namespace_id: group.id) }
let(:pipeline_1) { ci_pipelines.create!(project_id: project_1.id, source: 13) }
let(:pipeline_2) { ci_pipelines.create!(project_id: project_1.id, source: 13) }
let(:pipeline_3) { ci_pipelines.create!(project_id: project_2.id, source: 13) }
let(:pipeline_4) { ci_pipelines.create!(project_id: project_2.id, source: 13) }
subject { described_class.new }
describe '#perform' do
before do
ci_daily_build_group_report_results.create!(
id: 1,
project_id: project_1.id,
date: 4.days.ago,
last_pipeline_id: pipeline_1.id,
ref_path: 'main',
group_name: 'rspec',
data: { coverage: 95.0 },
default_branch: true,
group_id: group.id
)
ci_daily_build_group_report_results.create!(
id: 2,
project_id: project_1.id,
date: 3.days.ago,
last_pipeline_id: pipeline_2.id,
ref_path: 'main',
group_name: 'rspec',
data: { coverage: 95.0 },
default_branch: true,
group_id: group.id
)
ci_daily_build_group_report_results.create!(
id: 3,
project_id: project_2.id,
date: 2.days.ago,
last_pipeline_id: pipeline_3.id,
ref_path: 'main',
group_name: 'rspec',
data: { coverage: 95.0 },
default_branch: true,
group_id: group.id
)
ci_daily_build_group_report_results.create!(
id: 4,
project_id: project_2.id,
date: 1.day.ago,
last_pipeline_id: pipeline_4.id,
ref_path: 'test_branch',
group_name: 'rspec',
data: { coverage: 95.0 },
default_branch: false,
group_id: group.id
)
stub_const("#{described_class}::INSERT_DELAY_SECONDS", 0)
end
it 'creates entries per project and default_branch combination in the given range', :aggregate_failures do
subject.perform(1, 4, 2)
entries = project_ci_feature_usages.order('project_id ASC, default_branch DESC')
expect(entries.count).to eq(3)
expect(entries[0]).to have_attributes(project_id: project_1.id, feature: 1, default_branch: true)
expect(entries[1]).to have_attributes(project_id: project_2.id, feature: 1, default_branch: true)
expect(entries[2]).to have_attributes(project_id: project_2.id, feature: 1, default_branch: false)
end
context 'when an entry for the project and default branch combination already exists' do
before do
subject.perform(1, 4, 2)
end
it 'does not create a new entry' do
expect { subject.perform(1, 4, 2) }.not_to change { project_ci_feature_usages.count }
end
end
end
end

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DormantUserPeriodSettingMetric do
using RSpec::Parameterized::TableSyntax
where(:deactivate_dormant_users_period_value, :expected_value) do
90 | 90 # default
365 | 365
end
with_them do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
stub_application_setting(deactivate_dormant_users_period: deactivate_dormant_users_period_value)
end
it_behaves_like 'a correct instrumented metric value', {}
end
end

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DormantUserSettingEnabledMetric do
using RSpec::Parameterized::TableSyntax
where(:deactivate_dormant_users_enabled, :expected_value) do
1 | 1
0 | 0
end
with_them do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
stub_application_setting(deactivate_dormant_users: deactivate_dormant_users_enabled)
end
it_behaves_like 'a correct instrumented metric value', {}
end
end

View File

@ -1,71 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe BackfillProjectsWithCoverage, :suppress_gitlab_schemas_validate_connection do
let(:projects) { table(:projects) }
let(:ci_pipelines) { table(:ci_pipelines) }
let(:ci_daily_build_group_report_results) { table(:ci_daily_build_group_report_results) }
let(:group) { table(:namespaces).create!(name: 'user', path: 'user') }
let(:project_1) { projects.create!(namespace_id: group.id) }
let(:project_2) { projects.create!(namespace_id: group.id) }
let(:pipeline_1) { ci_pipelines.create!(project_id: project_1.id) }
let(:pipeline_2) { ci_pipelines.create!(project_id: project_2.id) }
let(:pipeline_3) { ci_pipelines.create!(project_id: project_2.id) }
describe '#up' do
before do
stub_const("#{described_class}::BATCH_SIZE", 2)
stub_const("#{described_class}::SUB_BATCH_SIZE", 1)
ci_daily_build_group_report_results.create!(
id: 1,
project_id: project_1.id,
date: 3.days.ago,
last_pipeline_id: pipeline_1.id,
ref_path: 'main',
group_name: 'rspec',
data: { coverage: 95.0 },
default_branch: true,
group_id: group.id
)
ci_daily_build_group_report_results.create!(
id: 2,
project_id: project_2.id,
date: 2.days.ago,
last_pipeline_id: pipeline_2.id,
ref_path: 'main',
group_name: 'rspec',
data: { coverage: 95.0 },
default_branch: true,
group_id: group.id
)
ci_daily_build_group_report_results.create!(
id: 3,
project_id: project_2.id,
date: 1.day.ago,
last_pipeline_id: pipeline_3.id,
ref_path: 'test_branch',
group_name: 'rspec',
data: { coverage: 95.0 },
default_branch: false,
group_id: group.id
)
end
it 'schedules BackfillProjectsWithCoverage background jobs', :aggregate_failures do
Sidekiq::Testing.fake! do
freeze_time do
migrate!
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 1, 2, 1)
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 3, 3, 1)
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
end
end
end
end
end