Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-02-09 18:16:19 +00:00
parent ad1604c833
commit 1d45975965
39 changed files with 523 additions and 309 deletions

View File

@ -1,6 +1,7 @@
<!-- Set the correct label and milestone using autocomplete for guidance. Please @mention only the DRI(s) for each stage or group rather than an entire department. -->
/label ~"release post" ~"release post item" ~"Technical Writing" ~devops:: ~group:: ~"release post item::deprecation"
/label ~"type::maintenance"
/milestone %
/assign `@EM/PM` (choose the DRI; remove backticks here, and below)

View File

@ -1,6 +1,7 @@
<!-- Set the correct label and milestone using autocomplete for guidance. Please @mention only the DRI(s) for each stage or group rather than an entire department. -->
/label ~"release post" ~"release post item" ~"Technical Writing" ~devops:: ~group:: ~"release post item::removal"
/label ~"type::maintenance"
/milestone %
/assign `@EM/PM` (choose the DRI; remove backticks here, and below)

View File

@ -95,7 +95,7 @@ export default {
this.renderGFM();
this.updateTaskStatusText();
if (this.workItemsEnabled) {
if (this.workItemsEnabled && this.$el) {
this.renderTaskActions();
}
},
@ -174,8 +174,11 @@ export default {
);
button.id = `js-task-button-${index}`;
this.taskButtons.push(button.id);
button.innerHTML =
'<svg data-testid="ellipsis_v-icon" role="img" aria-hidden="true" class="dropdown-icon gl-icon s14"><use href="/assets/icons-7f1680a3670112fe4c8ef57b9dfb93f0f61b43a2a479d7abd6c83bcb724b9201.svg#ellipsis_v"></use></svg>';
button.innerHTML = `
<svg data-testid="ellipsis_v-icon" role="img" aria-hidden="true" class="dropdown-icon gl-icon s14">
<use href="${gon.sprite_icons}#ellipsis_v"></use>
</svg>
`;
item.prepend(button);
});
},
@ -191,7 +194,7 @@ export default {
const taskBadge = document.createElement('span');
taskBadge.innerHTML = `
<svg data-testid="issue-open-m-icon" role="img" aria-hidden="true" class="gl-icon gl-fill-green-500 s12">
<use href="/assets/icons-7f1680a3670112fe4c8ef57b9dfb93f0f61b43a2a479d7abd6c83bcb724b9201.svg#issue-open-m"></use>
<use href="${gon.sprite_icons}#issue-open-m"></use>
</svg>
<span class="badge badge-info badge-pill gl-badge sm gl-mr-1">
${__('Task')}
@ -245,7 +248,7 @@ export default {
modal-id="create-task-modal"
:title="s__('WorkItem|New Task')"
hide-footer
body-class="gl-py-0!"
body-class="gl-p-0!"
>
<create-work-item
:is-modal="true"

View File

@ -74,6 +74,8 @@ export function initIssueApp(issueData, store) {
return undefined;
}
const { fullPath } = el.dataset;
if (gon?.features?.fixCommentScroll) {
scrollToTargetOnResize();
}
@ -88,6 +90,7 @@ export function initIssueApp(issueData, store) {
store,
provide: {
canCreateIncident,
fullPath,
},
computed: {
...mapGetters(['getNoteableData']),

View File

@ -0,0 +1,11 @@
query projectWorkItemTypes($fullPath: ID!) {
workspace: project(fullPath: $fullPath) {
id
workItemTypes {
nodes {
id
name
}
}
}
}

View File

@ -5,11 +5,15 @@ import { createApolloProvider } from './graphql/provider';
export const initWorkItemsRoot = () => {
const el = document.querySelector('#js-work-items');
const { fullPath } = el.dataset;
return new Vue({
el,
router: createRouter(el.dataset.fullPath),
apolloProvider: createApolloProvider(),
provide: {
fullPath,
},
render(createElement) {
return createElement(App);
},

View File

@ -1,6 +1,8 @@
<script>
import { GlButton, GlAlert } from '@gitlab/ui';
import { GlButton, GlAlert, GlLoadingIcon, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { s__ } from '~/locale';
import createWorkItemMutation from '../graphql/create_work_item.mutation.graphql';
import projectWorkItemTypesQuery from '../graphql/project_work_item_types.query.graphql';
import ItemTitle from '../components/item_title.vue';
@ -8,8 +10,12 @@ export default {
components: {
GlButton,
GlAlert,
GlLoadingIcon,
GlDropdown,
GlDropdownItem,
ItemTitle,
},
inject: ['fullPath'],
props: {
isModal: {
type: Boolean,
@ -25,9 +31,34 @@ export default {
data() {
return {
title: this.initialTitle,
error: false,
error: null,
workItemTypes: [],
selectedWorkItemType: null,
};
},
apollo: {
workItemTypes: {
query: projectWorkItemTypesQuery,
variables() {
return {
fullPath: this.fullPath,
};
},
update(data) {
return data.workspace?.workItemTypes?.nodes;
},
error() {
this.error = s__(
'WorkItem|Something went wrong when fetching work item types. Please try again',
);
},
},
},
computed: {
dropdownButtonText() {
return this.selectedWorkItemType?.name || s__('WorkItem|Type');
},
},
methods: {
async createWorkItem() {
try {
@ -53,7 +84,9 @@ export default {
this.$emit('onCreate', this.title);
}
} catch {
this.error = true;
this.error = s__(
'WorkItem|Something went wrong when creating a work item. Please try again',
);
}
},
handleTitleInput(title) {
@ -66,18 +99,43 @@ export default {
}
this.$emit('closeModal');
},
selectWorkItemType(type) {
this.selectedWorkItemType = type;
},
},
};
</script>
<template>
<form @submit.prevent="createWorkItem">
<gl-alert v-if="error" variant="danger" @dismiss="error = false">{{
__('Something went wrong when creating a work item. Please try again')
}}</gl-alert>
<item-title :initial-title="title" data-testid="title-input" @title-input="handleTitleInput" />
<gl-alert v-if="error" variant="danger" @dismiss="error = null">{{ error }}</gl-alert>
<div :class="{ 'gl-px-5': isModal }" data-testid="content">
<item-title
:initial-title="title"
data-testid="title-input"
@title-input="handleTitleInput"
/>
<div>
<gl-dropdown :text="dropdownButtonText">
<gl-loading-icon
v-if="$apollo.queries.workItemTypes.loading"
size="md"
data-testid="loading-types"
/>
<template v-else>
<gl-dropdown-item
v-for="type in workItemTypes"
:key="type.id"
@click="selectWorkItemType(type)"
>
{{ type.name }}
</gl-dropdown-item>
</template>
</gl-dropdown>
</div>
</div>
<div
class="gl-bg-gray-10 gl-py-5 gl-px-6"
class="gl-bg-gray-10 gl-py-5 gl-px-6 gl-mt-4"
:class="{ 'gl-display-flex gl-justify-content-end': isModal }"
>
<gl-button

View File

@ -51,6 +51,14 @@ module Mutations
required: false,
description: 'Array of user IDs to assign to the issue.'
argument :move_before_id, ::Types::GlobalIDType[::Issue],
required: false,
description: 'Global ID of issue that should be placed before the current issue.'
argument :move_after_id, ::Types::GlobalIDType[::Issue],
required: false,
description: 'Global ID of issue that should be placed after the current issue.'
field :issue,
Types::IssueType,
null: true,
@ -93,6 +101,13 @@ module Mutations
params[:assignee_ids] &&= params[:assignee_ids].map { |assignee_id| assignee_id&.model_id }
params[:label_ids] &&= params[:label_ids].map { |label_id| label_id&.model_id }
if params[:move_before_id].present? || params[:move_after_id].present?
params[:move_between_ids] = [
params.delete(:move_before_id)&.model_id,
params.delete(:move_after_id)&.model_id
]
end
params
end

View File

@ -91,7 +91,7 @@ module Boards
end
def move_between_ids(move_params)
ids = [move_params[:move_after_id], move_params[:move_before_id]]
ids = [move_params[:move_before_id], move_params[:move_after_id]]
.map(&:to_i)
.map { |m| m > 0 ? m : nil }

View File

@ -494,7 +494,7 @@ class IssuableBaseService < ::BaseProjectService
def handle_move_between_ids(issuable_position)
return unless params[:move_between_ids]
after_id, before_id = params.delete(:move_between_ids)
before_id, after_id = params.delete(:move_between_ids)
positioning_scope = issuable_position.class.relative_positioning_query_base(issuable_position)

View File

@ -2,6 +2,7 @@
module Issues
class BaseService < ::IssuableBaseService
extend ::Gitlab::Utils::Override
include IncidentManagement::UsageData
include IssueTypeHelpers
@ -61,6 +62,23 @@ module Issues
issue.system_note_timestamp = params[:created_at] || params[:updated_at]
end
override :handle_move_between_ids
def handle_move_between_ids(issue)
issue.check_repositioning_allowed! if params[:move_between_ids]
super
rebalance_if_needed(issue)
end
def issuable_for_positioning(id, positioning_scope)
return unless id
issue = positioning_scope.find(id)
issue if can?(current_user, :update_issue, issue)
end
def create_assignee_note(issue, old_assignees)
SystemNoteService.change_issuable_assignees(
issue, issue.project, current_user, old_assignees)

View File

@ -21,6 +21,8 @@ module Issues
def execute(skip_system_notes: false)
@issue = @build_service.execute
handle_move_between_ids(@issue)
filter_resolve_discussion_params
create(@issue, skip_system_notes: skip_system_notes)

View File

@ -21,7 +21,7 @@ module Issues
def move_between_ids
strong_memoize(:move_between_ids) do
ids = [params[:move_after_id], params[:move_before_id]]
ids = [params[:move_before_id], params[:move_after_id]]
.map(&:to_i)
.map { |m| m > 0 ? m : nil }

View File

@ -2,8 +2,6 @@
module Issues
class UpdateService < Issues::BaseService
extend ::Gitlab::Utils::Override
# NOTE: For Issues::UpdateService, we default the spam_params to nil, because spam_checking is not
# necessary in many cases, and we don't want to require every caller to explicitly pass it as nil
# to disable spam checking.
@ -92,14 +90,6 @@ module Issues
todo_service.update_issue(issuable, current_user)
end
def handle_move_between_ids(issue)
issue.check_repositioning_allowed! if params[:move_between_ids]
super
rebalance_if_needed(issue)
end
# rubocop: disable CodeReuse/ActiveRecord
def change_issue_duplicate(issue)
canonical_issue_id = params.delete(:canonical_issue_id)
@ -217,14 +207,6 @@ module Issues
).execute
end
def issuable_for_positioning(id, positioning_scope)
return unless id
issue = positioning_scope.find(id)
issue if can?(current_user, :update_issue, issue)
end
def create_confidentiality_note(issue)
SystemNoteService.change_issue_confidentiality(issue, issue.project, current_user)
end

View File

@ -3,4 +3,4 @@
%h4.pt-3.pb-3= _("Validate your GitLab CI configuration")
#js-ci-lint{ data: { endpoint: project_ci_lint_path(@project), pipeline_simulation_help_page_path: help_page_path('ci/lint', anchor: 'pipeline-simulation') , lint_help_page_path: help_page_path('ci/lint', anchor: 'validate-basic-logic-and-syntax') } }
#js-ci-lint{ data: { endpoint: project_ci_lint_path(@project), pipeline_simulation_help_page_path: help_page_path('ci/lint', anchor: 'simulate-a-pipeline') , lint_help_page_path: help_page_path('ci/lint', anchor: 'check-cicd-syntax') } }

View File

@ -36,5 +36,5 @@
= link_to edit_pipeline_schedule_path(pipeline_schedule), title: _('Edit'), class: 'btn gl-button btn-default btn-icon' do
= sprite_icon('pencil')
- if can?(current_user, :admin_pipeline_schedule, pipeline_schedule)
= link_to pipeline_schedule_path(pipeline_schedule), title: _('Delete'), method: :delete, class: 'btn gl-button btn-danger btn-icon', data: { confirm: _("Are you sure you want to delete this pipeline schedule?") } do
= link_to pipeline_schedule_path(pipeline_schedule), title: _('Delete'), method: :delete, class: 'btn gl-button btn-danger btn-icon', aria: { label: _('Delete pipeline schedule') }, data: { confirm: _("Are you sure you want to delete this pipeline schedule?"), confirm_btn_variant: 'danger' } do
= sprite_icon('remove')

View File

@ -3,7 +3,7 @@
.issue-details.issuable-details
.detail-page-description.content-block
#js-issuable-app{ data: { initial: issuable_initial_data(issuable).to_json} }
#js-issuable-app{ data: { initial: issuable_initial_data(issuable).to_json, full_path: @project.full_path } }
.title-container
%h2.title= markdown_field(issuable, :title)
- if issuable.description.present?

View File

@ -62,7 +62,7 @@ You may need to import projects from external sources like GitHub, Bitbucket, or
### Popular project imports
- [GitHub Enterprise to self-managed GitLab](../integration/github.md#enabling-github-oauth): Enabling OAuth makes it easier for developers to find and import their projects.
- [GitHub Enterprise to self-managed GitLab](../integration/github.md): Enabling OAuth makes it easier for developers to find and import their projects.
- [Bitbucket Server](../user/project/import/bitbucket_server.md#limitations): There are certain data limitations.
For assistance with these data types, contact your GitLab account manager or GitLab Support about our professional migration services.

View File

@ -426,3 +426,29 @@ Examples:
curl --request DELETE --data 'name_regex_delete=.*' --data 'older_than=1month' \
--header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
```
## Instance-wide endpoints
Beside the group- and project-specific GitLab APIs explained above,
the Container Registry has its own endpoints.
To query those, follow the Registry's built-in mechanism to obtain and use an
[authentication token](https://docs.docker.com/registry/spec/auth/token/).
NOTE:
These are different from project or personal access tokens in the GitLab application.
### Listing all container repositories
```plaintext
GET /v2/_catalogue
```
To list all container repositories on your GitLab instance, admin credentials are required:
```shell
$ curl --request GET --user "<admin-username>:<admin-password>" "https://gitlab.example.com/jwt/auth?service=container_registry&scope=registry:catalog:*"
{"token":" ... "}
$ curl --header "Authorization: Bearer <token_from_above>" https://gitlab.example.com:5050/v2/_catalog
{"repositories":["user/project1", "group/subgroup/project2", ... ]}
```

View File

@ -1420,6 +1420,8 @@ Input type: `CreateIssueInput`
| <a id="mutationcreateissuelocked"></a>`locked` | [`Boolean`](#boolean) | Indicates discussion is locked on the issue. |
| <a id="mutationcreateissuemergerequesttoresolvediscussionsof"></a>`mergeRequestToResolveDiscussionsOf` | [`MergeRequestID`](#mergerequestid) | IID of a merge request for which to resolve discussions. |
| <a id="mutationcreateissuemilestoneid"></a>`milestoneId` | [`MilestoneID`](#milestoneid) | ID of the milestone to assign to the issue. On update milestone will be removed if set to null. |
| <a id="mutationcreateissuemoveafterid"></a>`moveAfterId` | [`IssueID`](#issueid) | Global ID of issue that should be placed after the current issue. |
| <a id="mutationcreateissuemovebeforeid"></a>`moveBeforeId` | [`IssueID`](#issueid) | Global ID of issue that should be placed before the current issue. |
| <a id="mutationcreateissueprojectpath"></a>`projectPath` | [`ID!`](#id) | Project full path the issue is associated with. |
| <a id="mutationcreateissuetitle"></a>`title` | [`String!`](#string) | Title of the issue. |
| <a id="mutationcreateissuetype"></a>`type` | [`IssueType`](#issuetype) | Type of the issue. |

View File

@ -169,7 +169,7 @@ POST /projects/:id/ci/lint
| Attribute | Type | Required | Description |
| ---------- | ------- | -------- | -------- |
| `content` | string | yes | The CI/CD configuration content. |
| `dry_run` | boolean | no | Run [pipeline creation simulation](../ci/lint.md#pipeline-simulation), or only do static check. This is false by default. |
| `dry_run` | boolean | no | Run [pipeline creation simulation](../ci/lint.md#simulate-a-pipeline), or only do static check. This is false by default. |
| `include_jobs` | boolean | no | If the list of jobs that would exist in a static check or pipeline simulation should be included in the response. This is false by default. |
Example request:

View File

@ -16,7 +16,7 @@ Watch a video on [Using GitLab CI/CD pipelines with GitHub repositories](https:/
NOTE:
Because of [GitHub limitations](https://gitlab.com/gitlab-org/gitlab/-/issues/9147),
[GitHub OAuth](../../integration/github.md#enabling-github-oauth)
[GitHub OAuth](../../integration/github.md#enable-github-oauth-in-gitlab)
cannot be used to authenticate with GitHub as an external CI/CD repository.
## Connect with Personal Access Token

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -4,48 +4,54 @@ group: Pipeline Authoring
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Validate `.gitlab-ci.yml` syntax with the CI Lint tool **(FREE)**
# Validate GitLab CI/CD configuration **(FREE)**
If you want to test the validity of your GitLab CI/CD configuration before committing
the changes, you can use the CI Lint tool. This tool checks for syntax and logical
errors by default, and can simulate pipeline creation to try to find more complicated
issues as well.
Use the CI Lint tool to check the validity of GitLab CI/CD configuration.
You can validate the syntax from a `.gitlab-ci.yml` file or any other sample CI/CD configuration.
This tool checks for syntax and logic errors, and can simulate pipeline
creation to try to find more complicated configuration problems.
To access the CI Lint tool, navigate to **CI/CD > Pipelines** or **CI/CD > Jobs**
in your project and click **CI lint**.
If you use the [pipeline editor](pipeline_editor/index.md), it verifies configuration
syntax automatically.
If you use VS Code, you can also validate your CI/CD configuration with the
If you use VS Code, you can validate your CI/CD configuration with the
[GitLab Workflow VS Code extension](../user/project/repository/vscode.md).
## Validate basic logic and syntax
## Check CI/CD syntax
By default, the CI lint checks the syntax of your CI YAML configuration and also runs
some basic logical validations. Configuration added with the [`includes` keyword](yaml/index.md#include),
is also validated.
The CI lint tool checks the syntax of GitLab CI/CD configuration, including
configuration added with the [`includes` keyword](yaml/index.md#include).
To use the CI lint, paste a complete CI configuration (`.gitlab-ci.yml` for example)
into the text box and click **Validate**:
To check CI/CD configuration with the CI lint tool:
![CI Lint](img/ci_lint.png)
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select one of:
- **CI/CD > Pipelines**
- **CI/CD > Jobs**
1. In the top right, select **CI lint**.
1. Paste a copy of the CI/CD configuration you want to check into the text box.
1. Select **Validate**.
## Pipeline simulation
## Simulate a pipeline
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/229794) in GitLab 13.3.
Not all pipeline configuration issues can be found by the [basic CI lint validation](#validate-basic-logic-and-syntax).
You can simulate the creation of a pipeline for deeper validation that can discover
more complicated issues.
You can simulate the creation of a GitLab CI/CD pipeline to find more complicated issues,
including problems with [`needs`](yaml/index.md#needs) and [`rules`](yaml/index.md#rules)
configuration. A simulation runs as a Git `push` event on the default branch.
To validate the configuration by running a pipeline simulation:
Prerequisites:
1. Paste the GitLab CI configuration to verify into the text box.
1. Select the **Simulate pipeline creation for the default branch** checkbox.
- You must have [permissions](../user/permissions.md#project-members-permissions)
to create pipelines on this branch to validate with a simulation.
To simulate a pipeline:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select one of:
- **CI/CD > Pipelines**
- **CI/CD > Jobs**
1. In the top right, select **CI lint**.
1. Paste a copy of the CI/CD configuration you want to check into the text box.
1. Select **Simulate pipeline creation for the default branch**.
1. Select **Validate**.
![Dry run](img/ci_lint_dry_run.png)
### Pipeline simulation limitations
Simulations run as `git push` events against the default branch. You must have
[permissions](../user/permissions.md#project-members-permissions) to create pipelines
on this branch to validate with a simulation.

View File

@ -36,7 +36,7 @@ file is correct. Paste in full `.gitlab-ci.yml` files or individual jobs configu
to verify the basic syntax.
When a `.gitlab-ci.yml` file is present in a project, you can also use the CI Lint
tool to [simulate the creation of a full pipeline](lint.md#pipeline-simulation).
tool to [simulate the creation of a full pipeline](lint.md#simulate-a-pipeline).
It does deeper verification of the configuration syntax.
## Verify variables

View File

@ -5,10 +5,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
description: What to include in GitLab documentation pages.
---
# Documentation topic types
# Documentation topic types (CTRT)
At GitLab, we have not traditionally used types for our content. However, we are starting to
move in this direction, and we now use four primary topic types:
move in this direction, and we now use four primary topic types (CTRT):
- [Concept](#concept)
- [Task](#task)
@ -154,7 +154,7 @@ If multiple causes or workarounds exist, consider putting them into a table form
## Other types of content
There are other types of content in the GitLab documentation that don't
classify as one of the four primary [topic types](#documentation-topic-types).
classify as one of the four primary [topic types](#documentation-topic-types-ctrt).
These include:
- [Tutorials](#tutorials)
@ -174,7 +174,7 @@ In general, you might consider using a tutorial when:
Tutorials are learning aids that complement our core documentation.
They do not introduce new features.
Always use the primary [topic types](#documentation-topic-types) to document new features.
Always use the primary [topic types](#documentation-topic-types-ctrt) to document new features.
Tutorials should be in this format:

View File

@ -185,30 +185,6 @@ end
Duplicate jobs can happen when the TTL is reached, so make sure you lower this only for jobs
that can tolerate some duplication.
## Deduplication with load balancing
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6763) in GitLab 14.4.
Jobs that declare either `:sticky` or `:delayed` data consistency
are eligible for database load-balancing.
In both cases, jobs are [scheduled in the future](#scheduling-jobs-in-the-future) with a short delay (1 second).
This minimizes the chance of replication lag after a write.
If you really want to deduplicate jobs eligible for load balancing,
specify `including_scheduled: true` argument when defining deduplication strategy:
```ruby
class DelayedIdempotentWorker
include ApplicationWorker
data_consistency :delayed
deduplicate :until_executing, including_scheduled: true
idempotent!
# ...
end
```
### Preserve the latest WAL location for idempotent jobs
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69372) in GitLab 14.3.

View File

@ -259,10 +259,11 @@ these scenarios, since `:always` should be considered the exception, not the rul
To allow for reads to be served from replicas, we added two additional consistency modes: `:sticky` and `:delayed`.
When you declare either `:sticky` or `:delayed` consistency, workers become eligible for database
load-balancing. In both cases, jobs are enqueued with a short delay.
This minimizes the likelihood of replication lag after a write.
load-balancing.
The difference is in what happens when there is replication lag after the delay: `sticky` workers
In both cases, if the replica is not up-to-date and the time from scheduling the job was less than the minimum delay interval,
the jobs sleep up to the minimum delay interval (0.8 seconds). This gives the replication process time to finish.
The difference is in what happens when there is still replication lag after the delay: `sticky` workers
switch over to the primary right away, whereas `delayed` workers fail fast and are retried once.
If they still encounter replication lag, they also switch to the primary instead.
**If your worker never performs any writes, it is strongly advised to apply one of these consistency settings,

View File

@ -4,116 +4,117 @@ group: Integrations
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Integrate your GitLab instance with GitHub **(FREE SELF)**
# Use GitHub as an authentication provider **(FREE SELF)**
You can integrate your GitLab instance with GitHub.com and GitHub Enterprise. This integration
enables users to import projects from GitHub, or sign in to your GitLab instance
with their GitHub account.
You can integrate your GitLab instance with GitHub.com and GitHub Enterprise.
You can import projects from GitHub, or sign in to GitLab
with your GitHub credentials.
## Security check
## Create an OAuth app in GitHub
Some integrations risk compromising GitLab accounts. To help mitigate this
[OAuth 2 covert redirect](https://oauth.net/advisories/2014-1-covert-redirect/)
vulnerability, append `/users/auth` to the end of the authorization callback URL.
To enable the GitHub OmniAuth provider, you need an OAuth 2.0 client ID and client
secret from GitHub:
1. Sign in to GitHub.
1. [Create an OAuth App](https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app)
and provide the following information:
- The URL of your GitLab instance, such as `https://gitlab.example.com`.
- The authorization callback URL, such as, `https://gitlab.example.com/users/auth`.
Include the port number if your GitLab instance uses a non-default port.
### Check for security vulnerabilities
For some integrations, the [OAuth 2 covert redirect](https://oauth.net/advisories/2014-1-covert-redirect/)
vulnerability can compromise GitLab accounts.
To mitigate this vulnerability, append `/users/auth` to the authorization
callback URL.
However, as far as we know, GitHub does not validate the subdomain part of the `redirect_uri`.
This means that a subdomain takeover, an XSS, or an open redirect on any subdomain of
Therefore, a subdomain takeover, an XSS, or an open redirect on any subdomain of
your website could enable the covert redirect attack.
## Enabling GitHub OAuth
## Enable GitHub OAuth in GitLab
To enable the GitHub OmniAuth provider, you need an OAuth 2 Client ID and Client Secret from GitHub. To get these credentials, sign into GitHub and follow their procedure for [Creating an OAuth App](https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app).
1. [Configure the initial settings](omniauth.md#configure-initial-settings) in GitLab.
When you create an OAuth 2 app in GitHub, you need the following information:
1. Edit the GitLab configuration file using the following information:
- The URL of your GitLab instance, such as `https://gitlab.example.com`.
- The authorization callback URL; in this case, `https://gitlab.example.com/users/auth`. Include the port number if your GitLab instance uses a non-default port.
| GitHub setting | Value in the GitLab configuration file | Description |
|----------------|----------------------------------------|-------------------------|
| Client ID | `YOUR_APP_ID` | OAuth 2.0 client ID |
| Client secret | `YOUR_APP_SECRET` | OAuth 2.0 client secret |
| URL | `https://github.example.com/` | GitHub deployment URL |
See [Configure initial settings](omniauth.md#configure-initial-settings) for initial settings.
- **For Omnibus installations**
After you have configured the GitHub provider, you need the following information. You must substitute that information in the GitLab configuration file in these next steps.
1. Open the `/etc/gitlab/gitlab.rb` file.
| Setting from GitHub | Substitute in the GitLab configuration file | Description |
|:---------------------|:---------------------------------------------|:------------|
| Client ID | `YOUR_APP_ID` | OAuth 2 Client ID |
| Client Secret | `YOUR_APP_SECRET` | OAuth 2 Client Secret |
| URL | `https://github.example.com/` | GitHub Deployment URL |
For GitHub.com, update the following section:
Follow these steps to incorporate the GitHub OAuth 2 app in your GitLab server:
```ruby
gitlab_rails['omniauth_providers'] = [
{
name: "github",
# label: "Provider name", # optional label for login button, defaults to "GitHub"
app_id: "YOUR_APP_ID",
app_secret: "YOUR_APP_SECRET",
args: { scope: "user:email" }
}
]
```
**For Omnibus installations**
For GitHub Enterprise, update the following section and replace
`https://github.example.com/` with your GitHub URL:
1. Edit `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_rails['omniauth_providers'] = [
{
name: "github",
# label: "Provider name", # optional label for login button, defaults to "GitHub"
app_id: "YOUR_APP_ID",
app_secret: "YOUR_APP_SECRET",
url: "https://github.example.com/",
args: { scope: "user:email" }
}
]
```
For GitHub.com:
1. Save the file and [reconfigure](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure)
GitLab.
```ruby
gitlab_rails['omniauth_providers'] = [
{
name: "github",
# label: "Provider name", # optional label for login button, defaults to "GitHub"
app_id: "YOUR_APP_ID",
app_secret: "YOUR_APP_SECRET",
args: { scope: "user:email" }
}
]
```
- **For installations from source**
For GitHub Enterprise:
1. Open the `config/gitlab.yml` file.
```ruby
gitlab_rails['omniauth_providers'] = [
{
name: "github",
# label: "Provider name", # optional label for login button, defaults to "GitHub"
app_id: "YOUR_APP_ID",
app_secret: "YOUR_APP_SECRET",
url: "https://github.example.com/",
args: { scope: "user:email" }
}
]
```
For GitHub.com, update the following section:
**Replace `https://github.example.com/` with your GitHub URL.**
```yaml
- { name: 'github',
# label: 'Provider name', # optional label for login button, defaults to "GitHub"
app_id: 'YOUR_APP_ID',
app_secret: 'YOUR_APP_SECRET',
args: { scope: 'user:email' } }
```
1. Save the file and [reconfigure](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) GitLab for the changes to take effect.
For GitHub Enterprise, update the following section and replace
`https://github.example.com/` with your GitHub URL:
---
```yaml
- { name: 'github',
# label: 'Provider name', # optional label for login button, defaults to "GitHub"
app_id: 'YOUR_APP_ID',
app_secret: 'YOUR_APP_SECRET',
url: "https://github.example.com/",
args: { scope: 'user:email' } }
```
**For installations from source**
1. Save the file and [restart](../administration/restart_gitlab.md#installations-from-source)
GitLab.
1. Navigate to your repository and edit `config/gitlab.yml`:
1. Refresh the GitLab sign-in page. A GitHub icon should display below the
sign-in form.
For GitHub.com:
```yaml
- { name: 'github',
# label: 'Provider name', # optional label for login button, defaults to "GitHub"
app_id: 'YOUR_APP_ID',
app_secret: 'YOUR_APP_SECRET',
args: { scope: 'user:email' } }
```
For GitHub Enterprise:
```yaml
- { name: 'github',
# label: 'Provider name', # optional label for login button, defaults to "GitHub"
app_id: 'YOUR_APP_ID',
app_secret: 'YOUR_APP_SECRET',
url: "https://github.example.com/",
args: { scope: 'user:email' } }
```
**Replace `https://github.example.com/` with your GitHub URL.**
1. Save the file and [restart](../administration/restart_gitlab.md#installations-from-source) GitLab for the changes to take effect.
---
1. Refresh the GitLab sign in page. You should now see a GitHub icon below the regular sign in form.
1. Click the icon to begin the authentication process. GitHub asks the user to sign in and authorize the GitLab application.
1. Select the icon. Sign in to GitHub and authorize the GitLab application.
## GitHub Enterprise with self-signed Certificate

View File

@ -8,79 +8,67 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/223061) in GitLab 13.4.
> - Support for `grpcs` [introduced](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/issues/7) in GitLab 13.6.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300960) in GitLab 13.10, KAS became available on GitLab.com under `wss://kas.gitlab.com` through an Early Adopter Program.
> - Introduced in GitLab 13.11, the GitLab Agent became available to every project on GitLab.com.
> - Agent Server [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300960) on GitLab.com under `wss://kas.gitlab.com` through an Early Adopter Program in GitLab 13.10.
> - The agent became available to every project on GitLab.com in GitLab 13.11.
> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) from GitLab Premium to GitLab Free in 14.5.
> - [Renamed](https://gitlab.com/groups/gitlab-org/-/epics/7167) from "GitLab Kubernetes Agent" to "GitLab Agent for Kubernetes" in GitLab 14.6.
> - [Renamed](https://gitlab.com/groups/gitlab-org/-/epics/7167) from "GitLab Kubernetes Agent" to "GitLab agent for Kubernetes" in GitLab 14.6.
The [GitLab Agent for Kubernetes](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent) ("Agent", for short)
is an active in-cluster component for connecting Kubernetes clusters to GitLab safely to support cloud-native deployment, management, and monitoring.
You can connect your Kubernetes cluster with GitLab to deploy, manage,
and monitor your cloud-native solutions. You can choose from two primary workflows.
The Agent is installed into the cluster through code, providing you with a fast, safe, stable, and scalable solution.
In a **GitOps workflow**, you keep your Kubernetes manifests in GitLab. You install a GitLab agent in your cluster, and
any time you update your manifests, the agent updates the cluster. This workflow is fully driven with Git and is considered pull-based,
because the cluster is pulling updates from your GitLab repository.
With GitOps, you can manage containerized clusters and applications from a Git repository that:
In a **CI/CD** workflow, you use GitLab CI/CD to query and update your cluster by using the Kubernetes API.
This workflow is considered push-based, because GitLab is pushing requests from GitLab CI/CD to your cluster.
- Is the single source of truth of your system.
- Is the single place where you operate your system.
- Is a single resource to monitor your system.
By combining GitLab, Kubernetes, and GitOps, it results in a robust infrastructure:
- GitLab as the GitOps operator.
- Kubernetes as the automation and convergence system.
- GitLab CI/CD as the Continuous Integration and Continuous Deployment engine.
Beyond that, you can use all the features offered by GitLab as
the all-in-one DevOps platform for your product and your team.
Both of these workflows require you to [install an agent in your cluster](install/index.md).
## Supported cluster versions
GitLab is committed to support at least two production-ready Kubernetes minor
versions at any given time. We regularly review the versions we support, and
provide a three-month deprecation period before we remove support of a specific
version. The range of supported versions is based on the evaluation of:
- The versions supported by major managed Kubernetes providers.
- The versions [supported by the Kubernetes community](https://kubernetes.io/releases/version-skew-policy/#supported-versions).
GitLab supports the following Kubernetes versions, and you can upgrade your
Kubernetes version to any supported version at any time:
GitLab supports the following Kubernetes versions. You can upgrade your
Kubernetes version to a supported version at any time:
- 1.20 (support ends on July 22, 2022)
- 1.19 (support ends on February 22, 2022)
- 1.18 (support ends on November 22, 2021)
- 1.17 (support ends on September 22, 2021)
[Adding support to other versions of Kubernetes is managed under this epic](https://gitlab.com/groups/gitlab-org/-/epics/4827).
GitLab supports at least two production-ready Kubernetes minor
versions at any given time. GitLab regularly reviews the supported versions and
provides a three-month deprecation period before removing support for a specific
version. The list of supported versions is based on:
Some GitLab features may support versions outside the range provided here.
- The versions supported by major managed Kubernetes providers.
- The versions [supported by the Kubernetes community](https://kubernetes.io/releases/version-skew-policy/#supported-versions).
## Agent's features
[This epic](https://gitlab.com/groups/gitlab-org/-/epics/4827) tracks support for other Kubernetes versions.
By using the Agent, you can:
Some GitLab features might work on versions not listed here.
- Connect GitLab with a Kubernetes cluster behind a firewall or a
Network Address Translation (NAT).
- Have real-time access to API endpoints in your cluster from GitLab CI/CD.
- Use GitOps to configure your cluster through the [Agent's repository](repository.md).
- Perform pull-based or push-based GitOps deployments.
- Configure [Network Security Alerts](#kubernetes-network-security-alerts)
based on [Container Network Policies](../../application_security/policies/index.md#container-network-policy).
- Track objects applied to your cluster through [inventory objects](../../infrastructure/clusters/deploy/inventory_object.md).
- Use the [CI/CD Tunnel](ci_cd_tunnel.md) to access Kubernetes clusters
from GitLab CI/CD jobs while keeping the cluster's APIs safe and unexposed
to the internet.
- [Deploy the GitLab Runner in a Kubernetes cluster](https://docs.gitlab.com/runner/install/kubernetes-agent.html).
- [Scan your Kubernetes cluster for vulnerabilities](../../application_security/cluster_image_scanning/index.md).
## Using Kubernetes with GitOps **(PREMIUM)**
See the [Agent roadmap](https://gitlab.com/groups/gitlab-org/-/epics/3329) to track its development.
With GitOps, you can manage containerized clusters and applications from a Git repository that:
To contribute to the Agent, see the [Agent's development documentation](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/tree/master/doc).
- Is the single source of truth of your system.
- Is the single place where you operate your system.
## Agent's GitOps workflow **(PREMIUM)**
By combining GitLab, Kubernetes, and GitOps, you can have:
The Agent uses multiple GitLab projects to provide a flexible workflow
- GitLab as the GitOps operator.
- Kubernetes as the automation and convergence system.
- GitLab CI/CD for Continuous Integration and the agent for Continuous Deployment.
Beyond that, you can use all the features offered by GitLab as
the all-in-one DevOps platform for your product and your team.
### GitOps workflow **(PREMIUM)**
The agent uses multiple GitLab projects to provide a flexible workflow
that can suit various needs. This diagram shows these repositories and the main
The agent uses multiple GitLab projects to provide a flexible workflow.
This diagram shows these repositories and the main
actors involved in a deployment:
```mermaid
@ -88,7 +76,7 @@ sequenceDiagram
participant D as Developer
participant A as Application code repository
participant M as Manifest repository
participant K as GitLab Agent
participant K as GitLab agent
participant C as Agent configuration repository
loop Regularly
K-->>C: Grab the configuration
@ -101,68 +89,28 @@ sequenceDiagram
end
```
For more details, refer to our [architecture documentation](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md#high-level-architecture) in the Agent project.
For details, view the [architecture documentation](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md#high-level-architecture).
## Install the Agent in your cluster
To perform GitOps deployments, you need:
To connect your cluster to GitLab, [install the Agent on your cluster](install/index.md).
- A properly-configured Kubernetes cluster where the GitLab agent is running.
- A project that contains the agent's configuration file (`config.yaml`) in the repository.
This file tells the agent which repositories to synchronize with the cluster.
- A project that contains Kubernetes manifests. Any changes to manifests are applied to the cluster.
## GitOps deployments **(PREMIUM)**
You can keep the agent's configuration file and Kubernetes manifests in one project, or you can use multiple.
To perform GitOps deployments with the Agent, you need:
- One GitLab project (recommended): When you use one project for both the Kubernetes manifests
and the agent's configuration file, the projects can be either private or public.
- Two GitLab projects: When you use two different GitLab projects (one for Kubernetes
manifests and another for the agent's configuration file), the project with Kubernetes manifests must
be public. The project with the agent's configuration file can be either private or public.
- A properly-configured Kubernetes cluster where the Agent is running.
- A [configuration repository](repository.md) that contains a
`config.yaml` file, which tells the Agent the repositories to synchronize
with the cluster.
- A manifest repository that contains manifest files. Any changes to manifest files are applied to the cluster.
You can use a single GitLab project or different projects for the Agent
configuration and manifest files, as follows:
- Single GitLab project (recommended): When you use a single repository to hold
both the manifest and the configuration files, these projects can be either
private or public.
- Two GitLab projects: When you use two different GitLab projects (one for
manifest files and another for configuration files), the manifests project must
be public, while the configuration project can be either private or public.
Support for separated private manifest and configuration repositories is tracked in this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/220912).
## Kubernetes Network Security Alerts **(ULTIMATE)**
> [Deprecated](https://gitlab.com/groups/gitlab-org/-/epics/7476) in GitLab 14.8, and planned for [removal](https://gitlab.com/groups/gitlab-org/-/epics/7477) in GitLab 15.0.
WARNING:
Cilium integration is in its end-of-life process. It's [deprecated](https://gitlab.com/groups/gitlab-org/-/epics/7476)
for use in GitLab 14.8, and planned for [removal](https://gitlab.com/groups/gitlab-org/-/epics/7477)
in GitLab 15.0.
The GitLab Agent also provides an integration with Cilium. This integration provides a simple way to
generate network policy-related alerts and to surface those alerts in GitLab.
There are several components that work in concert for the Agent to generate the alerts:
- A working Kubernetes cluster.
- Cilium integration through either of these options:
- Installation through [cluster management template](../../project/clusters/protect/container_network_security/quick_start_guide.md#use-the-cluster-management-template-to-install-cilium).
- Enablement of [hubble-relay](https://docs.cilium.io/en/v1.8/concepts/overview/#hubble) on an
existing installation.
- One or more network policies through any of these options:
- Use the [Container Network Policy editor](../../application_security/policies/index.md#container-network-policy-editor) to create and manage policies.
- Use an [AutoDevOps](../../application_security/policies/index.md#container-network-policy) configuration.
- Add the required labels and annotations to existing network policies.
- A configuration repository with [Cilium configured in `config.yaml`](repository.md#surface-network-security-alerts-from-cluster-to-gitlab)
The setup process follows the same [Agent's installation steps](install/index.md),
with the following differences:
- When you define a configuration repository, you must do so with [Cilium settings](repository.md#surface-network-security-alerts-from-cluster-to-gitlab).
- You do not need to specify the `gitops` configuration section.
Support for separate private projects is tracked in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/283885).
## Remove an agent
You can remove an agent using the [GitLab UI](#remove-an-agent-through-the-gitlab-ui) or through the [GraphQL API](#remove-an-agent-with-the-gitlab-graphql-api).
You can remove an agent by using the [GitLab UI](#remove-an-agent-through-the-gitlab-ui) or the [GraphQL API](#remove-an-agent-with-the-gitlab-graphql-api).
### Remove an agent through the GitLab UI
@ -170,16 +118,16 @@ You can remove an agent using the [GitLab UI](#remove-an-agent-through-the-gitla
To remove an agent from the UI:
1. Go to your agent's configuration repository.
1. From your project's sidebar, select **Infrastructure > Kubernetes clusters**.
1. Select your agent from the table, and then in the **Options** column, click the vertical ellipsis
(**{ellipsis_v}**) button and select **Delete agent**.
1. On the top bar, select **Menu > Projects** and find the project that contains the agent's configuration file.
1. From the left sidebar, select **Infrastructure > Kubernetes clusters**.
1. In the table, in the row for your agent, in the **Options** column, select the vertical ellipsis (**{ellipsis_v}**).
1. Select **Delete agent**.
### Remove an agent with the GitLab GraphQL API
1. Get the `<cluster-agent-token-id>` from a query in the interactive GraphQL explorer.
For GitLab.com, go to <https://gitlab.com/-/graphql-explorer> to open GraphQL Explorer.
For self-managed GitLab instances, go to `https://gitlab.example.com/-/graphql-explorer`, replacing `gitlab.example.com` with your own instance's URL.
- For GitLab.com, go to <https://gitlab.com/-/graphql-explorer> to open GraphQL Explorer.
- For self-managed GitLab, go to `https://gitlab.example.com/-/graphql-explorer`, replacing `gitlab.example.com` with your instance's URL.
```graphql
query{
@ -225,16 +173,48 @@ For self-managed GitLab instances, go to `https://gitlab.example.com/-/graphql-e
}
```
1. Delete the Agent in your cluster:
1. Delete the agent in your cluster:
```shell
kubectl delete -n gitlab-kubernetes-agent -f ./resources.yml
```
## Migrating to the GitLab Agent from the legacy certificate-based integration
## Migrating to the agent from the legacy certificate-based integration
Find out how to [migrate to the GitLab Agent for Kubernetes](../../infrastructure/clusters/migrate_to_gitlab_agent.md) from the certificate-based integration depending on the features you use.
Find out how to [migrate to the agent for Kubernetes](../../infrastructure/clusters/migrate_to_gitlab_agent.md) from the certificate-based integration.
## Kubernetes network security alerts **(ULTIMATE)**
> [Deprecated](https://gitlab.com/groups/gitlab-org/-/epics/7476) in GitLab 14.8, and planned for [removal](https://gitlab.com/groups/gitlab-org/-/epics/7477) in GitLab 15.0.
WARNING:
Cilium integration is in its end-of-life process. It's [deprecated](https://gitlab.com/groups/gitlab-org/-/epics/7476)
for use in GitLab 14.8, and planned for [removal](https://gitlab.com/groups/gitlab-org/-/epics/7477)
in GitLab 15.0.
The agent for Kubernetes also provides an integration with Cilium. This integration provides a simple way to
generate network policy-related alerts and to surface those alerts in GitLab.
Several components work in concert for the agent to generate the alerts:
- A working Kubernetes cluster.
- Cilium integration through either of these options:
- Installation through [cluster management template](../../project/clusters/protect/container_network_security/quick_start_guide.md#use-the-cluster-management-template-to-install-cilium).
- Enablement of [hubble-relay](https://docs.cilium.io/en/v1.8/concepts/overview/#hubble) on an
existing installation.
- One or more network policies through any of these options:
- Use the [Container Network Policy editor](../../application_security/policies/index.md#container-network-policy-editor) to create and manage policies.
- Use an [AutoDevOps](../../application_security/policies/index.md#container-network-policy) configuration.
- Add the required labels and annotations to existing network policies.
- A configuration repository with [Cilium configured in `config.yaml`](repository.md#surface-network-security-alerts-from-cluster-to-gitlab)
The setup process follows the same [agent's installation steps](install/index.md),
with the following differences:
- When you define a configuration repository, you must do so with [Cilium settings](repository.md#surface-network-security-alerts-from-cluster-to-gitlab).
- You do not need to specify the `gitops` configuration section.
## Related topics
- [Troubleshooting](troubleshooting.md)
- [Contribute to the GitLab agent's development](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/tree/master/doc)

View File

@ -11630,6 +11630,9 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
msgid "Delete pipeline schedule"
msgstr ""
msgid "Delete project"
msgstr ""
@ -33809,9 +33812,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
msgid "Something went wrong when creating a work item. Please try again"
msgstr ""
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@ -41093,6 +41093,15 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
msgid "WorkItem|Something went wrong when creating a work item. Please try again"
msgstr ""
msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
msgstr ""
msgid "WorkItem|Type"
msgstr ""
msgid "WorkItem|Work Items"
msgstr ""

View File

@ -263,7 +263,8 @@ module QA
# status as unmerged, the test will fail.
# Revisit after merge page re-architect is done https://gitlab.com/groups/gitlab-org/-/epics/5598
# To remove page refresh logic if possible
retry_until(max_attempts: 3, reload: true) do
# We don't raise on failure because this method is used as a predicate matcher
retry_until(max_attempts: 3, reload: true, raise_on_failure: false) do
has_element?(:merged_status_content, text: 'The changes were merged into', wait: 20)
end
end

View File

@ -88,7 +88,7 @@ module QA
mr.wait_until_ready_to_merge(transient_test: transient_test)
mr.retry_until(reload: true, message: 'Wait until ready to click MWPS') do
merge_request = merge_request.reload!
merge_request.reload!
# Don't try to click MWPS if the MR is merged or the pipeline is complete
break if merge_request.state == 'merged' || mr.wait_until { project.pipelines.last }[:status] == 'success'
@ -102,8 +102,10 @@ module QA
end
aggregate_failures do
expect(mr.merged?).to be_truthy, "Expected content 'The changes were merged' but it did not appear."
expect { mr.merged? }.to eventually_be_truthy.within(max_duration: 60), "Expected content 'The changes were merged' but it did not appear."
expect(merge_request.reload!.merge_when_pipeline_succeeds).to be_truthy
expect(merge_request.state).to eq('merged')
expect(project.pipelines.last[:status]).to eq('success')
end
end
end

View File

@ -34,3 +34,17 @@ export const updateWorkItemMutationResponse = {
},
},
};
export const projectWorkItemTypesQueryResponse = {
data: {
workspace: {
id: '1',
workItemTypes: {
nodes: [
{ id: 'work-item-1', name: 'Issue' },
{ id: 'work-item-2', name: 'Incident' },
],
},
},
},
};

View File

@ -1,12 +1,14 @@
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { GlAlert } from '@gitlab/ui';
import { GlAlert, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import CreateWorkItem from '~/work_items/pages/create_work_item.vue';
import ItemTitle from '~/work_items/components/item_title.vue';
import { resolvers } from '~/work_items/graphql/resolvers';
import projectWorkItemTypesQuery from '~/work_items/graphql/project_work_item_types.query.graphql';
import { projectWorkItemTypesQueryResponse } from '../mock_data';
Vue.use(VueApollo);
@ -14,13 +16,20 @@ describe('Create work item component', () => {
let wrapper;
let fakeApollo;
const querySuccessHandler = jest.fn().mockResolvedValue(projectWorkItemTypesQueryResponse);
const findAlert = () => wrapper.findComponent(GlAlert);
const findTitleInput = () => wrapper.findComponent(ItemTitle);
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findCreateButton = () => wrapper.find('[data-testid="create-button"]');
const findCancelButton = () => wrapper.find('[data-testid="cancel-button"]');
const findContent = () => wrapper.find('[data-testid="content"]');
const findLoadingTypesIcon = () => wrapper.find('[data-testid="loading-types"]');
const createComponent = ({ data = {}, props = {} } = {}) => {
fakeApollo = createMockApollo([], resolvers);
const createComponent = ({ data = {}, props = {}, queryHandler = querySuccessHandler } = {}) => {
fakeApollo = createMockApollo([[projectWorkItemTypesQuery, queryHandler]], resolvers);
wrapper = shallowMount(CreateWorkItem, {
apolloProvider: fakeApollo,
data() {
@ -37,6 +46,9 @@ describe('Create work item component', () => {
push: jest.fn(),
},
},
provide: {
fullPath: 'full-path',
},
});
};
@ -84,6 +96,10 @@ describe('Create work item component', () => {
it('does not add right margin for cancel button', () => {
expect(findCancelButton().classes()).not.toContain('gl-mr-3');
});
it('does not add padding for content', () => {
expect(findContent().classes('gl-px-5')).toBe(false);
});
});
describe('when displayed in a modal', () => {
@ -118,6 +134,44 @@ describe('Create work item component', () => {
it('adds right margin for cancel button', () => {
expect(findCancelButton().classes()).toContain('gl-mr-3');
});
it('adds padding for content', () => {
expect(findContent().classes('gl-px-5')).toBe(true);
});
});
it('displays a loading icon inside dropdown when work items query is loading', () => {
createComponent();
expect(findLoadingTypesIcon().exists()).toBe(true);
});
it('displays an alert when work items query is rejected', async () => {
createComponent({ queryHandler: jest.fn().mockRejectedValue('Houston, we have a problem') });
await waitForPromises();
expect(findAlert().exists()).toBe(true);
expect(findAlert().text()).toContain('fetching work item types');
});
describe('when work item types are fetched', () => {
beforeEach(() => {
createComponent();
return waitForPromises();
});
it('displays a list of work item types', () => {
expect(findDropdownItems()).toHaveLength(2);
expect(findDropdownItems().at(0).text()).toContain('Issue');
});
it('selects a work item type on click', async () => {
expect(findDropdown().props('text')).toBe('Type');
findDropdownItems().at(0).vm.$emit('click');
await nextTick();
expect(findDropdown().props('text')).toBe('Issue');
});
});
it('hides the alert on dismissing the error', async () => {

View File

@ -15,6 +15,16 @@ describe('Work items router', () => {
wrapper = mount(App, {
router,
provide: {
fullPath: 'full-path',
},
mocks: {
$apollo: {
queries: {
workItemTypes: {},
},
},
},
});
};

View File

@ -52,5 +52,22 @@ RSpec.describe 'Create an issue' do
it_behaves_like 'has spam protection' do
let(:mutation_class) { ::Mutations::Issues::Create }
end
context 'when position params are provided' do
let(:existing_issue) { create(:issue, project: project, relative_position: 50) }
before do
input.merge!(
move_after_id: existing_issue.to_global_id.to_s
)
end
it 'sets the correct position' do
post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response['issue']['relativePosition']).to be < existing_issue.relative_position
end
end
end
end

View File

@ -92,6 +92,23 @@ RSpec.describe Issues::CreateService do
end
end
context 'when setting a position' do
let(:issue_before) { create(:issue, project: project, relative_position: 10) }
let(:issue_after) { create(:issue, project: project, relative_position: 50) }
before do
project.add_reporter(user)
opts.merge!(move_between_ids: [issue_before.id, issue_after.id])
end
it 'sets the correct relative position' do
expect(issue).to be_persisted
expect(issue.relative_position).to be_present
expect(issue.relative_position).to be_between(issue_before.relative_position, issue_after.relative_position)
end
end
it_behaves_like 'not an incident issue'
context 'when issue is incident type' do