Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-02-08 18:09:49 +00:00
parent 3bc30c280c
commit 89b770bb38
128 changed files with 1969 additions and 876 deletions

View File

@ -519,3 +519,5 @@ gem 'webauthn', '~> 2.3'
# IPAddress utilities
gem 'ipaddress', '~> 0.8.3'
gem 'parslet', '~> 1.8'

View File

@ -1464,6 +1464,7 @@ DEPENDENCIES
omniauth_openid_connect (~> 0.3.5)
org-ruby (~> 0.9.12)
parallel (~> 1.19)
parslet (~> 1.8)
peek (~> 1.1)
pg (~> 1.1)
pg_query (~> 1.3.0)

View File

@ -34,12 +34,12 @@ export default {
};
</script>
<template>
<p class="build-detail-row">
<span v-if="hasTitle" class="font-weight-bold">{{ title }}:</span> {{ value }}
<span v-if="hasHelpURL" class="help-button float-right">
<gl-link :href="helpUrl" target="_blank" rel="noopener noreferrer nofollow">
<gl-icon name="question-o" />
</gl-link>
</span>
<p class="gl-display-flex gl-justify-content-space-between gl-mb-2">
<span v-if="hasTitle"
><b>{{ title }}:</b> {{ value }}</span
>
<gl-link v-if="hasHelpURL" :href="helpUrl" target="_blank">
<gl-icon name="question-o" />
</gl-link>
</p>
</template>

View File

@ -20,18 +20,26 @@ export default {
},
},
data() {
const [chart] = getParameterValues('chart') || charts;
const tab = charts.indexOf(chart);
return {
chart,
selectedTab: tab >= 0 ? tab : 0,
selectedTab: 0,
};
},
created() {
this.selectTab();
window.addEventListener('popstate', this.selectTab);
},
methods: {
selectTab() {
const [chart] = getParameterValues('chart') || charts;
const tab = charts.indexOf(chart);
this.selectedTab = tab >= 0 ? tab : 0;
},
onTabChange(index) {
this.selectedTab = index;
const path = mergeUrlParams({ chart: charts[index] }, window.location.pathname);
updateHistory({ url: path });
if (index !== this.selectedTab) {
this.selectedTab = index;
const path = mergeUrlParams({ chart: charts[index] }, window.location.pathname);
updateHistory({ url: path, title: window.title });
}
},
},
};

View File

@ -982,7 +982,14 @@ $mr-widget-min-height: 69px;
}
.mini-pipeline-graph-dropdown-toggle,
.stage-cell .mini-pipeline-graph-dropdown-toggle svg {
.stage-cell .mini-pipeline-graph-dropdown-toggle svg,
// As the `mini-pipeline-item` mixin specificity is lower
// than the toggle of dropdown with 'variant="link"' we add
// classes ".gl-button.btn-link" to make it more specific.
// Once FF ci_mini_pipeline_gl_dropdown is removed, the `mini-pipeline-item`
// itself could increase its specificity to simplify this selector
button.gl-button.btn-link.mini-pipeline-graph-gl-dropdown-toggle,
.stage-cell button.gl-button.btn-link.mini-pipeline-graph-gl-dropdown-toggle svg {
height: $ci-action-icon-size-lg;
width: $ci-action-icon-size-lg;
}

View File

@ -24,10 +24,8 @@ class Projects::TemplatesController < Projects::ApplicationController
end
def names
templates = @template_type.dropdown_names(project)
respond_to do |format|
format.json { render json: templates }
format.json { render json: TemplateFinder.all_template_names_array(project, params[:template_type].to_s.pluralize) }
end
end

View File

@ -28,6 +28,10 @@ class LicenseTemplateFinder
end
end
def template_names
::Gitlab::Template::BaseTemplate.template_names_by_category(vendored_licenses)
end
private
def vendored_licenses

View File

@ -21,6 +21,18 @@ class TemplateFinder
new(type, project, params)
end
end
def all_template_names(project, type)
return {} if !VENDORED_TEMPLATES.key?(type.to_s) && type.to_s != 'licenses'
build(type, project).template_names
end
# This is issues and merge requests description templates only.
# This will be removed once we introduce group level inherited templates
def all_template_names_array(project, type)
all_template_names(project, type).values.flatten.uniq
end
end
attr_reader :type, :project, :params
@ -43,6 +55,10 @@ class TemplateFinder
vendored_templates.all(project)
end
end
def template_names
vendored_templates.template_names(project)
end
end
TemplateFinder.prepend_if_ee('::EE::TemplateFinder')

View File

@ -29,6 +29,12 @@ module Resolvers
.new(project: project, current_user: context[:current_user])
.validate(content, dry_run: dry_run)
response(result).merge(merged_yaml: result.merged_yaml)
end
private
def response(result)
if result.errors.empty?
{
status: :valid,
@ -43,8 +49,6 @@ module Resolvers
end
end
private
def make_jobs(config_jobs)
config_jobs.map do |job|
{

View File

@ -194,40 +194,28 @@ module BlobHelper
@ref_project ||= @target_project || @project
end
def template_dropdown_names(items)
grouped = items.group_by(&:category)
categories = grouped.keys
categories.each_with_object({}) do |category, hash|
hash[category] = grouped[category].map do |item|
{ name: item.name, id: item.key }
end
end
end
private :template_dropdown_names
def licenses_for_select(project)
@licenses_for_select ||= template_dropdown_names(TemplateFinder.build(:licenses, project).execute)
@licenses_for_select ||= TemplateFinder.all_template_names(project, :licenses)
end
def gitignore_names(project)
@gitignore_names ||= template_dropdown_names(TemplateFinder.build(:gitignores, project).execute)
@gitignore_names ||= TemplateFinder.all_template_names(project, :gitignores)
end
def gitlab_ci_ymls(project)
@gitlab_ci_ymls ||= template_dropdown_names(TemplateFinder.build(:gitlab_ci_ymls, project).execute)
@gitlab_ci_ymls ||= TemplateFinder.all_template_names(project, :gitlab_ci_ymls)
end
def gitlab_ci_syntax_ymls(project)
@gitlab_ci_syntax_ymls ||= template_dropdown_names(TemplateFinder.build(:gitlab_ci_syntax_ymls, project).execute)
@gitlab_ci_syntax_ymls ||= TemplateFinder.all_template_names(project, :gitlab_ci_syntax_ymls)
end
def metrics_dashboard_ymls(project)
@metrics_dashboard_ymls ||= template_dropdown_names(TemplateFinder.build(:metrics_dashboard_ymls, project).execute)
@metrics_dashboard_ymls ||= TemplateFinder.all_template_names(project, :metrics_dashboard_ymls)
end
def dockerfile_names(project)
@dockerfile_names ||= template_dropdown_names(TemplateFinder.build(:dockerfiles, project).execute)
@dockerfile_names ||= TemplateFinder.all_template_names(project, :dockerfiles)
end
def blob_editor_paths(project)

View File

@ -0,0 +1,49 @@
# frozen_string_literal: true
module IssuablesDescriptionTemplatesHelper
include Gitlab::Utils::StrongMemoize
include GitlabRoutingHelper
def template_dropdown_tag(issuable, &block)
title = selected_template(issuable) || "Choose a template"
options = {
toggle_class: 'js-issuable-selector',
title: title,
filter: true,
placeholder: 'Filter',
footer_content: true,
data: {
data: issuable_templates(ref_project, issuable.to_ability_name),
field_name: 'issuable_template',
selected: selected_template(issuable),
project_id: ref_project.id,
project_path: ref_project.path,
namespace_path: ref_project.namespace.full_path
}
}
dropdown_tag(title, options: options) do
capture(&block)
end
end
def issuable_templates(project, issuable_type)
@template_types ||= {}
@template_types[project.id] ||= {}
@template_types[project.id][issuable_type] ||= TemplateFinder.all_template_names_array(project, issuable_type.pluralize)
end
def issuable_templates_names(issuable)
issuable_templates(ref_project, issuable.to_ability_name).map { |template| template[:name] }
end
def selected_template(issuable)
params[:issuable_template] if issuable_templates(ref_project, issuable.to_ability_name).any? { |template| template[:name] == params[:issuable_template] }
end
def template_names_path(parent, issuable)
return '' unless parent.is_a?(Project)
project_template_names_path(parent, template_type: issuable.to_ability_name)
end
end

View File

@ -2,6 +2,7 @@
module IssuablesHelper
include GitlabRoutingHelper
include IssuablesDescriptionTemplatesHelper
def sidebar_gutter_toggle_icon
content_tag(:span, class: 'js-sidebar-toggle-container', data: { is_expanded: !sidebar_gutter_collapsed? }) do
@ -75,28 +76,6 @@ module IssuablesHelper
.to_json
end
def template_dropdown_tag(issuable, &block)
title = selected_template(issuable) || "Choose a template"
options = {
toggle_class: 'js-issuable-selector',
title: title,
filter: true,
placeholder: 'Filter',
footer_content: true,
data: {
data: issuable_templates(issuable),
field_name: 'issuable_template',
selected: selected_template(issuable),
project_path: ref_project.path,
namespace_path: ref_project.namespace.full_path
}
}
dropdown_tag(title, options: options) do
capture(&block)
end
end
def users_dropdown_label(selected_users)
case selected_users.length
when 0
@ -282,6 +261,7 @@ module IssuablesHelper
{
projectPath: ref_project.path,
projectId: ref_project.id,
projectNamespace: ref_project.namespace.full_path
}
end
@ -358,24 +338,6 @@ module IssuablesHelper
cookies[:collapsed_gutter] == 'true'
end
def issuable_templates(issuable)
@issuable_templates ||=
case issuable
when Issue
ref_project.repository.issue_template_names
when MergeRequest
ref_project.repository.merge_request_template_names
end
end
def issuable_templates_names(issuable)
issuable_templates(issuable).map { |template| template[:name] }
end
def selected_template(issuable)
params[:issuable_template] if issuable_templates(issuable).any? { |template| template[:name] == params[:issuable_template] }
end
def issuable_todo_button_data(issuable, is_collapsed)
{
todo_text: _('Add a to do'),
@ -413,12 +375,6 @@ module IssuablesHelper
end
end
def template_names_path(parent, issuable)
return '' unless parent.is_a?(Project)
project_template_names_path(parent, template_type: issuable.class.name.underscore)
end
def issuable_sidebar_options(issuable)
{
endpoint: "#{issuable[:issuable_json_path]}?serializer=sidebar_extras",

View File

@ -117,7 +117,7 @@ class Project < ApplicationRecord
use_fast_destroy :build_trace_chunks
after_destroy -> { run_after_commit { remove_pages } }
after_destroy -> { run_after_commit { legacy_remove_pages } }
after_destroy :remove_exports
after_validation :check_pending_delete
@ -1788,16 +1788,16 @@ class Project < ApplicationRecord
.delete_all
end
# TODO: what to do here when not using Legacy Storage? Do we still need to rename and delay removal?
# TODO: remove this method https://gitlab.com/gitlab-org/gitlab/-/issues/320775
# rubocop: disable CodeReuse/ServiceClass
def remove_pages
def legacy_remove_pages
return unless Feature.enabled?(:pages_update_legacy_storage, default_enabled: true)
# Projects with a missing namespace cannot have their pages removed
return unless namespace
mark_pages_as_not_deployed unless destroyed?
DestroyPagesDeploymentsWorker.perform_async(id)
# 1. We rename pages to temporary directory
# 2. We wait 5 minutes, due to NFS caching
# 3. We asynchronously remove pages with force

View File

@ -1,5 +1,6 @@
# frozen_string_literal: true
# Accessible as Project#external_issue_tracker
class JiraService < IssueTrackerService
extend ::Gitlab::Utils::Override
include Gitlab::Routing
@ -162,7 +163,7 @@ class JiraService < IssueTrackerService
jira_request { client.Issue.find(issue_key) }
end
def close_issue(entity, external_issue)
def close_issue(entity, external_issue, current_user)
issue = find_issue(external_issue.iid)
return if issue.nil? || has_resolution?(issue) || !jira_issue_transition_id.present?
@ -179,6 +180,7 @@ class JiraService < IssueTrackerService
# if it is closed, so we don't have one comment for every commit.
issue = find_issue(issue.key) if transition_issue(issue)
add_issue_solved_comment(issue, commit_id, commit_url) if has_resolution?(issue)
log_usage(:close_issue, current_user)
end
def create_cross_reference_note(mentioned, noteable, author)
@ -214,7 +216,7 @@ class JiraService < IssueTrackerService
}
}
add_comment(data, jira_issue)
add_comment(data, jira_issue).tap { log_usage(:cross_reference, author) }
end
def valid_connection?
@ -275,6 +277,12 @@ class JiraService < IssueTrackerService
end
end
def log_usage(action, user)
key = "i_ecosystem_jira_service_#{action}"
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(key, values: user.id)
end
def add_issue_solved_comment(issue, commit_id, commit_url)
link_title = "Solved by commit #{commit_id}."
comment = "Issue solved with [#{commit_id}|#{commit_url}]."

View File

@ -43,7 +43,7 @@ class Repository
changelog license_blob license_key gitignore
gitlab_ci_yml branch_names tag_names branch_count
tag_count avatar exists? root_ref merged_branch_names
has_visible_content? issue_template_names merge_request_template_names
has_visible_content? issue_template_names_by_category merge_request_template_names_by_category
user_defined_metrics_dashboard_paths xcode_project? has_ambiguous_refs?).freeze
# Methods that use cache_method but only memoize the value
@ -60,8 +60,8 @@ class Repository
gitignore: :gitignore,
gitlab_ci: :gitlab_ci_yml,
avatar: :avatar,
issue_template: :issue_template_names,
merge_request_template: :merge_request_template_names,
issue_template: :issue_template_names_by_category,
merge_request_template: :merge_request_template_names_by_category,
metrics_dashboard: :user_defined_metrics_dashboard_paths,
xcode_config: :xcode_project?
}.freeze
@ -572,15 +572,16 @@ class Repository
end
cache_method :avatar
def issue_template_names
Gitlab::Template::IssueTemplate.dropdown_names(project)
# store issue_template_names as hash
def issue_template_names_by_category
Gitlab::Template::IssueTemplate.repository_template_names(project)
end
cache_method :issue_template_names, fallback: []
cache_method :issue_template_names_by_category, fallback: {}
def merge_request_template_names
Gitlab::Template::MergeRequestTemplate.dropdown_names(project)
def merge_request_template_names_by_category
Gitlab::Template::MergeRequestTemplate.repository_template_names(project)
end
cache_method :merge_request_template_names, fallback: []
cache_method :merge_request_template_names_by_category, fallback: {}
def user_defined_metrics_dashboard_paths
Gitlab::Metrics::Dashboard::RepoDashboardFinder.list_dashboards(project)

View File

@ -55,7 +55,7 @@ module Issues
def close_external_issue(issue, closed_via)
return unless project.external_issue_tracker&.support_close_issue?
project.external_issue_tracker.close_issue(closed_via, issue)
project.external_issue_tracker.close_issue(closed_via, issue, current_user)
todo_service.close_issue(issue, current_user)
end

View File

@ -27,7 +27,11 @@ module Notes
end
note_saved = note.with_transaction_returning_status do
!only_commands && note.save
break false if only_commands
note.save.tap do
update_discussions(note)
end
end
when_saved(note) if note_saved
@ -54,12 +58,17 @@ module Notes
@quick_actions_service ||= QuickActionsService.new(project, current_user)
end
def when_saved(note)
def update_discussions(note)
# Ensure that individual notes that are promoted into discussions are
# updated in a transaction with the note creation to avoid inconsistencies:
# https://gitlab.com/gitlab-org/gitlab/-/issues/301237
if note.part_of_discussion? && note.discussion.can_convert_to_discussion?
note.discussion.convert_to_discussion!.save
note.clear_memoization(:discussion)
end
end
def when_saved(note)
todo_service.new_note(note, current_user)
clear_noteable_diffs_cache(note)
Suggestions::CreateService.new(note).execute

View File

@ -3,7 +3,13 @@
module Pages
class DeleteService < BaseService
def execute
PagesRemoveWorker.perform_async(project.id)
project.mark_pages_as_not_deployed # prevents domain from updating config when deleted
project.pages_domains.delete_all
DestroyPagesDeploymentsWorker.perform_async(project.id)
# TODO: remove this call https://gitlab.com/gitlab-org/gitlab/-/issues/320775
PagesRemoveWorker.perform_async(project.id) if Feature.enabled?(:pages_update_legacy_storage, default_enabled: true)
end
end
end

View File

@ -1,28 +1,35 @@
- page_title _("Applications")
%h3.page-title
System OAuth applications
= _('System OAuth applications')
%p.light
System OAuth applications don't belong to any user and can only be managed by admins
= _('System OAuth applications don\'t belong to any user and can only be managed by admins')
%hr
%p= link_to 'New application', new_admin_application_path, class: 'gl-button btn btn-success'
%table.table
%thead
%tr
%th Name
%th Callback URL
%th Clients
%th Trusted
%th Confidential
%th
%th
%tbody.oauth-applications
- @applications.each do |application|
%tr{ :id => "application_#{application.id}" }
%td= link_to application.name, admin_application_path(application)
%td= application.redirect_uri
%td= @application_counts[application.id].to_i
%td= application.trusted? ? 'Y': 'N'
%td= application.confidential? ? 'Y': 'N'
%td= link_to 'Edit', edit_admin_application_path(application), class: 'gl-button btn btn-link'
%td= render 'delete_form', application: application
%p= link_to _('New application'), new_admin_application_path, class: 'gl-button btn btn-success'
.table-responsive
%table.table
%thead
%tr
%th
= _('Name')
%th
= _('Callback URL')
%th
= _('Clients')
%th
= _('Trusted')
%th
= _('Confidential')
%th
%th
%tbody.oauth-applications
- @applications.each do |application|
%tr{ :id => "application_#{application.id}" }
%td= link_to application.name, admin_application_path(application)
%td= application.redirect_uri
%td= @application_counts[application.id].to_i
%td= application.trusted? ? _('Yes'): _('No')
%td= application.confidential? ? _('Yes'): _('No')
%td= link_to 'Edit', edit_admin_application_path(application), class: 'gl-button btn btn-link'
%td= render 'delete_form', application: application
= paginate @applications, theme: 'gitlab'

View File

@ -1,6 +1,6 @@
- issuable = local_assigns.fetch(:issuable, nil)
- return unless issuable && issuable_templates(issuable).any?
- return unless issuable && issuable_templates(ref_project, issuable.to_ability_name).any?
.issuable-form-select-holder.selectbox.form-group
.js-issuable-selector-wrap{ data: { issuable_type: issuable.to_ability_name, qa_selector: 'template_dropdown' } }

View File

@ -1,7 +1,7 @@
- issuable = local_assigns.fetch(:issuable)
- has_wip_commits = local_assigns.fetch(:has_wip_commits)
- form = local_assigns.fetch(:form)
- no_issuable_templates = issuable_templates(issuable).empty?
- no_issuable_templates = issuable_templates(ref_project, issuable.to_ability_name).empty?
- div_class = no_issuable_templates ? 'col-sm-10' : 'col-sm-7 col-lg-8'
- toggle_wip_link_start = '<a href="" class="js-toggle-wip">'
- toggle_wip_link_end = '</a>'

View File

@ -1,5 +1,6 @@
# frozen_string_literal: true
# TODO: remove this worker https://gitlab.com/gitlab-org/gitlab/-/issues/320775
class PagesRemoveWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
@ -11,7 +12,6 @@ class PagesRemoveWorker # rubocop:disable Scalability/IdempotentWorker
project = Project.find_by_id(project_id)
return unless project
project.remove_pages
project.pages_domains.delete_all
project.legacy_remove_pages
end
end

View File

@ -0,0 +1,5 @@
---
title: Back Button now switches to last active analytics tab
merge_request: 53495
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Make System OAuth app index table responsive and externalize text
merge_request: 50979
author: Kev @KevSlashNull
type: fixed

View File

@ -0,0 +1,5 @@
---
title: 'GraphQL: Add mergedYaml to CiConfigResolver response'
merge_request: 53081
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: 'gitaly: Fix access checks with transactions and quarantine environments'
merge_request: 53449
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Ensure note is promoted to discussion within reply create transaction
merge_request: 53542
author:
type: fixed

View File

@ -0,0 +1,8 @@
---
name: usage_data_track_ecosystem_jira_service
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52110
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/300447
milestone: '13.9'
type: development
group: group::ecosystem
default_enabled: false

View File

@ -13,15 +13,15 @@ documentation.
The [security features](../security/README.md) in GitLab may also help you meet
relevant compliance standards.
|Feature |GitLab tier |GitLab.com | Product level |
|Feature |GitLab tier |GitLab SaaS | Product level |
| ---------| :--------: | :-------: | :-----------: |
|**[Restrict SSH Keys](../security/ssh_keys_restrictions.md)**<br>Control the technology and key length of SSH keys used to access GitLab|Free+||Instance|
|**[Granular user roles and flexible permissions](../user/permissions.md)**<br>Manage access and permissions with five different user roles and settings for external users. Set permissions according to people's role, rather than either read or write access to a repository. Don't share the source code with people that only need access to the issue tracker.|Free+|✓|Instance, Group, Project|
|**[Enforce TOS acceptance](../user/admin_area/settings/terms.md)**<br>Enforce your users accepting new terms of service by blocking GitLab traffic.|Free+||Instance|
|**[Email all users of a project, group, or entire server](../tools/email.md)**<br>An admin can email groups of users based on project or group membership, or email everyone using the GitLab instance. This is great for scheduled maintenance or upgrades.|Starter+|||Instance
|**[Omnibus package supports log forwarding](https://docs.gitlab.com/omnibus/settings/logs.html#udp-log-forwarding)**<br>Forward your logs to a central system.|Starter+||Instance|
|**[Lock project membership to group](../user/group/index.md#member-lock)**<br>Group owners can prevent new members from being added to projects within a group.|Starter+|✓|Group|
|**[LDAP group sync](auth/ldap/index.md#group-sync)**<br>GitLab Enterprise Edition gives admins the ability to automatically sync groups and manage SSH keys, permissions, and authentication, so you can focus on building your product, not configuring your tools.|Starter+||Instance|
|**[Email all users of a project, group, or entire server](../tools/email.md)**<br>An admin can email groups of users based on project or group membership, or email everyone using the GitLab instance. This is great for scheduled maintenance or upgrades.|Premium+||Instance|
|**[Omnibus package supports log forwarding](https://docs.gitlab.com/omnibus/settings/logs.html#udp-log-forwarding)**<br>Forward your logs to a central system.|Premium+||Instance|
|**[Lock project membership to group](../user/group/index.md#member-lock)**<br>Group owners can prevent new members from being added to projects within a group.|Premium+|✓|Group|
|**[LDAP group sync](auth/ldap/index.md#group-sync)**<br>GitLab Enterprise Edition gives admins the ability to automatically sync groups and manage SSH keys, permissions, and authentication, so you can focus on building your product, not configuring your tools.|Premium+||Instance|
|**[LDAP group sync filters](auth/ldap/index.md#group-sync)**<br>GitLab Enterprise Edition Premium gives more flexibility to synchronize with LDAP based on filters, meaning you can leverage LDAP attributes to map GitLab permissions.|Premium+||Instance|
|**[Audit events](audit_events.md)**<br>To maintain the integrity of your code, GitLab Enterprise Edition Premium gives admins the ability to view any modifications made within the GitLab server in an advanced audit events system, so you can control, analyze, and track every change.|Premium+|✓|Instance, Group, Project|
|**[Auditor users](auditor_users.md)**<br>Auditor users are users who are given read-only access to all projects, groups, and other resources on the GitLab instance.|Premium+||Instance|

View File

@ -129,6 +129,10 @@ it is recommended that you disable all cron jobs except for those related to Geo
You can monitor queues and disable jobs in **Admin Area > Monitoring > Background Jobs**.
### Incident management
During Maintenance Mode, [Incident management](../../operations/incident_management/index.md) functions will be limited. The creation of [alerts](../../operations/incident_management/alerts.md) and [incidents](../../operations/incident_management/incidents.md#incident-creation) will be paused entirely. Notifications and paging on alerts and incidents will therefore be disabled.
### Geo secondaries
The maintenance mode setting will be propagated to the secondary as they sync up.

View File

@ -4,7 +4,7 @@ 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
---
# Terraform state administration (alpha) **(CORE)**
# Terraform state administration (alpha) **(FREE)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2673) in GitLab 12.10.

View File

@ -4,7 +4,7 @@ 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
---
# Group clusters API **(CORE)**
# Group clusters API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30213) in GitLab 12.1.

View File

@ -4,9 +4,10 @@ group: Project Management
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
---
# Group iterations API **(STARTER)**
# Group iterations API **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.5.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.5.
> - Moved to GitLab Premium in 13.9.
This page describes the group iterations API.
There's a separate [project iterations API](iterations.md) page.

View File

@ -159,9 +159,10 @@ Parameters:
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `milestone_id` | integer | yes | The ID of a group milestone |
## Get all burndown chart events for a single milestone **(STARTER)**
## Get all burndown chart events for a single milestone **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4737) in GitLab 12.1
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4737) in GitLab 12.1
> - Moved to GitLab Premium in 13.9.
Get all burndown chart events for a single milestone.

View File

@ -670,7 +670,7 @@ Example response:
}
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `shared_runners_minutes_limit` and `extra_shared_runners_minutes_limit` parameters:
Additional response parameters:
@ -685,7 +685,7 @@ Additional response parameters:
}
```
Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `marked_for_deletion_on` attribute:
```json

View File

@ -4,7 +4,7 @@ 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
---
# Instance clusters API **(CORE)**
# Instance clusters API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36001) in GitLab 13.2.

View File

@ -169,7 +169,7 @@ Example response:
]
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) can also see
the `weight` parameter:
```json
@ -183,7 +183,7 @@ the `weight` parameter:
]
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Ultimate](https://about.gitlab.com/pricing/) can also see
the `health_status` parameter:
```json
@ -347,7 +347,7 @@ Example response:
]
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) can also see
the `weight` parameter:
```json
@ -361,7 +361,7 @@ the `weight` parameter:
]
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Ultimate](https://about.gitlab.com/pricing/) can also see
the `health_status` parameter:
```json
@ -530,7 +530,7 @@ Example response:
]
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) can also see
the `weight` parameter:
```json
@ -544,7 +544,7 @@ the `weight` parameter:
]
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Ultimate](https://about.gitlab.com/pricing/) can also see
the `health_status` parameter:
```json
@ -684,7 +684,7 @@ Example response:
}
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) can also see
the `weight` parameter:
```json
@ -696,7 +696,7 @@ the `weight` parameter:
}
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Ultimate](https://about.gitlab.com/pricing/) can also see
the `epic` property:
```javascript
@ -833,7 +833,7 @@ Example response:
}
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) can also see
the `weight` parameter:
```json
@ -845,7 +845,7 @@ the `weight` parameter:
}
```
Users on GitLab [Premium](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium](https://about.gitlab.com/pricing/) can also see
the `epic` property:
```javascript
@ -864,7 +864,7 @@ the `epic` property:
}
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) can also see the `health_status`
Users of [GitLab Ultimate](https://about.gitlab.com/pricing/) can also see the `health_status`
property:
```json
@ -980,7 +980,7 @@ Example response:
}
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) can also see
the `weight` parameter:
```json
@ -992,7 +992,7 @@ the `weight` parameter:
}
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Ultimate](https://about.gitlab.com/pricing/) can also see
the `health_status` parameter:
```json
@ -1133,7 +1133,7 @@ Example response:
}
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) can also see
the `weight` parameter:
```json
@ -1145,7 +1145,7 @@ the `weight` parameter:
}
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Ultimate](https://about.gitlab.com/pricing/) can also see
the `health_status` parameter:
```json
@ -1298,7 +1298,7 @@ Example response:
}
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) can also see
the `weight` parameter:
```json
@ -1310,7 +1310,7 @@ the `weight` parameter:
}
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Ultimate](https://about.gitlab.com/pricing/) can also see
the `health_status` parameter:
```json
@ -1421,7 +1421,7 @@ Example response:
}
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) can also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) can also see
the `weight` parameter:
```json

View File

@ -4,9 +4,10 @@ group: Project Management
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
---
# Project iterations API **(STARTER)**
# Project iterations API **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.5.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.5.
> - Moved to GitLab Premium in 13.9.
This page describes the project iterations API.
There's a separate [group iterations API](group_iterations.md) page.

View File

@ -1183,7 +1183,7 @@ POST /projects/:id/merge_requests
}
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) also see
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/) also see
the `approvals_before_merge` parameter:
```json

View File

@ -159,9 +159,10 @@ Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `milestone_id` (required) - The ID of a project milestone
## Get all burndown chart events for a single milestone **(STARTER)**
## Get all burndown chart events for a single milestone **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4737) in GitLab 12.1
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4737) in GitLab 12.1
> - Moved to GitLab Premium in 13.9.
Gets all burndown chart events for a single milestone.

View File

@ -4,7 +4,7 @@ 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
---
# Project clusters API **(CORE)**
# Project clusters API **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/23922) in GitLab 11.7.

View File

@ -298,11 +298,11 @@ When the user is authenticated and `simple` is not set this returns something li
```
NOTE:
For users of GitLab [Premium or higher](https://about.gitlab.com/pricing/),
For users of [GitLab Premium or higher](https://about.gitlab.com/pricing/),
the `marked_for_deletion_at` attribute has been deprecated, and is removed
in API v5 in favor of the `marked_for_deletion_on` attribute.
Users of GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/)
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/)
can also see the `approvals_before_merge` parameter:
```json
@ -933,7 +933,7 @@ GET /projects/:id
}
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/)
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/)
can also see the `approvals_before_merge` parameter:
```json
@ -1053,7 +1053,7 @@ POST /projects
|-------------------------------------------------------------|---------|------------------------|-------------|
| `allow_merge_on_skipped_pipeline` | boolean | **{dotted-circle}** No | Set whether or not merge requests can be merged with skipped jobs. |
| `analytics_access_level` | string | no | One of `disabled`, `private` or `enabled` |
| `approvals_before_merge` **(STARTER)** | integer | **{dotted-circle}** No | How many approvers should approve merge requests by default. |
| `approvals_before_merge` **(PREMIUM)** | integer | **{dotted-circle}** No | How many approvers should approve merge requests by default. |
| `auto_cancel_pending_pipelines` | string | **{dotted-circle}** No | Auto-cancel pending pipelines. This isn't a boolean, but enabled/disabled. |
| `auto_devops_deploy_strategy` | string | **{dotted-circle}** No | Auto Deploy strategy (`continuous`, `manual` or `timed_incremental`). |
| `auto_devops_enabled` | boolean | **{dotted-circle}** No | Enable Auto DevOps for this project. |
@ -1081,8 +1081,8 @@ POST /projects
| `merge_method` | string | **{dotted-circle}** No | Set the [merge method](#project-merge-method) used. |
| `merge_requests_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
| `merge_requests_enabled` | boolean | **{dotted-circle}** No | _(Deprecated)_ Enable merge requests for this project. Use `merge_requests_access_level` instead. |
| `mirror_trigger_builds` **(STARTER)** | boolean | **{dotted-circle}** No | Pull mirroring triggers builds. |
| `mirror` **(STARTER)** | boolean | **{dotted-circle}** No | Enables pull mirroring in a project. |
| `mirror_trigger_builds` **(PREMIUM)** | boolean | **{dotted-circle}** No | Pull mirroring triggers builds. |
| `mirror` **(PREMIUM)** | boolean | **{dotted-circle}** No | Enables pull mirroring in a project. |
| `name` | string | **{check-circle}** Yes (if path isn't provided) | The name of the new project. Equals path if not provided. |
| `namespace_id` | integer | **{dotted-circle}** No | Namespace for the new project (defaults to the current user's namespace). |
| `operations_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
@ -1127,7 +1127,7 @@ POST /projects/user/:user_id
|-------------------------------------------------------------|---------|------------------------|-------------|
| `allow_merge_on_skipped_pipeline` | boolean | **{dotted-circle}** No | Set whether or not merge requests can be merged with skipped jobs. |
| `analytics_access_level` | string | no | One of `disabled`, `private` or `enabled` |
| `approvals_before_merge` **(STARTER)** | integer | **{dotted-circle}** No | How many approvers should approve merge requests by default. |
| `approvals_before_merge` **(PREMIUM)** | integer | **{dotted-circle}** No | How many approvers should approve merge requests by default. |
| `auto_cancel_pending_pipelines` | string | **{dotted-circle}** No | Auto-cancel pending pipelines. This isn't a boolean, but enabled/disabled. |
| `auto_devops_deploy_strategy` | string | **{dotted-circle}** No | Auto Deploy strategy (`continuous`, `manual` or `timed_incremental`). |
| `auto_devops_enabled` | boolean | **{dotted-circle}** No | Enable Auto DevOps for this project. |
@ -1153,8 +1153,8 @@ POST /projects/user/:user_id
| `merge_method` | string | **{dotted-circle}** No | Set the [merge method](#project-merge-method) used. |
| `merge_requests_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
| `merge_requests_enabled` | boolean | **{dotted-circle}** No | _(Deprecated)_ Enable merge requests for this project. Use `merge_requests_access_level` instead. |
| `mirror_trigger_builds` **(STARTER)** | boolean | **{dotted-circle}** No | Pull mirroring triggers builds. |
| `mirror` **(STARTER)** | boolean | **{dotted-circle}** No | Enables pull mirroring in a project. |
| `mirror_trigger_builds` **(PREMIUM)** | boolean | **{dotted-circle}** No | Pull mirroring triggers builds. |
| `mirror` **(PREMIUM)** | boolean | **{dotted-circle}** No | Enables pull mirroring in a project. |
| `name` | string | **{check-circle}** Yes | The name of the new project. |
| `namespace_id` | integer | **{dotted-circle}** No | Namespace for the new project (defaults to the current user's namespace). |
| `operations_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
@ -1200,7 +1200,7 @@ PUT /projects/:id
|-------------------------------------------------------------|----------------|------------------------|-------------|
| `allow_merge_on_skipped_pipeline` | boolean | **{dotted-circle}** No | Set whether or not merge requests can be merged with skipped jobs. |
| `analytics_access_level` | string | no | One of `disabled`, `private` or `enabled` |
| `approvals_before_merge` **(STARTER)** | integer | **{dotted-circle}** No | How many approvers should approve merge request by default. |
| `approvals_before_merge` **(PREMIUM)** | integer | **{dotted-circle}** No | How many approvers should approve merge request by default. |
| `auto_cancel_pending_pipelines` | string | **{dotted-circle}** No | Auto-cancel pending pipelines. This isn't a boolean, but enabled/disabled. |
| `auto_devops_deploy_strategy` | string | **{dotted-circle}** No | Auto Deploy strategy (`continuous`, `manual`, or `timed_incremental`). |
| `auto_devops_enabled` | boolean | **{dotted-circle}** No | Enable Auto DevOps for this project. |
@ -1229,15 +1229,15 @@ PUT /projects/:id
| `merge_method` | string | **{dotted-circle}** No | Set the [merge method](#project-merge-method) used. |
| `merge_requests_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
| `merge_requests_enabled` | boolean | **{dotted-circle}** No | _(Deprecated)_ Enable merge requests for this project. Use `merge_requests_access_level` instead. |
| `mirror_overwrites_diverged_branches` **(STARTER)** | boolean | **{dotted-circle}** No | Pull mirror overwrites diverged branches. |
| `mirror_trigger_builds` **(STARTER)** | boolean | **{dotted-circle}** No | Pull mirroring triggers builds. |
| `mirror_user_id` **(STARTER)** | integer | **{dotted-circle}** No | User responsible for all the activity surrounding a pull mirror event. _(admins only)_ |
| `mirror` **(STARTER)** | boolean | **{dotted-circle}** No | Enables pull mirroring in a project. |
| `mirror_overwrites_diverged_branches` **(PREMIUM)** | boolean | **{dotted-circle}** No | Pull mirror overwrites diverged branches. |
| `mirror_trigger_builds` **(PREMIUM)** | boolean | **{dotted-circle}** No | Pull mirroring triggers builds. |
| `mirror_user_id` **(PREMIUM)** | integer | **{dotted-circle}** No | User responsible for all the activity surrounding a pull mirror event. _(admins only)_ |
| `mirror` **(PREMIUM)** | boolean | **{dotted-circle}** No | Enables pull mirroring in a project. |
| `name` | string | **{dotted-circle}** No | The name of the project. |
| `operations_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | **{dotted-circle}** No | Set whether merge requests can only be merged when all the discussions are resolved. |
| `only_allow_merge_if_pipeline_succeeds` | boolean | **{dotted-circle}** No | Set whether merge requests can only be merged with successful jobs. |
| `only_mirror_protected_branches` **(STARTER)** | boolean | **{dotted-circle}** No | Only mirror protected branches. |
| `only_mirror_protected_branches` **(PREMIUM)** | boolean | **{dotted-circle}** No | Only mirror protected branches. |
| `packages_enabled` | boolean | **{dotted-circle}** No | Enable or disable packages repository feature. |
| `pages_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, `enabled`, or `public`. |
| `requirements_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, `enabled` or `public` |
@ -1877,7 +1877,7 @@ This endpoint:
- Deletes a project including all associated resources (including issues and
merge requests).
- From [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/220382) on
[Premium](https://about.gitlab.com/pricing/) or higher tiers, group
[Premium or higher](https://about.gitlab.com/pricing/) tiers, group
admins can [configure](../user/group/index.md#enabling-delayed-project-removal)
projects within a group to be deleted after a delayed period. When enabled,
actual deletion happens after the number of days specified in the
@ -2187,8 +2187,6 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
## Start the Housekeeping task for a project
> Introduced in GitLab 9.0.
```plaintext
POST /projects/:id/housekeeping
```
@ -2197,9 +2195,9 @@ POST /projects/:id/housekeeping
|-----------|----------------|------------------------|-------------|
| `id` | integer/string | **{check-circle}** Yes | The ID of the project or NAMESPACE/PROJECT_NAME. |
## Push Rules **(STARTER)**
## Push Rules **(PREMIUM)**
### Get project push rules **(STARTER)**
### Get project push rules **(PREMIUM)**
Get the [push rules](../push_rules/push_rules.md#enabling-push-rules) of a
project.
@ -2231,7 +2229,7 @@ GET /projects/:id/push_rule
}
```
Users of GitLab [Premium or higher](https://about.gitlab.com/pricing/)
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/)
can also see the `commit_committer_check` and `reject_unsigned_commits`
parameters:
@ -2245,7 +2243,7 @@ parameters:
}
```
### Add project push rule **(STARTER)**
### Add project push rule **(PREMIUM)**
Adds a push rule to a specified project.
@ -2268,7 +2266,7 @@ POST /projects/:id/push_rule
| `prevent_secrets` | boolean | **{dotted-circle}** No | GitLab rejects any files that are likely to contain secrets. |
| `reject_unsigned_commits` **(PREMIUM)** | boolean | **{dotted-circle}** No | Reject commit when it's not signed through GPG. |
### Edit project push rule **(STARTER)**
### Edit project push rule **(PREMIUM)**
Edits a push rule for a specified project.
@ -2293,7 +2291,7 @@ PUT /projects/:id/push_rule
### Delete project push rule
> Introduced in [GitLab Starter](https://about.gitlab.com/pricing/) 9.0.
> - Moved to GitLab Premium in 13.9.
Removes a push rule from a project. This is an idempotent method and can be
called multiple times. Either the push rule is available or not.
@ -2440,9 +2438,10 @@ Read more in the [Project import/export](project_import_export.md) documentation
Read more in the [Project members](members.md) documentation.
## Configure pull mirroring for a project **(STARTER)**
## Configure pull mirroring for a project **(PREMIUM)**
> Introduced in [GitLab Starter](https://about.gitlab.com/pricing/) 11.2.
> - Introduced in GitLab 11.
> - Moved to GitLab Premium in 13.9.
Configure pull mirroring while [creating a new project](#create-project) or [updating an existing project](#edit-project) using the API if the remote repository is publicly accessible or via `username/password` authentication. In case your HTTP repository is not publicly accessible, you can add the authentication information to the URL: `https://username:password@gitlab.company.com/group/project.git`, where password is a [personal access token](../user/profile/personal_access_tokens.md) with the API scope enabled.
@ -2452,9 +2451,9 @@ The relevant API parameters to update are:
- `mirror`: Enables pull mirroring on project when set to `true`.
- `only_mirror_protected_branches`: Set to `true` for protected branches.
## Start the pull mirroring process for a Project **(STARTER)**
## Start the pull mirroring process for a Project **(PREMIUM)**
> Introduced in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
> - Moved to GitLab Premium in 13.9.
```plaintext
POST /projects/:id/mirror/pull

View File

@ -5,7 +5,7 @@ info: "To determine the technical writer assigned to the Stage/Group associated
type: reference, api
---
# Repositories API **(CORE)**
# Repositories API **(FREE)**
## List repository tree
@ -410,6 +410,7 @@ follows:
- [{{ title }}]({{ commit.reference }})\
{% if author.contributor %} by {{ author.reference }}{% end %}\
{% if merge_request %} ([merge request]({{ merge_request.reference }})){% end %}
{% end %}
{% end %}
@ -457,11 +458,40 @@ If a line ends in a backslash, the next newline is ignored. This allows you to
wrap code across multiple lines, without introducing unnecessary newlines in the
Markdown output.
Tags that use `{%` and `%}` (known as expression tags) consume the newline that
directly follows them, if any. This means that this:
```plaintext
---
{% if foo %}
bar
{% end %}
---
```
Compiles into this:
```plaintext
---
bar
---
```
Instead of this:
```plaintext
---
bar
---
```
You can specify a custom template in your configuration like so:
```yaml
---
template: >
template: |
{% if categories %}
{% each categories %}
### {{ title }}
@ -469,6 +499,7 @@ template: >
{% each entries %}
- [{{ title }}]({{ commit.reference }})\
{% if author.contributor %} by {{ author.reference }}{% end %}
{% end %}
{% end %}
@ -477,6 +508,9 @@ template: >
{% end %}
```
Note that when specifying the template you should use `template: |` and not
`template: >`, as the latter doesn't preserve newlines in the template.
### Template data
At the top level, the following variable is available:

View File

@ -4,10 +4,11 @@ group: Project Management
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
---
# Resource iteration events API **(STARTER)**
# Resource iteration events API **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/229463) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.4.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/229463) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.5.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/229463) in GitLab 13.4.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/229463) in GitLab 13.5.
> - Moved to GitLab Premium in 13.9.
Resource iteration events keep track of what happens to GitLab [issues](../user/project/issues/).

View File

@ -1,6 +1,6 @@
---
stage: none
group: unassigned
stage: Manage
group: Access
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
---
@ -171,7 +171,7 @@ GET /users
]
```
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) also see the `shared_runners_minutes_limit`, `extra_shared_runners_minutes_limit`, and `using_license_seat` parameters.
Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) also see the `shared_runners_minutes_limit`, `extra_shared_runners_minutes_limit`, and `using_license_seat` parameters.
```json
[
@ -340,7 +340,7 @@ Example Responses:
NOTE:
The `plan` and `trial` parameters are only available on GitLab Enterprise Edition.
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) also see
Users on GitLab [Premium or higher](https://about.gitlab.com/pricing/) also see
the `shared_runners_minutes_limit`, and `extra_shared_runners_minutes_limit` parameters.
```json

View File

@ -6,7 +6,7 @@ comments: false
description: 'GitLab to Kubernetes communication'
---
# GitLab to Kubernetes communication **(CORE)**
# GitLab to Kubernetes communication **(FREE)**
The goal of this document is to define how GitLab can communicate with Kubernetes
and in-cluster services through the GitLab Kubernetes Agent.

View File

@ -136,10 +136,16 @@ Shared runners are automatically disabled for a project:
To disable shared runners for a group:
1. Go to the group's **Settings > CI/CD** and expand the **Runners** section.
1. In the **Shared runners** area, click **Enable shared runners for this group**.
1. In the **Shared runners** area, turn off the **Enable shared runners for this group** toggle.
1. Optionally, to allow shared runners to be enabled for individual projects or subgroups,
click **Allow projects and subgroups to override the group setting**.
NOTE:
To re-enable the shared runners for a group, turn on the
**Enable shared runners for this group** toggle.
Then, an owner or maintainer must explicitly change this setting
for each project subgroup or project.
### Group runners
Use *Group runners* when you want all projects in a group

View File

@ -67,6 +67,10 @@ Complexity is explained [on our client-facing API page](../api/graphql/index.md#
Fields default to adding `1` to a query's complexity score, but developers can
[specify a custom complexity](#field-complexity) when defining a field.
To estimate the complexity of a query, you can run the
[`gitlab:graphql:analyze`](rake_tasks.md#analyze-graphql-queries)
Rake task.
### Request timeout
Requests time out at 30 seconds.

View File

@ -4,7 +4,7 @@ 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
---
# Auto DevOps development guide **(CORE)**
# Auto DevOps development guide **(FREE)**
This document provides a development guide for contributors to
[Auto DevOps](../topics/autodevops/index.md).

View File

@ -4,7 +4,7 @@ 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
---
# Kubernetes integration - development guidelines **(CORE)**
# Kubernetes integration - development guidelines **(FREE)**
This document provides various guidelines when developing for the GitLab
[Kubernetes integration](../user/project/clusters/index.md).

View File

@ -261,6 +261,48 @@ bundle exec rake db:obsolete_ignored_columns
Feel free to remove their definitions from their `ignored_columns` definitions.
## Validate GraphQL queries
To check the validity of one or more of our front-end GraphQL queries,
run:
```shell
# Validate all queries
bundle exec rake gitlab::graphql:validate
# Validate one query
bundle exec rake gitlab::graphql:validate[path/to/query.graphql]
# Validate a directory
bundle exec rake gitlab::graphql:validate[path/to/queries]
```
This prints out a report with an entry for each query, explaining why
each query is invalid if it fails to pass validation.
We strip out `@client` fields during validation so it is important to mark
client fields with the `@client` directive to avoid false positives.
## Analyze GraphQL queries
Analogous to `ANALYZE` in SQL, we can run `gitlab:graphql:analyze` to
estimate the of the cost of running a query.
Usage:
```shell
# Analyze all queries
bundle exec rake gitlab::graphql:analyze
# Analyze one query
bundle exec rake gitlab::graphql:analyze[path/to/query.graphql]
# Analyze a directory
bundle exec rake gitlab::graphql:analyze[path/to/queries]
```
This prints out a report for each query, including the complexity
of the query if it is valid.
The complexity depends on the arguments in some cases, so the reported
complexity is a best-effort assessment of the upper bound.
## Update GraphQL documentation and schema definitions
To generate GraphQL documentation based on the GitLab schema, run:

View File

@ -185,9 +185,8 @@ The Redis [`PFCOUNT`](https://redis.io/commands/pfcount),
[`PFMERGE`](https://redis.io/commands/pfmergge) commands operate on
HyperLogLogs, a data structure that allows estimating the number of unique
elements with low memory usage. (In addition to the `PFCOUNT` documentation,
Thoughtbot's article on [HyperLogLogs in
Redis](https://thoughtbot.com/blog/hyperloglogs-in-redis) provides a good
background here.)
Thoughtbot's article on [HyperLogLogs in Redis](https://thoughtbot.com/blog/hyperloglogs-in-redis)
provides a good background here.)
[`Gitlab::Redis::HLL`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/redis/hll.rb)
provides a convenient interface for adding and counting values in HyperLogLogs.

View File

@ -4,7 +4,7 @@ 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
---
# Customizing Auto DevOps **(CORE)**
# Customizing Auto DevOps **(FREE)**
While [Auto DevOps](index.md) provides great defaults to get you started, you can customize
almost everything to fit your needs. Auto DevOps offers everything from custom

View File

@ -4,7 +4,7 @@ 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
---
# Auto DevOps **(CORE)**
# Auto DevOps **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/37115) in GitLab 10.0.
> - Generally available on GitLab 11.0.

View File

@ -4,7 +4,7 @@ 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
---
# Getting started with Auto DevOps **(CORE)**
# Getting started with Auto DevOps **(FREE)**
This step-by-step guide helps you use [Auto DevOps](index.md) to
deploy a project hosted on GitLab.com to Google Kubernetes Engine.

View File

@ -4,7 +4,7 @@ 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
---
# Requirements for Auto DevOps **(CORE)**
# Requirements for Auto DevOps **(FREE)**
You can set up Auto DevOps for [Kubernetes](#auto-devops-requirements-for-kubernetes),
[Amazon Elastic Container Service (ECS)](#auto-devops-requirements-for-amazon-ecs),

View File

@ -4,7 +4,7 @@ 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
---
# Stages of Auto DevOps **(CORE)**
# Stages of Auto DevOps **(FREE)**
The following sections describe the stages of [Auto DevOps](index.md).
Read them carefully to understand how each one works.

View File

@ -4,7 +4,7 @@ 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
---
# Upgrading PostgreSQL for Auto DevOps **(CORE)**
# Upgrading PostgreSQL for Auto DevOps **(FREE)**
Auto DevOps provides an [in-cluster PostgreSQL database](customize.md#postgresql-database-support)
for your application.

View File

@ -4,7 +4,7 @@ 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
---
# GitLab Managed Apps **(CORE)**
# GitLab Managed Apps **(FREE)**
GitLab provides **GitLab Managed Apps** for various
applications which can be added directly to your configured cluster. These

View File

@ -4,7 +4,7 @@ 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
---
# Crossplane configuration **(CORE)**
# Crossplane configuration **(FREE)**
After [installing](applications.md#crossplane) Crossplane, you must configure it for use.
The process of configuring Crossplane includes:

View File

@ -4,7 +4,7 @@ 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
---
# Cluster management project **(CORE)**
# Cluster management project **(FREE)**
WARNING:
This is an _alpha_ feature, and it is subject to change at any time without

View File

@ -130,7 +130,7 @@ GitLab.com is fronted by Cloudflare. For incoming connections to GitLab.com you
For outgoing connections from CI/CD runners we are not providing static IP addresses.
All our runners are deployed into Google Cloud Platform (GCP) - any IP based
firewall can be configured by looking up all
[IP address ranges or CIDR blocks for GCP](https://cloud.google.com/compute/docs/faq#where_can_i_find_product_name_short_ip_ranges).
[IP address ranges or CIDR blocks for GCP](https://cloud.google.com/compute/docs/faq#find_ip_range).
## Hostname list

View File

@ -5,15 +5,16 @@ group: Project Management
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
---
# Iterations **(STARTER)**
# Iterations **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214713) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.1.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214713) in GitLab 13.1.
> - It was deployed behind a feature flag, disabled by default.
> - [Became enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/221047) on GitLab 13.2.
> - It's enabled on GitLab.com.
> - It's able to be enabled or disabled per-group.
> - It's recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#disable-iterations). **(STARTER ONLY)**
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#disable-iterations). **(PREMIUM ONLY)**
> - Moved to GitLab Premium in 13.9.
Iterations are a way to track issues over a period of time. This allows teams
to track velocity and volatility metrics. Iterations can be used with [milestones](../../project/milestones/index.md)
@ -50,7 +51,7 @@ To create an iteration:
## Edit an iteration
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218277) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.2.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218277) in GitLab 13.2.
NOTE:
You need Developer [permissions](../../permissions.md) or higher to edit an iteration.
@ -59,14 +60,14 @@ To edit an iteration, click the three-dot menu (**{ellipsis_v}**) > **Edit itera
## Add an issue to an iteration
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216158) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.2.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216158) in GitLab 13.2.
To learn how to add an issue to an iteration, see the steps in
[Managing issues](../../project/issues/managing_issues.md#add-an-issue-to-an-iteration).
## View an iteration report
> Viewing iteration reports in projects [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/222763) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.5.
> Viewing iteration reports in projects [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/222763) in GitLab 13.5.
You can track the progress of an iteration by reviewing iteration reports.
An iteration report displays a list of all the issues assigned to an iteration and their status.
@ -79,8 +80,8 @@ To view an iteration report, go to the iterations list page and click an iterati
### Iteration burndown and burnup charts
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/222750) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.5.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/269972) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.7.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/222750) in GitLab 13.5.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/269972) in GitLab 13.7.
The iteration report includes [burndown and burnup charts](../../project/milestones/burndown_and_burnup_charts.md),
similar to how they appear when viewing a [milestone](../../project/milestones/index.md).
@ -104,7 +105,7 @@ To group issues by label:
You can also search for labels by typing in the search input.
1. Click or tap outside of the label dropdown. The page is now grouped by the selected labels.
## Disable iterations **(STARTER ONLY)**
## Disable iterations **(PREMIUM SELF)**
GitLab Iterations feature is deployed with a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)

View File

@ -4,7 +4,7 @@ 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
---
# Infrastructure as code with Terraform and GitLab **(CORE)**
# Infrastructure as code with Terraform and GitLab **(FREE)**
## Motivation

View File

@ -4,7 +4,7 @@ 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
---
# Terraform integration in Merge Requests **(CORE)**
# Terraform integration in Merge Requests **(FREE)**
Collaborating around Infrastructure as Code (IaC) changes requires both code changes and expected infrastructure changes to be checked and approved. GitLab provides a solution to help collaboration around Terraform code changes and their expected effects using the Merge Request pages. This way users don't have to build custom tools or rely on 3rd party solutions to streamline their IaC workflows.

View File

@ -4,7 +4,7 @@ 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
---
# GitLab managed Terraform State **(CORE)**
# GitLab managed Terraform State **(FREE)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2673) in GitLab 13.0.

View File

@ -4,7 +4,7 @@ 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
---
# Adding EKS clusters **(CORE)**
# Adding EKS clusters **(FREE)**
GitLab supports adding new and existing EKS clusters.

View File

@ -4,7 +4,7 @@ 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
---
# Adding GKE clusters **(CORE)**
# Adding GKE clusters **(FREE)**
GitLab supports adding new and existing GKE clusters.

View File

@ -4,7 +4,7 @@ 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
---
# Adding and removing Kubernetes clusters **(CORE)**
# Adding and removing Kubernetes clusters **(FREE)**
GitLab offers integrated cluster creation for the following Kubernetes providers:

View File

@ -4,7 +4,7 @@ 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
---
# Runbooks **(CORE)**
# Runbooks **(FREE)**
Runbooks are a collection of documented procedures that explain how to
carry out a particular process, be it starting, stopping, debugging,

View File

@ -4,7 +4,7 @@ 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
---
# Deploying AWS Lambda function using GitLab CI/CD **(CORE)**
# Deploying AWS Lambda function using GitLab CI/CD **(FREE)**
GitLab allows users to easily deploy AWS Lambda functions and create rich serverless applications.

View File

@ -4,7 +4,7 @@ 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
---
# Serverless **(CORE)**
# Serverless **(FREE)**
> Introduced in GitLab 11.5.

View File

@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Description templates
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/4981) in GitLab 8.11.
We all know that a properly submitted issue is more likely to be addressed in
a timely manner by the developers of a project.
@ -87,10 +85,9 @@ For example: `https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_templat
![Description templates](img/description_templates.png)
## Setting a default template for merge requests and issues **(STARTER)**
## Setting a default template for merge requests and issues **(PREMIUM)**
> - Templates for merge requests [introduced](https://gitlab.com/gitlab-org/gitlab/commit/7478ece8b48e80782b5465b96c79f85cc91d391b) in GitLab 6.9.
> - Templates for issues [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28) in GitLab 8.1.
> - Moved to GitLab Premium in 13.9.
The visibility of issues or merge requests should be set to either "Everyone
with access" or "Only Project Members" in your project's **Settings / Visibility, project features, permissions** section, otherwise the

View File

@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Issue Boards **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5554) in [GitLab 8.11](https://about.gitlab.com/releases/2016/08/22/gitlab-8-11-released/#issue-board).
The GitLab Issue Board is a software project management tool used to plan,
organize, and visualize a workflow for a feature or product release.
It can be used as a [Kanban](https://en.wikipedia.org/wiki/Kanban_(development)) or a
@ -52,9 +50,8 @@ the Issue Board feature.
## Multiple issue boards
> - [Introduced](https://about.gitlab.com/releases/2016/10/22/gitlab-8-13-released/) in GitLab 8.13.
> - Multiple issue boards per project [moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53811) to [GitLab Free](https://about.gitlab.com/pricing/) in GitLab 12.1.
> - Multiple issue boards per group are available in [GitLab Premium](https://about.gitlab.com/pricing/).
> - Multiple issue boards per project [moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53811) to GitLab Free in 12.1.
> - Multiple issue boards per group are available in GitLab Premium.
Multiple issue boards allow for more than one issue board for a given project **(FREE)** or group **(PREMIUM)**.
This is great for large projects with more than one team or when a repository hosts the code of multiple products.
@ -230,10 +227,10 @@ and vice versa.
GitLab issue boards are available on the GitLab Free tier, but some
advanced functionality is present in [higher tiers only](https://about.gitlab.com/pricing/).
### Configurable issue boards **(STARTER)**
### Configurable issue boards **(PREMIUM)**
> - [Introduced](https://about.gitlab.com/releases/2017/11/22/gitlab-10-2-released/#issue-boards-configuration) in GitLab 10.2.
> - Setting current iteration as scope [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196804) in GitLab 13.8.
> - Moved to GitLab Premium in 13.9.
An issue board can be associated with a [milestone](milestones/index.md#milestones),
[labels](labels.md), assignee, weight, and current [iteration](../group/iterations/index.md),
@ -256,14 +253,15 @@ the Configurable Issue Board feature.
### Focus mode
> - [Introduced]((https://about.gitlab.com/releases/2017/04/22/gitlab-9-1-released/#issue-boards-focus-mode-ees-eep)) in [GitLab Starter](https://about.gitlab.com/pricing/) 9.1.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28597) to the Free tier of GitLab SaaS in 12.10.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28597) to GitLab Free SaaS in 12.10.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212331) to GitLab Free self-managed in 13.0.
To enable or disable focus mode, select the **Toggle focus mode** button (**{maximize}**) at the top
right. In focus mode, the navigation UI is hidden, allowing you to focus on issues in the board.
### Sum of issue weights **(STARTER)**
### Sum of issue weights **(PREMIUM)**
> Moved to GitLab Premium in 13.9.
The top of each list indicates the sum of issue weights for the issues that
belong to that list. This is useful when using boards for capacity allocation,
@ -273,9 +271,6 @@ especially in combination with [assignee lists](#assignee-lists).
### Group issue boards **(PREMIUM)**
> - One group issue board per group introduced in GitLab 10.6.
> - Multiple group issue boards [introduced](https://about.gitlab.com/releases/2017/09/22/gitlab-10-0-released/#group-issue-boards) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.0.
Accessible at the group navigation level, a group issue board offers the same features as a project-level board.
It can display issues from all projects in that
group and its descendant subgroups. Similarly, you can only filter by group labels for these
@ -359,9 +354,10 @@ You can also [drag issues](#drag-issues-between-lists) to change their position
![Drag issues between swimlanes](img/epics_swimlanes_drag_and_drop.png)
## Work In Progress limits **(STARTER)**
## Work In Progress limits **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11403) in GitLab 12.7
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11403) in GitLab 12.7
> - Moved to GitLab Premium in 13.9.
You can set a Work In Progress (WIP) limit for each issue list on an issue board. When a limit is
set, the list's header shows the number of issues in the list and the soft limit of issues.
@ -546,8 +542,8 @@ to another list, the label changes and a system note is recorded.
When dragging issues between lists, different behavior occurs depending on the source list and the target list.
| | To Open | To Closed | To label `B` list | To assignee `Bob` list |
|----------------------------|--------------------|--------------|------------------------------|---------------------------------------|
| | To Open | To Closed | To label `B` list | To assignee `Bob` list |
| ------------------------------ | ------------------ | ------------ | ---------------------------- | ------------------------------------- |
| **From Open** | - | Issue closed | `B` added | `Bob` assigned |
| **From Closed** | Issue reopened | - | Issue reopened<br/>`B` added | Issue reopened<br/>`Bob` assigned |
| **From label `A` list** | `A` removed | Issue closed | `A` removed<br/>`B` added | `Bob` assigned |

View File

@ -23,13 +23,13 @@ The numbers in the image correspond to the following features:
- **1.** [Issue actions](#issue-actions)
- **2.** [To Do](#to-do)
- **3.** [Assignee](#assignee)
- **3.1.** [Multiple Assignees **(STARTER)**](#multiple-assignees)
- **4.** [Epic **(PREMIUM)**](#epic)
- **3.1.** [Multiple Assignees](#multiple-assignees)
- **4.** [Epic](#epic)
- **5.** [Milestone](#milestone)
- **6.** [Time tracking](#time-tracking)
- **7.** [Due date](#due-date)
- **8.** [Labels](#labels)
- **9.** [Weight **(STARTER)**](#weight)
- **9.** [Weight](#weight)
- **10.** [Confidentiality](#confidentiality)
- **11.** [Lock issue](#lock-issue)
- **12.** [Participants](#participants)
@ -86,7 +86,7 @@ An issue can be assigned to:
- Yourself.
- Another person.
- [Many people](#multiple-assignees). **(STARTER)**
- [Many people](#multiple-assignees). **(PREMIUM)**
The assignees can be changed as often as needed. The idea is that the assignees are
responsible for that issue until it's reassigned to someone else to take it from there.
@ -96,7 +96,7 @@ NOTE:
If a user is not member of that project, it can only be
assigned to them if they created the issue themselves.
#### Multiple Assignees **(STARTER)**
#### Multiple Assignees **(PREMIUM)**
Often, multiple people work on the same issue together. This can be difficult
to track in large teams where there is shared ownership of an issue.
@ -138,7 +138,7 @@ available to all projects in the group.
If a label doesn't exist yet, you can create one by clicking **Edit**
followed by **Create new label** in the dropdown menu.
### Weight **(STARTER)**
### Weight **(PREMIUM)**
[Assign a weight](issue_weight.md) to an issue.
Larger values are used to indicate more effort is required to complete the issue. Only
@ -194,7 +194,8 @@ The plain text title and description of the issue fill the top center of the iss
The description fully supports [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown-gfm),
allowing many formatting options.
> [In GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/10103) and later, changes to an issue's description are listed in the [issue history](#issue-history). **(STARTER)**
[In GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/10103) and later, changes to an
issue's description are listed in the [issue history](#issue-history). **(PREMIUM)**
### Mentions

View File

@ -5,15 +5,15 @@ group: Project Management
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
---
# Issue weight **(STARTER)**
# Issue weight **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76) in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3.
> - Moved to GitLab Premium in 13.9.
When you have a lot of issues, it can be hard to get an overview.
By adding a weight to each issue, you can get a better idea of how much time,
value or complexity a given issue has or costs.
You can set the weight of an issue during its creation, by simply changing the
You can set the weight of an issue during its creation, by changing the
value in the dropdown menu. You can set it to a non-negative integer
value from 0, 1, 2, and so on. (The database stores a 4-byte value, so the
upper bound is essentially limitless).

View File

@ -287,9 +287,9 @@ editing it and clicking on the delete button.
## Promote an issue to an epic **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3777) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.6.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/37081) to [GitLab Premium](https://about.gitlab.com/pricing/) in 12.8.
> - Promoting issues to epics via the UI [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233974) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.6.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3777) in GitLab Ultimate 11.6.
> - Moved to GitLab Premium in 12.8.
> - Promoting issues to epics via the UI [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233974) in GitLab Premium 13.6.
You can promote an issue to an epic in the immediate parent group.
@ -302,9 +302,10 @@ Alternatively, you can use the `/promote` [quick action](../quick_actions.md#qui
Read more about promoting an issue to an epic on the [Manage epics page](../../group/epics/manage_epics.md#promote-an-issue-to-an-epic).
## Add an issue to an iteration **(STARTER)**
## Add an issue to an iteration **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216158) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.2.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216158) in GitLab 13.2.
> - Moved to GitLab Premium in 13.9.
To add an issue to an [iteration](../../group/iterations/index.md):

View File

@ -4,9 +4,9 @@ group: Project Management
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
---
# Multiple Assignees for Issues **(STARTER)**
# Multiple Assignees for Issues **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1904) in [GitLab Starter 9.2](https://about.gitlab.com/releases/2017/05/22/gitlab-9-2-released/#multiple-assignees-for-issues).
> - Moved to GitLab Premium in 13.9.
In large teams, where there is shared ownership of an issue, it can be difficult
to track who is working on it, who already completed their contributions, who
@ -40,4 +40,4 @@ to assign the issue to.
![adding multiple assignees](img/multiple_assignees.gif)
An assignee can be easily removed by deselecting them from the same dropdown menu.
To remove an assignee, deselect them from the same dropdown menu.

View File

@ -5,18 +5,17 @@ group: Project Management
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
---
# Burndown and burnup charts **(STARTER)**
# Burndown and burnup charts **(PREMIUM)**
[Burndown](#burndown-charts) and [burnup](#burnup-charts) charts show the progress of completing a milestone.
![burndown and burnup chart](img/burndown_and_burnup_charts_v13_6.png)
## Burndown charts
## Burndown charts **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1540) in [GitLab Starter](https://about.gitlab.com/pricing/) 9.1 for project milestones.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5354) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.8 for group milestones.
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6495) to [GitLab Starter](https://about.gitlab.com/pricing/) 11.2 for group milestones.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6903) [fixed burndown charts](#fixed-burndown-charts) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.6.
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6495) to GitLab 11.2 for group milestones.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6903) [fixed burndown charts](#fixed-burndown-charts) in GitLab 13.6.
> - Moved to GitLab Premium in 13.9.
Burndown charts show the number of issues over the course of a milestone.
@ -101,10 +100,11 @@ Therefore, when the milestone start date is changed, the number of opened issues
change.
Reopened issues are considered as having been opened on the day after they were last closed.
## Burnup charts
## Burnup charts **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6903) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.6.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/268350) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.7.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6903) in GitLab 13.6.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/268350) in GitLab 13.7.
> - Moved to GitLab Premium in 13.9.
Burnup charts show the assigned and completed work for a milestone.

View File

@ -123,10 +123,16 @@ From the project and group issue/merge request list pages, you can [filter](../.
### Filtering in issue boards
- From [project issue boards](../issue_board.md), you can filter by both group milestones and project milestones in the [search and filter bar](../../search/index.md#issue-boards).
- From [group issue boards](../issue_board.md#group-issue-boards), you can filter by only group milestones in the [search and filter bar](../../search/index.md#issue-boards). **(PREMIUM)**
- From [project issue boards](../issue_board.md), you can filter by both group milestones and project milestones in the [issue board configuration](../issue_board.md#configurable-issue-boards). **(STARTER)**
- From [group issue boards](../issue_board.md#group-issue-boards) you can filter by only group milestones in the [issue board configuration](../issue_board.md#configurable-issue-boards). **(STARTER)**
From [project issue boards](../issue_board.md), you can filter by both group milestones and project
milestones in:
- [Search and filter bar](../../search/index.md#issue-boards)
- [Issue board configuration](../issue_board.md#configurable-issue-boards)
From [group issue boards](../issue_board.md#group-issue-boards), you can filter by only group milestones in:
- [Search and filter bar](../../search/index.md#issue-boards)
- [Issue board configuration](../issue_board.md#configurable-issue-boards)
### Special milestone filters
@ -155,15 +161,17 @@ There are also tabs below these that show the following:
- **Participants**: Shows all assignees of issues assigned to the milestone.
- **Labels**: Shows all labels that are used in issues assigned to the milestone.
### Project Burndown Charts **(STARTER)**
### Project Burndown Charts
For project milestones in [GitLab Starter](https://about.gitlab.com/pricing/), a [burndown chart](burndown_and_burnup_charts.md) is in the milestone view, showing the progress of completing a milestone.
For project milestones, a [burndown chart](burndown_and_burnup_charts.md) is in the milestone view,
showing the progress of completing a milestone.
![burndown chart](img/burndown_chart_v13_6.png)
### Group Burndown Charts **(STARTER)**
### Group Burndown Charts
For group milestones in [GitLab Starter](https://about.gitlab.com/pricing/), a [burndown chart](burndown_and_burnup_charts.md) is in the milestone view, showing the progress of completing a milestone.
For group milestones, a [burndown chart](burndown_and_burnup_charts.md) is in the milestone view,
showing the progress of completing a milestone.
### Milestone sidebar

View File

@ -6,9 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Service Desk **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/149) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.1.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/214839) to [GitLab Starter](https://about.gitlab.com/pricing/) in 13.0.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/215364) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.2.
> - Moved to GitLab Free in 13.2.
Service Desk is a module that allows your team to connect
with any external party through email, without any external tools.
@ -89,9 +87,8 @@ Service Desk is now enabled for this project! You should be able to access it fr
### Using customized email templates
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2460) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/214839) to [GitLab Starter](https://about.gitlab.com/pricing/) in 13.0.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/215364) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.2.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2460) in GitLab Premium 12.7.
> - Moved to GitLab Free in 13.2.
An email is sent to the author when:
@ -159,7 +156,7 @@ To edit the custom email display name:
### Using custom email address
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2201) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.0.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2201) in GitLab Premium 13.0.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/284656) in GitLab 13.8.
If the `service_desk_email` is configured, then you can create Service Desk

View File

@ -26,9 +26,7 @@ module API
use :pagination
end
get ':id/templates/:type' do
templates = TemplateFinder
.build(params[:type], user_project)
.execute
templates = TemplateFinder.all_template_names_array(user_project, params[:type])
present paginate(::Kaminari.paginate_array(templates)), with: Entities::TemplatesList
end

View File

@ -228,7 +228,7 @@ module API
service.execute
status(200)
rescue => ex
rescue Gitlab::Changelog::Error => ex
render_api_error!("Failed to generate the changelog: #{ex.message}", 500)
end
end

157
lib/gitlab/changelog/ast.rb Normal file
View File

@ -0,0 +1,157 @@
# frozen_string_literal: true
module Gitlab
module Changelog
# AST nodes to evaluate when rendering a template.
#
# Evaluating an AST is done by walking over the nodes and calling
# `evaluate`. This method takes two arguments:
#
# 1. An instance of `EvalState`, used for tracking data such as the number
# of nested loops.
# 2. An object used as the data for the current scope. This can be an Array,
# Hash, String, or something else. It's up to the AST node to determine
# what to do with it.
#
# While tree walking interpreters (such as implemented here) aren't usually
# the fastest type of interpreter, they are:
#
# 1. Fast enough for our use case
# 2. Easy to implement and maintain
#
# In addition, our AST interpreter doesn't allow for arbitrary code
# execution, unlike existing template engines such as Mustache
# (https://github.com/mustache/mustache/issues/244) or ERB.
#
# Our interpreter also takes care of limiting the number of nested loops.
# And unlike Liquid, our interpreter is much smaller and thus has a smaller
# attack surface. Liquid isn't without its share of issues, such as
# https://github.com/Shopify/liquid/pull/1071.
#
# We also evaluated using Handlebars using the project
# https://github.com/SmartBear/ruby-handlebars. Sadly, this implementation
# of Handlebars doesn't support control of whitespace
# (https://github.com/SmartBear/ruby-handlebars/issues/37), and the project
# didn't appear to be maintained that much.
#
# This doesn't mean these template engines aren't good, instead it means
# they won't work for our use case. For more information, refer to the
# comment https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50063#note_469293322.
module AST
# An identifier in a selector.
Identifier = Struct.new(:name) do
def evaluate(state, data)
return data if name == 'it'
data[name] if data.is_a?(Hash)
end
end
# An integer used in a selector.
Integer = Struct.new(:value) do
def evaluate(state, data)
data[value] if data.is_a?(Array)
end
end
# A selector used for loading a value.
Selector = Struct.new(:steps) do
def evaluate(state, data)
steps.reduce(data) do |current, step|
break if current.nil?
step.evaluate(state, current)
end
end
end
# A tag used for displaying a value in the output.
Variable = Struct.new(:selector) do
def evaluate(state, data)
selector.evaluate(state, data).to_s
end
end
# A collection of zero or more expressions.
Expressions = Struct.new(:nodes) do
def evaluate(state, data)
nodes.map { |node| node.evaluate(state, data) }.join('')
end
end
# A single text node.
Text = Struct.new(:text) do
def evaluate(*)
text
end
end
# An `if` expression, with an optional `else` clause.
If = Struct.new(:condition, :true_body, :false_body) do
def evaluate(state, data)
result =
if truthy?(condition.evaluate(state, data))
true_body.evaluate(state, data)
elsif false_body
false_body.evaluate(state, data)
end
result.to_s
end
def truthy?(value)
# We treat empty collections and such as false, removing the need for
# some sort of `if length(x) > 0` expression.
value.respond_to?(:empty?) ? !value.empty? : !!value
end
end
# An `each` expression.
Each = Struct.new(:collection, :body) do
def evaluate(state, data)
values = collection.evaluate(state, data)
return '' unless values.respond_to?(:each)
# While unlikely to happen, it's possible users attempt to nest many
# loops in order to negatively impact the GitLab instance. To make
# this more difficult, we limit the number of nested loops a user can
# create.
state.enter_loop do
values.map { |value| body.evaluate(state, value) }.join('')
end
end
end
# A class for transforming a raw Parslet AST into a more structured/easier
# to work with AST.
#
# For more information about Parslet transformations, refer to the
# documentation at http://kschiess.github.io/parslet/transform.html.
class Transformer < Parslet::Transform
rule(ident: simple(:name)) { Identifier.new(name.to_s) }
rule(int: simple(:name)) { Integer.new(name.to_i) }
rule(text: simple(:text)) { Text.new(text.to_s) }
rule(exprs: subtree(:nodes)) { Expressions.new(nodes) }
rule(selector: sequence(:steps)) { Selector.new(steps) }
rule(selector: simple(:step)) { Selector.new([step]) }
rule(variable: simple(:selector)) { Variable.new(selector) }
rule(each: simple(:values), body: simple(:body)) do
Each.new(values, body)
end
rule(if: simple(:cond), true_body: simple(:true_body)) do
If.new(cond, true_body)
end
rule(
if: simple(:cond),
true_body: simple(:true_body),
false_body: simple(:false_body)
) do
If.new(cond, true_body, false_body)
end
end
end
end
end

View File

@ -4,8 +4,6 @@ module Gitlab
module Changelog
# A class used for committing a release's changelog to a Git repository.
class Committer
CommitError = Class.new(StandardError)
def initialize(project, user)
@project = project
@user = user
@ -25,7 +23,7 @@ module Gitlab
# When retrying, we need to reprocess the existing changelog from
# scratch, otherwise we may end up throwing away changes. As such, all
# the logic is contained within the retry block.
Retriable.retriable(on: CommitError) do
Retriable.retriable(on: Error) do
commit = Gitlab::Git::Commit.last_for_path(
@project.repository,
branch,
@ -57,7 +55,7 @@ module Gitlab
result = service.execute
raise CommitError.new(result[:message]) if result[:status] != :success
raise Error.new(result[:message]) if result[:status] != :success
end
end

View File

@ -4,8 +4,6 @@ module Gitlab
module Changelog
# Configuration settings used when generating changelogs.
class Config
ConfigError = Class.new(StandardError)
# When rendering changelog entries, authors are not included.
AUTHORS_NONE = 'none'
@ -37,17 +35,14 @@ module Gitlab
end
if (template = hash['template'])
# We use the full namespace here (and further down) as otherwise Rails
# may use the wrong constant when autoloading is used.
config.template =
::Gitlab::Changelog::Template::Compiler.new.compile(template)
config.template = Parser.new.parse_and_transform(template)
end
if (categories = hash['categories'])
if categories.is_a?(Hash)
config.categories = categories
else
raise ConfigError, 'The "categories" configuration key must be a Hash'
raise Error, 'The "categories" configuration key must be a Hash'
end
end
@ -57,8 +52,7 @@ module Gitlab
def initialize(project)
@project = project
@date_format = DEFAULT_DATE_FORMAT
@template =
::Gitlab::Changelog::Template::Compiler.new.compile(DEFAULT_TEMPLATE)
@template = Parser.new.parse_and_transform(DEFAULT_TEMPLATE)
@categories = {}
end

View File

@ -0,0 +1,8 @@
# frozen_string_literal: true
module Gitlab
module Changelog
# An error raised when a changelog couldn't be generated.
Error = Class.new(StandardError)
end
end

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
module Gitlab
module Changelog
# A class for tracking state when evaluating a template
class EvalState
MAX_LOOPS = 4
def initialize
@loops = 0
end
def enter_loop
if @loops == MAX_LOOPS
raise Error, "You can only nest up to #{MAX_LOOPS} loops"
end
@loops += 1
retval = yield
@loops -= 1
retval
end
end
end
end

View File

@ -0,0 +1,176 @@
# frozen_string_literal: true
module Gitlab
module Changelog
# A parser for the template syntax used for generating changelogs.
#
# As a quick primer on the template syntax, a basic template looks like
# this:
#
# {% each users %}
# Name: {{name}}
# Age: {{age}}
#
# {% if birthday %}
# This user is celebrating their birthday today! Yay!
# {% end %}
# {% end %}
#
# For more information, refer to the Parslet documentation found at
# http://kschiess.github.io/parslet/.
class Parser < Parslet::Parser
root(:exprs)
rule(:exprs) do
(
variable | if_expr | each_expr | escaped | text | newline
).repeat.as(:exprs)
end
rule(:space) { match('[ \\t]') }
rule(:whitespace) { match('\s').repeat }
rule(:lf) { str("\n") }
rule(:newline) { lf.as(:text) }
# Escaped newlines are ignored, allowing the user to control the
# whitespace in the output. All other escape sequences are treated as
# literal text.
#
# For example, this:
#
# foo \
# bar
#
# Is parsed into this:
#
# foo bar
rule(:escaped) do
backslash = str('\\')
(backslash >> lf).ignore | (backslash >> chars).as(:text)
end
# A sequence of regular characters, with the exception of newlines and
# escaped newlines.
rule(:chars) do
char = match("[^{\\\\\n]")
# The rules here are such that we do treat single curly braces or
# non-opening tags (e.g. `{foo}`) as text, but not opening tags
# themselves (e.g. `{{`).
(
char.repeat(1) | curly_open >> (curly_open | percent).absent?
).repeat(1)
end
rule(:text) { chars.as(:text) }
# An integer, limited to 10 digits (= a 32 bits integer).
#
# The size is limited to prevents users from creating integers that are
# too large, as this may result in runtime errors.
rule(:integer) { match('\d').repeat(1, 10).as(:int) }
# An identifier to look up in a data structure.
#
# We only support simple ASCII identifiers as we simply don't have a need
# for more complex identifiers (e.g. those containing multibyte
# characters).
rule(:ident) { match('[a-zA-Z_]').repeat(1).as(:ident) }
# A selector is used for reading a value, consisting of one or more
# "steps".
#
# Examples:
#
# name
# users.0.name
# 0
# it
rule(:selector) do
step = ident | integer
whitespace >>
(step >> (str('.') >> step).repeat).as(:selector) >>
whitespace
end
rule(:curly_open) { str('{') }
rule(:curly_close) { str('}') }
rule(:percent) { str('%') }
# A variable tag.
#
# Examples:
#
# {{name}}
# {{users.0.name}}
rule(:variable) do
curly_open.repeat(2) >> selector.as(:variable) >> curly_close.repeat(2)
end
rule(:expr_open) { curly_open >> percent >> whitespace }
rule(:expr_close) do
# Since whitespace control is important (as Markdown is whitespace
# sensitive), we default to stripping a newline that follows a %} tag.
# This is less annoying compared to having to opt-in to this behaviour.
whitespace >> percent >> curly_close >> lf.maybe.ignore
end
rule(:end_tag) { expr_open >> str('end') >> expr_close }
# An `if` expression, with an optional `else` clause.
#
# Examples:
#
# {% if foo %}
# yes
# {% end %}
#
# {% if foo %}
# yes
# {% else %}
# no
# {% end %}
rule(:if_expr) do
else_tag =
expr_open >> str('else') >> expr_close >> exprs.as(:false_body)
expr_open >>
str('if') >>
space.repeat(1) >>
selector.as(:if) >>
expr_close >>
exprs.as(:true_body) >>
else_tag.maybe >>
end_tag
end
# An `each` expression, used for iterating over collections.
#
# Example:
#
# {% each users %}
# * {{name}}
# {% end %}
rule(:each_expr) do
expr_open >>
str('each') >>
space.repeat(1) >>
selector.as(:each) >>
expr_close >>
exprs.as(:body) >>
end_tag
end
def parse_and_transform(input)
AST::Transformer.new.apply(parse(input))
rescue Parslet::ParseFailed => ex
# We raise a custom error so it's easier to catch different changelog
# related errors. In addition, this ensures the caller of this method
# doesn't depend on a Parslet specific error class.
raise Error.new("Failed to parse the template: #{ex.message}")
end
end
end
end

View File

@ -54,14 +54,16 @@ module Gitlab
end
def to_markdown
state = EvalState.new
data = { 'categories' => entries_for_template }
# While not critical, we would like release sections to be separated by
# an empty line in the changelog; ensuring it's readable even in its
# raw form.
#
# Since it can be a bit tricky to get this right using Liquid, we
# Since it can be a bit tricky to get this right in a template, we
# enforce an empty line separator ourselves.
markdown =
@config.template.render('categories' => entries_for_template).strip
markdown = @config.template.evaluate(state, data).strip
# The release header can't be changed using the Liquid template, as we
# need this to be in a known format. Without this restriction, we won't
@ -80,14 +82,20 @@ module Gitlab
end
def entries_for_template
@entries.map do |category, entries|
{
rows = []
@entries.each do |category, entries|
next if entries.empty?
rows << {
'title' => category,
'count' => entries.length,
'single_change' => entries.length == 1,
'entries' => entries
}
end
rows
end
end
end

View File

@ -6,6 +6,7 @@
- [{{ title }}]({{ commit.reference }})\
{% if author.contributor %} by {{ author.reference }}{% end %}\
{% if merge_request %} ([merge request]({{ merge_request.reference }})){% end %}
{% end %}
{% end %}

View File

@ -1,154 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Changelog
module Template
# Compiler is used for turning a minimal user templating language into an
# ERB template, without giving the user access to run arbitrary code.
#
# The template syntax is deliberately made as minimal as possible, and
# only supports the following:
#
# * Printing a value
# * Iterating over collections
# * if/else
#
# The syntax looks as follows:
#
# {% each users %}
#
# Name: {{user}}
# Likes cats: {% if likes_cats %}yes{% else %}no{% end %}
#
# {% end %}
#
# Newlines can be escaped by ending a line with a backslash. So this:
#
# foo \
# bar
#
# Is the same as this:
#
# foo bar
#
# Templates are compiled into ERB templates, while taking care to make
# sure the user can't run arbitrary code. By using ERB we can let it do
# the heavy lifting of rendering data; all we need to provide is a
# translation layer.
#
# # Security
#
# The template syntax this compiler exposes is safe to be used by
# untrusted users. Not only are they unable to run arbitrary code, the
# compiler also enforces a limit on the integer sizes and the number of
# nested loops. ERB tags added by the user are also disabled.
class Compiler
# A pattern to match a single integer, with an upper size limit.
#
# We enforce a limit of 10 digits (= a 32 bits integer) so users can't
# trigger the allocation of infinitely large bignums, or trigger
# RangeError errors when using such integers to access an array value.
INTEGER = /^\d{1,10}$/.freeze
# The name/path of a variable, such as `user.address.city`.
#
# It's important that this regular expression _doesn't_ allow for
# anything but letters, numbers, and underscores, otherwise a user may
# use those to "escape" our template and run arbirtary Ruby code. For
# example, take this variable:
#
# {{') ::Kernel.exit #'}}
#
# This would then be compiled into:
#
# <%= read(variables, '') ::Kernel.exit #'') %>
#
# Restricting the allowed characters makes this impossible.
VAR_NAME = /([\w\.]+)/.freeze
# A variable tag, such as `{{username}}`.
VAR = /{{ \s* #{VAR_NAME} \s* }}/x.freeze
# The opening tag for a statement.
STM_START = /{% \s*/x.freeze
# The closing tag for a statement.
STM_END = /\s* %}/x.freeze
# A regular `end` closing tag.
NORMAL_END = /#{STM_START} end #{STM_END}/x.freeze
# An `end` closing tag on its own line, without any non-whitespace
# preceding or following it.
#
# These tags need some special care to make it easier to control
# whitespace.
LONELY_END = /^\s*#{NORMAL_END}\s$/x.freeze
# An `else` tag.
ELSE = /#{STM_START} else #{STM_END}/x.freeze
# The start of an `each` tag.
EACH = /#{STM_START} each \s+ #{VAR_NAME} #{STM_END}/x.freeze
# The start of an `if` tag.
IF = /#{STM_START} if \s+ #{VAR_NAME} #{STM_END}/x.freeze
# The pattern to use for escaping newlines.
ESCAPED_NEWLINE = /\\\n$/.freeze
# The start tag for ERB tags. These tags will be escaped, preventing
# users from using ERB directly.
ERB_START_TAG = /<\\?\s*\\?\s*%/.freeze
def compile(template)
transformed_lines = ['<% it = variables %>']
# ERB tags must be stripped here, otherwise a user may introduce ERB
# tags by making clever use of whitespace. See
# https://gitlab.com/gitlab-org/gitlab/-/issues/300224 for more
# information.
template = template.gsub(ERB_START_TAG, '<%%')
template.each_line { |line| transformed_lines << transform(line) }
# We use the full namespace here as otherwise Rails may use the wrong
# constant when autoloading is used.
::Gitlab::Changelog::Template::Template.new(transformed_lines.join)
end
def transform(line)
line.gsub!(ESCAPED_NEWLINE, '')
# This replacement ensures that "end" blocks on their own lines
# don't add extra newlines. Using an ERB -%> tag sadly swallows too
# many newlines.
line.gsub!(LONELY_END, '<% end %>')
line.gsub!(NORMAL_END, '<% end %>')
line.gsub!(ELSE, '<% else -%>')
line.gsub!(EACH) do
# No, `it; variables` isn't a syntax error. Using `;` marks
# `variables` as block-local, making it possible to re-assign it
# without affecting outer definitions of this variable. We use
# this to scope template variables to the right input Hash.
"<% each(#{read_path(Regexp.last_match(1))}) do |it; variables| -%><% variables = it -%>"
end
line.gsub!(IF) { "<% if truthy?(#{read_path(Regexp.last_match(1))}) -%>" }
line.gsub!(VAR) { "<%= #{read_path(Regexp.last_match(1))} %>" }
line
end
def read_path(path)
return path if path == 'it'
args = path.split('.')
args.map! { |arg| arg.match?(INTEGER) ? "#{arg}" : "'#{arg}'" }
"read(variables, #{args.join(', ')})"
end
end
end
end
end

View File

@ -1,70 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Changelog
module Template
# Context is used to provide a binding/context to ERB templates used for
# rendering changelogs.
#
# This class extends BasicObject so that we only expose the bare minimum
# needed to render the ERB template.
class Context < BasicObject
MAX_NESTED_LOOPS = 4
def initialize(variables)
@variables = variables
@loop_nesting = 0
end
def get_binding
::Kernel.binding
end
def each(value, &block)
max = MAX_NESTED_LOOPS
if @loop_nesting == max
::Kernel.raise(
::Template::TemplateError.new("You can only nest up to #{max} loops")
)
end
@loop_nesting += 1
result = value.each(&block) if value.respond_to?(:each)
@loop_nesting -= 1
result
end
# rubocop: disable Style/TrivialAccessors
def variables
@variables
end
# rubocop: enable Style/TrivialAccessors
def read(source, *steps)
current = source
steps.each do |step|
case current
when ::Hash
current = current[step]
when ::Array
return '' unless step.is_a?(::Integer)
current = current[step]
else
break
end
end
current
end
def truthy?(value)
value.respond_to?(:any?) ? value.any? : !!value
end
end
end
end
end

View File

@ -1,29 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Changelog
module Template
# A wrapper around an ERB template user for rendering changelogs.
class Template
TemplateError = Class.new(StandardError)
def initialize(erb)
# Don't change the trim mode, as this may require changes to the
# regular expressions used to turn the template syntax into ERB
# tags.
@erb = ERB.new(erb, trim_mode: '-')
end
def render(data)
context = Context.new(data).get_binding
# ERB produces a SyntaxError when processing templates, as it
# internally uses eval() for this.
@erb.result(context)
rescue SyntaxError
raise TemplateError.new("The template's syntax is invalid")
end
end
end
end
end

View File

@ -226,6 +226,7 @@ module Gitlab
metadata['username'] = context_data['meta.user'] if context_data&.fetch('meta.user', nil)
metadata['remote_ip'] = context_data['meta.remote_ip'] if context_data&.fetch('meta.remote_ip', nil)
metadata.merge!(Feature::Gitaly.server_feature_flags)
metadata.merge!(route_to_primary)
deadline_info = request_deadline(timeout)
metadata.merge!(deadline_info.slice(:deadline_type))
@ -233,6 +234,24 @@ module Gitlab
{ metadata: metadata, deadline: deadline_info[:deadline] }
end
# Gitlab::Git::HookEnv will set the :gitlab_git_env variable in case we're
# running in the context of a Gitaly hook call, which may make use of
# quarantined object directories. We thus need to pass along the path of
# the quarantined object directory to Gitaly, otherwise it won't be able to
# find these quarantined objects. Given that the quarantine directory is
# generated with a random name, they'll have different names when multiple
# Gitaly nodes take part in a single transaction. As a result, we are
# forced to route all requests to the primary node which has injected the
# quarantine object directory to us.
def self.route_to_primary
return {} unless Gitlab::SafeRequestStore.active?
return {} unless Gitlab::SafeRequestStore[:gitlab_git_env]
{ 'gitaly-route-repository-accessor-policy' => 'primary-only' }
end
private_class_method :route_to_primary
def self.request_deadline(timeout)
# timeout being 0 means the request is allowed to run indefinitely.
# We can't allow that inside a request, but this won't count towards Gitaly

View File

@ -95,19 +95,29 @@ module Gitlab
File.join(base_dir, categories[category])
end
# If template is organized by category it returns { category_name: [{ name: template_name }, { name: template2_name }] }
# If no category is present returns [{ name: template_name }, { name: template2_name}]
def dropdown_names(project = nil)
return [] if project && !project.repository.exists?
# `repository_template_names` - reads through Gitaly the actual templates names within a
# given project's repository. This is only used by issue and merge request templates,
# that need to call this once and then cache the returned value.
#
# `template_names` - is an alias to `repository_template_names`. It would read through
# Gitaly the actual template names within a given project's repository for all file templates
# other than `issue` and `merge request` description templates, which would instead
# overwrite the `template_names` method to return a redis cached version, by reading cached values
# from `repository.issue_template_names_by_category` and `repository.merge_request_template_names_by_category`
# methods.
def repository_template_names(project)
template_names_by_category(self.all(project))
end
alias_method :template_names, :repository_template_names
if categories.any?
categories.keys.map do |category|
files = self.by_category(category, project)
[category, files.map { |t| { name: t.name } }]
end.to_h
else
files = self.all(project)
files.map { |t| { name: t.name } }
def template_names_by_category(items)
grouped = items.group_by(&:category)
categories = grouped.keys
categories.each_with_object({}) do |category, hash|
hash[category] = grouped[category].map do |item|
{ name: item.name, id: item.key, key: item.key, project_id: item.try(:project_id) }
end
end
end

View File

@ -11,8 +11,8 @@ module Gitlab
def initialize(project, base_dir, extension, categories = {})
@categories = categories
@extension = extension
@repository = project.repository
@commit = @repository.head_commit if @repository.exists?
@repository = project&.repository
@commit = @repository.head_commit if @repository&.exists?
super(base_dir)
end
@ -51,7 +51,7 @@ module Gitlab
private
def select_directory(file_name)
return [] unless @commit
return unless @commit
# Insert root as directory
directories = ["", *@categories.keys]

View File

@ -15,6 +15,16 @@ module Gitlab
def finder(project)
Gitlab::Template::Finders::RepoTemplateFinder.new(project, self.base_dir, self.extension, self.categories)
end
def template_names(project)
return {} unless project&.repository&.exists?
# here we rely on project.repository caching mechanism. Ideally we would want the template finder to have its
# own caching mechanism to avoid the back and forth call jumps between finder and model.
#
# follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300279
project.repository.issue_template_names_by_category
end
end
end
end

View File

@ -15,6 +15,16 @@ module Gitlab
def finder(project)
Gitlab::Template::Finders::RepoTemplateFinder.new(project, self.base_dir, self.extension, self.categories)
end
def template_names(project)
return {} unless project&.repository&.exists?
# here we rely on project.repository caching mechanism. Ideally we would want the template finder to have its
# own caching mechanism to avoid the back and forth call jumps between finder and model.
#
# follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300279
project.repository.merge_request_template_names_by_category
end
end
end
end

View File

@ -0,0 +1,22 @@
---
# Ecosystem category
- name: i_ecosystem_jira_service_close_issue
category: ecosystem
redis_slot: ecosystem
aggregation: weekly
feature_flag: usage_data_track_ecosystem_jira_service
- name: i_ecosystem_jira_service_cross_reference
category: ecosystem
redis_slot: ecosystem
aggregation: weekly
feature_flag: usage_data_track_ecosystem_jira_service
- name: i_ecosystem_jira_service_list_issues
category: ecosystem
redis_slot: ecosystem
aggregation: weekly
feature_flag: usage_data_track_ecosystem_jira_service
- name: i_ecosystem_jira_service_create_issue
category: ecosystem
redis_slot: ecosystem
aggregation: weekly
feature_flag: usage_data_track_ecosystem_jira_service

Some files were not shown because too many files have changed in this diff Show More