summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2019-01-15 13:53:30 +0100
committerYorick Peterse <yorickpeterse@gmail.com>2019-01-15 13:53:30 +0100
commit7c58b3d2ed7a6eb855312a5eec7e3ff95ca2b670 (patch)
tree2efa79b23d647e4bef7422ec7fb99ae44eac57b1
parent64372c0f46b3b6bb17a41c9bf41579294050e49b (diff)
parentbbf5e92300e9c86cd1d1866fa29266f6c2bc1114 (diff)
downloadgitlab-ce-7c58b3d2ed7a6eb855312a5eec7e3ff95ca2b670.tar.gz
Merge branch '11-7-stable' from GitLab.org
-rw-r--r--app/controllers/projects/releases_controller.rb9
-rw-r--r--app/models/merge_request.rb29
-rw-r--r--app/models/suggestion.rb12
-rw-r--r--app/services/suggestions/apply_service.rb34
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml2
-rw-r--r--app/views/projects/_export.html.haml3
-rw-r--r--app/views/projects/settings/operations/_error_tracking.html.haml2
-rw-r--r--changelogs/unreleased/fix-udpate-head-pipeline-method.yml5
-rw-r--r--changelogs/unreleased/jivl-update-placeholder-sentry-config.yml5
-rw-r--r--changelogs/unreleased/osw-fix-quick-suggestion-application-being-reverted.yml5
-rw-r--r--changelogs/unreleased/sh-fix-gon-helper-avatar.yml5
-rw-r--r--doc/administration/gitaly/index.md2
-rw-r--r--doc/api/README.md3
-rw-r--r--doc/api/releases/index.md (renamed from doc/api/releases.md)7
-rw-r--r--doc/api/releases/links.md177
-rw-r--r--doc/user/project/releases/index.md5
-rw-r--r--doc/user/project/settings/import_export.md2
-rw-r--r--lib/api/release/links.rb2
-rw-r--r--lib/api/releases.rb1
-rw-r--r--lib/gitlab/gon_helper.rb15
-rw-r--r--locale/gitlab.pot2
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb16
-rw-r--r--spec/lib/gitlab/gon_helper_spec.rb9
-rw-r--r--spec/models/merge_request_spec.rb17
-rw-r--r--spec/requests/api/release/links_spec.rb58
-rw-r--r--spec/requests/api/releases_spec.rb61
-rw-r--r--spec/services/suggestions/apply_service_spec.rb173
-rw-r--r--spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb24
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