diff options
author | Robert Speicher <rspeicher@gmail.com> | 2019-01-15 00:45:49 +0000 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2019-01-15 00:45:49 +0000 |
commit | bbf5e92300e9c86cd1d1866fa29266f6c2bc1114 (patch) | |
tree | ab309cc63b57fd272287f0407614a0816ac69597 | |
parent | 61c9b7f5e9115e6022d7ce37673cd3d22341a42a (diff) | |
parent | 38b57664b42f9768dfae049adbde6a1a69959c1c (diff) | |
download | gitlab-ce-bbf5e92300e9c86cd1d1866fa29266f6c2bc1114.tar.gz |
Merge branch '11-7-stable-prepare-rc6' into '11-7-stable'
Prepare 11.7 RC6 release
See merge request gitlab-org/gitlab-ce!24363
28 files changed, 481 insertions, 204 deletions
diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb index 62bdc84b41a..4c39ee4045f 100644 --- a/app/controllers/projects/releases_controller.rb +++ b/app/controllers/projects/releases_controller.rb @@ -4,16 +4,7 @@ class Projects::ReleasesController < Projects::ApplicationController # Authorize before_action :require_non_empty_project before_action :authorize_read_release! - before_action :check_releases_page_feature_flag def index end - - private - - def check_releases_page_feature_flag - return render_404 unless Feature.enabled?(:releases_page, @project) - - push_frontend_feature_flag(:releases_page, @project) - end end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 613860ec31a..237b01636fb 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -550,15 +550,19 @@ class MergeRequest < ActiveRecord::Base end def diff_refs - if persisted? - merge_request_diff.diff_refs - else - Gitlab::Diff::DiffRefs.new( - base_sha: diff_base_sha, - start_sha: diff_start_sha, - head_sha: diff_head_sha - ) - end + persisted? ? merge_request_diff.diff_refs : repository_diff_refs + end + + # Instead trying to fetch the + # persisted diff_refs, this method goes + # straight to the repository to get the + # most recent data possible. + def repository_diff_refs + Gitlab::Diff::DiffRefs.new( + base_sha: branch_merge_base_sha, + start_sha: target_branch_sha, + head_sha: source_branch_sha + ) end def branch_merge_base_sha @@ -1098,9 +1102,10 @@ class MergeRequest < ActiveRecord::Base end def update_head_pipeline - self.head_pipeline = find_actual_head_pipeline - - update_column(:head_pipeline_id, head_pipeline.id) if head_pipeline_id_changed? + find_actual_head_pipeline.try do |pipeline| + self.head_pipeline = pipeline + update_column(:head_pipeline_id, head_pipeline.id) if head_pipeline_id_changed? + end end def merge_request_pipeline_exists? diff --git a/app/models/suggestion.rb b/app/models/suggestion.rb index c76b8e71507..7eee4fbbe5f 100644 --- a/app/models/suggestion.rb +++ b/app/models/suggestion.rb @@ -5,8 +5,7 @@ class Suggestion < ApplicationRecord validates :note, presence: true validates :commit_id, presence: true, if: :applied? - delegate :original_position, :position, :diff_file, - :noteable, to: :note + delegate :original_position, :position, :noteable, to: :note def project noteable.source_project @@ -16,6 +15,15 @@ class Suggestion < ApplicationRecord noteable.source_branch end + def file_path + position.file_path + end + + def diff_file + repository = project.repository + position.diff_file(repository) + end + # For now, suggestions only serve as a way to send patches that # will change a single line (being able to apply multiple in the same place), # which explains `from_line` and `to_line` being the same line. diff --git a/app/services/suggestions/apply_service.rb b/app/services/suggestions/apply_service.rb index d931d528c86..cc47b46b527 100644 --- a/app/services/suggestions/apply_service.rb +++ b/app/services/suggestions/apply_service.rb @@ -11,6 +11,10 @@ module Suggestions return error('Suggestion is not appliable') end + unless latest_diff_refs?(suggestion) + return error('The file has been changed') + end + params = file_update_params(suggestion) result = ::Files::UpdateService.new(suggestion.project, @current_user, params).execute @@ -19,30 +23,44 @@ module Suggestions end result + rescue Files::UpdateService::FileChangedError + error('The file has been changed') end private - def file_update_params(suggestion) - diff_file = suggestion.diff_file + # Checks whether the latest diff refs for the branch matches with + # the position refs we're using to update the file content. Since + # the persisted refs are updated async (for MergeRequest), + # it's more consistent to fetch this data directly from the repository. + def latest_diff_refs?(suggestion) + suggestion.position.diff_refs == suggestion.noteable.repository_diff_refs + end - file_path = diff_file.file_path - branch_name = suggestion.noteable.source_branch - file_content = new_file_content(suggestion) + def file_update_params(suggestion) + blob = suggestion.diff_file.new_blob + file_path = suggestion.file_path + branch_name = suggestion.branch + file_content = new_file_content(suggestion, blob) commit_message = "Apply suggestion to #{file_path}" + file_last_commit = + Gitlab::Git::Commit.last_for_path(suggestion.project.repository, + blob.commit_id, + blob.path) + { file_path: file_path, branch_name: branch_name, start_branch: branch_name, commit_message: commit_message, - file_content: file_content + file_content: file_content, + last_commit_sha: file_last_commit&.id } end - def new_file_content(suggestion) + def new_file_content(suggestion, blob) range = suggestion.from_line_index..suggestion.to_line_index - blob = suggestion.diff_file.new_blob blob.load_all_data! content = blob.data.lines diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml index e516c76400a..c8fdc0112b4 100644 --- a/app/views/layouts/nav/sidebar/_project.html.haml +++ b/app/views/layouts/nav/sidebar/_project.html.haml @@ -29,7 +29,7 @@ = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity' do %span= _('Activity') - - if project_nav_tab?(:releases) && Feature.enabled?(:releases_page, @project) + - if project_nav_tab?(:releases) = nav_link(controller: :releases) do = link_to project_releases_path(@project), title: _('Releases'), class: 'shortcuts-project-releases' do %span= _('Releases') diff --git a/app/views/projects/_export.html.haml b/app/views/projects/_export.html.haml index aa980da7e95..91deffe07c1 100644 --- a/app/views/projects/_export.html.haml +++ b/app/views/projects/_export.html.haml @@ -19,7 +19,7 @@ %ul %li Project and wiki repositories %li Project uploads - %li Project configuration including web hooks and services + %li Project configuration, including services %li Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities %li LFS objects %p @@ -28,6 +28,7 @@ %li Job traces and artifacts %li Container registry images %li CI variables + %li Webhooks %li Any encrypted tokens %p Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page. diff --git a/app/views/projects/settings/operations/_error_tracking.html.haml b/app/views/projects/settings/operations/_error_tracking.html.haml index 71335e4dfd0..871b60f05ba 100644 --- a/app/views/projects/settings/operations/_error_tracking.html.haml +++ b/app/views/projects/settings/operations/_error_tracking.html.haml @@ -18,7 +18,7 @@ = form.label :enabled, _('Active'), class: 'form-check-label' .form-group = form.label :api_url, _('Sentry API URL'), class: 'label-bold' - = form.url_field :api_url, class: 'form-control', placeholder: _('http://<sentry-host>/api/0/projects/{organization_slug}/{project_slug}/issues/') + = form.url_field :api_url, class: 'form-control', placeholder: _('http://<sentry-host>/api/0/projects/{organization_slug}/{project_slug}/') %p.form-text.text-muted = _('Enter your Sentry API URL') .form-group diff --git a/changelogs/unreleased/fix-udpate-head-pipeline-method.yml b/changelogs/unreleased/fix-udpate-head-pipeline-method.yml new file mode 100644 index 00000000000..8dbb9f8e42b --- /dev/null +++ b/changelogs/unreleased/fix-udpate-head-pipeline-method.yml @@ -0,0 +1,5 @@ +--- +title: Fix unexpected exception by failure of finding an actual head pipeline +merge_request: 24257 +author: +type: fixed diff --git a/changelogs/unreleased/jivl-update-placeholder-sentry-config.yml b/changelogs/unreleased/jivl-update-placeholder-sentry-config.yml new file mode 100644 index 00000000000..eb860fd3905 --- /dev/null +++ b/changelogs/unreleased/jivl-update-placeholder-sentry-config.yml @@ -0,0 +1,5 @@ +--- +title: Update url placeholder for the sentry configuration page +merge_request: 24338 +author: +type: other diff --git a/changelogs/unreleased/osw-fix-quick-suggestion-application-being-reverted.yml b/changelogs/unreleased/osw-fix-quick-suggestion-application-being-reverted.yml new file mode 100644 index 00000000000..1f80d7535a5 --- /dev/null +++ b/changelogs/unreleased/osw-fix-quick-suggestion-application-being-reverted.yml @@ -0,0 +1,5 @@ +--- +title: Adjust applied suggestion reverting previous changes +merge_request: 24250 +author: +type: fixed diff --git a/changelogs/unreleased/sh-fix-gon-helper-avatar.yml b/changelogs/unreleased/sh-fix-gon-helper-avatar.yml new file mode 100644 index 00000000000..c83273608ad --- /dev/null +++ b/changelogs/unreleased/sh-fix-gon-helper-avatar.yml @@ -0,0 +1,5 @@ +--- +title: Fix no avatar not showing in user selection box +merge_request: 24346 +author: +type: fixed diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md index cf37eaa0b61..05c1923f0cb 100644 --- a/doc/administration/gitaly/index.md +++ b/doc/administration/gitaly/index.md @@ -217,6 +217,8 @@ repository from your GitLab server over HTTP. ## TLS support +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22602) in GitLab 11.7. + Gitaly supports TLS credentials for GRPC authentication. To be able to communicate with a gitaly instance that listens for secure connections you will need to use `tls://` url scheme in the `gitaly_address` of the corresponding storage entry in the gitlab configuration. diff --git a/doc/api/README.md b/doc/api/README.md index 3ed1a3799c8..6c5bb1c0940 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -69,6 +69,9 @@ The following API resources are available: - [Sidekiq metrics](sidekiq_metrics.md) - [System hooks](system_hooks.md) - [Tags](tags.md) +- [Releases](releases/index.md) +- Release Assets + - [Links](releases/links.md) - [Todos](todos.md) - [Users](users.md) - [Validate CI configuration](lint.md) (linting) diff --git a/doc/api/releases.md b/doc/api/releases/index.md index 4613fe3482a..943109a3ea9 100644 --- a/doc/api/releases.md +++ b/doc/api/releases/index.md @@ -1,7 +1,8 @@ # Releases API > - [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/41766) in GitLab 11.7. -> - Using this API you can manipulate GitLab's [Release](../user/project/releases/index.md) entries. +> - Using this API you can manipulate GitLab's [Release](../../user/project/releases/index.md) entries. +> - For manipulating links as a release asset, see [Release Links API](links.md) ## List Releases @@ -241,7 +242,7 @@ POST /projects/:id/releases | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | | `name` | string | yes | The release name. | | `tag_name` | string | yes | The tag where the release will be created from. | -| `description` | string | no | The description of the release. You can use [markdown](../user/markdown.md). | +| `description` | string | yes | The description of the release. You can use [markdown](../user/markdown.md). | | `ref` | string | no | If `tag_name` doesn't exist, the release will be created from `ref`. It can be a commit SHA, another tag name, or a branch name. | | `assets:links`| array of hash | no | An array of assets links. | | `assets:links:name`| string | no (if `assets:links` specified, it's required) | The name of the link. | @@ -331,8 +332,8 @@ PUT /projects/:id/releases/:tag_name | Attribute | Type | Required | Description | | ------------- | -------------- | -------- | --------------------------------------- | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `tag_name` | string | yes | The tag where the release will be created from. | | `name` | string | no | The release name. | -| `tag_name` | string | no | The tag where the release will be created from. | | `description` | string | no | The description of the release. You can use [markdown](../user/markdown.md). | Example request: diff --git a/doc/api/releases/links.md b/doc/api/releases/links.md new file mode 100644 index 00000000000..ae99f3bd8b6 --- /dev/null +++ b/doc/api/releases/links.md @@ -0,0 +1,177 @@ +# Release links API + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/41766) in GitLab 11.7. + +Using this API you can manipulate GitLab's [Release](../../user/project/releases/index.md) links. For manipulating other Release assets, see [Release API](index.md). + +## Get links + +Get assets as links from a Release. + +``` +GET /projects/:id/releases/:tag_name/assets/links +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `tag_name` | string | yes | The tag associated with the Release. | + +Example request: + +```sh +curl --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1/assets/links" +``` + +Example response: + +```json +[ + { + "id":2, + "name":"awesome-v0.2.msi", + "url":"http://192.168.10.15:3000/msi", + "external":true + }, + { + "id":1, + "name":"awesome-v0.2.dmg", + "url":"http://192.168.10.15:3000", + "external":true + } +] +``` + +## Get a link + +Get an asset as a link from a Release. + +``` +GET /projects/:id/releases/:tag_name/assets/links/:link_id +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `tag_name` | string | yes | The tag associated with the Release. | +| `link_id` | integer | yes | The id of the link. | + +Example request: + +```sh +curl --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1/assets/links/1" +``` + +Example response: + +```json +{ + "id":1, + "name":"awesome-v0.2.dmg", + "url":"http://192.168.10.15:3000", + "external":true +} +``` + +## Create a link + +Create an asset as a link from a Release. + +``` +POST /projects/:id/releases/:tag_name/assets/links +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `tag_name` | string | yes | The tag associated with the Release. | +| `name` | string | yes | The name of the link. | +| `url` | string | yes | The URL of the link. | + +Example request: + +```sh +curl --request POST \ + --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" \ + --data name="awesome-v0.2.dmg" \ + --data url="http://192.168.10.15:3000" \ + "http://localhost:3000/api/v4/projects/24/releases/v0.1/assets/links" +``` + +Example response: + +```json +{ + "id":1, + "name":"awesome-v0.2.dmg", + "url":"http://192.168.10.15:3000", + "external":true +} +``` + +## Update a link + +Update an asset as a link from a Release. + +``` +PUT /projects/:id/releases/:tag_name/assets/links/:link_id +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `tag_name` | string | yes | The tag associated with the Release. | +| `link_id` | integer | yes | The id of the link. | +| `name` | string | no | The name of the link. | +| `url` | string | no | The URL of the link. | + +NOTE: **NOTE** +You have to specify at least one of `name` or `url` + +Example request: + +```sh +curl --request PUT --data name="new name" --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1/assets/links/1" +``` + +Example response: + +```json +{ + "id":1, + "name":"new name", + "url":"http://192.168.10.15:3000", + "external":true +} +``` + +## Delete a link + +Delete an asset as a link from a Release. + +``` +DELETE /projects/:id/releases/:tag_name/assets/links/:link_id +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `tag_name` | string | yes | The tag associated with the Release. | +| `link_id` | integer | yes | The id of the link. | + +Example request: + +```sh +curl --request DELETE --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1/assets/links/1" +``` + +Example response: + +```json +{ + "id":1, + "name":"new name", + "url":"http://192.168.10.15:3000", + "external":true +} +``` diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md index 890d6fbc6c7..00a4f6c6a6b 100644 --- a/doc/user/project/releases/index.md +++ b/doc/user/project/releases/index.md @@ -12,7 +12,7 @@ GitLab's **Releases** are a way to track deliverables in your project. Consider a snapshot in time of the source, build output, and other metadata or artifacts associated with a released version of your code. -At the moment, you can create Release entries via the [Releases API](../../../api/releases.md); +At the moment, you can create Release entries via the [Releases API](../../../api/releases/index.md); we recommend doing this as one of the last steps in your CI/CD release pipeline. ## Getting started with Releases @@ -51,6 +51,9 @@ A link is any URL which can point to whatever you like; documentation, built binaries, or other related materials. These can be both internal or external links from your GitLab instance. +NOTE: **NOTE** +You can manipulate links of each release entry with [Release Links API](../../../api/releases/links.md) + ## Releases list Navigate to **Project > Releases** in order to see the list of releases for a given diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md index 3bbfa74f4b7..89008fd15b9 100644 --- a/doc/user/project/settings/import_export.md +++ b/doc/user/project/settings/import_export.md @@ -61,7 +61,7 @@ The following items will be exported: - Project and wiki repositories - Project uploads -- Project configuration including web hooks and services +- Project configuration, including services - Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities - LFS objects diff --git a/lib/api/release/links.rb b/lib/api/release/links.rb index a75a320e929..e3072684ef7 100644 --- a/lib/api/release/links.rb +++ b/lib/api/release/links.rb @@ -8,8 +8,6 @@ module API RELEASE_ENDPOINT_REQUIREMETS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS .merge(tag_name: API::NO_SLASH_URL_PART_REGEX) - before { error!('404 Not Found', 404) unless Feature.enabled?(:releases_page, user_project) } - params do requires :id, type: String, desc: 'The ID of a project' end diff --git a/lib/api/releases.rb b/lib/api/releases.rb index c3d4101528c..576fee51db0 100644 --- a/lib/api/releases.rb +++ b/lib/api/releases.rb @@ -7,7 +7,6 @@ module API RELEASE_ENDPOINT_REQUIREMETS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS .merge(tag_name: API::NO_SLASH_URL_PART_REGEX) - before { error!('404 Not Found', 404) unless Feature.enabled?(:releases_page, user_project) } before { authorize_read_releases! } params do diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb index 15137140639..9b1794eec91 100644 --- a/lib/gitlab/gon_helper.rb +++ b/lib/gitlab/gon_helper.rb @@ -8,10 +8,7 @@ module Gitlab def add_gon_variables gon.api_version = 'v4' - gon.default_avatar_url = - Gitlab::Utils.append_path( - Gitlab.config.gitlab.url, - ActionController::Base.helpers.image_path('no_avatar.png')) + gon.default_avatar_url = default_avatar_url gon.max_file_size = Gitlab::CurrentSettings.max_attachment_size gon.asset_host = ActionController::Base.asset_host gon.webpack_public_path = webpack_public_path @@ -50,5 +47,15 @@ module Gitlab # use this method to push multiple feature flags. gon.push({ features: { var_name => enabled } }, true) end + + def default_avatar_url + # We can't use ActionController::Base.helpers.image_url because it + # doesn't return an actual URL because request is nil for some reason. + # + # We also can't use Gitlab::Utils.append_path because the image path + # may be an absolute URL. + URI.join(Gitlab.config.gitlab.url, + ActionController::Base.helpers.image_path('no_avatar.png')).to_s + end end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 7a5633ca446..1782c9d5e4d 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -8026,7 +8026,7 @@ msgstr "" msgid "here" msgstr "" -msgid "http://<sentry-host>/api/0/projects/{organization_slug}/{project_slug}/issues/" +msgid "http://<sentry-host>/api/0/projects/{organization_slug}/{project_slug}/" msgstr "" msgid "https://your-bitbucket-server" diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb index f170a2ab613..5b9d21d3d5b 100644 --- a/spec/controllers/projects/releases_controller_spec.rb +++ b/spec/controllers/projects/releases_controller_spec.rb @@ -6,10 +6,6 @@ describe Projects::ReleasesController do let!(:project) { create(:project, :repository, :public) } let!(:user) { create(:user) } - before do - stub_feature_flags(releases_page: true) - end - describe 'GET #index' do it 'renders a 200' do get_index @@ -43,18 +39,6 @@ describe Projects::ReleasesController do expect(response.status).to eq(404) end end - - context 'when releases_page feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it 'renders a 404' do - get_index - - expect(response.status).to eq(404) - end - end end private diff --git a/spec/lib/gitlab/gon_helper_spec.rb b/spec/lib/gitlab/gon_helper_spec.rb index c6f09ca2112..1ff2334bacf 100644 --- a/spec/lib/gitlab/gon_helper_spec.rb +++ b/spec/lib/gitlab/gon_helper_spec.rb @@ -29,4 +29,13 @@ describe Gitlab::GonHelper do helper.push_frontend_feature_flag(:my_feature_flag, 10) end end + + describe '#default_avatar_url' do + it 'returns an absolute URL' do + url = helper.default_avatar_url + + expect(url).to match(/^http/) + expect(url).to match(/no_avatar.*png$/) + end + end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 96d49e86dab..ed80a662a3b 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -1390,6 +1390,23 @@ describe MergeRequest do .to change { merge_request.reload.head_pipeline } .from(nil).to(pipeline) end + + context 'when merge request has already had head pipeline' do + before do + merge_request.update!(head_pipeline: pipeline) + end + + context 'when failed to find an actual head pipeline' do + before do + allow(merge_request).to receive(:find_actual_head_pipeline) { } + end + + it 'does not update the current head pipeline' do + expect { subject } + .not_to change { merge_request.reload.head_pipeline } + end + end + end end context 'when there are no pipelines with the diff head sha' do diff --git a/spec/requests/api/release/links_spec.rb b/spec/requests/api/release/links_spec.rb index 9d62257d470..ba948e37e2f 100644 --- a/spec/requests/api/release/links_spec.rb +++ b/spec/requests/api/release/links_spec.rb @@ -74,16 +74,6 @@ describe API::Release::Links do end end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it_behaves_like '404 response' do - let(:request) { get api("/projects/#{project.id}/releases/v0.1/assets/links", maintainer) } - end - end end describe 'GET /projects/:id/releases/:tag_name/assets/links/:link_id' do @@ -129,16 +119,6 @@ describe API::Release::Links do end end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it_behaves_like '404 response' do - let(:request) { get api("/projects/#{project.id}/releases/non_existing_tag/assets/links/#{release_link.id}", maintainer) } - end - end end describe 'POST /projects/:id/releases/:tag_name/assets/links' do @@ -231,19 +211,6 @@ describe API::Release::Links do end end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it_behaves_like '404 response' do - let(:request) do - post api("/projects/#{project.id}/releases/v0.1/assets/links", maintainer), - params: params - end - end - end end describe 'PUT /projects/:id/releases/:tag_name/assets/links/:link_id' do @@ -328,19 +295,6 @@ describe API::Release::Links do end end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it_behaves_like '404 response' do - let(:request) do - put api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}", maintainer), - params: params - end - end - end end describe 'DELETE /projects/:id/releases/:tag_name/assets/links/:link_id' do @@ -401,17 +355,5 @@ describe API::Release::Links do end end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it_behaves_like '404 response' do - let(:request) do - delete api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}", maintainer) - end - end - end end end diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb index 978fa0142c2..811e23fb854 100644 --- a/spec/requests/api/releases_spec.rb +++ b/spec/requests/api/releases_spec.rb @@ -83,18 +83,6 @@ describe API::Releases do end end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it 'cannot find the API' do - get api("/projects/#{project.id}/releases", maintainer) - - expect(response).to have_gitlab_http_status(:not_found) - end - end end describe 'GET /projects/:id/releases/:tag_name' do @@ -205,18 +193,6 @@ describe API::Releases do end end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it 'cannot find the API' do - get api("/projects/#{project.id}/releases/v0.1", maintainer) - - expect(response).to have_gitlab_http_status(:not_found) - end - end end describe 'POST /projects/:id/releases' do @@ -458,18 +434,6 @@ describe API::Releases do expect(response).to have_gitlab_http_status(:conflict) end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it 'cannot find the API' do - post api("/projects/#{project.id}/releases", maintainer), params: params - - expect(response).to have_gitlab_http_status(:not_found) - end - end end describe 'PUT /projects/:id/releases/:tag_name' do @@ -565,19 +529,6 @@ describe API::Releases do end end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it 'cannot find the API' do - put api("/projects/#{project.id}/releases/v0.1", non_project_member), - params: params - - expect(response).to have_gitlab_http_status(:not_found) - end - end end describe 'DELETE /projects/:id/releases/:tag_name' do @@ -648,17 +599,5 @@ describe API::Releases do end end end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it 'cannot find the API' do - delete api("/projects/#{project.id}/releases/v0.1", non_project_member) - - expect(response).to have_gitlab_http_status(:not_found) - end - end end end diff --git a/spec/services/suggestions/apply_service_spec.rb b/spec/services/suggestions/apply_service_spec.rb index 3a483717756..e5ca1c155ed 100644 --- a/spec/services/suggestions/apply_service_spec.rb +++ b/spec/services/suggestions/apply_service_spec.rb @@ -117,13 +117,184 @@ describe Suggestions::ApplyService do expect(commit.committer_email).to eq(user.commit_email) expect(commit.author_name).to eq(user.name) end + + context 'when it fails to apply because the file was changed' do + it 'returns error message' do + service = instance_double(Files::UpdateService) + + expect(Files::UpdateService).to receive(:new) + .and_return(service) + + allow(service).to receive(:execute) + .and_raise(Files::UpdateService::FileChangedError) + + result = subject.execute(suggestion) + + expect(result).to eq(message: 'The file has been changed', status: :error) + end + end + + context 'when diff ref from position is different from repo diff refs' do + it 'returns error message' do + outdated_refs = Gitlab::Diff::DiffRefs.new(base_sha: 'foo', start_sha: 'bar', head_sha: 'outdated') + + allow(suggestion).to receive(:appliable?) { true } + allow(suggestion.position).to receive(:diff_refs) { outdated_refs } + + result = subject.execute(suggestion) + + expect(result).to eq(message: 'The file has been changed', status: :error) + end + end + + context 'multiple suggestions applied' do + let(:expected_content) do + <<-CONTENT.strip_heredoc + require 'fileutils' + require 'open3' + + module Popen + extend self + + + def popen(cmd, path=nil) + unless cmd.is_a?(Array) + # v1 change + end + + path ||= Dir.pwd + # v1 change + vars = { + "PWD" => path + } + + options = { + chdir: path + } + # v2 change + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + + @cmd_output = "" + # v2 change + + Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| + @cmd_output << stdout.read + @cmd_output << stderr.read + @cmd_status = wait_thr.value.exitstatus + end + + return @cmd_output, @cmd_status + end + end + CONTENT + end + + let(:merge_request) do + create(:merge_request, source_project: project, + target_project: project) + end + + def create_suggestion(diff, old_line: nil, new_line: nil, from_content:, to_content:, path:) + position = Gitlab::Diff::Position.new(old_path: path, + new_path: path, + old_line: old_line, + new_line: new_line, + diff_refs: diff.diff_refs) + + suggestion_note = create(:diff_note_on_merge_request, noteable: merge_request, + original_position: position, + position: position, + project: project) + create(:suggestion, note: suggestion_note, + from_content: from_content, + to_content: to_content) + end + + def apply_suggestion(suggestion) + suggestion.note.reload + merge_request.reload + merge_request.clear_memoized_shas + + result = subject.execute(suggestion) + refresh = MergeRequests::RefreshService.new(project, user) + refresh.execute(merge_request.diff_head_sha, + suggestion.commit_id, + merge_request.source_branch_ref) + + result + end + + def fetch_raw_diff(suggestion) + project.reload.commit(suggestion.commit_id).diffs.diff_files.first.diff.diff + end + + it 'applies multiple suggestions in subsequent versions correctly' do + diff = merge_request.merge_request_diff + path = 'files/ruby/popen.rb' + + suggestion_1_changes = { old_line: nil, + new_line: 13, + from_content: "\n", + to_content: "# v1 change\n", + path: path } + + suggestion_2_changes = { old_line: 24, + new_line: 31, + from_content: " @cmd_output << stderr.read\n", + to_content: "# v2 change\n", + path: path } + + suggestion_1 = create_suggestion(diff, suggestion_1_changes) + suggestion_2 = create_suggestion(diff, suggestion_2_changes) + + apply_suggestion(suggestion_1) + + suggestion_1_diff = fetch_raw_diff(suggestion_1) + + # rubocop: disable Layout/TrailingWhitespace + expected_suggestion_1_diff = <<-CONTENT.strip_heredoc + @@ -10,7 +10,7 @@ module Popen + end + + path ||= Dir.pwd + - + +# v1 change + vars = { + "PWD" => path + } + CONTENT + # rubocop: enable Layout/TrailingWhitespace + + apply_suggestion(suggestion_2) + + suggestion_2_diff = fetch_raw_diff(suggestion_2) + + # rubocop: disable Layout/TrailingWhitespace + expected_suggestion_2_diff = <<-CONTENT.strip_heredoc + @@ -28,7 +28,7 @@ module Popen + + Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| + @cmd_output << stdout.read + - @cmd_output << stderr.read + +# v2 change + @cmd_status = wait_thr.value.exitstatus + end + CONTENT + # rubocop: enable Layout/TrailingWhitespace + + expect(suggestion_1_diff.strip).to eq(expected_suggestion_1_diff.strip) + expect(suggestion_2_diff.strip).to eq(expected_suggestion_2_diff.strip) + end + end end context 'fork-project' do let(:project) { create(:project, :public, :repository) } let(:forked_project) do - fork_project_with_submodules(project, user) + fork_project_with_submodules(project, user, repository: project.repository) end let(:merge_request) do diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb index ec20c346234..2852aa380b2 100644 --- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb +++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb @@ -51,28 +51,10 @@ describe 'layouts/nav/sidebar/_project' do end describe 'releases entry' do - describe 'when releases feature flag is disabled' do - before do - stub_feature_flags(releases_page: false) - end - - it 'does not render releases link' do - render - - expect(rendered).not_to have_link('Releases', href: project_releases_path(project)) - end - end - - describe 'when releases feature flags is enabled' do - before do - stub_feature_flags(releases_page: true) - end - - it 'renders releases link' do - render + it 'renders releases link' do + render - expect(rendered).to have_link('Releases', href: project_releases_path(project)) - end + expect(rendered).to have_link('Releases', href: project_releases_path(project)) end end end |