Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
17e74fcd46
commit
62d57690bc
11 changed files with 320 additions and 76 deletions
|
@ -5852,6 +5852,36 @@ type DastProfileCreatePayload {
|
|||
pipelineUrl: String
|
||||
}
|
||||
|
||||
"""
|
||||
Autogenerated input type of DastProfileDelete
|
||||
"""
|
||||
input DastProfileDeleteInput {
|
||||
"""
|
||||
A unique identifier for the client performing the mutation.
|
||||
"""
|
||||
clientMutationId: String
|
||||
|
||||
"""
|
||||
ID of the profile to be deleted.
|
||||
"""
|
||||
id: DastProfileID!
|
||||
}
|
||||
|
||||
"""
|
||||
Autogenerated return type of DastProfileDelete
|
||||
"""
|
||||
type DastProfileDeletePayload {
|
||||
"""
|
||||
A unique identifier for the client performing the mutation.
|
||||
"""
|
||||
clientMutationId: String
|
||||
|
||||
"""
|
||||
Errors encountered during execution of the mutation.
|
||||
"""
|
||||
errors: [String!]!
|
||||
}
|
||||
|
||||
"""
|
||||
An edge in a connection.
|
||||
"""
|
||||
|
@ -16368,6 +16398,7 @@ type Mutation {
|
|||
createTestCase(input: CreateTestCaseInput!): CreateTestCasePayload
|
||||
dastOnDemandScanCreate(input: DastOnDemandScanCreateInput!): DastOnDemandScanCreatePayload
|
||||
dastProfileCreate(input: DastProfileCreateInput!): DastProfileCreatePayload
|
||||
dastProfileDelete(input: DastProfileDeleteInput!): DastProfileDeletePayload
|
||||
dastScannerProfileCreate(input: DastScannerProfileCreateInput!): DastScannerProfileCreatePayload
|
||||
dastScannerProfileDelete(input: DastScannerProfileDeleteInput!): DastScannerProfileDeletePayload
|
||||
dastScannerProfileUpdate(input: DastScannerProfileUpdateInput!): DastScannerProfileUpdatePayload
|
||||
|
|
|
@ -15916,6 +15916,94 @@
|
|||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "INPUT_OBJECT",
|
||||
"name": "DastProfileDeleteInput",
|
||||
"description": "Autogenerated input type of DastProfileDelete",
|
||||
"fields": null,
|
||||
"inputFields": [
|
||||
{
|
||||
"name": "id",
|
||||
"description": "ID of the profile to be deleted.",
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "DastProfileID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "clientMutationId",
|
||||
"description": "A unique identifier for the client performing the mutation.",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
}
|
||||
],
|
||||
"interfaces": null,
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "DastProfileDeletePayload",
|
||||
"description": "Autogenerated return type of DastProfileDelete",
|
||||
"fields": [
|
||||
{
|
||||
"name": "clientMutationId",
|
||||
"description": "A unique identifier for the client performing the mutation.",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "errors",
|
||||
"description": "Errors encountered during execution of the mutation.",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [
|
||||
|
||||
],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "DastProfileEdge",
|
||||
|
@ -45740,6 +45828,33 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "dastProfileDelete",
|
||||
"description": null,
|
||||
"args": [
|
||||
{
|
||||
"name": "input",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "INPUT_OBJECT",
|
||||
"name": "DastProfileDeleteInput",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "OBJECT",
|
||||
"name": "DastProfileDeletePayload",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "dastScannerProfileCreate",
|
||||
"description": null,
|
||||
|
|
|
@ -24,6 +24,8 @@ Fields that are deprecated are marked with **{warning-solid}**.
|
|||
Items (fields, enums, etc) that have been removed according to our [deprecation process](../index.md#deprecation-process) can be found
|
||||
in [Removed Items](../removed_items.md).
|
||||
|
||||
<!-- vale gitlab.Spelling = NO -->
|
||||
|
||||
## Object types
|
||||
|
||||
Object types represent the resources that the GitLab GraphQL API can return.
|
||||
|
@ -941,6 +943,15 @@ Autogenerated return type of DastProfileCreate.
|
|||
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
|
||||
| `pipelineUrl` | String | The URL of the pipeline that was created. Requires `runAfterCreate` to be set to `true`. |
|
||||
|
||||
### DastProfileDeletePayload
|
||||
|
||||
Autogenerated return type of DastProfileDelete.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
|
||||
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
|
||||
|
||||
### DastScannerProfile
|
||||
|
||||
Represents a DAST scanner profile.
|
||||
|
|
|
@ -4597,6 +4597,94 @@ Use this feature to ignore jobs, or use the
|
|||
[special YAML features](#special-yaml-features) and transform the hidden jobs
|
||||
into templates.
|
||||
|
||||
### `!reference` tags
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/266173) in GitLab 13.9.
|
||||
> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
|
||||
> - It's disabled on GitLab.com.
|
||||
> - It's not recommended for production use.
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-reference-tags). **(FREE SELF)**
|
||||
|
||||
WARNING:
|
||||
This feature might not be available to you. Check the **version history** note above for details.
|
||||
|
||||
Use the `!reference` custom YAML tag to select keyword configuration from other job
|
||||
sections and reuse it in the current section. Unlike [YAML anchors](#anchors), you can
|
||||
use `!reference` tags to reuse configuration from [included](#include) configuration
|
||||
files as well.
|
||||
|
||||
In this example, a `script` and an `after_script` from two different locations are
|
||||
reused in the `test` job:
|
||||
|
||||
- `setup.yml`:
|
||||
|
||||
```yaml
|
||||
.setup:
|
||||
script:
|
||||
- echo creating environment
|
||||
```
|
||||
|
||||
- `.gitlab-ci.yml`:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- local: setup.yml
|
||||
|
||||
.teardown:
|
||||
after_script:
|
||||
- echo deleting environment
|
||||
|
||||
test:
|
||||
script:
|
||||
- !reference [.setup, script]
|
||||
- echo running my own command
|
||||
after_script:
|
||||
- !reference [.teardown, after_script]
|
||||
```
|
||||
|
||||
In this example, `test-vars-1` reuses the all the variables in `.vars`, while `test-vars-2`
|
||||
selects a specific variable and reuses it as a new `MY_VAR` variable.
|
||||
|
||||
```yaml
|
||||
.vars:
|
||||
variables:
|
||||
URL: "http://my-url.internal"
|
||||
IMPORTANT_VAR: "the details"
|
||||
|
||||
test-vars-1:
|
||||
variables: !reference [.vars, variables]
|
||||
script:
|
||||
- printenv
|
||||
|
||||
test-vars-2:
|
||||
variables:
|
||||
MY_VAR: !reference [.vars, variables, IMPORTANT_VAR]
|
||||
script:
|
||||
- printenv
|
||||
```
|
||||
|
||||
You can't reuse a section that already includes a `!reference` tag. Only one level
|
||||
of nesting is supported.
|
||||
|
||||
#### Enable or disable `!reference` tags **(FREE SELF)**
|
||||
|
||||
The `!reference` tag is under development and not ready for production use. It is
|
||||
deployed behind a feature flag that is **disabled by default**.
|
||||
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
|
||||
can enable it.
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:ci_custom_yaml_tags)
|
||||
```
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:ci_custom_yaml_tags)
|
||||
```
|
||||
|
||||
## Skip Pipeline
|
||||
|
||||
To push a commit without triggering a pipeline, add `[ci skip]` or `[skip ci]`, using any
|
||||
|
|
|
@ -48,6 +48,17 @@ NOTE:
|
|||
We follow the same structure and deprecations as [Webhooks](../user/project/integrations/webhooks.md)
|
||||
for Push and Tag events, but we never display commits.
|
||||
|
||||
## Create a system hook
|
||||
|
||||
To create a system hook:
|
||||
|
||||
1. In the top navigation bar, go to **{admin}** **Admin Area**.
|
||||
1. In the left sidebar, select **System Hooks**.
|
||||
1. Provide the **URL** and **Secret Token**.
|
||||
1. Select the check box next to each **Trigger** you want to enable.
|
||||
1. Select **Enable SSL verification**, if desired.
|
||||
1. Click **Add system hook**.
|
||||
|
||||
## Hooks request example
|
||||
|
||||
**Request header**:
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
Fields that are deprecated are marked with **{warning-solid}**.
|
||||
Items (fields, enums, etc) that have been removed according to our [deprecation process](../index.md#deprecation-process) can be found
|
||||
in [Removed Items](../removed_items.md).
|
||||
|
||||
<!-- vale gitlab.Spelling = NO -->
|
||||
\
|
||||
|
||||
:plain
|
||||
|
|
|
@ -44,7 +44,7 @@ module Gitlab
|
|||
|
||||
def aggregated_metrics_data(start_date:, end_date:)
|
||||
aggregated_metrics.each_with_object({}) do |aggregation, data|
|
||||
next if aggregation[:feature_flag] && Feature.disabled?(aggregation[:feature_flag], default_enabled: false, type: :development)
|
||||
next if aggregation[:feature_flag] && Feature.disabled?(aggregation[:feature_flag], default_enabled: :yaml, type: :development)
|
||||
|
||||
case aggregation[:source]
|
||||
when REDIS_SOURCE
|
||||
|
|
|
@ -1,70 +1,70 @@
|
|||
import Vue from 'vue';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import DescriptionField from '~/issue_show/components/fields/description.vue';
|
||||
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
|
||||
import eventHub from '~/issue_show/event_hub';
|
||||
import Store from '~/issue_show/stores';
|
||||
import descriptionField from '~/issue_show/components/fields/description.vue';
|
||||
import { keyboardDownEvent } from '../../helpers';
|
||||
|
||||
describe('Description field component', () => {
|
||||
let vm;
|
||||
let store;
|
||||
let wrapper;
|
||||
|
||||
beforeEach((done) => {
|
||||
const Component = Vue.extend(descriptionField);
|
||||
const el = document.createElement('div');
|
||||
store = new Store({
|
||||
titleHtml: '',
|
||||
descriptionHtml: '',
|
||||
issuableRef: '',
|
||||
});
|
||||
store.formState.description = 'test';
|
||||
const findTextarea = () => wrapper.find({ ref: 'textarea' });
|
||||
|
||||
document.body.appendChild(el);
|
||||
|
||||
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
|
||||
|
||||
vm = new Component({
|
||||
el,
|
||||
const mountComponent = (description = 'test') =>
|
||||
shallowMount(DescriptionField, {
|
||||
attachTo: document.body,
|
||||
propsData: {
|
||||
markdownPreviewPath: '/',
|
||||
markdownDocsPath: '/',
|
||||
formState: store.formState,
|
||||
formState: {
|
||||
description,
|
||||
},
|
||||
},
|
||||
}).$mount();
|
||||
stubs: {
|
||||
MarkdownField,
|
||||
},
|
||||
});
|
||||
|
||||
Vue.nextTick(done);
|
||||
beforeEach(() => {
|
||||
jest.spyOn(eventHub, '$emit');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
wrapper = null;
|
||||
});
|
||||
|
||||
it('renders markdown field with description', () => {
|
||||
expect(vm.$el.querySelector('.md-area textarea').value).toBe('test');
|
||||
wrapper = mountComponent();
|
||||
|
||||
expect(findTextarea().element.value).toBe('test');
|
||||
});
|
||||
|
||||
it('renders markdown field with a markdown description', (done) => {
|
||||
store.formState.description = '**test**';
|
||||
it('renders markdown field with a markdown description', () => {
|
||||
const markdown = '**test**';
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(vm.$el.querySelector('.md-area textarea').value).toBe('**test**');
|
||||
wrapper = mountComponent(markdown);
|
||||
|
||||
done();
|
||||
});
|
||||
expect(findTextarea().element.value).toBe(markdown);
|
||||
});
|
||||
|
||||
it('focuses field when mounted', () => {
|
||||
expect(document.activeElement).toBe(vm.$refs.textarea);
|
||||
wrapper = mountComponent();
|
||||
|
||||
expect(document.activeElement).toBe(findTextarea().element);
|
||||
});
|
||||
|
||||
it('triggers update with meta+enter', () => {
|
||||
vm.$el.querySelector('.md-area textarea').dispatchEvent(keyboardDownEvent(13, true));
|
||||
wrapper = mountComponent();
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalled();
|
||||
findTextarea().trigger('keydown.enter', { metaKey: true });
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('update.issuable');
|
||||
});
|
||||
|
||||
it('triggers update with ctrl+enter', () => {
|
||||
vm.$el.querySelector('.md-area textarea').dispatchEvent(keyboardDownEvent(13, false, true));
|
||||
wrapper = mountComponent();
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalled();
|
||||
});
|
||||
findTextarea().trigger('keydown.enter', { ctrlKey: true });
|
||||
|
||||
it('has a ref named `textarea`', () => {
|
||||
expect(vm.$refs.textarea).not.toBeNull();
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('update.issuable');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,48 +1,42 @@
|
|||
import Vue from 'vue';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import TitleField from '~/issue_show/components/fields/title.vue';
|
||||
import eventHub from '~/issue_show/event_hub';
|
||||
import Store from '~/issue_show/stores';
|
||||
import titleField from '~/issue_show/components/fields/title.vue';
|
||||
import { keyboardDownEvent } from '../../helpers';
|
||||
|
||||
describe('Title field component', () => {
|
||||
let vm;
|
||||
let store;
|
||||
let wrapper;
|
||||
|
||||
const findInput = () => wrapper.find({ ref: 'input' });
|
||||
|
||||
beforeEach(() => {
|
||||
const Component = Vue.extend(titleField);
|
||||
store = new Store({
|
||||
titleHtml: '',
|
||||
descriptionHtml: '',
|
||||
issuableRef: '',
|
||||
});
|
||||
store.formState.title = 'test';
|
||||
jest.spyOn(eventHub, '$emit');
|
||||
|
||||
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
|
||||
|
||||
vm = new Component({
|
||||
wrapper = shallowMount(TitleField, {
|
||||
propsData: {
|
||||
formState: store.formState,
|
||||
formState: {
|
||||
title: 'test',
|
||||
},
|
||||
},
|
||||
}).$mount();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
wrapper = null;
|
||||
});
|
||||
|
||||
it('renders form control with formState title', () => {
|
||||
expect(vm.$el.querySelector('.form-control').value).toBe('test');
|
||||
expect(findInput().element.value).toBe('test');
|
||||
});
|
||||
|
||||
it('triggers update with meta+enter', () => {
|
||||
vm.$el.querySelector('.form-control').dispatchEvent(keyboardDownEvent(13, true));
|
||||
findInput().trigger('keydown.enter', { metaKey: true });
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalled();
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('update.issuable');
|
||||
});
|
||||
|
||||
it('triggers update with ctrl+enter', () => {
|
||||
vm.$el.querySelector('.form-control').dispatchEvent(keyboardDownEvent(13, false, true));
|
||||
findInput().trigger('keydown.enter', { ctrlKey: true });
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('has a ref named `input`', () => {
|
||||
expect(vm.$refs.input).not.toBeNull();
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('update.issuable');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
export const keyboardDownEvent = (code, metaKey = false, ctrlKey = false) => {
|
||||
const e = new CustomEvent('keydown');
|
||||
|
||||
e.keyCode = code;
|
||||
e.metaKey = metaKey;
|
||||
e.ctrlKey = ctrlKey;
|
||||
|
||||
return e;
|
||||
};
|
|
@ -142,6 +142,7 @@ RSpec.describe Gitlab::Usage::Metrics::Aggregates::Aggregate, :clean_gitlab_redi
|
|||
|
||||
it 'does not calculate data for aggregates with ff turned off' do
|
||||
skip_feature_flags_yaml_validation
|
||||
skip_default_enabled_yaml_check
|
||||
stub_feature_flags(enabled_feature_flag => true, disabled_feature_flag => false)
|
||||
allow(sources::RedisHll).to receive(:calculate_metrics_union).and_return(6)
|
||||
|
||||
|
|
Loading…
Reference in a new issue