Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-09-17 03:07:58 +00:00
parent 190e96db65
commit f8d256d470
42 changed files with 907 additions and 546 deletions

View File

@ -37,7 +37,7 @@ export default {
:use-link="false"
class="gl-leading-0"
/>
<span class="mw-70p gl-inline-block gl-truncate gl-pl-3" :title="name">
<span class="gl-inline-block gl-max-w-7/10 gl-truncate gl-pl-3" :title="name">
{{ name }}
</span>
</span>

View File

@ -49,4 +49,12 @@ export function initShow() {
import(/* webpackChunkName: 'design_management' */ '~/design_management')
.then((module) => module.default())
.catch(() => {});
if (gon.features.workItemsViewPreference) {
import(/* webpackChunkName: 'work_items_feedback' */ '~/work_items_feedback')
.then(({ initWorkItemsFeedback }) => {
initWorkItemsFeedback();
})
.catch({});
}
}

View File

@ -116,7 +116,7 @@ export default {
return this.tag.layers ? n__('%d layer', '%d layers', this.tag.layers) : '';
},
mobileClasses() {
return this.isMobile ? 'mw-s' : '';
return this.isMobile ? 'gl-max-w-20' : '';
},
shortDigest() {
// remove sha256: from the string, and show only the first 7 char

View File

@ -1,3 +1,11 @@
import { initWorkItemsRoot } from '~/work_items';
initWorkItemsRoot();
if (gon.features.work_items_view_preference) {
import('~/work_items_feedback')
.then(({ initWorkItemsFeedback }) => {
initWorkItemsFeedback();
})
.catch({});
}

View File

@ -198,7 +198,7 @@ export default {
v-show="dragging && !enableDragBehavior"
class="card upload-dropzone-border upload-dropzone-overlay gl-absolute gl-flex gl-h-full gl-w-full gl-items-center gl-justify-center gl-p-4"
>
<div v-show="!isDragDataValid" class="mw-50 gl-text-center">
<div v-show="!isDragDataValid" class="gl-max-w-1/2 gl-text-center">
<slot name="invalid-drag-data-slot">
<h3 :class="{ 'gl-inline gl-text-base': !displayAsCard }">
{{ __('Oh no!') }}
@ -210,7 +210,7 @@ export default {
}}</span>
</slot>
</div>
<div v-show="isDragDataValid" class="mw-50 gl-text-center">
<div v-show="isDragDataValid" class="gl-max-w-1/2 gl-text-center">
<slot name="valid-drag-data-slot">
<h3 :class="{ 'gl-inline gl-text-base': !displayAsCard }">
{{ __('Incoming!') }}

View File

@ -81,6 +81,14 @@ export const initWorkItemsRoot = ({ workItemType, workspaceType } = {}) => {
},
});
if (gon.features.workItemsViewPreference) {
import(/* webpackChunkName: 'work_items_feedback' */ '~/work_items_feedback')
.then(({ initWorkItemsFeedback }) => {
initWorkItemsFeedback();
})
.catch({});
}
return new Vue({
el,
name: 'WorkItemsRoot',

View File

@ -10,7 +10,6 @@ Vue.use(VueRouter);
export function createRouter({
fullPath,
workItemType = 'work_items',
workspaceType = WORKSPACE_PROJECT,
defaultBranch,
isGroup,
@ -24,6 +23,6 @@ export function createRouter({
return new VueRouter({
routes: routes(isGroup),
mode: 'history',
base: joinPaths(gon?.relative_url_root, workspacePath, fullPath, '-', workItemType),
base: joinPaths(gon?.relative_url_root, workspacePath, fullPath, '-'),
});
}

View File

@ -5,7 +5,7 @@ import { ROUTES } from '../constants';
function getRoutes(isGroup) {
const routes = [
{
path: '/:iid',
path: '/:type(issues|epics|work_items)/:iid',
name: ROUTES.workItem,
component: () => import('../pages/work_item_root.vue'),
props: true,
@ -27,7 +27,7 @@ function getRoutes(isGroup) {
if (isGroup) {
routes.unshift({
path: '/',
path: '/:type(issues|epics|work_items)',
name: ROUTES.index,
component: WorkItemList,
});
@ -35,7 +35,7 @@ function getRoutes(isGroup) {
if (gon.features?.workItemsAlpha) {
routes.unshift({
path: '/new',
path: '/:type(issues|epics|work_items)/new',
name: ROUTES.new,
component: () => import('../pages/create_work_item.vue'),
});

View File

@ -0,0 +1,104 @@
<script>
import { GlBadge, GlPopover, GlLink, GlToggle } from '@gitlab/ui';
import { uniqueId } from 'lodash';
import { createAlert } from '~/alert';
import { __ } from '~/locale';
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import getUserPreferences from '../graphql/user_preferences.query.graphql';
import setUseWorkItemsView from '../graphql/set_use_work_items_view.mutation.graphql';
export default {
name: 'WorkItemToggle',
components: {
GlBadge,
GlPopover,
GlLink,
GlToggle,
},
data() {
return {
currentUser: {
userPreferences: {},
},
feedbackIssue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/463598',
};
},
apollo: {
currentUser: {
query: getUserPreferences,
},
},
computed: {
onOff() {
return this.currentUser.userPreferences.useWorkItemsView ? __('On') : __('Off');
},
},
methods: {
setWorkItemsView(val) {
this.$apollo
.mutate({
mutation: setUseWorkItemsView,
variables: {
useWorkItemsView: val,
},
update: (cache, { data: { userPreferencesUpdate } }) => {
cache.modify({
id: cache.identify(this.currentUser),
fields: {
userPreferences(existingPreferences = {}) {
return {
...existingPreferences,
...userPreferencesUpdate.userPreferences,
};
},
},
});
window.location.reload();
},
})
.catch((error) => {
createAlert({
message: __('Something went wrong. Please try again.'),
});
Sentry.captureException(error);
});
},
},
badgeId: uniqueId(),
i18n: {
previewWorkItems: __(
'Preview the new issues experience, with real time updates and refreshed design. Some features are not yet supported, see feedback issue for details.',
),
leaveFeedback: __('Leave feedback'),
newIssueLook: __('New issue look'),
},
};
</script>
<template>
<div class="gl-flex gl-content-center">
<gl-badge :id="$options.badgeId" variant="info" icon="information-o" href="#"
>{{ $options.i18n.newIssueLook }}: {{ onOff }}</gl-badge
>
<gl-popover
:target="$options.badgeId"
data-testid="work-item-feedback-popover"
triggers="focus click manual blur"
placement="bottom"
show-close-button
:title="$options.i18n.newIssueLook"
>
<gl-toggle
:value="currentUser.userPreferences.useWorkItemsView"
:label="onOff"
label-position="left"
@change="setWorkItemsView"
/>
<div class="gl-pt-2">
{{ $options.i18n.previewWorkItems }}
</div>
<gl-link target="_blank" :href="feedbackIssue">{{ $options.i18n.leaveFeedback }}</gl-link>
</gl-popover>
</div>
</template>

View File

@ -0,0 +1,7 @@
mutation setUseWorkItemsView($useWorkItemsView: Boolean) {
userPreferencesUpdate(input: { useWorkItemsView: $useWorkItemsView }) {
userPreferences {
useWorkItemsView
}
}
}

View File

@ -0,0 +1,8 @@
query getUserPreferences {
currentUser {
id
userPreferences {
useWorkItemsView
}
}
}

View File

@ -2,6 +2,7 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { apolloProvider } from '~/graphql_shared/issuable_client';
import WorkItemFeedback from './components/work_item_feedback.vue';
import WorkItemViewToggle from './components/work_item_view_toggle.vue';
Vue.use(VueApollo);
@ -12,7 +13,7 @@ export const initWorkItemsFeedback = ({
content,
expiry,
featureName,
}) => {
} = {}) => {
if (expiry) {
const expiryDate = new Date(expiry);
if (Date.now() > expiryDate) {
@ -34,7 +35,7 @@ export const initWorkItemsFeedback = ({
featureName,
},
render(h) {
return h(WorkItemFeedback);
return h(feedbackIssue ? WorkItemFeedback : WorkItemViewToggle);
},
});
};

View File

@ -364,7 +364,6 @@ li.note {
.h-32-px { height: 32px;}
.mw-6em { max-width: 6em; }
.mw-70p { max-width: 70%; }
// By default flex items don't shrink below their minimum content size.
// To change this, these clases set a min-width or min-height

View File

@ -67,6 +67,7 @@ class Projects::IssuesController < Projects::ApplicationController
push_force_frontend_feature_flag(:work_items_alpha, project&.work_items_alpha_feature_flag_enabled?)
push_frontend_feature_flag(:epic_widget_edit_confirmation, project)
push_frontend_feature_flag(:namespace_level_work_items, project&.group)
push_frontend_feature_flag(:work_items_view_preference, current_user)
end
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
@ -140,6 +141,15 @@ class Projects::IssuesController < Projects::ApplicationController
respond_with(@issue)
end
def show
return super unless show_work_item? && request.format.html?
@right_sidebar = false
@work_item = issue.becomes(::WorkItem) # rubocop:disable Cop/AvoidBecomes -- We need the instance to be a work item
render 'projects/work_items/show'
end
def edit
respond_with(@issue)
end
@ -390,6 +400,10 @@ class Projects::IssuesController < Projects::ApplicationController
private
def show_work_item?
Feature.enabled?(:work_items_view_preference, current_user) && current_user&.user_preference&.use_work_items_view
end
def work_item_redirect_except_actions
ISSUES_EXCEPT_ACTIONS
end

View File

@ -55,7 +55,7 @@ class BulkImport < ApplicationRecord
# rubocop:disable Style/SymbolProc
after_transition any => [:finished, :failed, :timeout] do |bulk_import|
bulk_import.update_has_failures
bulk_import.notify_owners_of_completion
bulk_import.send_completion_notification
end
# rubocop:enable Style/SymbolProc
@ -103,24 +103,12 @@ class BulkImport < ApplicationRecord
finished? || failed? || timeout? || canceled?
end
def notify_owners_of_completion
users_to_notify = parent_group_entity&.group&.owners
return if users_to_notify.blank?
users_to_notify.each do |owner|
run_after_commit do
Notify.bulk_import_complete(owner.id, id).deliver_later
end
def send_completion_notification
run_after_commit do
Notify.bulk_import_complete(user.id, id).deliver_later
end
end
# Finds the root group entity of the BulkImport's entity tree.
# @return [BulkImports::Entity, nil]
def parent_group_entity
entities.group_entity.where(parent: nil).first
end
def destination_group_roots
entities.where(parent: nil).filter_map do |entity|
entity.group || entity.project

View File

@ -67,6 +67,7 @@ class ProcessCommitWorker
Gitlab::ClosingIssueExtractor
.new(project, user)
.closed_by_message(commit.safe_message)
.reject { |issue| issue.is_a?(Issue) && !issue.autoclose_by_merged_closing_merge_request? }
end
def update_issue_metrics(commit, author)

View File

@ -0,0 +1,9 @@
---
name: work_items_view_preference
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/461855
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165085
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/482931
milestone: '17.4'
group: group::project management
type: beta
default_enabled: false

View File

@ -504,4 +504,4 @@ To resolve this, you can update the Git [server hooks](../server_hooks.md) for G
### Successful restore with repositories showing as empty when using `fapolicyd`
When using `fapolicyd` for increased security, GitLab can report that a restore was successful but repositories show as empty. For more troubleshooting help, see
[Gitaly Troubleshooting documentation](../../administration/gitaly/troubleshooting.md#repositories-are-shown-as-empty-after-a-gitlab-restore).
[Gitaly Troubleshooting documentation](../gitaly/troubleshooting.md#repositories-are-shown-as-empty-after-a-gitlab-restore).

View File

@ -0,0 +1,163 @@
---
stage: Plan
group: Project Management
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Group Markdown uploads API
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
Markdown uploads are [files uploaded to a group](../security/user_file_uploads.md)
that can be referenced in Markdown text in an epic or a wiki page.
## List uploads
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2.
Get all uploads of the group sorted by `created_at` in descending order.
You must have at least the Maintainer role to use this endpoint.
```plaintext
GET /groups/:id/uploads
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads"
```
Example response:
```json
[
{
"id": 1,
"size": 1024,
"filename": "image.png",
"created_at":"2024-06-20T15:53:03.067Z",
"uploaded_by": {
"id": 18,
"name" : "Alexandra Bashirian",
"username" : "eileen.lowe"
}
},
{
"id": 2,
"size": 512,
"filename": "other-image.png",
"created_at":"2024-06-19T15:53:03.067Z",
"uploaded_by": null
}
]
```
## Download an uploaded file by ID
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2.
You must have at least the Maintainer role to use this endpoint.
```plaintext
GET /groups/:id/uploads/:upload_id
```
Supported attributes:
| Attribute | Type | Required | Description |
|-------------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
| `upload_id` | integer | Yes | The ID of the upload. |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads/1"
```
If successful, returns [`200`](rest/index.md#status-codes) and the uploaded file in the response body.
## Download an uploaded file by secret and filename
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164441) in GitLab 17.4.
You must have at least the Guest role to use this endpoint.
```plaintext
GET /groups/:id/uploads/:secret/:filename
```
Supported attributes:
| Attribute | Type | Required | Description |
|-------------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
| `secret` | string | Yes | The 32-character secret of the upload. |
| `filename` | string | Yes | The filename of the upload. |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads/648d97c6eef5fc5df8d1004565b3ee5a/sample.jpg"
```
If successful, returns [`200`](rest/index.md#status-codes) and the uploaded file in the response body.
## Delete an uploaded file by ID
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2.
You must have at least the Maintainer role to use this endpoint.
```plaintext
DELETE /groups/:id/uploads/:upload_id
```
Supported attributes:
| Attribute | Type | Required | Description |
|-------------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
| `upload_id` | integer | Yes | The ID of the upload. |
Example request:
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads/1"
```
If successful, returns [`204`](rest/index.md#status-codes) status code without any response body.
## Delete an uploaded file by secret and filename
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164441) in GitLab 17.4.
You must have at least the Maintainer role to use this endpoint.
```plaintext
DELETE /groups/:id/uploads/:secret/:filename
```
Supported attributes:
| Attribute | Type | Required | Description |
|-------------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
| `secret` | string | Yes | The 32-character secret of the upload. |
| `filename` | string | Yes | The filename of the upload. |
Example request:
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads/648d97c6eef5fc5df8d1004565b3ee5a/sample.jpg"
```
If successful, returns [`204`](rest/index.md#status-codes) status code without any response body.

View File

@ -1613,159 +1613,6 @@ Example response:
]
```
## Markdown uploads
Markdown uploads are files uploaded to a group that can be referenced in Markdown text in an epic or wiki page.
### List uploads
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2.
Get all uploads of the group sorted by `created_at` in descending order.
You must have at least the Maintainer role to use this endpoint.
```plaintext
GET /groups/:id/uploads
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads"
```
Returned object:
```json
[
{
"id": 1,
"size": 1024,
"filename": "image.png",
"created_at":"2024-06-20T15:53:03.067Z",
"uploaded_by": {
"id": 18,
"name" : "Alexandra Bashirian",
"username" : "eileen.lowe"
}
},
{
"id": 2,
"size": 512,
"filename": "other-image.png",
"created_at":"2024-06-19T15:53:03.067Z",
"uploaded_by": null
}
]
```
### Download an uploaded file by ID
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2.
You must have at least the Maintainer role to use this endpoint.
```plaintext
GET /groups/:id/uploads/:upload_id
```
Supported attributes:
| Attribute | Type | Required | Description |
|-------------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
| `upload_id` | integer | Yes | The ID of the upload. |
If successful, returns [`200`](rest/index.md#status-codes) and the uploaded file in the response body.
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads/1"
```
### Download an uploaded file by secret and filename
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164441) in GitLab 17.4.
You must have at least the Guest role to use this endpoint.
```plaintext
GET /groups/:id/uploads/:secret/:filename
```
Supported attributes:
| Attribute | Type | Required | Description |
|-------------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
| `secret` | string | Yes | The 32-character secret of the upload. |
| `filename` | string | Yes | The filename of the upload. |
If successful, returns [`200`](rest/index.md#status-codes) and the uploaded file in the response body.
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads/648d97c6eef5fc5df8d1004565b3ee5a/sample.jpg"
```
### Delete an uploaded file by ID
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2.
You must have at least the Maintainer role to use this endpoint.
```plaintext
DELETE /groups/:id/uploads/:upload_id
```
Supported attributes:
| Attribute | Type | Required | Description |
|-------------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
| `upload_id` | integer | Yes | The ID of the upload. |
If successful, returns [`204`](rest/index.md#status-codes) status code without any response body.
Example request:
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads/1"
```
### Delete an uploaded file by secret and filename
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164441) in GitLab 17.4.
You must have at least the Maintainer role to use this endpoint.
```plaintext
DELETE /groups/:id/uploads/:secret/:filename
```
Supported attributes:
| Attribute | Type | Required | Description |
|-------------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding). |
| `secret` | string | Yes | The 32-character secret of the upload. |
| `filename` | string | Yes | The filename of the upload. |
If successful, returns [`204`](rest/index.md#status-codes) status code without any response body.
Example request:
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/uploads/648d97c6eef5fc5df8d1004565b3ee5a/sample.jpg"
```
## Group audit events
DETAILS:

View File

@ -58,39 +58,39 @@ are returned.
GET /projects
```
| Attribute | Type | Required | Description |
|------------------------------------------------|----------|----------|-------------|
| `archived` | boolean | No | Limit by archived status. |
| `id_after` | integer | No | Limit results to projects with IDs greater than the specified ID. |
| `id_before` | integer | No | Limit results to projects with IDs less than the specified ID. |
| `imported` | boolean | No | Limit results to projects which were imported from external systems by current user. |
| `include_hidden` | boolean | No | Include hidden projects. _(administrators only)_ Premium and Ultimate only. |
| `include_pending_delete` | boolean | No | Include projects pending deletion. _(administrators only)_ |
| `last_activity_after` | datetime | No | Limit results to projects with last activity after specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `last_activity_before` | datetime | No | Limit results to projects with last activity before specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `membership` | boolean | No | Limit by projects that the current user is a member of. |
| `min_access_level` | integer | No | Limit by current user minimal [role (`access_level`)](members.md#roles). |
| `order_by` | string | No | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, `star_count`, `last_activity_at`, or `similarity` fields. `repository_size`, `storage_size`, `packages_size` or `wiki_size` fields are only allowed for administrators. `similarity` is only available when searching and is limited to projects that the current user is a member of. Default is `created_at`. |
| `owned` | boolean | No | Limit by projects explicitly owned by the current user. |
| `repository_checksum_failed` | boolean | No | Limit projects where the repository checksum calculation has failed. Premium and Ultimate only. |
| `repository_storage` | string | No | Limit results to projects stored on `repository_storage`. _(administrators only)_ |
| `search_namespaces` | boolean | No | Include ancestor namespaces when matching search criteria. Default is `false`. |
| `search` | string | No | Return list of projects matching the search criteria. |
| `simple` | boolean | No | Return only limited fields for each project. This operation is a no-op without authentication where only simple fields are returned. |
| `sort` | string | No | Return projects sorted in `asc` or `desc` order. Default is `desc`. |
| `starred` | boolean | No | Limit by projects starred by the current user. |
| `statistics` | boolean | No | Include project statistics. Available only to users with at least the Reporter role. |
| `topic_id` | integer | No | Limit results to projects with the assigned topic given by the topic ID. |
| `topic` | string | No | Comma-separated topic names. Limit results to projects that match all of given topics. See `topics` attribute. |
| `updated_after` | datetime | No | Limit results to projects last updated after the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393979) in GitLab 15.10. For this filter to work, you must also provide `updated_at` as the `order_by` attribute. |
| `updated_before` | datetime | No | Limit results to projects last updated before the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393979) in GitLab 15.10. For this filter to work, you must also provide `updated_at` as the `order_by` attribute. |
| `visibility` | string | No | Limit by visibility `public`, `internal`, or `private`. |
| `wiki_checksum_failed` | boolean | No | Limit projects where the wiki checksum calculation has failed. Premium and Ultimate only. |
| `with_custom_attributes` | boolean | No | Include [custom attributes](custom_attributes.md) in response. _(administrator only)_ |
| `with_issues_enabled` | boolean | No | Limit by enabled issues feature. |
| `with_merge_requests_enabled` | boolean | No | Limit by enabled merge requests feature. |
| `with_programming_language` | string | No | Limit by projects which use the given programming language. |
| `marked_for_deletion_on` | date | No | Filter by date when project was marked for deletion. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/463939) in GitLab 17.1. Premium and Ultimate only. |
| Attribute | Type | Required | Description |
|:------------------------------|:---------|:---------|:------------|
| `archived` | boolean | No | Limit by archived status. |
| `id_after` | integer | No | Limit results to projects with IDs greater than the specified ID. |
| `id_before` | integer | No | Limit results to projects with IDs less than the specified ID. |
| `imported` | boolean | No | Limit results to projects which were imported from external systems by current user. |
| `include_hidden` | boolean | No | Include hidden projects. _(administrators only)_ Premium and Ultimate only. |
| `include_pending_delete` | boolean | No | Include projects pending deletion. _(administrators only)_ |
| `last_activity_after` | datetime | No | Limit results to projects with last activity after specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `last_activity_before` | datetime | No | Limit results to projects with last activity before specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `membership` | boolean | No | Limit by projects that the current user is a member of. |
| `min_access_level` | integer | No | Limit by current user minimal [role (`access_level`)](members.md#roles). |
| `order_by` | string | No | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, `star_count`, `last_activity_at`, or `similarity` fields. `repository_size`, `storage_size`, `packages_size` or `wiki_size` fields are only allowed for administrators. `similarity` is only available when searching and is limited to projects that the current user is a member of. Default is `created_at`. |
| `owned` | boolean | No | Limit by projects explicitly owned by the current user. |
| `repository_checksum_failed` | boolean | No | Limit projects where the repository checksum calculation has failed. Premium and Ultimate only. |
| `repository_storage` | string | No | Limit results to projects stored on `repository_storage`. _(administrators only)_ |
| `search_namespaces` | boolean | No | Include ancestor namespaces when matching search criteria. Default is `false`. |
| `search` | string | No | Return list of projects matching the search criteria. |
| `simple` | boolean | No | Return only limited fields for each project. This operation is a no-op without authentication where only simple fields are returned. |
| `sort` | string | No | Return projects sorted in `asc` or `desc` order. Default is `desc`. |
| `starred` | boolean | No | Limit by projects starred by the current user. |
| `statistics` | boolean | No | Include project statistics. Available only to users with at least the Reporter role. |
| `topic_id` | integer | No | Limit results to projects with the assigned topic given by the topic ID. |
| `topic` | string | No | Comma-separated topic names. Limit results to projects that match all of given topics. See `topics` attribute. |
| `updated_after` | datetime | No | Limit results to projects last updated after the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393979) in GitLab 15.10. For this filter to work, you must also provide `updated_at` as the `order_by` attribute. |
| `updated_before` | datetime | No | Limit results to projects last updated before the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393979) in GitLab 15.10. For this filter to work, you must also provide `updated_at` as the `order_by` attribute. |
| `visibility` | string | No | Limit by visibility `public`, `internal`, or `private`. |
| `wiki_checksum_failed` | boolean | No | Limit projects where the wiki checksum calculation has failed. Premium and Ultimate only. |
| `with_custom_attributes` | boolean | No | Include [custom attributes](custom_attributes.md) in response. _(administrator only)_ |
| `with_issues_enabled` | boolean | No | Limit by enabled issues feature. |
| `with_merge_requests_enabled` | boolean | No | Limit by enabled merge requests feature. |
| `with_programming_language` | string | No | Limit by projects which use the given programming language. |
| `marked_for_deletion_on` | date | No | Filter by date when project was marked for deletion. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/463939) in GitLab 17.1. Premium and Ultimate only. |
This endpoint supports [keyset pagination](rest/index.md#keyset-based-pagination)
for selected `order_by` options.
@ -336,7 +336,7 @@ GET /users/:user_id/projects
```
| Attribute | Type | Required | Description |
|-------------------------------|----------|----------|-------------|
|:------------------------------|:---------|:---------|:------------|
| `user_id` | string | Yes | The ID or username of the user. |
| `archived` | boolean | No | Limit by archived status. |
| `id_after` | integer | No | Limit results to projects with IDs greater than the specified ID. |
@ -618,7 +618,7 @@ GET /users/:user_id/contributed_projects
```
| Attribute | Type | Required | Description |
|------------|---------|----------|-------------|
|:-----------|:--------|:---------|:------------|
| `user_id` | string | Yes | The ID or username of the user. |
| `order_by` | string | No | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, `star_count`, or `last_activity_at` fields. Default is `created_at`. |
| `simple` | boolean | No | Return only limited fields for each project. Without authentication, this operation is a no-op; only simple fields are returned. |
@ -863,7 +863,7 @@ GET /users/:user_id/starred_projects
```
| Attribute | Type | Required | Description |
|-------------------------------|----------|----------|-------------|
|:------------------------------|:---------|:---------|:------------|
| `user_id` | string | Yes | The ID or username of the user. |
| `archived` | boolean | No | Limit by archived status. |
| `membership` | boolean | No | Limit by projects that the current user is a member of. |
@ -1121,7 +1121,7 @@ GET /projects/:id
```
| Attribute | Type | Required | Description |
|--------------------------|-------------------|----------|-------------|
|:-------------------------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `license` | boolean | No | Include project license data. |
| `statistics` | boolean | No | Include project statistics. Available only to users with at least the Reporter role. |
@ -1395,7 +1395,7 @@ GET /projects/:id/users
```
| Attribute | Type | Required | Description |
|--------------|-------------------|----------|-------------|
|:-------------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `search` | string | No | Search for specific users. |
| `skip_users` | integer array | No | Filter out users with the specified IDs. |
@ -1430,7 +1430,7 @@ GET /projects/:id/groups
```
| Attribute | Type | Required | Description |
|---------------------------|-------------------|----------|-------------|
|:--------------------------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `search` | string | No | Search for specific groups. |
| `shared_min_access_level` | integer | No | Limit to shared groups with at least this [role (`access_level`)](members.md#roles). |
@ -1468,7 +1468,7 @@ GET /projects/:id/share_locations
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `search` | string | No | Search for specific groups. |
@ -1493,10 +1493,6 @@ GET /projects/:id/share_locations
]
```
## Get project events
Refer to the [Events API documentation](events.md#list-a-projects-visible-events).
## Create project
> - `operations_access_level` [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/385798) in GitLab 16.0.
@ -1525,7 +1521,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your-token>" \
General project attributes:
| Attribute | Type | Required | Description |
|----------------------------------------------------|---------|--------------------------------|-------------|
|:---------------------------------------------------|:--------|:-------------------------------|:------------|
| `name` | string | Yes (if `path` isn't provided) | The name of the new project. Equals path if not provided. |
| `path` | string | Yes (if `name` isn't provided) | Repository name for new project. Generated based on name if not provided (generated as lowercase with dashes). The path must not start or end with a special character and must not contain consecutive special characters. |
| `allow_merge_on_skipped_pipeline` | boolean | No | Set whether or not merge requests can be merged with skipped jobs. |
@ -1592,7 +1588,7 @@ settings with access control options can be one of:
- `enabled`: Enable and set the feature to **Everyone with access**.
| Attribute | Type | Required | Description |
|----------------------------------------|--------|----------|-------------|
|:---------------------------------------|:-------|:---------|:------------|
| `analytics_access_level` | string | No | Set visibility of [analytics](../user/analytics/index.md). |
| `builds_access_level` | string | No | Set visibility of [pipelines](../ci/pipelines/settings.md#change-which-users-can-view-your-pipelines). |
| `container_registry_access_level` | string | No | Set visibility of [container registry](../user/packages/container_registry/index.md#change-visibility-of-the-container-registry). |
@ -1631,7 +1627,7 @@ POST /projects/user/:user_id
General project attributes:
| Attribute | Type | Required | Description |
|----------------------------------------------------|---------|----------|-------------|
|:---------------------------------------------------|:--------|:---------|:------------|
| `name` | string | Yes | The name of the new project. |
| `user_id` | integer | Yes | The user ID of the project owner. |
| `allow_merge_on_skipped_pipeline` | boolean | No | Set whether or not merge requests can be merged with skipped jobs. |
@ -1700,7 +1696,7 @@ settings with access control options can be one of:
- `enabled`: Enable and set the feature to **Everyone with access**.
| Attribute | Type | Required | Description |
|----------------------------------------|--------|----------|-------------|
|:---------------------------------------|:-------|:---------|:------------|
| `analytics_access_level` | string | No | Set visibility of [analytics](../user/analytics/index.md). |
| `builds_access_level` | string | No | Set visibility of [pipelines](../ci/pipelines/settings.md#change-which-users-can-view-your-pipelines). |
| `container_registry_access_level` | string | No | Set visibility of [container registry](../user/packages/container_registry/index.md#change-visibility-of-the-container-registry). |
@ -1748,7 +1744,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your-token>" \
General project attributes:
| Attribute | Type | Required | Description |
|----------------------------------------------------|-------------------|----------|-------------|
|:---------------------------------------------------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `allow_merge_on_skipped_pipeline` | boolean | No | Set whether or not merge requests can be merged with skipped jobs. |
| `allow_pipeline_trigger_approve_deployment` | boolean | No | Set whether or not a pipeline triggerer is allowed to approve deployments. Premium and Ultimate only. |
@ -1768,8 +1764,8 @@ General project attributes:
| `ci_allow_fork_pipelines_to_run_in_parent_project` | boolean | No | Enable or disable [running pipelines in the parent project for merge requests from forks](../ci/pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project). _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/325189) in GitLab 15.3.)_ |
| `ci_separated_caches` | boolean | No | Set whether or not caches should be [separated](../ci/caching/index.md#cache-key-names) by branch protection status. |
| `ci_restrict_pipeline_cancellation_role` | string | No | Set the [role required to cancel a pipeline or job](../ci/pipelines/settings.md#restrict-roles-that-can-cancel-pipelines-or-jobs). One of `developer`, `maintainer`, or `no_one`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/429921) in GitLab 16.8. Premium and Ultimate only. |
| `ci_pipeline_variables_minimum_override_role` | string | No | When `restrict_user_defined_variables` is enabled, you can specify which role can override variables. One of `owner`, `maintainer`, `developer` or `no_one_allowed`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/440338) in GitLab 17.1. |
| `ci_push_repository_for_job_token_allowed` | boolean | No | Enable or disable the ability to push to the project repository using job token. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/389060) in GitLab 17.2. |
| `ci_pipeline_variables_minimum_override_role` | string | No | When `restrict_user_defined_variables` is enabled, you can specify which role can override variables. One of `owner`, `maintainer`, `developer` or `no_one_allowed`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/440338) in GitLab 17.1. |
| `ci_push_repository_for_job_token_allowed` | boolean | No | Enable or disable the ability to push to the project repository using job token. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/389060) in GitLab 17.2. |
| `container_expiration_policy_attributes` | hash | No | Update the image cleanup policy for this project. Accepts: `cadence` (string), `keep_n` (integer), `older_than` (string), `name_regex` (string), `name_regex_delete` (string), `name_regex_keep` (string), `enabled` (boolean). |
| `container_registry_enabled` | boolean | No | _(Deprecated)_ Enable container registry for this project. Use `container_registry_access_level` instead. |
| `default_branch` | string | No | The [default branch](../user/project/repository/branches/default.md) name. |
@ -1833,7 +1829,7 @@ settings with access control options can be one of:
- `enabled`: Enable and set the feature to **Everyone with access**.
| Attribute | Type | Required | Description |
|----------------------------------------|--------|----------|-------------|
|:---------------------------------------|:-------|:---------|:------------|
| `analytics_access_level` | string | No | Set visibility of [analytics](../user/analytics/index.md). |
| `builds_access_level` | string | No | Set visibility of [pipelines](../ci/pipelines/settings.md#change-which-users-can-view-your-pipelines). |
| `container_registry_access_level` | string | No | Set visibility of [container registry](../user/packages/container_registry/index.md#change-visibility-of-the-container-registry). |
@ -1867,7 +1863,7 @@ POST /projects/:id/fork
```
| Attribute | Type | Required | Description |
|--------------------------|-------------------|----------|-------------|
|:-------------------------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `branches` | string | No | Branches to fork (empty for all branches). |
| `description` | string | No | The description assigned to the resultant project after forking. |
@ -1889,7 +1885,7 @@ GET /projects/:id/forks
```
| Attribute | Type | Required | Description |
|-------------------------------|-------------------|----------|-------------|
|:------------------------------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `archived` | boolean | No | Limit by archived status. |
| `membership` | boolean | No | Limit by projects that the current user is a member of. |
@ -2007,7 +2003,7 @@ POST /projects/:id/star
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
```shell
@ -2114,13 +2110,13 @@ By default, this request returns 20 results at a time because the API results [a
Parameters:
| Attribute | Type | Required | Description |
| ------------------------------------- | ----------------- | -------- | ---------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding) owned by the authenticated user |
| `search` | string | no | Return the list of authorized groups matching the search criteria |
| `min_access_level` | integer | no | Limit to groups where current user has at least the specified [role (`access_level`)](members.md#roles) |
| `relation` | array of strings | no | Filter the groups by relation (direct or inherited) |
| `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (administrators only) |
| Attribute | Type | Required | Description |
|:-------------------------|:-----------------|:---------|:------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding) owned by the authenticated user |
| `search` | string | no | Return the list of authorized groups matching the search criteria |
| `min_access_level` | integer | no | Limit to groups where current user has at least the specified [role (`access_level`)](members.md#roles) |
| `relation` | array of strings | no | Filter the groups by relation (direct or inherited) |
| `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (administrators only) |
```plaintext
GET /projects/:id/invited_groups
@ -2149,9 +2145,9 @@ Unstars a given project. Returns status code `304` if the project is not starred
POST /projects/:id/unstar
```
| Attribute | Type | Required | Description |
|-----------|----------------|------------------------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| Attribute | Type | Required | Description |
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/unstar"
@ -2256,10 +2252,10 @@ List the users who starred the specified project.
GET /projects/:id/starrers
```
| Attribute | Type | Required | Description |
|-----------|----------------|------------------------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `search` | string | No | Search for specific users. |
| Attribute | Type | Required | Description |
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `search` | string | No | Search for specific users. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/starrers"
@ -2303,7 +2299,7 @@ GET /projects/:id/languages
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
```shell
@ -2332,7 +2328,7 @@ POST /projects/:id/archive
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
```shell
@ -2466,7 +2462,7 @@ POST /projects/:id/unarchive
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
```shell
@ -2613,11 +2609,11 @@ The option to delete projects immediately from deletion protection settings in t
DELETE /projects/:id
```
| Attribute | Type | Required | Description |
|----------------------------------------|-------------------|----------|-------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `full_path` | string | no | Full path of project to use with `permanently_remove`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/396500) in GitLab 15.11. To find the project path, use `path_with_namespace` from [get single project](projects.md#get-single-project). Premium and Ultimate only. |
| `permanently_remove` | boolean/string | no | Immediately deletes a project if it is marked for deletion. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/396500) in GitLab 15.11. Premium and Ultimate only. |
| Attribute | Type | Required | Description |
|:---------------------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `full_path` | string | no | Full path of project to use with `permanently_remove`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/396500) in GitLab 15.11. To find the project path, use `path_with_namespace` from [get single project](projects.md#get-single-project). Premium and Ultimate only. |
| `permanently_remove` | boolean/string | no | Immediately deletes a project if it is marked for deletion. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/396500) in GitLab 15.11. Premium and Ultimate only. |
## Restore project marked for deletion
@ -2632,7 +2628,7 @@ POST /projects/:id/restore
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
## Upload a project avatar
@ -2644,7 +2640,7 @@ PUT /projects/:id
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `avatar` | string | Yes | The file to be uploaded. |
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
@ -2679,8 +2675,8 @@ You can access this endpoint without authentication if the project is publicly a
GET /projects/:id/avatar
```
| Attribute | Type | Required | Description |
| --------- | ----------------- | -------- | --------------------- |
| Attribute | Type | Required | Description |
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | yes | ID or [URL-encoded path](rest/index.md#namespaced-path-encoding) of the project. |
Example:
@ -2711,7 +2707,7 @@ POST /projects/:id/share
```
| Attribute | Type | Required | Description |
|----------------|-------------------|----------|-------------|
|:---------------|:------------------|:---------|:------------|
| `group_access` | integer | Yes | The [role (`access_level`)](members.md#roles) to grant the group. |
| `group_id` | integer | Yes | The ID of the group to share with. |
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
@ -2726,7 +2722,7 @@ DELETE /projects/:id/share/:group_id
```
| Attribute | Type | Required | Description |
|------------|-------------------|----------|-------------|
|:-----------|:------------------|:---------|:------------|
| `group_id` | integer | Yes | The ID of the group. |
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
@ -2748,7 +2744,7 @@ POST /projects/:id/import_project_members/:project_id
```
| Attribute | Type | Required | Description |
|--------------|-------------------|----------|-------------|
|:-------------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path](rest/index.md#namespaced-path-encoding) of the target project to receive the members. |
| `project_id` | integer or string | Yes | The ID or [URL-encoded path](rest/index.md#namespaced-path-encoding) of the source project to import the members from. |
@ -2801,7 +2797,7 @@ POST /projects/:id/fork/:forked_from_id
```
| Attribute | Type | Required | Description |
|------------------|-------------------|----------|-------------|
|:-----------------|:------------------|:---------|:------------|
| `forked_from_id` | ID | Yes | The ID of the project that was forked from. |
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
@ -2812,7 +2808,7 @@ DELETE /projects/:id/fork
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
## Search for projects by name
@ -2826,7 +2822,7 @@ GET /projects
```
| Attribute | Type | Required | Description |
|------------|--------|----------|-------------|
|:-----------|:-------|:---------|:------------|
| `search` | string | Yes | A string contained in the project name. |
| `order_by` | string | No | Return requests ordered by `id`, `name`, `created_at`, `star_count`, or `last_activity_at` fields. |
| `sort` | string | No | Return requests sorted in `asc` or `desc` order. |
@ -2842,7 +2838,7 @@ POST /projects/:id/housekeeping
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `task` | string | No | `prune` to trigger manual prune of unreachable objects or `eager` to trigger eager housekeeping. |
@ -2857,7 +2853,7 @@ GET /projects/:id/transfer_locations
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `search` | string | No | The group names to search for. |
@ -2900,7 +2896,7 @@ PUT /projects/:id/transfer
```
| Attribute | Type | Required | Description |
|-------------|-------------------|----------|-------------|
|:------------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `namespace` | integer or string | Yes | The ID or path of the namespace to transfer to project to. |
@ -3023,22 +3019,6 @@ Example response:
}
```
## Branches
Read more in the [Branches](branches.md) documentation.
## Project import/export
Read more in the [Project import/export](project_import_export.md) documentation.
## Project members
Read more in the [Project members](members.md) documentation.
## Project vulnerabilities
Read more in the [Project vulnerabilities](project_vulnerabilities.md) documentation.
## Get a project's pull mirror details
DETAILS:
@ -3056,7 +3036,7 @@ GET /projects/:id/mirror/pull
Supported attributes:
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
Example request:
@ -3100,7 +3080,7 @@ where `token` is a [personal access token](../user/profile/personal_access_token
with the API scope enabled.
| Attribute | Type | Required | Description |
|----------------------------------|---------|----------|-------------|
|:---------------------------------|:--------|:---------|:------------|
| `import_url` | string | Yes | URL of remote repository being mirrored (with `user:token` if needed). |
| `mirror` | boolean | Yes | Enables pull mirroring on project when set to `true`. |
| `mirror_trigger_builds` | boolean | No | Trigger pipelines for mirror updates when set to `true`. |
@ -3150,17 +3130,13 @@ POST /projects/:id/mirror/pull
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/mirror/pull"
```
## Project badges
Read more in the [Project Badges](project_badges.md) documentation.
## Download snapshot of a Git repository
This endpoint may only be accessed by an administrative user.
@ -3177,7 +3153,7 @@ GET /projects/:id/snapshot
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `wiki` | boolean | No | Whether to download the wiki, rather than project, repository. |
@ -3193,7 +3169,7 @@ GET /projects/:id/storage
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------|
|:----------|:------------------|:---------|:------------|
| `id` | integer or string | Yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
```json

View File

@ -26,21 +26,21 @@ This function takes pagination parameters `page` and `per_page` to restrict the
GET /users
```
| Attribute | Type | Required | Description |
| ------------------ | ------- | -------- | ------------------------------------------------------------|
| `username` | string | no | Get a single user with a specific username. |
| `search` | string | no | Search for a username. |
| `active` | boolean | no | Filters only active users. Default is `false`. |
| `external` | boolean | no | Filters only external users. Default is `false`. |
| `blocked` | boolean | no | Filters only blocked users. Default is `false`. |
| `humans` | boolean | no | Filters only regular users that are not bot or internal users. Default is `false`. |
| `created_after` | DateTime| no | Returns users created after specified time. |
| `created_before` | DateTime| no | Returns users created before specified time. |
| `exclude_active` | boolean | no | Filters only non active users. Default is `false`. |
| `exclude_external` | boolean | no | Filters only non external users. Default is `false`. |
| `exclude_humans` | boolean | no | Filters only bot or internal users. Default is `false`. |
| `exclude_internal` | boolean | no | Filters only non internal users. Default is `false`. |
| `without_project_bots`| boolean | no | Filters user without project bots. Default is `false`. |
| Attribute | Type | Required | Description |
|:-----------------------|:---------|:---------|:------------|
| `username` | string | no | Get a single user with a specific username. |
| `search` | string | no | Search for a username. |
| `active` | boolean | no | Filters only active users. Default is `false`. |
| `external` | boolean | no | Filters only external users. Default is `false`. |
| `blocked` | boolean | no | Filters only blocked users. Default is `false`. |
| `humans` | boolean | no | Filters only regular users that are not bot or internal users. Default is `false`. |
| `created_after` | DateTime | no | Returns users created after specified time. |
| `created_before` | DateTime | no | Returns users created before specified time. |
| `exclude_active` | boolean | no | Filters only non active users. Default is `false`. |
| `exclude_external` | boolean | no | Filters only non external users. Default is `false`. |
| `exclude_humans` | boolean | no | Filters only bot or internal users. Default is `false`. |
| `exclude_internal` | boolean | no | Filters only non internal users. Default is `false`. |
| `without_project_bots` | boolean | no | Filters user without project bots. Default is `false`. |
```json
[
@ -151,18 +151,18 @@ GET /users
You can use all [parameters available for everyone](#for-non-administrator-users) plus these additional parameters available only for administrators.
| Attribute | Type | Required | Description |
| ------------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
| `extern_uid` | string | no | Get a single user with a specific external authentication provider UID. |
| `provider` | string | no | The external provider. |
| `order_by` | string | no | Return users ordered by `id`, `name`, `username`, `created_at`, or `updated_at` fields. Default is `id` |
| `sort` | string | no | Return users sorted in `asc` or `desc` order. Default is `desc` |
| Attribute | Type | Required | Description |
|:-------------------|:--------|:---------|:------------|
| `extern_uid` | string | no | Get a single user with a specific external authentication provider UID. |
| `provider` | string | no | The external provider. |
| `order_by` | string | no | Return users ordered by `id`, `name`, `username`, `created_at`, or `updated_at` fields. Default is `id` |
| `sort` | string | no | Return users sorted in `asc` or `desc` order. Default is `desc` |
| `two_factor` | string | no | Filter users by Two-factor authentication. Filter values are `enabled` or `disabled`. By default it returns all users |
| `without_projects` | boolean | no | Filter users without projects. Default is `false`, which means that all users are returned, with and without projects. |
| `admins` | boolean | no | Return only administrators. Default is `false` |
| `admins` | boolean | no | Return only administrators. Default is `false` |
| `auditors` | boolean | no | Return only auditor users. Default is `false`. If not included, it returns all users. Premium and Ultimate only. |
| `saml_provider_id` | number | no | Return only users created by the specified SAML provider ID. If not included, it returns all users. Premium and Ultimate only. |
| `skip_ldap` | boolean | no | Skip LDAP users. Premium and Ultimate only. |
| `saml_provider_id` | number | no | Return only users created by the specified SAML provider ID. If not included, it returns all users. Premium and Ultimate only. |
| `skip_ldap` | boolean | no | Skip LDAP users. Premium and Ultimate only. |
```json
[
@ -354,8 +354,8 @@ GET /users/:id
Parameters:
| Attribute | Type | Required | Description |
|-----------|---------|----------|------------------|
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of a user |
```json
@ -394,7 +394,6 @@ DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** Self-managed, GitLab Dedicated
> - The `namespace_id` field in the response was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82045) in GitLab 14.10.
> - The `created_by` field in the response was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93092) in GitLab 15.6.
> - The `email_reset_offered_at` field in the response [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/137610) in GitLab 16.7.
@ -404,8 +403,8 @@ GET /users/:id
Parameters:
| Attribute | Type | Required | Description |
|-----------|---------|----------|------------------|
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of a user |
Example Responses:
@ -538,7 +537,6 @@ DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** Self-managed, GitLab Dedicated
> - The `namespace_id` field in the response was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82045) in GitLab 14.10.
> - Ability to create an auditor user was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366404) in GitLab 15.3.
Creates a new user. Note only administrators can create new
@ -561,42 +559,42 @@ POST /users
Parameters:
| Attribute | Required | Description |
| :----------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Attribute | Required | Description |
|:-------------------------------------|:---------|:------------|
| `admin` | No | User is an administrator. Valid values are `true` or `false`. Defaults to false. |
| `auditor` | No | User is an auditor. Valid values are `true` or `false`. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366404) in GitLab 15.3. Premium and Ultimate only. |
| `avatar` | No | Image file for user's avatar |
| `bio` | No | User's biography |
| `can_create_group` | No | User can create top-level groups - true or false |
| `auditor` | No | User is an auditor. Valid values are `true` or `false`. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366404) in GitLab 15.3. Premium and Ultimate only. |
| `avatar` | No | Image file for user's avatar |
| `bio` | No | User's biography |
| `can_create_group` | No | User can create top-level groups - true or false |
| `color_scheme_id` | No | User's color scheme for the file viewer (for more information, see the [user preference documentation](../user/profile/preferences.md#change-the-syntax-highlighting-theme)) |
| `commit_email` | No | User's commit email address |
| `email` | Yes | Email |
| `extern_uid` | No | External UID |
| `external` | No | Flags the user as external - true or false (default) |
| `extra_shared_runners_minutes_limit` | No | Can be set by administrators only. Additional compute minutes for this user. Premium and Ultimate only. |
| `force_random_password` | No | Set user password to a random value - true or false (default) |
| `group_id_for_saml` | No | ID of group where SAML has been configured |
| `linkedin` | No | LinkedIn |
| `location` | No | User's location |
| `name` | Yes | Name |
| `note` | No | Administrator notes for this user |
| `organization` | No | Organization name |
| `password` | No | Password |
| `commit_email` | No | User's commit email address |
| `email` | Yes | Email |
| `extern_uid` | No | External UID |
| `external` | No | Flags the user as external - true or false (default) |
| `extra_shared_runners_minutes_limit` | No | Can be set by administrators only. Additional compute minutes for this user. Premium and Ultimate only. |
| `force_random_password` | No | Set user password to a random value - true or false (default) |
| `group_id_for_saml` | No | ID of group where SAML has been configured |
| `linkedin` | No | LinkedIn |
| `location` | No | User's location |
| `name` | Yes | Name |
| `note` | No | Administrator notes for this user |
| `organization` | No | Organization name |
| `password` | No | Password |
| `private_profile` | No | User's profile is private - true or false. The default value is determined by [this](../administration/settings/account_and_limit_settings.md#set-profiles-of-new-users-to-private-by-default) setting. |
| `projects_limit` | No | Number of projects user can create |
| `pronouns` | No | User's pronouns |
| `provider` | No | External provider name |
| `public_email` | No | User's public email address |
| `reset_password` | No | Send user password reset link - true or false(default) |
| `shared_runners_minutes_limit` | No | Can be set by administrators only. Maximum number of monthly compute minutes for this user. Can be `nil` (default; inherit system default), `0` (unlimited), or `> 0`. Premium and Ultimate only. |
| `skip_confirmation` | No | Skip confirmation - true or false (default) |
| `skype` | No | Skype ID |
| `theme_id` | No | GitLab theme for the user (for more information, see the [user preference documentation](../user/profile/preferences.md#change-the-color-theme) for more information) |
| `twitter` | No | X (formerly Twitter) account |
| `discord` | No | Discord account |
| `username` | Yes | Username |
| `view_diffs_file_by_file` | No | Flag indicating the user sees only one file diff per page |
| `website_url` | No | Website URL |
| `projects_limit` | No | Number of projects user can create |
| `pronouns` | No | User's pronouns |
| `provider` | No | External provider name |
| `public_email` | No | User's public email address |
| `reset_password` | No | Send user password reset link - true or false(default) |
| `shared_runners_minutes_limit` | No | Can be set by administrators only. Maximum number of monthly compute minutes for this user. Can be `nil` (default; inherit system default), `0` (unlimited), or `> 0`. Premium and Ultimate only. |
| `skip_confirmation` | No | Skip confirmation - true or false (default) |
| `skype` | No | Skype ID |
| `theme_id` | No | GitLab theme for the user (for more information, see the [user preference documentation](../user/profile/preferences.md#change-the-color-theme) for more information) |
| `twitter` | No | X (formerly Twitter) account |
| `discord` | No | Discord account |
| `username` | Yes | Username |
| `view_diffs_file_by_file` | No | Flag indicating the user sees only one file diff per page |
| `website_url` | No | Website URL |
## User modification
@ -604,7 +602,6 @@ DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** Self-managed, GitLab Dedicated
> - The `namespace_id` field in the response was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82045) in GitLab 14.10.
> - Ability to modify an auditor user was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366404) in GitLab 15.3.
Modifies an existing user. Only administrators can change attributes of a user.
@ -617,41 +614,41 @@ PUT /users/:id
Parameters:
| Attribute | Required | Description |
| :----------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `admin` | No |User is an administrator. Valid values are `true` or `false`. Defaults to false. |
| `auditor` | No | User is an auditor. Valid values are `true` or `false`. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366404) in GitLab 15.3.(default) Premium and Ultimate only. |
| `avatar` | No | Image file for user's avatar |
| `bio` | No | User's biography |
| `can_create_group` | No | User can create groups - true or false |
| Attribute | Required | Description |
|:-------------------------------------|:---------|:------------|
| `admin` | No | User is an administrator. Valid values are `true` or `false`. Defaults to false. |
| `auditor` | No | User is an auditor. Valid values are `true` or `false`. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366404) in GitLab 15.3.(default) Premium and Ultimate only. |
| `avatar` | No | Image file for user's avatar |
| `bio` | No | User's biography |
| `can_create_group` | No | User can create groups - true or false |
| `color_scheme_id` | No | User's color scheme for the file viewer (for more information, see the [user preference documentation](../user/profile/preferences.md#change-the-syntax-highlighting-theme) for more information) |
| `commit_email` | No | User's commit email. Set to `_private` to use the private commit email. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375148) in GitLab 15.5. |
| `email` | No | Email |
| `extern_uid` | No | External UID |
| `external` | No | Flags the user as external - true or false (default) |
| `extra_shared_runners_minutes_limit` | No | Can be set by administrators only. Additional compute minutes for this user. Premium and Ultimate only. |
| `group_id_for_saml` | No | ID of group where SAML has been configured |
| `id` | Yes | ID of the user |
| `linkedin` | No | LinkedIn |
| `location` | No | User's location |
| `name` | No | Name |
| `note` | No | Administration notes for this user |
| `organization` | No | Organization name |
| `password` | No | Password |
| `private_profile` | No | User's profile is private - true or false. |
| `projects_limit` | No | Limit projects each user can create |
| `pronouns` | No | Pronouns |
| `provider` | No | External provider name |
| `public_email` | No | Public email of the user (must be already verified) |
| `shared_runners_minutes_limit` | No | Can be set by administrators only. Maximum number of monthly compute minutes for this user. Can be `nil` (default; inherit system default), `0` (unlimited) or `> 0`. Premium and Ultimate only. |
| `skip_reconfirmation` | No | Skip reconfirmation - true or false (default) |
| `skype` | No | Skype ID |
| `theme_id` | No | GitLab theme for the user (for more information, see the [user preference documentation](../user/profile/preferences.md#change-the-color-theme) for more information) |
| `twitter` | No | X (formerly Twitter) account |
| `discord` | No | Discord account |
| `username` | No | Username |
| `view_diffs_file_by_file` | No | Flag indicating the user sees only one file diff per page |
| `website_url` | No | Website URL |
| `email` | No | Email |
| `extern_uid` | No | External UID |
| `external` | No | Flags the user as external - true or false (default) |
| `extra_shared_runners_minutes_limit` | No | Can be set by administrators only. Additional compute minutes for this user. Premium and Ultimate only. |
| `group_id_for_saml` | No | ID of group where SAML has been configured |
| `id` | Yes | ID of the user |
| `linkedin` | No | LinkedIn |
| `location` | No | User's location |
| `name` | No | Name |
| `note` | No | Administration notes for this user |
| `organization` | No | Organization name |
| `password` | No | Password |
| `private_profile` | No | User's profile is private - true or false. |
| `projects_limit` | No | Limit projects each user can create |
| `pronouns` | No | Pronouns |
| `provider` | No | External provider name |
| `public_email` | No | Public email of the user (must be already verified) |
| `shared_runners_minutes_limit` | No | Can be set by administrators only. Maximum number of monthly compute minutes for this user. Can be `nil` (default; inherit system default), `0` (unlimited) or `> 0`. Premium and Ultimate only. |
| `skip_reconfirmation` | No | Skip reconfirmation - true or false (default) |
| `skype` | No | Skype ID |
| `theme_id` | No | GitLab theme for the user (for more information, see the [user preference documentation](../user/profile/preferences.md#change-the-color-theme) for more information) |
| `twitter` | No | X (formerly Twitter) account |
| `discord` | No | Discord account |
| `username` | No | Username |
| `view_diffs_file_by_file` | No | Flag indicating the user sees only one file diff per page |
| `website_url` | No | Website URL |
On password update, the user is forced to change it upon next login.
Note, at the moment this method does only return a `404` error,
@ -672,9 +669,9 @@ DELETE /users/:id/identities/:provider
Parameters:
| Attribute | Type | Required | Description |
|------------|---------|----------|------------------------|
| `id` | integer | yes | ID of a user |
| Attribute | Type | Required | Description |
|:-----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of a user |
| `provider` | string | yes | External provider name |
## User deletion
@ -696,9 +693,9 @@ DELETE /users/:id
Parameters:
| Attribute | Type | Required | Description |
|---------------|---------|----------|----------------------------------------------|
| `id` | integer | yes | ID of a user |
| Attribute | Type | Required | Description |
|:--------------|:--------|:---------|:------------|
| `id` | integer | yes | ID of a user |
| `hard_delete` | boolean | no | If true, contributions that would usually be [moved to Ghost User](../user/profile/account/delete_account.md#associated-records) are deleted instead, as well as groups owned solely by this user. |
## List current user
@ -769,7 +766,6 @@ DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** Self-managed, GitLab Dedicated
> - The `namespace_id` field in the response was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82045) in GitLab 14.10.
> - The `created_by` field in the response was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93092) in GitLab 15.6.
> - The `email_reset_offered_at` field in the response [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/137610) in GitLab 16.7.
@ -779,8 +775,8 @@ GET /user
Parameters:
| Attribute | Type | Required | Description |
|-----------|---------|----------|--------------------------------------------------|
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `sudo` | integer | no | ID of a user to make the call in their place |
```json
@ -873,8 +869,8 @@ Get the status of a user. This endpoint can be accessed without authentication.
GET /users/:id_or_username/status
```
| Attribute | Type | Required | Description |
| ---------------- | ------ | -------- | ------------------------------------------------- |
| Attribute | Type | Required | Description |
|:-----------------|:-------|:---------|:------------|
| `id_or_username` | string | yes | ID or username of the user to get a status of |
```shell
@ -902,10 +898,10 @@ PUT /user/status
PATCH /user/status
```
| Attribute | Type | Required | Description |
| -------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Attribute | Type | Required | Description |
|:---------------------|:-------|:---------|:------------|
| `emoji` | string | no | Name of the emoji to use as status. If omitted `speech_balloon` is used. Emoji name can be one of the specified names in the [Gemojione index](https://github.com/bonusly/gemojione/blob/master/config/index.json). |
| `message` | string | no | Message to set as a status. It can also contain emoji codes. Cannot exceed 100 characters. |
| `message` | string | no | Message to set as a status. It can also contain emoji codes. Cannot exceed 100 characters. |
| `clear_status_after` | string | no | Automatically clean up the status after a given time interval, allowed values: `30_minutes`, `3_hours`, `8_hours`, `1_day`, `3_days`, `7_days`, `30_days` |
Difference between `PUT` and `PATCH`
@ -972,10 +968,10 @@ PUT /user/preferences
Parameters:
| Attribute | Required | Description |
| :------------------------------- | :------- | :--------------------------------------------------------------------------- |
| `view_diffs_file_by_file` | Yes | Flag indicating the user sees only one file diff per page. |
| `show_whitespace_in_diffs` | Yes | Flag indicating the user sees whitespace changes in diffs. |
| Attribute | Required | Description |
|:---------------------------------|:---------|:------------|
| `view_diffs_file_by_file` | Yes | Flag indicating the user sees only one file diff per page. |
| `show_whitespace_in_diffs` | Yes | Flag indicating the user sees whitespace changes in diffs. |
| `pass_user_identities_to_ci_jwt` | Yes | Flag indicating the user passes their external identities as CI information. This attribute does not contain enough information to identify or authorize the user in an external system. The attribute is internal to GitLab, and must not be passed to third-party services. For more information and examples, see [Token Payload](../ci/secrets/id_token_authentication.md#token-payload). |
## User follow
@ -994,8 +990,8 @@ Unfollow a user.
POST /users/:id/unfollow
```
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | ---------------------------- |
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of the user to follow |
```shell
@ -1030,8 +1026,8 @@ Get the list of users being followed.
GET /users/:id/following
```
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | ---------------------------- |
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of the user to follow |
```shell
@ -1067,13 +1063,13 @@ Example response:
Get the counts (same as in the upper-left menu) of the authenticated user.
| Attribute | Type | Description |
| --------------------------------- | ------ | ---------------------------------------------------------------------------- |
| `assigned_issues` | number | Number of issues that are open and assigned to the current user. |
| `assigned_merge_requests` | number | Number of merge requests that are active and assigned to the current user. |
| `merge_requests` | number | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50026) in GitLab 13.8. Equivalent to and replaced by `assigned_merge_requests`. |
| Attribute | Type | Description |
|:----------------------------------|:-------|:------------|
| `assigned_issues` | number | Number of issues that are open and assigned to the current user. |
| `assigned_merge_requests` | number | Number of merge requests that are active and assigned to the current user. |
| `merge_requests` | number | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50026) in GitLab 13.8. Equivalent to and replaced by `assigned_merge_requests`. |
| `review_requested_merge_requests` | number | Number of merge requests that the current user has been requested to review. |
| `todos` | number | Number of pending to-do items for current user. |
| `todos` | number | Number of pending to-do items for current user. |
```plaintext
GET /user_counts
@ -1116,8 +1112,8 @@ GET /users/:id/associations_count
Parameters:
| Attribute | Type | Required | Description |
|-----------|---------|----------|------------------|
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of a user |
Example response:
@ -1178,8 +1174,8 @@ GET /users/:id/emails
Parameters:
| Attribute | Type | Required | Description |
|-----------|---------|----------|----------------------|
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of specified user |
## Single email
@ -1193,7 +1189,7 @@ GET /user/emails/:email_id
Parameters:
| Attribute | Type | Required | Description |
|------------|---------|----------|-------------|
|:-----------|:--------|:---------|:------------|
| `email_id` | integer | yes | Email ID |
```json
@ -1215,7 +1211,7 @@ POST /user/emails
Parameters:
| Attribute | Type | Required | Description |
|-----------|--------|----------|-------------|
|:----------|:-------|:---------|:------------|
| `email` | string | yes | Email address |
```json
@ -1253,10 +1249,10 @@ POST /users/:id/emails
Parameters:
| Attribute | Type | Required | Description |
|---------------------|---------|----------|---------------------------------------------------------------------------|
| `id` | string | yes | ID of specified user |
| `email` | string | yes | Email address |
| Attribute | Type | Required | Description |
|:--------------------|:--------|:---------|:------------|
| `id` | string | yes | ID of specified user |
| `email` | string | yes | Email address |
| `skip_confirmation` | boolean | no | Skip confirmation and assume email is verified - true or false (default) |
## Delete email for current user
@ -1276,7 +1272,7 @@ DELETE /user/emails/:email_id
Parameters:
| Attribute | Type | Required | Description |
|------------|---------|----------|-------------|
|:-----------|:--------|:---------|:------------|
| `email_id` | integer | yes | Email ID |
Returns:
@ -1302,10 +1298,10 @@ DELETE /users/:id/emails/:email_id
Parameters:
| Attribute | Type | Required | Description |
|------------|---------|----------|----------------------|
| Attribute | Type | Required | Description |
|:-----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of specified user |
| `email_id` | integer | yes | Email ID |
| `email_id` | integer | yes | Email ID |
## Get user contribution events
@ -1327,7 +1323,7 @@ The activities that update the user event timestamps (`last_activity_on` and `cu
- Git HTTP/SSH activities (such as clone, push)
- User logging in to GitLab
- User visiting pages related to dashboards, projects, issues, and merge requests ([introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54947) in GitLab 11.8)
- User visiting pages related to dashboards, projects, issues, and merge requests
- User using the API
- User using the GraphQL API
@ -1340,8 +1336,8 @@ GET /user/activities
Parameters:
| Attribute | Type | Required | Description |
| --------- | ------ | -------- | ---------------------------------------------------------------------------------------------- |
| Attribute | Type | Required | Description |
|:----------|:-------|:---------|:------------|
| `from` | string | no | Date string in the format `YEAR-MM-DD`. For example, `2016-03-11`. Defaults to 6 months ago. |
```shell
@ -1378,8 +1374,6 @@ DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** Self-managed, GitLab Dedicated
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20532) in GitLab 12.8.
Pre-requisite:
- You must be an administrator.
@ -1395,9 +1389,9 @@ GET /users/:id/memberships
Parameters:
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | ------------------------------------------------------------------ |
| `id` | integer | yes | ID of a specified user |
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of a specified user |
| `type` | string | no | Filter memberships by type. Can be either `Project` or `Namespace` |
Returns:
@ -1453,9 +1447,9 @@ PATCH /users/:id/disable_two_factor
Parameters:
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- |
| `id` | integer | yes | ID of the user |
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `id` | integer | yes | ID of the user |
```shell
curl --request PATCH --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/1/disable_two_factor"
@ -1489,19 +1483,19 @@ Be sure to copy or save the `token` in the response, the value cannot be retriev
POST /user/runners
```
| Attribute | Type | Required | Description |
|--------------------|--------------|----------|---------------------------------------------------------------------------------------------------|
| `runner_type` | string | yes | Specifies the scope of the runner; `instance_type`, `group_type`, or `project_type`. |
| `group_id` | integer | no | The ID of the group that the runner is created in. Required if `runner_type` is `group_type`. |
| Attribute | Type | Required | Description |
|:-------------------|:-------------|:---------|:------------|
| `runner_type` | string | yes | Specifies the scope of the runner; `instance_type`, `group_type`, or `project_type`. |
| `group_id` | integer | no | The ID of the group that the runner is created in. Required if `runner_type` is `group_type`. |
| `project_id` | integer | no | The ID of the project that the runner is created in. Required if `runner_type` is `project_type`. |
| `description` | string | no | Description of the runner. |
| `paused` | boolean | no | Specifies if the runner should ignore new jobs. |
| `locked` | boolean | no | Specifies if the runner should be locked for the current project. |
| `run_untagged` | boolean | no | Specifies if the runner should handle untagged jobs. |
| `tag_list` | string array | no | A list of runner tags. |
| `access_level` | string | no | The access level of the runner; `not_protected` or `ref_protected`. |
| `maximum_timeout` | integer | no | Maximum timeout that limits the amount of time (in seconds) that runners can run jobs. |
| `maintenance_note` | string | no | Free-form maintenance notes for the runner (1024 characters). |
| `description` | string | no | Description of the runner. |
| `paused` | boolean | no | Specifies if the runner should ignore new jobs. |
| `locked` | boolean | no | Specifies if the runner should be locked for the current project. |
| `run_untagged` | boolean | no | Specifies if the runner should handle untagged jobs. |
| `tag_list` | string array | no | A list of runner tags. |
| `access_level` | string | no | The access level of the runner; `not_protected` or `ref_protected`. |
| `maximum_timeout` | integer | no | Maximum timeout that limits the amount of time (in seconds) that runners can run jobs. |
| `maintenance_note` | string | no | Free-form maintenance notes for the runner (1024 characters). |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "runner_type=instance_type" \
@ -1528,9 +1522,9 @@ Upload an avatar to current user.
PUT /user/avatar
```
| Attribute | Type | Required | Description |
|-----------|-------------------|----------|-------------------------------------------------------------------------------------------------------------|
| `avatar` | string | Yes | The file to be uploaded. The ideal image size is 192 x 192 pixels. The maximum file size allowed is 200 KiB. |
| Attribute | Type | Required | Description |
|:----------|:-------|:---------|:------------|
| `avatar` | string | Yes | The file to be uploaded. The ideal image size is 192 x 192 pixels. The maximum file size allowed is 200 KiB. |
To upload an avatar from your file system, use the `--form` argument. This causes
cURL to post data using the header `Content-Type: multipart/form-data`. The

View File

@ -36,7 +36,7 @@ You can read more about enabling browser-specific keyboard navigation on [a11ypr
[checkbox](#checkbox-inputs-with-accessible-names),
[radio](#radio-inputs-with-accessible-names),
[file](#file-inputs-with-accessible-names),
and [toggle](#gltoggle-components-with-an-accessible-names) inputs have accessible names.
and [toggle](#gltoggle-components-with-accessible-names) inputs have accessible names.
- [Buttons](#buttons-and-links-with-descriptive-accessible-names),
[links](#buttons-and-links-with-descriptive-accessible-names),
and [images](#images-with-accessible-names) have descriptive accessible names.
@ -244,7 +244,7 @@ File input examples:
<input id="attach-file" type="file" />
```
#### GlToggle components with an accessible names
#### GlToggle components with accessible names
`GlToggle` examples:
@ -256,9 +256,9 @@ File input examples:
<gl-toggle v-model="notifications" :label="__('Notifications')" label-position="hidden" />
```
#### GlFormCombobox components with an accessible names
#### GlFormCombobox components with accessible names
`GlFormCombobox` examples:
`GlFormCombobox` example:
```html
<!-- GlFormCombobox with label -->

View File

@ -88,7 +88,7 @@ mutation{
Project members that do not have the Owner or Maintainer role cannot access this GraphQL endpoint.
You can also use the REST API for [projects](../api/project_markdown_uploads.md#delete-an-uploaded-file-by-secret-and-filename) or [groups](../api/groups.md#delete-an-uploaded-file-by-secret-and-filename) to delete an uploaded file.
You can also use the REST API for [projects](../api/project_markdown_uploads.md#delete-an-uploaded-file-by-secret-and-filename) or [groups](../api/group_markdown_uploads.md#delete-an-uploaded-file-by-secret-and-filename) to delete an uploaded file.
<!-- ## Troubleshooting

View File

@ -125,6 +125,14 @@ To create an epic from a list in epic board:
![Create a GitLab epic from an epic board](img/epic_board_epic_create_v15_10.png)
### Edit an epic
<!-- When issues_list_drawer feature flag is removed, change the info below into a proper task topic -->
If your administrator enabled the [epic drawer](manage_epics.md#open-epics-in-a-drawer),
when you select an epic card from the epic board, the epic opens in a drawer.
There, you can edit all the fields, including the description, comments, or related items.
### Filter epics
Use the filters on top of your epic board to show only

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -155,6 +155,30 @@ To update multiple epics at the same time:
1. Select the appropriate fields and their values from the sidebar.
1. Select **Update selected**.
### Open epics in a drawer
DETAILS:
**Offering:** Self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/464063) in GitLab 17.4 [with a flag](../../../administration/feature_flags.md) named `issues_list_drawer`. Disabled by default.
FLAG:
The availability of this feature is controlled by a feature flag.
For more information, see the history.
This feature is available for testing, but not ready for production use.
When this feature is enabled, when you select an epic from the list or epic board, it opens in a drawer.
You can then edit the epic or create comments.
To open the epic in full view:
- Open the epic in a new tab. From the list of epics, either:
- Right-click the epic and open it in a new browser tab.
- Hold <kbd>Cmd</kbd> or <kbd>Ctrl</kbd> and click the epic.
- From the drawer, in the top-left corner, select **Open in full view**.
![Epic opened in a drawer.](img/epic_drawer_v17_4.png)
## Assignees
DETAILS:

View File

@ -404,24 +404,12 @@ To group issues by epic in an issue board:
![Epics Swimlanes](img/epics_swimlanes_v17_1.png)
To edit an issue without leaving this view, select the issue card (not its title), and a sidebar
appears on the right. There you can see and edit the issue's:
You can then [edit](#edit-an-issue) issues without leaving this view and [drag](#move-issues-and-lists)
them to change their position and epic assignment:
- Title
- Assignees
- [Epic](../group/epics/index.md)
- Milestone
- Time tracking value (view only)
- Due date
- Labels
- Weight
- Notifications setting
You can also [drag issues](#move-issues-and-lists) to change their position and epic assignment:
- To reorder an issue, drag it to the new position within a list.
- To reorder an issue, drag it to the new position in a list.
- To assign an issue to another epic, drag it to the epic's horizontal lane.
- To unassign an issue from an epic, drag it to the **Issues with no epic assigned** lane.
- To remove an issue from an epic, drag it to the **Issues with no epic assigned** lane.
- To move an issue to another epic _and_ another list, at the same time, drag the issue diagonally.
![Drag issues between swimlanes](img/epics_swimlanes_drag_and_drop.png)
@ -506,6 +494,13 @@ You can edit the following issue attributes in the right sidebar:
Additionally, you can also see the time tracking value.
<!-- When issues_list_drawer feature flag is removed, use the info below
and in issues/managing_issues.md#open-issues-in-a-drawer to update the main topic above -->
If your administrator enabled the [issue drawer](issues/managing_issues.md#open-issues-in-a-drawer),
when you select an issue card from the issue board, the issue opens in a drawer.
There, you can edit all the fields, including the description, comments, or related items.
### Create a new list
To create a new list:
@ -515,7 +510,7 @@ To create a new list:
![creating a new list in an issue board](img/issue_board_add_list_v17_1.png)
1. Choose the label, user, milestone or iteration to base the new list on.
1. Choose the label, user, milestone, or iteration to base the new list on.
1. Select **Add to board**.
The new list is inserted at the right end of the lists, before **Closed**.

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -477,7 +477,27 @@ Or:
- To use a [keyboard shortcut](../../shortcuts.md), press <kbd>Shift</kbd> + <kbd>i</kbd>.
- On the left sidebar, at the top, select **Assigned issues** (**{issues}**).
## Filter the list of issues
## Issue list
The issue list shows all issues in your project or group.
You can use it to view, sort, and manage issues.
To view the issue list:
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Plan > Issues**.
From the issue list, you can:
- View issue details like title, assignees, labels, and milestone.
- [Sort issues](sorting_issue_lists.md) by various criteria.
- Filter issues to find specific ones.
- Edit issues individually or in bulk.
- Create new issues.
The following sections describe how to work with the issue list.
### Filter the list of issues
> - Filtering by type was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322755) in GitLab 13.10 [with a flag](../../../administration/feature_flags.md) named `vue_issues_list`. Disabled by default.
> - Filtering by type was [enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/322755) in GitLab 14.10.
@ -499,7 +519,7 @@ To filter the list of issues:
1. Repeat this process to filter by multiple attributes. Multiple attributes are joined by a logical
`AND`.
### Filter by title or description
#### Filter by title or description
To filter the list issues for text in a title or description:
@ -520,7 +540,7 @@ However, GitLab won't match the sentence or the words `I`, `am` or `M&A` exactly
as they aren't deemed lexically meaningful or significant.
It's a limitation of PostgreSQL full text search.
### Filter with the OR operator
#### Filter with the OR operator
> - OR filtering for author and assignee was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23532) in GitLab 15.6 [with a flag](../../../administration/feature_flags.md) named `or_issuable_queries`. Disabled by default.
> - OR filtering for label was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23532) in GitLab 15.8 [with a flag](../../../administration/feature_flags.md) named `or_issuable_queries`. Disabled by default.
@ -536,7 +556,7 @@ You can use the OR operator (**is one of: `||`**) when you [filter the list of i
`is one of` represents an inclusive OR. For example, if you filter by `Assignee is one of Sidney Jones` and
`Assignee is one of Zhang Wei`, GitLab shows issues where either `Sidney`, `Zhang`, or both of them are assignees.
### Filter issues by ID
#### Filter issues by ID
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Plan > Issues**.
@ -544,6 +564,30 @@ You can use the OR operator (**is one of: `||`**) when you [filter the list of i
![filter issues by specific ID](img/issue_search_by_id_v15_0.png)
### Open issues in a drawer
DETAILS:
**Offering:** Self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/464063) in GitLab 17.4 [with a flag](../../../administration/feature_flags.md) named `issues_list_drawer`. Disabled by default.
FLAG:
The availability of this feature is controlled by a feature flag.
For more information, see the history.
This feature is available for testing, but not ready for production use.
When this feature is enabled, when you select an issue from the list or issue board, it opens in a drawer.
You can then edit the issue or create comments.
To open the issue in full view:
- Open the issue in a new tab. From the list of issues, either:
- Right-click the issue and open it in a new browser tab.
- Hold <kbd>Cmd</kbd> or <kbd>Ctrl</kbd> and click the issue.
- From the drawer, in the top-left corner, select **Open in full view**.
![Issue opened in a drawer.](img/issue_drawer_v17_4.png)
## Copy issue reference
To refer to an issue elsewhere in GitLab, you can use its full URL or a short reference, which looks like

View File

@ -67,6 +67,7 @@ module Gitlab
gon.current_user_avatar_url = current_user.avatar_url
gon.time_display_relative = current_user.time_display_relative
gon.time_display_format = current_user.time_display_format
gon.current_user_use_work_items_view = current_user.user_preference&.use_work_items_view || false
end
if current_organization && Feature.enabled?(:ui_for_organizations, current_user)
@ -81,6 +82,7 @@ module Gitlab
push_frontend_feature_flag(:organization_switching, current_user)
# To be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/399248
push_frontend_feature_flag(:remove_monitor_metrics)
push_frontend_feature_flag(:work_items_view_preference, current_user)
end
# Exposes the state of a feature flag to the frontend code.

View File

@ -35685,6 +35685,9 @@ msgid_plural "New issues"
msgstr[0] ""
msgstr[1] ""
msgid "New issue look"
msgstr ""
msgid "New issue title"
msgstr ""
@ -41307,6 +41310,9 @@ msgstr ""
msgid "Preview payload"
msgstr ""
msgid "Preview the new issues experience, with real time updates and refreshed design. Some features are not yet supported, see feedback issue for details."
msgstr ""
msgid "Previous commit"
msgstr ""

15
scripts/internal_events/monitor.rb Normal file → Executable file
View File

@ -1,3 +1,4 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
# Internal Events Tracking Monitor
@ -18,6 +19,20 @@
# - To exit the script, press Ctrl+C.
#
unless defined?(Rails)
puts <<~TEXT
Error! The Internal Events Tracking Monitor could not access the Rails context!
Ensure GDK is running, then run:
bin/rails runner scripts/internal_events/monitor.rb #{ARGV.join(' ')}
TEXT
exit! 1
end
require 'terminal-table'
require 'net/http'

View File

@ -182,6 +182,14 @@ RSpec.describe Projects::IssuesController, :request_store, feature_category: :te
end
end
context 'when use_work_items_view is enabled' do
it 'displays the work item view' do
user.user_preference.update!(use_work_items_view: true)
get :show, params: { namespace_id: project.namespace, project_id: project, id: issue.iid }
expect(response).to render_template 'projects/work_items/show'
end
end
context 'when issue is of type task' do
let(:query) { {} }

View File

@ -133,10 +133,10 @@ describe('tags list row', () => {
expect(getTooltipFor(findName()).value).toBe(tag.name);
});
it('on mobile has mw-s class', () => {
it('on mobile has gl-max-w-20 class', () => {
mountComponent({ ...defaultProps, isMobile: true });
expect(findName().classes('mw-s')).toBe(true);
expect(findName().classes('gl-max-w-20')).toBe(true);
});
});

View File

@ -43,7 +43,7 @@ exports[`Upload dropzone component correctly overrides description and drop mess
style="display: none;"
>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style="display: none;"
>
<h3>
@ -54,7 +54,7 @@ exports[`Upload dropzone component correctly overrides description and drop mess
</span>
</div>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
>
<h3>
Incoming!
@ -113,7 +113,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
style=""
>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style="display: none;"
>
<h3>
@ -124,7 +124,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
</span>
</div>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
>
<h3>
Incoming!
@ -183,7 +183,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
style=""
>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style="display: none;"
>
<h3>
@ -194,7 +194,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
</span>
</div>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
>
<h3>
Incoming!
@ -253,7 +253,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
style=""
>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style=""
>
<h3>
@ -264,7 +264,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
</span>
</div>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style="display: none;"
>
<h3>
@ -324,7 +324,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
style=""
>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style=""
>
<h3>
@ -335,7 +335,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
</span>
</div>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style="display: none;"
>
<h3>
@ -395,7 +395,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
style="display: none;"
>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style=""
>
<h3>
@ -406,7 +406,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
</span>
</div>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style="display: none;"
>
<h3>
@ -466,7 +466,7 @@ exports[`Upload dropzone component when no slot provided renders default dropzon
style="display: none;"
>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style="display: none;"
>
<h3>
@ -477,7 +477,7 @@ exports[`Upload dropzone component when no slot provided renders default dropzon
</span>
</div>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
>
<h3>
Incoming!
@ -506,7 +506,7 @@ exports[`Upload dropzone component when slot provided renders dropzone with slot
style="display: none;"
>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
style="display: none;"
>
<h3>
@ -517,7 +517,7 @@ exports[`Upload dropzone component when slot provided renders dropzone with slot
</span>
</div>
<div
class="gl-text-center mw-50"
class="gl-max-w-1/2 gl-text-center"
>
<h3>
Incoming!

View File

@ -4917,3 +4917,14 @@ export const mockMoveWorkItemMutationResponse = ({ error = undefined } = {}) =>
},
},
});
export const mockUserPreferences = (useWorkItemsView = true) => ({
data: {
currentUser: {
id: '1',
userPreferences: {
useWorkItemsView,
},
},
},
});

View File

@ -87,20 +87,20 @@ describe('Work items router', () => {
});
it('renders work item on `/1` route', async () => {
await createComponent('/1');
await createComponent('/work_items/1');
expect(wrapper.findComponent(WorkItemsRoot).exists()).toBe(true);
});
it('does not render create work item page on `/new` route if `workItemsAlpha` feature flag is off', async () => {
await createComponent('/new');
await createComponent('/work_items/new');
expect(wrapper.findComponent(CreateWorkItem).exists()).toBe(false);
});
it('renders create work item page on `/new` route', async () => {
window.gon.features.workItemsAlpha = true;
await createComponent('/new');
await createComponent('/work_items/new');
expect(wrapper.findComponent(CreateWorkItem).exists()).toBe(true);
});
@ -109,18 +109,24 @@ describe('Work items router', () => {
gon.relative_url_root = '/my-org';
const router = createRouter({ fullPath: '/work_item' });
expect(router.options.base).toBe('/my-org/work_item/-/work_items');
expect(router.options.base).toBe('/my-org/work_item/-');
});
it('includes groups in path for groups', () => {
const router = createRouter({ fullPath: '/work_item', workspaceType: 'group' });
expect(router.options.base).toBe('/groups/work_item/-/work_items');
expect(router.options.base).toBe('/groups/work_item/-');
});
it('includes workItemType if provided', () => {
const router = createRouter({ fullPath: '/work_item', workItemType: 'epics' });
it('renders work item on `/issues/1` route', async () => {
await createComponent('/issues/1');
expect(router.options.base).toBe('/work_item/-/epics');
expect(wrapper.findComponent(WorkItemsRoot).exists()).toBe(true);
});
it('renders work item on `/epics/1` route', async () => {
await createComponent('/epics/1');
expect(wrapper.findComponent(WorkItemsRoot).exists()).toBe(true);
});
});

View File

@ -0,0 +1,106 @@
import { GlToggle, GlBadge, GlPopover, GlLink } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import userPreferencesQuery from '~/work_items_feedback/graphql/user_preferences.query.graphql';
import setUseWorkItemsView from '~/work_items_feedback/graphql/set_use_work_items_view.mutation.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import { mockUserPreferences } from 'jest/work_items/mock_data';
import waitForPromises from 'helpers/wait_for_promises';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import WorkItemToggle from '~/work_items_feedback/components/work_item_view_toggle.vue';
describe('WorkItemToggle', () => {
Vue.use(VueApollo);
useMockLocationHelper();
let wrapper;
const userPreferencesViewOnQueryHandler = jest.fn().mockResolvedValue(mockUserPreferences());
const userPreferencesViewsOffQueryHandler = jest
.fn()
.mockResolvedValue(mockUserPreferences(false));
const mutationHandler = jest.fn().mockResolvedValue({
data: {
userPreferencesUpdate: {
userPreferences: {
useWorkItemsView: true,
},
},
},
});
const createComponent = ({
userPreferencesQueryHandler = userPreferencesViewOnQueryHandler,
mutationHandler: providedMutationHandler = mutationHandler,
} = {}) => {
const apolloProvider = createMockApollo([
[userPreferencesQuery, userPreferencesQueryHandler],
[setUseWorkItemsView, providedMutationHandler],
]);
wrapper = shallowMountExtended(WorkItemToggle, {
apolloProvider,
stubs: {
GlBadge,
GlPopover,
GlLink,
GlToggle,
},
});
};
const findToggle = () => wrapper.findComponent(GlToggle);
describe('template', () => {
it('displays the toggle on if useWorkItemsView from GraphQL API is on', async () => {
createComponent();
await waitForPromises();
expect(findToggle().props('value')).toBe(true);
});
it('displays the toggle off if useWorkItemsView from GraphQL API is off', async () => {
createComponent({ userPreferencesQueryHandler: userPreferencesViewsOffQueryHandler });
await waitForPromises();
expect(findToggle().props('value')).toBe(false);
});
});
describe('interaction', () => {
it('sends a mutation if toggled', async () => {
createComponent();
await waitForPromises();
await findToggle().vm.$emit('change', false);
expect(mutationHandler).toHaveBeenCalledWith({
useWorkItemsView: false,
});
});
it('refreshes the view if mutation is successful', async () => {
createComponent();
await waitForPromises();
await findToggle().vm.$emit('change', true);
await waitForPromises();
expect(findToggle().props('value')).toBe(true);
expect(window.location.reload).toHaveBeenCalled();
});
it('does not refresh the view if mutation fails', async () => {
const errorMutationHandler = jest.fn().mockRejectedValue(new Error('GraphQL error'));
createComponent({ mutationHandler: errorMutationHandler });
await waitForPromises();
await findToggle().vm.$emit('change', false);
await waitForPromises();
expect(findToggle().props('value')).toBe(true);
expect(window.location.reload).not.toHaveBeenCalled();
});
});
});

View File

@ -154,13 +154,13 @@ RSpec.describe BulkImport, type: :model, feature_category: :importers do
end
describe 'completion notification trigger' do
RSpec::Matchers.define :notify_owner_of_completion do
RSpec::Matchers.define :send_completion_notification do
def supports_block_expectations?
true
end
match(notify_expectation_failures: true) do |proc|
expect(Notify).to receive(:bulk_import_complete).with(user.id, import.id).and_call_original
expect(Notify).to receive(:bulk_import_complete).with(import.user.id, import.id).and_call_original
proc.call
true
@ -174,47 +174,23 @@ RSpec.describe BulkImport, type: :model, feature_category: :importers do
end
end
subject(:import) do
create(:bulk_import, :started, entities: [
create(
:bulk_import_entity,
group: create(:group, owners: user)
)
])
end
subject(:import) { create(:bulk_import, :started) }
let(:user) { create(:user) }
let(:non_triggering_events) do
import.status_paths.events - %i[finish cleanup_stale fail_op]
end
it { expect { import.finish! }.to notify_owner_of_completion }
it { expect { import.fail_op! }.to notify_owner_of_completion }
it { expect { import.cleanup_stale! }.to notify_owner_of_completion }
it { expect { import.finish! }.to send_completion_notification }
it { expect { import.fail_op! }.to send_completion_notification }
it { expect { import.cleanup_stale! }.to send_completion_notification }
it "does not email after non-completing events" do
non_triggering_events.each do |event|
expect { import.send(:"#{event}!") }.not_to notify_owner_of_completion
expect { import.send(:"#{event}!") }.not_to send_completion_notification
end
end
end
describe '#parent_group_entity' do
subject(:import) do
create(:bulk_import, :started, entities: [
root_node,
create(:bulk_import_entity, parent: root_node),
create(:bulk_import_entity, parent: root_node)
])
end
let_it_be(:root_node) { create(:bulk_import_entity) }
it 'returns the topmost node of the first tree of the import entity structure' do
expect(import.parent_group_entity).to eq(root_node)
end
end
describe '#destination_group_roots' do
subject(:import) do
create(:bulk_import, :started, entities: [

View File

@ -5,7 +5,8 @@ require 'spec_helper'
RSpec.describe ProcessCommitWorker, feature_category: :source_code_management do
let_it_be(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:auto_close_issues) { true }
let(:project) { create(:project, :public, :repository, autoclose_referenced_issues: auto_close_issues) }
let(:issue) { create(:issue, project: project, author: user) }
let(:commit) { project.commit }
@ -115,6 +116,31 @@ RSpec.describe ProcessCommitWorker, feature_category: :source_code_management do
end
end
end
context 'when project has issue auto close disabled' do
let(:auto_close_issues) { false }
it 'does not close related issues' do
expect { perform }.to not_change { Issues::CloseWorker.jobs.size }
end
context 'when issue is an external issue' do
let(:issue) { ExternalIssue.new('JIRA-123', project) }
let(:project) do
create(
:project,
:with_jira_integration,
:public,
:repository,
autoclose_referenced_issues: auto_close_issues
)
end
it 'closes issues that should be closed per the commit message' do
expect { perform }.to change { Issues::CloseWorker.jobs.size }.by(1)
end
end
end
end
context 'when commit has no issue references' do