Skip to content
Snippets Groups Projects
Commit f444f745 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@12-6-stable-ee

parent 58fa510a
No related branches found
No related tags found
No related merge requests found
Showing
with 190 additions and 24 deletions
Loading
Loading
@@ -12,6 +12,14 @@ module Clusters
cluster.kubeclient&.get_namespace(Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE)
rescue Kubeclient::ResourceNotFoundError
nil
rescue Kubeclient::HttpError => e
# If the kubernetes auth engine is enabled, it will return 403
if e.error_code == 403
Gitlab::ErrorTracking.track_exception(e)
nil
else
raise
end
end
end
end
Loading
Loading
@@ -32,6 +32,7 @@ module Ci
 
has_many :stages, -> { order(position: :asc) }, inverse_of: :pipeline
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
has_many :latest_statuses_ordered_by_stage, -> { latest.order(:stage_idx, :stage) }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
has_many :processables, -> { processables },
class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
has_many :builds, foreign_key: :commit_id, inverse_of: :pipeline
Loading
Loading
@@ -45,6 +46,7 @@ module Ci
has_many :merge_requests_as_head_pipeline, foreign_key: "head_pipeline_id", class_name: 'MergeRequest'
 
has_many :pending_builds, -> { pending }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :failed_builds, -> { latest.failed }, foreign_key: :commit_id, class_name: 'Ci::Build', inverse_of: :pipeline
has_many :retryable_builds, -> { latest.failed_or_canceled.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :cancelable_statuses, -> { cancelable }, foreign_key: :commit_id, class_name: 'CommitStatus'
has_many :manual_actions, -> { latest.manual_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
Loading
Loading
@@ -377,9 +379,7 @@ module Ci
end
 
def legacy_stages_using_composite_status
stages = statuses.latest
.order(:stage_idx, :stage)
.group_by(&:stage)
stages = latest_statuses_ordered_by_stage.group_by(&:stage)
 
stages.map do |stage_name, jobs|
composite_status = Gitlab::Ci::Status::Composite
Loading
Loading
Loading
Loading
@@ -78,7 +78,7 @@ class PipelineEntity < Grape::Entity
end
 
expose :failed_builds, if: -> (*) { can_retry? }, using: JobEntity do |pipeline|
pipeline.builds.failed
pipeline.failed_builds
end
 
private
Loading
Loading
Loading
Loading
@@ -40,7 +40,11 @@ class PipelineSerializer < BaseSerializer
 
def preloaded_relations
[
:latest_statuses_ordered_by_stage,
:stages,
{
failed_builds: %i(project metadata)
},
:retryable_builds,
:cancelable_statuses,
:trigger_requests,
Loading
Loading
@@ -48,6 +52,7 @@ class PipelineSerializer < BaseSerializer
:scheduled_actions,
:artifacts,
:merge_request,
:user,
{
pending_builds: :project,
project: [:route, { namespace: :route }],
Loading
Loading
---
title: Fix stack trace highlight for PHP
merge_request: 22258
author:
type: fixed
---
title: Handle forbidden error when checking for knative
merge_request: 22170
author:
type: fixed
---
title: Eliminate N+1 queries in PipelinesController#index
merge_request: 22189
author:
type: performance
Loading
Loading
@@ -57,7 +57,7 @@ Parameters:
Creates a two-way relation between two issues. User must be allowed to update both issues in order to succeed.
 
```
POST /projects/:id/issues/:issue_iid/links/:target_project_id/:target_issue_iid
POST /projects/:id/issues/:issue_iid/links
```
 
| Attribute | Type | Required | Description |
Loading
Loading
@@ -67,6 +67,12 @@ POST /projects/:id/issues/:issue_iid/links/:target_project_id/:target_issue_iid
| `target_project_id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) of a target project |
| `target_issue_iid` | integer/string | yes | The internal ID of a target project's issue |
 
```bash
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues/1/links?target_project_id=5&target_issue_iid=1"
```
Example response:
```json
{
"source_issue" : {
Loading
Loading
Loading
Loading
@@ -116,6 +116,35 @@ rendered to HTML when viewed.
Interactive features, including JavaScript plots, will not work when viewed in
GitLab.
 
### OpenAPI viewer
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/19515) in GitLab 12.6.
GitLab can render OpenAPI specification files with its file viewer, provided
their filenames include `openapi` or `swagger` and their extension is `yaml`,
`yml`, or `json`. The following examples are all correct:
- `openapi.yml`
- `openapi.yaml`
- `openapi.json`
- `swagger.yml`
- `swagger.yaml`
- `swagger.json`
- `gitlab_swagger.yml`
- `openapi_gitlab.yml`
- `OpenAPI.YML`
- `openapi.Yaml`
- `openapi.JSON`
- `openapi.gitlab.yml`
- `gitlab.openapi.yml`
Then, to render them:
1. Navigate to the OpenAPI file in your repository in GitLab's UI.
1. Click the "Display OpenAPI" button which is located between the "Display source"
and "Edit" buttons (when an OpenAPI file is found, it replaces the
"Display rendered file" button).
## Branches
 
For details, see [Branches](branches/index.md).
Loading
Loading
Loading
Loading
@@ -28,7 +28,7 @@ module Gitlab
end
 
def highlight_entry_context(filename, context)
language = Rouge::Lexer.guess_by_filename(filename).tag
language = guess_language_by_filename(filename)
 
context.map do |line_number, line_of_code|
[
Loading
Loading
@@ -38,6 +38,12 @@ module Gitlab
]
end
end
def guess_language_by_filename(filename)
Rouge::Lexer.guess_by_filename(filename).tag
rescue Rouge::Guesser::Ambiguous => e
e.alternatives.min_by(&:tag)&.tag
end
end
end
end
Loading
Loading
@@ -6,7 +6,7 @@ describe Projects::PipelinesController do
include ApiHelpers
 
let_it_be(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let_it_be(:project) { create(:project, :public, :repository) }
let(:feature) { ProjectFeature::ENABLED }
 
before do
Loading
Loading
@@ -19,12 +19,12 @@ describe Projects::PipelinesController do
 
describe 'GET index.json' do
before do
%w(pending running success failed canceled).each_with_index do |status, index|
create_pipeline(status, project.commit("HEAD~#{index}"))
end
create_all_pipeline_types
end
 
context 'when using persisted stages', :request_store do
render_views
before do
stub_feature_flags(ci_pipeline_persisted_stages: true)
end
Loading
Loading
@@ -32,9 +32,7 @@ describe Projects::PipelinesController do
it 'returns serialized pipelines', :request_store do
expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original
 
queries = ActiveRecord::QueryRecorder.new do
get_pipelines_index_json
end
get_pipelines_index_json
 
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('pipeline')
Loading
Loading
@@ -49,8 +47,22 @@ describe Projects::PipelinesController do
json_response.dig('pipelines', 0, 'details', 'stages').tap do |stages|
expect(stages.count).to eq 3
end
end
it 'does not execute N+1 queries' do
get_pipelines_index_json
control_count = ActiveRecord::QueryRecorder.new do
get_pipelines_index_json
end.count
 
expect(queries.count).to be
create_all_pipeline_types
# There appears to be one extra query for Pipelines#has_warnings? for some reason
expect { get_pipelines_index_json }.not_to exceed_query_limit(control_count + 1)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['pipelines'].count).to eq 10
end
end
 
Loading
Loading
@@ -133,19 +145,27 @@ describe Projects::PipelinesController do
format: :json
end
 
def create_all_pipeline_types
%w(pending running success failed canceled).each_with_index do |status, index|
create_pipeline(status, project.commit("HEAD~#{index}"))
end
end
def create_pipeline(status, sha)
user = create(:user)
pipeline = create(:ci_empty_pipeline, status: status,
project: project,
sha: sha)
sha: sha,
user: user)
 
create_build(pipeline, 'build', 1, 'build')
create_build(pipeline, 'test', 2, 'test')
create_build(pipeline, 'deploy', 3, 'deploy')
create_build(pipeline, 'build', 1, 'build', user)
create_build(pipeline, 'test', 2, 'test', user)
create_build(pipeline, 'deploy', 3, 'deploy', user)
end
 
def create_build(pipeline, stage, stage_idx, name)
def create_build(pipeline, stage, stage_idx, name, user = nil)
status = %w[created running pending success failed canceled].sample
create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name, status: status)
create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name, status: status, user: user)
end
end
 
Loading
Loading
Loading
Loading
@@ -35,6 +35,16 @@ FactoryBot.define do
[8, "}\n"]
]
},
{
'function' => 'print',
'lineNo' => 3,
'filename' => 'hello_world.php',
'context' => [
[1, "// PHP/Hack example\n"],
[2, "<?php\n"],
[3, "echo 'Hello, World!';\n"]
]
},
{
'filename' => 'blank.txt'
}
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe Clusters::KnativeServingNamespaceFinder do
include KubernetesHelpers
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:service) { environment.deployment_platform }
let(:project) { cluster.cluster_project.project }
let(:environment) { create(:environment, project: project) }
subject { described_class.new(cluster) }
before do
stub_kubeclient_discover(service.api_url)
end
it 'finds the namespace in a cluster where it exists' do
stub_kubeclient_get_namespace(service.api_url, namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE)
expect(subject.execute).to be_a Kubeclient::Resource
end
it 'returns nil in a cluster where it does not' do
stub_kubeclient_get_namespace(
service.api_url,
namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE,
response: {
status: [404, "Resource Not Found"]
}
)
expect(subject.execute).to be nil
end
it 'returns nil in a cluster where the lookup results in a 403 as it will in some versions of kubernetes' do
stub_kubeclient_get_namespace(
service.api_url,
namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE,
response: {
status: [403, "Resource Not Found"]
}
)
expect(subject.execute).to be nil
end
it 'raises an error if error code is not 404 or 403' do
stub_kubeclient_get_namespace(
service.api_url,
namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE,
response: {
status: [500, "Internal Server Error"]
}
)
expect { subject.execute }.to raise_error(Kubeclient::HttpError)
end
end
Loading
Loading
@@ -48,6 +48,16 @@ describe Gitlab::ErrorTracking::StackTraceHighlightDecorator do
[8, '<span id="LC1" class="line" lang="swift"><span class="p">}</span></span>']
]
},
{
'function' => 'print',
'lineNo' => 3,
'filename' => 'hello_world.php',
'context' => [
[1, '<span id="LC1" class="line" lang="hack"><span class="c1">// PHP/Hack example</span></span>'],
[2, '<span id="LC1" class="line" lang="hack"><span class="cp">&lt;?php</span></span>'],
[3, '<span id="LC1" class="line" lang="hack"><span class="k">echo</span> <span class="s1">\'Hello, World!\'</span><span class="p">;</span></span>']
]
},
{
'filename' => 'blank.txt'
}
Loading
Loading
Loading
Loading
@@ -160,6 +160,7 @@ ci_pipelines:
- user
- stages
- statuses
- latest_statuses_ordered_by_stage
- builds
- processables
- trigger_requests
Loading
Loading
@@ -168,6 +169,7 @@ ci_pipelines:
- auto_canceled_pipelines
- auto_canceled_jobs
- pending_builds
- failed_builds
- retryable_builds
- cancelable_statuses
- manual_actions
Loading
Loading
Loading
Loading
@@ -159,7 +159,7 @@ describe PipelineSerializer do
 
it 'verifies number of queries', :request_store do
recorded = ActiveRecord::QueryRecorder.new { subject }
expected_queries = Gitlab.ee? ? 38 : 35
expected_queries = Gitlab.ee? ? 42 : 39
 
expect(recorded.count).to be_within(2).of(expected_queries)
expect(recorded.cached_count).to eq(0)
Loading
Loading
@@ -180,7 +180,7 @@ describe PipelineSerializer do
# pipeline. With the same ref this check is cached but if refs are
# different then there is an extra query per ref
# https://gitlab.com/gitlab-org/gitlab-foss/issues/46368
expected_queries = Gitlab.ee? ? 41 : 38
expected_queries = Gitlab.ee? ? 45 : 42
 
expect(recorded.count).to be_within(2).of(expected_queries)
expect(recorded.cached_count).to eq(0)
Loading
Loading
Loading
Loading
@@ -229,9 +229,9 @@ module KubernetesHelpers
.to_return(kube_response(kube_v1_namespace_list_body))
end
 
def stub_kubeclient_get_namespace(api_url, namespace: 'default')
def stub_kubeclient_get_namespace(api_url, namespace: 'default', response: kube_response({}))
WebMock.stub_request(:get, api_url + "/api/v1/namespaces/#{namespace}")
.to_return(kube_response({}))
.to_return(response)
end
 
def stub_kubeclient_put_cluster_role(api_url, name)
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment