Commit 11aa231d authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 4487c419 e3121749
...@@ -293,7 +293,7 @@ gem 'gon', '~> 6.2' ...@@ -293,7 +293,7 @@ gem 'gon', '~> 6.2'
gem 'request_store', '~> 1.5' gem 'request_store', '~> 1.5'
gem 'base32', '~> 0.3.0' gem 'base32', '~> 0.3.0'
gem "gitlab-license", "~> 1.0" gem "gitlab-license", "~> 1.3"
# Protect against bruteforcing # Protect against bruteforcing
gem 'rack-attack', '~> 6.3.0' gem 'rack-attack', '~> 6.3.0'
......
...@@ -443,7 +443,7 @@ GEM ...@@ -443,7 +443,7 @@ GEM
jaeger-client (~> 1.1) jaeger-client (~> 1.1)
opentracing (~> 0.4) opentracing (~> 0.4)
redis (> 3.0.0, < 5.0.0) redis (> 3.0.0, < 5.0.0)
gitlab-license (1.0.0) gitlab-license (1.3.0)
gitlab-mail_room (0.0.8) gitlab-mail_room (0.0.8)
gitlab-markup (1.7.1) gitlab-markup (1.7.1)
gitlab-net-dns (0.9.1) gitlab-net-dns (0.9.1)
...@@ -1374,7 +1374,7 @@ DEPENDENCIES ...@@ -1374,7 +1374,7 @@ DEPENDENCIES
gitlab-experiment (~> 0.4.9) gitlab-experiment (~> 0.4.9)
gitlab-fog-azure-rm (~> 1.0) gitlab-fog-azure-rm (~> 1.0)
gitlab-labkit (= 0.14.0) gitlab-labkit (= 0.14.0)
gitlab-license (~> 1.0) gitlab-license (~> 1.3)
gitlab-mail_room (~> 0.0.8) gitlab-mail_room (~> 0.0.8)
gitlab-markup (~> 1.7.1) gitlab-markup (~> 1.7.1)
gitlab-net-dns (~> 0.9.1) gitlab-net-dns (~> 0.9.1)
......
import ZenMode from '~/zen_mode'; import ZenMode from '~/zen_mode';
import initEditRelease from '~/releases/mount_edit'; import initEditRelease from '~/releases/mount_edit';
document.addEventListener('DOMContentLoaded', () => { new ZenMode(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new initEditRelease();
initEditRelease();
});
<script> <script>
import { GlAlert, GlBadge, GlIcon, GlLink, GlSprintf, GlTable, GlTooltip } from '@gitlab/ui'; import {
GlAlert,
GlBadge,
GlIcon,
GlLink,
GlLoadingIcon,
GlSprintf,
GlTable,
GlTooltip,
} from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import CiBadge from '~/vue_shared/components/ci_badge_link.vue'; import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
...@@ -14,6 +23,7 @@ export default { ...@@ -14,6 +23,7 @@ export default {
GlBadge, GlBadge,
GlIcon, GlIcon,
GlLink, GlLink,
GlLoadingIcon,
GlSprintf, GlSprintf,
GlTable, GlTable,
GlTooltip, GlTooltip,
...@@ -67,15 +77,20 @@ export default { ...@@ -67,15 +77,20 @@ export default {
jobStatus: s__('Terraform|Job status'), jobStatus: s__('Terraform|Job status'),
locked: s__('Terraform|Locked'), locked: s__('Terraform|Locked'),
lockedByUser: s__('Terraform|Locked by %{user} %{timeAgo}'), lockedByUser: s__('Terraform|Locked by %{user} %{timeAgo}'),
lockingState: s__('Terraform|Locking state'),
name: s__('Terraform|Name'), name: s__('Terraform|Name'),
pipeline: s__('Terraform|Pipeline'), pipeline: s__('Terraform|Pipeline'),
unknownUser: s__('Terraform|Unknown User'), unknownUser: s__('Terraform|Unknown User'),
unlockingState: s__('Terraform|Unlocking state'),
updatedUser: s__('Terraform|%{user} updated %{timeAgo}'), updatedUser: s__('Terraform|%{user} updated %{timeAgo}'),
}, },
methods: { methods: {
createdByUserName(item) { createdByUserName(item) {
return item.latestVersion?.createdByUser?.name; return item.latestVersion?.createdByUser?.name;
}, },
loadingLockText(item) {
return item.lockedAt ? this.$options.i18n.unlockingState : this.$options.i18n.lockingState;
},
lockedByUserName(item) { lockedByUserName(item) {
return item.lockedByUser?.name || this.$options.i18n.unknownUser; return item.lockedByUser?.name || this.$options.i18n.unknownUser;
}, },
...@@ -119,7 +134,18 @@ export default { ...@@ -119,7 +134,18 @@ export default {
{{ item.name }} {{ item.name }}
</p> </p>
<div v-if="item.lockedAt" :id="`terraformLockedBadgeContainer${item.name}`" class="gl-mx-2"> <div v-if="item.loadingLock" class="gl-mx-3">
<p class="gl-display-flex gl-justify-content-start gl-align-items-baseline gl-m-0">
<gl-loading-icon class="gl-pr-1" />
{{ loadingLockText(item) }}
</p>
</div>
<div
v-else-if="item.lockedAt"
:id="`terraformLockedBadgeContainer${item.name}`"
class="gl-mx-3"
>
<gl-badge :id="`terraformLockedBadge${item.name}`"> <gl-badge :id="`terraformLockedBadge${item.name}`">
<gl-icon name="lock" /> <gl-icon name="lock" />
{{ $options.i18n.locked }} {{ $options.i18n.locked }}
......
...@@ -64,6 +64,9 @@ export default { ...@@ -64,6 +64,9 @@ export default {
disableModalSubmit() { disableModalSubmit() {
return this.removeConfirmText !== this.state.name; return this.removeConfirmText !== this.state.name;
}, },
loading() {
return this.state.loadingLock || this.state.loadingRemove;
},
primaryModalProps() { primaryModalProps() {
return { return {
text: this.$options.i18n.modalRemove, text: this.$options.i18n.modalRemove,
...@@ -77,9 +80,23 @@ export default { ...@@ -77,9 +80,23 @@ export default {
this.removeConfirmText = ''; this.removeConfirmText = '';
}, },
lock() { lock() {
this.updateStateCache({
_showDetails: false,
errorMessages: [],
loadingLock: true,
loadingRemove: false,
});
this.stateActionMutation(lockState); this.stateActionMutation(lockState);
}, },
unlock() { unlock() {
this.updateStateCache({
_showDetails: false,
errorMessages: [],
loadingLock: true,
loadingRemove: false,
});
this.stateActionMutation(unlockState); this.stateActionMutation(unlockState);
}, },
updateStateCache(newData) { updateStateCache(newData) {
...@@ -96,18 +113,20 @@ export default { ...@@ -96,18 +113,20 @@ export default {
remove() { remove() {
if (!this.disableModalSubmit) { if (!this.disableModalSubmit) {
this.hideModal(); this.hideModal();
this.updateStateCache({
_showDetails: false,
errorMessages: [],
loadingLock: false,
loadingRemove: true,
});
this.stateActionMutation(removeState); this.stateActionMutation(removeState);
} }
}, },
stateActionMutation(mutation) { stateActionMutation(mutation) {
let errorMessages = []; let errorMessages = [];
this.updateStateCache({
_showDetails: false,
errorMessages,
loadingActions: true,
});
this.$apollo this.$apollo
.mutate({ .mutate({
mutation, mutation,
...@@ -132,7 +151,8 @@ export default { ...@@ -132,7 +151,8 @@ export default {
this.updateStateCache({ this.updateStateCache({
_showDetails: Boolean(errorMessages.length), _showDetails: Boolean(errorMessages.length),
errorMessages, errorMessages,
loadingActions: false, loadingLock: false,
loadingRemove: false,
}); });
}); });
}, },
...@@ -146,7 +166,7 @@ export default { ...@@ -146,7 +166,7 @@ export default {
icon="ellipsis_v" icon="ellipsis_v"
right right
:data-testid="`terraform-state-actions-${state.name}`" :data-testid="`terraform-state-actions-${state.name}`"
:disabled="state.loadingActions" :disabled="loading"
toggle-class="gl-px-3! gl-shadow-none!" toggle-class="gl-px-3! gl-shadow-none!"
> >
<template #button-content> <template #button-content>
......
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
fragment State on TerraformState { fragment State on TerraformState {
_showDetails @client _showDetails @client
errorMessages @client errorMessages @client
loadingActions @client loadingLock @client
loadingRemove @client
id id
name name
......
...@@ -9,8 +9,11 @@ export default { ...@@ -9,8 +9,11 @@ export default {
errorMessages: (state) => { errorMessages: (state) => {
return state.errorMessages || []; return state.errorMessages || [];
}, },
loadingActions: (state) => { loadingLock: (state) => {
return state.loadingActions || false; return state.loadingLock || false;
},
loadingRemove: (state) => {
return state.loadingRemove || false;
}, },
}, },
Mutation: { Mutation: {
...@@ -32,7 +35,8 @@ export default { ...@@ -32,7 +35,8 @@ export default {
// eslint-disable-next-line no-underscore-dangle // eslint-disable-next-line no-underscore-dangle
_showDetails: terraformState._showDetails, _showDetails: terraformState._showDetails,
errorMessages: terraformState.errorMessages, errorMessages: terraformState.errorMessages,
loadingActions: terraformState.loadingActions, loadingLock: terraformState.loadingLock,
loadingRemove: terraformState.loadingRemove,
}, },
}); });
} }
......
...@@ -8,6 +8,10 @@ module Integrations ...@@ -8,6 +8,10 @@ module Integrations
Gitlab::DataBuilder::Push.build_sample(project, current_user) Gitlab::DataBuilder::Push.build_sample(project, current_user)
end end
def use_newest_record?
Feature.enabled?(:integrations_test_webhook_reorder, project)
end
def note_events_data def note_events_data
note = NotesFinder.new(current_user, project: project, target: project).execute.reorder(nil).last # rubocop: disable CodeReuse/ActiveRecord note = NotesFinder.new(current_user, project: project, target: project).execute.reorder(nil).last # rubocop: disable CodeReuse/ActiveRecord
...@@ -33,14 +37,24 @@ module Integrations ...@@ -33,14 +37,24 @@ module Integrations
end end
def job_events_data def job_events_data
build = project.builds.first build = if use_newest_record?
Ci::JobsFinder.new(current_user: current_user, project: project).execute.first
else
project.builds.first
end
return { error: s_('TestHooks|Ensure the project has CI jobs.') } unless build.present? return { error: s_('TestHooks|Ensure the project has CI jobs.') } unless build.present?
Gitlab::DataBuilder::Build.build(build) Gitlab::DataBuilder::Build.build(build)
end end
def pipeline_events_data def pipeline_events_data
pipeline = project.ci_pipelines.newest_first.first pipeline = if use_newest_record?
Ci::PipelinesFinder.new(project, current_user, order_by: 'id', sort: 'desc').execute.first
else
project.ci_pipelines.newest_first.first
end
return { error: s_('TestHooks|Ensure the project has CI pipelines.') } unless pipeline.present? return { error: s_('TestHooks|Ensure the project has CI pipelines.') } unless pipeline.present?
Gitlab::DataBuilder::Pipeline.build(pipeline) Gitlab::DataBuilder::Pipeline.build(pipeline)
...@@ -48,6 +62,7 @@ module Integrations ...@@ -48,6 +62,7 @@ module Integrations
def wiki_page_events_data def wiki_page_events_data
page = project.wiki.list_pages(limit: 1).first page = project.wiki.list_pages(limit: 1).first
if !project.wiki_enabled? || page.blank? if !project.wiki_enabled? || page.blank?
return { error: s_('TestHooks|Ensure the wiki is enabled and has pages.') } return { error: s_('TestHooks|Ensure the wiki is enabled and has pages.') }
end end
...@@ -56,14 +71,24 @@ module Integrations ...@@ -56,14 +71,24 @@ module Integrations
end end
def deployment_events_data def deployment_events_data
deployment = project.deployments.first deployment = if use_newest_record?
DeploymentsFinder.new(project: project, order_by: 'created_at', sort: 'desc').execute.first
else
project.deployments.first
end
return { error: s_('TestHooks|Ensure the project has deployments.') } unless deployment.present? return { error: s_('TestHooks|Ensure the project has deployments.') } unless deployment.present?
Gitlab::DataBuilder::Deployment.build(deployment) Gitlab::DataBuilder::Deployment.build(deployment)
end end
def releases_events_data def releases_events_data
release = project.releases.first release = if use_newest_record?
ReleasesFinder.new(project, current_user, order_by: :created_at, sort: :desc).execute.first
else
project.releases.first
end
return { error: s_('TestHooks|Ensure the project has releases.') } unless release.present? return { error: s_('TestHooks|Ensure the project has releases.') } unless release.present?
release.to_hook_data('create') release.to_hook_data('create')
......
...@@ -6,6 +6,10 @@ module TestHooks ...@@ -6,6 +6,10 @@ module TestHooks
private private
def use_newest_record?
Feature.enabled?(:integrations_test_webhook_reorder)
end
def data def data
strong_memoize(:data) do strong_memoize(:data) do
case trigger case trigger
...@@ -20,7 +24,12 @@ module TestHooks ...@@ -20,7 +24,12 @@ module TestHooks
end end
def merge_requests_events_data def merge_requests_events_data
merge_request = MergeRequest.of_projects(current_user.projects.select(:id)).first merge_request = if use_newest_record?
MergeRequest.of_projects(current_user.projects.select(:id)).last
else
MergeRequest.of_projects(current_user.projects.select(:id)).first
end
return { error: s_('TestHooks|Ensure one of your projects has merge requests.') } unless merge_request.present? return { error: s_('TestHooks|Ensure one of your projects has merge requests.') } unless merge_request.present?
merge_request.to_hook_data(current_user) merge_request.to_hook_data(current_user)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
- can_edit = can?(current_user, :admin_project, @project) - can_edit = can?(current_user, :admin_project, @project)
.dropdown.btn-group .dropdown.btn-group
%button.btn.gl-button.btn-default.rounded-right.text-center{ class: ('has-tooltip' if type == :icon), title: (_('Import issues') if type == :icon), %button.btn.gl-button.rounded-right.btn-default.btn-icon.text-center{ class: ('has-tooltip' if type == :icon), title: (_('Import issues') if type == :icon),
data: { toggle: 'dropdown', qa_selector: 'import_issues_button' }, 'aria-label' => _('Import issues'), 'aria-haspopup' => 'true', 'aria-expanded' => 'false' } data: { toggle: 'dropdown', qa_selector: 'import_issues_button' }, 'aria-label' => _('Import issues'), 'aria-haspopup' => 'true', 'aria-expanded' => 'false' }
- if type == :icon - if type == :icon
= sprite_icon('import') = sprite_icon('import')
......
= link_to safe_params.merge(rss_url_options), class: 'btn gl-button btn-default has-tooltip', data: { container: 'body', testid: 'rss-feed-link' }, title: _('Subscribe to RSS feed') do = link_to safe_params.merge(rss_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body', testid: 'rss-feed-link' }, title: _('Subscribe to RSS feed') do
= sprite_icon('rss', css_class: 'qa-rss-icon') = sprite_icon('rss', css_class: 'qa-rss-icon')
= link_to safe_params.merge(calendar_url_options), class: 'btn gl-button btn-default has-tooltip', data: { container: 'body' }, title: _('Subscribe to calendar') do = link_to safe_params.merge(calendar_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body' }, title: _('Subscribe to calendar') do
= sprite_icon('calendar') = sprite_icon('calendar')
- if current_user - if current_user
%button.csv_download_link.btn.gl-button.btn-default.has-tooltip{ title: _('Export as CSV'), %button.csv_download_link.btn.gl-button.btn-default.btn-icon.has-tooltip{ title: _('Export as CSV'),
data: { toggle: 'modal', target: ".#{issuable_type}-export-modal", qa_selector: 'export_as_csv_button' } } data: { toggle: 'modal', target: ".#{issuable_type}-export-modal", qa_selector: 'export_as_csv_button' } }
= sprite_icon('export') = sprite_icon('export')
---
title: Add loading display to Terraform lock action
merge_request: 53475
author:
type: changed
---
title: Add btn-icon class for icon only buttons in issues header
merge_request: 53562
author: Yogi (@yo)
type: other
---
name: integrations_test_webhook_reorder
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53433
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/320861
milestone: '13.9'
type: development
group: group::ecosystem
default_enabled: false
--- ---
filenames: filenames:
- ee/app/assets/javascripts/on_demand_scans/graphql/dast_scan_create.mutation.graphql
- ee/app/assets/javascripts/oncall_schedules/graphql/mutations/update_oncall_schedule_rotation.mutation.graphql - ee/app/assets/javascripts/oncall_schedules/graphql/mutations/update_oncall_schedule_rotation.mutation.graphql
- ee/app/assets/javascripts/security_configuration/api_fuzzing/graphql/api_fuzzing_ci_configuration.query.graphql - ee/app/assets/javascripts/security_configuration/api_fuzzing/graphql/api_fuzzing_ci_configuration.query.graphql
- ee/app/assets/javascripts/on_demand_scans/graphql/dast_profile_update.mutation.graphql
...@@ -29,7 +29,7 @@ No matter how you use GitLab, we have documentation for you. ...@@ -29,7 +29,7 @@ No matter how you use GitLab, we have documentation for you.
| [**Contributing to GitLab**](#contributing-to-gitlab)<br/>At GitLab, everyone can contribute! | [**New to Git and GitLab?**](#new-to-git-and-gitlab)<br/>We have the resources to get you started. | | [**Contributing to GitLab**](#contributing-to-gitlab)<br/>At GitLab, everyone can contribute! | [**New to Git and GitLab?**](#new-to-git-and-gitlab)<br/>We have the resources to get you started. |
| [**Build an integration with GitLab**](#build-an-integration-with-gitlab)<br/>Consult our integration documentation. | [**Coming to GitLab from another platform?**](#coming-to-gitlab-from-another-platform)<br/>Consult our guides. | | [**Build an integration with GitLab**](#build-an-integration-with-gitlab)<br/>Consult our integration documentation. | [**Coming to GitLab from another platform?**](#coming-to-gitlab-from-another-platform)<br/>Consult our guides. |
| [**Install GitLab**](https://about.gitlab.com/install/)<br/>Installation options for different platforms. | [**Customers**](subscriptions/index.md)<br/>Information for new and existing customers. | | [**Install GitLab**](https://about.gitlab.com/install/)<br/>Installation options for different platforms. | [**Customers**](subscriptions/index.md)<br/>Information for new and existing customers. |
| [**Update GitLab**](update/README.md)<br/>Update your GitLab self-managed instance to the latest version. | [**Reference Architectures**](administration/reference_architectures/index.md)<br/>GitLab reference architectures. | | [**Update GitLab**](update/index.md)<br/>Update your GitLab self-managed instance to the latest version. | [**Reference Architectures**](administration/reference_architectures/index.md)<br/>GitLab reference architectures. |
| [**GitLab releases**](https://about.gitlab.com/releases/)<br/>What's new in GitLab. | | | [**GitLab releases**](https://about.gitlab.com/releases/)<br/>What's new in GitLab. | |
## Popular topics ## Popular topics
......
...@@ -32,7 +32,7 @@ Learn how to install, configure, update, and maintain your GitLab instance. ...@@ -32,7 +32,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
### Installing GitLab ### Installing GitLab
- [Install](../install/README.md): Requirements, directory structures, and installation methods. - [Install](../install/index.md): Requirements, directory structures, and installation methods.
- [Database load balancing](database_load_balancing.md): Distribute database queries among multiple database servers. - [Database load balancing](database_load_balancing.md): Distribute database queries among multiple database servers.
- [Omnibus support for log forwarding](https://docs.gitlab.com/omnibus/settings/logs.html#udp-log-shipping-gitlab-enterprise-edition-only). - [Omnibus support for log forwarding](https://docs.gitlab.com/omnibus/settings/logs.html#udp-log-shipping-gitlab-enterprise-edition-only).
- [Reference architectures](reference_architectures/index.md): Add additional resources to support more users. - [Reference architectures](reference_architectures/index.md): Add additional resources to support more users.
...@@ -92,7 +92,7 @@ Learn how to install, configure, update, and maintain your GitLab instance. ...@@ -92,7 +92,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
### Maintaining GitLab ### Maintaining GitLab
- [Rake tasks](../raketasks/README.md): Perform various tasks for maintenance, backups, automatic webhooks setup, and more. - [Rake tasks](../raketasks/index.md): Perform various tasks for maintenance, backups, automatic webhooks setup, and more.
- [Backup and restore](../raketasks/backup_restore.md): Backup and restore your GitLab instance. - [Backup and restore](../raketasks/backup_restore.md): Backup and restore your GitLab instance.
- [Operations](operations/index.md): Keeping GitLab up and running (clean up Redis sessions, moving repositories, Sidekiq MemoryKiller, Puma). - [Operations](operations/index.md): Keeping GitLab up and running (clean up Redis sessions, moving repositories, Sidekiq MemoryKiller, Puma).
- [Restart GitLab](restart_gitlab.md): Learn how to restart GitLab and its components. - [Restart GitLab](restart_gitlab.md): Learn how to restart GitLab and its components.
...@@ -103,14 +103,14 @@ Learn how to install, configure, update, and maintain your GitLab instance. ...@@ -103,14 +103,14 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [GitLab versions and maintenance policy](../policy/maintenance.md): Understand GitLab versions and releases (Major, Minor, Patch, Security), as well as update recommendations. - [GitLab versions and maintenance policy](../policy/maintenance.md): Understand GitLab versions and releases (Major, Minor, Patch, Security), as well as update recommendations.
- [GitLab in maintenance mode](maintenance_mode/index.md): Put GitLab in maintenance mode. - [GitLab in maintenance mode](maintenance_mode/index.md): Put GitLab in maintenance mode.
- [Update GitLab](../update/README.md): Update guides to upgrade your installation to a new version. - [Update GitLab](../update/index.md): Update guides to upgrade your installation to a new version.
- [Upgrading without downtime](../update/README.md#upgrading-without-downtime): Upgrade to a newer major, minor, or patch version of GitLab without taking your GitLab instance offline. - [Upgrading without downtime](../update/index.md#upgrading-without-downtime): Upgrade to a newer major, minor, or patch version of GitLab without taking your GitLab instance offline.
- [Migrate your GitLab CI/CD data to another version of GitLab](../migrate_ci_to_ce/README.md): If you have an old GitLab installation (older than 8.0), follow this guide to migrate your existing GitLab CI/CD data to another version of GitLab. - [Migrate your GitLab CI/CD data to another version of GitLab](../migrate_ci_to_ce/README.md): If you have an old GitLab installation (older than 8.0), follow this guide to migrate your existing GitLab CI/CD data to another version of GitLab.
### Upgrading or downgrading GitLab ### Upgrading or downgrading GitLab
- [Upgrade from GitLab CE to GitLab EE](../update/README.md#upgrading-between-editions): learn how to upgrade GitLab Community Edition to GitLab Enterprise Editions. - [Upgrade from GitLab CE to GitLab EE](../update/index.md#upgrading-between-editions): learn how to upgrade GitLab Community Edition to GitLab Enterprise Editions.
- [Downgrade from GitLab EE to GitLab CE](../downgrade_ee_to_ce/README.md): Learn how to downgrade GitLab Enterprise Editions to Community Edition. - [Downgrade from GitLab EE to GitLab CE](../downgrade_ee_to_ce/index.md): Learn how to downgrade GitLab Enterprise Editions to Community Edition.
### GitLab platform integrations ### GitLab platform integrations
......
...@@ -13,7 +13,7 @@ Keep your GitLab instance up and running smoothly. ...@@ -13,7 +13,7 @@ Keep your GitLab instance up and running smoothly.
you have been running a large GitLab server (thousands of users) since before you have been running a large GitLab server (thousands of users) since before
GitLab 7.3 we recommend cleaning up stale sessions to compact the Redis GitLab 7.3 we recommend cleaning up stale sessions to compact the Redis
database after you upgrade to GitLab 7.3. database after you upgrade to GitLab 7.3.
- [Rake tasks](../../raketasks/README.md): Tasks for common administration and operational processes such as - [Rake tasks](../../raketasks/index.md): Tasks for common administration and operational processes such as
[cleaning up unneeded items from GitLab instance](../../raketasks/cleanup.md), integrity checks, [cleaning up unneeded items from GitLab instance](../../raketasks/cleanup.md), integrity checks,
and more. and more.
- [Moving repositories](moving_repositories.md): Moving all repositories managed - [Moving repositories](moving_repositories.md): Moving all repositories managed
......
...@@ -292,7 +292,7 @@ sudo gitlab-rake gitlab:exclusive_lease:clear[project_housekeeping:4] ...@@ -292,7 +292,7 @@ sudo gitlab-rake gitlab:exclusive_lease:clear[project_housekeeping:4]
## Display status of database migrations ## Display status of database migrations
See the [upgrade documentation](../../update/README.md#checking-for-background-migrations-before-upgrading) See the [upgrade documentation](../../update/index.md#checking-for-background-migrations-before-upgrading)
for how to check that migrations are complete when upgrading GitLab. for how to check that migrations are complete when upgrading GitLab.
To check the status of specific migrations, you can use the following Rake task: To check the status of specific migrations, you can use the following Rake task:
......
...@@ -41,7 +41,7 @@ the swap available when needed. ...@@ -41,7 +41,7 @@ the swap available when needed.
## Setup instructions ## Setup instructions
To install GitLab for this default reference architecture, use the standard To install GitLab for this default reference architecture, use the standard
[installation instructions](../../install/README.md). [installation instructions](../../install/index.md).
You can also optionally configure GitLab to use an [external PostgreSQL service](../postgresql/external.md) You can also optionally configure GitLab to use an [external PostgreSQL service](../postgresql/external.md)
or an [external object storage service](../object_storage.md) for added or an [external object storage service](../object_storage.md) for added
......
...@@ -33,7 +33,7 @@ per 1,000 users: ...@@ -33,7 +33,7 @@ per 1,000 users:
For GitLab instances with less than 2,000 users, it's recommended that you use For GitLab instances with less than 2,000 users, it's recommended that you use
the [default setup](#automated-backups) by the [default setup](#automated-backups) by
[installing GitLab](../../install/README.md) on a single machine to minimize [installing GitLab](../../install/index.md) on a single machine to minimize
maintenance and resource costs. maintenance and resource costs.
If your organization has more than 2,000 users, the recommendation is to scale the If your organization has more than 2,000 users, the recommendation is to scale the
......
...@@ -144,7 +144,10 @@ test its execution using `CREATE INDEX CONCURRENTLY` in the `#database-lab` Slac ...@@ -144,7 +144,10 @@ test its execution using `CREATE INDEX CONCURRENTLY` in the `#database-lab` Slac
##### Query Plans ##### Query Plans
- The query plan for each raw SQL query included in the merge request along with the link to the query plan following each raw SQL snippet. - The query plan for each raw SQL query included in the merge request along with the link to the query plan following each raw SQL snippet.
- Provide the link to the plan at: [explain.depesz.com](https://explain.depesz.com). Paste both the plan and the query used in the form. - Provide a public link to the plan from either:
- [postgres.ai](https://postgres.ai/): Follow the link in `#database-lab` and generate a shareable, public link
by clicking the **Share** button in the upper right corner.
- [explain.depesz.com](https://explain.depesz.com): Paste both the plan and the query used in the form.
- When providing query plans, make sure it hits enough data: - When providing query plans, make sure it hits enough data:
- You can use a GitLab production replica to test your queries on a large scale, - You can use a GitLab production replica to test your queries on a large scale,
through the `#database-lab` Slack channel or through [ChatOps](understanding_explain_plans.md#chatops). through the `#database-lab` Slack channel or through [ChatOps](understanding_explain_plans.md#chatops).
......
--- ---
stage: none redirect_to: 'index.md'
group: unassigned
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
--- ---
# Downgrading from EE to CE This document was moved to [another location](index.md).
If you ever decide to downgrade your Enterprise Edition back to the Community <!-- This redirect file can be deleted after 2021-05-11. -->
Edition, there are a few steps you need take before installing the CE package <!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
on top of the current EE package, or, if you are in an installation from source,
before you change remotes and fetch the latest CE code.
## Disable Enterprise-only features
First thing to do is to disable the following features.
### Authentication mechanisms
Kerberos and Atlassian Crowd are only available on the Enterprise Edition, so
you should disable these mechanisms before downgrading and you should provide
alternative authentication methods to your users.
### Remove Service Integration entries from the database
The `GithubService` class is only available in the Enterprise Edition codebase,
so if you downgrade to the Community Edition, the following error displays:
```plaintext
Completed 500 Internal Server Error in 497ms (ActiveRecord: 32.2ms)
ActionView::Template::Error (The single-table inheritance mechanism failed to locate the subclass: 'GithubService'. This
error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this
column if you didn't intend it to be used for storing the inheritance class or overwrite Service.inheritance_column to
use another column for that information.)
```
All services are created automatically for every project you have, so in order
to avoid getting this error, you need to remove all instances of the
`GithubService` from your database:
**Omnibus Installation**
```shell
sudo gitlab-rails runner "Service.where(type: ['GithubService']).delete_all"
```
**Source Installation**
```shell
bundle exec rails runner "Service.where(type: ['GithubService']).delete_all" production
```
NOTE:
If you are running `GitLab =< v13.0` you need to also remove `JenkinsDeprecatedService` records
and if you are running `GitLab =< v13.6` you need to also remove `JenkinsService` records.
### Variables environment scopes
If you're using this feature and there are variables sharing the same
key, but they have different scopes in a project, then you might want to
revisit the environment scope setting for those variables.
In CE, environment scopes are completely ignored, therefore you could
accidentally get a variable which you're not expecting for a particular
environment. Make sure that you have the right variables in this case.
Data is completely preserved, so you could always upgrade back to EE and
restore the behavior if you leave it alone.
## Downgrade to CE
After performing the above mentioned steps, you are now ready to downgrade your
GitLab installation to the Community Edition.
**Omnibus Installation**
To downgrade an Omnibus installation, it is sufficient to install the Community
Edition package on top of the currently installed one. You can do this manually,
by directly [downloading the package](https://packages.gitlab.com/gitlab/gitlab-ce)
you need, or by adding our CE package repository and following the
[CE installation instructions](https://about.gitlab.com/install/?version=ce).
**Source Installation**
To downgrade a source installation, you need to replace the current remote of
your GitLab installation with the Community Edition's remote, fetch the latest
changes, and checkout the latest stable branch:
```shell
git remote set-url origin git@gitlab.com:gitlab-org/gitlab-foss.git
git fetch --all
git checkout 8-x-stable
```
Remember to follow the correct [update guides](../update/README.md) to make
sure all dependencies are up to date.
---
stage: Enablement
group: Distribution
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
---
# Downgrading from EE to CE
If you ever decide to downgrade your Enterprise Edition back to the Community
Edition, there are a few steps you need take before installing the CE package
on top of the current EE package, or, if you are in an installation from source,
before you change remotes and fetch the latest CE code.
## Disable Enterprise-only features
First thing to do is to disable the following features.
### Authentication mechanisms
Kerberos and Atlassian Crowd are only available on the Enterprise Edition, so
you should disable these mechanisms before downgrading and you should provide
alternative authentication methods to your users.
### Remove Service Integration entries from the database
The `GithubService` class is only available in the Enterprise Edition codebase,
so if you downgrade to the Community Edition, the following error displays:
```plaintext
Completed 500 Internal Server Error in 497ms (ActiveRecord: 32.2ms)
ActionView::Template::Error (The single-table inheritance mechanism failed to locate the subclass: 'GithubService'. This
error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this
column if you didn't intend it to be used for storing the inheritance class or overwrite Service.inheritance_column to
use another column for that information.)
```
All services are created automatically for every project you have, so in order
to avoid getting this error, you need to remove all instances of the
`GithubService` from your database:
**Omnibus Installation**
```shell
sudo gitlab-rails runner "Service.where(type: ['GithubService']).delete_all"
```
**Source Installation**
```shell
bundle exec rails runner "Service.where(type: ['GithubService']).delete_all" production
```
NOTE:
If you are running `GitLab =< v13.0` you need to also remove `JenkinsDeprecatedService` records
and if you are running `GitLab =< v13.6` you need to also remove `JenkinsService` records.
### Variables environment scopes
If you're using this feature and there are variables sharing the same
key, but they have different scopes in a project, then you might want to
revisit the environment scope setting for those variables.
In CE, environment scopes are completely ignored, therefore you could
accidentally get a variable which you're not expecting for a particular
environment. Make sure that you have the right variables in this case.
Data is completely preserved, so you could always upgrade back to EE and
restore the behavior if you leave it alone.
## Downgrade to CE
After performing the above mentioned steps, you are now ready to downgrade your
GitLab installation to the Community Edition.
**Omnibus Installation**
To downgrade an Omnibus installation, it is sufficient to install the Community
Edition package on top of the currently installed one. You can do this manually,
by directly [downloading the package](https://packages.gitlab.com/gitlab/gitlab-ce)
you need, or by adding our CE package repository and following the
[CE installation instructions](https://about.gitlab.com/install/?version=ce).
**Source Installation**
To downgrade a source installation, you need to replace the current remote of
your GitLab installation with the Community Edition's remote, fetch the latest
changes, and checkout the latest stable branch:
```shell
git remote set-url origin git@gitlab.com:gitlab-org/gitlab-foss.git
git fetch --all
git checkout 8-x-stable
```
Remember to follow the correct [update guides](../update/index.md) to make
sure all dependencies are up to date.
--- ---
stage: Enablement redirect_to: 'index.md'
group: Distribution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
comments: false
description: Read through the GitLab installation methods.
type: index
--- ---
# Installation **(FREE SELF)** This document was moved to [another location](index.md).
GitLab can be installed in most GNU/Linux distributions and with several <!-- This redirect file can be deleted after 2021-05-11. -->
cloud providers. To get the best experience from GitLab, you must balance <!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
performance, reliability, ease of administration (backups, upgrades, and
troubleshooting), and the cost of hosting.
Depending on your platform, select from the following available methods to
install GitLab:
- [_Omnibus GitLab_](#installing-gitlab-on-linux-using-the-omnibus-gitlab-package-recommended):
The official deb/rpm packages that contain a bundle of GitLab and the
components it depends on, including PostgreSQL, Redis, and Sidekiq.
- [_GitLab Helm chart_](#installing-gitlab-on-kubernetes-via-the-gitlab-helm-charts):
The cloud native Helm chart for installing GitLab and all of its components
on Kubernetes.
- [_Docker_](#installing-gitlab-with-docker): The Omnibus GitLab packages,
Dockerized.
- [_Source_](#installing-gitlab-from-source): Install GitLab and all of its
components from scratch.
- [_Cloud provider_](#installing-gitlab-on-cloud-providers): Install directly
from platforms like AWS, Azure, and GCP.
If you're not sure which installation method to use, we recommend you use
Omnibus GitLab. The Omnibus GitLab packages are mature,
[scalable](../administration/reference_architectures/index.md), and are used
today on GitLab.com. The Helm charts are recommended for those who are familiar
with Kubernetes.
## Requirements
Before you install GitLab, be sure to review the [system requirements](requirements.md).
The system requirements include details about the minimum hardware, software,
database, and additional requirements to support GitLab.
## Installing GitLab on Linux using the Omnibus GitLab package (recommended)
The Omnibus GitLab package uses our official deb/rpm repositories, and is
recommended for most users.
If you need additional scale or resilience, we recommend deploying
GitLab as described in our [reference architecture documentation](../administration/reference_architectures/index.md).
[**> Install GitLab using the Omnibus GitLab package.**](https://about.gitlab.com/install/)
### GitLab Environment Toolkit (alpha)
The [GitLab Environment Toolkit](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit) provides a set of automation tools to easily deploy a [reference architecture](../administration/reference_architectures/index.md) on most major cloud providers.
It is currently in alpha, and is not recommended for production use.
[**> Install a GitLab reference architecture using the GitLab Environment Toolkit.**](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit#documentation)
## Installing GitLab on Kubernetes via the GitLab Helm charts
When installing GitLab on Kubernetes, there are some trade-offs that you
need to be aware of:
- Administration and troubleshooting requires Kubernetes knowledge.
- It can be more expensive for smaller installations. The default installation
requires more resources than a single node Omnibus deployment, as most services
are deployed in a redundant fashion.
- There are some feature [limitations to be aware of](https://docs.gitlab.com/charts/#limitations).
Due to these trade-offs, having Kubernetes experience is a requirement for
using this method. We recommend being familiar with Kubernetes before using it
to deploy GitLab in production. The methods for management, observability, and
some concepts are different than traditional deployments.
[**> Install GitLab on Kubernetes using the GitLab Helm charts.**](https://docs.gitlab.com/charts/)
## Installing GitLab with Docker
GitLab maintains a set of official Docker images based on the Omnibus GitLab
package.
[**> Install GitLab using the official GitLab Docker images.**](docker.md)
## Installing GitLab from source
If the Omnibus GitLab package isn't available for your distribution, you can
install GitLab from source. This can be useful with unsupported systems, like
\*BSD. For an overview of the directory structure, see the
[structure documentation](installation.md#gitlab-directory-structure).
[**> Install GitLab from source.**](installation.md)
## Installing GitLab on cloud providers
GitLab can be installed on a variety of cloud providers by using any of
the above methods, provided the cloud provider supports it.
- [Install on AWS](aws/index.md): Install Omnibus GitLab on AWS using the community AMIs that GitLab provides.
- [Install GitLab on Google Cloud Platform](google_cloud_platform/index.md): Install Omnibus GitLab on a VM in GCP.
- [Install GitLab on Azure](azure/index.md): Install Omnibus GitLab from Azure Marketplace.
- [Install GitLab on OpenShift](https://docs.gitlab.com/charts/installation/cloud/openshift.html): Install GitLab on OpenShift by using the GitLab Helm charts.
- [Install GitLab on DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-gitlab-on-ubuntu-18-04): Install Omnibus GitLab on DigitalOcean.
- _Testing only!_ [DigitalOcean and Docker Machine](digitaloceandocker.md):
Quickly test any version of GitLab on DigitalOcean using Docker Machine.
## Next steps
Here are a few resources you might want to check out after completing the
installation:
- [Upload a license](../user/admin_area/license.md) or [start a free trial](https://about.gitlab.com/free-trial/):
Activate all GitLab Enterprise Edition functionality with a license.
- [Set up runners](https://docs.gitlab.com/runner/): Set up one or more GitLab
Runners, the agents that are responsible for all of the GitLab CI/CD features.
- [GitLab Pages](../administration/pages/index.md): Configure GitLab Pages to
allow hosting of static sites.
- [GitLab Registry](../administration/packages/container_registry.md): With the
GitLab Container Registry, every project can have its own space to store Docker
images.
- [Secure GitLab](../security/README.md#securing-your-gitlab-installation):
Recommended practices to secure your GitLab instance.
- [SMTP](https://docs.gitlab.com/omnibus/settings/smtp.html): Configure SMTP
for proper email notifications support.
- [LDAP](../administration/auth/ldap/index.md): Configure LDAP to be used as
an authentication mechanism for GitLab.
- [Back up and restore GitLab](../raketasks/backup_restore.md): Learn the different
ways you can back up or restore GitLab.
- [Upgrade GitLab](../update/README.md): Every 22nd of the month, a new feature-rich GitLab version
is released. Learn how to upgrade to it, or to an interim release that contains a security fix.
- [Scaling GitLab](../administration/reference_architectures/index.md):
GitLab supports several different types of clustering.
- [Advanced Search](../integration/elasticsearch.md): Leverage Elasticsearch for
faster, more advanced code search across your entire GitLab instance.
- [Geo replication](../administration/geo/index.md):
Geo is the solution for widely distributed development teams.
- [Release and maintenance policy](../policy/maintenance.md): Learn about GitLab
policies governing version naming, as well as release pace for major, minor, patch,
and security releases.
- [Pricing](https://about.gitlab.com/pricing/): Pricing for the different tiers.
---
stage: Enablement
group: Distribution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
comments: false
description: Read through the GitLab installation methods.
type: index
---
# Installation **(FREE SELF)**
GitLab can be installed in most GNU/Linux distributions and with several
cloud providers. To get the best experience from GitLab, you must balance
performance, reliability, ease of administration (backups, upgrades, and
troubleshooting), and the cost of hosting.
Depending on your platform, select from the following available methods to
install GitLab:
- [_Omnibus GitLab_](#installing-gitlab-on-linux-using-the-omnibus-gitlab-package-recommended):
The official deb/rpm packages that contain a bundle of GitLab and the
components it depends on, including PostgreSQL, Redis, and Sidekiq.
- [_GitLab Helm chart_](#installing-gitlab-on-kubernetes-via-the-gitlab-helm-charts):
The cloud native Helm chart for installing GitLab and all of its components
on Kubernetes.
- [_Docker_](#installing-gitlab-with-docker): The Omnibus GitLab packages,
Dockerized.
- [_Source_](#installing-gitlab-from-source): Install GitLab and all of its
components from scratch.
- [_Cloud provider_](#installing-gitlab-on-cloud-providers): Install directly
from platforms like AWS, Azure, and GCP.
If you're not sure which installation method to use, we recommend you use
Omnibus GitLab. The Omnibus GitLab packages are mature,
[scalable](../administration/reference_architectures/index.md), and are used
today on GitLab.com. The Helm charts are recommended for those who are familiar
with Kubernetes.
## Requirements
Before you install GitLab, be sure to review the [system requirements](requirements.md).
The system requirements include details about the minimum hardware, software,
database, and additional requirements to support GitLab.
## Installing GitLab on Linux using the Omnibus GitLab package (recommended)
The Omnibus GitLab package uses our official deb/rpm repositories, and is
recommended for most users.
If you need additional scale or resilience, we recommend deploying
GitLab as described in our [reference architecture documentation](../administration/reference_architectures/index.md).
[**> Install GitLab using the Omnibus GitLab package.**](https://about.gitlab.com/install/)
### GitLab Environment Toolkit (alpha)
The [GitLab Environment Toolkit](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit) provides a set of automation tools to easily deploy a [reference architecture](../administration/reference_architectures/index.md) on most major cloud providers.
It is currently in alpha, and is not recommended for production use.
[**> Install a GitLab reference architecture using the GitLab Environment Toolkit.**](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit#documentation)
## Installing GitLab on Kubernetes via the GitLab Helm charts
When installing GitLab on Kubernetes, there are some trade-offs that you
need to be aware of:
- Administration and troubleshooting requires Kubernetes knowledge.
- It can be more expensive for smaller installations. The default installation
requires more resources than a single node Omnibus deployment, as most services
are deployed in a redundant fashion.
- There are some feature [limitations to be aware of](https://docs.gitlab.com/charts/#limitations).
Due to these trade-offs, having Kubernetes experience is a requirement for
using this method. We recommend being familiar with Kubernetes before using it
to deploy GitLab in production. The methods for management, observability, and
some concepts are different than traditional deployments.
[**> Install GitLab on Kubernetes using the GitLab Helm charts.**](https://docs.gitlab.com/charts/)
## Installing GitLab with Docker
GitLab maintains a set of official Docker images based on the Omnibus GitLab
package.
[**> Install GitLab using the official GitLab Docker images.**](docker.md)
## Installing GitLab from source
If the Omnibus GitLab package isn't available for your distribution, you can
install GitLab from source. This can be useful with unsupported systems, like
\*BSD. For an overview of the directory structure, see the
[structure documentation](installation.md#gitlab-directory-structure).
[**> Install GitLab from source.**](installation.md)
## Installing GitLab on cloud providers
GitLab can be installed on a variety of cloud providers by using any of
the above methods, provided the cloud provider supports it.
- [Install on AWS](aws/index.md): Install Omnibus GitLab on AWS using the community AMIs that GitLab provides.
- [Install GitLab on Google Cloud Platform](google_cloud_platform/index.md): Install Omnibus GitLab on a VM in GCP.
- [Install GitLab on Azure](azure/index.md): Install Omnibus GitLab from Azure Marketplace.
- [Install GitLab on OpenShift](https://docs.gitlab.com/charts/installation/cloud/openshift.html): Install GitLab on OpenShift by using the GitLab Helm charts.
- [Install GitLab on DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-gitlab-on-ubuntu-18-04): Install Omnibus GitLab on DigitalOcean.
- _Testing only!_ [DigitalOcean and Docker Machine](digitaloceandocker.md):
Quickly test any version of GitLab on DigitalOcean using Docker Machine.
## Next steps
Here are a few resources you might want to check out after completing the
installation:
- [Upload a license](../user/admin_area/license.md) or [start a free trial](https://about.gitlab.com/free-trial/):
Activate all GitLab Enterprise Edition functionality with a license.
- [Set up runners](https://docs.gitlab.com/runner/): Set up one or more GitLab
Runners, the agents that are responsible for all of the GitLab CI/CD features.
- [GitLab Pages](../administration/pages/index.md): Configure GitLab Pages to
allow hosting of static sites.
- [GitLab Registry](../administration/packages/container_registry.md): With the
GitLab Container Registry, every project can have its own space to store Docker
images.
- [Secure GitLab](../security/README.md#securing-your-gitlab-installation):
Recommended practices to secure your GitLab instance.
- [SMTP](https://docs.gitlab.com/omnibus/settings/smtp.html): Configure SMTP
for proper email notifications support.
- [LDAP](../administration/auth/ldap/index.md): Configure LDAP to be used as
an authentication mechanism for GitLab.
- [Back up and restore GitLab](../raketasks/backup_restore.md): Learn the different
ways you can back up or restore GitLab.
- [Upgrade GitLab](../update/index.md): Every 22nd of the month, a new feature-rich GitLab version
is released. Learn how to upgrade to it, or to an interim release that contains a security fix.
- [Scaling GitLab](../administration/reference_architectures/index.md):
GitLab supports several different types of clustering.
- [Advanced Search](../integration/elasticsearch.md): Leverage Elasticsearch for
faster, more advanced code search across your entire GitLab instance.
- [Geo replication](../administration/geo/index.md):
Geo is the solution for widely distributed development teams.
- [Release and maintenance policy](../policy/maintenance.md): Learn about GitLab
policies governing version naming, as well as release pace for major, minor, patch,
and security releases.
- [Pricing](https://about.gitlab.com/pricing/): Pricing for the different tiers.
...@@ -9,7 +9,7 @@ type: howto ...@@ -9,7 +9,7 @@ type: howto
This is the official installation guide to set up a production GitLab server This is the official installation guide to set up a production GitLab server
using the source files. To set up a **development installation** or for many using the source files. To set up a **development installation** or for many
other installation options, see the [main installation page](README.md). other installation options, see the [main installation page](index.md).
It was created for and tested on **Debian/Ubuntu** operating systems. It was created for and tested on **Debian/Ubuntu** operating systems.
Read [requirements.md](requirements.md) for hardware and operating system requirements. Read [requirements.md](requirements.md) for hardware and operating system requirements.
If you want to install on RHEL/CentOS, we recommend using the If you want to install on RHEL/CentOS, we recommend using the
......
...@@ -22,7 +22,7 @@ as the hardware requirements that are needed to install and use GitLab. ...@@ -22,7 +22,7 @@ as the hardware requirements that are needed to install and use GitLab.
- Scientific Linux (please use the CentOS packages and instructions) - Scientific Linux (please use the CentOS packages and instructions)
- Oracle Linux (please use the CentOS packages and instructions) - Oracle Linux (please use the CentOS packages and instructions)
For the installation options, see [the main installation page](README.md). For the installation options, see [the main installation page](index.md).
### Unsupported Linux distributions and Unix-like operating systems ### Unsupported Linux distributions and Unix-like operating systems
......
...@@ -236,6 +236,18 @@ It can be set to: ...@@ -236,6 +236,18 @@ It can be set to:
of specific users IDs to enable the feature for. of specific users IDs to enable the feature for.
- [User IDs](#user-ids) - [User IDs](#user-ids)
## Legacy feature flag migration
Legacy feature flags became read-only in GitLab 13.4. GitLab 14.0 removes support for legacy feature
flags. You must migrate your legacy feature flags to the new version. To do so, follow these steps:
1. Take a screenshot of the legacy flag for tracking.
1. Delete the flag through the API or UI (you don't need to alter the code).
1. Create a new feature flag with the same name as the legacy flag you deleted. Make sure the
strategies and environments match the deleted flag.
See [this video tutorial](https://www.youtube.com/watch?v=CAJY2IGep7Y) for help with this migration.
## Disable a feature flag for a specific environment ## Disable a feature flag for a specific environment
In [GitLab 13.0 and earlier](https://gitlab.com/gitlab-org/gitlab/-/issues/8621), In [GitLab 13.0 and earlier](https://gitlab.com/gitlab-org/gitlab/-/issues/8621),
......
...@@ -74,7 +74,7 @@ A step-by-step guide to [upgrading the Omnibus-bundled PostgreSQL is documented ...@@ -74,7 +74,7 @@ A step-by-step guide to [upgrading the Omnibus-bundled PostgreSQL is documented
## Upgrading major versions ## Upgrading major versions
Backward-incompatible changes and migrations are reserved for major versions. See the [upgrade guide](../update/README.md#upgrading-to-a-new-major-version). Backward-incompatible changes and migrations are reserved for major versions. See the [upgrade guide](../update/index.md#upgrading-to-a-new-major-version).
## Patch releases ## Patch releases
......
--- ---
stage: none redirect_to: 'index.md'
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
comments: false
--- ---
# Rake tasks **(FREE SELF)** This document was moved to [another location](index.md).
GitLab provides [Rake](https://ruby.github.io/rake/) tasks for common administration and operational processes. <!-- This redirect file can be deleted after 2021-05-11. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
GitLab Rake tasks are performed using:
- `gitlab-rake <raketask>` for [Omnibus GitLab](https://docs.gitlab.com/omnibus/README.html) installations.
- `bundle exec rake <raketask>` for [source](../install/installation.md) installations.
## Available Rake tasks
The following are available Rake tasks:
| Tasks | Description |
|:----------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------|
| [Back up and restore](backup_restore.md) | Back up, restore, and migrate GitLab instances between servers. |
| [Clean up](cleanup.md) | Clean up unneeded items from GitLab instances. |
| [Development](../development/rake_tasks.md) | Tasks for GitLab contributors. |
| [Doctor tasks](../administration/raketasks/doctor.md) | Checks for data integrity issues. |
| [Elasticsearch](../integration/elasticsearch.md#gitlab-advanced-search-rake-tasks) **(PREMIUM SELF)** | Maintain Elasticsearch in a GitLab instance. |
| [Enable namespaces](features.md) | Enable usernames and namespaces for user projects. |
| [General maintenance](../administration/raketasks/maintenance.md) | General maintenance and self-check tasks. |
| [Geo maintenance](../administration/raketasks/geo.md) **(PREMIUM SELF)** | [Geo](../administration/geo/index.md)-related maintenance. |
| [GitHub import](../administration/raketasks/github_import.md) | Retrieve and import repositories from GitHub. |
| [Import repositories](import.md) | Import bare repositories into your GitLab instance. |
| [Import large project exports](../development/import_project.md#importing-via-a-rake-task) | Import large GitLab [project exports](../user/project/settings/import_export.md). |
| [Integrity checks](../administration/raketasks/check.md) | Check the integrity of repositories, files, and LDAP. |
| [LDAP maintenance](../administration/raketasks/ldap.md) | [LDAP](../administration/auth/ldap/index.md)-related tasks. |
| [List repositories](list_repos.md) | List of all GitLab-managed Git repositories on disk. |
| [Migrate Snippets to Git](migrate_snippets.md) | Migrate GitLab Snippets to Git repositories and show migration status |
| [Praefect Rake tasks](../administration/raketasks/praefect.md) | [Praefect](../administration/gitaly/praefect.md)-related tasks. |
| [Project import/export](../administration/raketasks/project_import_export.md) | Prepare for [project exports and imports](../user/project/settings/import_export.md). |
| [Sample Prometheus data](generate_sample_prometheus_data.md) | Generate sample Prometheus data. |
| [SPDX license list import](spdx.md) **(PREMIUM SELF)** | Import a local copy of the [SPDX license list](https://spdx.org/licenses/) for matching [License Compliance policies](../user/compliance/license_compliance/index.md).| |
| [Repository storage](../administration/raketasks/storage.md) | List and migrate existing projects and attachments from legacy storage to hashed storage. |
| [Uploads migrate](../administration/raketasks/uploads/migrate.md) | Migrate uploads between storage local and object storage. |
| [Uploads sanitize](../administration/raketasks/uploads/sanitize.md) | Remove EXIF data from images uploaded to earlier versions of GitLab. |
| [Usage data](../administration/troubleshooting/gitlab_rails_cheat_sheet.md#generate-usage-ping) | Generate and troubleshoot [Usage Ping](../development/usage_ping.md).|
| [User management](user_management.md) | Perform user management tasks. |
| [Webhooks administration](web_hooks.md) | Maintain project Webhooks. |
| [X.509 signatures](x509_signatures.md) | Update X.509 commit signatures, useful if certificate store has changed. |
...@@ -1024,7 +1024,7 @@ restoring a single project or group, you can use a workaround by restoring ...@@ -1024,7 +1024,7 @@ restoring a single project or group, you can use a workaround by restoring
your backup to a separate, temporary GitLab instance, and then export your your backup to a separate, temporary GitLab instance, and then export your
project or group from there: project or group from there:
1. [Install a new GitLab](../install/README.md) instance at the same version as 1. [Install a new GitLab](../install/index.md) instance at the same version as
the backed-up instance from which you want to restore. the backed-up instance from which you want to restore.
1. [Restore the backup](#restore-gitlab) into this new instance, then 1. [Restore the backup](#restore-gitlab) into this new instance, then
export your [project](../user/project/settings/import_export.md) export your [project](../user/project/settings/import_export.md)
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
comments: false
---
# Rake tasks **(FREE SELF)**
GitLab provides [Rake](https://ruby.github.io/rake/) tasks for common administration and operational processes.
GitLab Rake tasks are performed using:
- `gitlab-rake <raketask>` for [Omnibus GitLab](https://docs.gitlab.com/omnibus/README.html) installations.
- `bundle exec rake <raketask>` for [source](../install/installation.md) installations.
## Available Rake tasks
The following are available Rake tasks:
| Tasks | Description |
|:----------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------|
| [Back up and restore](backup_restore.md) | Back up, restore, and migrate GitLab instances between servers. |
| [Clean up](cleanup.md) | Clean up unneeded items from GitLab instances. |
| [Development](../development/rake_tasks.md) | Tasks for GitLab contributors. |
| [Doctor tasks](../administration/raketasks/doctor.md) | Checks for data integrity issues. |
| [Elasticsearch](../integration/elasticsearch.md#gitlab-advanced-search-rake-tasks) **(PREMIUM SELF)** | Maintain Elasticsearch in a GitLab instance. |
| [Enable namespaces](features.md) | Enable usernames and namespaces for user projects. |
| [General maintenance](../administration/raketasks/maintenance.md) | General maintenance and self-check tasks. |
| [Geo maintenance](../administration/raketasks/geo.md) **(PREMIUM SELF)** | [Geo](../administration/geo/index.md)-related maintenance. |
| [GitHub import](../administration/raketasks/github_import.md) | Retrieve and import repositories from GitHub. |
| [Import repositories](import.md) | Import bare repositories into your GitLab instance. |
| [Import large project exports](../development/import_project.md#importing-via-a-rake-task) | Import large GitLab [project exports](../user/project/settings/import_export.md). |
| [Integrity checks](../administration/raketasks/check.md) | Check the integrity of repositories, files, and LDAP. |
| [LDAP maintenance](../administration/raketasks/ldap.md) | [LDAP](../administration/auth/ldap/index.md)-related tasks. |
| [List repositories](list_repos.md) | List of all GitLab-managed Git repositories on disk. |
| [Migrate Snippets to Git](migrate_snippets.md) | Migrate GitLab Snippets to Git repositories and show migration status |
| [Praefect Rake tasks](../administration/raketasks/praefect.md) | [Praefect](../administration/gitaly/praefect.md)-related tasks. |
| [Project import/export](../administration/raketasks/project_import_export.md) | Prepare for [project exports and imports](../user/project/settings/import_export.md). |
| [Sample Prometheus data](generate_sample_prometheus_data.md) | Generate sample Prometheus data. |
| [SPDX license list import](spdx.md) **(PREMIUM SELF)** | Import a local copy of the [SPDX license list](https://spdx.org/licenses/) for matching [License Compliance policies](../user/compliance/license_compliance/index.md).| |
| [Repository storage](../administration/raketasks/storage.md) | List and migrate existing projects and attachments from legacy storage to hashed storage. |
| [Uploads migrate](../administration/raketasks/uploads/migrate.md) | Migrate uploads between storage local and object storage. |
| [Uploads sanitize](../administration/raketasks/uploads/sanitize.md) | Remove EXIF data from images uploaded to earlier versions of GitLab. |
| [Usage data](../administration/troubleshooting/gitlab_rails_cheat_sheet.md#generate-usage-ping) | Generate and troubleshoot [Usage Ping](../development/usage_ping.md).|
| [User management](user_management.md) | Perform user management tasks. |
| [Webhooks administration](web_hooks.md) | Maintain project Webhooks. |
| [X.509 signatures](x509_signatures.md) | Update X.509 commit signatures, useful if certificate store has changed. |
...@@ -19,6 +19,6 @@ tutorials, technical overviews, blog posts) and videos. ...@@ -19,6 +19,6 @@ tutorials, technical overviews, blog posts) and videos.
- [Cron](cron/index.md) - [Cron](cron/index.md)
- [Git](git/index.md) - [Git](git/index.md)
- [GitLab Flow](gitlab_flow.md) - [GitLab Flow](gitlab_flow.md)
- [GitLab Installation](../install/README.md) - [GitLab Installation](../install/index.md)
- [GitLab Pages](../user/project/pages/index.md) - [GitLab Pages](../user/project/pages/index.md)
- [Offline GitLab](offline/index.md) - [Offline GitLab](offline/index.md)
This diff is collapsed.
This diff is collapsed.
...@@ -35,7 +35,7 @@ to identify the ideal upgrade path. ...@@ -35,7 +35,7 @@ to identify the ideal upgrade path.
Before upgrading to a new major version, you should ensure that any background Before upgrading to a new major version, you should ensure that any background
migration jobs from previous releases have been completed. To see the current size of the `background_migration` queue, migration jobs from previous releases have been completed. To see the current size of the `background_migration` queue,
[Check for background migrations before upgrading](README.md#checking-for-background-migrations-before-upgrading). [Check for background migrations before upgrading](index.md#checking-for-background-migrations-before-upgrading).
## Guidelines for all versions ## Guidelines for all versions
......
...@@ -13,7 +13,7 @@ you are running. To verify, sign in to GitLab and browse to `/help`. The GitLab ...@@ -13,7 +13,7 @@ you are running. To verify, sign in to GitLab and browse to `/help`. The GitLab
are listed at the top of the **Help** page. are listed at the top of the **Help** page.
If you are running GitLab Community Edition (CE), upgrade your installation to If you are running GitLab Community Edition (CE), upgrade your installation to
GitLab Enterprise Edition (EE). For more details, see [Upgrading between editions](../../update/README.md#upgrading-between-editions). GitLab Enterprise Edition (EE). For more details, see [Upgrading between editions](../../update/index.md#upgrading-between-editions).
If you have questions or need assistance upgrading from GitLab CE to EE please [contact GitLab Support](https://about.gitlab.com/support/#contact-support). If you have questions or need assistance upgrading from GitLab CE to EE please [contact GitLab Support](https://about.gitlab.com/support/#contact-support).
The license is a base64-encoded ASCII text file with a `.gitlab-license` The license is a base64-encoded ASCII text file with a `.gitlab-license`
...@@ -133,7 +133,7 @@ The banner disappears after the new license becomes active. ...@@ -133,7 +133,7 @@ The banner disappears after the new license becomes active.
### There is no License tab in the Admin Area ### There is no License tab in the Admin Area
If you originally installed Community Edition rather than Enterprise Edition you must If you originally installed Community Edition rather than Enterprise Edition you must
[upgrade to Enterprise Edition](../../update/README.md#community-to-enterprise-edition) [upgrade to Enterprise Edition](../../update/index.md#community-to-enterprise-edition)
before uploading your license. before uploading your license.
GitLab.com users can't upload and use a self-managed license. If you GitLab.com users can't upload and use a self-managed license. If you
......
...@@ -35,8 +35,8 @@ import { ...@@ -35,8 +35,8 @@ import {
TYPE_SITE_PROFILE, TYPE_SITE_PROFILE,
TYPE_SCANNER_PROFILE, TYPE_SCANNER_PROFILE,
} from '../settings'; } from '../settings';
import dastScanCreateMutation from '../graphql/dast_scan_create.mutation.graphql'; import dastProfileCreateMutation from '../graphql/dast_profile_create.mutation.graphql';
import dastScanUpdateMutation from '../graphql/dast_scan_update.mutation.graphql'; import dastProfileUpdateMutation from '../graphql/dast_profile_update.mutation.graphql';
import dastOnDemandScanCreateMutation from '../graphql/dast_on_demand_scan_create.mutation.graphql'; import dastOnDemandScanCreateMutation from '../graphql/dast_on_demand_scan_create.mutation.graphql';
import ProfileSelectorSummaryCell from './profile_selector/summary_cell.vue'; import ProfileSelectorSummaryCell from './profile_selector/summary_cell.vue';
import ScannerProfileSelector from './profile_selector/scanner_profile_selector.vue'; import ScannerProfileSelector from './profile_selector/scanner_profile_selector.vue';
...@@ -252,15 +252,15 @@ export default { ...@@ -252,15 +252,15 @@ export default {
this.loading = button; this.loading = button;
this.hideErrors(); this.hideErrors();
let mutation = dastOnDemandScanCreateMutation; let mutation = dastOnDemandScanCreateMutation;
let reponseType = 'dastOnDemandScanCreate'; let responseType = 'dastOnDemandScanCreate';
let input = { let input = {
fullPath: this.projectPath, fullPath: this.projectPath,
dastScannerProfileId: this.selectedScannerProfile.id, dastScannerProfileId: this.selectedScannerProfile.id,
dastSiteProfileId: this.selectedSiteProfile.id, dastSiteProfileId: this.selectedSiteProfile.id,
}; };
if (this.glFeatures.dastSavedScans) { if (this.glFeatures.dastSavedScans) {
mutation = this.isEdit ? dastScanUpdateMutation : dastScanCreateMutation; mutation = this.isEdit ? dastProfileUpdateMutation : dastProfileCreateMutation;
reponseType = this.isEdit ? 'dastScanUpdate' : 'dastScanCreate'; responseType = this.isEdit ? 'dastProfileUpdate' : 'dastProfileCreate';
input = { input = {
...input, ...input,
...(this.isEdit ? { id: this.dastScan.id } : {}), ...(this.isEdit ? { id: this.dastScan.id } : {}),
...@@ -278,13 +278,13 @@ export default { ...@@ -278,13 +278,13 @@ export default {
}, },
}) })
.then(({ data }) => { .then(({ data }) => {
const response = data[reponseType]; const response = data[responseType];
const { errors } = response; const { errors } = response;
if (errors?.length) { if (errors?.length) {
this.showErrors(ERROR_RUN_SCAN, errors); this.showErrors(ERROR_RUN_SCAN, errors);
this.loading = false; this.loading = false;
} else if (this.glFeatures.dastSavedScans && !runAfterCreate) { } else if (this.glFeatures.dastSavedScans && !runAfterCreate) {
redirectTo(response.dastScan.editPath); redirectTo(response.dastProfile.editPath);
} else { } else {
redirectTo(response.pipelineUrl); redirectTo(response.pipelineUrl);
} }
......
mutation dastProfileCreate($input: DastProfileCreateInput!) {
dastProfileCreate(input: $input) {
dastProfile {
editPath
}
pipelineUrl
errors
}
}
mutation dastProfileUpdate($input: DastProfileUpdateInput!) {
dastProfileUpdate(input: $input) {
dastProfile {
editPath
}
pipelineUrl
errors
}
}
mutation dastScanCreate(
$fullPath: ID!
$name: String!
$description: String
$dastSiteProfileId: DastSiteProfileID!
$dastScannerProfileID: DastScannerProfileID!
$runAfterCreate: Boolean
) {
dastScanCreate(
input: {
fullPath: $fullPath
name: $name
description: $description
dastSiteProfileId: $dastSiteProfileId
dastScannerProfileID: $dastScannerProfileID
runAfterCreate: $runAfterCreate
}
) {
dastScan {
editPath
}
pipelineUrl
errors
}
}
mutation dastScanUpdate(
$id: DastScanID!
$fullPath: ID!
$name: String!
$description: String
$dastSiteProfileId: DastSiteProfileID!
$dastScannerProfileID: DastScannerProfileID!
$runAfterCreate: Boolean
) {
dastScanUpdate(
input: {
id: $id
fullPath: $fullPath
name: $name
description: $description
dastSiteProfileId: $dastSiteProfileId
dastScannerProfileID: $dastScannerProfileID
runAfterCreate: $runAfterCreate
}
) @client {
dastScan {
editPath
}
pipelineUrl
errors
}
}
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql" #import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
query DastSavedScans($fullPath: ID!, $after: String, $before: String, $first: Int, $last: Int) { query DastProfiles($fullPath: ID!, $after: String, $before: String, $first: Int, $last: Int) {
project @client { project(fullPath: $fullPath) {
savedScans(after: $after, before: $before, first: $first, last: $last) { dastProfiles(after: $after, before: $before, first: $first, last: $last) {
pageInfo { pageInfo {
...PageInfo ...PageInfo
} }
......
/* eslint-disable @gitlab/require-i18n-strings */
import Vue from 'vue'; import Vue from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import { range } from 'lodash';
import createDefaultClient from '~/lib/graphql'; import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo); Vue.use(VueApollo);
// NOTE: We currently mock some fake DAST scans while the feature is feature-flagged and the
// backend is being worked on.
// This will be cleaned up as part of https://gitlab.com/gitlab-org/gitlab/-/issues/295248.
let id = 0;
const generateFakeDastScan = () => {
id += 1;
return {
node: {
id,
name: `My daily scan #${id}`,
description: 'Tests for SQL injection',
dastSiteProfile: {
id,
targetUrl: 'http://example.com ',
__typename: 'DastSiteProfile',
},
dastScannerProfile: {
id,
scanType: Math.random() < 0.5 ? 'PASSIVE' : 'ACTIVE',
__typename: 'DastScannerProfile',
},
editPath: '/on_demand_scans/1/edit',
__typename: 'DastSavedScan',
},
__typename: 'DastSavedScanEdge',
};
};
const resolvers = {
Query: {
project: () => ({
__typename: 'Project',
savedScans: {
pageInfo: {
hasNextPage: true,
hasPreviousPage: false,
startCursor: 'startCursor',
endCursor: 'endCursor',
__typename: 'PageInfo',
},
edges: range(10).map(generateFakeDastScan),
__typename: 'DastSavedScanConnection',
},
}),
},
};
export default new VueApollo({ export default new VueApollo({
defaultClient: createDefaultClient(resolvers, { defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
assumeImmutableResults: true,
}),
}); });
import dastSavedScansQuery from 'ee/security_configuration/dast_profiles/graphql/dast_saved_scans.query.graphql'; import dastProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_profiles.query.graphql';
import dastSavedScansDelete from 'ee/security_configuration/dast_profiles/graphql/dast_saved_scans_delete.mutation.graphql'; import dastSavedScansDelete from 'ee/security_configuration/dast_profiles/graphql/dast_saved_scans_delete.mutation.graphql';
import dastSiteProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_site_profiles.query.graphql'; import dastSiteProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_site_profiles.query.graphql';
import dastSiteProfilesDelete from 'ee/security_configuration/dast_profiles/graphql/dast_site_profiles_delete.mutation.graphql'; import dastSiteProfilesDelete from 'ee/security_configuration/dast_profiles/graphql/dast_site_profiles_delete.mutation.graphql';
...@@ -13,11 +13,11 @@ import { s__ } from '~/locale'; ...@@ -13,11 +13,11 @@ import { s__ } from '~/locale';
export const getProfileSettings = ({ createNewProfilePaths, isDastSavedScansEnabled }) => ({ export const getProfileSettings = ({ createNewProfilePaths, isDastSavedScansEnabled }) => ({
...(isDastSavedScansEnabled ...(isDastSavedScansEnabled
? { ? {
savedScans: { dastProfiles: {
profileType: 'savedScans', profileType: 'dastProfiles',
createNewProfilePath: createNewProfilePaths.savedScan, createNewProfilePath: createNewProfilePaths.savedScan,
graphQL: { graphQL: {
query: dastSavedScansQuery, query: dastProfilesQuery,
deletion: { deletion: {
mutation: dastSavedScansDelete, mutation: dastSavedScansDelete,
optimisticResponse: dastProfilesDeleteResponse({ optimisticResponse: dastProfilesDeleteResponse({
......
...@@ -6,8 +6,8 @@ import createApolloProvider from 'helpers/mock_apollo_helper'; ...@@ -6,8 +6,8 @@ import createApolloProvider from 'helpers/mock_apollo_helper';
import OnDemandScansForm from 'ee/on_demand_scans/components/on_demand_scans_form.vue'; import OnDemandScansForm from 'ee/on_demand_scans/components/on_demand_scans_form.vue';
import ScannerProfileSelector from 'ee/on_demand_scans/components/profile_selector/scanner_profile_selector.vue'; import ScannerProfileSelector from 'ee/on_demand_scans/components/profile_selector/scanner_profile_selector.vue';
import SiteProfileSelector from 'ee/on_demand_scans/components/profile_selector/site_profile_selector.vue'; import SiteProfileSelector from 'ee/on_demand_scans/components/profile_selector/site_profile_selector.vue';
import dastScanCreateMutation from 'ee/on_demand_scans/graphql/dast_scan_create.mutation.graphql'; import dastProfileCreateMutation from 'ee/on_demand_scans/graphql/dast_profile_create.mutation.graphql';
import dastScanUpdateMutation from 'ee/on_demand_scans/graphql/dast_scan_update.mutation.graphql'; import dastProfileUpdateMutation from 'ee/on_demand_scans/graphql/dast_profile_update.mutation.graphql';
import dastOnDemandScanCreateMutation from 'ee/on_demand_scans/graphql/dast_on_demand_scan_create.mutation.graphql'; import dastOnDemandScanCreateMutation from 'ee/on_demand_scans/graphql/dast_on_demand_scan_create.mutation.graphql';
import dastScannerProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_scanner_profiles.query.graphql'; import dastScannerProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_scanner_profiles.query.graphql';
import dastSiteProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_site_profiles.query.graphql'; import dastSiteProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_site_profiles.query.graphql';
...@@ -79,8 +79,8 @@ describe('OnDemandScansForm', () => { ...@@ -79,8 +79,8 @@ describe('OnDemandScansForm', () => {
const setupSuccess = ({ edit = false } = {}) => { const setupSuccess = ({ edit = false } = {}) => {
jest.spyOn(subject.vm.$apollo, 'mutate').mockResolvedValue({ jest.spyOn(subject.vm.$apollo, 'mutate').mockResolvedValue({
data: { data: {
[edit ? 'dastScanUpdate' : 'dastScanCreate']: { [edit ? 'dastProfileUpdate' : 'dastProfileCreate']: {
dastScan: { editPath }, dastProfile: { editPath },
pipelineUrl, pipelineUrl,
errors: [], errors: [],
}, },
...@@ -265,9 +265,9 @@ describe('OnDemandScansForm', () => { ...@@ -265,9 +265,9 @@ describe('OnDemandScansForm', () => {
expect(saveButton.props('disabled')).toBe(!saveButtonLoading); expect(saveButton.props('disabled')).toBe(!saveButtonLoading);
}); });
it(`triggers dastScanCreateMutation mutation with runAfterCreate set to ${runAfterCreate}`, async () => { it(`triggers dastProfileCreateMutation mutation with runAfterCreate set to ${runAfterCreate}`, () => {
expect(subject.vm.$apollo.mutate).toHaveBeenCalledWith({ expect(subject.vm.$apollo.mutate).toHaveBeenCalledWith({
mutation: dastScanCreateMutation, mutation: dastProfileCreateMutation,
variables: { variables: {
input: { input: {
name: 'My daily scan', name: 'My daily scan',
...@@ -301,9 +301,9 @@ describe('OnDemandScansForm', () => { ...@@ -301,9 +301,9 @@ describe('OnDemandScansForm', () => {
actionFunction(); actionFunction();
}); });
it(`triggers dastScanUpdateMutation mutation with runAfterCreate set to ${runAfterCreate}`, async () => { it(`triggers dastProfileUpdateMutation mutation with runAfterCreate set to ${runAfterCreate}`, async () => {
expect(subject.vm.$apollo.mutate).toHaveBeenCalledWith({ expect(subject.vm.$apollo.mutate).toHaveBeenCalledWith({
mutation: dastScanUpdateMutation, mutation: dastProfileUpdateMutation,
variables: { variables: {
input: { input: {
id: 1, id: 1,
...@@ -356,7 +356,7 @@ describe('OnDemandScansForm', () => { ...@@ -356,7 +356,7 @@ describe('OnDemandScansForm', () => {
mountShallowSubject(); mountShallowSubject();
jest jest
.spyOn(subject.vm.$apollo, 'mutate') .spyOn(subject.vm.$apollo, 'mutate')
.mockResolvedValue({ data: { dastScanCreate: { pipelineUrl: null, errors } } }); .mockResolvedValue({ data: { dastProfileCreate: { pipelineUrl: null, errors } } });
await setValidFormData(); await setValidFormData();
submitForm(); submitForm();
}); });
......
...@@ -26,7 +26,7 @@ describe('EE - DastProfiles', () => { ...@@ -26,7 +26,7 @@ describe('EE - DastProfiles', () => {
const defaultMocks = { const defaultMocks = {
$apollo: { $apollo: {
queries: { queries: {
savedScans: { dastProfiles: {
fetchMore: jest.fn().mockResolvedValue(), fetchMore: jest.fn().mockResolvedValue(),
}, },
siteProfiles: { siteProfiles: {
...@@ -139,7 +139,7 @@ describe('EE - DastProfiles', () => { ...@@ -139,7 +139,7 @@ describe('EE - DastProfiles', () => {
describe.each` describe.each`
tabName | index | givenLocationHash tabName | index | givenLocationHash
${'Saved Scans'} | ${0} | ${'saved-scans'} ${'Saved Scans'} | ${0} | ${'dast-profiles'}
${'Site Profiles'} | ${1} | ${'site-profiles'} ${'Site Profiles'} | ${1} | ${'site-profiles'}
${'Scanner Profiles'} | ${2} | ${'scanner-profiles'} ${'Scanner Profiles'} | ${2} | ${'scanner-profiles'}
`('with location hash set to "$givenLocationHash"', ({ tabName, index, givenLocationHash }) => { `('with location hash set to "$givenLocationHash"', ({ tabName, index, givenLocationHash }) => {
...@@ -173,7 +173,7 @@ describe('EE - DastProfiles', () => { ...@@ -173,7 +173,7 @@ describe('EE - DastProfiles', () => {
describe.each` describe.each`
description | profileType description | profileType
${'Saved Scans List'} | ${'savedScans'} ${'Saved Scans List'} | ${'dastProfiles'}
${'Site Profiles List'} | ${'siteProfiles'} ${'Site Profiles List'} | ${'siteProfiles'}
${'Scanner Profiles List'} | ${'scannerProfiles'} ${'Scanner Profiles List'} | ${'scannerProfiles'}
`('$description', ({ profileType }) => { `('$description', ({ profileType }) => {
......
...@@ -3,10 +3,9 @@ ...@@ -3,10 +3,9 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe ::Integrations::Test::ProjectService do RSpec.describe ::Integrations::Test::ProjectService do
let(:user) { double('user') }
describe '#execute' do describe '#execute' do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:user) { project.owner }
let(:event) { nil } let(:event) { nil }
let(:sample_data) { { data: 'sample' } } let(:sample_data) { { data: 'sample' } }
let(:success_result) { { success: true, result: {} } } let(:success_result) { { success: true, result: {} } }
......
...@@ -28684,6 +28684,9 @@ msgstr "" ...@@ -28684,6 +28684,9 @@ msgstr ""
msgid "Terraform|Locked by %{user} %{timeAgo}" msgid "Terraform|Locked by %{user} %{timeAgo}"
msgstr "" msgstr ""
msgid "Terraform|Locking state"
msgstr ""
msgid "Terraform|Name" msgid "Terraform|Name"
msgstr "" msgstr ""
...@@ -28717,6 +28720,9 @@ msgstr "" ...@@ -28717,6 +28720,9 @@ msgstr ""
msgid "Terraform|Unlock" msgid "Terraform|Unlock"
msgstr "" msgstr ""
msgid "Terraform|Unlocking state"
msgstr ""
msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible." msgid "Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously\twill remain intact, only the state file with all its versions are to be removed. This action is non-revertible."
msgstr "" msgstr ""
......
...@@ -89,17 +89,34 @@ describe('StatesTableActions', () => { ...@@ -89,17 +89,34 @@ describe('StatesTableActions', () => {
}); });
describe('when the state is loading', () => { describe('when the state is loading', () => {
beforeEach(() => { describe('when lock/unlock is processing', () => {
return createComponent({ beforeEach(() => {
state: { return createComponent({
...defaultProps.state, state: {
loadingActions: true, ...defaultProps.state,
}, loadingLock: true,
},
});
});
it('disables the actions dropdown', () => {
expect(findActionsDropdown().props('disabled')).toBe(true);
}); });
}); });
it('disables the actions dropdown', () => { describe('when remove is processing', () => {
expect(findActionsDropdown().props('disabled')).toBe(true); beforeEach(() => {
return createComponent({
state: {
...defaultProps.state,
loadingRemove: true,
},
});
});
it('disables the actions dropdown', () => {
expect(findActionsDropdown().props('disabled')).toBe(true);
});
}); });
}); });
...@@ -188,7 +205,8 @@ describe('StatesTableActions', () => { ...@@ -188,7 +205,8 @@ describe('StatesTableActions', () => {
...unlockedProps.state, ...unlockedProps.state,
_showDetails: false, _showDetails: false,
errorMessages: [], errorMessages: [],
loadingActions: true, loadingLock: true,
loadingRemove: false,
}, },
}, },
// Apollo fields // Apollo fields
...@@ -205,7 +223,8 @@ describe('StatesTableActions', () => { ...@@ -205,7 +223,8 @@ describe('StatesTableActions', () => {
...unlockedProps.state, ...unlockedProps.state,
_showDetails: true, _showDetails: true,
errorMessages: ['There was an error'], errorMessages: ['There was an error'],
loadingActions: false, loadingLock: false,
loadingRemove: false,
}, },
}, },
// Apollo fields // Apollo fields
......
...@@ -14,6 +14,8 @@ describe('StatesTable', () => { ...@@ -14,6 +14,8 @@ describe('StatesTable', () => {
_showDetails: true, _showDetails: true,
errorMessages: ['State 1 has errored'], errorMessages: ['State 1 has errored'],
name: 'state-1', name: 'state-1',
loadingLock: false,
loadingRemove: false,
lockedAt: '2020-10-13T00:00:00Z', lockedAt: '2020-10-13T00:00:00Z',
lockedByUser: { lockedByUser: {
name: 'user-1', name: 'user-1',
...@@ -25,6 +27,8 @@ describe('StatesTable', () => { ...@@ -25,6 +27,8 @@ describe('StatesTable', () => {
_showDetails: false, _showDetails: false,
errorMessages: [], errorMessages: [],
name: 'state-2', name: 'state-2',
loadingLock: true,
loadingRemove: false,
lockedAt: null, lockedAt: null,
lockedByUser: null, lockedByUser: null,
updatedAt: '2020-10-10T00:00:00Z', updatedAt: '2020-10-10T00:00:00Z',
...@@ -34,6 +38,8 @@ describe('StatesTable', () => { ...@@ -34,6 +38,8 @@ describe('StatesTable', () => {
_showDetails: false, _showDetails: false,
errorMessages: [], errorMessages: [],
name: 'state-3', name: 'state-3',
loadingLock: true,
loadingRemove: false,
lockedAt: '2020-10-10T00:00:00Z', lockedAt: '2020-10-10T00:00:00Z',
lockedByUser: { lockedByUser: {
name: 'user-2', name: 'user-2',
...@@ -63,6 +69,8 @@ describe('StatesTable', () => { ...@@ -63,6 +69,8 @@ describe('StatesTable', () => {
_showDetails: true, _showDetails: true,
errorMessages: ['State 4 has errored'], errorMessages: ['State 4 has errored'],
name: 'state-4', name: 'state-4',
loadingLock: false,
loadingRemove: false,
lockedAt: '2020-10-10T00:00:00Z', lockedAt: '2020-10-10T00:00:00Z',
lockedByUser: null, lockedByUser: null,
updatedAt: '2020-10-10T00:00:00Z', updatedAt: '2020-10-10T00:00:00Z',
...@@ -106,8 +114,8 @@ describe('StatesTable', () => { ...@@ -106,8 +114,8 @@ describe('StatesTable', () => {
it.each` it.each`
name | toolTipText | locked | lineNumber name | toolTipText | locked | lineNumber
${'state-1'} | ${'Locked by user-1 2 days ago'} | ${true} | ${0} ${'state-1'} | ${'Locked by user-1 2 days ago'} | ${true} | ${0}
${'state-2'} | ${null} | ${false} | ${1} ${'state-2'} | ${'Locking state'} | ${false} | ${1}
${'state-3'} | ${'Locked by user-2 5 days ago'} | ${true} | ${2} ${'state-3'} | ${'Unlocking state'} | ${false} | ${2}
${'state-4'} | ${'Locked by Unknown User 5 days ago'} | ${true} | ${3} ${'state-4'} | ${'Locked by Unknown User 5 days ago'} | ${true} | ${3}
`( `(
'displays the name and locked information "$name" for line "$lineNumber"', 'displays the name and locked information "$name" for line "$lineNumber"',
......
...@@ -2,6 +2,7 @@ import { GlAlert, GlBadge, GlKeysetPagination, GlLoadingIcon, GlTab } from '@git ...@@ -2,6 +2,7 @@ import { GlAlert, GlBadge, GlKeysetPagination, GlLoadingIcon, GlTab } from '@git
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import EmptyState from '~/terraform/components/empty_state.vue'; import EmptyState from '~/terraform/components/empty_state.vue';
import StatesTable from '~/terraform/components/states_table.vue'; import StatesTable from '~/terraform/components/states_table.vue';
import TerraformList from '~/terraform/components/terraform_list.vue'; import TerraformList from '~/terraform/components/terraform_list.vue';
...@@ -27,17 +28,20 @@ describe('TerraformList', () => { ...@@ -27,17 +28,20 @@ describe('TerraformList', () => {
}, },
}; };
// Override @client _showDetails const mockResolvers = {
getStatesQuery.getStates.definitions[1].selectionSet.selections[0].directives = []; TerraformState: {
_showDetails: jest.fn().mockResolvedValue(false),
// Override @client errorMessages errorMessages: jest.fn().mockResolvedValue([]),
getStatesQuery.getStates.definitions[1].selectionSet.selections[1].directives = []; loadingLock: jest.fn().mockResolvedValue(false),
loadingRemove: jest.fn().mockResolvedValue(false),
// Override @client loadingActions },
getStatesQuery.getStates.definitions[1].selectionSet.selections[2].directives = []; Mutation: {
addDataToTerraformState: jest.fn().mockResolvedValue({}),
},
};
const statsQueryResponse = queryResponse || jest.fn().mockResolvedValue(apolloQueryResponse); const statsQueryResponse = queryResponse || jest.fn().mockResolvedValue(apolloQueryResponse);
const apolloProvider = createMockApollo([[getStatesQuery, statsQueryResponse]]); const apolloProvider = createMockApollo([[getStatesQuery, statsQueryResponse]], mockResolvers);
wrapper = shallowMount(TerraformList, { wrapper = shallowMount(TerraformList, {
localVue, localVue,
...@@ -66,7 +70,8 @@ describe('TerraformList', () => { ...@@ -66,7 +70,8 @@ describe('TerraformList', () => {
id: 'gid://gitlab/Terraform::State/1', id: 'gid://gitlab/Terraform::State/1',
name: 'state-1', name: 'state-1',
latestVersion: null, latestVersion: null,
loadingActions: false, loadingLock: false,
loadingRemove: false,
lockedAt: null, lockedAt: null,
lockedByUser: null, lockedByUser: null,
updatedAt: null, updatedAt: null,
...@@ -77,7 +82,8 @@ describe('TerraformList', () => { ...@@ -77,7 +82,8 @@ describe('TerraformList', () => {
id: 'gid://gitlab/Terraform::State/2', id: 'gid://gitlab/Terraform::State/2',
name: 'state-2', name: 'state-2',
latestVersion: null, latestVersion: null,
loadingActions: false, loadingLock: false,
loadingRemove: false,
lockedAt: null, lockedAt: null,
lockedByUser: null, lockedByUser: null,
updatedAt: null, updatedAt: null,
...@@ -98,7 +104,7 @@ describe('TerraformList', () => { ...@@ -98,7 +104,7 @@ describe('TerraformList', () => {
}, },
}); });
return wrapper.vm.$nextTick(); return waitForPromises();
}); });
it('displays a states tab and count', () => { it('displays a states tab and count', () => {
...@@ -126,7 +132,7 @@ describe('TerraformList', () => { ...@@ -126,7 +132,7 @@ describe('TerraformList', () => {
}, },
}); });
return wrapper.vm.$nextTick(); return waitForPromises();
}); });
it('renders the states table without pagination buttons', () => { it('renders the states table without pagination buttons', () => {
...@@ -146,7 +152,7 @@ describe('TerraformList', () => { ...@@ -146,7 +152,7 @@ describe('TerraformList', () => {
}, },
}); });
return wrapper.vm.$nextTick(); return waitForPromises();
}); });
it('displays a states tab with no count', () => { it('displays a states tab with no count', () => {
...@@ -164,7 +170,7 @@ describe('TerraformList', () => { ...@@ -164,7 +170,7 @@ describe('TerraformList', () => {
beforeEach(() => { beforeEach(() => {
createWrapper({ terraformStates: null, queryResponse: jest.fn().mockRejectedValue() }); createWrapper({ terraformStates: null, queryResponse: jest.fn().mockRejectedValue() });
return wrapper.vm.$nextTick(); return waitForPromises();
}); });
it('displays an alert message', () => { it('displays an alert message', () => {
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Integrations::Test::ProjectService do RSpec.describe Integrations::Test::ProjectService do
include AfterNextHelpers
describe '#execute' do describe '#execute' do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let(:integration) { create(:slack_service, project: project) } let(:integration) { create(:slack_service, project: project) }
...@@ -72,9 +74,7 @@ RSpec.describe Integrations::Test::ProjectService do ...@@ -72,9 +74,7 @@ RSpec.describe Integrations::Test::ProjectService do
create(:note, project: project) create(:note, project: project)
allow(Gitlab::DataBuilder::Note).to receive(:build).and_return(sample_data) allow(Gitlab::DataBuilder::Note).to receive(:build).and_return(sample_data)
allow_next_instance_of(NotesFinder) do |finder| allow_next(NotesFinder).to receive(:execute).and_return(Note.all)
allow(finder).to receive(:execute).and_return(Note.all)
end
expect(integration).to receive(:test).with(sample_data).and_return(success_result) expect(integration).to receive(:test).with(sample_data).and_return(success_result)
expect(subject).to eq(success_result) expect(subject).to eq(success_result)
...@@ -92,9 +92,7 @@ RSpec.describe Integrations::Test::ProjectService do ...@@ -92,9 +92,7 @@ RSpec.describe Integrations::Test::ProjectService do
it 'executes integration' do it 'executes integration' do
allow(project).to receive(:issues).and_return([issue]) allow(project).to receive(:issues).and_return([issue])
allow(issue).to receive(:to_hook_data).and_return(sample_data) allow(issue).to receive(:to_hook_data).and_return(sample_data)
allow_next_instance_of(IssuesFinder) do |finder| allow_next(IssuesFinder).to receive(:execute).and_return([issue])
allow(finder).to receive(:execute).and_return([issue])
end
expect(integration).to receive(:test).with(sample_data).and_return(success_result) expect(integration).to receive(:test).with(sample_data).and_return(success_result)
expect(subject).to eq(success_result) expect(subject).to eq(success_result)
...@@ -124,9 +122,7 @@ RSpec.describe Integrations::Test::ProjectService do ...@@ -124,9 +122,7 @@ RSpec.describe Integrations::Test::ProjectService do
it 'executes integration' do it 'executes integration' do
allow(merge_request).to receive(:to_hook_data).and_return(sample_data) allow(merge_request).to receive(:to_hook_data).and_return(sample_data)
allow_next_instance_of(MergeRequestsFinder) do |finder| allow_next(MergeRequestsFinder).to receive(:execute).and_return([merge_request])
allow(finder).to receive(:execute).and_return([merge_request])
end
expect(integration).to receive(:test).with(sample_data).and_return(success_result) expect(integration).to receive(:test).with(sample_data).and_return(success_result)
expect(subject).to include(success_result) expect(subject).to include(success_result)
...@@ -135,6 +131,7 @@ RSpec.describe Integrations::Test::ProjectService do ...@@ -135,6 +131,7 @@ RSpec.describe Integrations::Test::ProjectService do
context 'deployment' do context 'deployment' do
let_it_be(:project) { create(:project, :test_repo) } let_it_be(:project) { create(:project, :test_repo) }
let(:deployment) { build(:deployment) }
let(:event) { 'deployment' } let(:event) { 'deployment' }
it 'returns error message if not enough data' do it 'returns error message if not enough data' do
...@@ -143,16 +140,32 @@ RSpec.describe Integrations::Test::ProjectService do ...@@ -143,16 +140,32 @@ RSpec.describe Integrations::Test::ProjectService do
end end
it 'executes integration' do it 'executes integration' do
create(:deployment, project: project)
allow(Gitlab::DataBuilder::Deployment).to receive(:build).and_return(sample_data) allow(Gitlab::DataBuilder::Deployment).to receive(:build).and_return(sample_data)
allow_next(DeploymentsFinder).to receive(:execute).and_return([deployment])
expect(integration).to receive(:test).with(sample_data).and_return(success_result) expect(integration).to receive(:test).with(sample_data).and_return(success_result)
expect(subject).to eq(success_result) expect(subject).to eq(success_result)
end end
context 'when the reorder feature flag is disabled' do
before do
stub_feature_flags(integrations_test_webhook_reorder: false)
end
it 'executes the old query' do
allow(Gitlab::DataBuilder::Deployment).to receive(:build).and_return(sample_data)
expect(DeploymentsFinder).not_to receive(:new)
expect(project).to receive(:deployments).and_return([deployment])
expect(integration).to receive(:test).with(sample_data).and_return(success_result)
expect(subject).to eq(success_result)
end
end
end end
context 'pipeline' do context 'pipeline' do
let(:event) { 'pipeline' } let(:event) { 'pipeline' }
let(:pipeline) { build(:ci_pipeline) }
it 'returns error message if not enough data' do it 'returns error message if not enough data' do
expect(integration).not_to receive(:test) expect(integration).not_to receive(:test)
...@@ -160,12 +173,27 @@ RSpec.describe Integrations::Test::ProjectService do ...@@ -160,12 +173,27 @@ RSpec.describe Integrations::Test::ProjectService do
end end
it 'executes integration' do it 'executes integration' do
create(:ci_empty_pipeline, project: project)
allow(Gitlab::DataBuilder::Pipeline).to receive(:build).and_return(sample_data) allow(Gitlab::DataBuilder::Pipeline).to receive(:build).and_return(sample_data)
allow_next(Ci::PipelinesFinder).to receive(:execute).and_return([pipeline])
expect(integration).to receive(:test).with(sample_data).and_return(success_result) expect(integration).to receive(:test).with(sample_data).and_return(success_result)
expect(subject).to eq(success_result) expect(subject).to eq(success_result)
end end
context 'when the reorder feature flag is disabled' do
before do
stub_feature_flags(integrations_test_webhook_reorder: false)
end
it 'executes the old query' do
create(:ci_empty_pipeline, project: project)
allow(Gitlab::DataBuilder::Pipeline).to receive(:build).and_return(sample_data)
expect(Ci::PipelinesFinder).not_to receive(:new)
expect(integration).to receive(:test).with(sample_data).and_return(success_result)
expect(subject).to eq(success_result)
end
end
end end
context 'wiki_page' do context 'wiki_page' do
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe TestHooks::ProjectService do RSpec.describe TestHooks::ProjectService do
include AfterNextHelpers
let(:current_user) { create(:user) } let(:current_user) { create(:user) }
describe '#execute' do describe '#execute' do
...@@ -64,9 +66,7 @@ RSpec.describe TestHooks::ProjectService do ...@@ -64,9 +66,7 @@ RSpec.describe TestHooks::ProjectService do
create(:note, project: project) create(:note, project: project)
allow(Gitlab::DataBuilder::Note).to receive(:build).and_return(sample_data) allow(Gitlab::DataBuilder::Note).to receive(:build).and_return(sample_data)
allow_next_instance_of(NotesFinder) do |finder| allow_next(NotesFinder).to receive(:execute).and_return(Note.all)
allow(finder).to receive(:execute).and_return(Note.all)
end
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result) expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result) expect(service.execute).to include(success_result)
...@@ -83,9 +83,7 @@ RSpec.describe TestHooks::ProjectService do ...@@ -83,9 +83,7 @@ RSpec.describe TestHooks::ProjectService do
it 'executes hook' do it 'executes hook' do
allow(issue).to receive(:to_hook_data).and_return(sample_data) allow(issue).to receive(:to_hook_data).and_return(sample_data)
allow_next_instance_of(IssuesFinder) do |finder| allow_next(IssuesFinder).to receive(:execute).and_return([issue])
allow(finder).to receive(:execute).and_return([issue])
end
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result) expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result) expect(service.execute).to include(success_result)
...@@ -118,9 +116,7 @@ RSpec.describe TestHooks::ProjectService do ...@@ -118,9 +116,7 @@ RSpec.describe TestHooks::ProjectService do
it 'executes hook' do it 'executes hook' do
allow(merge_request).to receive(:to_hook_data).and_return(sample_data) allow(merge_request).to receive(:to_hook_data).and_return(sample_data)
allow_next_instance_of(MergeRequestsFinder) do |finder| allow_next(MergeRequestsFinder).to receive(:execute).and_return([merge_request])
allow(finder).to receive(:execute).and_return([merge_request])
end
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result) expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result) expect(service.execute).to include(success_result)
...@@ -130,6 +126,7 @@ RSpec.describe TestHooks::ProjectService do ...@@ -130,6 +126,7 @@ RSpec.describe TestHooks::ProjectService do
context 'job_events' do context 'job_events' do
let(:trigger) { 'job_events' } let(:trigger) { 'job_events' }
let(:trigger_key) { :job_hooks } let(:trigger_key) { :job_hooks }
let(:ci_job) { build(:ci_build) }
it 'returns error message if not enough data' do it 'returns error message if not enough data' do
expect(hook).not_to receive(:execute) expect(hook).not_to receive(:execute)
...@@ -137,17 +134,33 @@ RSpec.describe TestHooks::ProjectService do ...@@ -137,17 +134,33 @@ RSpec.describe TestHooks::ProjectService do
end end
it 'executes hook' do it 'executes hook' do
create(:ci_build, project: project)
allow(Gitlab::DataBuilder::Build).to receive(:build).and_return(sample_data) allow(Gitlab::DataBuilder::Build).to receive(:build).and_return(sample_data)
allow_next(Ci::JobsFinder).to receive(:execute).and_return([ci_job])
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result) expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result) expect(service.execute).to include(success_result)
end end
context 'when the reorder feature flag is disabled' do
before do
stub_feature_flags(integrations_test_webhook_reorder: false)
end
it 'executes the old query' do
allow(Gitlab::DataBuilder::Build).to receive(:build).and_return(sample_data)
expect(Ci::JobsFinder).not_to receive(:new)
expect(project).to receive(:builds).and_return([ci_job])
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result)
end
end
end end
context 'pipeline_events' do context 'pipeline_events' do
let(:trigger) { 'pipeline_events' } let(:trigger) { 'pipeline_events' }
let(:trigger_key) { :pipeline_hooks } let(:trigger_key) { :pipeline_hooks }
let(:pipeline) { build(:ci_empty_pipeline) }
it 'returns error message if not enough data' do it 'returns error message if not enough data' do
expect(hook).not_to receive(:execute) expect(hook).not_to receive(:execute)
...@@ -155,12 +168,27 @@ RSpec.describe TestHooks::ProjectService do ...@@ -155,12 +168,27 @@ RSpec.describe TestHooks::ProjectService do
end end
it 'executes hook' do it 'executes hook' do
create(:ci_empty_pipeline, project: project)
allow(Gitlab::DataBuilder::Pipeline).to receive(:build).and_return(sample_data) allow(Gitlab::DataBuilder::Pipeline).to receive(:build).and_return(sample_data)
allow_next(Ci::PipelinesFinder).to receive(:execute).and_return([pipeline])
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result) expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result) expect(service.execute).to include(success_result)
end end
context 'when the reorder feature flag is disabled' do
before do
stub_feature_flags(integrations_test_webhook_reorder: false)
end
it 'executes the old query' do
create(:ci_empty_pipeline, project: project)
allow(Gitlab::DataBuilder::Pipeline).to receive(:build).and_return(sample_data)
expect(Ci::PipelinesFinder).not_to receive(:new)
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result)
end
end
end end
context 'wiki_page_events' do context 'wiki_page_events' do
...@@ -192,6 +220,7 @@ RSpec.describe TestHooks::ProjectService do ...@@ -192,6 +220,7 @@ RSpec.describe TestHooks::ProjectService do
context 'releases_events' do context 'releases_events' do
let(:trigger) { 'releases_events' } let(:trigger) { 'releases_events' }
let(:trigger_key) { :release_hooks } let(:trigger_key) { :release_hooks }
let(:release) { build(:release) }
it 'returns error message if not enough data' do it 'returns error message if not enough data' do
expect(hook).not_to receive(:execute) expect(hook).not_to receive(:execute)
...@@ -199,12 +228,27 @@ RSpec.describe TestHooks::ProjectService do ...@@ -199,12 +228,27 @@ RSpec.describe TestHooks::ProjectService do
end end
it 'executes hook' do it 'executes hook' do
allow(project).to receive(:releases).and_return([Release.new]) allow(release).to receive(:to_hook_data).and_return(sample_data)
allow_any_instance_of(Release).to receive(:to_hook_data).and_return(sample_data) allow_next(ReleasesFinder).to receive(:execute).and_return([release])
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result) expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result) expect(service.execute).to include(success_result)
end end
context 'when the reorder feature flag is disabled' do
before do
stub_feature_flags(integrations_test_webhook_reorder: false)
end
it 'executes the old query' do
allow(release).to receive(:to_hook_data).and_return(sample_data)
expect(ReleasesFinder).not_to receive(:new)
expect(project).to receive(:releases).and_return([release])
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result)
end
end
end end
end end
end end
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe TestHooks::SystemService do RSpec.describe TestHooks::SystemService do
let(:current_user) { create(:user) } include AfterNextHelpers
describe '#execute' do describe '#execute' do
let(:project) { create(:project, :repository) } let_it_be(:project) { create(:project, :repository) }
let(:hook) { create(:system_hook) } let(:hook) { create(:system_hook) }
let(:service) { described_class.new(hook, current_user, trigger) } let(:service) { described_class.new(hook, project.owner, trigger) }
let(:success_result) { { status: :success, http_status: 200, message: 'ok' } } let(:success_result) { { status: :success, http_status: 200, message: 'ok' } }
before do before do
...@@ -63,6 +63,9 @@ RSpec.describe TestHooks::SystemService do ...@@ -63,6 +63,9 @@ RSpec.describe TestHooks::SystemService do
context 'merge_requests_events' do context 'merge_requests_events' do
let(:trigger) { 'merge_requests_events' } let(:trigger) { 'merge_requests_events' }
let(:trigger_key) { :merge_request_hooks }
let(:merge_requests) { build_list(:merge_request, 2) }
let(:sample_data) { { data: 'sample' } }
it 'returns error message if the user does not have any repository with a merge request' do it 'returns error message if the user does not have any repository with a merge request' do
expect(hook).not_to receive(:execute) expect(hook).not_to receive(:execute)
...@@ -70,15 +73,24 @@ RSpec.describe TestHooks::SystemService do ...@@ -70,15 +73,24 @@ RSpec.describe TestHooks::SystemService do
end end
it 'executes hook' do it 'executes hook' do
trigger_key = :merge_request_hooks expect(MergeRequest).to receive(:of_projects).and_return(merge_requests)
sample_data = { data: 'sample' } expect(merge_requests.last).to receive(:to_hook_data).and_return(sample_data)
create(:project_member, user: current_user, project: project)
create(:merge_request, source_project: project)
allow_any_instance_of(MergeRequest).to receive(:to_hook_data).and_return(sample_data)
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result) expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result) expect(service.execute).to include(success_result)
end end
context 'when the reorder feature flag is disabled' do
before do
stub_feature_flags(integrations_test_webhook_reorder: false)
end
it 'executes the old query' do
expect(MergeRequest).to receive(:of_projects).and_return(merge_requests)
expect(merge_requests.first).to receive(:to_hook_data).and_return(sample_data)
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
expect(service.execute).to include(success_result)
end
end
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment