Commit 600ca978 authored by 🤖 GitLab Bot 🤖's avatar 🤖 GitLab Bot 🤖

Add latest changes from gitlab-org/[email protected]

parent 571d993b
......@@ -18,13 +18,14 @@ See [the general developer security release guidelines](https://gitlab.com/gitla
- [ ] Title of this merge request is the same as for all backports.
- [ ] A [CHANGELOG entry](https://docs.gitlab.com/ee/development/changelog.html) is added without a `merge_request` value, with `type` set to `security`
- [ ] Assign to a reviewer and maintainer, per our [Code Review process].
- [ ] If this merge request targets `master`, ensure it's approved according to our [Approval Guidelines].
- [ ] For the MR targeting `master`:
- [ ] Ping appsec team member who created the issue and ask for a non-blocking review with `Please review this MR`.
- [ ] Ensure it's approved according to our [Approval Guidelines].
- [ ] Merge request _must not_ close the corresponding security issue, _unless_ it targets `master`.
**Note:** Reviewer/maintainer should not be a Release Manager
## Reviewer checklist
## Maintainer checklist
- [ ] Correct milestone is applied and the title is matching across all backports
- [ ] Assigned to `@gitlab-release-tools-bot` with passing CI pipelines
......
......@@ -2,7 +2,7 @@
import { mapActions, mapGetters, mapState } from 'vuex';
import dateFormat from 'dateformat';
import createFlash from '~/flash';
import { GlFormInput, GlLink, GlLoadingIcon, GlBadge } from '@gitlab/ui';
import { GlButton, GlFormInput, GlLink, GlLoadingIcon, GlBadge } from '@gitlab/ui';
import { __, sprintf, n__ } from '~/locale';
import LoadingButton from '~/vue_shared/components/loading_button.vue';
import Icon from '~/vue_shared/components/icon.vue';
......@@ -17,6 +17,7 @@ import query from '../queries/details.query.graphql';
export default {
components: {
LoadingButton,
GlButton,
GlFormInput,
GlLink,
GlLoadingIcon,
......@@ -188,6 +189,15 @@ export default {
:loading="updatingResolveStatus"
@click="updateIssueStatus('resolved')"
/>
<gl-button
v-if="error.gitlab_issue"
class="ml-2"
data-qa-selector="view_issue_button"
:href="error.gitlab_issue"
variant="success"
>
{{ __('View issue') }}
</gl-button>
<form
ref="sentryIssueForm"
:action="projectIssuesPath"
......
......@@ -16,6 +16,8 @@ module Ci
archive: nil,
metadata: nil,
trace: nil,
metrics_referee: nil,
network_referee: nil,
junit: 'junit.xml',
codequality: 'gl-code-quality-report.json',
sast: 'gl-sast-report.json',
......@@ -37,6 +39,8 @@ module Ci
REPORT_TYPES = {
junit: :gzip,
metrics: :gzip,
metrics_referee: :gzip,
network_referee: :gzip,
# All these file formats use `raw` as we need to store them uncompressed
# for Frontend to fetch the files and do analysis
......@@ -108,7 +112,9 @@ module Ci
license_management: 10, ## EE-specific
license_scanning: 101, ## EE-specific till 13.0
performance: 11, ## EE-specific
metrics: 12 ## EE-specific
metrics: 12, ## EE-specific
metrics_referee: 13, ## runner referees
network_referee: 14 ## runner referees
}
enum file_format: {
......
# frozen_string_literal: true
module DiffViewer
class Collapsed < Base
include Simple
include Static
self.partial_name = 'collapsed'
end
end
......@@ -44,7 +44,7 @@
- @group_notifications.each do |setting|
= render 'group_settings', setting: setting, group: setting.source
%h5
= _('Projects (%{count})') % { count: @project_notifications.count }
= _('Projects (%{count})') % { count: @project_notifications.size }
%p.account-well
= _('To specify the notification level per project of a group you belong to, you need to visit project page and change notification level there.')
.append-bottom-default
......
......@@ -3,8 +3,6 @@
.diff-viewer{ data: { type: viewer.type }, class: ('hidden' if hidden) }
- if viewer.render_error
= render 'projects/diffs/render_error', viewer: viewer
- elsif viewer.collapsed?
= render 'projects/diffs/collapsed', viewer: viewer
- else
- viewer.prepare!
......
---
title: Add epic milestone sourcing foreign key
merge_request: 21907
author:
type: fixed
---
title: Metrics and network referee artifact types added to job artifact types
merge_request: 20181
author:
type: added
---
title: Add View Issue button to error tracking details page
merge_request: 22862
author:
type: added
# frozen_string_literal: true
class AddEpicDateSourcingMilestoneIndexes < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_index :epics, due_date_column
add_concurrent_index :epics, start_date_column
end
def down
remove_concurrent_index :epics, start_date_column
remove_concurrent_index :epics, due_date_column
end
private
def due_date_column
:due_date_sourcing_milestone_id
end
def start_date_column
:start_date_sourcing_milestone_id
end
end
# frozen_string_literal: true
class AddEpicStartDateSourcingMilestoneIdForeignKey < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_foreign_key :epics, :milestones, column: start_date_column, on_delete: :nullify, validate: false
end
def down
remove_foreign_key_if_exists :epics, column: start_date_column
end
private
def start_date_column
:start_date_sourcing_milestone_id
end
end
# frozen_string_literal: true
class AddEpicDueDateSourcingMilestoneIdForeignKey < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_foreign_key :epics, :milestones, column: due_date_column, on_delete: :nullify, validate: false
end
def down
remove_foreign_key_if_exists :epics, column: due_date_column
end
private
def due_date_column
:due_date_sourcing_milestone_id
end
end
# frozen_string_literal: true
class FixInvalidEpicSourcingMilestoneIds < ActiveRecord::Migration[5.2]
DOWNTIME = false
def up
nullify_invalid_data(:start_date_sourcing_milestone_id)
nullify_invalid_data(:due_date_sourcing_milestone_id)
end
def down
# no-op
end
private
def nullify_invalid_data(column_name)
execute(<<-SQL.squish)
UPDATE epics
SET #{column_name} = null
WHERE #{column_name} NOT IN (SELECT id FROM milestones);
SQL
end
end
# frozen_string_literal: true
class ValidateForeignKeyEpicStartDateSourcingMilestone < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
validate_foreign_key(:epics, :start_date_sourcing_milestone_id)
end
def down
# no-op
end
end
# frozen_string_literal: true
class ValidateForeignKeyEpicDueDateSourcingMilestone < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
validate_foreign_key(:epics, :due_date_sourcing_milestone_id)
end
def down
# no-op
end
end
......@@ -1573,6 +1573,7 @@ ActiveRecord::Schema.define(version: 2020_01_14_113341) do
t.index ["author_id"], name: "index_epics_on_author_id"
t.index ["closed_by_id"], name: "index_epics_on_closed_by_id"
t.index ["due_date_sourcing_epic_id"], name: "index_epics_on_due_date_sourcing_epic_id", where: "(due_date_sourcing_epic_id IS NOT NULL)"
t.index ["due_date_sourcing_milestone_id"], name: "index_epics_on_due_date_sourcing_milestone_id"
t.index ["end_date"], name: "index_epics_on_end_date"
t.index ["group_id"], name: "index_epics_on_group_id"
t.index ["iid"], name: "index_epics_on_iid"
......@@ -1580,6 +1581,7 @@ ActiveRecord::Schema.define(version: 2020_01_14_113341) do
t.index ["parent_id"], name: "index_epics_on_parent_id"
t.index ["start_date"], name: "index_epics_on_start_date"
t.index ["start_date_sourcing_epic_id"], name: "index_epics_on_start_date_sourcing_epic_id", where: "(start_date_sourcing_epic_id IS NOT NULL)"
t.index ["start_date_sourcing_milestone_id"], name: "index_epics_on_start_date_sourcing_milestone_id"
end
create_table "events", id: :serial, force: :cascade do |t|
......@@ -4587,6 +4589,8 @@ ActiveRecord::Schema.define(version: 2020_01_14_113341) do
add_foreign_key "epics", "epics", column: "due_date_sourcing_epic_id", name: "fk_013c9f36ca", on_delete: :nullify
add_foreign_key "epics", "epics", column: "parent_id", name: "fk_25b99c1be3", on_delete: :cascade
add_foreign_key "epics", "epics", column: "start_date_sourcing_epic_id", name: "fk_9d480c64b2", on_delete: :nullify
add_foreign_key "epics", "milestones", column: "due_date_sourcing_milestone_id", name: "fk_3c1fd1cccc", on_delete: :nullify
add_foreign_key "epics", "milestones", column: "start_date_sourcing_milestone_id", name: "fk_1fbed67632", on_delete: :nullify
add_foreign_key "epics", "milestones", on_delete: :nullify
add_foreign_key "epics", "namespaces", column: "group_id", name: "fk_f081aa4489", on_delete: :cascade
add_foreign_key "epics", "users", column: "assignee_id", name: "fk_dccd3f98fc", on_delete: :nullify
......
......@@ -8,6 +8,7 @@ The Packages feature allows GitLab to act as a repository for the following:
| Software repository | Description | Available in GitLab version |
| ------------------- | ----------- | --------------------------- |
| [NuGet Repository](../../user/packages/nuget_repository/index.md) | The GitLab NuGet Repository enables every project in GitLab to have its own space to store [NuGet](https://www.nuget.org/) packages. | 12.8+ |
| [Conan Repository](../../user/packages/conan_repository/index.md) | The GitLab Conan Repository enables every project in GitLab to have its own space to store [Conan](https://conan.io/) packages. | 12.4+ |
| [Maven Repository](../../user/packages/maven_repository/index.md) | The GitLab Maven Repository enables every project in GitLab to have its own space to store [Maven](https://maven.apache.org/) packages. | 11.3+ |
| [NPM Registry](../../user/packages/npm_registry/index.md) | The GitLab NPM Registry enables every project in GitLab to have its own space to store [NPM](https://www.npmjs.com/) packages. | 11.7+ |
......
......@@ -13,7 +13,7 @@ The Packages feature allows GitLab to act as a repository for the following:
| [Conan Repository](conan_repository/index.md) **(PREMIUM)** | The GitLab Conan Repository enables every project in GitLab to have its own space to store [Conan](https://conan.io/) packages. | 12.6+ |
| [Maven Repository](maven_repository/index.md) **(PREMIUM)** | The GitLab Maven Repository enables every project in GitLab to have its own space to store [Maven](https://maven.apache.org/) packages. | 11.3+ |
| [NPM Registry](npm_registry/index.md) **(PREMIUM)** | The GitLab NPM Registry enables every project in GitLab to have its own space to store [NPM](https://www.npmjs.com/) packages. | 11.7+ |
| [NuGet Repository](https://gitlab.com/gitlab-org/gitlab/issues/20050) **(PREMIUM)** | *COMING SOON* The GitLab NuGet Repository will enable every project in GitLab to have its own space to store [NuGet](https://www.nuget.org/) packages. | 12.7 (planned) |
| [NuGet Repository](nuget_repository/index.md) **(PREMIUM)** | *COMING SOON* The GitLab NuGet Repository will enable every project in GitLab to have its own space to store [NuGet](https://www.nuget.org/) packages. | 12.8+ |
TIP: **Tip:**
Don't you see your package management system supported yet? Consider contributing
......
# GitLab NuGet Repository **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/20050) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
CAUTION: **Work in progress**
This feature is in development, sections on uploading and installing packages will be coming soon, please follow along and help us make sure we're building the right solution for you in the [NuGet issue](https://gitlab.com/gitlab-org/gitlab/issues/20050).
With the GitLab NuGet Repository, every project can have its own space to store NuGet packages.
The GitLab NuGet Repository works with either [nuget CLI](https://www.nuget.org/) or [Visual Studio](https://visualstudio.microsoft.com/vs/).
## Setting up your development environment
You will need [nuget CLI](https://www.nuget.org/) 5.2 or above. Previous versions have not been tested against the GitLab NuGet Repository and might not work. You can install it by visiting the [downloads page](https://www.nuget.org/downloads).
If you have [Visual Studio](https://visualstudio.microsoft.com/vs/), [nuget CLI](https://www.nuget.org/) is probably already installed.
You can confirm that [nuget CLI](https://www.nuget.org/) is properly installed with:
```sh
nuget help
```
You should see something similar to:
```
NuGet Version: 5.2.0.6090
usage: NuGet <command> [args] [options]
Type 'NuGet help <command>' for help on a specific command.
Available commands:
[output truncated]
```
## Enabling the NuGet Repository
NOTE: **Note:**
This option is available only if your GitLab administrator has
[enabled support for the NuGet Repository](../../../administration/packages/index.md).**(PREMIUM ONLY)**
After the NuGet Repository is enabled, it will be available for all new projects
by default. To enable it for existing projects, or if you want to disable it:
1. Navigate to your project's **Settings > General > Permissions**.
1. Find the Packages feature and enable or disable it.
1. Click on **Save changes** for the changes to take effect.
You should then be able to see the **Packages** section on the left sidebar.
## Adding the GitLab NuGet Repository as a source to nuget
You will need the following:
- Your GitLab username.
- A personal access token. You can generate a [personal access token](../../../user/profile/personal_access_tokens.md) with the scope set to `api` for repository authentication.
- A suitable name for your source.
- Your project ID which can be found on the home page of your project.
You can now add a new source to nuget either using [nuget CLI](https://www.nuget.org/) or [Visual Studio](https://visualstudio.microsoft.com/vs/).
### Using nuget CLI
To add the GitLab NuGet Repository as a source with `nuget`:
```sh
nuget source Add -Name <source_name> -Source "https://example.gitlab.com/api/v4/projects/<your_project_id>/packages/nuget/index.json" -UserName <gitlab_username> -Password <gitlab_token>
```
Replace:
- `<source_name>` with your desired source name.
- `<your_project_id>` with your project ID.
- `<gitlab-username>` with your GitLab username.
- `<gitlab-token>` with your personal access token.
- `example.gitlab.com` with the URL of the GitLab instance you're using.
For example:
```sh
nuget source Add -Name "GitLab" -Source "https//gitlab.example/api/v4/projects/10/packages/nuget/index.json" -UserName carol -Password 12345678asdf
```
### Using Visual Studio
1. Open [Visual Studio](https://visualstudio.microsoft.com/vs/).
1. Open the **FILE > OPTIONS** (Windows) or **Visual Studio > Preferences** (Mac OS).
1. In the **NuGet** section, open **Sources**. You will see a list of all your NuGet sources.
1. Click **Add**.
1. Fill the fields with:
- **Name**: Desired name for the source
- **Location**: `https://gitlab.com/api/v4/projects/<your_project_id>/packages/nuget/index.json`
- Replace `<your_project_id>` with your project ID.
- If you have a self-hosted GitLab installation, replace `gitlab.com` with your domain name.
- **Username**: Your GitLab username
- **Password**: Your personal access token
![Visual Studio Adding a NuGet source](img/visual_studio_adding_nuget_source.png)
1. Click **Save**.
![Visual Studio NuGet source added](img/visual_studio_nuget_source_added.png)
In case of any warning, please make sure that the **Location**, **Username** and **Password** are correct.
......@@ -62,3 +62,15 @@ If the error has not been linked to an existing GitLab issue, a 'Create Issue' b
If a link does exist, it will be shown in the details and the 'Create Issue' button will be hidden:
![Error Details with Issue Link](img/error_details_with_issue_v12_6.png)
## Taking Action on errors
You can take action on Sentry Errors from within the GitLab UI.
### Ignoring errors
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/39665) in GitLab 12.7.
From within the [Error Details](#error-details) page you can ignore a Sentry error by simply clicking the **Ignore** button near the top of the page.
Ignoring an error will prevent it from appearing in the [Error Tracking List](#error-tracking-list), and will silence notifications that were set up within Sentry.
......@@ -358,6 +358,10 @@ module Gitlab
end
end
def modified_file?
new_file? || deleted_file? || content_changed?
end
# We can't use Object#try because Blob doesn't inherit from Object, but
# from BasicObject (via SimpleDelegator).
def try_blobs(meth)
......@@ -393,33 +397,16 @@ module Gitlab
end
def simple_viewer_class
return DiffViewer::Collapsed if collapsed?
return DiffViewer::NotDiffable unless diffable?
return DiffViewer::Text if modified_file? && text?
return DiffViewer::NoPreview if content_changed?
return DiffViewer::Added if new_file?
return DiffViewer::Deleted if deleted_file?
return DiffViewer::Renamed if renamed_file?
return DiffViewer::ModeChanged if mode_changed?
if content_changed?
if text?
DiffViewer::Text
else
DiffViewer::NoPreview
end
elsif new_file?
if text?
DiffViewer::Text
else
DiffViewer::Added
end
elsif deleted_file?
if text?
DiffViewer::Text
else
DiffViewer::Deleted
end
elsif renamed_file?
DiffViewer::Renamed
elsif mode_changed?
DiffViewer::ModeChanged
else
DiffViewer::NoPreview
end
DiffViewer::NoPreview
end
def rich_viewer_class
......@@ -427,8 +414,9 @@ module Gitlab
end
def viewer_class_from(classes)
return if collapsed?
return unless diffable?
return unless new_file? || deleted_file? || content_changed?
return unless modified_file?
return if different_type? || external_storage_error?
verify_binary = !stored_externally?
......
......@@ -20480,6 +20480,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
msgid "View issue"
msgstr ""
msgid "View it on GitLab"
msgstr ""
......
......@@ -34,7 +34,7 @@ describe 'Database schema' do
draft_notes: %w[discussion_id commit_id],
emails: %w[user_id],
events: %w[target_id],
epics: %w[updated_by_id last_edited_by_id start_date_sourcing_milestone_id due_date_sourcing_milestone_id state_id],
epics: %w[updated_by_id last_edited_by_id state_id],
forked_project_links: %w[forked_from_project_id],
geo_event_log: %w[hashed_storage_attachments_event_id],
geo_job_artifact_deleted_events: %w[job_artifact_id],
......
......@@ -198,6 +198,7 @@ describe('ErrorDetails', () => {
const gitlabIssue = 'https://gitlab.example.com/issues/1';
const findGitLabLink = () => wrapper.find(`[href="${gitlabIssue}"]`);
const findCreateIssueButton = () => wrapper.find('[data-qa-selector="create_issue_button"]');
const findViewIssueButton = () => wrapper.find('[data-qa-selector="view_issue_button"]');
describe('is present', () => {
beforeEach(() => {
......@@ -209,6 +210,10 @@ describe('ErrorDetails', () => {
mountComponent();
});
it('should display the View issue button', () => {
expect(findViewIssueButton().exists()).toBe(true);
});
it('should display the issue link', () => {
expect(findGitLabLink().exists()).toBe(true);
});
......@@ -228,9 +233,14 @@ describe('ErrorDetails', () => {
mountComponent();
});
it('should not display the View issue button', () => {
expect(findViewIssueButton().exists()).toBe(false);
});
it('should not display an issue link', () => {
expect(findGitLabLink().exists()).toBe(false);
});
it('should display the create issue button', () => {
expect(findCreateIssueButton().exists()).toBe(true);
});
......
......@@ -347,6 +347,16 @@ describe Gitlab::Diff::File do
end
describe '#simple_viewer' do
context 'when the file is collapsed' do
before do
allow(diff_file).to receive(:collapsed?).and_return(true)
end
it 'returns a Collapsed viewer' do
expect(diff_file.simple_viewer).to be_a(DiffViewer::Collapsed)
end
end
context 'when the file is not diffable' do
before do
allow(diff_file).to receive(:diffable?).and_return(false)
......
......@@ -1828,6 +1828,58 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end
end
end
context 'when artifact_type is metrics_referee' do
context 'when artifact_format is gzip' do
let(:file_upload) { fixture_file_upload('spec/fixtures/referees/metrics_referee.json.gz') }
let(:params) { { artifact_type: :metrics_referee, artifact_format: :gzip } }
it 'stores metrics_referee data' do
upload_artifacts(file_upload, headers_with_token, params)
expect(response).to have_gitlab_http_status(201)
expect(job.reload.job_artifacts_metrics_referee).not_to be_nil
end
end
context 'when artifact_format is raw' do
let(:file_upload) { fixture_file_upload('spec/fixtures/referees/metrics_referee.json.gz') }
let(:params) { { artifact_type: :metrics_referee, artifact_format: :raw } }
it 'returns an error' do
upload_artifacts(file_upload, headers_with_token, params)
expect(response).to have_gitlab_http_status(400)
expect(job.reload.job_artifacts_metrics_referee).to be_nil
end
end
end
context 'when artifact_type is network_referee' do
context 'when artifact_format is gzip' do
let(:file_upload) { fixture_file_upload('spec/fixtures/referees/network_referee.json.gz') }
let(:params) { { artifact_type: :network_referee, artifact_format: :gzip } }
it 'stores network_referee data' do
upload_artifacts(file_upload, headers_with_token, params)
expect(response).to have_gitlab_http_status(201)
expect(job.reload.job_artifacts_network_referee).not_to be_nil
end
end
context 'when artifact_format is raw' do
let(:file_upload) { fixture_file_upload('spec/fixtures/referees/network_referee.json.gz') }
let(:params) { { artifact_type: :network_referee, artifact_format: :raw } }
it 'returns an error' do
upload_artifacts(file_upload, headers_with_token, params)
expect(response).to have_gitlab_http_status(400)
expect(job.reload.job_artifacts_network_referee).to be_nil
end
end
end
end
context 'when artifacts are being stored outside of tmp path' do
......
......@@ -35,7 +35,8 @@ describe Ci::RetryBuildService do
job_artifacts_license_management job_artifacts_license_scanning
job_artifacts_performance
job_artifacts_codequality job_artifacts_metrics scheduled_at
job_variables waiting_for_resource_at].freeze
job_variables waiting_for_resource_at job_artifacts_metrics_referee
job_artifacts_network_referee].freeze
IGNORE_ACCESSORS =
%i[type lock_version target_url base_tags trace_sections
......
......@@ -9,15 +9,7 @@ describe 'projects/diffs/_viewer.html.haml' do
let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') }
let(:viewer_class) do