diff --git a/.rubocop.yml b/.rubocop.yml index ebc27c4cc9e..a05fffe8740 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -299,7 +299,11 @@ RSpec/ImplicitSubject: Enabled: false RSpec/LeakyConstantDeclaration: - Enabled: false + Enabled: true + Exclude: + - 'spec/**/*.rb' + - 'ee/spec/**/*.rb' + - 'qa/spec/**/*.rb' RSpec/EmptyLineAfterHook: Enabled: false diff --git a/app/models/service.rb b/app/models/service.rb index d866eeb3531..5782fab3266 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -34,6 +34,7 @@ class Service < ApplicationRecord validates :project_id, presence: true, unless: -> { template? || instance? } validates :project_id, absence: true, if: -> { template? || instance? } + validates :type, uniqueness: { scope: :project_id }, unless: -> { template? || instance? }, on: :create validates :type, presence: true validates :template, uniqueness: { scope: :type }, if: -> { template? } validates :instance, uniqueness: { scope: :type }, if: -> { instance? } diff --git a/bin/background_jobs b/bin/background_jobs index b3d7cc04d4f..598d36abde6 100755 --- a/bin/background_jobs +++ b/bin/background_jobs @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash cd $(dirname $0)/.. diff --git a/bin/background_jobs_sk b/bin/background_jobs_sk index 25218718bb8..131cfe116ff 100755 --- a/bin/background_jobs_sk +++ b/bin/background_jobs_sk @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash cd $(dirname $0)/.. app_root=$(pwd) diff --git a/bin/background_jobs_sk_cluster b/bin/background_jobs_sk_cluster index 9f44bb7381f..1982fd0810d 100755 --- a/bin/background_jobs_sk_cluster +++ b/bin/background_jobs_sk_cluster @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash cd $(dirname $0)/.. app_root=$(pwd) diff --git a/changelogs/unreleased/207385-service-project-type-uniqueness-validation.yml b/changelogs/unreleased/207385-service-project-type-uniqueness-validation.yml new file mode 100644 index 00000000000..93f55ae6312 --- /dev/null +++ b/changelogs/unreleased/207385-service-project-type-uniqueness-validation.yml @@ -0,0 +1,5 @@ +--- +title: Validate uniqueness of project_id and type when a new project service is created +merge_request: 26308 +author: +type: fixed diff --git a/doc/user/analytics/img/label_based_stage_vsm_v12_9.png b/doc/user/analytics/img/label_based_stage_vsm_v12_9.png new file mode 100644 index 00000000000..f1cbd9e1a8e Binary files /dev/null and b/doc/user/analytics/img/label_based_stage_vsm_v12_9.png differ diff --git a/doc/user/analytics/img/new_vsm_stage_v12_9.png b/doc/user/analytics/img/new_vsm_stage_v12_9.png new file mode 100644 index 00000000000..dbef25d33ed Binary files /dev/null and b/doc/user/analytics/img/new_vsm_stage_v12_9.png differ diff --git a/doc/user/analytics/img/vsm_stage_list_v12_9.png b/doc/user/analytics/img/vsm_stage_list_v12_9.png new file mode 100644 index 00000000000..3775cdeddb4 Binary files /dev/null and b/doc/user/analytics/img/vsm_stage_list_v12_9.png differ diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md index 9d925b00d8b..385cc39c0c0 100644 --- a/doc/user/analytics/value_stream_analytics.md +++ b/doc/user/analytics/value_stream_analytics.md @@ -151,6 +151,56 @@ A few notes: cycles, calculate their median time and the result is what the dashboard of Value Stream Analytics is showing. +## Customizable Value Stream Analytics + +The default stages are designed to work straight out of the box, but they might not be suitable for all teams. Different teams use different approaches to building software, so some teams might want to customize their Value Stream Analytics. From GitLab 12.9, users can hide default stages and create custom stages that align better to their development workflow. + +### Adding a stage + +In the following example we're creating a new stage that measures and tracks issues from creation time until they are closed. + +1. Navigate to your group page. +1. Open Value Stream Analytics from the sidebar: **Analytics > Value Stream** +1. Click the "Add a stage" button. +1. Fill in the new stage form: + - Name: Issue start to finish + - Start event: Issue created + - End event: Issue closed +1. Click the "Add stage" button. + +![New Value Stream Analytics Stage](img/new_vsm_stage_v12_9.png "Form for creating a new stage") + +The new stage is persisted and it will always show up on the value stream analytics page for your group. In case you want to alter or delete the stage you can easily do that for customized stages by hovering over the stage and clicking the three-dot icon that appears. + +![Value Stream Analytics Stages](img/vsm_stage_list_v12_9.png) + +Creating a custom stage requires specifying two events, a start and an end. Be careful to choose a start event that occurs *before* your end event. For example, consider if a stage started when an issue is added to a board, and ended when the issue is created. This stage would not work because the end event has already happened when the start event occurs. To prevent such invalid stages, the form prohibits incompatible start and end events. After you select the start event, the stop event dropdown will only list the compatible events. + +Note: The ability to re-order the stages is a [planned enhancement](https://gitlab.com/gitlab-org/gitlab/issues/196698). + +### Label based stages + +The pre-defined start and end events can cover many use cases involving both issues and merge requests. For supporting more complex workflows, we can use stages based on group labels. These events are based on labels being added/removed. In particular, [scoped labels](../project/labels.md#scoped-labels-premium) are useful for complex workflows. + +In this example we'd like to measure more accurate code review times. The workflow is the following: + +- When the code review starts, the reviewer adds `workflow::code_review_start` label to the merge request. +- When the code review is finished, the reviewer adds `workflow::code_review_complete` label to the merge request. + +Creating a new stage called "Code Review": + +![New Label Based Value Stream Analytics Stage](img/label_based_stage_vsm_v12_9.png "Creating a label based Value Stream Analytics Stage") + +### Hiding unused stages + +Sometimes certain default stages are not relevant to a team. In this case you can easily hide stages so they no longer appear in the list. First, add a custom stage to activate customizability. Then hover over the default stage you want to hide, click the three-dot icon that appears and select "Hide stage". + +To recover a default stage that was previously hidden: + +1. Click "Add a stage" button. +1. In the top right corner open the "Recover hidden stage" dropdown. +1. Select a stage. + ## Days to completion chart > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21631) in GitLab 12.6. diff --git a/spec/fixtures/lib/gitlab/import_export/complex/project.json b/spec/fixtures/lib/gitlab/import_export/complex/project.json index 72ed8b818d8..0fbe33a3f8a 100644 --- a/spec/fixtures/lib/gitlab/import_export/complex/project.json +++ b/spec/fixtures/lib/gitlab/import_export/complex/project.json @@ -7312,7 +7312,7 @@ "tag_push_events": true, "note_events": true, "job_events": true, - "type": "AssemblaService", + "type": "AsanaService", "category": "common", "default": false, "wiki_page_events": true diff --git a/spec/fixtures/lib/gitlab/import_export/light/project.json b/spec/fixtures/lib/gitlab/import_export/light/project.json index 51e2e9ac623..c0ef3690d27 100644 --- a/spec/fixtures/lib/gitlab/import_export/light/project.json +++ b/spec/fixtures/lib/gitlab/import_export/light/project.json @@ -125,7 +125,7 @@ }, { "id": 101, - "title": "JetBrains TeamCity CI", + "title": "Jira", "project_id": 5, "created_at": "2016-06-14T15:01:51.315Z", "updated_at": "2016-06-14T15:01:51.315Z", @@ -139,7 +139,7 @@ "tag_push_events": true, "note_events": true, "job_events": true, - "type": "TeamcityService", + "type": "JiraService", "category": "ci", "default": false, "wiki_page_events": true diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb index d0673b21329..7c80b5231d1 100644 --- a/spec/models/service_spec.rb +++ b/spec/models/service_spec.rb @@ -56,6 +56,14 @@ describe Service do expect(build(:service, :instance)).to be_invalid end end + + it 'validates uniqueness of type and project_id on create' do + project = create(:project) + + expect(create(:service, project: project, type: 'Service')).to be_valid + expect(build(:service, project: project, type: 'Service').valid?(:create)).to eq(false) + expect(build(:service, project: project, type: 'Service').valid?(:update)).to eq(true) + end end describe 'Scopes' do