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

Add latest changes from gitlab-org/gitlab@master

parent 93d7441c
No related branches found
No related tags found
No related merge requests found
Showing
with 511 additions and 48 deletions
Loading
Loading
@@ -7,7 +7,7 @@ export default () => {
const el = document.getElementById('js-edit-release-page');
 
const store = createStore({ detail: detailModule });
store.dispatch('setInitialState', el.dataset);
store.dispatch('detail/setInitialState', el.dataset);
 
return new Vue({
el,
Loading
Loading
Loading
Loading
@@ -46,6 +46,12 @@ module Types
field :milestones, Types::MilestoneType.connection_type, null: true,
description: 'Find milestones',
resolver: Resolvers::MilestoneResolver
field :boards,
Types::BoardType.connection_type,
null: true,
description: 'Boards of the group',
resolver: Resolvers::BoardsResolver
end
end
 
Loading
Loading
Loading
Loading
@@ -179,6 +179,12 @@ module Types
null: true,
description: 'Paginated collection of Sentry errors on the project',
resolver: Resolvers::ErrorTracking::SentryErrorCollectionResolver
field :boards,
Types::BoardType.connection_type,
null: true,
description: 'Boards of the project',
resolver: Resolvers::BoardsResolver
end
end
 
Loading
Loading
Loading
Loading
@@ -58,7 +58,7 @@ module IncidentManagement
end
 
def issue_description
horizontal_line = "\n---\n\n"
horizontal_line = "\n\n---\n\n"
 
[
alert_summary,
Loading
Loading
---
title: 'GraphQL: Add Board type'
merge_request: 22497
author: Alexander Koval
type: added
---
title: Fix "Edit Release" page
merge_request: 25469
author:
type: fixed
---
title: Fix markdown layout of incident issues
merge_request: 25352
author:
type: fixed
Loading
Loading
@@ -159,6 +159,61 @@ enum BlobViewersType {
simple
}
 
"""
Represents a project or group board
"""
type Board {
"""
ID (global ID) of the board
"""
id: ID!
"""
Name of the board
"""
name: String
"""
Weight of the board
"""
weight: Int
}
"""
The connection type for Board.
"""
type BoardConnection {
"""
A list of edges.
"""
edges: [BoardEdge]
"""
A list of nodes.
"""
nodes: [Board]
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type BoardEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: Board
}
type Commit {
"""
Author of the commit
Loading
Loading
@@ -2715,6 +2770,31 @@ type Group {
"""
avatarUrl: String
 
"""
Boards of the group
"""
boards(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): BoardConnection
"""
Description of the namespace
"""
Loading
Loading
@@ -5174,6 +5254,31 @@ type Project {
"""
avatarUrl: String
 
"""
Boards of the project
"""
boards(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): BoardConnection
"""
Indicates if the project stores Docker container images in a container registry
"""
Loading
Loading
Loading
Loading
@@ -368,6 +368,59 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "boards",
"description": "Boards of the project",
"args": [
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "before",
"description": "Returns the elements in the list that come before the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": "Returns the first _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "last",
"description": "Returns the last _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "BoardConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "containerRegistryEnabled",
"description": "Indicates if the project stores Docker container images in a container registry",
Loading
Loading
@@ -3122,6 +3175,59 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "boards",
"description": "Boards of the group",
"args": [
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "before",
"description": "Returns the elements in the list that come before the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": "Returns the first _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "last",
"description": "Returns the last _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "BoardConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "description",
"description": "Description of the namespace",
Loading
Loading
@@ -4322,6 +4428,177 @@
],
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "BoardConnection",
"description": "The connection type for Board.",
"fields": [
{
"name": "edges",
"description": "A list of edges.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "BoardEdge",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "nodes",
"description": "A list of nodes.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Board",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "pageInfo",
"description": "Information to aid in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "PageInfo",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "BoardEdge",
"description": "An edge in a connection.",
"fields": [
{
"name": "cursor",
"description": "A cursor for use in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "node",
"description": "The item at the end of the edge.",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "Board",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "Board",
"description": "Represents a project or group board",
"fields": [
{
"name": "id",
"description": "ID (global ID) of the board",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "name",
"description": "Name of the board",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "weight",
"description": "Weight of the board",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "Epic",
Loading
Loading
Loading
Loading
@@ -49,6 +49,16 @@ An emoji awarded by a user.
| `type` | EntryType! | Type of tree entry |
| `webUrl` | String | Web URL of the blob |
 
## Board
Represents a project or group board
| Name | Type | Description |
| --- | ---- | ---------- |
| `id` | ID! | ID (global ID) of the board |
| `name` | String | Name of the board |
| `weight` | Int | Weight of the board |
## Commit
 
| Name | Type | Description |
Loading
Loading
Loading
Loading
@@ -498,7 +498,7 @@ Parameters:
 
## Transfer project to group
 
Transfer a project to the Group namespace. Available only for admin
Transfer a project to the Group namespace. Available only to instance administrators. Transferring projects may fail when tagged packages exist in the project's repository.
 
```
POST /groups/:id/projects/:project_id
Loading
Loading
@@ -508,9 +508,13 @@ Parameters:
 
| Attribute | Type | Required | Description |
| ------------ | -------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `id` | integer/string | yes | The ID or [URL-encoded path of the target group](README.md#namespaced-path-encoding) |
| `project_id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
 
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4/projects/56
```
## Update group
 
Updates the project group. Only available to group owners and administrators.
Loading
Loading
Loading
Loading
@@ -15,7 +15,7 @@ own advantages. These methods can be mixed and matched if needed:
- [Child/Parent Pipelines](#child--parent-pipelines): Good for monorepos and projects with lots of independently defined components.
 
For more details about
any of the keywords used below, check out our [CI YAML reference](../yaml/) for details.
any of the keywords used below, check out our [CI YAML reference](../yaml/README.md) for details.
 
## Basic Pipelines
 
Loading
Loading
Loading
Loading
@@ -20,6 +20,7 @@ module Banzai
# the cost of doing a full regex match.
def xpath_search
"descendant-or-self::a[contains(@href,'metrics') and \
contains(@href,'environments') and \
starts-with(@href, '#{Gitlab.config.gitlab.url}')]"
end
 
Loading
Loading
Loading
Loading
@@ -9,8 +9,8 @@ module Banzai
 
METRICS_CSS_CLASS = '.js-render-metrics'
EMBED_LIMIT = 100
URL = Gitlab::Metrics::Dashboard::Url
 
Route = Struct.new(:regex, :permission)
Embed = Struct.new(:project_path, :permission)
 
# Finds all embeds based on the css class the FE
Loading
Loading
@@ -59,14 +59,28 @@ module Banzai
embed = Embed.new
url = node.attribute('data-dashboard-url').to_s
 
set_path_and_permission(embed, url, URL.metrics_regex, :read_environment)
set_path_and_permission(embed, url, URL.grafana_regex, :read_project) unless embed.permission
permissions_by_route.each do |route|
set_path_and_permission(embed, url, route.regex, route.permission) unless embed.permission
end
 
embeds[node] = embed if embed.permission
end
end
end
 
def permissions_by_route
[
Route.new(
::Gitlab::Metrics::Dashboard::Url.metrics_regex,
:read_environment
),
Route.new(
::Gitlab::Metrics::Dashboard::Url.grafana_regex,
:read_project
)
]
end
# Attempts to determine the path and permission attributes
# of a url based on expected dashboard url formats and
# sets the attributes on an Embed object
Loading
Loading
Loading
Loading
@@ -29,8 +29,7 @@ module Banzai
Filter::AudioLinkFilter,
Filter::ImageLazyLoadFilter,
Filter::ImageLinkFilter,
Filter::InlineMetricsFilter,
Filter::InlineGrafanaMetricsFilter,
*metrics_filters,
Filter::TableOfContentsFilter,
Filter::TableOfContentsTagFilter,
Filter::AutolinkFilter,
Loading
Loading
@@ -48,6 +47,13 @@ module Banzai
]
end
 
def self.metrics_filters
[
Filter::InlineMetricsFilter,
Filter::InlineGrafanaMetricsFilter
]
end
def self.reference_filters
[
Filter::UserReferenceFilter,
Loading
Loading
Loading
Loading
@@ -11310,31 +11310,19 @@ msgstr ""
msgid "LicenseCompliance|Add licenses manually to approve or blacklist"
msgstr ""
 
msgid "LicenseCompliance|Approve"
msgid "LicenseCompliance|Allow"
msgstr ""
 
msgid "LicenseCompliance|Approve license"
msgid "LicenseCompliance|Allowed"
msgstr ""
 
msgid "LicenseCompliance|Approve license?"
msgstr ""
msgid "LicenseCompliance|Approved"
msgstr ""
msgid "LicenseCompliance|Blacklist"
msgstr ""
msgid "LicenseCompliance|Blacklist license"
msgstr ""
msgid "LicenseCompliance|Blacklist license?"
msgid "LicenseCompliance|Cancel"
msgstr ""
 
msgid "LicenseCompliance|Blacklisted"
msgid "LicenseCompliance|Denied"
msgstr ""
 
msgid "LicenseCompliance|Cancel"
msgid "LicenseCompliance|Deny"
msgstr ""
 
msgid "LicenseCompliance|Here you can approve or blacklist licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and approve or blacklist them in merge request."
Loading
Loading
@@ -11378,6 +11366,9 @@ msgstr ""
msgid "LicenseCompliance|License name"
msgstr ""
 
msgid "LicenseCompliance|License review"
msgstr ""
msgid "LicenseCompliance|Packages"
msgstr ""
 
Loading
Loading
@@ -11423,6 +11414,9 @@ msgstr ""
msgid "Licenses|Components"
msgstr ""
 
msgid "Licenses|Detected in Project"
msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest pipeline%{linkEnd} scan"
msgstr ""
 
Loading
Loading
@@ -11438,6 +11432,15 @@ msgstr ""
msgid "Licenses|Name"
msgstr ""
 
msgid "Licenses|Policies"
msgstr ""
msgid "Licenses|Policy"
msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
 
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe GitlabSchema.types['Board'] do
it { expect(described_class.graphql_name).to eq('Board') }
it { expect(described_class).to require_graphql_authorizations(:read_board) }
it 'has specific fields' do
expected_fields = %w[id name]
is_expected.to include_graphql_fields(*expected_fields)
end
end
Loading
Loading
@@ -16,9 +16,17 @@ describe GitlabSchema.types['Group'] do
web_url avatar_url share_with_group_lock project_creation_level
subgroup_creation_level require_two_factor_authentication
two_factor_grace_period auto_devops_enabled emails_disabled
mentions_disabled parent
mentions_disabled parent boards
]
 
is_expected.to include_graphql_fields(*expected_fields)
end
describe 'boards field' do
subject { described_class.fields['boards'] }
it 'returns boards' do
is_expected.to have_graphql_type(Types::BoardType.connection_type)
end
end
end
Loading
Loading
@@ -24,6 +24,7 @@ describe GitlabSchema.types['Project'] do
namespace group statistics repository merge_requests merge_request issues
issue pipelines removeSourceBranchAfterMerge sentryDetailedError snippets
grafanaIntegration autocloseReferencedIssues suggestion_commit_message environments
boards
]
 
is_expected.to include_graphql_fields(*expected_fields)
Loading
Loading
@@ -77,4 +78,10 @@ describe GitlabSchema.types['Project'] do
it { is_expected.to have_graphql_type(Types::EnvironmentType.connection_type) }
it { is_expected.to have_graphql_resolver(Resolvers::EnvironmentsResolver) }
end
describe 'boards field' do
subject { described_class.fields['boards'] }
it { is_expected.to have_graphql_type(Types::BoardType.connection_type) }
end
end
Loading
Loading
@@ -8,40 +8,26 @@ describe Banzai::Filter::InlineGrafanaMetricsFilter do
let_it_be(:project) { create(:project) }
let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
 
let(:input) { %(<a href="#{url}">example</a>) }
let(:input) { %(<a href="#{trigger_url}">example</a>) }
let(:doc) { filter(input) }
let(:url) { grafana_integration.grafana_url + dashboard_path }
let(:dashboard_path) do
'/d/XDaNK6amz/gitlab-omnibus-redis' \
'?from=1570397739557&to=1570484139557' \
'&var-instance=All&panelId=14'
end
 
it 'appends a metrics charts placeholder with dashboard url after metrics links' do
node = doc.at_css('.js-render-metrics')
expect(node).to be_present
dashboard_url = urls.project_grafana_api_metrics_dashboard_url(
let(:trigger_url) { grafana_integration.grafana_url + dashboard_path }
let(:dashboard_url) do
urls.project_grafana_api_metrics_dashboard_url(
project,
embedded: true,
grafana_url: url,
grafana_url: trigger_url,
start: "2019-10-06T21:35:39Z",
end: "2019-10-07T21:35:39Z"
)
expect(node.attribute('data-dashboard-url').to_s).to eq(dashboard_url)
end
 
context 'when the dashboard link is part of a paragraph' do
let(:paragraph) { %(This is an <a href="#{url}">example</a> of metrics.) }
let(:input) { %(<p>#{paragraph}</p>) }
it 'appends the charts placeholder after the enclosing paragraph' do
expect(unescape(doc.at_css('p').to_s)).to include(paragraph)
expect(doc.at_css('.js-render-metrics')).to be_present
end
end
it_behaves_like 'a metrics embed filter'
 
context 'when grafana is not configured' do
before do
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