Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-07-23 12:09:23 +00:00
parent defde9698e
commit d9b0b3243e
20 changed files with 281 additions and 190 deletions

View file

@ -1 +1 @@
e3bedb3507c01fbe8395dd76589e095d7da14e66 1b06a8764c22fc3960271b02470317077f284508

View file

@ -1 +1 @@
13.3.0 13.4.0

View file

@ -743,14 +743,14 @@ export function moveToNeighboringCommit({ dispatch, state }, { direction }) {
} }
} }
export const setCurrentDiffFileIdFromNote = ({ commit, rootGetters }, noteId) => { export const setCurrentDiffFileIdFromNote = ({ commit, state, rootGetters }, noteId) => {
const note = rootGetters.notesById[noteId]; const note = rootGetters.notesById[noteId];
if (!note) return; if (!note) return;
const fileHash = rootGetters.getDiscussion(note.discussion_id).diff_file?.file_hash; const fileHash = rootGetters.getDiscussion(note.discussion_id).diff_file?.file_hash;
if (fileHash) { if (fileHash && state.diffFiles.some(f => f.file_hash === fileHash)) {
commit(types.UPDATE_CURRENT_DIFF_FILE_ID, fileHash); commit(types.UPDATE_CURRENT_DIFF_FILE_ID, fileHash);
} }
}; };

View file

@ -15,10 +15,10 @@ module AlertManagement
return error_no_permissions unless allowed? return error_no_permissions unless allowed?
return error_issue_already_exists if alert.issue return error_issue_already_exists if alert.issue
result = create_issue result = create_incident
issue = result.payload[:issue] return result unless result.success?
return error(result.message, issue) if result.error? issue = result.payload[:issue]
return error(object_errors(alert), issue) unless associate_alert_with_issue(issue) return error(object_errors(alert), issue) unless associate_alert_with_issue(issue)
SystemNoteService.new_alert_issue(alert, issue, user) SystemNoteService.new_alert_issue(alert, issue, user)
@ -36,30 +36,19 @@ module AlertManagement
user.can?(:create_issue, project) user.can?(:create_issue, project)
end end
def create_issue def create_incident
label_result = find_or_create_incident_label ::IncidentManagement::Incidents::CreateService.new(
issue = Issues::CreateService.new(
project, project,
user, user,
title: alert_presenter.title, title: alert_presenter.title,
description: alert_presenter.issue_description, description: alert_presenter.issue_description
label_ids: [label_result.payload[:label].id]
).execute ).execute
return error(object_errors(issue), issue) unless issue.valid?
success(issue)
end end
def associate_alert_with_issue(issue) def associate_alert_with_issue(issue)
alert.update(issue_id: issue.id) alert.update(issue_id: issue.id)
end end
def success(issue)
ServiceResponse.success(payload: { issue: issue })
end
def error(message, issue = nil) def error(message, issue = nil)
ServiceResponse.error(payload: { issue: issue }, message: message) ServiceResponse.error(payload: { issue: issue }, message: message)
end end
@ -78,10 +67,6 @@ module AlertManagement
end end
end end
def find_or_create_incident_label
IncidentManagement::CreateIncidentLabelService.new(project, user).execute
end
def object_errors(object) def object_errors(object)
object.errors.full_messages.to_sentence object.errors.full_messages.to_sentence
end end

View file

@ -3,32 +3,30 @@
module IncidentManagement module IncidentManagement
class CreateIssueService < BaseService class CreateIssueService < BaseService
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
include IncidentManagement::Settings
def initialize(project, params) def initialize(project, params)
super(project, User.alert_bot, params) super(project, User.alert_bot, params)
end end
def execute def execute
return error_with('setting disabled') unless incident_management_setting.create_issue? return error('setting disabled') unless incident_management_setting.create_issue?
return error_with('invalid alert') unless alert.valid? return error('invalid alert') unless alert.valid?
issue = create_issue result = create_incident
return error_with(issue_errors(issue)) unless issue.valid? return error(result.message, result.payload[:issue]) unless result.success?
success(issue: issue) result
end end
private private
def create_issue def create_incident
label_result = find_or_create_incident_label ::IncidentManagement::Incidents::CreateService.new(
Issues::CreateService.new(
project, project,
current_user, current_user,
title: issue_title, title: issue_title,
description: issue_description, description: issue_description
label_ids: [label_result.payload[:label].id]
).execute ).execute
end end
@ -46,10 +44,6 @@ module IncidentManagement
].compact.join(horizontal_line) ].compact.join(horizontal_line)
end end
def find_or_create_incident_label
IncidentManagement::CreateIncidentLabelService.new(project, current_user).execute
end
def alert_summary def alert_summary
alert.issue_summary_markdown alert.issue_summary_markdown
end end
@ -68,21 +62,10 @@ module IncidentManagement
incident_management_setting.issue_template_content incident_management_setting.issue_template_content
end end
def incident_management_setting def error(message, issue = nil)
strong_memoize(:incident_management_setting) do
project.incident_management_setting ||
project.build_incident_management_setting
end
end
def issue_errors(issue)
issue.errors.full_messages.to_sentence
end
def error_with(message)
log_error(%{Cannot create incident issue for "#{project.full_name}": #{message}}) log_error(%{Cannot create incident issue for "#{project.full_name}": #{message}})
error(message) ServiceResponse.error(payload: { issue: issue }, message: message)
end end
end end
end end

View file

@ -0,0 +1,47 @@
# frozen_string_literal: true
module IncidentManagement
module Incidents
class CreateService < BaseService
def initialize(project, current_user, title:, description:)
super(project, current_user)
@title = title
@description = description
end
def execute
issue = Issues::CreateService.new(
project,
current_user,
title: title,
description: description,
label_ids: [find_or_create_incident_label.id]
).execute
return error(issue.errors.full_messages.to_sentence, issue) unless issue.valid?
success(issue)
end
private
attr_reader :title, :description
def find_or_create_incident_label
IncidentManagement::CreateIncidentLabelService
.new(project, current_user)
.execute
.payload[:label]
end
def success(issue)
ServiceResponse.success(payload: { issue: issue })
end
def error(message, issue = nil)
ServiceResponse.error(payload: { issue: issue }, message: message)
end
end
end
end

View file

@ -12,25 +12,19 @@ module IncidentManagement
def execute def execute
return forbidden unless webhook_available? return forbidden unless webhook_available?
issue = create_issue create_incident
return error(issue.errors.full_messages.to_sentence, issue) unless issue.valid?
success(issue)
end end
private private
alias_method :incident_payload, :params alias_method :incident_payload, :params
def create_issue def create_incident
label_result = find_or_create_incident_label ::IncidentManagement::Incidents::CreateService.new(
Issues::CreateService.new(
project, project,
current_user, current_user,
title: issue_title, title: issue_title,
description: issue_description, description: issue_description
label_ids: [label_result.payload[:label].id]
).execute ).execute
end end
@ -42,10 +36,6 @@ module IncidentManagement
ServiceResponse.error(message: 'Forbidden', http_status: :forbidden) ServiceResponse.error(message: 'Forbidden', http_status: :forbidden)
end end
def find_or_create_incident_label
::IncidentManagement::CreateIncidentLabelService.new(project, current_user).execute
end
def issue_title def issue_title
incident_payload['title'] incident_payload['title']
end end
@ -53,14 +43,6 @@ module IncidentManagement
def issue_description def issue_description
Gitlab::IncidentManagement::PagerDuty::IncidentIssueDescription.new(incident_payload).to_s Gitlab::IncidentManagement::PagerDuty::IncidentIssueDescription.new(incident_payload).to_s
end end
def success(issue)
ServiceResponse.success(payload: { issue: issue })
end
def error(message, issue = nil)
ServiceResponse.error(payload: { issue: issue }, message: message)
end
end end
end end
end end

View file

@ -16,9 +16,10 @@ module IncidentManagement
alert = find_alert(alert_id) alert = find_alert(alert_id)
return unless alert return unless alert
new_issue = create_issue_for(alert) result = create_issue_for(alert)
return unless new_issue&.persisted? return unless result.success?
new_issue = result.payload[:issue]
link_issue_with_alert(alert, new_issue.id) link_issue_with_alert(alert, new_issue.id)
end end
@ -36,7 +37,6 @@ module IncidentManagement
IncidentManagement::CreateIssueService IncidentManagement::CreateIssueService
.new(alert.project, parsed_payload(alert)) .new(alert.project, parsed_payload(alert))
.execute .execute
.dig(:issue)
end end
def link_issue_with_alert(alert, issue_id) def link_issue_with_alert(alert, issue_id)

View file

@ -0,0 +1,5 @@
---
title: Update gitlab-shell to v13.4.0
merge_request: 37677
author:
type: changed

View file

@ -1,5 +1,13 @@
---
stage: Plan
group: Certify
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Reply by email # Reply by email
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/1173) in GitLab 8.0.
GitLab can be set up to allow users to comment on issues and merge requests by GitLab can be set up to allow users to comment on issues and merge requests by
replying to notification emails. replying to notification emails.

View file

@ -5,6 +5,17 @@ description: 'Learn how to contribute to GitLab.'
# Contributor and Development Docs # Contributor and Development Docs
Learn the processes and technical information needed for contributing to GitLab.
This content is intended for members of the GitLab Team as well as community contributors.
Content specific to the GitLab Team should instead be included in the [Handbook](https://about.gitlab.com/handbook/).
For information on using GitLab to work on your own software projects, see the [GitLab user documentation](../user/index.md).
For information on working with GitLab's API, see the [API documentation](../api/README.md).
For information on how to install, configure, update, and upgrade your own GitLab instance, see the [administration documentation](../administration/index.md).
## Get started ## Get started
- Set up GitLab's development environment with [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/README.md) - Set up GitLab's development environment with [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/README.md)

View file

@ -0,0 +1,58 @@
# Documentation deployment process
The [`dockerfiles` directory](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/)
contains all needed Dockerfiles to build and deploy <https://docs.gitlab.com>. It
is heavily inspired by Docker's
[Dockerfile](https://github.com/docker/docker.github.io/blob/06ed03db13895bfe867761b6fc2ad40acf6026dd/Dockerfile).
The following Dockerfiles are used.
| Dockerfile | Docker image | Description |
| ---------- | ------------ | ----------- |
| [`Dockerfile.bootstrap`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/Dockerfile.bootstrap) | `gitlab-docs:bootstrap` | Contains all the dependencies that are needed to build the website. If the gems are updated and `Gemfile{,.lock}` changes, the image must be rebuilt. |
| [`Dockerfile.builder.onbuild`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/Dockerfile.builder.onbuild) | `gitlab-docs:builder-onbuild` | Base image to build the docs website. It uses `ONBUILD` to perform all steps and depends on `gitlab-docs:bootstrap`. |
| [`Dockerfile.nginx.onbuild`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/Dockerfile.nginx.onbuild) | `gitlab-docs:nginx-onbuild` | Base image to use for building documentation archives. It uses `ONBUILD` to perform all required steps to copy the archive, and relies upon its parent `Dockerfile.builder.onbuild` that is invoked when building single documentation archives (see the `Dockerfile` of each branch. |
| [`Dockerfile.archives`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/Dockerfile.archives) | `gitlab-docs:archives` | Contains all the versions of the website in one archive. It copies all generated HTML files from every version in one location. |
## How to build the images
Although build images are built automatically via GitLab CI/CD, you can build
and tag all tooling images locally:
1. Make sure you have [Docker installed](https://docs.docker.com/install/).
1. Make sure you're in the `dockerfiles/` directory of the `gitlab-docs` repository.
1. Build the images:
```shell
docker build -t registry.gitlab.com/gitlab-org/gitlab-docs:bootstrap -f Dockerfile.bootstrap ../
docker build -t registry.gitlab.com/gitlab-org/gitlab-docs:builder-onbuild -f Dockerfile.builder.onbuild ../
docker build -t registry.gitlab.com/gitlab-org/gitlab-docs:nginx-onbuild -f Dockerfile.nginx.onbuild ../
```
For each image, there's a manual job under the `images` stage in
[`.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/.gitlab-ci.yml) which can be invoked at will.
## Update an old Docker image with new upstream docs content
If there are any changes to any of the stable branches of the products that are
not included in the single Docker image, just rerun the pipeline (`https://gitlab.com/gitlab-org/gitlab-docs/pipelines/new`)
for the version in question.
## Porting new website changes to old versions
CAUTION: **Warning:**
Porting changes to older branches can have unintended effects as we're constantly
changing the backend of the website. Use only when you know what you're doing
and make sure to test locally.
The website will keep changing and being improved. In order to consolidate
those changes to the stable branches, we'd need to pick certain changes
from time to time.
If this is not possible or there are many changes, merge master into them:
```shell
git branch 12.0
git fetch origin master
git merge origin/master
```

View file

@ -138,6 +138,8 @@ If you need to build and deploy the site immediately (must have maintainer level
1. In [`gitlab-docs`](https://gitlab.com/gitlab-org/gitlab-docs), go to **{rocket}** **CI / CD > Schedules**. 1. In [`gitlab-docs`](https://gitlab.com/gitlab-org/gitlab-docs), go to **{rocket}** **CI / CD > Schedules**.
1. For the `Build docs.gitlab.com every 4 hours` scheduled pipeline, click the **play** (**{play}**) button. 1. For the `Build docs.gitlab.com every 4 hours` scheduled pipeline, click the **play** (**{play}**) button.
Read more about the [deployment process](deployment_process.md).
## Using YAML data files ## Using YAML data files
The easiest way to achieve something similar to The easiest way to achieve something similar to

View file

@ -1,51 +1,21 @@
# GitLab Docs monthly release process # GitLab Docs monthly release process
The [`dockerfiles` directory](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/)
contains all needed Dockerfiles to build and deploy the versioned website. It
is heavily inspired by Docker's
[Dockerfile](https://github.com/docker/docker.github.io/blob/06ed03db13895bfe867761b6fc2ad40acf6026dd/Dockerfile).
The following Dockerfiles are used.
| Dockerfile | Docker image | Description |
| ---------- | ------------ | ----------- |
| [`Dockerfile.bootstrap`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/Dockerfile.bootstrap) | `gitlab-docs:bootstrap` | Contains all the dependencies that are needed to build the website. If the gems are updated and `Gemfile{,.lock}` changes, the image must be rebuilt. |
| [`Dockerfile.builder.onbuild`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/Dockerfile.builder.onbuild) | `gitlab-docs:builder-onbuild` | Base image to build the docs website. It uses `ONBUILD` to perform all steps and depends on `gitlab-docs:bootstrap`. |
| [`Dockerfile.nginx.onbuild`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/Dockerfile.nginx.onbuild) | `gitlab-docs:nginx-onbuild` | Base image to use for building documentation archives. It uses `ONBUILD` to perform all required steps to copy the archive, and relies upon its parent `Dockerfile.builder.onbuild` that is invoked when building single documentation archives (see the `Dockerfile` of each branch. |
| [`Dockerfile.archives`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/dockerfiles/Dockerfile.archives) | `gitlab-docs:archives` | Contains all the versions of the website in one archive. It copies all generated HTML files from every version in one location. |
## How to build the images
Although build images are built automatically via GitLab CI/CD, you can build
and tag all tooling images locally:
1. Make sure you have [Docker installed](https://docs.docker.com/install/).
1. Make sure you're in the `dockerfiles/` directory of the `gitlab-docs` repository.
1. Build the images:
```shell
docker build -t registry.gitlab.com/gitlab-org/gitlab-docs:bootstrap -f Dockerfile.bootstrap ../
docker build -t registry.gitlab.com/gitlab-org/gitlab-docs:builder-onbuild -f Dockerfile.builder.onbuild ../
docker build -t registry.gitlab.com/gitlab-org/gitlab-docs:nginx-onbuild -f Dockerfile.nginx.onbuild ../
```
For each image, there's a manual job under the `images` stage in
[`.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/.gitlab-ci.yml) which can be invoked at will.
## Monthly release process
When a new GitLab version is released on the 22nd, we need to create the respective When a new GitLab version is released on the 22nd, we need to create the respective
single Docker image, and update some files so that the dropdown works correctly. single Docker image, and update some files so that the dropdown works correctly.
### 1. Add the chart version ## 1. Add the chart version
Since the charts use a different version number than all the other GitLab Since the charts use a different version number than all the other GitLab
products, we need to add a products, we need to add a
[version mapping](https://docs.gitlab.com/charts/installation/version_mappings.html): [version mapping](https://docs.gitlab.com/charts/installation/version_mappings.html):
1. Check that there is a [stable branch created](https://gitlab.com/gitlab-org/charts/gitlab/-/branches) NOTE: **Note:**
for the new chart version. If you're unsure or can't find it, drop a line in The charts stable branch is not created automatically like the other products.
the `#g_delivery` channel. There's an [issue to track this](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/1442).
It is usually created on the 21st or the 22nd.
To add a new charts version:
1. Make sure you're in the root path of the `gitlab-docs` repository. 1. Make sure you're in the root path of the `gitlab-docs` repository.
1. Open `content/_data/chart_versions.yaml` and add the new stable branch version using the 1. Open `content/_data/chart_versions.yaml` and add the new stable branch version using the
version mapping. Note that only the `major.minor` version is needed. version mapping. Note that only the `major.minor` version is needed.
@ -56,7 +26,7 @@ It can be handy to create the future mappings since they are pretty much known.
In that case, when a new GitLab version is released, you don't have to repeat In that case, when a new GitLab version is released, you don't have to repeat
this first step. this first step.
### 2. Create an image for a single version ## 2. Create an image for a single version
The single docs version must be created before the release merge request, but The single docs version must be created before the release merge request, but
this needs to happen when the stable branches for all products have been created. this needs to happen when the stable branches for all products have been created.
@ -89,7 +59,7 @@ docker run -it --rm -p 4000:4000 docs:12.0
Visit `http://localhost:4000/12.0/` to see if everything works correctly. Visit `http://localhost:4000/12.0/` to see if everything works correctly.
### 3. Create the release merge request ## 3. Create the release merge request
NOTE: **Note:** NOTE: **Note:**
To be [automated](https://gitlab.com/gitlab-org/gitlab-docs/-/issues/750). To be [automated](https://gitlab.com/gitlab-org/gitlab-docs/-/issues/750).
@ -135,7 +105,7 @@ version and rotates the old one:
git push origin release-12-0 git push origin release-12-0
``` ```
### 4. Update the dropdown for all online versions ## 4. Update the dropdown for all online versions
The versions dropdown is in a way "hardcoded". When the site is built, it looks The versions dropdown is in a way "hardcoded". When the site is built, it looks
at the contents of `content/_data/versions.yaml` and based on that, the dropdown at the contents of `content/_data/versions.yaml` and based on that, the dropdown
@ -144,14 +114,18 @@ dropdown will list one or more releases behind. Remember that the new changes of
the dropdown are included in the unmerged `release-X-Y` branch. the dropdown are included in the unmerged `release-X-Y` branch.
The content of `content/_data/versions.yaml` needs to change for all online The content of `content/_data/versions.yaml` needs to change for all online
versions: versions (stable branches `X.Y` of the `gitlab-docs` project):
1. Run the Rake task that will create all the respective merge requests needed to 1. Run the Rake task that will create all the respective merge requests needed to
update the dropdowns and will be set to automatically be merged when their update the dropdowns and will be set to automatically be merged when their
pipelines succeed. The `release-X-Y` branch needs to be present locally, pipelines succeed:
and you need to have switched to it, otherwise the Rake task will fail:
NOTE: **Note:**
The `release-X-Y` branch needs to be present locally,
and you need to have switched to it, otherwise the Rake task will fail.
```shell ```shell
git checkout release-X-Y
./bin/rake release:dropdowns ./bin/rake release:dropdowns
``` ```
@ -162,46 +136,22 @@ versions:
TIP: **Tip:** TIP: **Tip:**
In case a pipeline fails, see [troubleshooting](#troubleshooting). In case a pipeline fails, see [troubleshooting](#troubleshooting).
### 5. Merge the release merge request ## 5. Merge the release merge request
The dropdown merge requests should have now been merged into their respective The dropdown merge requests should have now been merged into their respective
version (stable branch), which will trigger another pipeline. At this point, version (stable `X.Y` branch), which will trigger another pipeline. At this point,
you need to only babysit the pipelines and make sure they don't fail: you need to only babysit the pipelines and make sure they don't fail:
1. Check the pipelines page: `https://gitlab.com/gitlab-org/gitlab-docs/pipelines` 1. Check the [pipelines page](https://gitlab.com/gitlab-org/gitlab-docs/pipelines)
and make sure all stable branches have green pipelines. and make sure all stable branches have green pipelines.
1. After all the pipelines of the online versions succeed, merge the release merge request. 1. After all the pipelines of the online versions succeed, merge the release merge request.
1. Finally, from `https://gitlab.com/gitlab-org/gitlab-docs/pipeline_schedules` run 1. Finally, run the
the `Build docker images weekly` pipeline that will build the `:latest` and `:archives` Docker images. [`Build docker images weekly` pipeline](https://gitlab.com/gitlab-org/gitlab-docs/pipeline_schedules)
that will build the `:latest` and `:archives` Docker images.
Once the scheduled pipeline succeeds, the docs site will be deployed with all Once the scheduled pipeline succeeds, the docs site will be deployed with all
new versions online. new versions online.
## Update an old Docker image with new upstream docs content
If there are any changes to any of the stable branches of the products that are
not included in the single Docker image, just rerun the pipeline (`https://gitlab.com/gitlab-org/gitlab-docs/pipelines/new`)
for the version in question.
## Porting new website changes to old versions
CAUTION: **Warning:**
Porting changes to older branches can have unintended effects as we're constantly
changing the backend of the website. Use only when you know what you're doing
and make sure to test locally.
The website will keep changing and being improved. In order to consolidate
those changes to the stable branches, we'd need to pick certain changes
from time to time.
If this is not possible or there are many changes, merge master into them:
```shell
git branch 12.0
git fetch origin master
git merge origin/master
```
## Troubleshooting ## Troubleshooting
Releasing a new version is a long process that involves many moving parts. Releasing a new version is a long process that involves many moving parts.

View file

@ -1594,24 +1594,39 @@ describe('DiffsStoreActions', () => {
describe('setCurrentDiffFileIdFromNote', () => { describe('setCurrentDiffFileIdFromNote', () => {
it('commits UPDATE_CURRENT_DIFF_FILE_ID', () => { it('commits UPDATE_CURRENT_DIFF_FILE_ID', () => {
const commit = jest.fn(); const commit = jest.fn();
const state = { diffFiles: [{ file_hash: '123' }] };
const rootGetters = { const rootGetters = {
getDiscussion: () => ({ diff_file: { file_hash: '123' } }), getDiscussion: () => ({ diff_file: { file_hash: '123' } }),
notesById: { '1': { discussion_id: '2' } }, notesById: { '1': { discussion_id: '2' } },
}; };
setCurrentDiffFileIdFromNote({ commit, rootGetters }, '1'); setCurrentDiffFileIdFromNote({ commit, state, rootGetters }, '1');
expect(commit).toHaveBeenCalledWith(types.UPDATE_CURRENT_DIFF_FILE_ID, '123'); expect(commit).toHaveBeenCalledWith(types.UPDATE_CURRENT_DIFF_FILE_ID, '123');
}); });
it('does not commit UPDATE_CURRENT_DIFF_FILE_ID when discussion has no diff_file', () => { it('does not commit UPDATE_CURRENT_DIFF_FILE_ID when discussion has no diff_file', () => {
const commit = jest.fn(); const commit = jest.fn();
const state = { diffFiles: [{ file_hash: '123' }] };
const rootGetters = { const rootGetters = {
getDiscussion: () => ({ id: '1' }), getDiscussion: () => ({ id: '1' }),
notesById: { '1': { discussion_id: '2' } }, notesById: { '1': { discussion_id: '2' } },
}; };
setCurrentDiffFileIdFromNote({ commit, rootGetters }, '1'); setCurrentDiffFileIdFromNote({ commit, state, rootGetters }, '1');
expect(commit).not.toHaveBeenCalled();
});
it('does not commit UPDATE_CURRENT_DIFF_FILE_ID when diff file does not exist', () => {
const commit = jest.fn();
const state = { diffFiles: [{ file_hash: '123' }] };
const rootGetters = {
getDiscussion: () => ({ diff_file: { file_hash: '124' } }),
notesById: { '1': { discussion_id: '2' } },
};
setCurrentDiffFileIdFromNote({ commit, state, rootGetters }, '1');
expect(commit).not.toHaveBeenCalled(); expect(commit).not.toHaveBeenCalled();
}); });

View file

@ -172,7 +172,7 @@ RSpec.describe Gitlab::ImportExport::Group::TreeRestorer do
let(:filepath) { "group_exports/visibility_levels/#{visibility_level}" } let(:filepath) { "group_exports/visibility_levels/#{visibility_level}" }
it "imports all subgroups as #{visibility_level}" do it "imports all subgroups as #{visibility_level}" do
expect(group.children.map(&:visibility_level)).to eq(expected_visibilities) expect(group.children.map(&:visibility_level)).to match_array(expected_visibilities)
end end
end end
end end

View file

@ -88,7 +88,6 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
it_behaves_like 'creating an alert issue' it_behaves_like 'creating an alert issue'
it_behaves_like 'setting an issue attributes' it_behaves_like 'setting an issue attributes'
it_behaves_like 'create alert issue sets issue labels'
end end
context 'when the alert is generic' do context 'when the alert is generic' do
@ -97,7 +96,6 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
it_behaves_like 'creating an alert issue' it_behaves_like 'creating an alert issue'
it_behaves_like 'setting an issue attributes' it_behaves_like 'setting an issue attributes'
it_behaves_like 'create alert issue sets issue labels'
end end
context 'when issue cannot be created' do context 'when issue cannot be created' do

View file

@ -25,10 +25,10 @@ RSpec.describe IncidentManagement::CreateIssueService do
create(:project_incident_management_setting, project: project) create(:project_incident_management_setting, project: project)
end end
subject { service.execute } subject(:execute) { service.execute }
context 'when create_issue enabled' do context 'when create_issue enabled' do
let(:issue) { subject[:issue] } let(:issue) { execute.payload[:issue] }
before do before do
setting.update!(create_issue: true) setting.update!(create_issue: true)
@ -36,7 +36,7 @@ RSpec.describe IncidentManagement::CreateIssueService do
context 'without issue_template_content' do context 'without issue_template_content' do
it 'creates an issue with alert summary only' do it 'creates an issue with alert summary only' do
expect(subject).to include(status: :success) expect(execute).to be_success
expect(issue.author).to eq(user) expect(issue.author).to eq(user)
expect(issue.title).to eq(alert_title) expect(issue.title).to eq(alert_title)
@ -61,7 +61,8 @@ RSpec.describe IncidentManagement::CreateIssueService do
.to receive(:log_error) .to receive(:log_error)
.with(error_message(issue_error)) .with(error_message(issue_error))
expect(subject).to include(status: :error, message: issue_error) expect(execute).to be_error
expect(execute.message).to eq(issue_error)
end end
end end
@ -70,7 +71,7 @@ RSpec.describe IncidentManagement::CreateIssueService do
let(:template_content) { 'some content' } let(:template_content) { 'some content' }
it 'creates an issue appending issue template' do it 'creates an issue appending issue template' do
expect(subject).to include(status: :success) expect(execute).to be_success
expect(issue.description).to include(alert_presenter.issue_summary_markdown) expect(issue.description).to include(alert_presenter.issue_summary_markdown)
expect(separator_count(issue.description)).to eq(1) expect(separator_count(issue.description)).to eq(1)
@ -95,7 +96,7 @@ RSpec.describe IncidentManagement::CreateIssueService do
end end
it 'creates an issue interpreting quick actions' do it 'creates an issue interpreting quick actions' do
expect(subject).to include(status: :success) expect(execute).to be_success
expect(issue.description).to include(plain_text) expect(issue.description).to include(plain_text)
expect(issue.due_date).to be_present expect(issue.due_date).to be_present
@ -128,7 +129,7 @@ RSpec.describe IncidentManagement::CreateIssueService do
end end
it 'includes both templates' do it 'includes both templates' do
expect(subject).to include(status: :success) expect(execute).to be_success
expect(issue.description).to include(alert_presenter.issue_summary_markdown) expect(issue.description).to include(alert_presenter.issue_summary_markdown)
expect(issue.description).to include(template_content) expect(issue.description).to include(template_content)
@ -162,7 +163,7 @@ RSpec.describe IncidentManagement::CreateIssueService do
it 'creates an issue' do it 'creates an issue' do
query_title = "#{gitlab_alert.title} #{gitlab_alert.computed_operator} #{gitlab_alert.threshold}" query_title = "#{gitlab_alert.title} #{gitlab_alert.computed_operator} #{gitlab_alert.threshold}"
expect(subject).to include(status: :success) expect(execute).to be_success
expect(issue.author).to eq(user) expect(issue.author).to eq(user)
expect(issue.title).to eq(alert_presenter.full_title) expect(issue.title).to eq(alert_presenter.full_title)
@ -181,7 +182,8 @@ RSpec.describe IncidentManagement::CreateIssueService do
.to receive(:log_error) .to receive(:log_error)
.with(error_message('invalid alert')) .with(error_message('invalid alert'))
expect(subject).to eq(status: :error, message: 'invalid alert') expect(execute).to be_error
expect(execute.message).to eq('invalid alert')
end end
end end
@ -197,10 +199,6 @@ RSpec.describe IncidentManagement::CreateIssueService do
it_behaves_like 'invalid alert' it_behaves_like 'invalid alert'
end end
end end
describe "label `incident`" do
it_behaves_like 'create alert issue sets issue labels'
end
end end
context 'when create_issue disabled' do context 'when create_issue disabled' do
@ -213,7 +211,8 @@ RSpec.describe IncidentManagement::CreateIssueService do
.to receive(:log_error) .to receive(:log_error)
.with(error_message('setting disabled')) .with(error_message('setting disabled'))
expect(subject).to eq(status: :error, message: 'setting disabled') expect(execute).to be_error
expect(execute.message).to eq('setting disabled')
end end
end end

View file

@ -0,0 +1,67 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe IncidentManagement::Incidents::CreateService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { User.alert_bot }
let(:description) { 'Incident description' }
describe '#execute' do
subject(:create_incident) { described_class.new(project, user, title: title, description: description).execute }
context 'when incident has title and description' do
let(:title) { 'Incident title' }
let(:new_issue) { Issue.last! }
let(:label_title) { IncidentManagement::CreateIncidentLabelService::LABEL_PROPERTIES[:title] }
it 'responds with success' do
expect(create_incident).to be_success
end
it 'creates an incident issue' do
expect { create_incident }.to change(Issue, :count).by(1)
end
it 'created issue has correct attributes' do
create_incident
expect(new_issue.title).to eq(title)
expect(new_issue.description).to eq(description)
expect(new_issue.author).to eq(user)
expect(new_issue.labels.map(&:title)).to eq([label_title])
end
context 'when incident label does not exists' do
it 'creates incident label' do
expect { create_incident }.to change { project.labels.where(title: label_title).count }.by(1)
end
end
context 'when incident label already exists' do
let!(:label) { create(:label, project: project, title: label_title) }
it 'does not create new labels' do
expect { create_incident }.not_to change(Label, :count)
end
end
end
context 'when incident has no title' do
let(:title) { '' }
it 'does not create an issue' do
expect { create_incident }.not_to change(Issue, :count)
end
it 'responds with errors' do
expect(create_incident).to be_error
expect(create_incident.message).to eq("Title can't be blank")
end
it 'result payload contains an Issue object' do
expect(create_incident.payload[:issue]).to be_kind_of(Issue)
end
end
end
end

View file

@ -1,19 +0,0 @@
# frozen_string_literal: true
RSpec.shared_examples 'create alert issue sets issue labels' do
let(:title) { IncidentManagement::CreateIncidentLabelService::LABEL_PROPERTIES[:title] }
let!(:label) { create(:label, project: project, title: title) }
let(:label_service) { instance_double(IncidentManagement::CreateIncidentLabelService, execute: label_service_response) }
before do
allow(IncidentManagement::CreateIncidentLabelService).to receive(:new).with(project, user).and_return(label_service)
end
context 'when create incident label responds with success' do
let(:label_service_response) { ServiceResponse.success(payload: { label: label }) }
it 'adds label to issue' do
expect(issue.labels).to eq([label])
end
end
end