Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
0a154f21ff
commit
3bf86ff021
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { mapState } from 'vuex';
|
||||
import { GlBadge, GlTab, GlTabs } from '@gitlab/ui';
|
||||
import { GlBadge, GlTab, GlTabs, GlButton, GlModalDirective } from '@gitlab/ui';
|
||||
import { createAlert } from '~/alert';
|
||||
import { s__, sprintf } from '~/locale';
|
||||
import { getParameterByName } from '~/lib/utils/url_utility';
|
||||
|
|
@ -12,6 +12,9 @@ import {
|
|||
|
||||
import importSourceUsersQuery from '../graphql/queries/import_source_users.query.graphql';
|
||||
import PlaceholdersTable from './placeholders_table.vue';
|
||||
import CsvUploadModal from './csv_upload_modal.vue';
|
||||
|
||||
const UPLOAD_CSV_PLACEHOLDERS_MODAL_ID = 'upload-placeholders-csv-modal';
|
||||
|
||||
const DEFAULT_PAGE_SIZE = 20;
|
||||
|
||||
|
|
@ -21,10 +24,14 @@ export default {
|
|||
GlBadge,
|
||||
GlTab,
|
||||
GlTabs,
|
||||
GlButton,
|
||||
PlaceholdersTable,
|
||||
CsvUploadModal,
|
||||
},
|
||||
directives: {
|
||||
GlModal: GlModalDirective,
|
||||
},
|
||||
inject: ['group'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
selectedTabIndex: 0,
|
||||
|
|
@ -36,7 +43,6 @@ export default {
|
|||
},
|
||||
};
|
||||
},
|
||||
|
||||
apollo: {
|
||||
sourceUsers: {
|
||||
query: importSourceUsersQuery,
|
||||
|
|
@ -58,7 +64,6 @@ export default {
|
|||
},
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState('placeholder', ['pagination']),
|
||||
isLoading() {
|
||||
|
|
@ -86,7 +91,6 @@ export default {
|
|||
this.unassignedCount = this.pagination.awaitingReassignmentItems;
|
||||
this.reassignedCount = this.pagination.reassignedItems;
|
||||
},
|
||||
|
||||
methods: {
|
||||
onConfirm(item) {
|
||||
this.$toast.show(
|
||||
|
|
@ -98,14 +102,12 @@ export default {
|
|||
this.reassignedCount += 1;
|
||||
this.unassignedCount -= 1;
|
||||
},
|
||||
|
||||
onPrevPage() {
|
||||
this.cursor = {
|
||||
before: this.sourceUsers.pageInfo.startCursor,
|
||||
after: null,
|
||||
};
|
||||
},
|
||||
|
||||
onNextPage() {
|
||||
this.cursor = {
|
||||
after: this.sourceUsers.pageInfo.endCursor,
|
||||
|
|
@ -113,11 +115,12 @@ export default {
|
|||
};
|
||||
},
|
||||
},
|
||||
uploadCsvModalId: UPLOAD_CSV_PLACEHOLDERS_MODAL_ID,
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<gl-tabs v-model="selectedTabIndex" class="gl-mt-3">
|
||||
<gl-tabs v-model="selectedTabIndex" nav-class="gl-grow gl-items-center gl-mt-3">
|
||||
<gl-tab>
|
||||
<template #title>
|
||||
<span>{{ s__('UserMapping|Awaiting reassignment') }}</span>
|
||||
|
|
@ -151,5 +154,18 @@ export default {
|
|||
@next="onNextPage"
|
||||
/>
|
||||
</gl-tab>
|
||||
|
||||
<template #tabs-end>
|
||||
<gl-button
|
||||
v-gl-modal="$options.uploadCsvModalId"
|
||||
variant="link"
|
||||
icon="media"
|
||||
class="gl-ml-auto"
|
||||
data-testid="reassign-csv-button"
|
||||
>
|
||||
{{ s__('UserMapping|Reassign with CSV file') }}
|
||||
</gl-button>
|
||||
<csv-upload-modal :modal-id="$options.uploadCsvModalId" />
|
||||
</template>
|
||||
</gl-tabs>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
<script>
|
||||
import { GlModal, GlLink, GlSprintf, GlButton, GlAlert } from '@gitlab/ui';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import { s__, __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlModal,
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
GlButton,
|
||||
GlAlert,
|
||||
},
|
||||
inject: {
|
||||
reassignmentCsvDownloadPath: {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
props: {
|
||||
modalId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
docsLink: helpPagePath('user/project/import/index', {
|
||||
anchor: 'request-reassignment-by-using-a-csv-file',
|
||||
}),
|
||||
i18n: {
|
||||
description: s__(
|
||||
'UserMapping|Use a CSV file to reassign contributions from placeholder users to existing group members. This can be done in a few steps. %{linkStart}Learn more about matching users by CSV%{linkEnd}.',
|
||||
),
|
||||
},
|
||||
primaryAction: {
|
||||
text: s__('UserMapping|Reassign'),
|
||||
},
|
||||
cancelAction: {
|
||||
text: __('Cancel'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-modal
|
||||
:ref="modalId"
|
||||
:modal-id="modalId"
|
||||
:title="s__('UserMapping|Reassign with CSV file')"
|
||||
:action-primary="$options.primaryAction"
|
||||
:action-cancel="$options.cancelAction"
|
||||
>
|
||||
<gl-sprintf :message="$options.i18n.description">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="$options.docsLink" target="_blank">
|
||||
{{ content }}
|
||||
</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
<ol class="gl-ml-0 gl-mt-5">
|
||||
<li>
|
||||
<gl-button
|
||||
:href="reassignmentCsvDownloadPath"
|
||||
variant="link"
|
||||
icon="download"
|
||||
data-testid="csv-download-button"
|
||||
class="vertical-align-text-top"
|
||||
>{{ s__('UserMapping|Download the pre-filled CSV template.') }}</gl-button
|
||||
>
|
||||
</li>
|
||||
<li>{{ s__('UserMapping|Review and complete filling out the CSV file.') }}</li>
|
||||
<li>{{ s__('UserMapping|Upload reviewed and completed CSV file.') }}</li>
|
||||
</ol>
|
||||
<gl-alert variant="warning" :dismissible="false">
|
||||
{{
|
||||
s__(
|
||||
'UserMapping|Once you select "Reassign", the processing will start and users will receive and email to accept the contribution reassignment. Once a users has accepted the reassignment, it cannot be undone. Check all data is correct before continuing.',
|
||||
)
|
||||
}}
|
||||
</gl-alert>
|
||||
</gl-modal>
|
||||
</template>
|
||||
|
|
@ -293,6 +293,7 @@ export default {
|
|||
} else {
|
||||
this.unsetError();
|
||||
this.workItemsToAdd = [];
|
||||
this.closeForm();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
|
|
@ -328,6 +329,7 @@ export default {
|
|||
} else {
|
||||
this.unsetError();
|
||||
this.$emit('addChild');
|
||||
this.closeForm();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
|
|
@ -340,6 +342,9 @@ export default {
|
|||
this.submitInProgress = false;
|
||||
});
|
||||
},
|
||||
closeForm() {
|
||||
this.$emit('cancel');
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
titleInputLabel: __('Title'),
|
||||
|
|
@ -446,7 +451,7 @@ export default {
|
|||
>
|
||||
{{ addOrCreateButtonLabel }}
|
||||
</gl-button>
|
||||
<gl-button category="secondary" size="small" @click="$emit('cancel')">
|
||||
<gl-button category="secondary" size="small" @click="closeForm">
|
||||
{{ s__('WorkItem|Cancel') }}
|
||||
</gl-button>
|
||||
</gl-form>
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/472750
|
|||
milestone: '17.3'
|
||||
group: group::source code
|
||||
type: beta
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/468669
|
|||
milestone: '17.2'
|
||||
group: group::authorization
|
||||
type: beta
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: autoflow_enabled
|
||||
feature_issue_url: https://gitlab.com/groups/gitlab-org/-/epics/12120
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/160947
|
||||
rollout_issue_url:
|
||||
milestone: '17.3'
|
||||
group: group::environments
|
||||
type: wip
|
||||
default_enabled: false
|
||||
|
|
@ -52,6 +52,12 @@ Users are considered inactive in LDAP when they:
|
|||
- Are marked as disabled or deactivated in Active Directory through the user account control attribute. This means attribute
|
||||
`userAccountControl:1.2.840.113556.1.4.803` has bit 2 set.
|
||||
|
||||
To check if a user is active or inactive in LDAP, use the following PowerShell command and the [Active Directory Module](https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2022-ps) to check the Active Directory:
|
||||
|
||||
```powershell
|
||||
Get-ADUser -Identity <username> -Properties userAccountControl | Select-Object Name, userAccountControl
|
||||
```
|
||||
|
||||
GitLab checks LDAP users' status:
|
||||
|
||||
- When signing in using any authentication provider.
|
||||
|
|
|
|||
|
|
@ -1211,9 +1211,11 @@ than GitLab to prevent XSS attacks.
|
|||
|
||||
### Rate limits
|
||||
|
||||
> - [Changed](https://gitlab.com/groups/gitlab-org/-/epics/14653) in GitLab 17.3: You can exclude subnets from Pages rate limits.
|
||||
|
||||
You can enforce rate limits to help minimize the risk of a Denial of Service (DoS) attack. GitLab Pages
|
||||
uses a [token bucket algorithm](https://en.wikipedia.org/wiki/Token_bucket) to enforce rate limiting. By default,
|
||||
requests or TLS connections that exceed the specified limits are reported but not rejected.
|
||||
requests or TLS connections that exceed the specified limits are reported and rejected.
|
||||
|
||||
GitLab Pages supports the following types of rate limiting:
|
||||
|
||||
|
|
@ -1222,20 +1224,25 @@ GitLab Pages supports the following types of rate limiting:
|
|||
|
||||
HTTP request-based rate limits are enforced using the following:
|
||||
|
||||
- `rate_limit_source_ip`: Set the maximum threshold in number of requests per client IP per second. Set to 0 to disable this feature.
|
||||
- `rate_limit_source_ip`: Sets the maximum threshold in number of requests per client IP per second. Set to 0 to disable this feature.
|
||||
- `rate_limit_source_ip_burst`: Sets the maximum threshold of number of requests allowed in an initial outburst of requests per client IP.
|
||||
For example, when you load a web page that loads a number of resources at the same time.
|
||||
- `rate_limit_domain`: Set the maximum threshold in number of requests per hosted pages domain per second. Set to 0 to disable this feature.
|
||||
- `rate_limit_domain`: Sets the maximum threshold in number of requests per hosted pages domain per second. Set to 0 to disable this feature.
|
||||
- `rate_limit_domain_burst`: Sets the maximum threshold of number of requests allowed in an initial outburst of requests per hosted pages domain.
|
||||
|
||||
TLS connection-based rate limits are enforced using the following:
|
||||
|
||||
- `rate_limit_tls_source_ip`: Set the maximum threshold in number of TLS connections per client IP per second. Set to 0 to disable this feature.
|
||||
- `rate_limit_tls_source_ip`: Sets the maximum threshold in number of TLS connections per client IP per second. Set to 0 to disable this feature.
|
||||
- `rate_limit_tls_source_ip_burst`: Sets the maximum threshold of number of TLS connections allowed in an initial outburst of TLS connections per client IP.
|
||||
For example, when you load a web page from different web browsers at the same time.
|
||||
- `rate_limit_tls_domain`: Set the maximum threshold in number of TLS connections per hosted pages domain per second. Set to 0 to disable this feature.
|
||||
- `rate_limit_tls_domain`: Sets the maximum threshold in number of TLS connections per hosted pages domain per second. Set to 0 to disable this feature.
|
||||
- `rate_limit_tls_domain_burst`: Sets the maximum threshold of number of TLS connections allowed in an initial outburst of TLS connections per hosted pages domain.
|
||||
|
||||
To allow certain IP ranges (subnets) to bypass all rate limits:
|
||||
|
||||
- `rate_limit_subnets_allow_list`: Sets the allow list with the IP ranges (subnets) that should bypass all rate limits.
|
||||
For example, `['1.2.3.4/24', '2001:db8::1/32']`.
|
||||
|
||||
An IPv6 address receives a large prefix in the 128-bit address space. The prefix is typically at least size /64. Because of the large number of possible addresses, if the client's IP address is IPv6, the limit is applied to the IPv6 prefix with a length of 64, rather than the entire IPv6 address.
|
||||
|
||||
#### Enable HTTP requests rate limits by source-IP
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ glab mr merge
|
|||
## GitLab Duo for the CLI
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md)
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** Experiment, Self-managed, GitLab Dedicated
|
||||
|
||||
The GitLab CLI includes features powered by [GitLab Duo](../../user/ai_features.md). These include:
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ After you save a visualization, you can add it to a new or existing custom dashb
|
|||
### Generate a custom visualization with GitLab Duo
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate for a limited time. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ the Vulnerability Report's [Activity filter](../vulnerability_report/index.md#ac
|
|||
## Explaining a vulnerability
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with [GitLab Duo Enterprise](../../../subscriptions/subscription-add-ons.md)
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10368) in GitLab 16.0 as an [experiment](../../../policy/experiment-beta-support.md#experiment) on GitLab.com.
|
||||
|
|
@ -90,7 +90,7 @@ The following data is shared with third-party AI APIs:
|
|||
## Vulnerability resolution
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with [GitLab Duo Enterprise](../../../subscriptions/subscription-add-ons.md)
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ The following GitLab Duo features are
|
|||
## Summarize issue discussions with Discussion summary
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate for a limited time. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ Provide feedback on this experimental feature in [issue 416833](https://gitlab.c
|
|||
## Summarize an issue with Issue description generation
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate for a limited time. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ how and where you can access these features.
|
|||
### GitLab Duo Chat
|
||||
|
||||
DETAILS:
|
||||
**Tier: GitLab.com and Self-managed:** Premium or Ultimate for a limited time. In the future, Premium with GitLab Duo Pro or Ultimate with [GitLab Duo Pro or Enterprise](../../subscriptions/subscription-add-ons.md). **GitLab Dedicated:** GitLab Duo Pro or Enterprise.
|
||||
**Tier: GitLab.com and Self-managed:** For a limited time, Premium or Ultimate. In the future, Premium with GitLab Duo Pro or Ultimate with [GitLab Duo Pro or Enterprise](../../subscriptions/subscription-add-ons.md). **GitLab Dedicated:** GitLab Duo Pro or Enterprise.
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
- Help you write and understand code faster, get up to speed on the status of projects,
|
||||
|
|
@ -55,7 +55,7 @@ DETAILS:
|
|||
### Code explanation in the IDE
|
||||
|
||||
DETAILS:
|
||||
**Tier: GitLab.com and Self-managed:** Premium or Ultimate for a limited time. In the future, Premium with GitLab Duo Pro or Ultimate with [GitLab Duo Pro or Enterprise](../../subscriptions/subscription-add-ons.md). **GitLab Dedicated:** GitLab Duo Pro or Enterprise.
|
||||
**Tier: GitLab.com and Self-managed:** For a limited time, Premium or Ultimate. In the future, Premium with GitLab Duo Pro or Ultimate with [GitLab Duo Pro or Enterprise](../../subscriptions/subscription-add-ons.md). **GitLab Dedicated:** GitLab Duo Pro or Enterprise.
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
- Helps you understand the selected code by explaining it more clearly.
|
||||
|
|
@ -76,7 +76,7 @@ DETAILS:
|
|||
### GitLab Duo for the CLI
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment, Self-managed, GitLab Dedicated
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ DETAILS:
|
|||
### Merge commit message generation
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md)
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
- Helps you merge more quickly by generating meaningful commit messages.
|
||||
|
|
@ -97,7 +97,7 @@ DETAILS:
|
|||
### Root cause analysis
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md)
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123692) in GitLab 16.2 as an [experiment](../../policy/experiment-beta-support.md#experiment) on GitLab.com.
|
||||
|
|
@ -110,7 +110,7 @@ DETAILS:
|
|||
### Vulnerability explanation
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md)
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
- Helps you understand vulnerabilities, how they can be exploited, and how to fix them.
|
||||
|
|
@ -134,7 +134,7 @@ DETAILS:
|
|||
### Merge request summary
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate for a limited time. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Beta
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ DETAILS:
|
|||
### Issue description generation
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate for a limited time. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ DETAILS:
|
|||
### Discussion summary
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate for a limited time. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ DETAILS:
|
|||
### Code review summary
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate for a limited time. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
|
|
@ -195,7 +195,7 @@ DETAILS:
|
|||
### Vulnerability resolution
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md)
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
|
|
@ -206,7 +206,7 @@ DETAILS:
|
|||
### Product Analytics
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate for a limited time. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ Alternatively, you can use root cause analysis to [troubleshoot failed CI/CD job
|
|||
## Troubleshoot failed CI/CD jobs with root cause analysis
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md)
|
||||
**Tier:** For a limited time, Ultimate. In the future, Ultimate with [GitLab Duo Enterprise](../../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123692) in GitLab 16.2 as an [experiment](../../policy/experiment-beta-support.md#experiment) on GitLab.com.
|
||||
|
|
|
|||
|
|
@ -303,6 +303,31 @@ If you don't want to display achievements on your profile, you can opt out. To d
|
|||
1. In the **Main settings** section, clear the **Display achievements on your profile** checkbox.
|
||||
1. Select **Update profile settings**.
|
||||
|
||||
## Change visibility of specific achievements
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/161225) in GitLab 17.3.
|
||||
|
||||
If you don't want to display all achievements on your profile, you can change the visibility of specific achievements.
|
||||
|
||||
To hide one of your achievements, call the [`userAchievementsUpdate` GraphQL mutation](../../api/graphql/reference/index.md#mutationuserachievementsupdate).
|
||||
|
||||
```graphql
|
||||
mutation {
|
||||
userAchievementsUpdate(input: {
|
||||
userAchievementId: "gid://gitlab/Achievements::UserAchievement/<user achievement id>"
|
||||
showOnProfile: false
|
||||
}) {
|
||||
userAchievement {
|
||||
id
|
||||
showOnProfile
|
||||
}
|
||||
errors
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To show one of your achievements again, call the same mutation with the value `true` for the `showOnProfile` argument.
|
||||
|
||||
## Reorder achievements
|
||||
|
||||
By default, achievements on your profile are displayed in ascending order by awarded date.
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ Code generation is used when:
|
|||
- You write a comment and press <kbd>Enter</kbd>.
|
||||
- You enter an empty function or method.
|
||||
- The file you're editing has fewer than five lines of code.
|
||||
|
||||
Code generation requests take longer than code completion requests, but provide more accurate responses because:
|
||||
|
||||
- A larger LLM is used.
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ If you are not authenticated, then the list shows public projects only.
|
|||
To view projects you are a member of:
|
||||
|
||||
1. On the left sidebar, select **Search or go to**.
|
||||
1. Select **Your work**.
|
||||
1. Select **View all my projects**.
|
||||
|
||||
On the left sidebar, **Projects** is selected. On the list, on the **Yours** tab,
|
||||
all the projects you are a member of are displayed.
|
||||
|
|
@ -96,6 +96,12 @@ called `my-project` under your username, the project is created at `https://gitl
|
|||
|
||||
To view your personal projects:
|
||||
|
||||
1. On the left sidebar, select **Search or go to**.
|
||||
1. Select **View all my projects**.
|
||||
1. Select the **Personal** tab.
|
||||
|
||||
Or
|
||||
|
||||
1. On the left sidebar, select your avatar and then your username.
|
||||
1. On the left sidebar, select **Personal projects**.
|
||||
|
||||
|
|
@ -103,6 +109,12 @@ To view your personal projects:
|
|||
|
||||
To view projects you have [starred](#star-a-project):
|
||||
|
||||
1. On the left sidebar, select **Search or go to**.
|
||||
1. Select **View all my projects**.
|
||||
1. Select the **Starred** tab.
|
||||
|
||||
Or
|
||||
|
||||
1. On the left sidebar, select your avatar and then your username.
|
||||
1. On the left sidebar, select **Starred projects**.
|
||||
|
||||
|
|
@ -259,8 +271,7 @@ Active pipeline schedules of archived projects don't become read-only.
|
|||
Archived projects are:
|
||||
|
||||
- Labeled with an `archived` badge on the project page.
|
||||
- Listed on the group page in the **Inactive** tab.
|
||||
- Hidden from project lists in **Your Work** and **Explore**.
|
||||
- Listed in the **Inactive** tab on the group page, **Your work** page, and **Explore** page.
|
||||
- Read-only.
|
||||
|
||||
Prerequisites:
|
||||
|
|
@ -328,9 +339,7 @@ You can sort projects by:
|
|||
- Name
|
||||
- Created date
|
||||
- Updated date
|
||||
- Owner
|
||||
|
||||
You can also choose to hide or show archived projects.
|
||||
- Stars
|
||||
|
||||
### Filter projects by language
|
||||
|
||||
|
|
@ -343,10 +352,22 @@ You can filter projects by the programming language they use. To do this:
|
|||
1. Select either:
|
||||
- **View all your projects**, to filter your projects.
|
||||
- **Explore**, to filter all projects you can access.
|
||||
1. Above the list of projects, select **Search or filter results**.
|
||||
1. From the **Language** dropdown list, select the language you want to filter projects by.
|
||||
|
||||
A list of projects that use the selected language is displayed.
|
||||
|
||||
### View only projects you own
|
||||
|
||||
To view only the projects you are the owner of:
|
||||
|
||||
1. On the left sidebar, select **Search or go to**.
|
||||
1. Select either:
|
||||
- **View all your projects**, to filter your projects.
|
||||
- **Explore**, to filter all projects you can access.
|
||||
1. Above the list of projects, select **Search or filter results**.
|
||||
1. From the **Role** dropdown list, select **Owner**.
|
||||
|
||||
## Rename a repository
|
||||
|
||||
A project's repository name defines its URL and its place on the file disk
|
||||
|
|
|
|||
|
|
@ -391,6 +391,7 @@ module API
|
|||
mount ::API::Ml::Mlflow::Entrypoint
|
||||
end
|
||||
|
||||
mount ::API::Internal::Autoflow
|
||||
mount ::API::Internal::Base
|
||||
mount ::API::Internal::Coverage if Gitlab::Utils.to_boolean(ENV['COVERBAND_ENABLED'], default: false)
|
||||
mount ::API::Internal::Lfs
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module Helpers
|
||||
module KasHelpers
|
||||
def authenticate_gitlab_kas_request!
|
||||
render_api_error!('KAS JWT authentication invalid', 401) unless Gitlab::Kas.verify_api_request(headers)
|
||||
end
|
||||
|
||||
def gitaly_info(project)
|
||||
Gitlab::GitalyClient.connection_data(project.repository_storage)
|
||||
end
|
||||
|
||||
def gitaly_repository(project)
|
||||
project.repository.gitaly_repository.to_h
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -14,10 +14,6 @@ module API
|
|||
'k8s_api_proxy_requests_via_pat_access' => 'request_api_proxy_access_via_pat'
|
||||
}.freeze
|
||||
|
||||
def authenticate_gitlab_kas_request!
|
||||
render_api_error!('KAS JWT authentication invalid', 401) unless Gitlab::Kas.verify_api_request(headers)
|
||||
end
|
||||
|
||||
def agent_token
|
||||
cluster_agent_token_from_authorization_token
|
||||
end
|
||||
|
|
@ -28,14 +24,6 @@ module API
|
|||
end
|
||||
strong_memoize_attr :agent
|
||||
|
||||
def gitaly_info(project)
|
||||
Gitlab::GitalyClient.connection_data(project.repository_storage)
|
||||
end
|
||||
|
||||
def gitaly_repository(project)
|
||||
project.repository.gitaly_repository.to_h
|
||||
end
|
||||
|
||||
def check_agent_token
|
||||
unauthorized! unless agent_token
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
# AutoFlow Internal API
|
||||
module Internal
|
||||
class Autoflow < ::API::Base
|
||||
before do
|
||||
authenticate_gitlab_kas_request!
|
||||
end
|
||||
|
||||
helpers ::API::Helpers::KasHelpers
|
||||
|
||||
namespace 'internal' do
|
||||
namespace 'autoflow' do
|
||||
desc 'Retrieve repository information' do
|
||||
detail 'Retrieve repository information for the given project'
|
||||
end
|
||||
params do
|
||||
requires :id, type: String, desc: 'ID or full path of the project'
|
||||
end
|
||||
get '/repository_info', feature_category: :deployment_management, urgency: :low do
|
||||
project = find_project(params[:id])
|
||||
|
||||
not_found! unless project
|
||||
|
||||
status 200
|
||||
{
|
||||
project_id: project.id,
|
||||
gitaly_info: gitaly_info(project),
|
||||
gitaly_repository: gitaly_repository(project),
|
||||
default_branch: project.default_branch_or_main
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -8,6 +8,7 @@ module API
|
|||
authenticate_gitlab_kas_request!
|
||||
end
|
||||
|
||||
helpers ::API::Helpers::KasHelpers
|
||||
helpers ::API::Helpers::Kubernetes::AgentHelpers
|
||||
|
||||
namespace 'internal' do
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ module Gitlab
|
|||
STUB_CLASSES = {
|
||||
agent_tracker: Gitlab::Agent::AgentTracker::Rpc::AgentTracker::Stub,
|
||||
configuration_project: Gitlab::Agent::ConfigurationProject::Rpc::ConfigurationProject::Stub,
|
||||
autoflow: Gitlab::Agent::AutoFlow::Rpc::AutoFlow::Stub,
|
||||
notifications: Gitlab::Agent::Notifications::Rpc::Notifications::Stub
|
||||
}.freeze
|
||||
|
||||
|
|
@ -54,6 +55,34 @@ module Gitlab
|
|||
.git_push_event(request, metadata: metadata)
|
||||
end
|
||||
|
||||
def send_autoflow_event(project:, type:, id:, data:)
|
||||
# We only want to send events if AutoFlow is enabled and no-op otherwise
|
||||
return unless Feature.enabled?(:autoflow_enabled, project)
|
||||
|
||||
project_proto = Gitlab::Agent::Event::Project.new(
|
||||
id: project.id,
|
||||
full_path: project.full_path
|
||||
)
|
||||
request = Gitlab::Agent::AutoFlow::Rpc::CloudEventRequest.new(
|
||||
event: Gitlab::Agent::Event::CloudEvent.new(
|
||||
id: id,
|
||||
source: "GitLab",
|
||||
spec_version: "v1",
|
||||
type: type,
|
||||
attributes: {
|
||||
datacontenttype: Gitlab::Agent::Event::CloudEvent::CloudEventAttributeValue.new(
|
||||
ce_string: "application/json"
|
||||
)
|
||||
},
|
||||
text_data: data.to_json
|
||||
),
|
||||
flow_project: project_proto
|
||||
)
|
||||
|
||||
stub_for(:autoflow)
|
||||
.cloud_event(request, metadata: metadata)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def stub_for(service)
|
||||
|
|
|
|||
|
|
@ -15825,6 +15825,9 @@ msgstr ""
|
|||
msgid "CreateValueStreamForm|'%{name}' Value Stream created"
|
||||
msgstr ""
|
||||
|
||||
msgid "CreateValueStreamForm|'%{name}' Value Stream has been successfully created."
|
||||
msgstr ""
|
||||
|
||||
msgid "CreateValueStreamForm|'%{name}' Value Stream saved"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -57953,6 +57956,9 @@ msgstr ""
|
|||
msgid "UserMapping|Don't reassign"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Download the pre-filled CSV template."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Import details:"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -57974,6 +57980,9 @@ msgstr ""
|
|||
msgid "UserMapping|Notify again"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Once you select \"Reassign\", the processing will start and users will receive and email to accept the contribution reassignment. Once a users has accepted the reassignment, it cannot be undone. Check all data is correct before continuing."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Original user: %{source_name} (%{source_username})"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -58001,6 +58010,9 @@ msgstr ""
|
|||
msgid "UserMapping|Reassign placeholder to"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Reassign with CSV file"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Reassigned"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -58058,6 +58070,9 @@ msgstr ""
|
|||
msgid "UserMapping|Rejected"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Review and complete filling out the CSV file."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Review reassignment details"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -58094,6 +58109,12 @@ msgstr ""
|
|||
msgid "UserMapping|To learn more about reassignments, visit the docs (%{help_link}). If you don't recognize this request, report abuse (%{report_link})."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Upload reviewed and completed CSV file."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|Use a CSV file to reassign contributions from placeholder users to existing group members. This can be done in a few steps. %{linkStart}Learn more about matching users by CSV%{linkEnd}."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserMapping|You have approved the reassignment of contributions from %{strong_open}%{source_user_name} (@%{source_username})%{strong_close} on %{strong_open}%{source_hostname}%{strong_close} to yourself on the group %{strong_open}%{destination_group}%{strong_close}. Reassignment processing is in progress. You'll have access to the group soon."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,16 @@ import Vue, { nextTick } from 'vue';
|
|||
// eslint-disable-next-line no-restricted-imports
|
||||
import Vuex from 'vuex';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { GlTab, GlTabs } from '@gitlab/ui';
|
||||
import { GlTab, GlTabs, GlModal } from '@gitlab/ui';
|
||||
import { createAlert } from '~/alert';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
|
||||
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { stubComponent, RENDER_ALL_SLOTS_TEMPLATE } from 'helpers/stub_component';
|
||||
import PlaceholdersTabApp from '~/members/placeholders/components/app.vue';
|
||||
import PlaceholdersTable from '~/members/placeholders/components/placeholders_table.vue';
|
||||
import CsvUploadModal from '~/members/placeholders/components/csv_upload_modal.vue';
|
||||
import importSourceUsersQuery from '~/members/placeholders/graphql/queries/import_source_users.query.graphql';
|
||||
import { MEMBERS_TAB_TYPES } from '~/members/constants';
|
||||
import {
|
||||
|
|
@ -38,7 +39,10 @@ describe('PlaceholdersTabApp', () => {
|
|||
show: jest.fn(),
|
||||
};
|
||||
|
||||
const createComponent = ({ queryHandler = sourceUsersQueryHandler } = {}) => {
|
||||
const createComponent = ({
|
||||
queryHandler = sourceUsersQueryHandler,
|
||||
mountFn = shallowMountExtended,
|
||||
} = {}) => {
|
||||
store = new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBERS_TAB_TYPES.placeholder]: {
|
||||
|
|
@ -52,20 +56,31 @@ describe('PlaceholdersTabApp', () => {
|
|||
|
||||
mockApollo = createMockApollo([[importSourceUsersQuery, queryHandler]]);
|
||||
|
||||
wrapper = shallowMount(PlaceholdersTabApp, {
|
||||
wrapper = mountFn(PlaceholdersTabApp, {
|
||||
apolloProvider: mockApollo,
|
||||
store,
|
||||
provide: {
|
||||
group: mockGroup,
|
||||
reassignmentCsvDownloadPath: 'foo/bar',
|
||||
},
|
||||
mocks: { $toast },
|
||||
stubs: { GlTab },
|
||||
stubs: {
|
||||
GlTabs: stubComponent(GlTabs, {
|
||||
template: RENDER_ALL_SLOTS_TEMPLATE,
|
||||
}),
|
||||
GlTab,
|
||||
GlModal: stubComponent(GlModal, {
|
||||
template: RENDER_ALL_SLOTS_TEMPLATE,
|
||||
}),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const findTabs = () => wrapper.findComponent(GlTabs);
|
||||
const findTabAt = (index) => wrapper.findAllComponents(GlTab).at(index);
|
||||
const findPlaceholdersTable = () => wrapper.findComponent(PlaceholdersTable);
|
||||
const findReassignCsvButton = () => wrapper.findByTestId('reassign-csv-button');
|
||||
const findCsvModal = () => wrapper.findComponent(CsvUploadModal);
|
||||
|
||||
it('renders tabs', () => {
|
||||
createComponent();
|
||||
|
|
@ -250,4 +265,23 @@ describe('PlaceholdersTabApp', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('reassign CSV button', () => {
|
||||
it('renders the button and the modal', () => {
|
||||
createComponent();
|
||||
|
||||
expect(findReassignCsvButton().exists()).toBe(true);
|
||||
expect(findCsvModal().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('shows modal when button is clicked', async () => {
|
||||
createComponent({ mountFn: mountExtended });
|
||||
|
||||
findReassignCsvButton().trigger('click');
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(findCsvModal().findComponent(GlModal).isVisible()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import CsvUploadModal from '~/members/placeholders/components/csv_upload_modal.vue';
|
||||
|
||||
describe('CsvUploadModal', () => {
|
||||
let wrapper;
|
||||
|
||||
const defaultInjectedAttributes = {
|
||||
reassignmentCsvDownloadPath: 'foo/bar',
|
||||
};
|
||||
|
||||
const findDownloadLink = () => wrapper.findByTestId('csv-download-button');
|
||||
|
||||
function createComponent() {
|
||||
return shallowMountExtended(CsvUploadModal, {
|
||||
propsData: {
|
||||
modalId: 'csv-upload-modal',
|
||||
},
|
||||
provide: {
|
||||
...defaultInjectedAttributes,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = createComponent();
|
||||
});
|
||||
|
||||
it('has the CSV download button with the required attributes', () => {
|
||||
const downloadLink = findDownloadLink();
|
||||
|
||||
expect(downloadLink.exists()).toBe(true);
|
||||
expect(downloadLink.attributes('href')).toBe(
|
||||
defaultInjectedAttributes.reassignmentCsvDownloadPath,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -181,7 +181,7 @@ describe('WorkItemLinksForm', () => {
|
|||
expect(findInput().props('state')).toBe(false);
|
||||
});
|
||||
|
||||
it('creates child task in non confidential parent', async () => {
|
||||
it('creates child task in non confidential parent and closes the form', async () => {
|
||||
findInput().vm.$emit('input', 'Create task test');
|
||||
|
||||
findForm().vm.$emit('submit', {
|
||||
|
|
@ -201,6 +201,7 @@ describe('WorkItemLinksForm', () => {
|
|||
},
|
||||
});
|
||||
expect(wrapper.emitted('addChild')).toEqual([[]]);
|
||||
expect(wrapper.emitted('cancel')).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('creates child task in confidential parent', async () => {
|
||||
|
|
@ -244,7 +245,7 @@ describe('WorkItemLinksForm', () => {
|
|||
expect(findWorkItemTokenInput().exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('creates child issue in non confidential parent', async () => {
|
||||
it('creates child issue in non confidential parent and closes the form', async () => {
|
||||
findInput().vm.$emit('input', 'Create issue test');
|
||||
|
||||
findProjectSelector().vm.$emit('selectProject', projectData[0].fullPath);
|
||||
|
|
@ -267,6 +268,7 @@ describe('WorkItemLinksForm', () => {
|
|||
},
|
||||
});
|
||||
expect(wrapper.emitted('addChild')).toEqual([[]]);
|
||||
expect(wrapper.emitted('cancel')).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('creates child issue in confidential parent', async () => {
|
||||
|
|
@ -423,7 +425,7 @@ describe('WorkItemLinksForm', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('selects and adds children', async () => {
|
||||
it('selects, adds children and closes the form', async () => {
|
||||
await selectAvailableWorkItemTokens();
|
||||
|
||||
expect(findAddChildButton().text()).toBe('Add tasks');
|
||||
|
|
@ -435,7 +437,9 @@ describe('WorkItemLinksForm', () => {
|
|||
preventDefault: jest.fn(),
|
||||
});
|
||||
await waitForPromises();
|
||||
|
||||
expect(updateMutationResolver).toHaveBeenCalled();
|
||||
expect(wrapper.emitted('cancel')).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('shows validation error when non-confidential child items are being added to confidential parent', async () => {
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ RSpec.describe Gitlab::Kas::Client do
|
|||
allow(Gitlab::Kas).to receive(:enabled?).and_return(true)
|
||||
allow(Gitlab::Kas).to receive(:internal_url).and_return(kas_url)
|
||||
|
||||
expect(JSONWebToken::HMACToken).to receive(:new)
|
||||
allow(JSONWebToken::HMACToken).to receive(:new)
|
||||
.with(Gitlab::Kas.secret)
|
||||
.and_return(token)
|
||||
|
||||
expect(token).to receive(:issuer=).with(Settings.gitlab.host)
|
||||
expect(token).to receive(:audience=).with(described_class::JWT_AUDIENCE)
|
||||
allow(token).to receive(:issuer=).with(Settings.gitlab.host)
|
||||
allow(token).to receive(:audience=).with(described_class::JWT_AUDIENCE)
|
||||
end
|
||||
|
||||
describe '#get_connected_agents_by_agent_ids' do
|
||||
|
|
@ -110,6 +110,59 @@ RSpec.describe Gitlab::Kas::Client do
|
|||
it { expect(subject).to eq(agent_configurations) }
|
||||
end
|
||||
|
||||
describe '#send_autoflow_event' do
|
||||
subject { described_class.new.send_autoflow_event(project: project, type: 'any-type', id: 'any-id', data: { 'any-data-key': 'any-data-value' }) }
|
||||
|
||||
context 'when autoflow_enabled FF is disabled' do
|
||||
before do
|
||||
stub_feature_flags(autoflow_enabled: false)
|
||||
end
|
||||
|
||||
it { expect(subject).to be_nil }
|
||||
end
|
||||
|
||||
context 'when autoflow_enabled FF is enabled' do
|
||||
let(:stub) { instance_double(Gitlab::Agent::AutoFlow::Rpc::AutoFlow::Stub) }
|
||||
let(:request) { instance_double(Gitlab::Agent::AutoFlow::Rpc::CloudEventRequest) }
|
||||
let(:event_param) { instance_double(Gitlab::Agent::Event::CloudEvent) }
|
||||
let(:project_param) { instance_double(Gitlab::Agent::Event::Project) }
|
||||
let(:response) { double(Gitlab::Agent::AutoFlow::Rpc::CloudEventResponse) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(autoflow_enabled: true)
|
||||
|
||||
expect(Gitlab::Agent::AutoFlow::Rpc::AutoFlow::Stub).to receive(:new)
|
||||
.with('example.kas.internal', :this_channel_is_insecure, timeout: described_class::TIMEOUT)
|
||||
.and_return(stub)
|
||||
|
||||
expect(Gitlab::Agent::Event::Project).to receive(:new)
|
||||
.with(id: project.id, full_path: project.full_path)
|
||||
.and_return(project_param)
|
||||
|
||||
expect(Gitlab::Agent::Event::CloudEvent).to receive(:new)
|
||||
.with(id: 'any-id', source: "GitLab", spec_version: "v1", type: 'any-type',
|
||||
attributes: {
|
||||
datacontenttype: Gitlab::Agent::Event::CloudEvent::CloudEventAttributeValue.new(
|
||||
ce_string: "application/json"
|
||||
)
|
||||
},
|
||||
text_data: '{"any-data-key":"any-data-value"}'
|
||||
)
|
||||
.and_return(event_param)
|
||||
|
||||
expect(Gitlab::Agent::AutoFlow::Rpc::CloudEventRequest).to receive(:new)
|
||||
.with(event: event_param, flow_project: project_param)
|
||||
.and_return(request)
|
||||
|
||||
expect(stub).to receive(:cloud_event)
|
||||
.with(request, metadata: { 'authorization' => 'bearer test-token' })
|
||||
.and_return(response)
|
||||
end
|
||||
|
||||
it { expect(subject).to eq(response) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#send_git_push_event' do
|
||||
let(:stub) { instance_double(Gitlab::Agent::Notifications::Rpc::Notifications::Stub) }
|
||||
let(:request) { instance_double(Gitlab::Agent::Notifications::Rpc::GitPushEventRequest) }
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ RSpec.describe Ci::BuildTraceChunks::Fog do
|
|||
create(:ci_build_trace_chunk, :fog_with_data, chunk_index: 1, build: build)
|
||||
end
|
||||
|
||||
it 'deletes multiple data' do
|
||||
it 'deletes multiple data', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/456375' do
|
||||
files = connection.directories.new(key: bucket).files
|
||||
|
||||
expect(files.count).to eq(2)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe API::Internal::Autoflow, feature_category: :deployment_management do
|
||||
let(:jwt_auth_headers) do
|
||||
jwt_token = JWT.encode(
|
||||
{ 'iss' => Gitlab::Kas::JWT_ISSUER, 'aud' => Gitlab::Kas::JWT_AUDIENCE },
|
||||
Gitlab::Kas.secret,
|
||||
'HS256'
|
||||
)
|
||||
|
||||
{ Gitlab::Kas::INTERNAL_API_KAS_REQUEST_HEADER => jwt_token }
|
||||
end
|
||||
|
||||
let(:jwt_secret) { SecureRandom.random_bytes(Gitlab::Kas::SECRET_LENGTH) }
|
||||
|
||||
before do
|
||||
allow(Gitlab::Kas).to receive(:secret).and_return(jwt_secret)
|
||||
end
|
||||
|
||||
shared_examples 'authorization' do
|
||||
context 'when not authenticated' do
|
||||
it 'returns 401' do
|
||||
send_request(headers: { Gitlab::Kas::INTERNAL_API_KAS_REQUEST_HEADER => '' })
|
||||
|
||||
expect(response).to have_gitlab_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /internal/autoflow/repository_info' do
|
||||
def send_request(headers: {}, params: {})
|
||||
get api('/internal/autoflow/repository_info'), params: params, headers: headers.reverse_merge(jwt_auth_headers)
|
||||
end
|
||||
|
||||
def expect_success_response
|
||||
expect(response).to have_gitlab_http_status(:success)
|
||||
|
||||
expect(json_response).to match(
|
||||
a_hash_including(
|
||||
'project_id' => project.id,
|
||||
'gitaly_info' => a_hash_including(
|
||||
'address' => match(/\.socket$/),
|
||||
'token' => 'secret'
|
||||
),
|
||||
'gitaly_repository' => a_hash_including(
|
||||
'storage_name' => project.repository_storage,
|
||||
'relative_path' => "#{project.disk_path}.git",
|
||||
'gl_repository' => "project-#{project.id}",
|
||||
'gl_project_path' => project.full_path
|
||||
),
|
||||
'default_branch' => project.default_branch_or_main
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
include_examples 'authorization'
|
||||
|
||||
context 'when project exists' do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
it 'returns expected data for numerical project id', :aggregate_failures do
|
||||
send_request(params: { id: project.id })
|
||||
|
||||
expect_success_response
|
||||
end
|
||||
|
||||
it 'returns expected data for project full path', :aggregate_failures do
|
||||
send_request(params: { id: project.full_path })
|
||||
|
||||
expect_success_response
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project does not exists' do
|
||||
it 'returns expected data', :aggregate_failures do
|
||||
send_request(params: { id: non_existing_record_id })
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue