Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
ad1604c833
commit
1d45975965
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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']),
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
query projectWorkItemTypes($fullPath: ID!) {
|
||||
workspace: project(fullPath: $fullPath) {
|
||||
id
|
||||
workItemTypes {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 }
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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') } }
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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", ... ]}
|
||||
```
|
||||
|
|
|
@ -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. |
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 |
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ""
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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 () => {
|
||||
|
|
|
@ -15,6 +15,16 @@ describe('Work items router', () => {
|
|||
|
||||
wrapper = mount(App, {
|
||||
router,
|
||||
provide: {
|
||||
fullPath: 'full-path',
|
||||
},
|
||||
mocks: {
|
||||
$apollo: {
|
||||
queries: {
|
||||
workItemTypes: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue