Commit 6593f1f6 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 2f369bd9
......@@ -3,7 +3,8 @@
*.rake @gitlab-org/maintainers/rails-backend
# Technical writing team are the default reviewers for everything in `doc/`
/doc/* @gl-docsteam
*.md @gl-docsteam
doc/ @gl-docsteam
# Frontend maintainers should see everything in `app/assets/`
app/assets/ @gitlab-org/maintainers/frontend
......
......@@ -183,7 +183,7 @@ export class CopyAsGFM {
}
// Export CopyAsGFM as a global for rspec to access
// see /spec/features/copy_as_gfm_spec.rb
// see /spec/features/markdown/copy_as_gfm_spec.rb
if (process.env.NODE_ENV !== 'production') {
window.CopyAsGFM = CopyAsGFM;
}
......
......@@ -53,7 +53,7 @@ import InlineHTML from './marks/inline_html';
// The nodes and marks referenced here transform that same HTML to GFM to be copied to the clipboard.
// Every filter in lib/banzai/pipeline/gfm_pipeline.rb that generates HTML
// from GFM should have a node or mark here.
// The GFM-to-HTML-to-GFM cycle is tested in spec/features/copy_as_gfm_spec.rb.
// The GFM-to-HTML-to-GFM cycle is tested in spec/features/markdown/copy_as_gfm_spec.rb.
export default [
new Doc(),
......
......@@ -12,6 +12,7 @@ function cleanSuggestionLine(line = {}) {
return {
...line,
text: trimFirstCharOfLineContent(line.text),
rich_text: trimFirstCharOfLineContent(line.rich_text),
};
}
......
......@@ -24,7 +24,8 @@ export default {
{{ line.new_line }}
</td>
<td class="line_content" :class="lineType">
<span v-if="line.text">{{ line.text }}</span>
<span v-if="line.rich_text" v-html="line.rich_text"></span>
<span v-else-if="line.text">{{ line.text }}</span>
<!-- TODO: replace this hack with zero-width whitespace when we have rich_text from BE -->
<span v-else>&#8203;</span>
</td>
......
......@@ -4,7 +4,9 @@ class SuggestionEntity < API::Entities::Suggestion
include RequestAwareEntity
unexpose :from_line, :to_line, :from_content, :to_content
expose :diff_lines, using: DiffLineEntity
expose :diff_lines, using: DiffLineEntity do |suggestion|
Gitlab::Diff::Highlight.new(suggestion.diff_lines).highlight
end
expose :current_user do
expose :can_apply do |suggestion|
Ability.allowed?(current_user, :apply_suggestion, suggestion)
......
......@@ -84,7 +84,9 @@ module QuickActions
# rubocop: enable CodeReuse/ActiveRecord
def find_milestones(project, params = {})
MilestonesFinder.new(params.merge(project_ids: [project.id], group_ids: [project.group&.id])).execute
group_ids = project.group.self_and_ancestors.select(:id) if project.group
MilestonesFinder.new(params.merge(project_ids: [project.id], group_ids: group_ids)).execute
end
def parent
......
---
title: Fix milestone quick action to handle ancestor group milestones
merge_request: 22231
author:
type: fixed
---
title: Apply word-diff highlighting to Suggestions
merge_request: 22182
author:
type: changed
---
title: Copy repository route under - scope
merge_request: 22092
author:
type: changed
---
title: Add back feature flag for cache invalidator
merge_request: 22106
author:
type: changed
......@@ -274,8 +274,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
# The wiki routing contains wildcard characters so
# The wiki and repository routing contains wildcard characters so
# its preferable to keep it below all other project routes
draw :repository_scoped
draw :wiki
end
# End of the /-/ scope.
......@@ -481,6 +482,13 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
# its preferable to keep it below all other project routes
draw :repository
# To ensure an old unscoped routing is used for the UI we need to
# add prefix 'as' to the scope routing and place it below original routing.
# Issue https://gitlab.com/gitlab-org/gitlab/issues/118849
scope '-', as: 'scoped' do
draw :repository
end
# All new routes should go under /-/ scope.
# Look for scope '-' at the top of the file.
# rubocop: enable Cop/PutProjectRoutesUnderScope
......
......@@ -39,32 +39,6 @@ scope format: false do
end
end
scope path: '-', constraints: { id: Gitlab::PathRegex.git_reference_regex } do
resources :network, only: [:show]
resources :graphs, only: [:show] do
member do
get :charts
get :commits
get :ci
get :languages
end
end
get '/branches/:state', to: 'branches#index', as: :branches_filtered, constraints: { state: /active|stale|all/ }
resources :branches, only: [:index, :new, :create, :destroy] do
get :diverging_commit_counts, on: :collection
end
delete :merged_branches, controller: 'branches', action: :destroy_all_merged
resources :tags, only: [:index, :show, :new, :create, :destroy] do
resource :release, controller: 'tags/releases', only: [:edit, :update]
end
resources :protected_branches, only: [:index, :show, :create, :update, :destroy, :patch], constraints: { id: Gitlab::PathRegex.git_reference_regex }
resources :protected_tags, only: [:index, :show, :create, :update, :destroy]
end
scope constraints: { id: /[^\0]+/ } do
scope controller: :blob do
get '/new/*id', action: :new, as: :new_blob
......
# frozen_string_literal: true
# All routing related to repository browsing
# that is already under /-/ scope only
# Don't use format parameter as file extension (old 3.0.x behavior)
# See http://guides.rubyonrails.org/routing.html#route-globbing-and-wildcard-segments
scope format: false do
scope constraints: { id: Gitlab::PathRegex.git_reference_regex } do
resources :network, only: [:show]
resources :graphs, only: [:show] do
member do
get :charts
get :commits
get :ci
get :languages
end
end
get '/branches/:state', to: 'branches#index', as: :branches_filtered, constraints: { state: /active|stale|all/ }
resources :branches, only: [:index, :new, :create, :destroy] do
get :diverging_commit_counts, on: :collection
end
delete :merged_branches, controller: 'branches', action: :destroy_all_merged
resources :tags, only: [:index, :show, :new, :create, :destroy] do
resource :release, controller: 'tags/releases', only: [:edit, :update]
end
resources :protected_branches, only: [:index, :show, :create, :update, :destroy, :patch], constraints: { id: Gitlab::PathRegex.git_reference_regex }
resources :protected_tags, only: [:index, :show, :create, :update, :destroy]
end
end
......@@ -10,7 +10,7 @@ to perform various actions.
All statistics are opt-out, you can enable/disable them from the admin panel
under **Admin area > Settings > Metrics and profiling > Usage statistics**.
## Version check **(CORE ONLY)**
## Version Check **(CORE ONLY)**
If enabled, version check will inform you if a new version is available and the
importance of it through a status. This is shown on the help page (i.e. `/help`)
......@@ -33,7 +33,23 @@ secure.
If you disable version check, this information will not be collected. Enable or
disable the version check at **Admin area > Settings > Metrics and profiling > Usage statistics**.
## Usage ping **(CORE ONLY)**
### Request flow example
The following example shows a basic request/response flow between the self-managed GitLab instance
and the GitLab Version Application:
```mermaid
sequenceDiagram
participant GitLab instance
participant Version Application
GitLab instance->>Version Application: Is there a version update?
loop Version Check
Version Application->>Version Application: Record version info
end
Version Application->>GitLab instance: Response (PNG/SVG)
```
## Usage Ping **(CORE ONLY)**
> [Introduced][ee-557] in GitLab Enterprise Edition 8.10. More statistics
[were added][ee-735] in GitLab Enterprise Edition
......@@ -52,7 +68,32 @@ You can view the exact JSON payload in the administration panel. To view the pay
1. Expand **Settings** in the left sidebar and click on **Metrics and profiling**.
1. Expand **Usage statistics** and click on the **Preview payload** button.
You can see how [the usage ping data maps to different stages of the product](https://gitlab.com/gitlab-data/analytics/blob/master/transform/snowflake-dbt/data/ping_metrics_to_stage_mapping_data.csv).
You can see how [the usage ping data maps to different stages of the product](https://gitlab.com/gitlab-data/analytics/blob/master/transform/snowflake-dbt/data/version_usage_stats_to_stage_mappings.csv).
### Request flow example
The following example shows a basic request/response flow between the self-managed GitLab instance, GitLab Version Application,
GitLab License Application and Salesforce:
```mermaid
sequenceDiagram
participant GitLab instance
participant Version Application
participant License Application
participant Salesforce
GitLab instance->>Version Application: Usage Ping data
loop Process Usage Data
Version Application->>Version Application: Parse Usage Data
Version Application->>Version Application: Record Usage Data
Version Application->>Version Application: Update license ping time
end
Version Application-xLicense Application: Request Zuora subscription id
License Application-xVersion Application: Zuora subscription id
Version Application-xSalesforce: Request Zuora account id by Zuora subscription id
Salesforce-xVersion Application: Zuora account id
Version Application-xSalesforce: Usage data for the Zuora account
Version Application->>GitLab instance: Conversational Development Index
```
### Deactivate the usage ping
......
......@@ -7,6 +7,7 @@ class Feature
# Server feature flags should use '_' to separate words.
SERVER_FEATURE_FLAGS =
%w[
cache_invalidator
inforef_uploadpack_cache
get_tag_messages_go
filter_shas_with_signatures_go
......
......@@ -7,8 +7,8 @@ const oldLine = {
meta_data: null,
new_line: null,
old_line: 5,
rich_text: '-oldtext',
text: '-oldtext',
rich_text: 'oldrichtext',
text: 'oldplaintext',
type: 'old',
};
......@@ -18,8 +18,8 @@ const newLine = {
meta_data: null,
new_line: 6,
old_line: null,
rich_text: '-newtext',
text: '-newtext',
rich_text: 'newrichtext',
text: 'newplaintext',
type: 'new',
};
......@@ -42,14 +42,46 @@ describe('SuggestionDiffRow', () => {
wrapper.destroy();
});
it('renders correctly', () => {
factory({
propsData: {
line: oldLine,
},
describe('renders correctly', () => {
it('has the right classes on the wrapper', () => {
factory({
propsData: {
line: oldLine,
},
});
expect(wrapper.is('.line_holder')).toBe(true);
});
it('renders the rich text when it is available', () => {
factory({
propsData: {
line: newLine,
},
});
expect(wrapper.find('td.line_content').text()).toEqual('newrichtext');
});
expect(wrapper.is('.line_holder')).toBe(true);
it('renders the plain text when it is available but rich text is not', () => {
factory({
propsData: {
line: Object.assign({}, newLine, { rich_text: undefined }),
},
});
expect(wrapper.find('td.line_content').text()).toEqual('newplaintext');
});
it('renders a zero-width space when it has no plain or rich texts', () => {
factory({
propsData: {
line: Object.assign({}, newLine, { rich_text: undefined, text: undefined }),
},
});
expect(wrapper.find('td.line_content').text()).toEqual('\u200B');
});
});
describe('when passed line has type old', () => {
......
......@@ -4,17 +4,19 @@ require 'spec_helper'
describe SafeUrl do
describe '#safe_url' do
class SafeUrlTestClass
include SafeUrl
let(:safe_url_test_class) do
Class.new do
include SafeUrl
attr_reader :url
attr_reader :url
def initialize(url)
@url = url
def initialize(url)
@url = url
end
end
end
let(:test_class) { SafeUrlTestClass.new(url) }
let(:test_class) { safe_url_test_class.new(url) }
let(:url) { 'http://example.com' }
subject { test_class.safe_url }
......
......@@ -326,7 +326,7 @@ describe API::Internal::Base do
expect(json_response["gitaly"]["repository"]["relative_path"]).to eq(project.repository.gitaly_repository.relative_path)
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-get-tag-messages-go' => 'true', 'gitaly-feature-filter-shas-with-signatures-go' => 'true')
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-get-tag-messages-go' => 'true', 'gitaly-feature-filter-shas-with-signatures-go' => 'true', 'gitaly-feature-cache-invalidator' => 'true')
expect(user.reload.last_activity_on).to eql(Date.today)
end
end
......@@ -346,7 +346,7 @@ describe API::Internal::Base do
expect(json_response["gitaly"]["repository"]["relative_path"]).to eq(project.repository.gitaly_repository.relative_path)
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-get-tag-messages-go' => 'true', 'gitaly-feature-filter-shas-with-signatures-go' => 'true')
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-get-tag-messages-go' => 'true', 'gitaly-feature-filter-shas-with-signatures-go' => 'true', 'gitaly-feature-cache-invalidator' => 'true')
expect(user.reload.last_activity_on).to be_nil
end
end
......@@ -588,7 +588,7 @@ describe API::Internal::Base do
expect(json_response["gitaly"]["repository"]["relative_path"]).to eq(project.repository.gitaly_repository.relative_path)
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-get-tag-messages-go' => 'true', 'gitaly-feature-filter-shas-with-signatures-go' => 'true')
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-get-tag-messages-go' => 'true', 'gitaly-feature-filter-shas-with-signatures-go' => 'true', 'gitaly-feature-cache-invalidator' => 'true')
end
end
......
......@@ -579,6 +579,10 @@ describe 'project routing' do
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "blob/master/blob/#{newline_file}" })
end
it 'to #show from scope routing' do
expect(get('/gitlab/gitlabhq/-/blob/master/app/models/project.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
end
end
# project_tree GET /:project_id/tree/:id(.:format) tree#show {id: /[^\0]+/, project_id: /[^\/]+/}
......@@ -596,6 +600,10 @@ describe 'project routing' do
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "master/#{newline_file}" })
end
it 'to #show from scope routing' do
expect(get('/gitlab/gitlabhq/-/tree/master/app/models/project.rb')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
end
end
# project_find_file GET /:namespace_id/:project_id/find_file/*id(.:format) projects/find_file#show {:id=>/[^\0]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/html/}
......
......@@ -856,9 +856,10 @@ describe QuickActions::InterpretService do
end
context 'only group milestones available' do
let(:group) { create(:group) }
let(:ancestor_group) { create(:group) }
let(:group) { create(:group, parent: ancestor_group) }
let(:project) { create(:project, :public, namespace: group) }
let(:milestone) { create(:milestone, group: group, title: '10.0') }
let(:milestone) { create(:milestone, group: ancestor_group, title: '10.0') }
it_behaves_like 'milestone command' do
let(:content) { "/milestone %#{milestone.title}" }
......
......@@ -3,18 +3,19 @@
require 'spec_helper'
describe QualifiedDomainArrayValidator do
class QualifiedDomainArrayValidatorTestClass
include ActiveModel::Validations
let(:qualified_domain_array_validator_test_class) do
Class.new do
include ActiveModel::Validations
attr_accessor :domain_array
attr_accessor :domain_array
def initialize(domain_array)
self.domain_array = domain_array
def initialize(domain_array)
self.domain_array = domain_array
end
end
end
let!(:record) do
QualifiedDomainArrayValidatorTestClass.new(['gitlab.com'])
qualified_domain_array_validator_test_class.new(['gitlab.com'])
end
subject { validator.validate(record) }
......
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