Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-10-21 00:10:26 +00:00
parent 40e8ba2fc8
commit 3f9ae4674e
66 changed files with 568 additions and 150 deletions

View file

@ -1 +1 @@
3d5bb4cdfd5f31e5e5f0c7506905755e51d0b611 faa097a0d42a9338445700a52aac25ba5887fd85

View file

@ -29,7 +29,7 @@ export default {
SafeHtml: GlSafeHtmlDirective, SafeHtml: GlSafeHtmlDirective,
}, },
formLabels: { formLabels: {
createProject: __('Self monitoring'), createProject: __('Self-monitoring'),
}, },
data() { data() {
return { return {
@ -60,7 +60,7 @@ export default {
if (this.projectCreated) { if (this.projectCreated) {
return sprintf( return sprintf(
s__( s__(
'SelfMonitoring|Self monitoring is active. Use the %{projectLinkStart}self monitoring project%{projectLinkEnd} to monitor the health of your instance.', 'SelfMonitoring|Self-monitoring is active. Use the %{projectLinkStart}self-monitoring project%{projectLinkEnd} to monitor the health of your instance.',
), ),
{ {
projectLinkStart: `<a href="${this.selfMonitorProjectFullUrl}">`, projectLinkStart: `<a href="${this.selfMonitorProjectFullUrl}">`,
@ -71,7 +71,7 @@ export default {
} }
return s__( return s__(
'SelfMonitoring|Activate self monitoring to create a project to use to monitor the health of your instance.', 'SelfMonitoring|Activate self-monitoring to create a project to use to monitor the health of your instance.',
); );
}, },
helpDocsPath() { helpDocsPath() {
@ -139,11 +139,11 @@ export default {
<h4 <h4
class="js-section-header settings-title js-settings-toggle js-settings-toggle-trigger-only" class="js-section-header settings-title js-settings-toggle js-settings-toggle-trigger-only"
> >
{{ s__('SelfMonitoring|Self monitoring') }} {{ s__('SelfMonitoring|Self-monitoring') }}
</h4> </h4>
<gl-button class="js-settings-toggle">{{ __('Expand') }}</gl-button> <gl-button class="js-settings-toggle">{{ __('Expand') }}</gl-button>
<p class="js-section-sub-header"> <p class="js-section-sub-header">
{{ s__('SelfMonitoring|Activate or deactivate instance self monitoring.') }} {{ s__('SelfMonitoring|Activate or deactivate instance self-monitoring.') }}
<gl-link :href="helpDocsPath">{{ __('Learn more.') }}</gl-link> <gl-link :href="helpDocsPath">{{ __('Learn more.') }}</gl-link>
</p> </p>
</div> </div>
@ -160,9 +160,9 @@ export default {
</form> </form>
</div> </div>
<gl-modal <gl-modal
:title="s__('SelfMonitoring|Deactivate self monitoring?')" :title="s__('SelfMonitoring|Deactivate self-monitoring?')"
:modal-id="modalId" :modal-id="modalId"
:ok-title="__('Delete self monitoring project')" :ok-title="__('Delete self-monitoring project')"
:cancel-title="__('Cancel')" :cancel-title="__('Cancel')"
ok-variant="danger" ok-variant="danger"
category="primary" category="primary"
@ -172,7 +172,7 @@ export default {
<div> <div>
{{ {{
s__( s__(
'SelfMonitoring|Deactivating self monitoring deletes the self monitoring project. Are you sure you want to deactivate self monitoring and delete the project?', 'SelfMonitoring|Deactivating self-monitoring deletes the self-monitoring project. Are you sure you want to deactivate self-monitoring and delete the project?',
) )
}} }}
</div> </div>

View file

@ -56,7 +56,7 @@ export const requestCreateProjectSuccess = ({ commit, dispatch }, selfMonitorDat
commit(types.SET_LOADING, false); commit(types.SET_LOADING, false);
commit(types.SET_PROJECT_URL, selfMonitorData.project_full_path); commit(types.SET_PROJECT_URL, selfMonitorData.project_full_path);
commit(types.SET_ALERT_CONTENT, { commit(types.SET_ALERT_CONTENT, {
message: s__('SelfMonitoring|Self monitoring project successfully created.'), message: s__('SelfMonitoring|Self-monitoring project successfully created.'),
actionText: __('View project'), actionText: __('View project'),
actionName: 'viewSelfMonitorProject', actionName: 'viewSelfMonitorProject',
}); });
@ -108,7 +108,7 @@ export const requestDeleteProjectSuccess = ({ commit }) => {
commit(types.SET_PROJECT_URL, ''); commit(types.SET_PROJECT_URL, '');
commit(types.SET_PROJECT_CREATED, false); commit(types.SET_PROJECT_CREATED, false);
commit(types.SET_ALERT_CONTENT, { commit(types.SET_ALERT_CONTENT, {
message: s__('SelfMonitoring|Self monitoring project successfully deleted.'), message: s__('SelfMonitoring|Self-monitoring project successfully deleted.'),
actionText: __('Undo'), actionText: __('Undo'),
actionName: 'createProject', actionName: 'createProject',
}); });

View file

@ -149,7 +149,9 @@ export default {
}, },
set(tabIdx) { set(tabIdx) {
const tabId = this.$options.tabsConfig[tabIdx].id; const tabId = this.$options.tabsConfig[tabIdx].id;
this.$router.replace({ name: 'tab', params: { tabId } }); if (this.$route.params?.tabId !== tabId) {
this.$router.push({ name: 'tab', params: { tabId } });
}
}, },
}, },
environmentName() { environmentName() {

View file

@ -15,9 +15,17 @@ Vue.use(VueApollo);
export default (selector) => { export default (selector) => {
const domEl = document.querySelector(selector); const domEl = document.querySelector(selector);
const { alertId, projectPath, projectIssuesPath, projectId, page, canUpdate } = domEl.dataset; const {
alertId,
projectPath,
projectIssuesPath,
projectAlertManagementDetailsPath,
projectId,
page,
canUpdate,
} = domEl.dataset;
const iid = alertId; const iid = alertId;
const router = createRouter(); const router = createRouter(projectAlertManagementDetailsPath);
const resolvers = { const resolvers = {
Mutation: { Mutation: {

View file

@ -6,7 +6,7 @@ Vue.use(VueRouter);
export default function createRouter(base) { export default function createRouter(base) {
return new VueRouter({ return new VueRouter({
mode: 'hash', mode: 'history',
base: joinPaths(gon.relative_url_root || '', base), base: joinPaths(gon.relative_url_root || '', base),
routes: [{ path: '/:tabId', name: 'tab' }], routes: [{ path: '/:tabId', name: 'tab' }],
}); });

View file

@ -21,6 +21,7 @@ module Projects::AlertManagementHelper
'project-path' => project.full_path, 'project-path' => project.full_path,
'project-id' => project.id, 'project-id' => project.id,
'project-issues-path' => project_issues_path(project), 'project-issues-path' => project_issues_path(project),
'project-alert-management-details-path' => details_project_alert_management_path(project, alert_id),
'page' => 'OPERATIONS', 'page' => 'OPERATIONS',
'can-update' => can?(current_user, :update_alert_management_alert, project).to_s 'can-update' => can?(current_user, :update_alert_management_alert, project).to_s
} }

View file

@ -121,7 +121,7 @@ module Ci
accepts_nested_attributes_for :variables, reject_if: :persisted? accepts_nested_attributes_for :variables, reject_if: :persisted?
delegate :full_path, to: :project, prefix: true delegate :full_path, to: :project, prefix: true
delegate :title, to: :pipeline_metadata, allow_nil: true delegate :name, to: :pipeline_metadata, allow_nil: true
validates :sha, presence: { unless: :importing? } validates :sha, presence: { unless: :importing? }
validates :ref, presence: { unless: :importing? } validates :ref, presence: { unless: :importing? }

View file

@ -9,6 +9,6 @@ module Ci
validates :pipeline, presence: true validates :pipeline, presence: true
validates :project, presence: true validates :project, presence: true
validates :title, presence: true, length: { minimum: 1, maximum: 255 } validates :name, presence: true, length: { minimum: 1, maximum: 255 }
end end
end end

View file

@ -53,6 +53,7 @@ module Ci
}.freeze }.freeze
end end
delegator_override :name
def name def name
# Currently, `merge_request_event_type` is the only source to name pipelines # Currently, `merge_request_event_type` is the only source to name pipelines
# but this could be extended with the other types in the future. # but this could be extended with the other types in the future.

View file

@ -73,7 +73,7 @@ module GoogleCloud
includes << { 'remote' => include_url } includes << { 'remote' => include_url }
gitlab_ci_yml['include'] = includes.uniq gitlab_ci_yml['include'] = includes.uniq
gitlab_ci_yml.to_yaml gitlab_ci_yml.deep_stringify_keys.to_yaml
end end
end end
end end

View file

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
# Fetches the self monitoring metrics dashboard and formats the output. # Fetches the self-monitoring metrics dashboard and formats the output.
# Use Gitlab::Metrics::Dashboard::Finder to retrieve dashboards. # Use Gitlab::Metrics::Dashboard::Finder to retrieve dashboards.
module Metrics module Metrics
module Dashboard module Dashboard

View file

@ -18,7 +18,7 @@
.sub-section .sub-section
%h4= _("Housekeeping") %h4= _("Housekeeping")
.form-group .form-group
- help_text = _("Leaving this setting enabled is recommended.") - help_text = _("Run housekeeping tasks to automatically optimize Git repositories. Disabling this option will cause performance to degenerate over time.")
- help_link = link_to s_('Learn more.'), help_page_path('administration/housekeeping.md', anchor: 'housekeeping-options'), target: '_blank', rel: 'noopener noreferrer' - help_link = link_to s_('Learn more.'), help_page_path('administration/housekeeping.md', anchor: 'housekeeping-options'), target: '_blank', rel: 'noopener noreferrer'
= f.gitlab_ui_checkbox_component :housekeeping_enabled, = f.gitlab_ui_checkbox_component :housekeeping_enabled,
_("Enable automatic repository housekeeping"), _("Enable automatic repository housekeeping"),

View file

@ -352,7 +352,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end end
resources :alert_management, only: [:index] do resources :alert_management, only: [:index] do
get 'details', on: :member member do
get 'details(/*page)', to: 'alert_management#details', as: 'details'
end
end end
get 'alert_management/:id', to: 'alert_management#details', as: 'alert_management_alert' get 'alert_management/:id', to: 'alert_management#details', as: 'alert_management_alert'

View file

@ -8,8 +8,8 @@ response = Sidekiq::Worker.skipping_transaction_check do
end end
if response[:status] == :success if response[:status] == :success
puts "Successfully created self monitoring project." puts "Successfully created self-monitoring project."
else else
puts "Could not create self monitoring project due to error: '#{response[:message]}'" puts "Could not create self-monitoring project due to error: '#{response[:message]}'"
puts "Check logs for more details." puts "Check logs for more details."
end end

View file

@ -3,8 +3,8 @@
response = ::Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService.new.execute response = ::Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService.new.execute
if response[:status] == :success if response[:status] == :success
puts "Successfully created self monitoring project." puts "Successfully created self-monitoring project."
else else
puts "Could not create self monitoring project due to error: '#{response[:message]}'" puts "Could not create self-monitoring project due to error: '#{response[:message]}'"
puts "Check logs for more details." puts "Check logs for more details."
end end

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
class RenameCiPipelineMetadataTitle < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
def up
rename_column_concurrently :ci_pipeline_metadata, :title, :name, batch_column_name: :pipeline_id
end
def down
undo_rename_column_concurrently :ci_pipeline_metadata, :title, :name
end
end

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
class CleanupRenameCiPipelineMetadataTitle < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
def up
cleanup_concurrent_column_rename :ci_pipeline_metadata, :title, :name
end
def down
undo_cleanup_concurrent_column_rename :ci_pipeline_metadata, :title, :name, batch_column_name: :pipeline_id
end
end

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
class DisableFastupdateOnIssuesTitleGinIndex < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
INDEX_NAME = 'index_issues_on_title_trigram'
def up
with_lock_retries do
execute <<~SQL
ALTER INDEX #{INDEX_NAME} SET ( fastupdate = false ) ;
SQL
end
end
def down
with_lock_retries do
execute <<~SQL
ALTER INDEX #{INDEX_NAME} RESET ( fastupdate ) ;
SQL
end
end
end

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
class DisableFastupdateOnIssuesDescriptionGinIndex < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
INDEX_NAME = 'index_issues_on_description_trigram'
def up
with_lock_retries do
execute <<~SQL
ALTER INDEX #{INDEX_NAME} SET ( fastupdate = false ) ;
SQL
end
end
def down
with_lock_retries do
execute <<~SQL
ALTER INDEX #{INDEX_NAME} RESET ( fastupdate ) ;
SQL
end
end
end

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
class DisableFastupdateOnMergeRequestsTitleGinIndex < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
INDEX_NAME = 'index_merge_requests_on_title_trigram'
def up
with_lock_retries do
execute <<~SQL
ALTER INDEX #{INDEX_NAME} SET ( fastupdate = false ) ;
SQL
end
end
def down
with_lock_retries do
execute <<~SQL
ALTER INDEX #{INDEX_NAME} RESET ( fastupdate ) ;
SQL
end
end
end

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
class DisableFastupdateOnMergeRequestsDescriptionGinIndex < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
INDEX_NAME = 'index_merge_requests_on_description_trigram'
def up
with_lock_retries do
execute <<~SQL
ALTER INDEX #{INDEX_NAME} SET ( fastupdate = false ) ;
SQL
end
end
def down
with_lock_retries do
execute <<~SQL
ALTER INDEX #{INDEX_NAME} RESET ( fastupdate ) ;
SQL
end
end
end

View file

@ -0,0 +1 @@
d28932a3d52279446e3ef84806a6bb6b53dc10c5b9ae81e2c626203da4238a9a

View file

@ -0,0 +1 @@
dc03ff5c63ada744d41e5e37e276306b1fe3bb2d8f925ebb0087be3a4b51791e

View file

@ -0,0 +1 @@
785ed2a3c711edf54f1b23bdbd4b333b7a4ee02b86f8581c1f4cc20003e5f832

View file

@ -0,0 +1 @@
b09530d7b72d70774624ef44683be6665bd1141be49db551a0dfe303ce67eefa

View file

@ -0,0 +1 @@
a72855a95f243d2a404d840fde900a99b9f568144dfde47e813c4e9bc81ef8cf

View file

@ -0,0 +1 @@
1bd5d356d0a15737178eee70bce65c9883bd5daa2a672a9049ccecb4e73f431b

View file

@ -13061,8 +13061,9 @@ ALTER SEQUENCE ci_pipeline_messages_id_seq OWNED BY ci_pipeline_messages.id;
CREATE TABLE ci_pipeline_metadata ( CREATE TABLE ci_pipeline_metadata (
project_id bigint NOT NULL, project_id bigint NOT NULL,
pipeline_id bigint NOT NULL, pipeline_id bigint NOT NULL,
title text NOT NULL, name text,
CONSTRAINT check_e6a636a3f3 CHECK ((char_length(title) <= 255)) CONSTRAINT check_25d23931f1 CHECK ((name IS NOT NULL)),
CONSTRAINT check_9d3665463c CHECK ((char_length(name) <= 255))
); );
CREATE TABLE ci_pipeline_schedule_variables ( CREATE TABLE ci_pipeline_schedule_variables (
@ -28355,7 +28356,7 @@ CREATE UNIQUE INDEX index_ci_pipeline_chat_data_on_pipeline_id ON ci_pipeline_ch
CREATE INDEX index_ci_pipeline_messages_on_pipeline_id ON ci_pipeline_messages USING btree (pipeline_id); CREATE INDEX index_ci_pipeline_messages_on_pipeline_id ON ci_pipeline_messages USING btree (pipeline_id);
CREATE INDEX index_ci_pipeline_metadata_on_pipeline_id_title ON ci_pipeline_metadata USING btree (pipeline_id, title); CREATE INDEX index_ci_pipeline_metadata_on_pipeline_id_name ON ci_pipeline_metadata USING btree (pipeline_id, name);
CREATE INDEX index_ci_pipeline_metadata_on_project_id ON ci_pipeline_metadata USING btree (project_id); CREATE INDEX index_ci_pipeline_metadata_on_project_id ON ci_pipeline_metadata USING btree (project_id);
@ -29271,7 +29272,7 @@ CREATE INDEX index_issues_on_closed_by_id ON issues USING btree (closed_by_id);
CREATE INDEX index_issues_on_confidential ON issues USING btree (confidential); CREATE INDEX index_issues_on_confidential ON issues USING btree (confidential);
CREATE INDEX index_issues_on_description_trigram ON issues USING gin (description gin_trgm_ops); CREATE INDEX index_issues_on_description_trigram ON issues USING gin (description gin_trgm_ops) WITH (fastupdate='false');
CREATE INDEX index_issues_on_duplicated_to_id ON issues USING btree (duplicated_to_id) WHERE (duplicated_to_id IS NOT NULL); CREATE INDEX index_issues_on_duplicated_to_id ON issues USING btree (duplicated_to_id) WHERE (duplicated_to_id IS NOT NULL);
@ -29307,7 +29308,7 @@ CREATE INDEX index_issues_on_promoted_to_epic_id ON issues USING btree (promoted
CREATE INDEX index_issues_on_sprint_id ON issues USING btree (sprint_id); CREATE INDEX index_issues_on_sprint_id ON issues USING btree (sprint_id);
CREATE INDEX index_issues_on_title_trigram ON issues USING gin (title gin_trgm_ops); CREATE INDEX index_issues_on_title_trigram ON issues USING gin (title gin_trgm_ops) WITH (fastupdate='false');
CREATE INDEX index_issues_on_updated_at ON issues USING btree (updated_at); CREATE INDEX index_issues_on_updated_at ON issues USING btree (updated_at);
@ -29521,7 +29522,7 @@ CREATE INDEX index_merge_requests_on_author_id_and_target_project_id ON merge_re
CREATE INDEX index_merge_requests_on_created_at ON merge_requests USING btree (created_at); CREATE INDEX index_merge_requests_on_created_at ON merge_requests USING btree (created_at);
CREATE INDEX index_merge_requests_on_description_trigram ON merge_requests USING gin (description gin_trgm_ops); CREATE INDEX index_merge_requests_on_description_trigram ON merge_requests USING gin (description gin_trgm_ops) WITH (fastupdate='false');
CREATE INDEX index_merge_requests_on_head_pipeline_id ON merge_requests USING btree (head_pipeline_id); CREATE INDEX index_merge_requests_on_head_pipeline_id ON merge_requests USING btree (head_pipeline_id);
@ -29557,7 +29558,7 @@ CREATE INDEX index_merge_requests_on_target_project_id_and_updated_at_and_id ON
CREATE INDEX index_merge_requests_on_target_project_id_iid_jira_description ON merge_requests USING btree (target_project_id, iid) WHERE (description ~ '[A-Z][A-Z_0-9]+-\d+'::text); CREATE INDEX index_merge_requests_on_target_project_id_iid_jira_description ON merge_requests USING btree (target_project_id, iid) WHERE (description ~ '[A-Z][A-Z_0-9]+-\d+'::text);
CREATE INDEX index_merge_requests_on_title_trigram ON merge_requests USING gin (title gin_trgm_ops); CREATE INDEX index_merge_requests_on_title_trigram ON merge_requests USING gin (title gin_trgm_ops) WITH (fastupdate='false');
CREATE INDEX index_merge_requests_on_tp_id_and_merge_commit_sha_and_id ON merge_requests USING btree (target_project_id, merge_commit_sha, id); CREATE INDEX index_merge_requests_on_tp_id_and_merge_commit_sha_and_id ON merge_requests USING btree (target_project_id, merge_commit_sha, id);

View file

@ -30,31 +30,31 @@ As an administrator, you can add new members to the group to give them the Maint
This project can be used to: This project can be used to:
- Self monitor your GitLab instance. The metrics dashboard of the project shows some basic resource - Self-monitor your GitLab instance. The metrics dashboard of the project shows some basic resource
usage charts, such as CPU and memory usage of each server in usage charts, such as CPU and memory usage of each server in
[Omnibus GitLab](https://docs.gitlab.com/omnibus/) installations. [Omnibus GitLab](https://docs.gitlab.com/omnibus/) installations.
- Also configure your own [custom metrics](../../../operations/metrics/index.md#adding-custom-metrics) - Also configure your own [custom metrics](../../../operations/metrics/index.md#adding-custom-metrics)
using metrics exposed by the [GitLab exporter](../prometheus/gitlab_metrics.md#metrics-available). using metrics exposed by the [GitLab exporter](../prometheus/gitlab_metrics.md#metrics-available).
## Create the self monitoring project ## Create the self-monitoring project
1. On the top bar, select **Main menu > Admin**. 1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling** and expand **Self monitoring**. 1. On the left sidebar, select **Settings > Metrics and profiling** and expand **Self-monitoring**.
1. Toggle **Self monitoring** on. 1. Toggle **Self-monitoring** on.
1. After your GitLab instance creates the project, GitLab displays a link to the 1. After your GitLab instance creates the project, GitLab displays a link to the
project in the text above the **Self monitoring** toggle. You can also find it project in the text above the **Self-monitoring** toggle. You can also find it
from the top bar by selecting **Main menu > Projects**. from the top bar by selecting **Main menu > Projects**.
## Delete the self monitoring project ## Delete the self-monitoring project
WARNING: WARNING:
Deleting the self monitoring project removes any changes made to the project. If Deleting the self-monitoring project removes any changes made to the project. If
you create the project again, it's created in its default state. you create the project again, it's created in its default state.
1. On the top bar, select **Main menu > Admin**. 1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, go to **Settings > Metrics and profiling** and expand **Self monitoring**. 1. On the left sidebar, go to **Settings > Metrics and profiling** and expand **Self-monitoring**.
1. Toggle **Self monitoring** off. 1. Toggle **Self-monitoring** off.
1. In the confirmation dialog that opens, select **Delete self monitoring project**. 1. In the confirmation dialog that opens, select **Delete self-monitoring project**.
It can take a few seconds for it to be deleted. It can take a few seconds for it to be deleted.
1. After the project is deleted, GitLab displays a message confirming your action. 1. After the project is deleted, GitLab displays a message confirming your action.
@ -66,7 +66,7 @@ panels, provide a regular expression in the **Instance label regex** field.
The dashboard uses metrics available in The dashboard uses metrics available in
[Omnibus GitLab](https://docs.gitlab.com/omnibus/) installations. [Omnibus GitLab](https://docs.gitlab.com/omnibus/) installations.
![GitLab self monitoring overview dashboard](img/self_monitoring_overview_dashboard.png) ![GitLab self-monitoring overview dashboard](img/self_monitoring_overview_dashboard.png)
You can also You can also
[create your own dashboards](../../../operations/metrics/dashboards/index.md). [create your own dashboards](../../../operations/metrics/dashboards/index.md).
@ -88,9 +88,9 @@ to GitLab to receive notifications of any alerts.
Once the integration is setup, you can Once the integration is setup, you can
[take action on incoming alerts](../../../operations/metrics/alerts.md#trigger-actions-from-alerts). [take action on incoming alerts](../../../operations/metrics/alerts.md#trigger-actions-from-alerts).
## Add custom metrics to the self monitoring project ## Add custom metrics to the self-monitoring project
You can add custom metrics in the self monitoring project by: You can add custom metrics in the self-monitoring project by:
1. [Duplicating](../../../operations/metrics/dashboards/index.md#duplicate-a-gitlab-defined-dashboard) the overview dashboard. 1. [Duplicating](../../../operations/metrics/dashboards/index.md#duplicate-a-gitlab-defined-dashboard) the overview dashboard.
1. [Editing](../../../operations/metrics/index.md) the newly created dashboard file and configuring it with [dashboard YAML properties](../../../operations/metrics/dashboards/yaml.md). 1. [Editing](../../../operations/metrics/index.md) the newly created dashboard file and configuring it with [dashboard YAML properties](../../../operations/metrics/dashboards/yaml.md).

View file

@ -109,8 +109,8 @@ The **Metrics and profiling** settings contain:
Enable and configure Grafana. Enable and configure Grafana.
- [Profiling - Performance bar](../../../administration/monitoring/performance/performance_bar.md#enable-the-performance-bar-for-non-administrators) - - [Profiling - Performance bar](../../../administration/monitoring/performance/performance_bar.md#enable-the-performance-bar-for-non-administrators) -
Enable access to the Performance Bar for non-administrator users in a given group. Enable access to the Performance Bar for non-administrator users in a given group.
- [Self monitoring](../../../administration/monitoring/gitlab_self_monitoring_project/index.md#create-the-self-monitoring-project) - - [Self-monitoring](../../../administration/monitoring/gitlab_self_monitoring_project/index.md#create-the-self-monitoring-project) -
Enable or disable instance self monitoring. Enable or disable instance self-monitoring.
- [Usage statistics](usage_statistics.md) - Enable or disable version check and Service Ping. - [Usage statistics](usage_statistics.md) - Enable or disable version check and Service Ping.
### Network ### Network

View file

@ -42,7 +42,7 @@ module Gitlab
name = @command.yaml_processor_result.workflow_name name = @command.yaml_processor_result.workflow_name
pipeline.build_pipeline_metadata(project: pipeline.project, title: name) pipeline.build_pipeline_metadata(project: pipeline.project, name: name)
end end
def stage_names def stage_names

View file

@ -98,7 +98,7 @@ module Gitlab
if environment.save if environment.save
success(result) success(result)
else else
log_error("Could not create environment for the Self monitoring project. Errors: %{errors}" % { errors: environment.errors.full_messages }) log_error("Could not create environment for the Self-monitoring project. Errors: %{errors}" % { errors: environment.errors.full_messages })
error(_('Could not create environment')) error(_('Could not create environment'))
end end
end end

View file

@ -23,7 +23,7 @@ module Gitlab
def validate_self_monitoring_project_exists(result) def validate_self_monitoring_project_exists(result)
unless project_created? || self_monitoring_project_id.present? unless project_created? || self_monitoring_project_id.present?
return error(_('Self monitoring project does not exist')) return error(_('Self-monitoring project does not exist'))
end end
success(result) success(result)

View file

@ -585,7 +585,7 @@ included_attributes:
- :target_sha - :target_sha
pipeline_metadata: pipeline_metadata:
- :project_id - :project_id
- :title - :name
stages: stages:
- :name - :name
- :status - :status

View file

@ -78,7 +78,7 @@ module Gitlab
end end
def predefined_dashboard_services_for(project) def predefined_dashboard_services_for(project)
# Only list the self monitoring dashboard on the self monitoring project, # Only list the self-monitoring dashboard on the self-monitoring project,
# since it is the only dashboard (at time of writing) that shows data # since it is the only dashboard (at time of writing) that shows data
# about GitLab itself. # about GitLab itself.
if project.self_monitoring? if project.self_monitoring?

View file

@ -4,15 +4,16 @@ module Gitlab
class SidekiqMigrateJobs class SidekiqMigrateJobs
LOG_FREQUENCY = 1_000 LOG_FREQUENCY = 1_000
attr_reader :sidekiq_set, :logger attr_reader :logger, :mappings
def initialize(sidekiq_set, logger: nil) # mappings is a hash of WorkerClassName => target_queue_name
@sidekiq_set = sidekiq_set def initialize(mappings, logger: nil)
@mappings = mappings
@logger = logger @logger = logger
end end
# mappings is a hash of WorkerClassName => target_queue_name # Migrate jobs in SortedSets, i.e. scheduled and retry sets.
def execute(mappings) def migrate_set(sidekiq_set)
source_queues_regex = Regexp.union(mappings.keys) source_queues_regex = Regexp.union(mappings.keys)
cursor = 0 cursor = 0
scanned = 0 scanned = 0
@ -41,7 +42,7 @@ module Gitlab
job_hash['queue'] = destination_queue job_hash['queue'] = destination_queue
migrated += migrate_job(job, score, job_hash) migrated += migrate_job_in_set(sidekiq_set, job, score, job_hash)
end end
end while cursor.to_i != 0 end while cursor.to_i != 0
@ -53,9 +54,45 @@ module Gitlab
} }
end end
# Migrates jobs from queues that are outside the mappings
def migrate_queues
routing_rules_queues = mappings.values.uniq
logger&.info("List of queues based on routing rules: #{routing_rules_queues}")
Sidekiq.redis do |conn|
conn.scan_each(match: "queue:*", type: 'list') do |key|
queue_from = key.split(':', 2).last
next if routing_rules_queues.include?(queue_from)
logger&.info("Migrating #{queue_from} queue")
migrated = 0
while queue_length(queue_from) > 0
begin
if migrated >= 0 && migrated % LOG_FREQUENCY == 0
logger&.info("Migrating from #{queue_from}. Total: #{queue_length(queue_from)}. Migrated: #{migrated}.")
end
job = conn.rpop "queue:#{queue_from}"
job_hash = Sidekiq.load_json job
next unless mappings.has_key?(job_hash['class'])
destination_queue = mappings[job_hash['class']]
job_hash['queue'] = destination_queue
conn.lpush("queue:#{destination_queue}", Sidekiq.dump_json(job_hash))
migrated += 1
rescue JSON::ParserError
logger&.error("Unmarshal JSON payload from SidekiqMigrateJobs failed. Job: #{job}")
next
end
end
logger&.info("Finished migrating #{queue_from} queue")
end
end
end
private private
def migrate_job(job, score, job_hash) def migrate_job_in_set(sidekiq_set, job, score, job_hash)
Sidekiq.redis do |connection| Sidekiq.redis do |connection|
removed = connection.zrem(sidekiq_set, job) removed = connection.zrem(sidekiq_set, job)
@ -68,5 +105,11 @@ module Gitlab
end end
end end
end end
def queue_length(queue_name)
Sidekiq.redis do |conn|
conn.llen("queue:#{queue_name}")
end
end
end end
end end

View file

@ -10,15 +10,22 @@ namespace :gitlab do
desc 'GitLab | Sidekiq | Migrate jobs in the scheduled set to new queue names' desc 'GitLab | Sidekiq | Migrate jobs in the scheduled set to new queue names'
task schedule: :environment do task schedule: :environment do
::Gitlab::SidekiqMigrateJobs ::Gitlab::SidekiqMigrateJobs
.new('schedule', logger: Logger.new($stdout)) .new(::Gitlab::SidekiqConfig.worker_queue_mappings, logger: Logger.new($stdout) )
.execute(::Gitlab::SidekiqConfig.worker_queue_mappings) .migrate_set('schedule')
end end
desc 'GitLab | Sidekiq | Migrate jobs in the retry set to new queue names' desc 'GitLab | Sidekiq | Migrate jobs in the retry set to new queue names'
task retry: :environment do task retry: :environment do
::Gitlab::SidekiqMigrateJobs ::Gitlab::SidekiqMigrateJobs
.new('retry', logger: Logger.new($stdout)) .new(::Gitlab::SidekiqConfig.worker_queue_mappings, logger: Logger.new($stdout) )
.execute(::Gitlab::SidekiqConfig.worker_queue_mappings) .migrate_set('retry')
end
desc 'GitLab | Sidekiq | Migrate jobs in queues outside of routing rules'
task queued: :environment do
::Gitlab::SidekiqMigrateJobs
.new(::Gitlab::SidekiqConfig.worker_queue_mappings, logger: Logger.new($stdout) )
.migrate_queues
end end
end end

View file

@ -12826,7 +12826,7 @@ msgstr ""
msgid "Delete row" msgid "Delete row"
msgstr "" msgstr ""
msgid "Delete self monitoring project" msgid "Delete self-monitoring project"
msgstr "" msgstr ""
msgid "Delete snippet" msgid "Delete snippet"
@ -24042,9 +24042,6 @@ msgstr ""
msgid "Leave zen mode" msgid "Leave zen mode"
msgstr "" msgstr ""
msgid "Leaving this setting enabled is recommended."
msgstr ""
msgid "Legacy burndown chart" msgid "Legacy burndown chart"
msgstr "" msgstr ""
@ -34757,6 +34754,9 @@ msgstr ""
msgid "Run housekeeping" msgid "Run housekeeping"
msgstr "" msgstr ""
msgid "Run housekeeping tasks to automatically optimize Git repositories. Disabling this option will cause performance to degenerate over time."
msgstr ""
msgid "Run manual or delayed jobs" msgid "Run manual or delayed jobs"
msgstr "" msgstr ""
@ -36999,10 +36999,10 @@ msgstr ""
msgid "Selecting a GitLab user will add a link to the GitLab user in the descriptions of issues and comments (e.g. \"By %{link_open}@johnsmith%{link_close}\"). It will also associate and/or assign these issues and comments with the selected user." msgid "Selecting a GitLab user will add a link to the GitLab user in the descriptions of issues and comments (e.g. \"By %{link_open}@johnsmith%{link_close}\"). It will also associate and/or assign these issues and comments with the selected user."
msgstr "" msgstr ""
msgid "Self monitoring" msgid "Self-monitoring"
msgstr "" msgstr ""
msgid "Self monitoring project does not exist" msgid "Self-monitoring project does not exist"
msgstr "" msgstr ""
msgid "Self-monitoring project does not exist. Please check logs for any error messages" msgid "Self-monitoring project does not exist. Please check logs for any error messages"
@ -37014,28 +37014,28 @@ msgstr ""
msgid "Self-monitoring project was not deleted. Please check logs for any error messages" msgid "Self-monitoring project was not deleted. Please check logs for any error messages"
msgstr "" msgstr ""
msgid "SelfMonitoring|Activate or deactivate instance self monitoring." msgid "SelfMonitoring|Activate or deactivate instance self-monitoring."
msgstr "" msgstr ""
msgid "SelfMonitoring|Activate self monitoring to create a project to use to monitor the health of your instance." msgid "SelfMonitoring|Activate self-monitoring to create a project to use to monitor the health of your instance."
msgstr "" msgstr ""
msgid "SelfMonitoring|Deactivate self monitoring?" msgid "SelfMonitoring|Deactivate self-monitoring?"
msgstr "" msgstr ""
msgid "SelfMonitoring|Deactivating self monitoring deletes the self monitoring project. Are you sure you want to deactivate self monitoring and delete the project?" msgid "SelfMonitoring|Deactivating self-monitoring deletes the self-monitoring project. Are you sure you want to deactivate self-monitoring and delete the project?"
msgstr "" msgstr ""
msgid "SelfMonitoring|Self monitoring" msgid "SelfMonitoring|Self-monitoring"
msgstr "" msgstr ""
msgid "SelfMonitoring|Self monitoring is active. Use the %{projectLinkStart}self monitoring project%{projectLinkEnd} to monitor the health of your instance." msgid "SelfMonitoring|Self-monitoring is active. Use the %{projectLinkStart}self-monitoring project%{projectLinkEnd} to monitor the health of your instance."
msgstr "" msgstr ""
msgid "SelfMonitoring|Self monitoring project successfully created." msgid "SelfMonitoring|Self-monitoring project successfully created."
msgstr "" msgstr ""
msgid "SelfMonitoring|Self monitoring project successfully deleted." msgid "SelfMonitoring|Self-monitoring project successfully deleted."
msgstr "" msgstr ""
msgid "Send" msgid "Send"

View file

@ -2,7 +2,7 @@
FactoryBot.define do FactoryBot.define do
factory :ci_pipeline_metadata, class: 'Ci::PipelineMetadata' do factory :ci_pipeline_metadata, class: 'Ci::PipelineMetadata' do
title { 'Pipeline title' } name { 'Pipeline name' }
pipeline factory: :ci_empty_pipeline pipeline factory: :ci_empty_pipeline
project project

View file

@ -19,7 +19,7 @@ FactoryBot.define do
transient { child_of { nil } } transient { child_of { nil } }
transient { upstream_of { nil } } transient { upstream_of { nil } }
transient { title { nil } } transient { name { nil } }
after(:build) do |pipeline, evaluator| after(:build) do |pipeline, evaluator|
if evaluator.child_of if evaluator.child_of
@ -29,8 +29,8 @@ FactoryBot.define do
pipeline.ensure_project_iid! pipeline.ensure_project_iid!
if evaluator.title if evaluator.name
pipeline.pipeline_metadata = build(:ci_pipeline_metadata, title: evaluator.title, project: pipeline.project, pipeline: pipeline) pipeline.pipeline_metadata = build(:ci_pipeline_metadata, name: evaluator.name, project: pipeline.project, pipeline: pipeline)
end end
end end

View file

@ -4,5 +4,7 @@ FactoryBot.define do
factory :member_role do factory :member_role do
namespace { association(:group) } namespace { association(:group) }
base_access_level { Gitlab::Access::DEVELOPER } base_access_level { Gitlab::Access::DEVELOPER }
trait(:guest) { base_access_level { GroupMember::GUEST } }
end end
end end

View file

@ -467,6 +467,10 @@ FactoryBot.define do
end end
end end
trait :in_group do
namespace factory: [:group]
end
trait :in_subgroup do trait :in_subgroup do
namespace factory: [:group, :nested] namespace factory: [:group, :nested]
end end

View file

@ -6961,7 +6961,7 @@
"id": 2, "id": 2,
"pipeline_id": 36, "pipeline_id": 36,
"project_id": 5, "project_id": 5,
"title": "Build pipeline" "name": "Build pipeline"
}, },
"notes": [ "notes": [
{ {

View file

@ -1,7 +1,7 @@
{"id":19,"project_id":5,"ref":"master","sha":"2ea1f3dec713d940208fb5ce4a38765ecb5d3f73","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.763Z","updated_at":"2016-03-22T15:20:35.763Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[{"id":24,"project_id":5,"pipeline_id":40,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":79,"project_id":5,"status":"failed","finished_at":"2016-03-29T06:28:12.695Z","trace":"Sed culpa est et facere saepe vel id ab. Quas temporibus aut similique dolorem consequatur corporis aut praesentium. Cum officia molestiae sit earum excepturi.\n\nSint possimus aut ratione quia. Quis nesciunt ratione itaque illo. Tenetur est dolor assumenda possimus voluptatem quia minima. Accusamus reprehenderit ut et itaque non reiciendis incidunt.\n\nRerum suscipit quibusdam dolore nam omnis. Consequatur ipsa nihil ut enim blanditiis delectus. Nulla quis hic occaecati mollitia qui placeat. Quo rerum sed perferendis a accusantium consequatur commodi ut. Sit quae et cumque vel eius tempora nostrum.\n\nUllam dolorem et itaque sint est. Ea molestias quia provident dolorem vitae error et et. Ea expedita officiis iste non. Qui vitae odit saepe illum. Dolores enim ratione deserunt tempore expedita amet non neque.\n\nEligendi asperiores voluptatibus omnis repudiandae expedita distinctio qui aliquid. Autem aut doloremque distinctio ab. Nostrum sapiente repudiandae aspernatur ea et quae voluptas. Officiis perspiciatis nisi laudantium asperiores error eligendi ab. Eius quia amet magni omnis exercitationem voluptatum et.\n\nVoluptatem ullam labore quas dicta est ex voluptas. Pariatur ea modi voluptas consequatur dolores perspiciatis similique. Numquam in distinctio perspiciatis ut qui earum. Quidem omnis mollitia facere aut beatae. Ea est iure et voluptatem.","created_at":"2016-03-22T15:20:35.950Z","updated_at":"2016-03-29T06:28:12.696Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":40,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null},{"id":80,"project_id":5,"status":"success","finished_at":null,"trace":"Impedit et optio nemo ipsa. Non ad non quis ut sequi laudantium omnis velit. Corporis a enim illo eos. Quia totam tempore inventore ad est.\n\nNihil recusandae cupiditate eaque voluptatem molestias sint. Consequatur id voluptatem cupiditate harum. Consequuntur iusto quaerat reiciendis aut autem libero est. Quisquam dolores veritatis rerum et sint maxime ullam libero. Id quas porro ut perspiciatis rem amet vitae.\n\nNemo inventore minus blanditiis magnam. Modi consequuntur nostrum aut voluptatem ex. Sunt rerum rem optio mollitia qui aliquam officiis officia. Aliquid eos et id aut minus beatae reiciendis.\n\nDolores non in temporibus dicta. Fugiat voluptatem est aspernatur expedita voluptatum nam qui. Quia et eligendi sit quae sint tempore exercitationem eos. Est sapiente corrupti quidem at. Qui magni odio repudiandae saepe tenetur optio dolore.\n\nEos placeat soluta at dolorem adipisci provident. Quo commodi id reprehenderit possimus quo tenetur. Ipsum et quae eligendi laborum. Et qui nesciunt at quasi quidem voluptatem cum rerum. Excepturi non facilis aut sunt vero sed.\n\nQui explicabo ratione ut eligendi recusandae. Quis quasi quas molestiae consequatur voluptatem et voluptatem. Ex repellat saepe occaecati aperiam ea eveniet dignissimos facilis.","created_at":"2016-03-22T15:20:35.966Z","updated_at":"2016-03-22T15:20:35.966Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":40,"commands":"$ build command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]}]} {"id":19,"project_id":5,"ref":"master","sha":"2ea1f3dec713d940208fb5ce4a38765ecb5d3f73","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.763Z","updated_at":"2016-03-22T15:20:35.763Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[{"id":24,"project_id":5,"pipeline_id":40,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":79,"project_id":5,"status":"failed","finished_at":"2016-03-29T06:28:12.695Z","trace":"Sed culpa est et facere saepe vel id ab. Quas temporibus aut similique dolorem consequatur corporis aut praesentium. Cum officia molestiae sit earum excepturi.\n\nSint possimus aut ratione quia. Quis nesciunt ratione itaque illo. Tenetur est dolor assumenda possimus voluptatem quia minima. Accusamus reprehenderit ut et itaque non reiciendis incidunt.\n\nRerum suscipit quibusdam dolore nam omnis. Consequatur ipsa nihil ut enim blanditiis delectus. Nulla quis hic occaecati mollitia qui placeat. Quo rerum sed perferendis a accusantium consequatur commodi ut. Sit quae et cumque vel eius tempora nostrum.\n\nUllam dolorem et itaque sint est. Ea molestias quia provident dolorem vitae error et et. Ea expedita officiis iste non. Qui vitae odit saepe illum. Dolores enim ratione deserunt tempore expedita amet non neque.\n\nEligendi asperiores voluptatibus omnis repudiandae expedita distinctio qui aliquid. Autem aut doloremque distinctio ab. Nostrum sapiente repudiandae aspernatur ea et quae voluptas. Officiis perspiciatis nisi laudantium asperiores error eligendi ab. Eius quia amet magni omnis exercitationem voluptatum et.\n\nVoluptatem ullam labore quas dicta est ex voluptas. Pariatur ea modi voluptas consequatur dolores perspiciatis similique. Numquam in distinctio perspiciatis ut qui earum. Quidem omnis mollitia facere aut beatae. Ea est iure et voluptatem.","created_at":"2016-03-22T15:20:35.950Z","updated_at":"2016-03-29T06:28:12.696Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":40,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null},{"id":80,"project_id":5,"status":"success","finished_at":null,"trace":"Impedit et optio nemo ipsa. Non ad non quis ut sequi laudantium omnis velit. Corporis a enim illo eos. Quia totam tempore inventore ad est.\n\nNihil recusandae cupiditate eaque voluptatem molestias sint. Consequatur id voluptatem cupiditate harum. Consequuntur iusto quaerat reiciendis aut autem libero est. Quisquam dolores veritatis rerum et sint maxime ullam libero. Id quas porro ut perspiciatis rem amet vitae.\n\nNemo inventore minus blanditiis magnam. Modi consequuntur nostrum aut voluptatem ex. Sunt rerum rem optio mollitia qui aliquam officiis officia. Aliquid eos et id aut minus beatae reiciendis.\n\nDolores non in temporibus dicta. Fugiat voluptatem est aspernatur expedita voluptatum nam qui. Quia et eligendi sit quae sint tempore exercitationem eos. Est sapiente corrupti quidem at. Qui magni odio repudiandae saepe tenetur optio dolore.\n\nEos placeat soluta at dolorem adipisci provident. Quo commodi id reprehenderit possimus quo tenetur. Ipsum et quae eligendi laborum. Et qui nesciunt at quasi quidem voluptatem cum rerum. Excepturi non facilis aut sunt vero sed.\n\nQui explicabo ratione ut eligendi recusandae. Quis quasi quas molestiae consequatur voluptatem et voluptatem. Ex repellat saepe occaecati aperiam ea eveniet dignissimos facilis.","created_at":"2016-03-22T15:20:35.966Z","updated_at":"2016-03-22T15:20:35.966Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":40,"commands":"$ build command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]}]}
{"id":20,"project_id":5,"ref":"master","sha":"ce84140e8b878ce6e7c4d298c7202ff38170e3ac","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.763Z","updated_at":"2016-03-22T15:20:35.763Z","tag":false,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[],"source":"external_pull_request_event","external_pull_request":{"id":3,"pull_request_iid":4,"source_branch":"feature","target_branch":"master","source_repository":"the-repository","target_repository":"the-repository","source_sha":"ce84140e8b878ce6e7c4d298c7202ff38170e3ac","target_sha":"a09386439ca39abe575675ffd4b89ae824fec22f","status":"open","created_at":"2016-03-22T15:20:35.763Z","updated_at":"2016-03-22T15:20:35.763Z"}} {"id":20,"project_id":5,"ref":"master","sha":"ce84140e8b878ce6e7c4d298c7202ff38170e3ac","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.763Z","updated_at":"2016-03-22T15:20:35.763Z","tag":false,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[],"source":"external_pull_request_event","external_pull_request":{"id":3,"pull_request_iid":4,"source_branch":"feature","target_branch":"master","source_repository":"the-repository","target_repository":"the-repository","source_sha":"ce84140e8b878ce6e7c4d298c7202ff38170e3ac","target_sha":"a09386439ca39abe575675ffd4b89ae824fec22f","status":"open","created_at":"2016-03-22T15:20:35.763Z","updated_at":"2016-03-22T15:20:35.763Z"}}
{"id":26,"project_id":5,"ref":"master","sha":"048721d90c449b244b7b4c53a9186b04330174ec","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.757Z","updated_at":"2016-03-22T15:20:35.757Z","tag":false,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"source":"merge_request_event","merge_request_id":27,"stages":[{"id":21,"project_id":5,"pipeline_id":37,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":74,"project_id":5,"status":"success","finished_at":null,"trace":"Ad ut quod repudiandae iste dolor doloribus. Adipisci consequuntur deserunt omnis quasi eveniet et sed fugit. Aut nemo omnis molestiae impedit ex consequatur ducimus. Voluptatum exercitationem quia aut est et hic dolorem.\n\nQuasi repellendus et eaque magni eum facilis. Dolorem aperiam nam nihil pariatur praesentium ad aliquam. Commodi enim et eos tenetur. Odio voluptatibus laboriosam mollitia rerum exercitationem magnam consequuntur. Tenetur ea vel eum corporis.\n\nVoluptatibus optio in aliquid est voluptates. Ad a ut ab placeat vero blanditiis. Earum aspernatur quia beatae expedita voluptatem dignissimos provident. Quis minima id nemo ut aut est veritatis provident.\n\nRerum voluptatem quidem eius maiores magnam veniam. Voluptatem aperiam aut voluptate et nulla deserunt voluptas. Quaerat aut accusantium laborum est dolorem architecto reiciendis. Aliquam asperiores doloribus omnis maxime enim nesciunt. Eum aut rerum repellendus debitis et ut eius.\n\nQuaerat assumenda ea sit consequatur autem in. Cum eligendi voluptatem quo sed. Ut fuga iusto cupiditate autem sint.\n\nOfficia totam officiis architecto corporis molestiae amet ut. Tempora sed dolorum rerum omnis voluptatem accusantium sit eum. Quia debitis ipsum quidem aliquam inventore sunt consequatur qui.","created_at":"2016-03-22T15:20:35.846Z","updated_at":"2016-03-22T15:20:35.846Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":37,"commands":"$ build command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null},{"id":73,"project_id":5,"status":"canceled","finished_at":null,"trace":null,"created_at":"2016-03-22T15:20:35.842Z","updated_at":"2016-03-22T15:20:35.842Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":37,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]}],"merge_request":{"id":27,"target_branch":"feature","source_branch":"feature_conflict","source_project_id":2147483547,"author_id":1,"assignee_id":null,"title":"MR1","created_at":"2016-06-14T15:02:36.568Z","updated_at":"2016-06-14T15:02:56.815Z","state":"opened","merge_status":"unchecked","target_project_id":5,"iid":9,"description":null,"position":0,"updated_by_id":null,"merge_error":null,"diff_head_sha":"HEAD","source_branch_sha":"ABCD","target_branch_sha":"DCBA","merge_params":{"force_remove_source_branch":null}}} {"id":26,"project_id":5,"ref":"master","sha":"048721d90c449b244b7b4c53a9186b04330174ec","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.757Z","updated_at":"2016-03-22T15:20:35.757Z","tag":false,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"source":"merge_request_event","merge_request_id":27,"stages":[{"id":21,"project_id":5,"pipeline_id":37,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":74,"project_id":5,"status":"success","finished_at":null,"trace":"Ad ut quod repudiandae iste dolor doloribus. Adipisci consequuntur deserunt omnis quasi eveniet et sed fugit. Aut nemo omnis molestiae impedit ex consequatur ducimus. Voluptatum exercitationem quia aut est et hic dolorem.\n\nQuasi repellendus et eaque magni eum facilis. Dolorem aperiam nam nihil pariatur praesentium ad aliquam. Commodi enim et eos tenetur. Odio voluptatibus laboriosam mollitia rerum exercitationem magnam consequuntur. Tenetur ea vel eum corporis.\n\nVoluptatibus optio in aliquid est voluptates. Ad a ut ab placeat vero blanditiis. Earum aspernatur quia beatae expedita voluptatem dignissimos provident. Quis minima id nemo ut aut est veritatis provident.\n\nRerum voluptatem quidem eius maiores magnam veniam. Voluptatem aperiam aut voluptate et nulla deserunt voluptas. Quaerat aut accusantium laborum est dolorem architecto reiciendis. Aliquam asperiores doloribus omnis maxime enim nesciunt. Eum aut rerum repellendus debitis et ut eius.\n\nQuaerat assumenda ea sit consequatur autem in. Cum eligendi voluptatem quo sed. Ut fuga iusto cupiditate autem sint.\n\nOfficia totam officiis architecto corporis molestiae amet ut. Tempora sed dolorum rerum omnis voluptatem accusantium sit eum. Quia debitis ipsum quidem aliquam inventore sunt consequatur qui.","created_at":"2016-03-22T15:20:35.846Z","updated_at":"2016-03-22T15:20:35.846Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":37,"commands":"$ build command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null},{"id":73,"project_id":5,"status":"canceled","finished_at":null,"trace":null,"created_at":"2016-03-22T15:20:35.842Z","updated_at":"2016-03-22T15:20:35.842Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":37,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]}],"merge_request":{"id":27,"target_branch":"feature","source_branch":"feature_conflict","source_project_id":2147483547,"author_id":1,"assignee_id":null,"title":"MR1","created_at":"2016-06-14T15:02:36.568Z","updated_at":"2016-06-14T15:02:56.815Z","state":"opened","merge_status":"unchecked","target_project_id":5,"iid":9,"description":null,"position":0,"updated_by_id":null,"merge_error":null,"diff_head_sha":"HEAD","source_branch_sha":"ABCD","target_branch_sha":"DCBA","merge_params":{"force_remove_source_branch":null}}}
{"id":36,"project_id":5,"ref":null,"sha":"sha-notes","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.755Z","updated_at":"2016-03-22T15:20:35.755Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"user_id":2147483547,"duration":null,"source":"push","merge_request_id":null,"pipeline_metadata": {"id": 2, "project_id": 5, "pipeline_id": 36, "title": "Build pipeline"},"notes":[{"id":2147483547,"note":"Natus rerum qui dolorem dolorum voluptas.","noteable_type":"Commit","author_id":1,"created_at":"2016-03-22T15:19:59.469Z","updated_at":"2016-03-22T15:19:59.469Z","project_id":5,"attachment":{"url":null},"line_code":null,"commit_id":"be93687618e4b132087f430a4d8fc3a609c9b77c","noteable_id":36,"system":false,"st_diff":null,"updated_by_id":null,"author":{"name":"Administrator"}}],"stages":[{"id":11,"project_id":5,"pipeline_id":36,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":71,"project_id":5,"status":"failed","finished_at":"2016-03-29T06:28:12.630Z","trace":null,"created_at":"2016-03-22T15:20:35.772Z","updated_at":"2016-03-29T06:28:12.634Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":36,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":{"image":"busybox:latest"},"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"stage_id":11,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null,"type":"Ci::Build","token":"abcd","artifacts_file_store":1,"artifacts_metadata_store":1,"artifacts_size":10},{"id":72,"project_id":5,"status":"success","finished_at":null,"trace":"Porro ea qui ut dolores. Labore ab nemo explicabo aspernatur quis voluptates corporis. Et quasi delectus est sit aperiam perspiciatis asperiores. Repudiandae cum aut consectetur accusantium officia sunt.\n\nQuidem dolore iusto quaerat ut aut inventore et molestiae. Libero voluptates atque nemo qui. Nulla temporibus ipsa similique facere.\n\nAliquam ipsam perferendis qui fugit accusantium omnis id voluptatum. Dignissimos aliquid dicta eos voluptatem assumenda quia. Sed autem natus unde dolor et non nisi et. Consequuntur nihil consequatur rerum est.\n\nSimilique neque est iste ducimus qui fuga cupiditate. Libero autem est aut fuga. Consectetur natus quis non ducimus ut dolore. Magni voluptatibus eius et maxime aut.\n\nAd officiis tempore voluptate vitae corrupti explicabo labore est. Consequatur expedita et sunt nihil aut. Deleniti porro iusto molestiae et beatae.\n\nDeleniti modi nulla qui et labore sequi corrupti. Qui voluptatem assumenda eum cupiditate et. Nesciunt ipsam ut ea possimus eum. Consectetur quidem suscipit atque dolore itaque voluptatibus et cupiditate.","created_at":"2016-03-22T15:20:35.777Z","updated_at":"2016-03-22T15:20:35.777Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":36,"commands":"$ deploy command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"deploy","trigger_request_id":null,"stage_idx":1,"stage_id":12,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]},{"id":12,"project_id":5,"pipeline_id":36,"name":"deploy","status":2,"created_at":"2016-03-22T15:45:45.772Z","updated_at":"2016-03-29T06:45:45.634Z"}]} {"id":36,"project_id":5,"ref":null,"sha":"sha-notes","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.755Z","updated_at":"2016-03-22T15:20:35.755Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"user_id":2147483547,"duration":null,"source":"push","merge_request_id":null,"pipeline_metadata": {"id": 2, "project_id": 5, "pipeline_id": 36, "name": "Build pipeline"},"notes":[{"id":2147483547,"note":"Natus rerum qui dolorem dolorum voluptas.","noteable_type":"Commit","author_id":1,"created_at":"2016-03-22T15:19:59.469Z","updated_at":"2016-03-22T15:19:59.469Z","project_id":5,"attachment":{"url":null},"line_code":null,"commit_id":"be93687618e4b132087f430a4d8fc3a609c9b77c","noteable_id":36,"system":false,"st_diff":null,"updated_by_id":null,"author":{"name":"Administrator"}}],"stages":[{"id":11,"project_id":5,"pipeline_id":36,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":71,"project_id":5,"status":"failed","finished_at":"2016-03-29T06:28:12.630Z","trace":null,"created_at":"2016-03-22T15:20:35.772Z","updated_at":"2016-03-29T06:28:12.634Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":36,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":{"image":"busybox:latest"},"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"stage_id":11,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null,"type":"Ci::Build","token":"abcd","artifacts_file_store":1,"artifacts_metadata_store":1,"artifacts_size":10},{"id":72,"project_id":5,"status":"success","finished_at":null,"trace":"Porro ea qui ut dolores. Labore ab nemo explicabo aspernatur quis voluptates corporis. Et quasi delectus est sit aperiam perspiciatis asperiores. Repudiandae cum aut consectetur accusantium officia sunt.\n\nQuidem dolore iusto quaerat ut aut inventore et molestiae. Libero voluptates atque nemo qui. Nulla temporibus ipsa similique facere.\n\nAliquam ipsam perferendis qui fugit accusantium omnis id voluptatum. Dignissimos aliquid dicta eos voluptatem assumenda quia. Sed autem natus unde dolor et non nisi et. Consequuntur nihil consequatur rerum est.\n\nSimilique neque est iste ducimus qui fuga cupiditate. Libero autem est aut fuga. Consectetur natus quis non ducimus ut dolore. Magni voluptatibus eius et maxime aut.\n\nAd officiis tempore voluptate vitae corrupti explicabo labore est. Consequatur expedita et sunt nihil aut. Deleniti porro iusto molestiae et beatae.\n\nDeleniti modi nulla qui et labore sequi corrupti. Qui voluptatem assumenda eum cupiditate et. Nesciunt ipsam ut ea possimus eum. Consectetur quidem suscipit atque dolore itaque voluptatibus et cupiditate.","created_at":"2016-03-22T15:20:35.777Z","updated_at":"2016-03-22T15:20:35.777Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":36,"commands":"$ deploy command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"deploy","trigger_request_id":null,"stage_idx":1,"stage_id":12,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]},{"id":12,"project_id":5,"pipeline_id":36,"name":"deploy","status":2,"created_at":"2016-03-22T15:45:45.772Z","updated_at":"2016-03-29T06:45:45.634Z"}]}
{"id":38,"iid":1,"project_id":5,"ref":"master","sha":"5f923865dde3436854e9ceb9cdb7815618d4e849","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.759Z","updated_at":"2016-03-22T15:20:35.759Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[{"id":22,"project_id":5,"pipeline_id":38,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":76,"project_id":5,"status":"success","finished_at":null,"trace":"Et rerum quia ea cumque ut modi non. Libero eaque ipsam architecto maiores expedita deleniti. Ratione quia qui est id.\n\nQuod sit officiis sed unde inventore veniam quisquam velit. Ea harum cum quibusdam quisquam minima quo possimus non. Temporibus itaque aliquam aut rerum veritatis at.\n\nMagnam ipsum eius recusandae qui quis sit maiores eum. Et animi iusto aut itaque. Doloribus harum deleniti nobis accusantium et libero.\n\nRerum fuga perferendis magni commodi officiis id repudiandae. Consequatur ratione consequatur suscipit facilis sunt iure est dicta. Qui unde quasi facilis et quae nesciunt. Magnam iste et nobis officiis tenetur. Aspernatur quo et temporibus non in.\n\nNisi rerum velit est ad enim sint molestiae consequuntur. Quaerat nisi nesciunt quasi officiis. Possimus non blanditiis laborum quos.\n\nRerum laudantium facere animi qui. Ipsa est iusto magnam nihil. Enim omnis occaecati non dignissimos ut recusandae eum quasi. Qui maxime dolor et nemo voluptates incidunt quia.","created_at":"2016-03-22T15:20:35.882Z","updated_at":"2016-03-22T15:20:35.882Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":38,"commands":"$ build command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null},{"id":75,"project_id":5,"status":"failed","finished_at":null,"trace":"Sed et iste recusandae dicta corporis. Sunt alias porro fugit sunt. Fugiat omnis nihil dignissimos aperiam explicabo doloremque sit aut. Harum fugit expedita quia rerum ut consequatur laboriosam aliquam.\n\nNatus libero ut ut tenetur earum. Tempora omnis autem omnis et libero dolores illum autem. Deleniti eos sunt mollitia ipsam. Cum dolor repellendus dolorum sequi officia. Ullam sunt in aut pariatur excepturi.\n\nDolor nihil debitis et est eos. Cumque eos eum saepe ducimus autem. Alias architecto consequatur aut pariatur possimus. Aut quos aut incidunt quam velit et. Quas voluptatum ad dolorum dignissimos.\n\nUt voluptates consectetur illo et. Est commodi accusantium vel quo. Eos qui fugiat soluta porro.\n\nRatione possimus alias vel maxime sint totam est repellat. Ipsum corporis eos sint voluptatem eos odit. Temporibus libero nulla harum eligendi labore similique ratione magnam. Suscipit sequi in omnis neque.\n\nLaudantium dolor amet omnis placeat mollitia aut molestiae. Aut rerum similique ipsum quod illo quas unde. Sunt aut veritatis eos omnis porro. Rem veritatis mollitia praesentium dolorem. Consequatur sequi ad cumque earum omnis quia necessitatibus.","created_at":"2016-03-22T15:20:35.864Z","updated_at":"2016-03-22T15:20:35.864Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":38,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]}]} {"id":38,"iid":1,"project_id":5,"ref":"master","sha":"5f923865dde3436854e9ceb9cdb7815618d4e849","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.759Z","updated_at":"2016-03-22T15:20:35.759Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[{"id":22,"project_id":5,"pipeline_id":38,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":76,"project_id":5,"status":"success","finished_at":null,"trace":"Et rerum quia ea cumque ut modi non. Libero eaque ipsam architecto maiores expedita deleniti. Ratione quia qui est id.\n\nQuod sit officiis sed unde inventore veniam quisquam velit. Ea harum cum quibusdam quisquam minima quo possimus non. Temporibus itaque aliquam aut rerum veritatis at.\n\nMagnam ipsum eius recusandae qui quis sit maiores eum. Et animi iusto aut itaque. Doloribus harum deleniti nobis accusantium et libero.\n\nRerum fuga perferendis magni commodi officiis id repudiandae. Consequatur ratione consequatur suscipit facilis sunt iure est dicta. Qui unde quasi facilis et quae nesciunt. Magnam iste et nobis officiis tenetur. Aspernatur quo et temporibus non in.\n\nNisi rerum velit est ad enim sint molestiae consequuntur. Quaerat nisi nesciunt quasi officiis. Possimus non blanditiis laborum quos.\n\nRerum laudantium facere animi qui. Ipsa est iusto magnam nihil. Enim omnis occaecati non dignissimos ut recusandae eum quasi. Qui maxime dolor et nemo voluptates incidunt quia.","created_at":"2016-03-22T15:20:35.882Z","updated_at":"2016-03-22T15:20:35.882Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":38,"commands":"$ build command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null},{"id":75,"project_id":5,"status":"failed","finished_at":null,"trace":"Sed et iste recusandae dicta corporis. Sunt alias porro fugit sunt. Fugiat omnis nihil dignissimos aperiam explicabo doloremque sit aut. Harum fugit expedita quia rerum ut consequatur laboriosam aliquam.\n\nNatus libero ut ut tenetur earum. Tempora omnis autem omnis et libero dolores illum autem. Deleniti eos sunt mollitia ipsam. Cum dolor repellendus dolorum sequi officia. Ullam sunt in aut pariatur excepturi.\n\nDolor nihil debitis et est eos. Cumque eos eum saepe ducimus autem. Alias architecto consequatur aut pariatur possimus. Aut quos aut incidunt quam velit et. Quas voluptatum ad dolorum dignissimos.\n\nUt voluptates consectetur illo et. Est commodi accusantium vel quo. Eos qui fugiat soluta porro.\n\nRatione possimus alias vel maxime sint totam est repellat. Ipsum corporis eos sint voluptatem eos odit. Temporibus libero nulla harum eligendi labore similique ratione magnam. Suscipit sequi in omnis neque.\n\nLaudantium dolor amet omnis placeat mollitia aut molestiae. Aut rerum similique ipsum quod illo quas unde. Sunt aut veritatis eos omnis porro. Rem veritatis mollitia praesentium dolorem. Consequatur sequi ad cumque earum omnis quia necessitatibus.","created_at":"2016-03-22T15:20:35.864Z","updated_at":"2016-03-22T15:20:35.864Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":38,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]}]}
{"id":39,"project_id":5,"ref":"master","sha":"d2d430676773caa88cdaf7c55944073b2fd5561a","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.761Z","updated_at":"2016-03-22T15:20:35.761Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[{"id":23,"project_id":5,"pipeline_id":39,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":78,"project_id":5,"status":"success","finished_at":null,"trace":"Dolorem deserunt quas quia error hic quo cum vel. Natus voluptatem cumque expedita numquam odit. Eos expedita nostrum corporis consequatur est recusandae.\n\nCulpa blanditiis rerum repudiandae alias voluptatem. Velit iusto est ullam consequatur doloribus porro. Corporis voluptas consectetur est veniam et quia quae.\n\nEt aut magni fuga nesciunt officiis molestias. Quaerat et nam necessitatibus qui rerum. Architecto quia officiis voluptatem laborum est recusandae. Quasi ducimus soluta odit necessitatibus labore numquam dignissimos. Quia facere sint temporibus inventore sunt nihil saepe dolorum.\n\nFacere dolores quis dolores a. Est minus nostrum nihil harum. Earum laborum et ipsum unde neque sit nemo. Corrupti est consequatur minima fugit. Illum voluptatem illo error ducimus officia qui debitis.\n\nDignissimos porro a autem harum aut. Aut id reprehenderit et exercitationem. Est et quisquam ipsa temporibus molestiae. Architecto natus dolore qui fugiat incidunt. Autem odit veniam excepturi et voluptatibus culpa ipsum eos.\n\nAmet quo quisquam dignissimos soluta modi dolores. Sint omnis eius optio corporis dolor. Eligendi animi porro quia placeat ut.","created_at":"2016-03-22T15:20:35.927Z","updated_at":"2016-03-22T15:20:35.927Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":39,"commands":"$ build command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null},{"id":77,"project_id":5,"status":"failed","finished_at":null,"trace":"Rerum ut et suscipit est perspiciatis. Inventore debitis cum eius vitae. Ex incidunt id velit aut quo nisi. Laboriosam repellat deserunt eius reiciendis architecto et. Est harum quos nesciunt nisi consectetur.\n\nAlias esse omnis sint officia est consequatur in nobis. Dignissimos dolorum vel eligendi nesciunt dolores sit. Veniam mollitia ducimus et exercitationem molestiae libero sed. Atque omnis debitis laudantium voluptatibus qui. Repellendus tempore est commodi pariatur.\n\nExpedita voluptate illum est alias non. Modi nesciunt ab assumenda laborum nulla consequatur molestias doloremque. Magnam quod officia vel explicabo accusamus ut voluptatem incidunt. Rerum ut aliquid ullam saepe. Est eligendi debitis beatae blanditiis reiciendis.\n\nQui fuga sit dolores libero maiores et suscipit. Consectetur asperiores omnis minima impedit eos fugiat. Similique omnis nisi sed vero inventore ipsum aliquam exercitationem.\n\nBlanditiis magni iure dolorum omnis ratione delectus molestiae. Atque officia dolor voluptatem culpa quod. Incidunt suscipit quidem possimus veritatis non vel. Iusto aliquid et id quia quasi.\n\nVel facere velit blanditiis incidunt cupiditate sed maiores consequuntur. Quasi quia dicta consequuntur et quia voluptatem iste id. Incidunt et rerum fuga esse sint.","created_at":"2016-03-22T15:20:35.905Z","updated_at":"2016-03-22T15:20:35.905Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":39,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]}]} {"id":39,"project_id":5,"ref":"master","sha":"d2d430676773caa88cdaf7c55944073b2fd5561a","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.761Z","updated_at":"2016-03-22T15:20:35.761Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[{"id":23,"project_id":5,"pipeline_id":39,"name":"test","status":1,"created_at":"2016-03-22T15:44:44.772Z","updated_at":"2016-03-29T06:44:44.634Z","statuses":[{"id":78,"project_id":5,"status":"success","finished_at":null,"trace":"Dolorem deserunt quas quia error hic quo cum vel. Natus voluptatem cumque expedita numquam odit. Eos expedita nostrum corporis consequatur est recusandae.\n\nCulpa blanditiis rerum repudiandae alias voluptatem. Velit iusto est ullam consequatur doloribus porro. Corporis voluptas consectetur est veniam et quia quae.\n\nEt aut magni fuga nesciunt officiis molestias. Quaerat et nam necessitatibus qui rerum. Architecto quia officiis voluptatem laborum est recusandae. Quasi ducimus soluta odit necessitatibus labore numquam dignissimos. Quia facere sint temporibus inventore sunt nihil saepe dolorum.\n\nFacere dolores quis dolores a. Est minus nostrum nihil harum. Earum laborum et ipsum unde neque sit nemo. Corrupti est consequatur minima fugit. Illum voluptatem illo error ducimus officia qui debitis.\n\nDignissimos porro a autem harum aut. Aut id reprehenderit et exercitationem. Est et quisquam ipsa temporibus molestiae. Architecto natus dolore qui fugiat incidunt. Autem odit veniam excepturi et voluptatibus culpa ipsum eos.\n\nAmet quo quisquam dignissimos soluta modi dolores. Sint omnis eius optio corporis dolor. Eligendi animi porro quia placeat ut.","created_at":"2016-03-22T15:20:35.927Z","updated_at":"2016-03-22T15:20:35.927Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":39,"commands":"$ build command","job_id":null,"name":"test build 2","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null},{"id":77,"project_id":5,"status":"failed","finished_at":null,"trace":"Rerum ut et suscipit est perspiciatis. Inventore debitis cum eius vitae. Ex incidunt id velit aut quo nisi. Laboriosam repellat deserunt eius reiciendis architecto et. Est harum quos nesciunt nisi consectetur.\n\nAlias esse omnis sint officia est consequatur in nobis. Dignissimos dolorum vel eligendi nesciunt dolores sit. Veniam mollitia ducimus et exercitationem molestiae libero sed. Atque omnis debitis laudantium voluptatibus qui. Repellendus tempore est commodi pariatur.\n\nExpedita voluptate illum est alias non. Modi nesciunt ab assumenda laborum nulla consequatur molestias doloremque. Magnam quod officia vel explicabo accusamus ut voluptatem incidunt. Rerum ut aliquid ullam saepe. Est eligendi debitis beatae blanditiis reiciendis.\n\nQui fuga sit dolores libero maiores et suscipit. Consectetur asperiores omnis minima impedit eos fugiat. Similique omnis nisi sed vero inventore ipsum aliquam exercitationem.\n\nBlanditiis magni iure dolorum omnis ratione delectus molestiae. Atque officia dolor voluptatem culpa quod. Incidunt suscipit quidem possimus veritatis non vel. Iusto aliquid et id quia quasi.\n\nVel facere velit blanditiis incidunt cupiditate sed maiores consequuntur. Quasi quia dicta consequuntur et quia voluptatem iste id. Incidunt et rerum fuga esse sint.","created_at":"2016-03-22T15:20:35.905Z","updated_at":"2016-03-22T15:20:35.905Z","started_at":null,"runner_id":null,"coverage":null,"commit_id":39,"commands":"$ build command","job_id":null,"name":"test build 1","deploy":false,"options":null,"allow_failure":false,"stage":"test","trigger_request_id":null,"stage_idx":1,"tag":null,"ref":"master","user_id":null,"target_url":null,"description":null,"erased_by_id":null,"erased_at":null}]}]}
{"id":41,"project_id":5,"ref":"master","sha":"2ea1f3dec713d940208fb5ce4a38765ecb5d3f73","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.763Z","updated_at":"2016-03-22T15:20:35.763Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[]} {"id":41,"project_id":5,"ref":"master","sha":"2ea1f3dec713d940208fb5ce4a38765ecb5d3f73","before_sha":null,"push_data":null,"created_at":"2016-03-22T15:20:35.763Z","updated_at":"2016-03-22T15:20:35.763Z","tag":null,"yaml_errors":null,"committed_at":null,"status":"failed","started_at":null,"finished_at":null,"duration":null,"stages":[]}

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`self monitor component When the self monitor project has not been created default state to match the default snapshot 1`] = ` exports[`self-monitor component When the self-monitor project has not been created default state to match the default snapshot 1`] = `
<section <section
class="settings no-animate js-self-monitoring-settings" class="settings no-animate js-self-monitoring-settings"
> >
@ -11,7 +11,7 @@ exports[`self monitor component When the self monitor project has not been creat
class="js-section-header settings-title js-settings-toggle js-settings-toggle-trigger-only" class="js-section-header settings-title js-settings-toggle js-settings-toggle-trigger-only"
> >
Self monitoring Self-monitoring
</h4> </h4>
@ -30,7 +30,7 @@ exports[`self monitor component When the self monitor project has not been creat
class="js-section-sub-header" class="js-section-sub-header"
> >
Activate or deactivate instance self monitoring. Activate or deactivate instance self-monitoring.
<gl-link-stub <gl-link-stub
href="/help/administration/monitoring/gitlab_self_monitoring_project/index" href="/help/administration/monitoring/gitlab_self_monitoring_project/index"
@ -47,7 +47,7 @@ exports[`self monitor component When the self monitor project has not been creat
name="self-monitoring-form" name="self-monitoring-form"
> >
<p> <p>
Activate self monitoring to create a project to use to monitor the health of your instance. Activate self-monitoring to create a project to use to monitor the health of your instance.
</p> </p>
<gl-form-group-stub <gl-form-group-stub
@ -55,7 +55,7 @@ exports[`self monitor component When the self monitor project has not been creat
optionaltext="(optional)" optionaltext="(optional)"
> >
<gl-toggle-stub <gl-toggle-stub
label="Self monitoring" label="Self-monitoring"
labelposition="top" labelposition="top"
/> />
</gl-form-group-stub> </gl-form-group-stub>
@ -69,15 +69,15 @@ exports[`self monitor component When the self monitor project has not been creat
dismisslabel="Close" dismisslabel="Close"
modalclass="" modalclass=""
modalid="delete-self-monitor-modal" modalid="delete-self-monitor-modal"
ok-title="Delete self monitoring project" ok-title="Delete self-monitoring project"
ok-variant="danger" ok-variant="danger"
size="md" size="md"
title="Deactivate self monitoring?" title="Deactivate self-monitoring?"
titletag="h4" titletag="h4"
> >
<div> <div>
Deactivating self monitoring deletes the self monitoring project. Are you sure you want to deactivate self monitoring and delete the project? Deactivating self-monitoring deletes the self-monitoring project. Are you sure you want to deactivate self-monitoring and delete the project?
</div> </div>
</gl-modal-stub> </gl-modal-stub>

View file

@ -4,11 +4,11 @@ import { TEST_HOST } from 'helpers/test_constants';
import SelfMonitor from '~/self_monitor/components/self_monitor_form.vue'; import SelfMonitor from '~/self_monitor/components/self_monitor_form.vue';
import { createStore } from '~/self_monitor/store'; import { createStore } from '~/self_monitor/store';
describe('self monitor component', () => { describe('self-monitor component', () => {
let wrapper; let wrapper;
let store; let store;
describe('When the self monitor project has not been created', () => { describe('When the self-monitor project has not been created', () => {
beforeEach(() => { beforeEach(() => {
store = createStore({ store = createStore({
projectEnabled: false, projectEnabled: false,
@ -35,7 +35,7 @@ describe('self monitor component', () => {
it('renders header text', () => { it('renders header text', () => {
wrapper = shallowMount(SelfMonitor, { store }); wrapper = shallowMount(SelfMonitor, { store });
expect(wrapper.find('.js-section-header').text()).toBe('Self monitoring'); expect(wrapper.find('.js-section-header').text()).toBe('Self-monitoring');
}); });
describe('expand/collapse button', () => { describe('expand/collapse button', () => {
@ -53,7 +53,7 @@ describe('self monitor component', () => {
wrapper = shallowMount(SelfMonitor, { store }); wrapper = shallowMount(SelfMonitor, { store });
expect(wrapper.find('.js-section-sub-header').text()).toContain( expect(wrapper.find('.js-section-sub-header').text()).toContain(
'Activate or deactivate instance self monitoring.', 'Activate or deactivate instance self-monitoring.',
); );
}); });
}); });
@ -63,7 +63,7 @@ describe('self monitor component', () => {
wrapper = shallowMount(SelfMonitor, { store }); wrapper = shallowMount(SelfMonitor, { store });
expect(wrapper.vm.selfMonitoringFormText).toContain( expect(wrapper.vm.selfMonitoringFormText).toContain(
'Activate self monitoring to create a project to use to monitor the health of your instance.', 'Activate self-monitoring to create a project to use to monitor the health of your instance.',
); );
}); });

View file

@ -6,7 +6,7 @@ import * as actions from '~/self_monitor/store/actions';
import * as types from '~/self_monitor/store/mutation_types'; import * as types from '~/self_monitor/store/mutation_types';
import createState from '~/self_monitor/store/state'; import createState from '~/self_monitor/store/state';
describe('self monitor actions', () => { describe('self-monitor actions', () => {
let state; let state;
let mock; let mock;
@ -129,7 +129,7 @@ describe('self monitor actions', () => {
payload: { payload: {
actionName: 'viewSelfMonitorProject', actionName: 'viewSelfMonitorProject',
actionText: 'View project', actionText: 'View project',
message: 'Self monitoring project successfully created.', message: 'Self-monitoring project successfully created.',
}, },
}, },
{ type: types.SET_SHOW_ALERT, payload: true }, { type: types.SET_SHOW_ALERT, payload: true },
@ -236,7 +236,7 @@ describe('self monitor actions', () => {
payload: { payload: {
actionName: 'createProject', actionName: 'createProject',
actionText: 'Undo', actionText: 'Undo',
message: 'Self monitoring project successfully deleted.', message: 'Self-monitoring project successfully deleted.',
}, },
}, },
{ type: types.SET_SHOW_ALERT, payload: true }, { type: types.SET_SHOW_ALERT, payload: true },

View file

@ -1,7 +1,7 @@
import mutations from '~/self_monitor/store/mutations'; import mutations from '~/self_monitor/store/mutations';
import createState from '~/self_monitor/store/state'; import createState from '~/self_monitor/store/state';
describe('self monitoring mutations', () => { describe('self-monitoring mutations', () => {
let localState; let localState;
beforeEach(() => { beforeEach(() => {

View file

@ -30,7 +30,7 @@ describe('AlertDetails', () => {
const projectPath = 'root/alerts'; const projectPath = 'root/alerts';
const projectIssuesPath = 'root/alerts/-/issues'; const projectIssuesPath = 'root/alerts/-/issues';
const projectId = '1'; const projectId = '1';
const $router = { replace: jest.fn() }; const $router = { push: jest.fn() };
function mountComponent({ function mountComponent({
data, data,
@ -352,7 +352,7 @@ describe('AlertDetails', () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ currentTabIndex: index }); wrapper.setData({ currentTabIndex: index });
expect($router.replace).toHaveBeenCalledWith({ name: 'tab', params: { tabId } }); expect($router.push).toHaveBeenCalledWith({ name: 'tab', params: { tabId } });
}); });
}); });
}); });

View file

@ -95,7 +95,7 @@ RSpec.describe ApplicationSettingsHelper do
end end
describe '.self_monitoring_project_data' do describe '.self_monitoring_project_data' do
context 'when self monitoring project does not exist' do context 'when self-monitoring project does not exist' do
it 'returns create_self_monitoring_project_path' do it 'returns create_self_monitoring_project_path' do
expect(helper.self_monitoring_project_data).to include( expect(helper.self_monitoring_project_data).to include(
'create_self_monitoring_project_path' => 'create_self_monitoring_project_path' =>
@ -137,7 +137,7 @@ RSpec.describe ApplicationSettingsHelper do
end end
end end
context 'when self monitoring project exists' do context 'when self-monitoring project exists' do
let(:project) { build(:project) } let(:project) { build(:project) }
before do before do

View file

@ -110,6 +110,7 @@ RSpec.describe Projects::AlertManagementHelper do
describe '#alert_management_detail_data' do describe '#alert_management_detail_data' do
let(:alert_id) { 1 } let(:alert_id) { 1 }
let(:issues_path) { project_issues_path(project) } let(:issues_path) { project_issues_path(project) }
let(:details_alert_management_path) { details_project_alert_management_path(project, alert_id) }
let(:can_update_alert) { true } let(:can_update_alert) { true }
before do before do
@ -125,6 +126,7 @@ RSpec.describe Projects::AlertManagementHelper do
'project-path' => project_path, 'project-path' => project_path,
'project-id' => project_id, 'project-id' => project_id,
'project-issues-path' => issues_path, 'project-issues-path' => issues_path,
'project-alert-management-details-path' => details_alert_management_path,
'page' => 'OPERATIONS', 'page' => 'OPERATIONS',
'can-update' => 'true' 'can-update' => 'true'
) )

View file

@ -262,7 +262,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Populate do
it 'builds pipeline_metadata' do it 'builds pipeline_metadata' do
run_chain run_chain
expect(pipeline.pipeline_metadata.title).to eq('Pipeline name') expect(pipeline.pipeline_metadata.name).to eq('Pipeline name')
expect(pipeline.pipeline_metadata.project).to eq(pipeline.project) expect(pipeline.pipeline_metadata.project).to eq(pipeline.project)
end end

View file

@ -11,13 +11,13 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::DeleteService
it 'returns error' do it 'returns error' do
expect(result).to eq( expect(result).to eq(
status: :error, status: :error,
message: 'Self monitoring project does not exist', message: 'Self-monitoring project does not exist',
last_step: :validate_self_monitoring_project_exists last_step: :validate_self_monitoring_project_exists
) )
end end
end end
context 'when self monitoring project exists' do context 'when self-monitoring project exists' do
let(:group) { create(:group) } let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) } let(:project) { create(:project, namespace: group) }

View file

@ -160,7 +160,7 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do
pipeline = Ci::Pipeline.find_by_sha('sha-notes') pipeline = Ci::Pipeline.find_by_sha('sha-notes')
pipeline_metadata = pipeline.pipeline_metadata pipeline_metadata = pipeline.pipeline_metadata
expect(pipeline_metadata.title).to eq('Build pipeline') expect(pipeline_metadata.name).to eq('Build pipeline')
expect(pipeline_metadata.pipeline_id).to eq(pipeline.id) expect(pipeline_metadata.pipeline_id).to eq(pipeline.id)
expect(pipeline_metadata.project_id).to eq(pipeline.project_id) expect(pipeline_metadata.project_id).to eq(pipeline.project_id)
end end

View file

@ -336,7 +336,7 @@ Ci::PipelineMetadata:
- id - id
- project_id - project_id
- pipeline_id - pipeline_id
- title - name
Ci::Stage: Ci::Stage:
- id - id
- name - name

View file

@ -44,7 +44,7 @@ RSpec.describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store
it_behaves_like 'valid dashboard service response' it_behaves_like 'valid dashboard service response'
end end
context 'when the self monitoring dashboard is specified' do context 'when the self-monitoring dashboard is specified' do
let(:dashboard_path) { self_monitoring_dashboard_path } let(:dashboard_path) { self_monitoring_dashboard_path }
it_behaves_like 'valid dashboard service response' it_behaves_like 'valid dashboard service response'
@ -181,7 +181,7 @@ RSpec.describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store
end end
end end
context 'when the project is self monitoring' do context 'when the project is self-monitoring' do
let(:self_monitoring_dashboard) do let(:self_monitoring_dashboard) do
{ {
path: self_monitoring_dashboard_path, path: self_monitoring_dashboard_path,
@ -199,7 +199,7 @@ RSpec.describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store
stub_application_setting(self_monitoring_project_id: project.id) stub_application_setting(self_monitoring_project_id: project.id)
end end
it 'includes self monitoring and project dashboards' do it 'includes self-monitoring and project dashboards' do
project_dashboard = { project_dashboard = {
path: dashboard_path, path: dashboard_path,
display_name: 'test.yml', display_name: 'test.yml',

View file

@ -30,7 +30,7 @@ RSpec.describe Gitlab::Metrics::Dashboard::ServiceSelector do
end end
end end
context 'when the path is for the self monitoring dashboard' do context 'when the path is for the self-monitoring dashboard' do
let(:arguments) { { dashboard_path: self_monitoring_dashboard_path } } let(:arguments) { { dashboard_path: self_monitoring_dashboard_path } }
it { is_expected.to be Metrics::Dashboard::SelfMonitoringDashboardService } it { is_expected.to be Metrics::Dashboard::SelfMonitoringDashboardService }

View file

@ -16,9 +16,9 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
clear_queues clear_queues
end end
describe '#execute', :aggregate_failures do describe '#migrate_set', :aggregate_failures do
shared_examples 'processing a set' do shared_examples 'processing a set' do
let(:migrator) { described_class.new(set_name) } let(:migrator) { described_class.new(mappings) }
let(:set_after) do let(:set_after) do
Sidekiq.redis { |c| c.zrange(set_name, 0, -1, with_scores: true) } Sidekiq.redis { |c| c.zrange(set_name, 0, -1, with_scores: true) }
@ -26,24 +26,32 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
end end
context 'when the set is empty' do context 'when the set is empty' do
let(:mappings) { { 'AuthorizedProjectsWorker' => 'new_queue' } }
it 'returns the number of scanned and migrated jobs' do it 'returns the number of scanned and migrated jobs' do
expect(migrator.execute('AuthorizedProjectsWorker' => 'new_queue')).to eq(scanned: 0, migrated: 0) expect(migrator.migrate_set(set_name)).to eq(
scanned: 0,
migrated: 0)
end end
end end
context 'when the set is not empty' do context 'when the set is not empty' do
let(:mappings) { {} }
it 'returns the number of scanned and migrated jobs' do it 'returns the number of scanned and migrated jobs' do
create_jobs create_jobs
expect(migrator.execute({})).to eq(scanned: 4, migrated: 0) expect(migrator.migrate_set(set_name)).to eq(scanned: 4, migrated: 0)
end end
end end
context 'when there are no matching jobs' do context 'when there are no matching jobs' do
let(:mappings) { { 'PostReceive' => 'new_queue' } }
it 'does not change any queue names' do it 'does not change any queue names' do
create_jobs(include_post_receive: false) create_jobs(include_post_receive: false)
expect(migrator.execute('PostReceive' => 'new_queue')).to eq(scanned: 3, migrated: 0) expect(migrator.migrate_set(set_name)).to eq(scanned: 3, migrated: 0)
expect(set_after.length).to eq(3) expect(set_after.length).to eq(3)
expect(set_after.map(&:first)).to all(include('queue' => 'default', expect(set_after.map(&:first)).to all(include('queue' => 'default',
@ -53,10 +61,13 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
context 'when there are matching jobs' do context 'when there are matching jobs' do
it 'migrates only the workers matching the given worker from the set' do it 'migrates only the workers matching the given worker from the set' do
migrator = described_class.new({ 'AuthorizedProjectsWorker' => 'new_queue' })
freeze_time do freeze_time do
create_jobs create_jobs
expect(migrator.execute('AuthorizedProjectsWorker' => 'new_queue')).to eq(scanned: 4, migrated: 3) expect(migrator.migrate_set(set_name)).to eq(
scanned: 4,
migrated: 3)
set_after.each.with_index do |(item, score), i| set_after.each.with_index do |(item, score), i|
if item['class'] == 'AuthorizedProjectsWorker' if item['class'] == 'AuthorizedProjectsWorker'
@ -71,11 +82,14 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
end end
it 'allows migrating multiple workers at once' do it 'allows migrating multiple workers at once' do
migrator = described_class.new({
'AuthorizedProjectsWorker' => 'new_queue',
'PostReceive' => 'another_queue'
})
freeze_time do freeze_time do
create_jobs create_jobs
expect(migrator.execute('AuthorizedProjectsWorker' => 'new_queue', 'PostReceive' => 'another_queue')) expect(migrator.migrate_set(set_name)).to eq(scanned: 4, migrated: 4)
.to eq(scanned: 4, migrated: 4)
set_after.each.with_index do |(item, score), i| set_after.each.with_index do |(item, score), i|
if item['class'] == 'AuthorizedProjectsWorker' if item['class'] == 'AuthorizedProjectsWorker'
@ -90,11 +104,14 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
end end
it 'allows migrating multiple workers to the same queue' do it 'allows migrating multiple workers to the same queue' do
migrator = described_class.new({
'AuthorizedProjectsWorker' => 'new_queue',
'PostReceive' => 'new_queue'
})
freeze_time do freeze_time do
create_jobs create_jobs
expect(migrator.execute('AuthorizedProjectsWorker' => 'new_queue', 'PostReceive' => 'new_queue')) expect(migrator.migrate_set(set_name)).to eq(scanned: 4, migrated: 4)
.to eq(scanned: 4, migrated: 4)
set_after.each.with_index do |(item, score), i| set_after.each.with_index do |(item, score), i|
expect(item).to include('queue' => 'new_queue', 'args' => [i]) expect(item).to include('queue' => 'new_queue', 'args' => [i])
@ -104,16 +121,17 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
end end
it 'does not try to migrate jobs that are removed from the set during the migration' do it 'does not try to migrate jobs that are removed from the set during the migration' do
migrator = described_class.new({ 'PostReceive' => 'new_queue' })
freeze_time do freeze_time do
create_jobs create_jobs
allow(migrator).to receive(:migrate_job).and_wrap_original do |meth, *args| allow(migrator).to receive(:migrate_job_in_set).and_wrap_original do |meth, *args|
Sidekiq.redis { |c| c.zrem(set_name, args.first) } Sidekiq.redis { |c| c.zrem(set_name, args.second) }
meth.call(*args) meth.call(*args)
end end
expect(migrator.execute('PostReceive' => 'new_queue')).to eq(scanned: 4, migrated: 0) expect(migrator.migrate_set(set_name)).to eq(scanned: 4, migrated: 0)
expect(set_after.length).to eq(3) expect(set_after.length).to eq(3)
expect(set_after.map(&:first)).to all(include('queue' => 'default')) expect(set_after.map(&:first)).to all(include('queue' => 'default'))
@ -121,11 +139,12 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
end end
it 'does not try to migrate unmatched jobs that are added to the set during the migration' do it 'does not try to migrate unmatched jobs that are added to the set during the migration' do
migrator = described_class.new({ 'PostReceive' => 'new_queue' })
create_jobs create_jobs
calls = 0 calls = 0
allow(migrator).to receive(:migrate_job).and_wrap_original do |meth, *args| allow(migrator).to receive(:migrate_job_in_set).and_wrap_original do |meth, *args|
if calls == 0 if calls == 0
travel_to(5.hours.from_now) { create_jobs(include_post_receive: false) } travel_to(5.hours.from_now) { create_jobs(include_post_receive: false) }
end end
@ -135,18 +154,19 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
meth.call(*args) meth.call(*args)
end end
expect(migrator.execute('PostReceive' => 'new_queue')).to eq(scanned: 4, migrated: 1) expect(migrator.migrate_set(set_name)).to eq(scanned: 4, migrated: 1)
expect(set_after.group_by { |job| job.first['queue'] }.transform_values(&:count)) expect(set_after.group_by { |job| job.first['queue'] }.transform_values(&:count))
.to eq('default' => 6, 'new_queue' => 1) .to eq('default' => 6, 'new_queue' => 1)
end end
it 'iterates through the entire set of jobs' do it 'iterates through the entire set of jobs' do
migrator = described_class.new({ 'NonExistentWorker' => 'new_queue' })
50.times do |i| 50.times do |i|
travel_to(i.hours.from_now) { create_jobs } travel_to(i.hours.from_now) { create_jobs }
end end
expect(migrator.execute('NonExistentWorker' => 'new_queue')).to eq(scanned: 200, migrated: 0) expect(migrator.migrate_set(set_name)).to eq(scanned: 200, migrated: 0)
expect(set_after.length).to eq(200) expect(set_after.length).to eq(200)
end end
@ -158,14 +178,16 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
stub_const("#{described_class}::LOG_FREQUENCY", 2) stub_const("#{described_class}::LOG_FREQUENCY", 2)
logger = Logger.new(StringIO.new) logger = Logger.new(StringIO.new)
migrator = described_class.new(set_name, logger: logger) migrator = described_class.new({
'AuthorizedProjectsWorker' => 'new_queue',
'PostReceive' => 'another_queue'
}, logger: logger)
expect(logger).to receive(:info).with(a_string_matching('Processing')).once.ordered expect(logger).to receive(:info).with(a_string_matching('Processing')).once.ordered
expect(logger).to receive(:info).with(a_string_matching('In progress')).once.ordered expect(logger).to receive(:info).with(a_string_matching('In progress')).once.ordered
expect(logger).to receive(:info).with(a_string_matching('Done')).once.ordered expect(logger).to receive(:info).with(a_string_matching('Done')).once.ordered
expect(migrator.execute('AuthorizedProjectsWorker' => 'new_queue', 'PostReceive' => 'new_queue')) expect(migrator.migrate_set(set_name)).to eq(scanned: 4, migrated: 4)
.to eq(scanned: 4, migrated: 4)
end end
end end
end end
@ -215,4 +237,168 @@ RSpec.describe Gitlab::SidekiqMigrateJobs, :clean_gitlab_redis_queues do
it_behaves_like 'processing a set' it_behaves_like 'processing a set'
end end
end end
describe '#migrate_queues', :aggregate_failures do
let(:migrator) { described_class.new(mappings, logger: logger) }
let(:logger) { nil }
def list_queues
queues = Sidekiq.redis do |conn|
conn.scan_each(match: "queue:*").to_a
end
queues.uniq.map { |queue| queue.split(':', 2).last }
end
def list_jobs(queue_name)
Sidekiq.redis { |conn| conn.lrange("queue:#{queue_name}", 0, -1) }
.map { |item| Sidekiq.load_json item }
end
def pre_migrate_checks; end
before do
queue_name_from_worker_name = Gitlab::SidekiqConfig::WorkerRouter.method(:queue_name_from_worker_name)
EmailReceiverWorker.sidekiq_options(queue: queue_name_from_worker_name.call(EmailReceiverWorker))
EmailReceiverWorker.perform_async('foo')
EmailReceiverWorker.perform_async('bar')
# test worker that has ':' inside the queue name
AuthorizedProjectUpdate::ProjectRecalculateWorker.sidekiq_options(
queue: queue_name_from_worker_name.call(AuthorizedProjectUpdate::ProjectRecalculateWorker)
)
AuthorizedProjectUpdate::ProjectRecalculateWorker.perform_async
end
after do
# resets the queue name to its original
EmailReceiverWorker.set_queue
AuthorizedProjectUpdate::ProjectRecalculateWorker.set_queue
end
shared_examples 'migrating queues' do
it 'migrates the jobs to the correct destination queue' do
queues = list_queues
expect(queues).to include(*queues_included_pre_migrate)
expect(queues).not_to include(*queues_excluded_pre_migrate)
pre_migrate_checks
migrator.migrate_queues
queues = list_queues
expect(queues).not_to include(*queues_excluded_post_migrate)
expect(queues).to include(*queues_included_post_migrate)
post_migrate_checks
end
end
context 'with all workers mapped to default queue' do
let(:mappings) do
{ 'EmailReceiverWorker' => 'default', 'AuthorizedProjectUpdate::ProjectRecalculateWorker' => 'default' }
end
let(:queues_included_pre_migrate) do
['email_receiver',
'authorized_project_update:authorized_project_update_project_recalculate']
end
let(:queues_excluded_pre_migrate) { ['default'] }
let(:queues_excluded_post_migrate) do
['email_receiver',
'authorized_project_update:authorized_project_update_project_recalculate']
end
let(:queues_included_post_migrate) { ['default'] }
def post_migrate_checks
jobs = list_jobs('default')
expect(jobs.length).to eq(3)
sorted = jobs.sort_by { |job| [job["class"], job["args"]] }
expect(sorted[0]).to include('class' => 'AuthorizedProjectUpdate::ProjectRecalculateWorker',
'queue' => 'default')
expect(sorted[1]).to include('class' => 'EmailReceiverWorker', 'args' => ['bar'], 'queue' => 'default')
expect(sorted[2]).to include('class' => 'EmailReceiverWorker', 'args' => ['foo'], 'queue' => 'default')
end
it_behaves_like 'migrating queues'
end
context 'with custom mapping to different queues' do
let(:mappings) do
{ 'EmailReceiverWorker' => 'new_email',
'AuthorizedProjectUpdate::ProjectRecalculateWorker' => 'new_authorized' }
end
let(:queues_included_pre_migrate) do
['email_receiver',
'authorized_project_update:authorized_project_update_project_recalculate']
end
let(:queues_excluded_pre_migrate) { %w[new_email new_authorized] }
let(:queues_excluded_post_migrate) do
['email_receiver',
'authorized_project_update:authorized_project_update_project_recalculate']
end
let(:queues_included_post_migrate) { %w[new_email new_authorized] }
def post_migrate_checks
email_jobs = list_jobs('new_email')
expect(email_jobs.length).to eq(2)
expect(email_jobs[0]).to include('class' => 'EmailReceiverWorker', 'args' => ['bar'], 'queue' => 'new_email')
expect(email_jobs[1]).to include('class' => 'EmailReceiverWorker', 'args' => ['foo'], 'queue' => 'new_email')
export_jobs = list_jobs('new_authorized')
expect(export_jobs.length).to eq(1)
expect(export_jobs[0]).to include('class' => 'AuthorizedProjectUpdate::ProjectRecalculateWorker',
'queue' => 'new_authorized')
end
it_behaves_like 'migrating queues'
end
context 'with illegal JSON payload' do
let(:job) { '{foo: 1}' }
let(:mappings) do
{ 'EmailReceiverWorker' => 'default', 'AuthorizedProjectUpdate::ProjectRecalculateWorker' => 'default' }
end
let(:queues_included_pre_migrate) do
['email_receiver',
'authorized_project_update:authorized_project_update_project_recalculate']
end
let(:queues_excluded_pre_migrate) { ['default'] }
let(:queues_excluded_post_migrate) do
['email_receiver',
'authorized_project_update:authorized_project_update_project_recalculate']
end
let(:queues_included_post_migrate) { ['default'] }
let(:logger) { Logger.new(StringIO.new) }
before do
Sidekiq.redis do |conn|
conn.lpush("queue:email_receiver", job)
end
end
def pre_migrate_checks
expect(logger).to receive(:error)
.with(a_string_matching('Unmarshal JSON payload from SidekiqMigrateJobs failed'))
.once
end
def post_migrate_checks
jobs = list_jobs('default')
expect(jobs.length).to eq(3)
sorted = jobs.sort_by { |job| [job["class"], job["args"]] }
expect(sorted[0]).to include('class' => 'AuthorizedProjectUpdate::ProjectRecalculateWorker',
'queue' => 'default')
expect(sorted[1]).to include('class' => 'EmailReceiverWorker', 'args' => ['bar'], 'queue' => 'default')
expect(sorted[2]).to include('class' => 'EmailReceiverWorker', 'args' => ['foo'], 'queue' => 'default')
end
it_behaves_like 'migrating queues'
end
end
end end

View file

@ -7,7 +7,7 @@ RSpec.describe Ci::PipelineMetadata do
it { is_expected.to belong_to(:pipeline) } it { is_expected.to belong_to(:pipeline) }
describe 'validations' do describe 'validations' do
it { is_expected.to validate_length_of(:title).is_at_least(1).is_at_most(255) } it { is_expected.to validate_length_of(:name).is_at_least(1).is_at_most(255) }
it { is_expected.to validate_presence_of(:project) } it { is_expected.to validate_presence_of(:project) }
it { is_expected.to validate_presence_of(:pipeline) } it { is_expected.to validate_presence_of(:pipeline) }
end end

View file

@ -50,7 +50,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
it { is_expected.to respond_to :git_author_full_text } it { is_expected.to respond_to :git_author_full_text }
it { is_expected.to respond_to :short_sha } it { is_expected.to respond_to :short_sha }
it { is_expected.to delegate_method(:full_path).to(:project).with_prefix } it { is_expected.to delegate_method(:full_path).to(:project).with_prefix }
it { is_expected.to delegate_method(:title).to(:pipeline_metadata).allow_nil } it { is_expected.to delegate_method(:name).to(:pipeline_metadata).allow_nil }
describe 'validations' do describe 'validations' do
it { is_expected.to validate_presence_of(:sha) } it { is_expected.to validate_presence_of(:sha) }

View file

@ -217,7 +217,7 @@ RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching,
expect(integration.prometheus_client).to be_nil expect(integration.prometheus_client).to be_nil
end end
context 'with self monitoring project and internal Prometheus URL' do context 'with self-monitoring project and internal Prometheus URL' do
before do before do
stub_application_setting(allow_local_requests_from_web_hooks_and_services: false) stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
stub_application_setting(self_monitoring_project_id: project.id) stub_application_setting(self_monitoring_project_id: project.id)

View file

@ -7074,7 +7074,7 @@ RSpec.describe Project, factory_default: :keep do
subject { project.self_monitoring? } subject { project.self_monitoring? }
context 'when the project is instance self monitoring' do context 'when the project is instance self-monitoring' do
before do before do
stub_application_setting(self_monitoring_project_id: project.id) stub_application_setting(self_monitoring_project_id: project.id)
end end
@ -7082,7 +7082,7 @@ RSpec.describe Project, factory_default: :keep do
it { is_expected.to be true } it { is_expected.to be true }
end end
context 'when the project is not self monitoring' do context 'when the project is not self-monitoring' do
it { is_expected.to be false } it { is_expected.to be false }
end end
end end

View file

@ -17,7 +17,7 @@ RSpec.describe 'Self-Monitoring project requests' do
login_as(admin) login_as(admin)
end end
context 'when the self monitoring project is created' do context 'when the self-monitoring project is created' do
let(:status_api) { status_create_self_monitoring_project_admin_application_settings_path } let(:status_api) { status_create_self_monitoring_project_admin_application_settings_path }
it_behaves_like 'triggers async worker, returns sidekiq job_id with response accepted' it_behaves_like 'triggers async worker, returns sidekiq job_id with response accepted'
@ -41,7 +41,7 @@ RSpec.describe 'Self-Monitoring project requests' do
login_as(admin) login_as(admin)
end end
context 'when the self monitoring project is being created' do context 'when the self-monitoring project is being created' do
it_behaves_like 'handles invalid job_id' it_behaves_like 'handles invalid job_id'
context 'when job is in progress' do context 'when job is in progress' do
@ -121,7 +121,7 @@ RSpec.describe 'Self-Monitoring project requests' do
login_as(admin) login_as(admin)
end end
context 'when the self monitoring project is deleted' do context 'when the self-monitoring project is deleted' do
let(:status_api) { status_delete_self_monitoring_project_admin_application_settings_path } let(:status_api) { status_delete_self_monitoring_project_admin_application_settings_path }
it_behaves_like 'triggers async worker, returns sidekiq job_id with response accepted' it_behaves_like 'triggers async worker, returns sidekiq job_id with response accepted'
@ -145,7 +145,7 @@ RSpec.describe 'Self-Monitoring project requests' do
login_as(admin) login_as(admin)
end end
context 'when the self monitoring project is being deleted' do context 'when the self-monitoring project is being deleted' do
it_behaves_like 'handles invalid job_id' it_behaves_like 'handles invalid job_id'
context 'when job is in progress' do context 'when job is in progress' do

View file

@ -67,7 +67,7 @@ RSpec.describe GoogleCloud::GeneratePipelineService do
let_it_be(:service_params) { { action: GoogleCloud::GeneratePipelineService::ACTION_DEPLOY_TO_CLOUD_RUN } } let_it_be(:service_params) { { action: GoogleCloud::GeneratePipelineService::ACTION_DEPLOY_TO_CLOUD_RUN } }
let_it_be(:service) { described_class.new(project, maintainer, service_params) } let_it_be(:service) { described_class.new(project, maintainer, service_params) }
before do before_all do
project.add_maintainer(maintainer) project.add_maintainer(maintainer)
file_name = '.gitlab-ci.yml' file_name = '.gitlab-ci.yml'
@ -103,6 +103,15 @@ EOF
expect(pipeline[:include]).to be_present expect(pipeline[:include]).to be_present
expect(gitlab_ci_yml).to include('https://gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library/-/raw/main/gcp/cloud-run.gitlab-ci.yml') expect(gitlab_ci_yml).to include('https://gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library/-/raw/main/gcp/cloud-run.gitlab-ci.yml')
end end
it 'stringifies keys from the existing pipelines' do
response = service.execute
branch_name = response[:branch_name]
gitlab_ci_yml = project.repository.gitlab_ci_yml_for(branch_name)
expect(YAML.safe_load(gitlab_ci_yml).keys).to eq(%w[stages build-java test-java include])
end
end end
describe 'when there is an existing pipeline with `deploy` stage' do describe 'when there is an existing pipeline with `deploy` stage' do

View file

@ -9,7 +9,10 @@ RSpec.describe 'sidekiq.rake', :aggregate_failures, :silence_stdout do
stub_warn_user_is_not_gitlab stub_warn_user_is_not_gitlab
end end
let(:migrator) { ::Gitlab::SidekiqMigrateJobs.new(mappings, logger: Logger.new($stdout)) }
shared_examples 'migration rake task' do shared_examples 'migration rake task' do
let(:mappings) { {} }
it 'runs the migrator with a mapping of workers to queues' do it 'runs the migrator with a mapping of workers to queues' do
test_routes = [ test_routes = [
['urgency=high', 'default'], ['urgency=high', 'default'],
@ -17,20 +20,17 @@ RSpec.describe 'sidekiq.rake', :aggregate_failures, :silence_stdout do
] ]
test_router = ::Gitlab::SidekiqConfig::WorkerRouter.new(test_routes) test_router = ::Gitlab::SidekiqConfig::WorkerRouter.new(test_routes)
migrator = ::Gitlab::SidekiqMigrateJobs.new(sidekiq_set, logger: Logger.new($stdout))
allow(::Gitlab::SidekiqConfig::WorkerRouter) allow(::Gitlab::SidekiqConfig::WorkerRouter)
.to receive(:global).and_return(test_router) .to receive(:global).and_return(test_router)
expect(::Gitlab::SidekiqMigrateJobs) expect(::Gitlab::SidekiqMigrateJobs)
.to receive(:new).with(sidekiq_set, logger: an_instance_of(Logger)).and_return(migrator) .to receive(:new).with(a_hash_including('PostReceive' => 'default',
'MergeWorker' => 'default',
'DeleteDiffFilesWorker' => 'delete_diff_files'),
logger: an_instance_of(Logger)).and_return(migrator)
expect(migrator) expect(migrator).to receive(:migrate_set).with(sidekiq_set).and_call_original
.to receive(:execute)
.with(a_hash_including('PostReceive' => 'default',
'MergeWorker' => 'default',
'DeleteDiffFilesWorker' => 'delete_diff_files'))
.and_call_original
run_rake_task("gitlab:sidekiq:migrate_jobs:#{sidekiq_set}") run_rake_task("gitlab:sidekiq:migrate_jobs:#{sidekiq_set}")
@ -50,4 +50,30 @@ RSpec.describe 'sidekiq.rake', :aggregate_failures, :silence_stdout do
it_behaves_like 'migration rake task' it_behaves_like 'migration rake task'
end end
describe 'gitlab:sidekiq:migrate_jobs:queued rake task' do
let(:mappings) { { 'PostReceive' => 'default' } }
it 'runs the migrator with a mapping of workers to queues' do
test_routes = [
['*', 'default']
]
test_router = ::Gitlab::SidekiqConfig::WorkerRouter.new(test_routes)
allow(::Gitlab::SidekiqConfig::WorkerRouter)
.to receive(:global).and_return(test_router)
expect(::Gitlab::SidekiqMigrateJobs)
.to receive(:new).with(a_hash_including('PostReceive' => 'default',
'MergeWorker' => 'default'),
logger: an_instance_of(Logger)).and_return(migrator)
expect(migrator).to receive(:migrate_queues).and_call_original
run_rake_task("gitlab:sidekiq:migrate_jobs:queued")
expect($stdout.string).to include('List of queues based on routing rules: ["default"]')
end
end
end end