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

Add latest changes from gitlab-org/gitlab@master

parent dd6afb4b
No related branches found
No related tags found
No related merge requests found
Showing
with 930 additions and 18 deletions
<script>
import { GlLink } from '@gitlab/ui';
import { __, sprintf } from '../../locale';
import { GlLink, GlSprintf } from '@gitlab/ui';
import { __ } from '../../locale';
import createFlash from '../../flash';
import Api from '../../api';
import state from '../state';
Loading
Loading
@@ -9,6 +9,7 @@ import Dropdown from './dropdown.vue';
export default {
components: {
GlLink,
GlSprintf,
Dropdown,
},
props: {
Loading
Loading
@@ -38,15 +39,6 @@ export default {
selectedProject() {
return state.selectedProject;
},
noForkText() {
return sprintf(
__(
"To protect this issue's confidentiality, %{link_start}fork the project%{link_end} and set the forks visibility to private.",
),
{ link_start: `<a href="${this.newForkPath}" class="help-link">`, link_end: '</a>' },
false,
);
},
},
mounted() {
this.fetchProjects();
Loading
Loading
@@ -123,8 +115,20 @@ export default {
}}
</template>
<template v-else>
{{ __('No forks available to you.') }}<br />
<span v-html="noForkText"></span>
{{ __('No forks are available to you.') }}<br />
<gl-sprintf
:message="
__(
`To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private.`,
)
"
>
<template #forkLink>
<a :href="newForkPath" target="_blank" class="help-link">{{
__('fork this project')
}}</a>
</template>
</gl-sprintf>
</template>
<gl-link
:href="helpPagePath"
Loading
Loading
Loading
Loading
@@ -288,7 +288,7 @@
list-style: none;
padding: 0 1px;
 
a,
a:not(.help-link),
button,
.menu-item {
@include dropdown-link;
Loading
Loading
Loading
Loading
@@ -214,7 +214,6 @@ ul.related-merge-requests > li {
}
 
.create-merge-request-dropdown-menu {
width: 300px;
opacity: 1;
visibility: visible;
transform: translateY(0);
Loading
Loading
# frozen_string_literal: true
module Resolvers
module ErrorTracking
class SentryDetailedErrorResolver < BaseResolver
argument :id, GraphQL::ID_TYPE,
required: true,
description: 'ID of the Sentry issue'
def resolve(**args)
project = object
current_user = context[:current_user]
issue_id = GlobalID.parse(args[:id]).model_id
# Get data from Sentry
response = ::ErrorTracking::IssueDetailsService.new(
project,
current_user,
{ issue_id: issue_id }
).execute
issue = response[:issue]
issue.gitlab_project = project if issue
issue
end
end
end
end
# frozen_string_literal: true
module Types
module ErrorTracking
class SentryDetailedErrorType < ::Types::BaseObject
graphql_name 'SentryDetailedError'
present_using SentryDetailedErrorPresenter
authorize :read_sentry_issue
field :id, GraphQL::ID_TYPE,
null: false,
description: "ID (global ID) of the error"
field :sentry_id, GraphQL::STRING_TYPE,
method: :id,
null: false,
description: "ID (Sentry ID) of the error"
field :title, GraphQL::STRING_TYPE,
null: false,
description: "Title of the error"
field :type, GraphQL::STRING_TYPE,
null: false,
description: "Type of the error"
field :user_count, GraphQL::INT_TYPE,
null: false,
description: "Count of users affected by the error"
field :count, GraphQL::INT_TYPE,
null: false,
description: "Count of occurrences"
field :first_seen, Types::TimeType,
null: false,
description: "Timestamp when the error was first seen"
field :last_seen, Types::TimeType,
null: false,
description: "Timestamp when the error was last seen"
field :message, GraphQL::STRING_TYPE,
null: true,
description: "Sentry metadata message of the error"
field :culprit, GraphQL::STRING_TYPE,
null: false,
description: "Culprit of the error"
field :external_url, GraphQL::STRING_TYPE,
null: false,
description: "External URL of the error"
field :sentry_project_id, GraphQL::ID_TYPE,
method: :project_id,
null: false,
description: "ID of the project (Sentry project)"
field :sentry_project_name, GraphQL::STRING_TYPE,
method: :project_name,
null: false,
description: "Name of the project affected by the error"
field :sentry_project_slug, GraphQL::STRING_TYPE,
method: :project_slug,
null: false,
description: "Slug of the project affected by the error"
field :short_id, GraphQL::STRING_TYPE,
null: false,
description: "Short ID (Sentry ID) of the error"
field :status, Types::ErrorTracking::SentryErrorStatusEnum,
null: false,
description: "Status of the error"
field :frequency, [Types::ErrorTracking::SentryErrorFrequencyType],
null: false,
description: "Last 24hr stats of the error"
field :first_release_last_commit, GraphQL::STRING_TYPE,
null: true,
description: "Commit the error was first seen"
field :last_release_last_commit, GraphQL::STRING_TYPE,
null: true,
description: "Commit the error was last seen"
field :first_release_short_version, GraphQL::STRING_TYPE,
null: true,
description: "Release version the error was first seen"
field :last_release_short_version, GraphQL::STRING_TYPE,
null: true,
description: "Release version the error was last seen"
def first_seen
DateTime.parse(object.first_seen)
end
def last_seen
DateTime.parse(object.last_seen)
end
def project_id
Gitlab::GlobalId.build(model_name: 'Project', id: object.project_id).to_s
end
end
end
end
# frozen_string_literal: true
module Types
module ErrorTracking
# rubocop: disable Graphql/AuthorizeTypes
class SentryErrorFrequencyType < ::Types::BaseObject
graphql_name 'SentryErrorFrequency'
field :time, Types::TimeType,
null: false,
description: "Time the error frequency stats were recorded"
field :count, GraphQL::INT_TYPE,
null: false,
description: "Count of errors received since the previously recorded time"
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
# frozen_string_literal: true
module Types
module ErrorTracking
class SentryErrorStatusEnum < ::Types::BaseEnum
graphql_name 'SentryErrorStatus'
description 'State of a Sentry error'
value 'RESOLVED', value: 'resolved', description: 'Error has been resolved'
value 'RESOLVED_IN_NEXT_RELEASE', value: 'resolvedInNextRelease', description: 'Error has been ignored until next release'
value 'UNRESOLVED', value: 'unresolved', description: 'Error is unresolved'
value 'IGNORED', value: 'ignored', description: 'Error has been ignored'
end
end
end
Loading
Loading
@@ -145,5 +145,11 @@ module Types
null: true,
description: 'Build pipelines of the project',
resolver: Resolvers::ProjectPipelinesResolver
field :sentry_detailed_error,
Types::ErrorTracking::SentryDetailedErrorType,
null: true,
description: 'Detailed version of a Sentry error on the project',
resolver: Resolvers::ErrorTracking::SentryDetailedErrorResolver
end
end
Loading
Loading
@@ -128,7 +128,7 @@ module Issuable
end
 
scope :joins_milestone_releases, -> do
joins("JOIN milestone_releases ON issues.milestone_id = milestone_releases.milestone_id
joins("JOIN milestone_releases ON #{table_name}.milestone_id = milestone_releases.milestone_id
JOIN releases ON milestone_releases.release_id = releases.id").distinct
end
 
Loading
Loading
# frozen_string_literal: true
module ErrorTracking
class DetailedErrorPolicy < BasePolicy
delegate { @subject.gitlab_project }
end
end
# frozen_string_literal: true
class SentryDetailedErrorPresenter < Gitlab::View::Presenter::Delegated
presents :error
FrequencyStruct = Struct.new(:time, :count, keyword_init: true)
def frequency
utc_offset = Time.zone_offset('UTC')
error.frequency.map do |f|
FrequencyStruct.new(time: Time.at(f[0], in: utc_offset), count: f[1])
end
end
end
Loading
Loading
@@ -28,7 +28,7 @@
%ul#create-merge-request-dropdown.create-merge-request-dropdown-menu.dropdown-menu.dropdown-menu-right.gl-show-field-errors{ class: ("create-confidential-merge-request-dropdown-menu" if can_create_confidential_merge_request?), data: { dropdown: true } }
- if can_create_merge_request
%li.droplab-item-selected{ role: 'button', data: { value: 'create-mr', text: create_mr_text } }
.menu-item
.menu-item.text-nowrap
= icon('check', class: 'icon')
- if can_create_confidential_merge_request?
= _('Create confidential merge request and branch')
Loading
Loading
---
title: GraphQL for Sentry rror details
merge_request: 19733
author:
type: added
---
title: Fixed query behind release filter on merge request search page.
merge_request: 38244
author:
type: fixed
---
title: Improve create confidential MR dropdown styling.
merge_request: 20176
author: Lee Tickett
type: other
Loading
Loading
@@ -4400,6 +4400,16 @@ type Project {
"""
requestAccessEnabled: Boolean
 
"""
Detailed version of a Sentry error on the project
"""
sentryDetailedError(
"""
ID of the Sentry issue
"""
id: ID!
): SentryDetailedError
"""
Indicates if shared runners are enabled on the project
"""
Loading
Loading
@@ -4886,6 +4896,150 @@ type RootStorageStatistics {
wikiSize: Int!
}
 
type SentryDetailedError {
"""
Count of occurrences
"""
count: Int!
"""
Culprit of the error
"""
culprit: String!
"""
External URL of the error
"""
externalUrl: String!
"""
Commit the error was first seen
"""
firstReleaseLastCommit: String
"""
Release version the error was first seen
"""
firstReleaseShortVersion: String
"""
Timestamp when the error was first seen
"""
firstSeen: Time!
"""
Last 24hr stats of the error
"""
frequency: [SentryErrorFrequency!]!
"""
ID (global ID) of the error
"""
id: ID!
"""
Commit the error was last seen
"""
lastReleaseLastCommit: String
"""
Release version the error was last seen
"""
lastReleaseShortVersion: String
"""
Timestamp when the error was last seen
"""
lastSeen: Time!
"""
Sentry metadata message of the error
"""
message: String
"""
ID (Sentry ID) of the error
"""
sentryId: String!
"""
ID of the project (Sentry project)
"""
sentryProjectId: ID!
"""
Name of the project affected by the error
"""
sentryProjectName: String!
"""
Slug of the project affected by the error
"""
sentryProjectSlug: String!
"""
Short ID (Sentry ID) of the error
"""
shortId: String!
"""
Status of the error
"""
status: SentryErrorStatus!
"""
Title of the error
"""
title: String!
"""
Type of the error
"""
type: String!
"""
Count of users affected by the error
"""
userCount: Int!
}
type SentryErrorFrequency {
"""
Count of errors received since the previously recorded time
"""
count: Int!
"""
Time the error frequency stats were recorded
"""
time: Time!
}
"""
State of a Sentry error
"""
enum SentryErrorStatus {
"""
Error has been ignored
"""
IGNORED
"""
Error has been resolved
"""
RESOLVED
"""
Error has been ignored until next release
"""
RESOLVED_IN_NEXT_RELEASE
"""
Error is unresolved
"""
UNRESOLVED
}
type Submodule implements Entry {
flatPath: String!
id: ID!
Loading
Loading
Loading
Loading
@@ -1166,6 +1166,33 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "sentryDetailedError",
"description": "Detailed version of a Sentry error on the project",
"args": [
{
"name": "id",
"description": "ID of the Sentry issue",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "SentryDetailedError",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "sharedRunnersEnabled",
"description": "Indicates if shared runners are enabled on the project",
Loading
Loading
@@ -13788,6 +13815,469 @@
],
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "SentryDetailedError",
"description": null,
"fields": [
{
"name": "count",
"description": "Count of occurrences",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "culprit",
"description": "Culprit of the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "externalUrl",
"description": "External URL of the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "firstReleaseLastCommit",
"description": "Commit the error was first seen",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "firstReleaseShortVersion",
"description": "Release version the error was first seen",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "firstSeen",
"description": "Timestamp when the error was first seen",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Time",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "frequency",
"description": "Last 24hr stats of the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "SentryErrorFrequency",
"ofType": null
}
}
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "id",
"description": "ID (global ID) of the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "lastReleaseLastCommit",
"description": "Commit the error was last seen",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "lastReleaseShortVersion",
"description": "Release version the error was last seen",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "lastSeen",
"description": "Timestamp when the error was last seen",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Time",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "message",
"description": "Sentry metadata message of the error",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "sentryId",
"description": "ID (Sentry ID) of the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "sentryProjectId",
"description": "ID of the project (Sentry project)",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "sentryProjectName",
"description": "Name of the project affected by the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "sentryProjectSlug",
"description": "Slug of the project affected by the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "shortId",
"description": "Short ID (Sentry ID) of the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "status",
"description": "Status of the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "SentryErrorStatus",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "title",
"description": "Title of the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "type",
"description": "Type of the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "userCount",
"description": "Count of users affected by the error",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "ENUM",
"name": "SentryErrorStatus",
"description": "State of a Sentry error",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": [
{
"name": "RESOLVED",
"description": "Error has been resolved",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "RESOLVED_IN_NEXT_RELEASE",
"description": "Error has been ignored until next release",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "UNRESOLVED",
"description": "Error is unresolved",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "IGNORED",
"description": "Error has been ignored",
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "SentryErrorFrequency",
"description": null,
"fields": [
{
"name": "count",
"description": "Count of errors received since the previously recorded time",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "time",
"description": "Time the error frequency stats were recorded",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Time",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "Metadata",
Loading
Loading
Loading
Loading
@@ -664,6 +664,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `repository` | Repository | Git repository of the project |
| `mergeRequest` | MergeRequest | A single merge request of the project |
| `issue` | Issue | A single issue of the project |
| `sentryDetailedError` | SentryDetailedError | Detailed version of a Sentry error on the project |
 
### ProjectPermissions
 
Loading
Loading
@@ -751,6 +752,39 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `packagesSize` | Int! | The packages size in bytes |
| `wikiSize` | Int! | The wiki size in bytes |
 
### SentryDetailedError
| Name | Type | Description |
| --- | ---- | ---------- |
| `id` | ID! | ID (global ID) of the error |
| `sentryId` | String! | ID (Sentry ID) of the error |
| `title` | String! | Title of the error |
| `type` | String! | Type of the error |
| `userCount` | Int! | Count of users affected by the error |
| `count` | Int! | Count of occurrences |
| `firstSeen` | Time! | Timestamp when the error was first seen |
| `lastSeen` | Time! | Timestamp when the error was last seen |
| `message` | String | Sentry metadata message of the error |
| `culprit` | String! | Culprit of the error |
| `externalUrl` | String! | External URL of the error |
| `sentryProjectId` | ID! | ID of the project (Sentry project) |
| `sentryProjectName` | String! | Name of the project affected by the error |
| `sentryProjectSlug` | String! | Slug of the project affected by the error |
| `shortId` | String! | Short ID (Sentry ID) of the error |
| `status` | SentryErrorStatus! | Status of the error |
| `frequency` | SentryErrorFrequency! => Array | Last 24hr stats of the error |
| `firstReleaseLastCommit` | String | Commit the error was first seen |
| `lastReleaseLastCommit` | String | Commit the error was last seen |
| `firstReleaseShortVersion` | String | Release version the error was first seen |
| `lastReleaseShortVersion` | String | Release version the error was last seen |
### SentryErrorFrequency
| Name | Type | Description |
| --- | ---- | ---------- |
| `time` | Time! | Time the error frequency stats were recorded |
| `count` | Int! | Count of errors received since the previously recorded time |
### Submodule
 
| Name | Type | Description |
Loading
Loading
Loading
Loading
@@ -203,7 +203,7 @@ job:
You can use [YAML anchors](#anchors) with scripts, which makes it possible to
include a predefined list of commands in multiple jobs.
 
Example:
For example:
 
```yaml
.something: &something
Loading
Loading
@@ -1413,6 +1413,11 @@ Also in the example, `GIT_STRATEGY` is set to `none` so that GitLab Runner won
try to check out the code after the branch is deleted when the `stop_review_app`
job is [automatically triggered](../environments.md#automatically-stopping-an-environment).
 
NOTE: **Note:**
The above example overwrites global variables. If your stop environment job depends
on global variables, you can use [anchor variables](#yaml-anchors-for-variables) when setting the `GIT_STRATEGY`
to change it without overriding the global variables.
The `stop_review_app` job is **required** to have the following keywords defined:
 
- `when` - [reference](#when)
Loading
Loading
@@ -3159,6 +3164,29 @@ which can be set in GitLab's UI.
 
Learn more about [variables and their priority][variables].
 
#### YAML anchors for variables
[YAML anchors](#anchors) can be used with `variables`, to easily repeat assignment
of variables across multiple jobs. It can also enable more flexibility when a job
requires a specific `variables` block that would otherwise override the global variables.
In the example below, we will override the `GIT_STRATEGY` variable without affecting
the use of the `SAMPLE_VARIABLE` variable:
```yaml
# global variables
variables: &global-variables
SAMPLE_VARIABLE: sample_variable_value
# a job that needs to set the GIT_STRATEGY variable, yet depend on global variables
job_no_git_strategy:
stage: cleanup
variables:
<<: *global-variables
GIT_STRATEGY: none
script: echo $SAMPLE_VARIABLE
```
#### Git strategy
 
> Introduced in GitLab 8.9 as an experimental feature. May change or be removed
Loading
Loading
Loading
Loading
@@ -4,6 +4,7 @@ module Gitlab
module ErrorTracking
class DetailedError
include ActiveModel::Model
include GlobalID::Identification
 
attr_accessor :count,
:culprit,
Loading
Loading
@@ -13,6 +14,7 @@ module Gitlab
:first_release_short_version,
:first_seen,
:frequency,
:gitlab_project,
:id,
:last_release_last_commit,
:last_release_short_version,
Loading
Loading
@@ -26,6 +28,10 @@ module Gitlab
:title,
:type,
:user_count
def self.declarative_policy_class
'ErrorTracking::DetailedErrorPolicy'
end
end
end
end
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