Commit da35510c authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 7f82744e
...@@ -104,11 +104,11 @@ export default { ...@@ -104,11 +104,11 @@ export default {
/> />
<div <div
:class="{ 'd-sm-flex': !group.isChildrenLoading }" :class="{ 'd-sm-flex': !group.isChildrenLoading }"
class="avatar-container rect-avatar s32 d-none flex-grow-0 flex-shrink-0 " class="avatar-container rect-avatar s40 d-none flex-grow-0 flex-shrink-0 "
> >
<a :href="group.relativePath" class="no-expand"> <a :href="group.relativePath" class="no-expand">
<img v-if="hasAvatar" :src="group.avatarUrl" class="avatar s32" /> <img v-if="hasAvatar" :src="group.avatarUrl" class="avatar s40" />
<identicon v-else :entity-id="group.id" :entity-name="group.name" size-class="s32" /> <identicon v-else :entity-id="group.id" :entity-name="group.name" size-class="s40" />
</a> </a>
</div> </div>
<div class="group-text-container d-flex flex-fill align-items-center"> <div class="group-text-container d-flex flex-fill align-items-center">
......
...@@ -55,12 +55,27 @@ module Types ...@@ -55,12 +55,27 @@ module Types
field :web_url, GraphQL::STRING_TYPE, null: true # rubocop:disable Graphql/Descriptions field :web_url, GraphQL::STRING_TYPE, null: true # rubocop:disable Graphql/Descriptions
field :upvotes, GraphQL::INT_TYPE, null: false # rubocop:disable Graphql/Descriptions field :upvotes, GraphQL::INT_TYPE, null: false # rubocop:disable Graphql/Descriptions
field :downvotes, GraphQL::INT_TYPE, null: false # rubocop:disable Graphql/Descriptions field :downvotes, GraphQL::INT_TYPE, null: false # rubocop:disable Graphql/Descriptions
field :subscribed, GraphQL::BOOLEAN_TYPE, method: :subscribed?, null: false # rubocop:disable Graphql/Descriptions
field :head_pipeline, Types::Ci::PipelineType, null: true, method: :actual_head_pipeline # rubocop:disable Graphql/Descriptions field :head_pipeline, Types::Ci::PipelineType, null: true, method: :actual_head_pipeline # rubocop:disable Graphql/Descriptions
field :pipelines, Types::Ci::PipelineType.connection_type, # rubocop:disable Graphql/Descriptions field :pipelines, Types::Ci::PipelineType.connection_type, # rubocop:disable Graphql/Descriptions
resolver: Resolvers::MergeRequestPipelinesResolver resolver: Resolvers::MergeRequestPipelinesResolver
field :milestone, Types::MilestoneType, description: 'The milestone this merge request is linked to',
null: true,
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Milestone, obj.milestone_id).find }
field :assignees, Types::UserType.connection_type, null: true, complexity: 5, description: 'The list of assignees for the merge request'
field :participants, Types::UserType.connection_type, null: true, complexity: 5, description: 'The list of participants on the merge request'
field :subscribed, GraphQL::BOOLEAN_TYPE, method: :subscribed?, null: false, complexity: 5,
description: 'Boolean flag for whether the currently logged in user is subscribed to this MR'
field :labels, Types::LabelType.connection_type, null: true, complexity: 5, description: 'The list of labels on the merge request'
field :discussion_locked, GraphQL::BOOLEAN_TYPE, description: 'Boolean flag determining if comments on the merge request are locked to members only',
null: false,
resolve: -> (obj, _args, _ctx) { !!obj.discussion_locked }
field :time_estimate, GraphQL::INT_TYPE, null: false, description: 'The time estimate for the merge request'
field :total_time_spent, GraphQL::INT_TYPE, null: false, description: 'Total time reported as spent on the merge request'
field :reference, GraphQL::STRING_TYPE, null: false, method: :to_reference, description: 'Internal merge request reference. Returned in shortened format by default' do
argument :full, GraphQL::BOOLEAN_TYPE, required: false, default_value: false, description: 'Boolean option specifying whether the reference should be returned in full'
end
field :task_completion_status, Types::TaskCompletionStatus, null: false # rubocop:disable Graphql/Descriptions field :task_completion_status, Types::TaskCompletionStatus, null: false # rubocop:disable Graphql/Descriptions
end end
end end
...@@ -291,7 +291,8 @@ module ApplicationSettingsHelper ...@@ -291,7 +291,8 @@ module ApplicationSettingsHelper
:snowplow_enabled, :snowplow_enabled,
:snowplow_site_id, :snowplow_site_id,
:push_event_hooks_limit, :push_event_hooks_limit,
:push_event_activities_limit :push_event_activities_limit,
:custom_http_clone_url_root
] ]
end end
......
...@@ -128,7 +128,8 @@ module ApplicationSettingImplementation ...@@ -128,7 +128,8 @@ module ApplicationSettingImplementation
snowplow_collector_hostname: nil, snowplow_collector_hostname: nil,
snowplow_cookie_domain: nil, snowplow_cookie_domain: nil,
snowplow_enabled: false, snowplow_enabled: false,
snowplow_site_id: nil snowplow_site_id: nil,
custom_http_clone_url_root: nil
} }
end end
......
...@@ -1036,8 +1036,8 @@ class Project < ApplicationRecord ...@@ -1036,8 +1036,8 @@ class Project < ApplicationRecord
end end
end end
def web_url def web_url(only_path: nil)
Gitlab::Routing.url_helpers.project_url(self) Gitlab::Routing.url_helpers.project_url(self, only_path: only_path)
end end
def readme_url def readme_url
...@@ -1316,7 +1316,18 @@ class Project < ApplicationRecord ...@@ -1316,7 +1316,18 @@ class Project < ApplicationRecord
end end
def http_url_to_repo def http_url_to_repo
"#{web_url}.git" custom_root = Gitlab::CurrentSettings.custom_http_clone_url_root
project_url = if custom_root.present?
Gitlab::Utils.append_path(
custom_root,
web_url(only_path: true)
)
else
web_url
end
"#{project_url}.git"
end end
# Is overridden in EE # Is overridden in EE
......
...@@ -54,7 +54,7 @@ class ProjectWiki ...@@ -54,7 +54,7 @@ class ProjectWiki
end end
def http_url_to_repo def http_url_to_repo
"#{Gitlab.config.gitlab.url}/#{full_path}.git" @project.http_url_to_repo.sub(%r{git\z}, 'wiki.git')
end end
def wiki_base_path def wiki_base_path
......
...@@ -53,6 +53,11 @@ ...@@ -53,6 +53,11 @@
= select(:application_setting, :enabled_git_access_protocol, [['Both SSH and HTTP(S)', nil], ['Only SSH', 'ssh'], ['Only HTTP(S)', 'http']], {}, class: 'form-control') = select(:application_setting, :enabled_git_access_protocol, [['Both SSH and HTTP(S)', nil], ['Only SSH', 'ssh'], ['Only HTTP(S)', 'http']], {}, class: 'form-control')
%span.form-text.text-muted#clone-protocol-help %span.form-text.text-muted#clone-protocol-help
= _('Allow only the selected protocols to be used for Git access.') = _('Allow only the selected protocols to be used for Git access.')
.form-group
= f.label :custom_http_clone_url_root, _('Custom Git clone URL for HTTP(S)'), class: 'label-bold'
= f.text_field :custom_http_clone_url_root, class: 'form-control', placeholder: 'https://git.example.com', :'aria-describedby' => 'custom_http_clone_url_root_help_block'
%span.form-text.text-muted#custom_http_clone_url_root_help_block
= _('Replaces the clone URL root.')
- ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type| - ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type|
- field_name = :"#{type}_key_restriction" - field_name = :"#{type}_key_restriction"
......
...@@ -59,3 +59,9 @@ ...@@ -59,3 +59,9 @@
%span.js-details-content.hide %span.js-details-content.hide
= link_to @pipeline.sha, project_commit_path(@project, @pipeline.sha), class: "commit-sha commit-hash-full" = link_to @pipeline.sha, project_commit_path(@project, @pipeline.sha), class: "commit-sha commit-hash-full"
= clipboard_button(text: @pipeline.sha, title: _("Copy commit SHA")) = clipboard_button(text: @pipeline.sha, title: _("Copy commit SHA"))
.well-segment.related-merge-request-info
.icon-container
= sprite_icon("git-merge")
%span.related-merge-requests
= @pipeline.all_related_merge_request_text
---
title: Fix creating epics with dates from api
merge_request: 18393
author:
type: fixed
---
title: Extend graphql query endpoint for merge requests to return more attributes to support sidebar implementation
merge_request: 17813
author:
type: other
---
title: Increase group avatar size to 40px
merge_request: 18654
author:
type: changed
---
title: Add "Custom HTTP Git clone URL root" setting
merge_request: 18422
author:
type: added
---
title: Show related merge requests in pipeline view
merge_request: 18697
author:
type: added
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddCustomHttpCloneUrlRootToApplicationSettings < ActiveRecord::Migration[5.2]
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
def change
add_column :application_settings, :custom_http_clone_url_root, :string, limit: 511
end
end
...@@ -340,6 +340,7 @@ ActiveRecord::Schema.define(version: 2019_10_16_220135) do ...@@ -340,6 +340,7 @@ ActiveRecord::Schema.define(version: 2019_10_16_220135) do
t.integer "throttle_incident_management_notification_per_period", default: 3600 t.integer "throttle_incident_management_notification_per_period", default: 3600
t.integer "push_event_hooks_limit", default: 3, null: false t.integer "push_event_hooks_limit", default: 3, null: false
t.integer "push_event_activities_limit", default: 3, null: false t.integer "push_event_activities_limit", default: 3, null: false
t.string "custom_http_clone_url_root", limit: 511
t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id" t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id"
t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id" t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id"
t.index ["instance_administration_project_id"], name: "index_applicationsettings_on_instance_administration_project_id" t.index ["instance_administration_project_id"], name: "index_applicationsettings_on_instance_administration_project_id"
......
...@@ -95,13 +95,12 @@ on the external URL of the current host. For example: ...@@ -95,13 +95,12 @@ on the external URL of the current host. For example:
![Clone panel](img/single_git_clone_panel.png) ![Clone panel](img/single_git_clone_panel.png)
However, you can customize the SSH remote URL to use the location-aware You can customize the SSH remote URL to use the location-aware
`git.example.com`. To do so, change the SSH remote URL's host by setting `git.example.com`. To do so, change the SSH remote URL's host by setting
`gitlab_rails['gitlab_ssh_host']` in `gitlab.rb` of web nodes. `gitlab_rails['gitlab_ssh_host']` in `gitlab.rb` of web nodes.
Unfortunately the means to specify a custom HTTP clone URL is not yet You can customize the HTTP remote URL as shown in
implemented. The feature request can be found at [Custom Git clone URL for HTTP(S)](../../../user/admin_area/settings/visibility_and_access_controls.md#custom-git-clone-url-for-https).
[Customizable Git HTTP clone root URL](https://gitlab.com/gitlab-org/gitlab/issues/31949).
## Example Git request handling behavior ## Example Git request handling behavior
......
...@@ -435,8 +435,13 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph ...@@ -435,8 +435,13 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `webUrl` | String | | | `webUrl` | String | |
| `upvotes` | Int! | | | `upvotes` | Int! | |
| `downvotes` | Int! | | | `downvotes` | Int! | |
| `subscribed` | Boolean! | |
| `headPipeline` | Pipeline | | | `headPipeline` | Pipeline | |
| `milestone` | Milestone | The milestone this merge request is linked to |
| `subscribed` | Boolean! | Boolean flag for whether the currently logged in user is subscribed to this MR |
| `discussionLocked` | Boolean! | Boolean flag determining if comments on the merge request are locked to members only |
| `timeEstimate` | Int! | The time estimate for the merge request |
| `totalTimeSpent` | Int! | Total time reported as spent on the merge request |
| `reference` | String! | Internal merge request reference. Returned in shortened format by default |
| `taskCompletionStatus` | TaskCompletionStatus! | | | `taskCompletionStatus` | TaskCompletionStatus! | |
### MergeRequestPermissions ### MergeRequestPermissions
......
...@@ -135,6 +135,30 @@ Starting with [GitLab 10.7](https://gitlab.com/gitlab-org/gitlab-ce/merge_reques ...@@ -135,6 +135,30 @@ Starting with [GitLab 10.7](https://gitlab.com/gitlab-org/gitlab-ce/merge_reques
HTTP(S) protocol will be allowed for Git clone or fetch requests done by GitLab Runner HTTP(S) protocol will be allowed for Git clone or fetch requests done by GitLab Runner
from CI/CD jobs, even if _Only SSH_ was selected. from CI/CD jobs, even if _Only SSH_ was selected.
## Custom Git clone URL for HTTP(S)
You can customize project Git clone URLs for HTTP(S). This will affect the clone
panel:
![Clone panel](img/clone_panel.png)
For example, if your
GitLab instance is at `https://example.com`, then project clone URLs look like
`https://example.com/foo/bar.git`. If you'd to provide clone URLs that look like
`https://git.example.com/gitlab/foo/bar.git` instead, then you can set this
setting to `https://git.example.com/gitlab/`.
![Custom Git clone URL for HTTP](img/custom_git_clone_url_for_https.png)
To specify a custom Git clone URL for HTTP(S):
1. Enter a root URL for **Custom Git clone URL for HTTP(S)**.
1. Click on **Save changes**.
NOTE: **Note:**
SSH clone URLs can be customized in `gitlab.rb` by setting
`gitlab_rails["gitlab_ssh_host"]` and other related settings.
## RSA, DSA, ECDSA, ED25519 SSH keys ## RSA, DSA, ECDSA, ED25519 SSH keys
These options specify the permitted types and lengths for SSH keys. These options specify the permitted types and lengths for SSH keys.
......
...@@ -4828,6 +4828,9 @@ msgstr "" ...@@ -4828,6 +4828,9 @@ msgstr ""
msgid "Custom CI configuration path" msgid "Custom CI configuration path"
msgstr "" msgstr ""
msgid "Custom Git clone URL for HTTP(S)"
msgstr ""
msgid "Custom hostname (for private commit emails)" msgid "Custom hostname (for private commit emails)"
msgstr "" msgstr ""
...@@ -13738,6 +13741,9 @@ msgstr "" ...@@ -13738,6 +13741,9 @@ msgstr ""
msgid "Replaced all labels with %{label_references} %{label_text}." msgid "Replaced all labels with %{label_references} %{label_text}."
msgstr "" msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
msgid "Reply by email" msgid "Reply by email"
msgstr "" msgstr ""
......
...@@ -98,6 +98,16 @@ describe 'Pipeline', :js do ...@@ -98,6 +98,16 @@ describe 'Pipeline', :js do
end end
end end
it 'shows links to the related merge requests' do
visit_pipeline
within '.related-merge-request-info' do
pipeline.all_merge_requests.map do |merge_request|
expect(page).to have_link(project_merge_request_path(project, merge_request))
end
end
end
it_behaves_like 'showing user status' do it_behaves_like 'showing user status' do
let(:user_with_status) { pipeline.user } let(:user_with_status) { pipeline.user }
......
...@@ -20,7 +20,9 @@ describe GitlabSchema.types['MergeRequest'] do ...@@ -20,7 +20,9 @@ describe GitlabSchema.types['MergeRequest'] do
merge_error allow_collaboration should_be_rebased rebase_commit_sha merge_error allow_collaboration should_be_rebased rebase_commit_sha
rebase_in_progress merge_commit_message default_merge_commit_message rebase_in_progress merge_commit_message default_merge_commit_message
merge_ongoing source_branch_exists mergeable_discussions_state web_url merge_ongoing source_branch_exists mergeable_discussions_state web_url
upvotes downvotes subscribed head_pipeline pipelines task_completion_status upvotes downvotes head_pipeline pipelines task_completion_status
milestone assignees participants subscribed labels discussion_locked time_estimate
total_time_spent reference
] ]
is_expected.to have_graphql_fields(*expected_fields) is_expected.to have_graphql_fields(*expected_fields)
......
...@@ -45,4 +45,22 @@ describe GitlabSchema.types['Project'] do ...@@ -45,4 +45,22 @@ describe GitlabSchema.types['Project'] do
is_expected.to have_graphql_resolver(Resolvers::IssuesResolver) is_expected.to have_graphql_resolver(Resolvers::IssuesResolver)
end end
end end
describe 'merge_requests field' do
subject { described_class.fields['mergeRequest'] }
it 'returns merge requests' do
is_expected.to have_graphql_type(Types::MergeRequestType)
is_expected.to have_graphql_resolver(Resolvers::MergeRequestsResolver.single)
end
end
describe 'merge_request field' do
subject { described_class.fields['mergeRequests'] }
it 'returns merge request' do
is_expected.to have_graphql_type(Types::MergeRequestType.connection_type)
is_expected.to have_graphql_resolver(Resolvers::MergeRequestsResolver)
end
end
end end
...@@ -631,10 +631,40 @@ describe Project do ...@@ -631,10 +631,40 @@ describe Project do
describe "#web_url" do describe "#web_url" do
let(:project) { create(:project, path: "somewhere") } let(:project) { create(:project, path: "somewhere") }
context 'when given the only_path option' do
subject { project.web_url(only_path: only_path) }
context 'when only_path is false' do
let(:only_path) { false }
it 'returns the full web URL for this repo' do
expect(subject).to eq("#{Gitlab.config.gitlab.url}/#{project.namespace.full_path}/somewhere")
end
end
context 'when only_path is true' do
let(:only_path) { true }
it 'returns the relative web URL for this repo' do
expect(subject).to eq("/#{project.namespace.full_path}/somewhere")
end
end
context 'when only_path is nil' do
let(:only_path) { nil }
it 'returns the full web URL for this repo' do
expect(subject).to eq("#{Gitlab.config.gitlab.url}/#{project.namespace.full_path}/somewhere")
end
end
end
context 'when not given the only_path option' do
it 'returns the full web URL for this repo' do it 'returns the full web URL for this repo' do
expect(project.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.namespace.full_path}/somewhere") expect(project.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.namespace.full_path}/somewhere")
end end
end end
end
describe "#readme_url" do describe "#readme_url" do
context 'with a non-existing repository' do context 'with a non-existing repository' do
...@@ -3226,15 +3256,60 @@ describe Project do ...@@ -3226,15 +3256,60 @@ describe Project do
describe '#http_url_to_repo' do describe '#http_url_to_repo' do
let(:project) { create(:project) } let(:project) { create(:project) }
context 'when a custom HTTP clone URL root is not set' do
it 'returns the url to the repo without a username' do it 'returns the url to the repo without a username' do
expect(project.http_url_to_repo).to eq("#{project.web_url}.git") expect(project.http_url_to_repo).to eq("#{project.web_url}.git")
expect(project.http_url_to_repo).not_to include('@') expect(project.http_url_to_repo).not_to include('@')
end end
end end
context 'when a custom HTTP clone URL root is set' do
before do
stub_application_setting(custom_http_clone_url_root: custom_http_clone_url_root)
end
context 'when custom HTTP clone URL root has a relative URL root' do
context 'when custom HTTP clone URL root ends with a slash' do
let(:custom_http_clone_url_root) { 'https://git.example.com:51234/mygitlab/' }
it 'returns the url to the repo, with the root replaced with the custom one' do
expect(project.http_url_to_repo).to eq("https://git.example.com:51234/mygitlab/#{project.full_path}.git")
end
end
context 'when custom HTTP clone URL root does not end with a slash' do
let(:custom_http_clone_url_root) { 'https://git.example.com:51234/mygitlab' }
it 'returns the url to the repo, with the root replaced with the custom one' do
expect(project.http_url_to_repo).to eq("https://git.example.com:51234/mygitlab/#{project.full_path}.git")
end
end
end
context 'when custom HTTP clone URL root does not have a relative URL root' do
context 'when custom HTTP clone URL root ends with a slash' do
let(:custom_http_clone_url_root) { 'https://git.example.com:51234/' }
it 'returns the url to the repo, with the root replaced with the custom one' do
expect(project.http_url_to_repo).to eq("https://git.example.com:51234/#{project.full_path}.git")
end
end
context 'when custom HTTP clone URL root does not end with a slash' do
let(:custom_http_clone_url_root) { 'https://git.example.com:51234' }
it 'returns the url to the repo, with the root replaced with the custom one' do
expect(project.http_url_to_repo).to eq("https://git.example.com:51234/#{project.full_path}.git")
end
end
end
end
end
describe '#lfs_http_url_to_repo' do describe '#lfs_http_url_to_repo' do
let(:project) { create(:project) } let(:project) { create(:project) }
context 'when a custom HTTP clone URL root is not set' do
it 'returns the url to the repo without a username' do it 'returns the url to the repo without a username' do
lfs_http_url_to_repo = project.lfs_http_url_to_repo('operation_that_doesnt_matter') lfs_http_url_to_repo = project.lfs_http_url_to_repo('operation_that_doesnt_matter')
...@@ -3243,6 +3318,19 @@ describe Project do ...@@ -3243,6 +3318,19 @@ describe Project do
end end
end end
context 'when a custom HTTP clone URL root is set' do
before do
stub_application_setting(custom_http_clone_url_root: 'https://git.example.com:51234')
end
it 'returns the url to the repo, with the root replaced with the custom one' do
lfs_http_url_to_repo = project.lfs_http_url_to_repo('operation_that_doesnt_matter')
expect(lfs_http_url_to_repo).to eq("https://git.example.com:51234/#{project.full_path}.git")
end
end
end
describe '#pipeline_status' do describe '#pipeline_status' do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
it 'builds a pipeline status' do it 'builds a pipeline status' do
......
...@@ -47,6 +47,7 @@ describe ProjectWiki do ...@@ -47,6 +47,7 @@ describe ProjectWiki do
describe "#http_url_to_repo" do describe "#http_url_to_repo" do
let(:project) { create :project } let(:project) { create :project }
context 'when a custom HTTP clone URL root is not set' do
it 'returns the full http url to the repo' do it 'returns the full http url to the repo' do
expected_url = "#{Gitlab.config.gitlab.url}/#{subject.full_path}.git" expected_url = "#{Gitlab.config.gitlab.url}/#{subject.full_path}.git"
...@@ -55,6 +56,19 @@ describe ProjectWiki do ...@@ -55,6 +56,19 @@ describe ProjectWiki do
end end
end end
context 'when a custom HTTP clone URL root is set' do
before do
stub_application_setting(custom_http_clone_url_root: 'https://git.example.com:51234')
end
it 'returns the full http url to the repo, with the root replaced with the custom one' do
expected_url = "https://git.example.com:51234/#{subject.full_path}.git"
expect(project_wiki.http_url_to_repo).to eq(expected_url)
end
end
end
describe "#wiki_base_path" do describe "#wiki_base_path" do
it "returns the wiki base path" do it "returns the wiki base path" do
wiki_base_path = "#{Gitlab.config.gitlab.relative_url_root}/#{project.full_path}/wikis" wiki_base_path = "#{Gitlab.config.gitlab.relative_url_root}/#{project.full_path}/wikis"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment