Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
1c6e8c1498
commit
9e74a704bc
|
@ -1 +1 @@
|
|||
ac9d905cb3e40b2c7cdd5369d858d608c95cf168
|
||||
320f41869d84d64ebbec8d3e0febfb37eca05ffb
|
||||
|
|
|
@ -1,97 +1,50 @@
|
|||
<script>
|
||||
import { GlSorting, GlSortingItem, GlFilteredSearch } from '@gitlab/ui';
|
||||
import { mapState, mapActions } from 'vuex';
|
||||
import { __, s__ } from '~/locale';
|
||||
import { ASCENDING_ODER, DESCENDING_ORDER } from '../constants';
|
||||
import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
|
||||
import getTableHeaders from '../utils';
|
||||
import PackageTypeToken from './tokens/package_type_token.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlSorting,
|
||||
GlSortingItem,
|
||||
GlFilteredSearch,
|
||||
},
|
||||
tokens: [
|
||||
{
|
||||
type: 'type',
|
||||
icon: 'package',
|
||||
title: s__('PackageRegistry|Type'),
|
||||
unique: true,
|
||||
token: PackageTypeToken,
|
||||
operators: [{ value: '=', description: __('is'), default: 'true' }],
|
||||
},
|
||||
],
|
||||
components: { RegistrySearch },
|
||||
computed: {
|
||||
...mapState({
|
||||
isGroupPage: (state) => state.config.isGroupPage,
|
||||
orderBy: (state) => state.sorting.orderBy,
|
||||
sort: (state) => state.sorting.sort,
|
||||
sorting: (state) => state.sorting,
|
||||
filter: (state) => state.filter,
|
||||
}),
|
||||
internalFilter: {
|
||||
get() {
|
||||
return this.filter;
|
||||
},
|
||||
set(value) {
|
||||
this.setFilter(value);
|
||||
},
|
||||
},
|
||||
sortText() {
|
||||
const field = this.sortableFields.find((s) => s.orderBy === this.orderBy);
|
||||
return field ? field.label : '';
|
||||
},
|
||||
sortableFields() {
|
||||
return getTableHeaders(this.isGroupPage);
|
||||
},
|
||||
isSortAscending() {
|
||||
return this.sort === ASCENDING_ODER;
|
||||
},
|
||||
tokens() {
|
||||
return [
|
||||
{
|
||||
type: 'type',
|
||||
icon: 'package',
|
||||
title: s__('PackageRegistry|Type'),
|
||||
unique: true,
|
||||
token: PackageTypeToken,
|
||||
operators: [{ value: '=', description: __('is'), default: 'true' }],
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setSorting', 'setFilter']),
|
||||
onDirectionChange() {
|
||||
const sort = this.isSortAscending ? DESCENDING_ORDER : ASCENDING_ODER;
|
||||
this.setSorting({ sort });
|
||||
this.$emit('sort:changed');
|
||||
},
|
||||
onSortItemClick(item) {
|
||||
this.setSorting({ orderBy: item });
|
||||
this.$emit('sort:changed');
|
||||
},
|
||||
clearSearch() {
|
||||
this.setFilter([]);
|
||||
this.$emit('filter:changed');
|
||||
updateSorting(newValue) {
|
||||
this.setSorting(newValue);
|
||||
this.$emit('update');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-display-flex gl-p-5 gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100">
|
||||
<gl-filtered-search
|
||||
v-model="internalFilter"
|
||||
class="gl-mr-4 gl-flex-fill-1"
|
||||
:placeholder="__('Filter results')"
|
||||
:available-tokens="tokens"
|
||||
@submit="$emit('filter:changed')"
|
||||
@clear="clearSearch"
|
||||
/>
|
||||
<gl-sorting
|
||||
:text="sortText"
|
||||
:is-ascending="isSortAscending"
|
||||
@sortDirectionChange="onDirectionChange"
|
||||
>
|
||||
<gl-sorting-item
|
||||
v-for="item in sortableFields"
|
||||
ref="packageListSortItem"
|
||||
:key="item.orderBy"
|
||||
@click="onSortItemClick(item.orderBy)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</gl-sorting-item>
|
||||
</gl-sorting>
|
||||
</div>
|
||||
<registry-search
|
||||
:filter="filter"
|
||||
:sorting="sorting"
|
||||
:tokens="$options.tokens"
|
||||
:sortable-fields="sortableFields"
|
||||
@sorting:changed="updateSorting"
|
||||
@filter:changed="setFilter"
|
||||
@filter:submit="$emit('update')"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -75,7 +75,7 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<package-title :package-help-url="packageHelpUrl" :packages-count="packagesCount" />
|
||||
<package-search @sort:changed="requestPackagesList" @filter:changed="requestPackagesList" />
|
||||
<package-search @update="requestPackagesList" />
|
||||
|
||||
<package-list @page:changed="onPageChanged" @package:delete="onPackageDeleteRequest">
|
||||
<template #empty-state>
|
||||
|
|
|
@ -26,9 +26,6 @@ export const LIST_LABEL_PACKAGE_TYPE = __('Type');
|
|||
export const LIST_LABEL_CREATED_AT = __('Published');
|
||||
export const LIST_LABEL_ACTIONS = '';
|
||||
|
||||
export const ASCENDING_ODER = 'asc';
|
||||
export const DESCENDING_ORDER = 'desc';
|
||||
|
||||
// The following is not translated because it is used to build a JavaScript exception error message
|
||||
export const MISSING_DELETE_PATH_ERROR = 'Missing delete_api_path link';
|
||||
|
||||
|
|
|
@ -128,12 +128,9 @@ export default {
|
|||
</template>
|
||||
|
||||
<template #content>
|
||||
<terraform-plan
|
||||
v-for="(plan, key) in plansObject"
|
||||
:key="key"
|
||||
:plan="plan"
|
||||
class="mr-widget-body"
|
||||
/>
|
||||
<div class="mr-widget-body gl-pb-1">
|
||||
<terraform-plan v-for="(plan, key) in plansObject" :key="key" :plan="plan" />
|
||||
</div>
|
||||
</template>
|
||||
</mr-widget-expanable-section>
|
||||
</section>
|
||||
|
|
|
@ -64,16 +64,16 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-display-flex">
|
||||
<div class="gl-display-flex gl-pb-3">
|
||||
<span
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-mr-3 gl-align-self-start gl-mt-1"
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-align-self-start gl-px-2"
|
||||
>
|
||||
<gl-icon :name="iconType" :size="18" data-testid="change-type-icon" />
|
||||
<gl-icon :name="iconType" :size="16" data-testid="change-type-icon" />
|
||||
</span>
|
||||
|
||||
<div class="gl-display-flex gl-flex-fill-1 gl-flex-direction-column flex-md-row">
|
||||
<div class="gl-flex-fill-1 gl-display-flex gl-flex-direction-column">
|
||||
<p class="gl-m-0 gl-pr-1">
|
||||
<div class="gl-display-flex gl-flex-fill-1 gl-flex-direction-column flex-md-row gl-pl-3">
|
||||
<div class="gl-flex-fill-1 gl-display-flex gl-flex-direction-column gl-pr-3">
|
||||
<p class="gl-mb-3 gl-line-height-normal">
|
||||
<gl-sprintf :message="reportHeaderText">
|
||||
<template #name>
|
||||
<strong>{{ plan.job_name }}</strong>
|
||||
|
@ -81,7 +81,7 @@ export default {
|
|||
</gl-sprintf>
|
||||
</p>
|
||||
|
||||
<p class="gl-m-0">
|
||||
<p class="gl-mb-3 gl-line-height-normal">
|
||||
<gl-sprintf :message="reportChangeText">
|
||||
<template #addNum>
|
||||
<strong>{{ addNum }}</strong>
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
<script>
|
||||
import { GlSorting, GlSortingItem, GlFilteredSearch } from '@gitlab/ui';
|
||||
|
||||
const ASCENDING_ORDER = 'asc';
|
||||
const DESCENDING_ORDER = 'desc';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlSorting,
|
||||
GlSortingItem,
|
||||
GlFilteredSearch,
|
||||
},
|
||||
props: {
|
||||
filter: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
sorting: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
tokens: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
sortableFields: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
internalFilter: {
|
||||
get() {
|
||||
return this.filter;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('filter:changed', value);
|
||||
},
|
||||
},
|
||||
sortText() {
|
||||
const field = this.sortableFields.find((s) => s.orderBy === this.sorting.orderBy);
|
||||
return field ? field.label : '';
|
||||
},
|
||||
isSortAscending() {
|
||||
return this.sorting.sort === ASCENDING_ORDER;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onDirectionChange() {
|
||||
const sort = this.isSortAscending ? DESCENDING_ORDER : ASCENDING_ORDER;
|
||||
this.$emit('sorting:changed', { sort });
|
||||
},
|
||||
onSortItemClick(item) {
|
||||
this.$emit('sorting:changed', { orderBy: item });
|
||||
},
|
||||
clearSearch() {
|
||||
this.$emit('filter:changed', []);
|
||||
this.$emit('filter:submit');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-display-flex gl-p-5 gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100">
|
||||
<gl-filtered-search
|
||||
v-model="internalFilter"
|
||||
class="gl-mr-4 gl-flex-fill-1"
|
||||
:placeholder="__('Filter results')"
|
||||
:available-tokens="tokens"
|
||||
@submit="$emit('filter:submit')"
|
||||
@clear="clearSearch"
|
||||
/>
|
||||
<gl-sorting
|
||||
:text="sortText"
|
||||
:is-ascending="isSortAscending"
|
||||
@sortDirectionChange="onDirectionChange"
|
||||
>
|
||||
<gl-sorting-item
|
||||
v-for="item in sortableFields"
|
||||
ref="packageListSortItem"
|
||||
:key="item.orderBy"
|
||||
@click="onSortItemClick(item.orderBy)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</gl-sorting-item>
|
||||
</gl-sorting>
|
||||
</div>
|
||||
</template>
|
|
@ -397,6 +397,14 @@ class ProjectsController < Projects::ApplicationController
|
|||
]
|
||||
end
|
||||
|
||||
def project_setting_attributes
|
||||
%i[
|
||||
show_default_award_emojis
|
||||
squash_option
|
||||
allow_editing_commit_messages
|
||||
]
|
||||
end
|
||||
|
||||
def project_params_attributes
|
||||
[
|
||||
:allow_merge_on_skipped_pipeline,
|
||||
|
@ -434,11 +442,7 @@ class ProjectsController < Projects::ApplicationController
|
|||
:suggestion_commit_message,
|
||||
:packages_enabled,
|
||||
:service_desk_enabled,
|
||||
project_setting_attributes: %i[
|
||||
show_default_award_emojis
|
||||
squash_option
|
||||
allow_editing_commit_messages
|
||||
]
|
||||
project_setting_attributes: project_setting_attributes
|
||||
] + [project_feature_attributes: project_feature_attributes]
|
||||
end
|
||||
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Arguments:
|
||||
# params:
|
||||
# project: Project model - Find deployments for this project
|
||||
# updated_after: DateTime
|
||||
# updated_before: DateTime
|
||||
# finished_after: DateTime
|
||||
# finished_before: DateTime
|
||||
# environment: String
|
||||
# status: String (see Deployment.statuses)
|
||||
# order_by: String (see ALLOWED_SORT_VALUES constant)
|
||||
# sort: String (asc | desc)
|
||||
class DeploymentsFinder
|
||||
attr_reader :project, :params
|
||||
attr_reader :params
|
||||
|
||||
ALLOWED_SORT_VALUES = %w[id iid created_at updated_at ref].freeze
|
||||
ALLOWED_SORT_VALUES = %w[id iid created_at updated_at ref finished_at].freeze
|
||||
DEFAULT_SORT_VALUE = 'id'
|
||||
|
||||
ALLOWED_SORT_DIRECTIONS = %w[asc desc].freeze
|
||||
DEFAULT_SORT_DIRECTION = 'asc'
|
||||
|
||||
def initialize(project, params = {})
|
||||
@project = project
|
||||
def initialize(params = {})
|
||||
@params = params
|
||||
end
|
||||
|
||||
|
@ -19,33 +29,20 @@ class DeploymentsFinder
|
|||
items = by_updated_at(items)
|
||||
items = by_environment(items)
|
||||
items = by_status(items)
|
||||
items = preload_associations(items)
|
||||
items = by_finished_between(items)
|
||||
sort(items)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def init_collection
|
||||
project
|
||||
.deployments
|
||||
.includes(
|
||||
:user,
|
||||
environment: [],
|
||||
deployable: {
|
||||
job_artifacts: [],
|
||||
pipeline: {
|
||||
project: {
|
||||
route: [],
|
||||
namespace: :route
|
||||
}
|
||||
},
|
||||
project: {
|
||||
namespace: :route
|
||||
}
|
||||
}
|
||||
)
|
||||
if params[:project]
|
||||
params[:project].deployments
|
||||
else
|
||||
Deployment.none
|
||||
end
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def sort(items)
|
||||
|
@ -68,6 +65,12 @@ class DeploymentsFinder
|
|||
end
|
||||
end
|
||||
|
||||
def by_finished_between(items)
|
||||
items = items.finished_between(params[:finished_after], params[:finished_before].presence) if params[:finished_after].present?
|
||||
|
||||
items
|
||||
end
|
||||
|
||||
def by_status(items)
|
||||
return items unless params[:status].present?
|
||||
|
||||
|
@ -87,4 +90,27 @@ class DeploymentsFinder
|
|||
sort_values['id'] = sort_values.delete('created_at') if sort_values['created_at'] # Sorting by `id` produces the same result as sorting by `created_at`
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def preload_associations(scope)
|
||||
scope.includes(
|
||||
:user,
|
||||
environment: [],
|
||||
deployable: {
|
||||
job_artifacts: [],
|
||||
pipeline: {
|
||||
project: {
|
||||
route: [],
|
||||
namespace: :route
|
||||
}
|
||||
},
|
||||
project: {
|
||||
namespace: :route
|
||||
}
|
||||
}
|
||||
)
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
end
|
||||
|
||||
DeploymentsFinder.prepend_if_ee('EE::DeploymentsFinder')
|
||||
|
|
|
@ -27,11 +27,11 @@ module InProductMarketingHelper
|
|||
end
|
||||
|
||||
def in_product_marketing_logo(track, series)
|
||||
inline_image_link('mailers/in_product_marketing', "#{track}-#{series}.png", width: '150')
|
||||
inline_image_link('mailers/in_product_marketing', "#{track}-#{series}.png", { width: '150', style: 'width: 150px;' })
|
||||
end
|
||||
|
||||
def about_link(folder, image, width)
|
||||
link_to inline_image_link(folder, image, { width: width, alt: s_('InProductMarketing|go to about.gitlab.com') }), 'https://about.gitlab.com/'
|
||||
link_to inline_image_link(folder, image, { width: width, style: "width: #{width}px;", alt: s_('InProductMarketing|go to about.gitlab.com') }), 'https://about.gitlab.com/'
|
||||
end
|
||||
|
||||
def in_product_marketing_tagline(track, series)
|
||||
|
@ -344,7 +344,7 @@ module InProductMarketingHelper
|
|||
end
|
||||
|
||||
def inline_image_link(folder, image, **options)
|
||||
attachments[image] = File.read(Rails.root.join("app/assets/images", folder, image))
|
||||
attachments.inline[image] = File.read(Rails.root.join("app/assets/images", folder, image))
|
||||
image_tag attachments[image].url, **options
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,8 +4,6 @@ module TreeHelper
|
|||
include BlobHelper
|
||||
include WebIdeButtonHelper
|
||||
|
||||
FILE_LIMIT = 1_000
|
||||
|
||||
# Return an image icon depending on the file type and mode
|
||||
#
|
||||
# type - String type of the tree item; either 'folder' or 'file'
|
||||
|
|
|
@ -228,7 +228,7 @@ module Ci
|
|||
end
|
||||
|
||||
def with_preloads
|
||||
preload(:job_artifacts_archive, :job_artifacts, project: [:namespace])
|
||||
preload(:job_artifacts_archive, :job_artifacts, :tags, project: [:namespace])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -21,4 +21,4 @@ class ProjectSetting < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
ProjectSetting.prepend_if_ee('EE::ProjectSetting')
|
||||
ProjectSetting.prepend_ee_mod
|
||||
|
|
|
@ -16,7 +16,7 @@ module Git
|
|||
wiki.after_post_receive
|
||||
|
||||
process_changes
|
||||
perform_housekeeping if Feature.enabled?(:wiki_housekeeping, wiki.container)
|
||||
perform_housekeeping
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -162,7 +162,7 @@
|
|||
#main-story.mktEditable{ mktoname: "main-story" }
|
||||
%table{ border: "0", cellpadding: "0", cellspacing: "0", role: "presentation", width: "100%" }
|
||||
%tr
|
||||
%td{ align: "left", style: "padding: 0px;" }
|
||||
%td{ align: "left", style: "padding: 0 20px;" }
|
||||
= about_link('mailers/in_product_marketing', 'gitlab-logo-gray-rgb.png', 200)
|
||||
%tr
|
||||
%td{ "aria-hidden" => "true", height: "30", style: "font-size: 0; line-height: 0;" }
|
||||
|
@ -187,7 +187,7 @@
|
|||
%p
|
||||
= in_product_marketing_progress(@track, @series)
|
||||
%tr{ style: "background-color: #ffffff;" }
|
||||
%td{ align: "center", style: "padding:50px 20px 0 20px;" }
|
||||
%td{ align: "center", style: "padding:75px 20px 25px;" }
|
||||
= about_link('', 'gitlab_logo.png', 80)
|
||||
%tr{ style: "background-color: #ffffff;" }
|
||||
%td{ align: "center", style: "padding:0px ;" }
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
%h5.gl-mt-0
|
||||
= _('Add an SSH key')
|
||||
%p.profile-settings-content
|
||||
- generate_link_url = help_page_path("ssh/README", anchor: 'generating-a-new-ssh-key-pair')
|
||||
- existing_link_url = help_page_path("ssh/README", anchor: 'review-existing-ssh-keys')
|
||||
- generate_link_url = help_page_path("ssh/README", anchor: 'generate-an-ssh-key-pair')
|
||||
- existing_link_url = help_page_path("ssh/README", anchor: 'see-if-you-have-an-existing-ssh-key-pair')
|
||||
- generate_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: generate_link_url }
|
||||
- existing_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: existing_link_url }
|
||||
= _('To add an SSH key you need to %{generate_link_start}generate one%{link_end} or use an %{existing_link_start}existing key%{link_end}.').html_safe % { generate_link_start: generate_link_start, existing_link_start: existing_link_start, link_end: '</a>'.html_safe }
|
||||
|
|
|
@ -24,3 +24,4 @@
|
|||
= form.check_box :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-input', data: { qa_selector: 'allow_merge_if_all_discussions_are_resolved_checkbox' }
|
||||
= form.label :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-label' do
|
||||
= s_('ProjectSettings|All discussions must be resolved')
|
||||
= render_if_exists 'projects/merge_request_merge_checks_jira_enforcement', form: form, project: @project
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add tag_list attribute to the JSON output for Jobs API
|
||||
merge_request: 44859
|
||||
author: Alon Liszt
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update styles for terraform MR widget
|
||||
merge_request: 52627
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Adds jira issue enforcement field
|
||||
merge_request: 52896
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Enable housekeeping for project and group wiki repos
|
||||
merge_request: 53011
|
||||
author:
|
||||
type: added
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: wiki_housekeeping
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51576
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/299343
|
||||
name: query_deploymenys_via_finished_at_in_vsa
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53050
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/300649
|
||||
milestone: '13.9'
|
||||
type: development
|
||||
group: group::editor
|
||||
group: group::optimize
|
||||
default_enabled: false
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddPreventMergeWithoutJiraIssueToProjectSettings < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
add_column :project_settings, :prevent_merge_without_jira_issue, :boolean, null: false, default: false
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_column :project_settings, :prevent_merge_without_jira_issue
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
ae84fa35fcc5a0780d86887294a32e250d2ac13dcf607750f834df5828e5bece
|
|
@ -16064,6 +16064,7 @@ CREATE TABLE project_settings (
|
|||
has_confluence boolean DEFAULT false NOT NULL,
|
||||
has_vulnerabilities boolean DEFAULT false NOT NULL,
|
||||
allow_editing_commit_messages boolean DEFAULT false NOT NULL,
|
||||
prevent_merge_without_jira_issue boolean DEFAULT false NOT NULL,
|
||||
CONSTRAINT check_bde223416c CHECK ((show_default_award_emojis IS NOT NULL))
|
||||
);
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ We have the following documentation to rapidly uplift your GitLab knowledge:
|
|||
|:--------------------------------------------------------------------------------------------------|:------------|
|
||||
| [GitLab basics guides](gitlab-basics/README.md) | Start working on the command line and with GitLab. |
|
||||
| [GitLab workflow overview](https://about.gitlab.com/blog/2016/10/25/gitlab-workflow-an-overview/) | Enhance your workflow with the best of GitLab Workflow. |
|
||||
| [Get started with GitLab CI/CD](ci/quick_start/README.md) | Quickly implement GitLab CI/CD. |
|
||||
| [Get started with GitLab CI/CD](ci/quick_start/index.md) | Quickly implement GitLab CI/CD. |
|
||||
| [Auto DevOps](topics/autodevops/index.md) | Learn more about Auto DevOps in GitLab. |
|
||||
| [GitLab Markdown](user/markdown.md) | Advanced formatting system (GitLab Flavored Markdown). |
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ libraries](https://graphql.org/code/#graphql-clients) to consume the
|
|||
API and avoid manual parsing.
|
||||
|
||||
Since there's no fixed endpoints and data model, new abilities can be
|
||||
added to the API without creating breaking changes. This allows us to
|
||||
added to the API without creating [breaking changes](../../development/contributing/#breaking-changes). This allows us to
|
||||
have a versionless API as described in [the GraphQL
|
||||
documentation](https://graphql.org/learn/best-practices/#versioning).
|
||||
|
||||
|
|
|
@ -5737,7 +5737,7 @@ type DastProfileCreatePayload {
|
|||
"""
|
||||
The URL of the pipeline that was created. Requires `runAfterCreate` to be set to `true`.
|
||||
"""
|
||||
pipelineUrl: String!
|
||||
pipelineUrl: String
|
||||
}
|
||||
|
||||
"""
|
||||
|
|
|
@ -15668,13 +15668,9 @@
|
|||
|
||||
],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
|
|
|
@ -914,7 +914,7 @@ Autogenerated return type of DastProfileCreate.
|
|||
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
|
||||
| `dastProfile` | DastProfile | The created profile. |
|
||||
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
|
||||
| `pipelineUrl` | String! | The URL of the pipeline that was created. Requires `runAfterCreate` to be set to `true`. |
|
||||
| `pipelineUrl` | String | The URL of the pipeline that was created. Requires `runAfterCreate` to be set to `true`. |
|
||||
|
||||
### DastScannerProfile
|
||||
|
||||
|
|
|
@ -54,6 +54,9 @@ Example of response
|
|||
{"file_type": "junit", "size": 750, "filename": "junit.xml.gz", "file_format": "gzip"}
|
||||
],
|
||||
"artifacts_expire_at": "2016-01-23T17:54:27.895Z",
|
||||
"tag_list": [
|
||||
"docker runner", "ubuntu18"
|
||||
],
|
||||
"id": 7,
|
||||
"name": "teaspoon",
|
||||
"pipeline": {
|
||||
|
@ -104,6 +107,9 @@ Example of response
|
|||
"finished_at": "2015-12-24T17:54:24.921Z",
|
||||
"duration": 0.192,
|
||||
"artifacts_expire_at": "2016-01-23T17:54:24.921Z",
|
||||
"tag_list": [
|
||||
"docker runner", "win10-2004"
|
||||
],
|
||||
"id": 6,
|
||||
"name": "rspec:other",
|
||||
"pipeline": {
|
||||
|
@ -179,6 +185,9 @@ Example of response
|
|||
"finished_at": "2015-12-24T17:54:24.921Z",
|
||||
"duration": 0.192,
|
||||
"artifacts_expire_at": "2016-01-23T17:54:24.921Z",
|
||||
"tag_list": [
|
||||
"docker runner", "ubuntu18"
|
||||
],
|
||||
"id": 6,
|
||||
"name": "rspec:other",
|
||||
"pipeline": {
|
||||
|
@ -239,6 +248,9 @@ Example of response
|
|||
{"file_type": "junit", "size": 750, "filename": "junit.xml.gz", "file_format": "gzip"}
|
||||
],
|
||||
"artifacts_expire_at": "2016-01-23T17:54:27.895Z",
|
||||
"tag_list": [
|
||||
"docker runner", "ubuntu18"
|
||||
],
|
||||
"id": 7,
|
||||
"name": "teaspoon",
|
||||
"pipeline": {
|
||||
|
@ -399,6 +411,9 @@ Example of response
|
|||
"finished_at": "2015-12-24T17:54:31.198Z",
|
||||
"duration": 0.465,
|
||||
"artifacts_expire_at": "2016-01-23T17:54:31.198Z",
|
||||
"tag_list": [
|
||||
"docker runner", "macos-10.15"
|
||||
],
|
||||
"id": 8,
|
||||
"name": "rubocop",
|
||||
"pipeline": {
|
||||
|
|
|
@ -55,7 +55,7 @@ at the repository's root. This file creates a [pipeline](pipelines/index.md), wh
|
|||
To get started with GitLab CI/CD, we recommend you read through
|
||||
the following documents:
|
||||
|
||||
- [Get started with GitLab CI/CD](quick_start/README.md).
|
||||
- [Get started with GitLab CI/CD](quick_start/index.md).
|
||||
- [Fundamental pipeline architectures](pipelines/pipeline_architectures.md).
|
||||
- [GitLab CI/CD basic workflow](introduction/index.md#basic-cicd-workflow).
|
||||
- [Step-by-step guide for writing `.gitlab-ci.yml` for the first time](../user/project/pages/getting_started/pages_from_scratch.md).
|
||||
|
@ -75,7 +75,7 @@ to your needs:
|
|||
|
||||
While building your `.gitlab-ci.yml`, you can use the [CI/CD configuration visualization](pipeline_editor/index.md#visualize-ci-configuration) to facilitate your writing experience.
|
||||
|
||||
For a broader overview, see the [CI/CD getting started](quick_start/README.md) guide.
|
||||
For a broader overview, see the [CI/CD getting started](quick_start/index.md) guide.
|
||||
|
||||
After you're familiar with how GitLab CI/CD works, see the
|
||||
[`.gitlab-ci.yml` full reference](yaml/README.md)
|
||||
|
@ -107,7 +107,7 @@ GitLab CI/CD supports numerous configuration options:
|
|||
| [Schedule pipelines](pipelines/schedules.md) | Schedule pipelines to run as often as you need. |
|
||||
| [Custom path for `.gitlab-ci.yml`](pipelines/settings.md#custom-cicd-configuration-path) | Define a custom path for the CI/CD configuration file. |
|
||||
| [Git submodules for CI/CD](git_submodules.md) | Configure jobs for using Git submodules. |
|
||||
| [SSH keys for CI/CD](ssh_keys/README.md) | Using SSH keys in your CI pipelines. |
|
||||
| [SSH keys for CI/CD](ssh_keys/index.md) | Using SSH keys in your CI pipelines. |
|
||||
| [Pipeline triggers](triggers/README.md) | Trigger pipelines through the API. |
|
||||
| [Pipelines for Merge Requests](merge_request_pipelines/index.md) | Design a pipeline structure for running a pipeline in merge requests. |
|
||||
| [Integrate with Kubernetes clusters](../user/project/clusters/index.md) | Connect your project to Google Kubernetes Engine (GKE) or an existing Kubernetes cluster. |
|
||||
|
@ -126,12 +126,12 @@ Its feature set is listed on the table below according to DevOps stages.
|
|||
|:------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **Configure** | |
|
||||
| [Auto DevOps](../topics/autodevops/index.md) | Set up your app's entire lifecycle. |
|
||||
| [ChatOps](chatops/README.md) | Trigger CI jobs from chat, with results sent back to the channel. |
|
||||
| [ChatOps](chatops/index.md) | Trigger CI jobs from chat, with results sent back to the channel. |
|
||||
|-------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **Verify** | |
|
||||
| [Browser Performance Testing](../user/project/merge_requests/browser_performance_testing.md) | Quickly determine the browser performance impact of pending code changes. |
|
||||
| [Load Performance Testing](../user/project/merge_requests/load_performance_testing.md) | Quickly determine the server performance impact of pending code changes. |
|
||||
| [CI services](services/README.md) | Link Docker containers with your base image. |
|
||||
| [CI services](services/index.md) | Link Docker containers with your base image. |
|
||||
| [Code Quality](../user/project/merge_requests/code_quality.md) | Analyze your source code quality. |
|
||||
| [GitLab CI/CD for external repositories](ci_cd_for_external_repos/index.md) **(PREMIUM)** | Get the benefits of GitLab CI/CD combined with repositories in GitHub and Bitbucket Cloud. |
|
||||
| [Interactive Web Terminals](interactive_web_terminal/index.md) **(FREE SELF)** | Open an interactive web terminal to debug the running jobs. |
|
||||
|
|
|
@ -1,116 +1,8 @@
|
|||
---
|
||||
stage: Configure
|
||||
group: Configure
|
||||
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
|
||||
type: index, concepts, howto
|
||||
redirect_to: 'index.md'
|
||||
---
|
||||
|
||||
# GitLab ChatOps **(FREE)**
|
||||
This document was moved to [another location](index.md).
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4466) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.6.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24780) to [GitLab Free](https://about.gitlab.com/pricing/) in 11.9.
|
||||
|
||||
GitLab ChatOps provides a method to interact with CI/CD jobs through chat services
|
||||
like Slack. Many organizations' discussion, collaboration, and troubleshooting takes
|
||||
place in chat services. Having a method to run CI/CD jobs with output
|
||||
posted back to the channel can significantly augment your team's workflow.
|
||||
|
||||
## How GitLab ChatOps works
|
||||
|
||||
GitLab ChatOps is built upon [GitLab CI/CD](../README.md) and
|
||||
[Slack Slash Commands](../../user/project/integrations/slack_slash_commands.md).
|
||||
ChatOps provides a `run` action for [slash commands](../../integration/slash_commands.md)
|
||||
with the following arguments:
|
||||
|
||||
- A `<job name>` to execute.
|
||||
- The `<job arguments>`.
|
||||
|
||||
ChatOps passes the following [CI/CD variables](../variables/README.md#predefined-environment-variables)
|
||||
to the job:
|
||||
|
||||
- `CHAT_INPUT` contains any additional arguments.
|
||||
- `CHAT_CHANNEL` is set to the name of channel the action was triggered in.
|
||||
|
||||
When executed, ChatOps looks up the specified job name and attempts to match it
|
||||
to a corresponding job in [`.gitlab-ci.yml`](../yaml/README.md). If a matching job
|
||||
is found on `master`, a pipeline containing only that job is scheduled. After the
|
||||
job completes:
|
||||
|
||||
- If the job completes in *less than 30 minutes*, the ChatOps sends the job's output to Slack.
|
||||
- If the job completes in *more than 30 minutes*, the job must use the
|
||||
[Slack API](https://api.slack.com/) to send data to the channel.
|
||||
|
||||
To use the `run` command, you must have
|
||||
[Developer access or above](../../user/permissions.md#project-members-permissions).
|
||||
If a job shouldn't be able to be triggered from chat, you can set the job to `except: [chat]`.
|
||||
|
||||
## Best practices for ChatOps CI jobs
|
||||
|
||||
Since ChatOps is built upon GitLab CI/CD, the job has all the same features and
|
||||
functions available. Consider these best practices when creating ChatOps jobs:
|
||||
|
||||
- GitLab strongly recommends you set `only: [chat]` so the job does not run as part
|
||||
of the standard CI pipeline.
|
||||
- If the job is set to `when: manual`, ChatOps creates the pipeline, but the job waits to be started.
|
||||
- ChatOps provides limited support for access control. If the user triggering the
|
||||
slash command has [Developer access or above](../../user/permissions.md#project-members-permissions)
|
||||
in the project, the job runs. The job itself can use existing
|
||||
[CI/CD variables](../variables/README.md#predefined-environment-variables) like
|
||||
`GITLAB_USER_ID` to perform additional rights validation, but
|
||||
these variables can be [overridden](../variables/README.md#priority-of-environment-variables).
|
||||
|
||||
### Controlling the ChatOps reply
|
||||
|
||||
The output for jobs with a single command is sent to the channel as a reply. For
|
||||
example, the chat reply of the following job is `Hello World` in the channel:
|
||||
|
||||
```yaml
|
||||
hello-world:
|
||||
stage: chatops
|
||||
only: [chat]
|
||||
script:
|
||||
- echo "Hello World"
|
||||
```
|
||||
|
||||
Jobs that contain multiple commands (or `before_script`) return additional
|
||||
content in the chat reply. In these cases, both the commands and their output are
|
||||
included, with the commands wrapped in ANSI color codes.
|
||||
|
||||
To selectively reply with the output of one command, its output must be bounded by
|
||||
the `chat_reply` section. For example, the following job lists the files in the
|
||||
current directory:
|
||||
|
||||
```yaml
|
||||
ls:
|
||||
stage: chatops
|
||||
only: [chat]
|
||||
script:
|
||||
- echo "This command will not be shown."
|
||||
- echo -e "section_start:$( date +%s ):chat_reply\r\033[0K\n$( ls -la )\nsection_end:$( date +%s ):chat_reply\r\033[0K"
|
||||
```
|
||||
|
||||
## GitLab ChatOps examples
|
||||
|
||||
The GitLab.com team created a repository of [common ChatOps scripts](https://gitlab.com/gitlab-com/chatops)
|
||||
they use to interact with our Production instance of GitLab. Administrators of
|
||||
other GitLab instances may find them useful. They can serve as inspiration for ChatOps
|
||||
scripts you can write to interact with your own applications.
|
||||
|
||||
## GitLab ChatOps icon
|
||||
|
||||
The [official GitLab ChatOps icon](img/gitlab-chatops-icon.png) is available for download.
|
||||
You can find and download the official GitLab ChatOps icon here.
|
||||
|
||||
![GitLab ChatOps bot icon](img/gitlab-chatops-icon-small.png)
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
|
||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||
one might have when setting this up, or when something is changed, or on upgrading, it's
|
||||
important to describe those, too. Think of things that may go wrong and include them here.
|
||||
This is important to minimize requests for support, and to avoid doc comments with
|
||||
questions that you know someone might ask.
|
||||
|
||||
Each scenario can be a third-level heading, e.g. `### Getting error message X`.
|
||||
If you have none to add when creating a doc, leave this section in place
|
||||
but commented out to help encourage others to add to it in the future. -->
|
||||
<!-- This redirect file can be deleted after 2021-05-01. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
---
|
||||
stage: Configure
|
||||
group: Configure
|
||||
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
|
||||
type: index, concepts, howto
|
||||
---
|
||||
|
||||
# GitLab ChatOps **(FREE)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4466) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.6.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24780) to [GitLab Free](https://about.gitlab.com/pricing/) in 11.9.
|
||||
|
||||
GitLab ChatOps provides a method to interact with CI/CD jobs through chat services
|
||||
like Slack. Many organizations' discussion, collaboration, and troubleshooting takes
|
||||
place in chat services. Having a method to run CI/CD jobs with output
|
||||
posted back to the channel can significantly augment your team's workflow.
|
||||
|
||||
## How GitLab ChatOps works
|
||||
|
||||
GitLab ChatOps is built upon [GitLab CI/CD](../README.md) and
|
||||
[Slack Slash Commands](../../user/project/integrations/slack_slash_commands.md).
|
||||
ChatOps provides a `run` action for [slash commands](../../integration/slash_commands.md)
|
||||
with the following arguments:
|
||||
|
||||
- A `<job name>` to execute.
|
||||
- The `<job arguments>`.
|
||||
|
||||
ChatOps passes the following [CI/CD variables](../variables/README.md#predefined-environment-variables)
|
||||
to the job:
|
||||
|
||||
- `CHAT_INPUT` contains any additional arguments.
|
||||
- `CHAT_CHANNEL` is set to the name of channel the action was triggered in.
|
||||
|
||||
When executed, ChatOps looks up the specified job name and attempts to match it
|
||||
to a corresponding job in [`.gitlab-ci.yml`](../yaml/README.md). If a matching job
|
||||
is found on `master`, a pipeline containing only that job is scheduled. After the
|
||||
job completes:
|
||||
|
||||
- If the job completes in *less than 30 minutes*, the ChatOps sends the job's output to Slack.
|
||||
- If the job completes in *more than 30 minutes*, the job must use the
|
||||
[Slack API](https://api.slack.com/) to send data to the channel.
|
||||
|
||||
To use the `run` command, you must have
|
||||
[Developer access or above](../../user/permissions.md#project-members-permissions).
|
||||
If a job shouldn't be able to be triggered from chat, you can set the job to `except: [chat]`.
|
||||
|
||||
## Best practices for ChatOps CI jobs
|
||||
|
||||
Since ChatOps is built upon GitLab CI/CD, the job has all the same features and
|
||||
functions available. Consider these best practices when creating ChatOps jobs:
|
||||
|
||||
- GitLab strongly recommends you set `only: [chat]` so the job does not run as part
|
||||
of the standard CI pipeline.
|
||||
- If the job is set to `when: manual`, ChatOps creates the pipeline, but the job waits to be started.
|
||||
- ChatOps provides limited support for access control. If the user triggering the
|
||||
slash command has [Developer access or above](../../user/permissions.md#project-members-permissions)
|
||||
in the project, the job runs. The job itself can use existing
|
||||
[CI/CD variables](../variables/README.md#predefined-environment-variables) like
|
||||
`GITLAB_USER_ID` to perform additional rights validation, but
|
||||
these variables can be [overridden](../variables/README.md#priority-of-environment-variables).
|
||||
|
||||
### Controlling the ChatOps reply
|
||||
|
||||
The output for jobs with a single command is sent to the channel as a reply. For
|
||||
example, the chat reply of the following job is `Hello World` in the channel:
|
||||
|
||||
```yaml
|
||||
hello-world:
|
||||
stage: chatops
|
||||
only: [chat]
|
||||
script:
|
||||
- echo "Hello World"
|
||||
```
|
||||
|
||||
Jobs that contain multiple commands (or `before_script`) return additional
|
||||
content in the chat reply. In these cases, both the commands and their output are
|
||||
included, with the commands wrapped in ANSI color codes.
|
||||
|
||||
To selectively reply with the output of one command, its output must be bounded by
|
||||
the `chat_reply` section. For example, the following job lists the files in the
|
||||
current directory:
|
||||
|
||||
```yaml
|
||||
ls:
|
||||
stage: chatops
|
||||
only: [chat]
|
||||
script:
|
||||
- echo "This command will not be shown."
|
||||
- echo -e "section_start:$( date +%s ):chat_reply\r\033[0K\n$( ls -la )\nsection_end:$( date +%s ):chat_reply\r\033[0K"
|
||||
```
|
||||
|
||||
## GitLab ChatOps examples
|
||||
|
||||
The GitLab.com team created a repository of [common ChatOps scripts](https://gitlab.com/gitlab-com/chatops)
|
||||
they use to interact with our Production instance of GitLab. Administrators of
|
||||
other GitLab instances may find them useful. They can serve as inspiration for ChatOps
|
||||
scripts you can write to interact with your own applications.
|
||||
|
||||
## GitLab ChatOps icon
|
||||
|
||||
The [official GitLab ChatOps icon](img/gitlab-chatops-icon.png) is available for download.
|
||||
You can find and download the official GitLab ChatOps icon here.
|
||||
|
||||
![GitLab ChatOps bot icon](img/gitlab-chatops-icon-small.png)
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
|
||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||
one might have when setting this up, or when something is changed, or on upgrading, it's
|
||||
important to describe those, too. Think of things that may go wrong and include them here.
|
||||
This is important to minimize requests for support, and to avoid doc comments with
|
||||
questions that you know someone might ask.
|
||||
|
||||
Each scenario can be a third-level heading, e.g. `### Getting error message X`.
|
||||
If you have none to add when creating a doc, leave this section in place
|
||||
but commented out to help encourage others to add to it in the future. -->
|
|
@ -41,7 +41,7 @@ repositories:
|
|||
1. Paste the token into the **Personal access token** field and click **List
|
||||
Repositories**. Click **Connect** to select the repository.
|
||||
|
||||
1. In GitHub, add a `.gitlab-ci.yml` to [configure GitLab CI/CD](../quick_start/README.md).
|
||||
1. In GitHub, add a `.gitlab-ci.yml` to [configure GitLab CI/CD](../quick_start/index.md).
|
||||
|
||||
GitLab:
|
||||
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Continuous Integration
|
||||
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
|
||||
comments: false
|
||||
type: index
|
||||
redirect_to: 'index.md'
|
||||
---
|
||||
|
||||
# Docker integration
|
||||
This document was moved to [another location](index.md).
|
||||
|
||||
GitLab CI/CD can be combined with [Docker](https://www.docker.com) to enable
|
||||
integration between the two.
|
||||
|
||||
The following documentation is available for using GitLab CI/CD with Docker:
|
||||
|
||||
- [Building Docker images with GitLab CI/CD](using_docker_build.md).
|
||||
- [Using Docker images](using_docker_images.md).
|
||||
- [Building images with kaniko and GitLab CI/CD](using_kaniko.md).
|
||||
<!-- This redirect file can be deleted after 2021-05-01. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Continuous Integration
|
||||
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
|
||||
comments: false
|
||||
type: index
|
||||
---
|
||||
|
||||
# Docker integration
|
||||
|
||||
GitLab CI/CD can be combined with [Docker](https://www.docker.com) to enable
|
||||
integration between the two.
|
||||
|
||||
The following documentation is available for using GitLab CI/CD with Docker:
|
||||
|
||||
- [Building Docker images with GitLab CI/CD](using_docker_build.md).
|
||||
- [Using Docker images](using_docker_images.md).
|
||||
- [Building images with kaniko and GitLab CI/CD](using_kaniko.md).
|
|
@ -91,7 +91,7 @@ Services inherit the same DNS servers, search domains, and additional hosts as
|
|||
the CI container itself.
|
||||
|
||||
You can see some widely used services examples in the relevant documentation of
|
||||
[CI services examples](../services/README.md).
|
||||
[CI services examples](../services/index.md).
|
||||
|
||||
### How services are linked to the job
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ To effectively use GitLab CI/CD, you need:
|
|||
of your project.
|
||||
- A [runner](runners/README.md) properly set up.
|
||||
|
||||
You can read our [quick start guide](quick_start/README.md) to get you started.
|
||||
You can read our [quick start guide](quick_start/index.md) to get you started.
|
||||
|
||||
If you are using an external CI/CD server like Jenkins or Drone CI, it is advised
|
||||
to disable GitLab CI/CD in order to not have any conflicts with the commits status
|
||||
|
|
|
@ -544,7 +544,7 @@ services:
|
|||
...
|
||||
```
|
||||
|
||||
If you wish to test your app with different PHP versions and [database management systems](../../services/README.md), you can define different `image` and `services` keywords for each test job.
|
||||
If you wish to test your app with different PHP versions and [database management systems](../../services/index.md), you can define different `image` and `services` keywords for each test job.
|
||||
|
||||
#### Variables
|
||||
|
||||
|
@ -589,7 +589,7 @@ unit_test:
|
|||
#### Deploy to production
|
||||
|
||||
The job `deploy_production` will deploy the app to the production server.
|
||||
To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../../ssh_keys/README.md#ssh-keys-when-using-the-docker-executor).
|
||||
To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../../ssh_keys/index.md#ssh-keys-when-using-the-docker-executor).
|
||||
If the SSH keys have added successfully, we can run Envoy.
|
||||
|
||||
As mentioned before, GitLab supports [Continuous Delivery](https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) methods as well.
|
||||
|
|
|
@ -241,7 +241,7 @@ before_script:
|
|||
## Access private packages or dependencies
|
||||
|
||||
If your test suite needs to access a private repository, you need to configure
|
||||
the [SSH keys](../ssh_keys/README.md) to be able to clone it.
|
||||
the [SSH keys](../ssh_keys/index.md) to be able to clone it.
|
||||
|
||||
## Use databases or other services
|
||||
|
||||
|
@ -250,7 +250,7 @@ run. If you're using the Docker executor, you can leverage Docker's ability to
|
|||
link to other containers. With GitLab Runner, this can be achieved by defining
|
||||
a `service`.
|
||||
|
||||
This functionality is covered in [the CI services](../services/README.md)
|
||||
This functionality is covered in [the CI services](../services/index.md)
|
||||
documentation.
|
||||
|
||||
## Testing things locally
|
||||
|
|
|
@ -13,7 +13,7 @@ type: reference
|
|||
> are encouraged to upgrade your GitLab instance if you haven't done already.
|
||||
> If you are **not** using GitLab 8.12 or higher, you would need to work your way
|
||||
> around submodules in order to access the sources of e.g., `gitlab.com/group/project`
|
||||
> with the use of [SSH keys](ssh_keys/README.md).
|
||||
> with the use of [SSH keys](ssh_keys/index.md).
|
||||
> - With GitLab 8.12 onward, your permissions are used to evaluate what a CI job
|
||||
> can access. More information about how this system works can be found in the
|
||||
> [Jobs permissions model](../user/permissions.md#job-permissions).
|
||||
|
|
|
@ -15,7 +15,7 @@ comparison to see what's different.
|
|||
|
||||
We have collected several resources that you may find useful before starting to migrate.
|
||||
|
||||
The [Quick Start Guide](../quick_start/README.md) is a good overview of how GitLab CI/CD works. You may also be interested in [Auto DevOps](../../topics/autodevops/index.md) which can be used to build, test, and deploy your applications with little to no configuration needed at all.
|
||||
The [Quick Start Guide](../quick_start/index.md) is a good overview of how GitLab CI/CD works. You may also be interested in [Auto DevOps](../../topics/autodevops/index.md) which can be used to build, test, and deploy your applications with little to no configuration needed at all.
|
||||
|
||||
For advanced CI/CD teams, [custom project templates](../../user/admin_area/custom_project_templates.md) can enable the reuse of pipeline configurations.
|
||||
|
||||
|
|
|
@ -15,11 +15,11 @@ before diving in. Think of this page as a "GitLab CI/CD for Jenkins Users" guide
|
|||
The following list of recommended steps was created after observing organizations
|
||||
that were able to quickly complete this migration:
|
||||
|
||||
1. Start by reading the GitLab CI/CD [Quick Start Guide](../quick_start/README.md) and [important product differences](#important-product-differences).
|
||||
1. Start by reading the GitLab CI/CD [Quick Start Guide](../quick_start/index.md) and [important product differences](#important-product-differences).
|
||||
1. Learn the importance of [managing the organizational transition](#managing-the-organizational-transition).
|
||||
1. [Add runners](../runners/README.md) to your GitLab instance.
|
||||
1. Educate and enable your developers to independently perform the following steps in their projects:
|
||||
1. Review the [Quick Start Guide](../quick_start/README.md) and [Pipeline Configuration Reference](../yaml/README.md).
|
||||
1. Review the [Quick Start Guide](../quick_start/index.md) and [Pipeline Configuration Reference](../yaml/README.md).
|
||||
1. Use the [Jenkins Wrapper](#jenkinsfile-wrapper) to temporarily maintain fragile Jenkins jobs.
|
||||
1. Migrate the build and CI jobs and configure them to show results directly in your merge requests. They can use [Auto DevOps](../../topics/autodevops/index.md) as a starting point, and [customize](../../topics/autodevops/customize.md) or [decompose](../../topics/autodevops/customize.md#using-components-of-auto-devops) the configuration as needed.
|
||||
1. Add [Review Apps](../review_apps/index.md).
|
||||
|
@ -79,7 +79,7 @@ There are some high level differences between the products worth mentioning:
|
|||
- from the [GitLab UI](../pipelines/index.md#run-a-pipeline-manually)
|
||||
- by [API call](../triggers/README.md)
|
||||
- by [webhook](../triggers/README.md#triggering-a-pipeline-from-a-webhook)
|
||||
- by [ChatOps](../chatops/README.md)
|
||||
- by [ChatOps](../chatops/index.md)
|
||||
|
||||
- You can control which jobs run in which cases, depending on how they are triggered,
|
||||
with the [`rules` syntax](../yaml/README.md#rules).
|
||||
|
|
|
@ -28,7 +28,7 @@ From the pipeline editor page you can:
|
|||
- [Commit](#commit-changes-to-ci-configuration) the changes to a specific branch.
|
||||
|
||||
NOTE:
|
||||
You must already have [a `.gitlab-ci.yml` file](../quick_start/README.md#create-a-gitlab-ciyml-file)
|
||||
You must already have [a `.gitlab-ci.yml` file](../quick_start/index.md#create-a-gitlab-ciyml-file)
|
||||
on the default branch (usually "master") of your project to use the editor.
|
||||
|
||||
## Validate CI configuration
|
||||
|
|
|
@ -20,7 +20,7 @@ to use pipeline features that improve efficiency right away, and get a faster so
|
|||
development lifecycle earlier.
|
||||
|
||||
First ensure you are familiar with [GitLab CI/CD fundamentals](../introduction/index.md)
|
||||
and understand the [quick start guide](../quick_start/README.md).
|
||||
and understand the [quick start guide](../quick_start/index.md).
|
||||
|
||||
## Identify bottlenecks and common failures
|
||||
|
||||
|
@ -235,7 +235,7 @@ Methods to reduce Docker image size:
|
|||
to analyze and shrink images.
|
||||
|
||||
To simplify Docker image management, you can create a dedicated group for managing
|
||||
[Docker images](../docker/README.md) and test, build and publish them with CI/CD pipelines.
|
||||
[Docker images](../docker/index.md) and test, build and publish them with CI/CD pipelines.
|
||||
|
||||
## Test, document, and learn
|
||||
|
||||
|
|
|
@ -1,157 +1,8 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Continuous Integration
|
||||
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
|
||||
type: reference
|
||||
redirect_to: 'index.md'
|
||||
---
|
||||
|
||||
# Get started with GitLab CI/CD
|
||||
This document was moved to [another location](index.md).
|
||||
|
||||
Use this document to get started with
|
||||
GitLab [continuous integration](https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/).
|
||||
|
||||
Before you start, make sure you have:
|
||||
|
||||
- A project in GitLab that you would like to use CI/CD for.
|
||||
- Maintainer or owner access for the project.
|
||||
|
||||
If you are migrating from another CI/CD tool, view this documentation:
|
||||
|
||||
- [Migrate from CircleCI](../migration/circleci.md).
|
||||
- [Migrate from Jenkins](../migration/jenkins.md).
|
||||
|
||||
## CI/CD process overview
|
||||
|
||||
To use GitLab CI/CD:
|
||||
|
||||
1. [Ensure you have runners available](#ensure-you-have-runners-available) to run your jobs.
|
||||
If you don't have a runner, [install GitLab Runner](https://docs.gitlab.com/runner/install/)
|
||||
and [register a runner](https://docs.gitlab.com/runner/register/) for your instance, project, or group.
|
||||
1. [Create a `.gitlab-ci.yml` file](#create-a-gitlab-ciyml-file)
|
||||
at the root of your repository. This file is where you define your CI/CD jobs.
|
||||
|
||||
When you commit the file to your repository, the runner runs your jobs.
|
||||
The job results [are displayed in a pipeline](#view-the-status-of-your-pipeline-and-jobs).
|
||||
|
||||
### Ensure you have runners available
|
||||
|
||||
In GitLab, runners are agents that run your CI/CD jobs.
|
||||
|
||||
You might already have runners available for your project, including
|
||||
[shared runners](../runners/README.md#shared-runners), which are
|
||||
available to all projects in your GitLab instance.
|
||||
|
||||
To view available runners:
|
||||
|
||||
- Go to **Settings > CI/CD** and expand **Runners**.
|
||||
|
||||
As long as you have at least one runner that's active, with a green circle next to it,
|
||||
you have a runner available to process your jobs.
|
||||
|
||||
If no runners are listed on the **Runners** page in the UI, you or an administrator
|
||||
must [install GitLab Runner](https://docs.gitlab.com/runner/install/) and
|
||||
[register](https://docs.gitlab.com/runner/register/) at least one runner.
|
||||
|
||||
If you are testing CI/CD, you can install GitLab Runner and register runners on your local machine.
|
||||
When your CI/CD jobs run, they run on your local machine.
|
||||
|
||||
### Create a `.gitlab-ci.yml` file
|
||||
|
||||
The `.gitlab-ci.yml` file is a [YAML](https://en.wikipedia.org/wiki/YAML) file where
|
||||
you configure specific instructions for GitLab CI/CD.
|
||||
|
||||
In this file, you define:
|
||||
|
||||
- The structure and order of jobs that the runner should execute.
|
||||
- The decisions the runner should make when specific conditions are encountered.
|
||||
|
||||
For example, you might want to run a suite of tests when you commit to
|
||||
any branch except `master`. When you commit to `master`, you want
|
||||
to run the same suite, but also publish your application.
|
||||
|
||||
All of this is defined in the `.gitlab-ci.yml` file.
|
||||
|
||||
To create a `.gitlab-ci.yml` file:
|
||||
|
||||
1. Go to **Project overview > Details**.
|
||||
1. Above the file list, select the branch you want to commit to,
|
||||
click the plus icon, then select **New file**:
|
||||
|
||||
![New file](img/new_file_v13_6.png)
|
||||
|
||||
1. For the **Filename**, type `.gitlab-ci.yml` and in the larger window,
|
||||
paste this sample code:
|
||||
|
||||
```yaml
|
||||
build-job:
|
||||
stage: build
|
||||
script:
|
||||
- echo "Hello, $GITLAB_USER_LOGIN!"
|
||||
|
||||
test-job1:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job tests something"
|
||||
|
||||
test-job2:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job tests something, but takes more time than test-job1."
|
||||
- echo "After the echo commands complete, it runs the sleep command for 20 seconds"
|
||||
- echo "which simulates a test that runs 20 seconds longer than test-job1"
|
||||
- sleep 20
|
||||
|
||||
deploy-prod:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "This job deploys something from the $CI_COMMIT_BRANCH branch."
|
||||
```
|
||||
|
||||
`$GITLAB_USER_LOGIN` and `$CI_COMMIT_BRANCH` are
|
||||
[predefined variables](../variables/predefined_variables.md)
|
||||
that populate when the job runs.
|
||||
|
||||
1. Click **Commit changes**.
|
||||
|
||||
The pipeline starts when the commit is committed.
|
||||
|
||||
#### `.gitlab-ci.yml` tips
|
||||
|
||||
- If you want the runner to use a Docker image to run the jobs, edit the `.gitlab-ci.yml` file
|
||||
to include your image name:
|
||||
|
||||
```yaml
|
||||
default:
|
||||
image: ruby:2.7.2
|
||||
```
|
||||
|
||||
This command tells the runner to use a Ruby image from Docker Hub.
|
||||
|
||||
- To validate your `.gitlab-ci.yml` file, use the
|
||||
[CI Lint tool](../lint.md), which is available in every project.
|
||||
- You can also use [CI/CD configuration visualization](../pipeline_editor/index.md#visualize-ci-configuration) to
|
||||
view a graphical representation of your `.gitlab-ci.yml` file.
|
||||
- For the complete `.gitlab-ci.yml` syntax, see
|
||||
[the `.gitlab-ci.yml` reference topic](../yaml/README.md).
|
||||
|
||||
### View the status of your pipeline and jobs
|
||||
|
||||
When you committed your changes, a pipeline started.
|
||||
|
||||
To view your pipeline:
|
||||
|
||||
- Go **CI/CD > Pipelines**.
|
||||
|
||||
A pipeline with three stages should be displayed:
|
||||
|
||||
![Three stages](img/three_stages_v13_6.png)
|
||||
|
||||
- To view a visual representation of your pipeline, click the pipeline ID.
|
||||
|
||||
![Pipeline graph](img/pipeline_graph_v13_6.png)
|
||||
|
||||
- To view details of a job, click the job name, for example, `deploy-prod`.
|
||||
|
||||
![Job details](img/job_details_v13_6.png)
|
||||
|
||||
If the job status is `stuck`, check to ensure a runner is probably configured for the project.
|
||||
<!-- This redirect file can be deleted after 2021-05-01. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Continuous Integration
|
||||
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
|
||||
type: reference
|
||||
---
|
||||
|
||||
# Get started with GitLab CI/CD
|
||||
|
||||
Use this document to get started with
|
||||
GitLab [continuous integration](https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/).
|
||||
|
||||
Before you start, make sure you have:
|
||||
|
||||
- A project in GitLab that you would like to use CI/CD for.
|
||||
- Maintainer or owner access for the project.
|
||||
|
||||
If you are migrating from another CI/CD tool, view this documentation:
|
||||
|
||||
- [Migrate from CircleCI](../migration/circleci.md).
|
||||
- [Migrate from Jenkins](../migration/jenkins.md).
|
||||
|
||||
## CI/CD process overview
|
||||
|
||||
To use GitLab CI/CD:
|
||||
|
||||
1. [Ensure you have runners available](#ensure-you-have-runners-available) to run your jobs.
|
||||
If you don't have a runner, [install GitLab Runner](https://docs.gitlab.com/runner/install/)
|
||||
and [register a runner](https://docs.gitlab.com/runner/register/) for your instance, project, or group.
|
||||
1. [Create a `.gitlab-ci.yml` file](#create-a-gitlab-ciyml-file)
|
||||
at the root of your repository. This file is where you define your CI/CD jobs.
|
||||
|
||||
When you commit the file to your repository, the runner runs your jobs.
|
||||
The job results [are displayed in a pipeline](#view-the-status-of-your-pipeline-and-jobs).
|
||||
|
||||
### Ensure you have runners available
|
||||
|
||||
In GitLab, runners are agents that run your CI/CD jobs.
|
||||
|
||||
You might already have runners available for your project, including
|
||||
[shared runners](../runners/README.md#shared-runners), which are
|
||||
available to all projects in your GitLab instance.
|
||||
|
||||
To view available runners:
|
||||
|
||||
- Go to **Settings > CI/CD** and expand **Runners**.
|
||||
|
||||
As long as you have at least one runner that's active, with a green circle next to it,
|
||||
you have a runner available to process your jobs.
|
||||
|
||||
If no runners are listed on the **Runners** page in the UI, you or an administrator
|
||||
must [install GitLab Runner](https://docs.gitlab.com/runner/install/) and
|
||||
[register](https://docs.gitlab.com/runner/register/) at least one runner.
|
||||
|
||||
If you are testing CI/CD, you can install GitLab Runner and register runners on your local machine.
|
||||
When your CI/CD jobs run, they run on your local machine.
|
||||
|
||||
### Create a `.gitlab-ci.yml` file
|
||||
|
||||
The `.gitlab-ci.yml` file is a [YAML](https://en.wikipedia.org/wiki/YAML) file where
|
||||
you configure specific instructions for GitLab CI/CD.
|
||||
|
||||
In this file, you define:
|
||||
|
||||
- The structure and order of jobs that the runner should execute.
|
||||
- The decisions the runner should make when specific conditions are encountered.
|
||||
|
||||
For example, you might want to run a suite of tests when you commit to
|
||||
any branch except `master`. When you commit to `master`, you want
|
||||
to run the same suite, but also publish your application.
|
||||
|
||||
All of this is defined in the `.gitlab-ci.yml` file.
|
||||
|
||||
To create a `.gitlab-ci.yml` file:
|
||||
|
||||
1. Go to **Project overview > Details**.
|
||||
1. Above the file list, select the branch you want to commit to,
|
||||
click the plus icon, then select **New file**:
|
||||
|
||||
![New file](img/new_file_v13_6.png)
|
||||
|
||||
1. For the **Filename**, type `.gitlab-ci.yml` and in the larger window,
|
||||
paste this sample code:
|
||||
|
||||
```yaml
|
||||
build-job:
|
||||
stage: build
|
||||
script:
|
||||
- echo "Hello, $GITLAB_USER_LOGIN!"
|
||||
|
||||
test-job1:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job tests something"
|
||||
|
||||
test-job2:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job tests something, but takes more time than test-job1."
|
||||
- echo "After the echo commands complete, it runs the sleep command for 20 seconds"
|
||||
- echo "which simulates a test that runs 20 seconds longer than test-job1"
|
||||
- sleep 20
|
||||
|
||||
deploy-prod:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "This job deploys something from the $CI_COMMIT_BRANCH branch."
|
||||
```
|
||||
|
||||
`$GITLAB_USER_LOGIN` and `$CI_COMMIT_BRANCH` are
|
||||
[predefined variables](../variables/predefined_variables.md)
|
||||
that populate when the job runs.
|
||||
|
||||
1. Click **Commit changes**.
|
||||
|
||||
The pipeline starts when the commit is committed.
|
||||
|
||||
#### `.gitlab-ci.yml` tips
|
||||
|
||||
- If you want the runner to use a Docker image to run the jobs, edit the `.gitlab-ci.yml` file
|
||||
to include your image name:
|
||||
|
||||
```yaml
|
||||
default:
|
||||
image: ruby:2.7.2
|
||||
```
|
||||
|
||||
This command tells the runner to use a Ruby image from Docker Hub.
|
||||
|
||||
- To validate your `.gitlab-ci.yml` file, use the
|
||||
[CI Lint tool](../lint.md), which is available in every project.
|
||||
- You can also use [CI/CD configuration visualization](../pipeline_editor/index.md#visualize-ci-configuration) to
|
||||
view a graphical representation of your `.gitlab-ci.yml` file.
|
||||
- For the complete `.gitlab-ci.yml` syntax, see
|
||||
[the `.gitlab-ci.yml` reference topic](../yaml/README.md).
|
||||
|
||||
### View the status of your pipeline and jobs
|
||||
|
||||
When you committed your changes, a pipeline started.
|
||||
|
||||
To view your pipeline:
|
||||
|
||||
- Go **CI/CD > Pipelines**.
|
||||
|
||||
A pipeline with three stages should be displayed:
|
||||
|
||||
![Three stages](img/three_stages_v13_6.png)
|
||||
|
||||
- To view a visual representation of your pipeline, click the pipeline ID.
|
||||
|
||||
![Pipeline graph](img/pipeline_graph_v13_6.png)
|
||||
|
||||
- To view details of a job, click the job name, for example, `deploy-prod`.
|
||||
|
||||
![Job details](img/job_details_v13_6.png)
|
||||
|
||||
If the job status is `stuck`, check to ensure a runner is probably configured for the project.
|
|
@ -1,21 +1,8 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Runner
|
||||
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
|
||||
comments: false
|
||||
type: index
|
||||
redirect_to: 'index.md'
|
||||
---
|
||||
|
||||
# GitLab CI services examples
|
||||
This document was moved to [another location](index.md).
|
||||
|
||||
The [`services`](../docker/using_docker_images.md#what-is-a-service)
|
||||
keyword defines a Docker image that runs during a `job` linked to the
|
||||
Docker image that the image keyword defines. This allows you to access
|
||||
the service image during build time.
|
||||
|
||||
The service image can run any application, but the most common use
|
||||
case is to run a database container, for example:
|
||||
|
||||
- [Using MySQL](mysql.md)
|
||||
- [Using PostgreSQL](postgres.md)
|
||||
- [Using Redis](redis.md)
|
||||
<!-- This redirect file can be deleted after 2021-05-01. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Runner
|
||||
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
|
||||
comments: false
|
||||
type: index
|
||||
---
|
||||
|
||||
# GitLab CI services examples
|
||||
|
||||
The [`services`](../docker/using_docker_images.md#what-is-a-service)
|
||||
keyword defines a Docker image that runs during a `job` linked to the
|
||||
Docker image that the image keyword defines. This allows you to access
|
||||
the service image during build time.
|
||||
|
||||
The service image can run any application, but the most common use
|
||||
case is to run a database container, for example:
|
||||
|
||||
- [Using MySQL](mysql.md)
|
||||
- [Using PostgreSQL](postgres.md)
|
||||
- [Using Redis](redis.md)
|
|
@ -1,212 +1,8 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Continuous Integration
|
||||
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
|
||||
type: tutorial
|
||||
redirect_to: 'index.md'
|
||||
---
|
||||
|
||||
# Using SSH keys with GitLab CI/CD
|
||||
This document was moved to [another location](index.md).
|
||||
|
||||
GitLab currently doesn't have built-in support for managing SSH keys in a build
|
||||
environment (where the GitLab Runner runs).
|
||||
|
||||
The SSH keys can be useful when:
|
||||
|
||||
1. You want to checkout internal submodules
|
||||
1. You want to download private packages using your package manager (e.g., Bundler)
|
||||
1. You want to deploy your application to your own server, or, for example, Heroku
|
||||
1. You want to execute SSH commands from the build environment to a remote server
|
||||
1. You want to rsync files from the build environment to a remote server
|
||||
|
||||
If anything of the above rings a bell, then you most likely need an SSH key.
|
||||
|
||||
The most widely supported method is to inject an SSH key into your build
|
||||
environment by extending your `.gitlab-ci.yml`, and it's a solution which works
|
||||
with any type of [executor](https://docs.gitlab.com/runner/executors/)
|
||||
(Docker, shell, etc.).
|
||||
|
||||
## How it works
|
||||
|
||||
1. Create a new SSH key pair locally with [`ssh-keygen`](https://linux.die.net/man/1/ssh-keygen)
|
||||
1. Add the private key as a [variable](../variables/README.md) to
|
||||
your project
|
||||
1. Run the [`ssh-agent`](https://linux.die.net/man/1/ssh-agent) during job to load
|
||||
the private key.
|
||||
1. Copy the public key to the servers you want to have access to (usually in
|
||||
`~/.ssh/authorized_keys`) or add it as a [deploy key](../../ssh/README.md#deploy-keys)
|
||||
if you are accessing a private GitLab repository.
|
||||
|
||||
The private key is displayed in the job log, unless you enable
|
||||
[debug logging](../variables/README.md#debug-logging). You might also want to
|
||||
check the [visibility of your pipelines](../pipelines/settings.md#visibility-of-pipelines).
|
||||
|
||||
## SSH keys when using the Docker executor
|
||||
|
||||
When your CI/CD jobs run inside Docker containers (meaning the environment is
|
||||
contained) and you want to deploy your code in a private server, you need a way
|
||||
to access it. This is where an SSH key pair comes in handy.
|
||||
|
||||
1. You first need to create an SSH key pair. For more information, follow
|
||||
the instructions to [generate an SSH key](../../ssh/README.md#generating-a-new-ssh-key-pair).
|
||||
**Do not** add a passphrase to the SSH key, or the `before_script` will
|
||||
prompt for it.
|
||||
|
||||
1. Create a new [variable](../variables/README.md#gitlab-cicd-environment-variables).
|
||||
As **Key** enter the name `SSH_PRIVATE_KEY` and in the **Value** field paste
|
||||
the content of your _private_ key that you created earlier.
|
||||
|
||||
1. Modify your `.gitlab-ci.yml` with a `before_script` action. In the following
|
||||
example, a Debian based image is assumed. Edit to your needs:
|
||||
|
||||
```yaml
|
||||
before_script:
|
||||
##
|
||||
## Install ssh-agent if not already installed, it is required by Docker.
|
||||
## (change apt-get to yum if you use an RPM-based image)
|
||||
##
|
||||
- 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
|
||||
|
||||
##
|
||||
## Run ssh-agent (inside the build environment)
|
||||
##
|
||||
- eval $(ssh-agent -s)
|
||||
|
||||
##
|
||||
## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
|
||||
## We're using tr to fix line endings which makes ed25519 keys work
|
||||
## without extra base64 encoding.
|
||||
## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
|
||||
##
|
||||
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
|
||||
|
||||
##
|
||||
## Create the SSH directory and give it the right permissions
|
||||
##
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
|
||||
##
|
||||
## Optionally, if you will be using any Git commands, set the user name and
|
||||
## and email.
|
||||
##
|
||||
# - git config --global user.email "user@example.com"
|
||||
# - git config --global user.name "User name"
|
||||
```
|
||||
|
||||
The [`before_script`](../yaml/README.md#before_script) can be set globally
|
||||
or per-job.
|
||||
|
||||
1. Make sure the private server's [SSH host keys are verified](#verifying-the-ssh-host-keys).
|
||||
|
||||
1. As a final step, add the _public_ key from the one you created in the first
|
||||
step to the services that you want to have an access to from within the build
|
||||
environment. If you are accessing a private GitLab repository you need to add
|
||||
it as a [deploy key](../../ssh/README.md#deploy-keys).
|
||||
|
||||
That's it! You can now have access to private servers or repositories in your
|
||||
build environment.
|
||||
|
||||
## SSH keys when using the Shell executor
|
||||
|
||||
If you are using the Shell executor and not Docker, it is easier to set up an
|
||||
SSH key.
|
||||
|
||||
You can generate the SSH key from the machine that GitLab Runner is installed
|
||||
on, and use that key for all projects that are run on this machine.
|
||||
|
||||
1. First, log in to the server that runs your jobs.
|
||||
|
||||
1. Then, from the terminal, log in as the `gitlab-runner` user:
|
||||
|
||||
```shell
|
||||
sudo su - gitlab-runner
|
||||
```
|
||||
|
||||
1. Generate the SSH key pair as described in the instructions to
|
||||
[generate an SSH key](../../ssh/README.md#generating-a-new-ssh-key-pair).
|
||||
**Do not** add a passphrase to the SSH key, or the `before_script` will
|
||||
prompt for it.
|
||||
|
||||
1. As a final step, add the _public_ key from the one you created earlier to the
|
||||
services that you want to have an access to from within the build environment.
|
||||
If you are accessing a private GitLab repository you need to add it as a
|
||||
[deploy key](../../ssh/README.md#deploy-keys).
|
||||
|
||||
After generating the key, try to sign in to the remote server to accept the
|
||||
fingerprint:
|
||||
|
||||
```shell
|
||||
ssh example.com
|
||||
```
|
||||
|
||||
For accessing repositories on GitLab.com, you would use `git@gitlab.com`.
|
||||
|
||||
## Verifying the SSH host keys
|
||||
|
||||
It is a good practice to check the private server's own public key to make sure
|
||||
you are not being targeted by a man-in-the-middle attack. If anything
|
||||
suspicious happens, you notice it because the job fails (the SSH
|
||||
connection fails when the public keys don't match).
|
||||
|
||||
To find out the host keys of your server, run the `ssh-keyscan` command from a
|
||||
trusted network (ideally, from the private server itself):
|
||||
|
||||
```shell
|
||||
## Use the domain name
|
||||
ssh-keyscan example.com
|
||||
|
||||
## Or use an IP
|
||||
ssh-keyscan 1.2.3.4
|
||||
```
|
||||
|
||||
Create a new [variable](../variables/README.md#gitlab-cicd-environment-variables) with
|
||||
`SSH_KNOWN_HOSTS` as "Key", and as a "Value" add the output of `ssh-keyscan`.
|
||||
|
||||
If you need to connect to multiple servers, all the server host keys
|
||||
need to be collected in the **Value** of the variable, one key per line.
|
||||
|
||||
NOTE:
|
||||
By using a variable instead of `ssh-keyscan` directly inside
|
||||
`.gitlab-ci.yml`, it has the benefit that you don't have to change `.gitlab-ci.yml`
|
||||
if the host domain name changes for some reason. Also, the values are predefined
|
||||
by you, meaning that if the host keys suddenly change, the CI/CD job doesn't fail,
|
||||
so there's something wrong with the server or the network.
|
||||
|
||||
Now that the `SSH_KNOWN_HOSTS` variable is created, in addition to the
|
||||
[content of `.gitlab-ci.yml`](#ssh-keys-when-using-the-docker-executor)
|
||||
above, here's what more you need to add:
|
||||
|
||||
```yaml
|
||||
before_script:
|
||||
##
|
||||
## Assuming you created the SSH_KNOWN_HOSTS variable, uncomment the
|
||||
## following two lines.
|
||||
##
|
||||
- echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
|
||||
- chmod 644 ~/.ssh/known_hosts
|
||||
|
||||
##
|
||||
## Alternatively, use ssh-keyscan to scan the keys of your private server.
|
||||
## Replace example.com with your private server's domain name. Repeat that
|
||||
## command if you have more than one server to connect to.
|
||||
##
|
||||
# - ssh-keyscan example.com >> ~/.ssh/known_hosts
|
||||
# - chmod 644 ~/.ssh/known_hosts
|
||||
|
||||
##
|
||||
## You can optionally disable host key checking. Be aware that by adding that
|
||||
## you are susceptible to man-in-the-middle attacks.
|
||||
## WARNING: Use this only with the Docker executor, if you use it with shell
|
||||
## you will overwrite your user's SSH config.
|
||||
##
|
||||
# - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config'
|
||||
```
|
||||
|
||||
## Example project
|
||||
|
||||
We have set up an [Example SSH Project](https://gitlab.com/gitlab-examples/ssh-private-key/) for your convenience
|
||||
that runs on [GitLab.com](https://gitlab.com) using our publicly available
|
||||
[shared runners](../runners/README.md).
|
||||
|
||||
Want to hack on it? Simply fork it, commit and push your changes. Within a few
|
||||
moments the changes is picked by a public runner and the job starts.
|
||||
<!-- This redirect file can be deleted after 2021-05-01. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Continuous Integration
|
||||
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
|
||||
type: tutorial
|
||||
---
|
||||
|
||||
# Using SSH keys with GitLab CI/CD
|
||||
|
||||
GitLab currently doesn't have built-in support for managing SSH keys in a build
|
||||
environment (where the GitLab Runner runs).
|
||||
|
||||
The SSH keys can be useful when:
|
||||
|
||||
1. You want to checkout internal submodules
|
||||
1. You want to download private packages using your package manager (e.g., Bundler)
|
||||
1. You want to deploy your application to your own server, or, for example, Heroku
|
||||
1. You want to execute SSH commands from the build environment to a remote server
|
||||
1. You want to rsync files from the build environment to a remote server
|
||||
|
||||
If anything of the above rings a bell, then you most likely need an SSH key.
|
||||
|
||||
The most widely supported method is to inject an SSH key into your build
|
||||
environment by extending your `.gitlab-ci.yml`, and it's a solution which works
|
||||
with any type of [executor](https://docs.gitlab.com/runner/executors/)
|
||||
(Docker, shell, etc.).
|
||||
|
||||
## How it works
|
||||
|
||||
1. Create a new SSH key pair locally with [`ssh-keygen`](https://linux.die.net/man/1/ssh-keygen)
|
||||
1. Add the private key as a [variable](../variables/README.md) to
|
||||
your project
|
||||
1. Run the [`ssh-agent`](https://linux.die.net/man/1/ssh-agent) during job to load
|
||||
the private key.
|
||||
1. Copy the public key to the servers you want to have access to (usually in
|
||||
`~/.ssh/authorized_keys`) or add it as a [deploy key](../../ssh/README.md#deploy-keys)
|
||||
if you are accessing a private GitLab repository.
|
||||
|
||||
The private key is displayed in the job log, unless you enable
|
||||
[debug logging](../variables/README.md#debug-logging). You might also want to
|
||||
check the [visibility of your pipelines](../pipelines/settings.md#visibility-of-pipelines).
|
||||
|
||||
## SSH keys when using the Docker executor
|
||||
|
||||
When your CI/CD jobs run inside Docker containers (meaning the environment is
|
||||
contained) and you want to deploy your code in a private server, you need a way
|
||||
to access it. This is where an SSH key pair comes in handy.
|
||||
|
||||
1. You first need to create an SSH key pair. For more information, follow
|
||||
the instructions to [generate an SSH key](../../ssh/README.md#generate-an-ssh-key-pair).
|
||||
**Do not** add a passphrase to the SSH key, or the `before_script` will
|
||||
prompt for it.
|
||||
|
||||
1. Create a new [variable](../variables/README.md#gitlab-cicd-environment-variables).
|
||||
As **Key** enter the name `SSH_PRIVATE_KEY` and in the **Value** field paste
|
||||
the content of your _private_ key that you created earlier.
|
||||
|
||||
1. Modify your `.gitlab-ci.yml` with a `before_script` action. In the following
|
||||
example, a Debian based image is assumed. Edit to your needs:
|
||||
|
||||
```yaml
|
||||
before_script:
|
||||
##
|
||||
## Install ssh-agent if not already installed, it is required by Docker.
|
||||
## (change apt-get to yum if you use an RPM-based image)
|
||||
##
|
||||
- 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
|
||||
|
||||
##
|
||||
## Run ssh-agent (inside the build environment)
|
||||
##
|
||||
- eval $(ssh-agent -s)
|
||||
|
||||
##
|
||||
## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
|
||||
## We're using tr to fix line endings which makes ed25519 keys work
|
||||
## without extra base64 encoding.
|
||||
## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
|
||||
##
|
||||
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
|
||||
|
||||
##
|
||||
## Create the SSH directory and give it the right permissions
|
||||
##
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
|
||||
##
|
||||
## Optionally, if you will be using any Git commands, set the user name and
|
||||
## and email.
|
||||
##
|
||||
# - git config --global user.email "user@example.com"
|
||||
# - git config --global user.name "User name"
|
||||
```
|
||||
|
||||
The [`before_script`](../yaml/README.md#before_script) can be set globally
|
||||
or per-job.
|
||||
|
||||
1. Make sure the private server's [SSH host keys are verified](#verifying-the-ssh-host-keys).
|
||||
|
||||
1. As a final step, add the _public_ key from the one you created in the first
|
||||
step to the services that you want to have an access to from within the build
|
||||
environment. If you are accessing a private GitLab repository you need to add
|
||||
it as a [deploy key](../../ssh/README.md#deploy-keys).
|
||||
|
||||
That's it! You can now have access to private servers or repositories in your
|
||||
build environment.
|
||||
|
||||
## SSH keys when using the Shell executor
|
||||
|
||||
If you are using the Shell executor and not Docker, it is easier to set up an
|
||||
SSH key.
|
||||
|
||||
You can generate the SSH key from the machine that GitLab Runner is installed
|
||||
on, and use that key for all projects that are run on this machine.
|
||||
|
||||
1. First, log in to the server that runs your jobs.
|
||||
|
||||
1. Then, from the terminal, log in as the `gitlab-runner` user:
|
||||
|
||||
```shell
|
||||
sudo su - gitlab-runner
|
||||
```
|
||||
|
||||
1. Generate the SSH key pair as described in the instructions to
|
||||
[generate an SSH key](../../ssh/README.md#generate-an-ssh-key-pair).
|
||||
**Do not** add a passphrase to the SSH key, or the `before_script` will
|
||||
prompt for it.
|
||||
|
||||
1. As a final step, add the _public_ key from the one you created earlier to the
|
||||
services that you want to have an access to from within the build environment.
|
||||
If you are accessing a private GitLab repository you need to add it as a
|
||||
[deploy key](../../ssh/README.md#deploy-keys).
|
||||
|
||||
After generating the key, try to sign in to the remote server to accept the
|
||||
fingerprint:
|
||||
|
||||
```shell
|
||||
ssh example.com
|
||||
```
|
||||
|
||||
For accessing repositories on GitLab.com, you would use `git@gitlab.com`.
|
||||
|
||||
## Verifying the SSH host keys
|
||||
|
||||
It is a good practice to check the private server's own public key to make sure
|
||||
you are not being targeted by a man-in-the-middle attack. If anything
|
||||
suspicious happens, you notice it because the job fails (the SSH
|
||||
connection fails when the public keys don't match).
|
||||
|
||||
To find out the host keys of your server, run the `ssh-keyscan` command from a
|
||||
trusted network (ideally, from the private server itself):
|
||||
|
||||
```shell
|
||||
## Use the domain name
|
||||
ssh-keyscan example.com
|
||||
|
||||
## Or use an IP
|
||||
ssh-keyscan 1.2.3.4
|
||||
```
|
||||
|
||||
Create a new [variable](../variables/README.md#gitlab-cicd-environment-variables) with
|
||||
`SSH_KNOWN_HOSTS` as "Key", and as a "Value" add the output of `ssh-keyscan`.
|
||||
|
||||
If you need to connect to multiple servers, all the server host keys
|
||||
need to be collected in the **Value** of the variable, one key per line.
|
||||
|
||||
NOTE:
|
||||
By using a variable instead of `ssh-keyscan` directly inside
|
||||
`.gitlab-ci.yml`, it has the benefit that you don't have to change `.gitlab-ci.yml`
|
||||
if the host domain name changes for some reason. Also, the values are predefined
|
||||
by you, meaning that if the host keys suddenly change, the CI/CD job doesn't fail,
|
||||
so there's something wrong with the server or the network.
|
||||
|
||||
Now that the `SSH_KNOWN_HOSTS` variable is created, in addition to the
|
||||
[content of `.gitlab-ci.yml`](#ssh-keys-when-using-the-docker-executor)
|
||||
above, here's what more you need to add:
|
||||
|
||||
```yaml
|
||||
before_script:
|
||||
##
|
||||
## Assuming you created the SSH_KNOWN_HOSTS variable, uncomment the
|
||||
## following two lines.
|
||||
##
|
||||
- echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
|
||||
- chmod 644 ~/.ssh/known_hosts
|
||||
|
||||
##
|
||||
## Alternatively, use ssh-keyscan to scan the keys of your private server.
|
||||
## Replace example.com with your private server's domain name. Repeat that
|
||||
## command if you have more than one server to connect to.
|
||||
##
|
||||
# - ssh-keyscan example.com >> ~/.ssh/known_hosts
|
||||
# - chmod 644 ~/.ssh/known_hosts
|
||||
|
||||
##
|
||||
## You can optionally disable host key checking. Be aware that by adding that
|
||||
## you are susceptible to man-in-the-middle attacks.
|
||||
## WARNING: Use this only with the Docker executor, if you use it with shell
|
||||
## you will overwrite your user's SSH config.
|
||||
##
|
||||
# - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config'
|
||||
```
|
||||
|
||||
## Example project
|
||||
|
||||
We have set up an [Example SSH Project](https://gitlab.com/gitlab-examples/ssh-private-key/) for your convenience
|
||||
that runs on [GitLab.com](https://gitlab.com) using our publicly available
|
||||
[shared runners](../runners/README.md).
|
||||
|
||||
Want to hack on it? Simply fork it, commit and push your changes. Within a few
|
||||
moments the changes is picked by a public runner and the job starts.
|
|
@ -22,8 +22,8 @@ Kubernetes-specific environment variables are detailed in the
|
|||
|
||||
| Variable | GitLab | Runner | Description |
|
||||
|-----------------------------------------------|--------|--------|-------------|
|
||||
| `CHAT_CHANNEL` | 10.6 | all | Source chat channel which triggered the [ChatOps](../chatops/README.md) command. |
|
||||
| `CHAT_INPUT` | 10.6 | all | Additional arguments passed in the [ChatOps](../chatops/README.md) command. |
|
||||
| `CHAT_CHANNEL` | 10.6 | all | Source chat channel which triggered the [ChatOps](../chatops/index.md) command. |
|
||||
| `CHAT_INPUT` | 10.6 | all | Additional arguments passed in the [ChatOps](../chatops/index.md) command. |
|
||||
| `CI` | all | 0.4 | Mark that job is executed in CI environment. |
|
||||
| `CI_API_V4_URL` | 11.7 | all | The GitLab API v4 root URL. |
|
||||
| `CI_BUILDS_DIR` | all | 11.10 | Top-level directory where builds are executed. |
|
||||
|
|
|
@ -13,7 +13,7 @@ type: reference
|
|||
|
||||
This document lists the configuration options for your GitLab `.gitlab-ci.yml` file.
|
||||
|
||||
- For a quick introduction to GitLab CI/CD, follow the [quick start guide](../quick_start/README.md).
|
||||
- For a quick introduction to GitLab CI/CD, follow the [quick start guide](../quick_start/index.md).
|
||||
- For a collection of examples, see [GitLab CI/CD Examples](../examples/README.md).
|
||||
- To view a large `.gitlab-ci.yml` file used in an enterprise, see the [`.gitlab-ci.yml` file for `gitlab`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml).
|
||||
|
||||
|
@ -543,7 +543,7 @@ Used to specify [a Docker image](../docker/using_docker_images.md#what-is-an-ima
|
|||
For:
|
||||
|
||||
- Usage examples, see [Define `image` and `services` from `.gitlab-ci.yml`](../docker/using_docker_images.md#define-image-and-services-from-gitlab-ciyml).
|
||||
- Detailed usage information, refer to [Docker integration](../docker/README.md) documentation.
|
||||
- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation.
|
||||
|
||||
#### `image:name`
|
||||
|
||||
|
@ -564,8 +564,8 @@ Used to specify a [service Docker image](../docker/using_docker_images.md#what-i
|
|||
For:
|
||||
|
||||
- Usage examples, see [Define `image` and `services` from `.gitlab-ci.yml`](../docker/using_docker_images.md#define-image-and-services-from-gitlab-ciyml).
|
||||
- Detailed usage information, refer to [Docker integration](../docker/README.md) documentation.
|
||||
- For example services, see [GitLab CI/CD Services](../services/README.md).
|
||||
- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation.
|
||||
- For example services, see [GitLab CI/CD Services](../services/index.md).
|
||||
|
||||
##### `services:name`
|
||||
|
||||
|
@ -1253,7 +1253,7 @@ check the value of the `$CI_PIPELINE_SOURCE` variable:
|
|||
| Value | Description |
|
||||
|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `api` | For pipelines triggered by the [pipelines API](../../api/pipelines.md#create-a-new-pipeline). |
|
||||
| `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/README.md) command. |
|
||||
| `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/index.md) command. |
|
||||
| `external` | When you use CI services other than GitLab. |
|
||||
| `external_pull_request_event` | When an external pull request on GitHub is created or updated. See [Pipelines for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). |
|
||||
| `merge_request_event` | For pipelines created when a merge request is created or updated. Required to enable [merge request pipelines](../merge_request_pipelines/index.md), [merged results pipelines](../merge_request_pipelines/pipelines_for_merged_results/index.md), and [merge trains](../merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md). |
|
||||
|
@ -1553,7 +1553,7 @@ In addition, `only` and `except` can use special keywords:
|
|||
|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `api` | For pipelines triggered by the [pipelines API](../../api/pipelines.md#create-a-new-pipeline). |
|
||||
| `branches` | When the Git reference for a pipeline is a branch. |
|
||||
| `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/README.md) command. |
|
||||
| `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/index.md) command. |
|
||||
| `external` | When you use CI services other than GitLab. |
|
||||
| `external_pull_requests` | When an external pull request on GitHub is created or updated (See [Pipelines for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests)). |
|
||||
| `merge_requests` | For pipelines created when a merge request is created or updated. Enables [merge request pipelines](../merge_request_pipelines/index.md), [merged results pipelines](../merge_request_pipelines/pipelines_for_merged_results/index.md), and [merge trains](../merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md). |
|
||||
|
|
|
@ -61,6 +61,6 @@ To request access to ChatOps on GitLab.com:
|
|||
|
||||
## See also
|
||||
|
||||
- [ChatOps Usage](../ci/chatops/README.md)
|
||||
- [ChatOps Usage](../ci/chatops/index.md)
|
||||
- [Understanding EXPLAIN plans](understanding_explain_plans.md)
|
||||
- [Feature Groups](feature_flags/development.md#feature-groups)
|
||||
|
|
|
@ -181,11 +181,21 @@ reasons for including it.
|
|||
`@mention` a maintainer in merge requests that contain:
|
||||
|
||||
- More than 500 changes.
|
||||
- Any major breaking changes.
|
||||
- Any major [breaking changes](#breaking-changes).
|
||||
- External libraries.
|
||||
|
||||
If you are not sure who to mention, the reviewer will do this for you early in the merge request process.
|
||||
|
||||
#### Breaking changes
|
||||
|
||||
A "breaking change" is any change that requires users to make a corresponding change to their code, settings, or workflow. "Users" might be humans, API clients, or even code classes that "use" another class. Examples of breaking changes include:
|
||||
|
||||
- Removing a user-facing feature without a replacement/workaround.
|
||||
- Changing the definition of an existing API (by re-naming query parameters, changing routes, etc.).
|
||||
- Removing a public method from a code class.
|
||||
|
||||
A breaking change can be considered "major" if it affects many users, or represents a significant change in behavior.
|
||||
|
||||
#### Issues workflow
|
||||
|
||||
This [documentation](issue_workflow.md) outlines the current issue workflow:
|
||||
|
|
|
@ -150,7 +150,7 @@ Commit messages should follow the guidelines below, for reasons explained by Chr
|
|||
#### Why these standards matter
|
||||
|
||||
1. Consistent commit messages that follow these guidelines make the history more readable.
|
||||
1. Concise standard commit messages helps to identify breaking changes for a deployment or ~"master:broken" quicker when
|
||||
1. Concise standard commit messages helps to identify [breaking changes](index.md#breaking-changes) for a deployment or ~"master:broken" quicker when
|
||||
reviewing commits between two points in time.
|
||||
|
||||
#### Commit message template
|
||||
|
|
|
@ -325,7 +325,7 @@ Note that the use of this method requires that we have first [recorded the user
|
|||
|
||||
### Enable the experiment
|
||||
|
||||
After all merge requests have been merged, use [`chatops`](../../ci/chatops/README.md) in the
|
||||
After all merge requests have been merged, use [`chatops`](../../ci/chatops/index.md) in the
|
||||
[appropriate channel](../feature_flags/controls.md#communicate-the-change) to start the experiment for 10% of the users.
|
||||
The feature flag should have the name of the experiment with the `_experiment_percentage` suffix appended.
|
||||
For visibility, please also share any commands run against production in the `#s_growth` channel:
|
||||
|
|
|
@ -37,7 +37,7 @@ easier to measure the impact of both separately.
|
|||
The GitLab feature library (using
|
||||
[Flipper](https://github.com/jnunemaker/flipper), and covered in the [Feature
|
||||
Flags process](process.md) guide) supports rolling out changes to a percentage of
|
||||
time to users. This in turn can be controlled using [GitLab ChatOps](../../ci/chatops/README.md).
|
||||
time to users. This in turn can be controlled using [GitLab ChatOps](../../ci/chatops/index.md).
|
||||
|
||||
For an up to date list of feature flag commands please see [the source
|
||||
code](https://gitlab.com/gitlab-com/chatops/blob/master/lib/chatops/commands/feature.rb).
|
||||
|
|
|
@ -75,5 +75,10 @@ This section describes how to add new metrics for self-monitoring
|
|||
1. Select the appropriate name for your metric. Refer to the guidelines
|
||||
for [Prometheus metric names](https://prometheus.io/docs/practices/naming/#metric-names).
|
||||
1. Update the list of [GitLab Prometheus metrics](../administration/monitoring/prometheus/gitlab_metrics.md).
|
||||
1. Carefully choose what labels you want to add to your metric. Values with high cardinality,
|
||||
like `project_path`, or `project_id` are strongly discouraged because they can affect our services
|
||||
availability due to the fact that each set of labels is exposed as a new entry in the `/metrics` endpoint.
|
||||
For example, a histogram with 10 buckets and a label with 100 values would generate 1000
|
||||
entries in the export endpoint.
|
||||
1. Trigger the relevant page or code that records the new metric.
|
||||
1. Check that the new metric appears at `/-/metrics`.
|
||||
|
|
|
@ -26,7 +26,7 @@ Taking the trigger term as `project-name`, the commands are:
|
|||
| `/project-name issue move <id> to <project>` | Moves issue ID `<id>` to `<project>` |
|
||||
| `/project-name issue comment <id> <shift+return> <comment>` | Adds a new comment to an issue with ID `<id>` and comment body `<comment>` |
|
||||
| `/project-name deploy <from> to <to>` | Deploy from the `<from>` environment to the `<to>` environment |
|
||||
| `/project-name run <job name> <arguments>` | Execute [ChatOps](../ci/chatops/README.md) job `<job name>` on `master` |
|
||||
| `/project-name run <job name> <arguments>` | Execute [ChatOps](../ci/chatops/index.md) job `<job name>` on `master` |
|
||||
|
||||
If you are using the [GitLab Slack application](../user/project/integrations/gitlab_slack_application.md) for
|
||||
your GitLab.com projects, [add the `gitlab` keyword at the beginning of the command](../user/project/integrations/gitlab_slack_application.md#usage).
|
||||
|
|
|
@ -38,7 +38,7 @@ Create merge requests and review code.
|
|||
|
||||
Use the built-in continuous integration in GitLab.
|
||||
|
||||
- [Get started with GitLab CI/CD](../ci/quick_start/README.md)
|
||||
- [Get started with GitLab CI/CD](../ci/quick_start/index.md)
|
||||
|
||||
## Install and Update
|
||||
|
||||
|
|
|
@ -17,179 +17,145 @@ GitLab remote server without supplying your username or password each time.
|
|||
This page can help you configure secure SSH keys which you can use to help secure
|
||||
connections to GitLab repositories.
|
||||
|
||||
- If you need information on creating SSH keys, start with our [options for SSH keys](#options-for-ssh-keys).
|
||||
- If you need information on creating SSH keys, start with our [options for SSH keys](#supported-ssh-key-types).
|
||||
- If you have SSH keys dedicated for your GitLab account, you may be interested in [Working with non-default SSH key pair paths](#working-with-non-default-ssh-key-pair-paths).
|
||||
- If you already have an SSH key pair, you can go to how you can [add an SSH key to your GitLab account](#adding-an-ssh-key-to-your-gitlab-account).
|
||||
- If you already have an SSH key pair, you can go to how you can [add an SSH key to your GitLab account](#add-an-ssh-key-to-your-gitlab-account).
|
||||
|
||||
## Requirements
|
||||
## Prerequisites
|
||||
|
||||
To support SSH, GitLab requires the installation of the OpenSSH client, which
|
||||
comes pre-installed on GNU/Linux and macOS, as well as on Windows 10.
|
||||
To use SSH to communicate with GitLab, you need:
|
||||
|
||||
Make sure that your system includes SSH version 6.5 or newer, as that excludes
|
||||
the now insecure MD5 signature scheme. The following command returns the version of
|
||||
SSH installed on your system:
|
||||
- The OpenSSH client, which comes pre-installed on GNU/Linux, macOS, and Windows 10.
|
||||
- SSH version 6.5 or later. Earlier versions used an MD5 signature, which is not secure.
|
||||
|
||||
```shell
|
||||
ssh -V
|
||||
```
|
||||
To view the version of SSH installed on your system, run `ssh -V`.
|
||||
|
||||
While GitLab does [not support installation on Microsoft Windows](../install/requirements.md#microsoft-windows),
|
||||
you can set up SSH keys to set up Windows [as a client](#options-for-microsoft-windows).
|
||||
GitLab does [not support installation on Microsoft Windows](../install/requirements.md#microsoft-windows),
|
||||
but you can set up SSH keys on the Windows [client](#options-for-microsoft-windows).
|
||||
|
||||
## Options for SSH keys
|
||||
## Supported SSH key types
|
||||
|
||||
GitLab supports the use of RSA, DSA, ECDSA, and ED25519 keys.
|
||||
To communicate with GitLab, you can use the following SSH key types:
|
||||
|
||||
- GitLab has [deprecated](https://about.gitlab.com/releases/2018/06/22/gitlab-11-0-released/#support-for-dsa-ssh-keys) DSA keys in GitLab 11.0.
|
||||
- As noted in [Practical Cryptography With Go](https://leanpub.com/gocrypto/read#leanpub-auto-ecdsa), the security issues related to DSA also apply to ECDSA.
|
||||
- [ED25519](#ed25519-ssh-keys)
|
||||
- [RSA](#rsa-ssh-keys)
|
||||
- DSA ([Deprecated](https://about.gitlab.com/releases/2018/06/22/gitlab-11-0-released/#support-for-dsa-ssh-keys) in GitLab 11.0.)
|
||||
- ECDSA (As noted in [Practical Cryptography With Go](https://leanpub.com/gocrypto/read#leanpub-auto-ecdsa), the security issues related to DSA also apply to ECDSA.)
|
||||
|
||||
NOTE:
|
||||
Available documentation suggests that ED25519 is more secure. If you use an RSA key, the US National Institute of Science and Technology in [Publication 800-57 Part 3 (PDF)](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf) recommends a key size of at least 2048 bits.
|
||||
|
||||
Therefore, our documentation focuses on the use of ED25519 and RSA keys.
|
||||
|
||||
Administrators can [restrict which keys should be permitted and their minimum lengths](../security/ssh_keys_restrictions.md).
|
||||
|
||||
## Review existing SSH keys
|
||||
|
||||
If you have existing SSH keys, you may be able to use them to help secure connections with GitLab
|
||||
repositories. By default, SSH keys on Linux and macOS systems are stored in the user's home directory,
|
||||
in the `.ssh/` subdirectory. The following table includes default filenames for each SSH key algorithm:
|
||||
|
||||
| Algorithm | Public key | Private key |
|
||||
| --------- | ---------- | ----------- |
|
||||
| ED25519 (preferred) | `id_ed25519.pub` | `id_ed25519` |
|
||||
| RSA (at least 2048-bit key size) | `id_rsa.pub` | `id_rsa` |
|
||||
| DSA (deprecated) | `id_dsa.pub` | `id_dsa` |
|
||||
| ECDSA | `id_ecdsa.pub` | `id_ecdsa` |
|
||||
|
||||
For recommendations, see [options for SSH keys](#options-for-ssh-keys).
|
||||
|
||||
## Generating a new SSH key pair
|
||||
|
||||
If you want to create:
|
||||
|
||||
- An ED25519 key, read [ED25519 SSH keys](#ed25519-ssh-keys).
|
||||
- An RSA key, read [RSA SSH keys](#rsa-ssh-keys).
|
||||
Administrators can [restrict which keys are permitted and their minimum lengths](../security/ssh_keys_restrictions.md).
|
||||
|
||||
### ED25519 SSH keys
|
||||
|
||||
The book [Practical Cryptography With Go](https://leanpub.com/gocrypto/read#leanpub-auto-chapter-5-digital-signatures)
|
||||
suggests that [ED25519](https://ed25519.cr.yp.to/) keys are more secure and performant than RSA keys.
|
||||
|
||||
As OpenSSH 6.5 introduced ED25519 SSH keys in 2014, they should be available on any current
|
||||
operating system.
|
||||
|
||||
You can create and configure an ED25519 key with the following command:
|
||||
|
||||
```shell
|
||||
ssh-keygen -t ed25519 -C "<comment>"
|
||||
```
|
||||
|
||||
The `-C` flag, with a quoted comment such as an email address, is an optional way to label your SSH keys.
|
||||
|
||||
You'll see a response similar to:
|
||||
|
||||
```plaintext
|
||||
Generating public/private ed25519 key pair.
|
||||
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
|
||||
```
|
||||
|
||||
For guidance, proceed to the [common steps](#common-steps-for-generating-an-ssh-key-pair).
|
||||
OpenSSH 6.5 introduced ED25519 SSH keys in 2014 and they should be available on most
|
||||
operating systems.
|
||||
|
||||
### RSA SSH keys
|
||||
|
||||
If you use RSA keys for SSH, the US National Institute of Standards and Technology recommends
|
||||
that you use a key size of [at least 2048 bits](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf).
|
||||
By default, the `ssh-keygen` command creates an 1024-bit RSA key.
|
||||
Available documentation suggests that ED25519 is more secure than RSA.
|
||||
|
||||
You can create and configure an RSA key with the following command, substituting if desired for the minimum recommended key size of `2048`:
|
||||
If you use an RSA key, the US National Institute of Science and Technology in
|
||||
[Publication 800-57 Part 3 (PDF)](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf)
|
||||
recommends a key size of at least 2048 bits. The default key size depends on your version of `ssh-keygen`.
|
||||
Review the `man` page for your installed `ssh-keygen` command for details.
|
||||
|
||||
```shell
|
||||
ssh-keygen -t rsa -b 2048 -C "email@example.com"
|
||||
```
|
||||
## See if you have an existing SSH key pair
|
||||
|
||||
The `-C` flag, with a quoted comment such as an email address, is an optional way to label your SSH keys.
|
||||
Before you create a key pair, see if a key pair already exists.
|
||||
|
||||
You'll see a response similar to:
|
||||
1. On Linux or macOS, go to your home directory.
|
||||
1. Go to the `.ssh/` subdirectory.
|
||||
1. See if a file with one of the following formats exists:
|
||||
|
||||
```plaintext
|
||||
Generating public/private rsa key pair.
|
||||
Enter file in which to save the key (/home/user/.ssh/id_rsa):
|
||||
```
|
||||
| Algorithm | Public key | Private key |
|
||||
| --------- | ---------- | ----------- |
|
||||
| ED25519 (preferred) | `id_ed25519.pub` | `id_ed25519` |
|
||||
| RSA (at least 2048-bit key size) | `id_rsa.pub` | `id_rsa` |
|
||||
| DSA (deprecated) | `id_dsa.pub` | `id_dsa` |
|
||||
| ECDSA | `id_ecdsa.pub` | `id_ecdsa` |
|
||||
|
||||
For guidance, proceed to the [common steps](#common-steps-for-generating-an-ssh-key-pair).
|
||||
## Generate an SSH key pair
|
||||
|
||||
NOTE:
|
||||
If you have OpenSSH version 7.8 or below, consider the problems associated
|
||||
with [encoding](#rsa-keys-and-openssh-from-versions-65-to-78).
|
||||
If you do not have an existing SSH key pair, generate a new one.
|
||||
|
||||
### Common steps for generating an SSH key pair
|
||||
1. Open a terminal.
|
||||
1. Type `ssh-keygen -t` followed by the key type and an optional comment.
|
||||
This comment is included in the `.pub` file that's created.
|
||||
You may want to use an email address for the comment.
|
||||
|
||||
For example, for ED25519:
|
||||
|
||||
Whether you're creating a [ED25519](#ed25519-ssh-keys) or an [RSA](#rsa-ssh-keys) key, you've started with the `ssh-keygen` command.
|
||||
At this point, you'll see the following message in the command line (for ED25519 keys):
|
||||
```shell
|
||||
ssh-keygen -t ed25519 -C "<comment>"
|
||||
```
|
||||
|
||||
```plaintext
|
||||
Generating public/private ed25519 key pair.
|
||||
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
|
||||
```
|
||||
For 2048-bit RSA:
|
||||
|
||||
If you don't already have an SSH key pair and are not generating a [deploy key](#deploy-keys),
|
||||
accept the suggested file and directory. Your SSH client uses
|
||||
the resulting SSH key pair with no additional configuration.
|
||||
```shell
|
||||
ssh-keygen -t rsa -b 2048 -C "<comment>"
|
||||
```
|
||||
|
||||
Alternatively, you can save the new SSH key pair in a different location.
|
||||
You can assign the directory and filename of your choice.
|
||||
You can also dedicate that SSH key pair to a [specific host](#working-with-non-default-ssh-key-pair-paths).
|
||||
1. Press Enter. Output similar to the following is displayed:
|
||||
|
||||
After assigning a file to save your SSH key, you can set up
|
||||
a [passphrase](https://www.ssh.com/ssh/passphrase/) for your SSH key:
|
||||
```plaintext
|
||||
Generating public/private ed25519 key pair.
|
||||
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
|
||||
```
|
||||
|
||||
```plaintext
|
||||
Enter passphrase (empty for no passphrase):
|
||||
Enter same passphrase again:
|
||||
```
|
||||
1. Accept the suggested filename and directory, unless you are generating a [deploy key](#deploy-keys)
|
||||
or want to save in a specific directory where you store other keys.
|
||||
|
||||
If successful, you'll see confirmation of where the `ssh-keygen` command
|
||||
saved your identification and private key.
|
||||
You can also dedicate the SSH key pair to a [specific host](#working-with-non-default-ssh-key-pair-paths).
|
||||
|
||||
When needed, you can update the passphrase with the following command:
|
||||
1. Specify a [passphrase](https://www.ssh.com/ssh/passphrase/):
|
||||
|
||||
```shell
|
||||
ssh-keygen -p -f /path/to/ssh_key
|
||||
```
|
||||
```plaintext
|
||||
Enter passphrase (empty for no passphrase):
|
||||
Enter same passphrase again:
|
||||
```
|
||||
|
||||
### RSA keys and OpenSSH from versions 6.5 to 7.8
|
||||
1. A confirmation is displayed, including information about where your files are stored.
|
||||
|
||||
Before OpenSSH 7.8, the default public key fingerprint for RSA keys was based on MD5,
|
||||
and is therefore insecure.
|
||||
A public and private key are generated.
|
||||
[Add the public SSH key to your GitLab account](#add-an-ssh-key-to-your-gitlab-account) and keep
|
||||
the private key secure.
|
||||
|
||||
If your version of OpenSSH lies between version 6.5 to version 7.8 (inclusive),
|
||||
run `ssh-keygen` with the `-o` option to save your private SSH keys in the more secure
|
||||
### Update your SSH key passphrase
|
||||
|
||||
You can update the passphrase for your SSH key.
|
||||
|
||||
1. Open a terminal and type this command:
|
||||
|
||||
```shell
|
||||
ssh-keygen -p -f /path/to/ssh_key
|
||||
```
|
||||
|
||||
1. At the prompts, type the passphrase and press Enter.
|
||||
|
||||
### Upgrade your RSA key pair to a more secure format
|
||||
|
||||
If your version of OpenSSH is between 6.5 and 7.8,
|
||||
you can save your private RSA SSH keys in a more secure
|
||||
OpenSSH format.
|
||||
|
||||
If you already have an RSA SSH key pair to use with GitLab, consider upgrading it
|
||||
to use the more secure password encryption format. You can do so with the following command:
|
||||
1. Open a terminal and type this command:
|
||||
|
||||
```shell
|
||||
ssh-keygen -o -f ~/.ssh/id_rsa
|
||||
```
|
||||
```shell
|
||||
ssh-keygen -o -f ~/.ssh/id_rsa
|
||||
```
|
||||
|
||||
Alternatively, you can generate a new RSA key with the more secure encryption format with
|
||||
the following command:
|
||||
Alternatively, you can generate a new RSA key with the more secure encryption format with
|
||||
the following command:
|
||||
|
||||
```shell
|
||||
ssh-keygen -o -t rsa -b 4096 -C "email@example.com"
|
||||
```
|
||||
```shell
|
||||
ssh-keygen -o -t rsa -b 4096 -C "<comment>"
|
||||
```
|
||||
|
||||
NOTE:
|
||||
As noted in the `ssh-keygen` man page, ED25519 already encrypts keys to the more secure
|
||||
OpenSSH format.
|
||||
## Add an SSH key to your GitLab account
|
||||
|
||||
## Adding an SSH key to your GitLab account
|
||||
|
||||
Now you can copy the SSH key you created to your GitLab account. To do so, follow these steps:
|
||||
Now you can copy the SSH key you created to your GitLab account.
|
||||
|
||||
1. Copy your **public** SSH key to a location that saves information in text format.
|
||||
The following options saves information for ED25519 keys to the clipboard
|
||||
|
|
|
@ -842,6 +842,17 @@ The site is validated and an active scan can run against it.
|
|||
|
||||
If a validated site profile's target URL is edited, the site is no longer validated.
|
||||
|
||||
### Revoke a site validation
|
||||
|
||||
To revoke validation from a site profile:
|
||||
|
||||
1. From your project's home page, go to **Security & Compliance > Configuration**.
|
||||
1. Select **Manage** in the **DAST Profiles** row.
|
||||
1. Select **Revoke validation** beside the validated profile.
|
||||
1. Select **Revoke validation**.
|
||||
|
||||
The site profile's validation is revoked. An active scan cannot be run against it or any other profile with the same URL.
|
||||
|
||||
#### Validated site profile headers
|
||||
|
||||
The following are code samples of how you could provide the required site profile header in your
|
||||
|
|
|
@ -43,7 +43,7 @@ You can either use the user interface (UI), or connect your local computer
|
|||
with GitLab [through the command line](../../../gitlab-basics/command-line-commands.md#start-working-on-your-project).
|
||||
|
||||
To configure [GitLab CI/CD](../../../ci/README.md) to build, test, and deploy
|
||||
your code, add a file called [`.gitlab-ci.yml`](../../../ci/quick_start/README.md)
|
||||
your code, add a file called [`.gitlab-ci.yml`](../../../ci/quick_start/index.md)
|
||||
to your repository's root.
|
||||
|
||||
**From the user interface:**
|
||||
|
|
|
@ -36,7 +36,7 @@ module API
|
|||
get ':id/deployments' do
|
||||
authorize! :read_deployment, user_project
|
||||
|
||||
deployments = DeploymentsFinder.new(user_project, params).execute
|
||||
deployments = DeploymentsFinder.new(params.merge(project: user_project)).execute
|
||||
|
||||
present paginate(deployments), with: Entities::Deployment
|
||||
end
|
||||
|
|
|
@ -9,6 +9,9 @@ module API
|
|||
expose :job_artifacts, as: :artifacts, using: ::API::Entities::Ci::JobArtifact
|
||||
expose :runner, with: ::API::Entities::Runner
|
||||
expose :artifacts_expire_at
|
||||
expose :tag_list do |job|
|
||||
job.tags.map(&:name).sort
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -45,7 +45,7 @@ module API
|
|||
builds = user_project.builds.order('id DESC')
|
||||
builds = filter_builds(builds, params[:scope])
|
||||
|
||||
builds = builds.preload(:user, :job_artifacts_archive, :job_artifacts, :runner, pipeline: :project)
|
||||
builds = builds.preload(:user, :job_artifacts_archive, :job_artifacts, :runner, :tags, pipeline: :project)
|
||||
present paginate(builds), with: Entities::Ci::Job
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
|
|
@ -15,9 +15,16 @@ module Gitlab
|
|||
private
|
||||
|
||||
def deployments_count
|
||||
query = @project.deployments.success.where("created_at >= ?", @from)
|
||||
query = query.where("created_at <= ?", @to) if @to
|
||||
query.count
|
||||
if Feature.enabled?(:query_deploymenys_via_finished_at_in_vsa)
|
||||
DeploymentsFinder
|
||||
.new(project: @project, finished_after: @from, finished_before: @to, status: :success)
|
||||
.execute
|
||||
.count
|
||||
else
|
||||
query = @project.deployments.success.where("created_at >= ?", @from)
|
||||
query = query.where("created_at <= ?", @to) if @to
|
||||
query.count
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,9 +48,21 @@ namespace :gitlab do
|
|||
if summary == :client_query
|
||||
$stdout.puts " - client query"
|
||||
elsif errs.present?
|
||||
$stdout.puts " - invalid query"
|
||||
$stdout.puts " - invalid query".color(:red)
|
||||
else
|
||||
$stdout.puts " - complexity: #{defn.complexity(GitlabSchema)}"
|
||||
complexity = defn.complexity(GitlabSchema)
|
||||
color = case complexity
|
||||
when 0..GitlabSchema::DEFAULT_MAX_COMPLEXITY
|
||||
:green
|
||||
when GitlabSchema::DEFAULT_MAX_COMPLEXITY..GitlabSchema::AUTHENTICATED_COMPLEXITY
|
||||
:yellow
|
||||
when GitlabSchema::AUTHENTICATED_COMPLEXITY..GitlabSchema::ADMIN_COMPLEXITY
|
||||
:orange
|
||||
else
|
||||
:red
|
||||
end
|
||||
|
||||
$stdout.puts " - complexity: #{complexity}".color(color)
|
||||
end
|
||||
|
||||
$stdout.puts ""
|
||||
|
@ -72,10 +84,10 @@ namespace :gitlab do
|
|||
when :client_query
|
||||
warn("SKIP #{defn.file}: client query")
|
||||
else
|
||||
warn("OK #{defn.file}") if errs.empty?
|
||||
warn("#{'OK'.color(:green)} #{defn.file}") if errs.empty?
|
||||
errs.each do |err|
|
||||
warn(<<~MSG)
|
||||
ERROR #{defn.file}: #{err.message} (at #{err.path.join('.')})
|
||||
#{'ERROR'.color(:red)} #{defn.file}: #{err.message} (at #{err.path.join('.')})
|
||||
MSG
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9194,6 +9194,9 @@ msgstr ""
|
|||
msgid "DastSiteValidation|Could not create validation token. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "DastSiteValidation|Could not revoke validation. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "DastSiteValidation|Download validation text file"
|
||||
msgstr ""
|
||||
|
||||
|
@ -9203,6 +9206,9 @@ msgstr ""
|
|||
msgid "DastSiteValidation|Retry validation"
|
||||
msgstr ""
|
||||
|
||||
msgid "DastSiteValidation|Revoke validation"
|
||||
msgstr ""
|
||||
|
||||
msgid "DastSiteValidation|Step 1 - Choose site validation method"
|
||||
msgstr ""
|
||||
|
||||
|
@ -9227,6 +9233,11 @@ msgstr ""
|
|||
msgid "DastSiteValidation|The validation is in progress. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "DastSiteValidation|This will affect %d other profile targeting the same URL."
|
||||
msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "DastSiteValidation|Validate"
|
||||
msgstr ""
|
||||
|
||||
|
@ -9245,6 +9256,9 @@ msgstr ""
|
|||
msgid "DastSiteValidation|Validation succeeded. Both active and passive scans can be run against the target site."
|
||||
msgstr ""
|
||||
|
||||
msgid "DastSiteValidation|You will not be able to run active scans against %{url}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Data is still calculating..."
|
||||
msgstr ""
|
||||
|
||||
|
@ -23047,6 +23061,9 @@ msgstr ""
|
|||
msgid "ProjectSettings|Require"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectSettings|Require an associated issue from Jira"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectSettings|Requirements"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -177,9 +177,9 @@
|
|||
"docdash": "^1.0.2",
|
||||
"eslint": "7.19.0",
|
||||
"eslint-import-resolver-jest": "3.0.0",
|
||||
"eslint-import-resolver-webpack": "^0.12.1",
|
||||
"eslint-plugin-jasmine": "^4.1.0",
|
||||
"eslint-plugin-no-jquery": "^2.3.0",
|
||||
"eslint-import-resolver-webpack": "0.12.1",
|
||||
"eslint-plugin-jasmine": "4.1.0",
|
||||
"eslint-plugin-no-jquery": "2.3.1",
|
||||
"gettext-extractor": "^3.4.3",
|
||||
"gettext-extractor-vue": "^4.0.2",
|
||||
"istanbul-lib-coverage": "^3.0.0",
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe DeploymentsFinder do
|
||||
subject { described_class.new(project, params).execute }
|
||||
subject { described_class.new(params).execute }
|
||||
|
||||
let(:project) { create(:project, :public, :test_repo) }
|
||||
let(:params) { {} }
|
||||
let_it_be(:project) { create(:project, :public, :test_repo) }
|
||||
let(:params) { { project: project } }
|
||||
|
||||
describe "#execute" do
|
||||
it 'returns all deployments by default' do
|
||||
|
@ -14,9 +14,17 @@ RSpec.describe DeploymentsFinder do
|
|||
is_expected.to match_array(deployments)
|
||||
end
|
||||
|
||||
context 'when project is missing' do
|
||||
let(:params) { {} }
|
||||
|
||||
it 'returns nothing' do
|
||||
is_expected.to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'filtering' do
|
||||
context 'when updated_at filters are specified' do
|
||||
let(:params) { { updated_before: 1.day.ago, updated_after: 3.days.ago } }
|
||||
let(:params) { { project: project, updated_before: 1.day.ago, updated_after: 3.days.ago } }
|
||||
let!(:deployment_1) { create(:deployment, :success, project: project, updated_at: 2.days.ago) }
|
||||
let!(:deployment_2) { create(:deployment, :success, project: project, updated_at: 4.days.ago) }
|
||||
let!(:deployment_3) { create(:deployment, :success, project: project, updated_at: 1.hour.ago) }
|
||||
|
@ -37,7 +45,7 @@ RSpec.describe DeploymentsFinder do
|
|||
create(:deployment, project: project, environment: environment2)
|
||||
end
|
||||
|
||||
let(:params) { { environment: environment1.name } }
|
||||
let(:params) { { project: project, environment: environment1.name } }
|
||||
|
||||
it 'returns deployments for the given environment' do
|
||||
is_expected.to match_array([deployment1])
|
||||
|
@ -47,7 +55,7 @@ RSpec.describe DeploymentsFinder do
|
|||
context 'when the deployment status is specified' do
|
||||
let!(:deployment1) { create(:deployment, :success, project: project) }
|
||||
let!(:deployment2) { create(:deployment, :failed, project: project) }
|
||||
let(:params) { { status: 'success' } }
|
||||
let(:params) { { project: project, status: 'success' } }
|
||||
|
||||
it 'returns deployments for the given environment' do
|
||||
is_expected.to match_array([deployment1])
|
||||
|
@ -55,36 +63,64 @@ RSpec.describe DeploymentsFinder do
|
|||
end
|
||||
|
||||
context 'when using an invalid deployment status' do
|
||||
let(:params) { { status: 'kittens' } }
|
||||
let(:params) { { project: project, status: 'kittens' } }
|
||||
|
||||
it 'raises ArgumentError' do
|
||||
expect { subject }.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when filtering by finished time' do
|
||||
let!(:deployment_1) { create(:deployment, :success, project: project, finished_at: 2.days.ago) }
|
||||
let!(:deployment_2) { create(:deployment, :success, project: project, finished_at: 4.days.ago) }
|
||||
let!(:deployment_3) { create(:deployment, :success, project: project, finished_at: 5.hours.ago) }
|
||||
|
||||
context 'when filtering by finished_after and finished_before' do
|
||||
let(:params) { { project: project, finished_after: 3.days.ago, finished_before: 1.day.ago } }
|
||||
|
||||
it { is_expected.to match_array([deployment_1]) }
|
||||
end
|
||||
|
||||
context 'when the finished_before parameter is missing' do
|
||||
let(:params) { { project: project, finished_after: 3.days.ago } }
|
||||
|
||||
it { is_expected.to match_array([deployment_1, deployment_3]) }
|
||||
end
|
||||
|
||||
context 'when finished_after is missing' do
|
||||
let(:params) { { project: project, finished_before: 1.day.ago } }
|
||||
|
||||
it 'does not apply any filters on finished time' do
|
||||
is_expected.to match_array([deployment_1, deployment_2, deployment_3])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'ordering' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
let(:params) { { order_by: order_by, sort: sort } }
|
||||
let(:params) { { project: project, order_by: order_by, sort: sort } }
|
||||
|
||||
let!(:deployment_1) { create(:deployment, :success, project: project, iid: 11, ref: 'master', created_at: 2.days.ago, updated_at: Time.now) }
|
||||
let!(:deployment_2) { create(:deployment, :success, project: project, iid: 12, ref: 'feature', created_at: 1.day.ago, updated_at: 2.hours.ago) }
|
||||
let!(:deployment_3) { create(:deployment, :success, project: project, iid: 8, ref: 'video', created_at: Time.now, updated_at: 1.hour.ago) }
|
||||
let!(:deployment_1) { create(:deployment, :success, project: project, iid: 11, ref: 'master', created_at: 2.days.ago, updated_at: Time.now, finished_at: 3.hours.ago) }
|
||||
let!(:deployment_2) { create(:deployment, :success, project: project, iid: 12, ref: 'feature', created_at: 1.day.ago, updated_at: 2.hours.ago, finished_at: 1.hour.ago) }
|
||||
let!(:deployment_3) { create(:deployment, :success, project: project, iid: 8, ref: 'video', created_at: Time.now, updated_at: 1.hour.ago, finished_at: 2.hours.ago) }
|
||||
|
||||
where(:order_by, :sort, :ordered_deployments) do
|
||||
'created_at' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
|
||||
'created_at' | 'desc' | [:deployment_3, :deployment_2, :deployment_1]
|
||||
'id' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
|
||||
'id' | 'desc' | [:deployment_3, :deployment_2, :deployment_1]
|
||||
'iid' | 'asc' | [:deployment_3, :deployment_1, :deployment_2]
|
||||
'iid' | 'desc' | [:deployment_2, :deployment_1, :deployment_3]
|
||||
'ref' | 'asc' | [:deployment_2, :deployment_1, :deployment_3]
|
||||
'ref' | 'desc' | [:deployment_3, :deployment_1, :deployment_2]
|
||||
'updated_at' | 'asc' | [:deployment_2, :deployment_3, :deployment_1]
|
||||
'updated_at' | 'desc' | [:deployment_1, :deployment_3, :deployment_2]
|
||||
'invalid' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
|
||||
'iid' | 'err' | [:deployment_3, :deployment_1, :deployment_2]
|
||||
'created_at' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
|
||||
'created_at' | 'desc' | [:deployment_3, :deployment_2, :deployment_1]
|
||||
'id' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
|
||||
'id' | 'desc' | [:deployment_3, :deployment_2, :deployment_1]
|
||||
'iid' | 'asc' | [:deployment_3, :deployment_1, :deployment_2]
|
||||
'iid' | 'desc' | [:deployment_2, :deployment_1, :deployment_3]
|
||||
'ref' | 'asc' | [:deployment_2, :deployment_1, :deployment_3]
|
||||
'ref' | 'desc' | [:deployment_3, :deployment_1, :deployment_2]
|
||||
'updated_at' | 'asc' | [:deployment_2, :deployment_3, :deployment_1]
|
||||
'updated_at' | 'desc' | [:deployment_1, :deployment_3, :deployment_2]
|
||||
'finished_at' | 'asc' | [:deployment_1, :deployment_3, :deployment_2]
|
||||
'finished_at' | 'desc' | [:deployment_2, :deployment_3, :deployment_1]
|
||||
'invalid' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
|
||||
'iid' | 'err' | [:deployment_3, :deployment_1, :deployment_2]
|
||||
end
|
||||
|
||||
with_them do
|
||||
|
@ -95,7 +131,7 @@ RSpec.describe DeploymentsFinder do
|
|||
end
|
||||
|
||||
describe 'transform `created_at` sorting to `id` sorting' do
|
||||
let(:params) { { order_by: 'created_at', sort: 'asc' } }
|
||||
let(:params) { { project: project, order_by: 'created_at', sort: 'asc' } }
|
||||
|
||||
it 'sorts by only one column' do
|
||||
expect(subject.order_values.size).to eq(1)
|
||||
|
@ -107,7 +143,7 @@ RSpec.describe DeploymentsFinder do
|
|||
end
|
||||
|
||||
describe 'tie-breaker for `updated_at` sorting' do
|
||||
let(:params) { { order_by: 'updated_at', sort: 'asc' } }
|
||||
let(:params) { { project: project, order_by: 'updated_at', sort: 'asc' } }
|
||||
|
||||
it 'sorts by two columns' do
|
||||
expect(subject.order_values.size).to eq(2)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"web_url",
|
||||
"artifacts",
|
||||
"artifacts_expire_at",
|
||||
"tag_list",
|
||||
"runner"
|
||||
],
|
||||
"properties": {
|
||||
|
@ -53,6 +54,9 @@
|
|||
]
|
||||
},
|
||||
"artifacts_expire_at": { "type": ["null", "string"] },
|
||||
"tag_list": {
|
||||
"type": "array"
|
||||
},
|
||||
"runner": {
|
||||
"oneOf": [
|
||||
{ "type": "null" },
|
||||
|
|
|
@ -93,6 +93,7 @@ describe('packages_list_app', () => {
|
|||
|
||||
it('call requestPackagesList on page:changed', () => {
|
||||
mountComponent();
|
||||
store.dispatch.mockClear();
|
||||
|
||||
const list = findListComponent();
|
||||
list.vm.$emit('page:changed', 1);
|
||||
|
@ -107,14 +108,6 @@ describe('packages_list_app', () => {
|
|||
expect(store.dispatch).toHaveBeenCalledWith('requestDeletePackage', 'foo');
|
||||
});
|
||||
|
||||
it('calls requestPackagesList on sort:changed', () => {
|
||||
mountComponent();
|
||||
|
||||
const list = findListComponent();
|
||||
list.vm.$emit('sort:changed');
|
||||
expect(store.dispatch).toHaveBeenCalledWith('requestPackagesList');
|
||||
});
|
||||
|
||||
it('does not call requestPackagesList two times on render', () => {
|
||||
mountComponent();
|
||||
|
||||
|
@ -142,10 +135,11 @@ describe('packages_list_app', () => {
|
|||
expect(findPackageSearch().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it.each(['sort:changed', 'filter:changed'])('on %p fetches data from the store', (event) => {
|
||||
it('on update fetches data from the store', () => {
|
||||
mountComponent();
|
||||
store.dispatch.mockClear();
|
||||
|
||||
findPackageSearch().vm.$emit(event);
|
||||
findPackageSearch().vm.$emit('update');
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith('requestPackagesList');
|
||||
});
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import Vuex from 'vuex';
|
||||
import { GlSorting, GlSortingItem, GlFilteredSearch } from '@gitlab/ui';
|
||||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import component from '~/packages/list/components/package_search.vue';
|
||||
import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
|
||||
import PackageTypeToken from '~/packages/list/components/tokens/package_type_token.vue';
|
||||
import getTableHeaders from '~/packages/list/utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
|
@ -10,12 +11,8 @@ localVue.use(Vuex);
|
|||
describe('Package Search', () => {
|
||||
let wrapper;
|
||||
let store;
|
||||
let sorting;
|
||||
let sortingItems;
|
||||
|
||||
const findPackageListSorting = () => wrapper.find(GlSorting);
|
||||
const findSortingItems = () => wrapper.findAll(GlSortingItem);
|
||||
const findFilteredSearch = () => wrapper.find(GlFilteredSearch);
|
||||
const findRegistrySearch = () => wrapper.find(RegistrySearch);
|
||||
|
||||
const createStore = (isGroupPage) => {
|
||||
const state = {
|
||||
|
@ -40,9 +37,6 @@ describe('Package Search', () => {
|
|||
wrapper = shallowMount(component, {
|
||||
localVue,
|
||||
store,
|
||||
stubs: {
|
||||
GlSortingItem,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -51,95 +45,63 @@ describe('Package Search', () => {
|
|||
wrapper = null;
|
||||
});
|
||||
|
||||
describe('searching', () => {
|
||||
it('has a filtered-search component', () => {
|
||||
mountComponent();
|
||||
it('has a registry search component', () => {
|
||||
mountComponent();
|
||||
|
||||
expect(findFilteredSearch().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('binds the correct props to filtered-search', () => {
|
||||
mountComponent();
|
||||
|
||||
expect(findFilteredSearch().props()).toMatchObject({
|
||||
value: [],
|
||||
placeholder: 'Filter results',
|
||||
availableTokens: wrapper.vm.tokens,
|
||||
});
|
||||
});
|
||||
|
||||
it('updates vuex when value changes', () => {
|
||||
mountComponent();
|
||||
|
||||
findFilteredSearch().vm.$emit('input', ['foo']);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith('setFilter', ['foo']);
|
||||
});
|
||||
|
||||
it('emits filter:changed on submit event', () => {
|
||||
mountComponent();
|
||||
|
||||
findFilteredSearch().vm.$emit('submit');
|
||||
expect(wrapper.emitted('filter:changed')).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('emits filter:changed on clear event and reset vuex', () => {
|
||||
mountComponent();
|
||||
|
||||
findFilteredSearch().vm.$emit('clear');
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith('setFilter', []);
|
||||
expect(wrapper.emitted('filter:changed')).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('has a PackageTypeToken token', () => {
|
||||
mountComponent();
|
||||
|
||||
expect(findFilteredSearch().props('availableTokens')).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
|
||||
]),
|
||||
);
|
||||
expect(findRegistrySearch().exists()).toBe(true);
|
||||
expect(findRegistrySearch().props()).toMatchObject({
|
||||
filter: store.state.filter,
|
||||
sorting: store.state.sorting,
|
||||
tokens: expect.arrayContaining([
|
||||
expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
|
||||
]),
|
||||
sortableFields: getTableHeaders(),
|
||||
});
|
||||
});
|
||||
|
||||
describe('sorting', () => {
|
||||
describe('when is in projects', () => {
|
||||
beforeEach(() => {
|
||||
mountComponent();
|
||||
sorting = findPackageListSorting();
|
||||
sortingItems = findSortingItems();
|
||||
});
|
||||
it.each`
|
||||
isGroupPage | page
|
||||
${false} | ${'project'}
|
||||
${true} | ${'group'}
|
||||
`('in a $page page binds the right props', ({ isGroupPage }) => {
|
||||
mountComponent(isGroupPage);
|
||||
|
||||
it('has all the sortable items', () => {
|
||||
expect(sortingItems).toHaveLength(wrapper.vm.sortableFields.length);
|
||||
});
|
||||
|
||||
it('on sort change set sorting in vuex and emit event', () => {
|
||||
sorting.vm.$emit('sortDirectionChange');
|
||||
expect(store.dispatch).toHaveBeenCalledWith('setSorting', { sort: 'asc' });
|
||||
expect(wrapper.emitted('sort:changed')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('on sort item click set sorting and emit event', () => {
|
||||
const item = sortingItems.at(0);
|
||||
const { orderBy } = wrapper.vm.sortableFields[0];
|
||||
item.vm.$emit('click');
|
||||
expect(store.dispatch).toHaveBeenCalledWith('setSorting', { orderBy });
|
||||
expect(wrapper.emitted('sort:changed')).toBeTruthy();
|
||||
});
|
||||
expect(findRegistrySearch().props()).toMatchObject({
|
||||
filter: store.state.filter,
|
||||
sorting: store.state.sorting,
|
||||
tokens: expect.arrayContaining([
|
||||
expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
|
||||
]),
|
||||
sortableFields: getTableHeaders(isGroupPage),
|
||||
});
|
||||
});
|
||||
|
||||
describe('when is in group', () => {
|
||||
beforeEach(() => {
|
||||
mountComponent(true);
|
||||
sorting = findPackageListSorting();
|
||||
sortingItems = findSortingItems();
|
||||
});
|
||||
it('on sorting:changed emits update event and calls vuex setSorting', () => {
|
||||
const payload = { sort: 'foo' };
|
||||
|
||||
it('has all the sortable items', () => {
|
||||
expect(sortingItems).toHaveLength(wrapper.vm.sortableFields.length);
|
||||
});
|
||||
});
|
||||
mountComponent();
|
||||
|
||||
findRegistrySearch().vm.$emit('sorting:changed', payload);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith('setSorting', payload);
|
||||
expect(wrapper.emitted('update')).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('on filter:changed calls vuex setFilter', () => {
|
||||
const payload = ['foo'];
|
||||
|
||||
mountComponent();
|
||||
|
||||
findRegistrySearch().vm.$emit('filter:changed', payload);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith('setFilter', payload);
|
||||
});
|
||||
|
||||
it('on filter:submit emits update event', () => {
|
||||
mountComponent();
|
||||
|
||||
findRegistrySearch().vm.$emit('filter:submit');
|
||||
|
||||
expect(wrapper.emitted('update')).toEqual([[]]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
import { GlSorting, GlSortingItem, GlFilteredSearch } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import component from '~/vue_shared/components/registry/registry_search.vue';
|
||||
|
||||
describe('Registry Search', () => {
|
||||
let wrapper;
|
||||
|
||||
const findPackageListSorting = () => wrapper.find(GlSorting);
|
||||
const findSortingItems = () => wrapper.findAll(GlSortingItem);
|
||||
const findFilteredSearch = () => wrapper.find(GlFilteredSearch);
|
||||
|
||||
const defaultProps = {
|
||||
filter: [],
|
||||
sorting: { sort: 'asc', orderBy: 'name' },
|
||||
tokens: ['foo'],
|
||||
sortableFields: [{ label: 'name', orderBy: 'name' }, { label: 'baz' }],
|
||||
};
|
||||
|
||||
const mountComponent = (propsData = defaultProps) => {
|
||||
wrapper = shallowMount(component, {
|
||||
propsData,
|
||||
stubs: {
|
||||
GlSortingItem,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
wrapper = null;
|
||||
});
|
||||
|
||||
describe('searching', () => {
|
||||
it('has a filtered-search component', () => {
|
||||
mountComponent();
|
||||
|
||||
expect(findFilteredSearch().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('binds the correct props to filtered-search', () => {
|
||||
mountComponent();
|
||||
|
||||
expect(findFilteredSearch().props()).toMatchObject({
|
||||
value: [],
|
||||
placeholder: 'Filter results',
|
||||
availableTokens: wrapper.vm.tokens,
|
||||
});
|
||||
});
|
||||
|
||||
it('emits filter:changed when value changes', () => {
|
||||
mountComponent();
|
||||
|
||||
findFilteredSearch().vm.$emit('input', 'foo');
|
||||
|
||||
expect(wrapper.emitted('filter:changed')).toEqual([['foo']]);
|
||||
});
|
||||
|
||||
it('emits filter:submit on submit event', () => {
|
||||
mountComponent();
|
||||
|
||||
findFilteredSearch().vm.$emit('submit');
|
||||
expect(wrapper.emitted('filter:submit')).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('emits filter:changed and filter:submit on clear event', () => {
|
||||
mountComponent();
|
||||
|
||||
findFilteredSearch().vm.$emit('clear');
|
||||
|
||||
expect(wrapper.emitted('filter:changed')).toEqual([[[]]]);
|
||||
expect(wrapper.emitted('filter:submit')).toEqual([[]]);
|
||||
});
|
||||
|
||||
it('binds tokens prop', () => {
|
||||
mountComponent();
|
||||
|
||||
expect(findFilteredSearch().props('availableTokens')).toEqual(defaultProps.tokens);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sorting', () => {
|
||||
it('has all the sortable items', () => {
|
||||
mountComponent();
|
||||
|
||||
expect(findSortingItems()).toHaveLength(defaultProps.sortableFields.length);
|
||||
});
|
||||
|
||||
it('on sort change emits sorting:changed event', () => {
|
||||
mountComponent();
|
||||
|
||||
findPackageListSorting().vm.$emit('sortDirectionChange');
|
||||
expect(wrapper.emitted('sorting:changed')).toEqual([[{ sort: 'desc' }]]);
|
||||
});
|
||||
|
||||
it('on sort item click emits sorting:changed event ', () => {
|
||||
mountComponent();
|
||||
|
||||
findSortingItems().at(0).vm.$emit('click');
|
||||
|
||||
expect(wrapper.emitted('sorting:changed')).toEqual([
|
||||
[{ orderBy: defaultProps.sortableFields[0].orderBy }],
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -218,7 +218,7 @@ RSpec.describe Gitlab::CycleAnalytics::StageSummary do
|
|||
|
||||
context 'when `to` is given' do
|
||||
before do
|
||||
Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) }
|
||||
Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project, finished_at: Time.zone.now) }
|
||||
end
|
||||
|
||||
it 'finds records created between `from` and `to` range' do
|
||||
|
@ -230,12 +230,34 @@ RSpec.describe Gitlab::CycleAnalytics::StageSummary do
|
|||
end
|
||||
|
||||
context 'when `from` and `to` are within a day' do
|
||||
it 'returns the number of deployments made on that day' do
|
||||
freeze_time do
|
||||
create(:deployment, :success, project: project)
|
||||
options[:from] = options[:to] = Time.now
|
||||
context 'when query_deploymenys_via_finished_at_in_vsa feature flag is off' do
|
||||
before do
|
||||
stub_feature_flags(query_deploymenys_via_finished_at_in_vsa: false)
|
||||
end
|
||||
|
||||
expect(subject).to eq('1')
|
||||
it 'returns the number of deployments made on that day' do
|
||||
freeze_time do
|
||||
create(:deployment, :success, project: project)
|
||||
options[:from] = options[:to] = Time.zone.now
|
||||
|
||||
expect(subject).to eq('1')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when query_deploymenys_via_finished_at_in_vsa feature flag is off' do
|
||||
before do
|
||||
stub_feature_flags(query_deploymenys_via_finished_at_in_vsa: true)
|
||||
end
|
||||
|
||||
it 'returns the number of deployments made on that day' do
|
||||
freeze_time do
|
||||
create(:deployment, :success, project: project, finished_at: Time.zone.now)
|
||||
options[:from] = Time.zone.now.at_beginning_of_day
|
||||
options[:to] = Time.zone.now.at_end_of_day
|
||||
|
||||
expect(subject).to eq('1')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ RSpec.describe API::Jobs do
|
|||
end
|
||||
|
||||
let!(:job) do
|
||||
create(:ci_build, :success, pipeline: pipeline,
|
||||
create(:ci_build, :success, :tags, pipeline: pipeline,
|
||||
artifacts_expire_at: 1.day.since)
|
||||
end
|
||||
|
||||
|
@ -50,6 +50,7 @@ RSpec.describe API::Jobs do
|
|||
expect(json_response).not_to be_empty
|
||||
expect(json_response.first['commit']['id']).to eq project.commit.id
|
||||
expect(Time.parse(json_response.first['artifacts_expire_at'])).to be_like_time(job.artifacts_expire_at)
|
||||
expect(json_response.first['tag_list'].sort).to eq job.tag_list.sort
|
||||
end
|
||||
|
||||
context 'without artifacts and trace' do
|
||||
|
|
|
@ -288,16 +288,6 @@ RSpec.describe Git::WikiPushService, services: true do
|
|||
|
||||
expect { subject }.not_to raise_error
|
||||
end
|
||||
|
||||
context 'when feature flag :wiki_housekeeping is disabled' do
|
||||
it 'does not perform housekeeping' do
|
||||
stub_feature_flags(wiki_housekeeping: false)
|
||||
|
||||
expect(housekeeping).not_to receive(:execute)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'increments the push counter' do
|
||||
|
|
|
@ -3,6 +3,32 @@
|
|||
module CycleAnalyticsHelpers
|
||||
include GitHelpers
|
||||
|
||||
def wait_for_stages_to_load
|
||||
expect(page).to have_selector '.js-stage-table'
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
def select_group(target_group)
|
||||
visit group_analytics_cycle_analytics_path(target_group)
|
||||
|
||||
wait_for_stages_to_load
|
||||
end
|
||||
|
||||
def toggle_dropdown(field)
|
||||
page.within("[data-testid='#{field}']") do
|
||||
find('.dropdown-toggle').click
|
||||
|
||||
wait_for_requests
|
||||
|
||||
expect(find('.dropdown-menu')).to have_selector('.dropdown-item')
|
||||
end
|
||||
end
|
||||
|
||||
def select_dropdown_option_by_value(name, value, elem = '.dropdown-item')
|
||||
toggle_dropdown name
|
||||
page.find("[data-testid='#{name}'] .dropdown-menu").find("#{elem}[value='#{value}']").click
|
||||
end
|
||||
|
||||
def create_commit_referencing_issue(issue, branch_name: generate(:branch))
|
||||
project.repository.add_branch(user, branch_name, 'master')
|
||||
create_commit("Commit for ##{issue.iid}", issue.project, user, branch_name)
|
||||
|
|
|
@ -4604,7 +4604,7 @@ eslint-import-resolver-node@^0.3.4:
|
|||
debug "^2.6.9"
|
||||
resolve "^1.13.1"
|
||||
|
||||
eslint-import-resolver-webpack@^0.12.1:
|
||||
eslint-import-resolver-webpack@0.12.1:
|
||||
version "0.12.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.12.1.tgz#771ae561e887ca4e53ee87605fbb36c5e290b0f5"
|
||||
integrity sha512-O/sUAXk6GWrICiN8JUkkjdt9uZpqZHP+FVnTxtEILL6EZMaPSrnP4lGPSFwcKsv7O211maqq4Nz60+dh236hVg==
|
||||
|
@ -4664,7 +4664,7 @@ eslint-plugin-import@^2.22.1:
|
|||
resolve "^1.17.0"
|
||||
tsconfig-paths "^3.9.0"
|
||||
|
||||
eslint-plugin-jasmine@^4.1.0:
|
||||
eslint-plugin-jasmine@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-4.1.0.tgz#4f6d41b1a8622348c97559cbcd29badffa74dbfa"
|
||||
integrity sha512-Vfuk2Sm1ULR7MqGjVIOOEdQWyoFBfSwvwUeo9MrajVGJB3C24c9Mmj1Cgf8Qwmf3aS2bezPt1sckpKXWpd74Dw==
|
||||
|
@ -4676,7 +4676,7 @@ eslint-plugin-jest@^23.8.2:
|
|||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "^2.5.0"
|
||||
|
||||
eslint-plugin-no-jquery@^2.3.0:
|
||||
eslint-plugin-no-jquery@2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.3.1.tgz#1c364cb863a38cc1570c8020155b6004cca62178"
|
||||
integrity sha512-/fiQUBSOMUETnfBuiK5ewvtRbek1IRTy5ov/6RZ6nlybvZ337vyGaNPWM1KgaIoIeN7dairNrPfq0h7A0tpT3A==
|
||||
|
|
Loading…
Reference in New Issue