提交 80ddaef3 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 da100a69
......@@ -8,6 +8,7 @@ import {
GlButton,
GlSprintf,
GlAlert,
GlTooltipDirective,
} from '@gitlab/ui';
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import { timeRanges } from '~/vue_shared/constants';
......@@ -34,6 +35,9 @@ export default {
DashboardPanel,
DateTimePicker,
},
directives: {
GlTooltip: GlTooltipDirective,
},
data() {
return {
yml: initialYml,
......@@ -67,6 +71,13 @@ export default {
this.fetchPanelPreviewMetrics();
}
},
onRefresh() {
// refetch data only if preview has been clicked
// and there are no errors
if (this.panelPreviewIsShown && !this.panelPreviewError) {
this.fetchPanelPreviewMetrics();
}
},
},
timeRanges,
};
......@@ -171,11 +182,18 @@ export default {
</gl-alert>
<date-time-picker
ref="dateTimePicker"
class="gl-flex-grow-1 preview-date-time-picker"
class="gl-flex-grow-1 preview-date-time-picker gl-xs-mb-3"
:value="panelPreviewTimeRange"
:options="$options.timeRanges"
@input="onDateTimePickerInput"
/>
<gl-button
v-gl-tooltip
data-testid="previewRefreshButton"
icon="retry"
:title="s__('Metrics|Refresh Prometheus data')"
@click="onRefresh"
/>
<dashboard-panel :graph-data="panelPreviewGraphData" />
</div>
</template>
<script>
import { GlDeprecatedButton } from '@gitlab/ui';
import { GlButton } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import { __, sprintf } from '~/locale';
......@@ -7,7 +7,7 @@ import notesEventHub from '../event_hub';
export default {
components: {
GlDeprecatedButton,
GlButton,
Icon,
},
computed: {
......@@ -40,12 +40,12 @@ export default {
<div class="timeline-content">
<div ref="timelineContent" v-html="timelineContent"></div>
<div class="discussion-filter-actions mt-2">
<gl-deprecated-button ref="showAllActivity" variant="default" @click="selectFilter(0)">
<gl-button ref="showAllActivity" variant="default" @click="selectFilter(0)">
{{ __('Show all activity') }}
</gl-deprecated-button>
<gl-deprecated-button ref="showComments" variant="default" @click="selectFilter(1)">
</gl-button>
<gl-button ref="showComments" variant="default" @click="selectFilter(1)">
{{ __('Show comments only') }}
</gl-deprecated-button>
</gl-button>
</div>
</div>
</li>
......
......@@ -192,12 +192,6 @@ class Projects::PipelinesController < Projects::ApplicationController
end
end
def test_reports_count
return unless Feature.enabled?(:junit_pipeline_view, project)
render json: { total_count: pipeline.test_reports_count }.to_json
end
private
def serialize_pipelines
......
......@@ -8,6 +8,7 @@ module Ci
include UsageStatistics
include Sortable
include IgnorableColumns
include Artifactable
extend Gitlab::Ci::Model
NotSupportedAdapterError = Class.new(StandardError)
......@@ -200,12 +201,6 @@ module Ci
load_performance: 25 ## EE-specific
}
enum file_format: {
raw: 1,
zip: 2,
gzip: 3
}, _suffix: true
# `file_location` indicates where actual files are stored.
# Ideally, actual files should be stored in the same directory, and use the same
# convention to generate its path. However, sometimes we can't do so due to backward-compatibility.
......@@ -220,11 +215,6 @@ module Ci
hashed_path: 2
}
FILE_FORMAT_ADAPTERS = {
gzip: Gitlab::Ci::Build::Artifacts::Adapters::GzipStream,
raw: Gitlab::Ci::Build::Artifacts::Adapters::RawStream
}.freeze
def validate_supported_file_format!
return if Feature.disabled?(:drop_license_management_artifact, project, default_enabled: true)
......
......@@ -915,12 +915,6 @@ module Ci
end
end
def test_reports_count
Rails.cache.fetch(['project', project.id, 'pipeline', id, 'test_reports_count'], force: false) do
test_reports.total_count
end
end
def accessibility_reports
Gitlab::Ci::Reports::AccessibilityReports.new.tap do |accessibility_reports|
builds.latest.with_reports(Ci::JobArtifact.accessibility_reports).each do |build|
......
......@@ -5,6 +5,7 @@
module Ci
class PipelineArtifact < ApplicationRecord
extend Gitlab::Ci::Model
include Artifactable
FILE_STORE_SUPPORTED = [
ObjectStorage::Store::LOCAL,
......@@ -24,11 +25,5 @@ module Ci
enum file_type: {
code_coverage: 1
}
enum file_format: {
raw: 1,
zip: 2,
gzip: 3
}, _suffix: true
end
end
# frozen_string_literal: true
module Ci
module Artifactable
extend ActiveSupport::Concern
FILE_FORMAT_ADAPTERS = {
gzip: Gitlab::Ci::Build::Artifacts::Adapters::GzipStream,
raw: Gitlab::Ci::Build::Artifacts::Adapters::RawStream
}.freeze
included do
enum file_format: {
raw: 1,
zip: 2,
gzip: 3
}, _suffix: true
end
end
end
......@@ -7,4 +7,6 @@ class JiraTrackerData < ApplicationRecord
attr_encrypted :api_url, encryption_options
attr_encrypted :username, encryption_options
attr_encrypted :password, encryption_options
enum deployment_type: { unknown: 0, server: 1, cloud: 2 }, _prefix: :deployment
end
---
title: Add migration for deployment_type of Jira server in jira_tracker_data table
merge_request: 36992
author:
type: added
---
title: Optimize counts.terraform_reports usage ping counter
merge_request: 37498
author:
type: performance
---
title: Fix gitlab-rake gitlab:license:info crashing when no license exists
merge_request: 39143
author:
type: fixed
......@@ -19,7 +19,6 @@ resources :pipelines, only: [:index, :new, :create, :show, :destroy] do
get :failures
get :status
get :test_report
get :test_reports_count
end
resources :stages, only: [], param: :name, controller: 'pipelines/stages' do
......
# frozen_string_literal: true
class AddDeploymentTypeToTracker < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
add_column :jira_tracker_data, :deployment_type, :smallint, default: 0, null: false
end
end
# frozen_string_literal: true
class AddIndexToCiJobArtifactsForTerraformReportsId < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_ci_job_artifacts_id_for_terraform_reports'
disable_ddl_transaction!
def up
add_concurrent_index :ci_job_artifacts, :id, where: 'file_type = 18', name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
end
end
8db7f9239f6a817f8ad1a4dea388e1a797009cd21e1729817005b0de36c4300f
\ No newline at end of file
d4ea24092289f6dba294c502b8ce89748165973fb2d7989fa7615433599a0c0c
\ No newline at end of file
......@@ -12700,6 +12700,7 @@ CREATE TABLE public.jira_tracker_data (
jira_issue_transition_id character varying,
project_key text,
issues_enabled boolean DEFAULT false NOT NULL,
deployment_type smallint DEFAULT 0 NOT NULL,
CONSTRAINT check_214cf6a48b CHECK ((char_length(project_key) <= 255))
);
......@@ -19203,6 +19204,8 @@ CREATE UNIQUE INDEX index_ci_instance_variables_on_key ON public.ci_instance_var
CREATE INDEX index_ci_job_artifacts_for_terraform_reports ON public.ci_job_artifacts USING btree (project_id, id) WHERE (file_type = 18);
CREATE INDEX index_ci_job_artifacts_id_for_terraform_reports ON public.ci_job_artifacts USING btree (id) WHERE (file_type = 18);
CREATE INDEX index_ci_job_artifacts_on_expire_at_and_job_id ON public.ci_job_artifacts USING btree (expire_at, job_id);
CREATE INDEX index_ci_job_artifacts_on_file_store ON public.ci_job_artifacts USING btree (file_store);
......
......@@ -331,6 +331,9 @@ The different supported drivers are:
| swift | OpenStack Swift Object Storage |
| oss | Aliyun OSS |
NOTE: **Note:**
Although most S3 compatible services (like [MinIO](https://min.io/)) should work with the registry, we only guarantee support for AWS S3. Because we cannot assert the correctness of third-party S3 implementations, we can debug issues, but we cannot patch the registry unless an issue is reproducible against an AWS S3 bucket.
Read more about the individual driver's configuration options in the
[Docker Registry docs](https://docs.docker.com/registry/configuration/#storage).
......
......@@ -2746,6 +2746,11 @@ type DastScannerProfileEdge {
Represents a DAST Site Profile.
"""
type DastSiteProfile {
"""
Relative web path to the edit page of a site profile
"""
editPath: String
"""
ID of the site profile
"""
......
......@@ -7395,6 +7395,20 @@
"name": "DastSiteProfile",
"description": "Represents a DAST Site Profile.",
"fields": [
{
"name": "editPath",
"description": "Relative web path to the edit page of a site profile",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "id",
"description": "ID of the site profile",
......@@ -453,6 +453,7 @@ Represents a DAST Site Profile.
| Name | Type | Description |
| --- | ---- | ---------- |
| `editPath` | String | Relative web path to the edit page of a site profile |
| `id` | DastSiteProfileID! | ID of the site profile |
| `profileName` | String | The name of the site profile |
| `targetUrl` | String | The URL of the target to be scanned |
......
......@@ -166,7 +166,7 @@ Read the [documentation on Pipelines for Merged Results](pipelines_for_merged_re
Read the [documentation on Merge Trains](pipelines_for_merged_results/merge_trains/index.md).
## Create pipelines in the parent project for merge requests from a forked project
## Run pipelines in the parent project for merge requests from a forked project **(STARTER)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217451) in GitLab 13.3.
......
此差异已折叠。
......@@ -27,6 +27,10 @@ Into a single commit on merge:
![A squashed commit followed by a merge commit](img/squash_squashed_commit.png)
NOTE: **Note:**
The squashed commit in this example is followed by a merge commit, because the merge method for this repository uses a merge commit. You can disable merge commits in
**Project Settings > General > Merge requests > Merge method > Fast-forward merge**.
The squashed commit's commit message will be either:
- Taken from the first multi-line commit message in the merge.
......@@ -39,9 +43,6 @@ It can be customized before merging a merge request.
![A squash commit message editor](img/squash_mr_message.png)
NOTE: **Note:**
The squashed commit in this example is followed by a merge commit, as the merge method for this example repository uses a merge commit.
Squashing also works with the fast-forward merge strategy, see [squashing and fast-forward merge](#squash-and-fast-forward-merge) for more details.
## Use cases
......
......@@ -15346,6 +15346,9 @@ msgstr ""
msgid "Metrics|Prometheus Query Documentation"
msgstr ""
msgid "Metrics|Refresh Prometheus data"
msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
......
# frozen_string_literal: true
require 'rspec/core/formatters'
module QA
module Support
class JsonFormatter < RSpec::Core::Formatters::JsonFormatter
RSpec::Core::Formatters.register self, :message, :dump_summary, :stop, :seed, :close
def dump_profile(profile)
# We don't currently use the profile info. This overrides the base
# implementation so that it's not included.
end
def stop(notification)
# Based on https://github.com/rspec/rspec-core/blob/main/lib/rspec/core/formatters/json_formatter.rb#L35
# But modified to include full details of multiple exceptions
@output_hash[:examples] = notification.examples.map do |example|
format_example(example).tap do |hash|
e = example.exception
if e
exceptions = e.respond_to?(:all_exceptions) ? e.all_exceptions : [e]
hash[:exceptions] = exceptions.map do |exception|
{
class: exception.class.name,
message: exception.message,
backtrace: exception.backtrace
}
end
end
end
end
end
private
def format_example(example)
{
id: example.id,
description: example.description,
full_description: example.full_description,
status: example.execution_result.status.to_s,
file_path: example.metadata[:file_path],
line_number: example.metadata[:line_number],
run_time: example.execution_result.run_time,
pending_message: example.execution_result.pending_message,
status_issue: example.metadata[:status_issue],
quarantine: example.metadata[:quarantine],
screenshot: example.metadata[:screenshot]
}
end
end
end
end
......@@ -989,76 +989,6 @@ RSpec.describe Projects::PipelinesController do
end
end
describe 'GET test_report_count.json' do
subject(:test_reports_count_json) do
get :test_reports_count, params: {
namespace_id: project.namespace,
project_id: project,
id: pipeline.id
},
format: :json
end
context 'when feature is enabled' do
before do
stub_feature_flags(junit_pipeline_view: true)
end
context 'when pipeline does not have a test report' do
let(:pipeline) { create(:ci_pipeline, project: project) }
it 'renders an empty badge counter' do
test_reports_count_json
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['total_count']).to eq(0)
end
end
context 'when pipeline has a test report' do
let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project) }
it 'renders the badge counter value' do
test_reports_count_json
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['total_count']).to eq(4)
end
end
context 'when pipeline has corrupt test reports' do
let(:pipeline) { create(:ci_pipeline, project: project) }
before do
job = create(:ci_build, pipeline: pipeline)
create(:ci_job_artifact, :junit_with_corrupted_data, job: job, project: project)
end
it 'renders 0' do
test_reports_count_json
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['total_count']).to eq(0)
end
end
end
context 'when feature is disabled' do
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
before do
stub_feature_flags(junit_pipeline_view: false)
end
it 'renders empty response' do
test_reports_count_json
expect(response).to have_gitlab_http_status(:no_content)
expect(response.body).to be_empty
end
end
end
describe 'GET latest' do
let(:branch_main) { project.repository.branches[0] }
let(:branch_secondary) { project.repository.branches[1] }
......
......@@ -40,6 +40,7 @@ describe('dashboard invalid url parameters', () => {
const findOpenRepositoryBtn = () => wrapper.find({ ref: 'openRepositoryBtn' });
const findPanel = () => wrapper.find(DashboardPanel);
const findTimeRangePicker = () => wrapper.find(DateTimePicker);
const findRefreshButton = () => wrapper.find('[data-testid="previewRefreshButton"]');
beforeEach(() => {
mockShowToast = jest.fn();
......@@ -138,6 +139,35 @@ describe('dashboard invalid url parameters', () => {
});
});
describe('refresh', () => {
it('is visible by default', () => {
expect(findRefreshButton().exists()).toBe(true);
});
it('when clicked does not trigger data fetch unless preview panel button is clicked', () => {
// mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, false);
return wrapper.vm.$nextTick(() => {
expect(store.dispatch).not.toHaveBeenCalled();
});
});
it('when clicked triggers data fetch if preview panel button is clicked', () => {
// mimic state where preview is visible. SET_PANEL_PREVIEW_IS_SHOWN is set to true
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, true);
findRefreshButton().vm.$emit('click');
return wrapper.vm.$nextTick(() => {
expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/fetchPanelPreviewMetrics',
undefined,
);
});
});
});
describe('instructions card', () => {
const mockDocsPath = '/docs-path';
const mockProjectPath = '/project-path';
......
......@@ -3118,40 +3118,6 @@ RSpec.describe Ci::Pipeline, :mailer do
end
end
describe '#test_reports_count', :use_clean_rails_memory_store_caching do
subject { pipeline.test_reports }
context 'when pipeline has multiple builds with test reports' do
let!(:build_rspec) { create(:ci_build, :success, name: 'rspec', pipeline: pipeline, project: project) }
let!(:build_java) { create(:ci_build, :success, name: 'java', pipeline: pipeline, project: project) }
before do
create(:ci_job_artifact, :junit, job: build_rspec, project: project)
create(:ci_job_artifact, :junit_with_ant, job: build_java, project: project)
end
it 'returns test report count equal to test reports total_count' do
expect(subject.total_count).to eq(7)
expect(subject.total_count).to eq(pipeline.test_reports_count)
end
it 'reads from cache when records are cached' do
expect(Rails.cache.fetch(['project', project.id, 'pipeline', pipeline.id, 'test_reports_count'], force: false)).to be_nil
pipeline.test_reports_count
expect(ActiveRecord::QueryRecorder.new { pipeline.test_reports_count }.count).to eq(0)
end
end
context 'when pipeline does not have any builds with test reports' do
it 'returns empty test report count' do
expect(subject.total_count).to eq(0)
expect(subject.total_count).to eq(pipeline.test_reports_count)
end
end
end
describe '#accessibility_reports' do
subject { pipeline.accessibility_reports }
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::Artifactable do
let(:ci_job_artifact) { build(:ci_job_artifact) }
describe 'artifact properties are included' do
context 'when enum is defined' do
subject { ci_job_artifact }
it { is_expected.to define_enum_for(:file_format).with_values(raw: 1, zip: 2, gzip: 3).with_suffix }
end
context 'when const is defined' do
subject { ci_job_artifact.class }
it { is_expected.to be_const_defined(:FILE_FORMAT_ADAPTERS) }
end
end
end
......@@ -8,4 +8,8 @@ RSpec.describe JiraTrackerData do
describe 'Associations' do
it { is_expected.to belong_to(:service) }
end
describe 'deployment_type' do
it { is_expected.to define_enum_for(:deployment_type).with_values([:unknown, :server, :cloud]).with_prefix(:deployment) }
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册