Commit f6cdec67 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent e2ee1eec
...@@ -102,6 +102,7 @@ ...@@ -102,6 +102,7 @@
"Redis", "Redis",
"Redmine", "Redmine",
"reCAPTCHA", "reCAPTCHA",
"Ruby",
"runit", "runit",
"Salesforce", "Salesforce",
"SAML", "SAML",
......
<script>
import { isString } from 'lodash';
import { GlLink, GlNewButton } from '@gitlab/ui';
const validateUrlAndLabel = value => isString(value.label) && isString(value.url);
export default {
components: {
GlLink,
GlNewButton,
},
props: {
branch: {
type: Object,
required: true,
validator: validateUrlAndLabel,
},
commit: {
type: Object,
required: true,
validator: validateUrlAndLabel,
},
mergeRequest: {
type: Object,
required: true,
validator: validateUrlAndLabel,
},
returnUrl: {
type: String,
required: true,
},
},
};
</script>
<template>
<div>
<div>
<h3>{{ s__('StaticSiteEditor|Success!') }}</h3>
<p>
{{
s__(
'StaticSiteEditor|Your changes have been submitted and a merge request has been created. The changes won’t be visible on the site until the merge request has been accepted.',
)
}}
</p>
<div>
<gl-new-button ref="returnToSiteButton" :href="returnUrl">{{
s__('StaticSiteEditor|Return to site')
}}</gl-new-button>
<gl-new-button ref="mergeRequestButton" :href="mergeRequest.url" variant="info">{{
s__('StaticSiteEditor|View merge request')
}}</gl-new-button>
</div>
</div>
<hr />
<div>
<h4>{{ s__('StaticSiteEditor|Summary of changes') }}</h4>
<ul>
<li>
{{ s__('StaticSiteEditor|A new branch was created:') }}
<gl-link ref="branchLink" :href="branch.url">{{ branch.label }}</gl-link>
</li>
<li>
{{ s__('StaticSiteEditor|Your changes were committed to it:') }}
<gl-link ref="commitLink" :href="commit.url">{{ commit.label }}</gl-link>
</li>
<li>
{{ s__('StaticSiteEditor|A merge request was created:') }}
<gl-link ref="mergeRequestLink" :href="mergeRequest.url">{{
mergeRequest.label
}}</gl-link>
</li>
</ul>
</div>
</div>
</template>
# frozen_string_literal: true
module Resolvers
module Projects
class ServicesResolver < BaseResolver
include Gitlab::Graphql::Authorize::AuthorizeResource
argument :active,
GraphQL::BOOLEAN_TYPE,
required: false,
description: 'Indicates if the service is active'
argument :type,
Types::Projects::ServiceTypeEnum,
required: false,
description: 'Class name of the service'
alias_method :project, :object
def resolve(**args)
authorize!(project)
services(args[:active], args[:type])
end
def authorized_resource?(project)
Ability.allowed?(context[:current_user], :admin_project, project)
end
private
def services(active, type)
servs = project.services
servs = servs.by_active_flag(active) unless active.nil?
servs = servs.by_type(type) unless type.blank?
servs
end
end
end
end
...@@ -199,6 +199,12 @@ module Types ...@@ -199,6 +199,12 @@ module Types
null: true, null: true,
description: 'Jira imports into the project', description: 'Jira imports into the project',
resolver: Resolvers::Projects::JiraImportsResolver resolver: Resolvers::Projects::JiraImportsResolver
field :services,
Types::Projects::ServiceType.connection_type,
null: true,
description: 'Project services',
resolver: Resolvers::Projects::ServicesResolver
end end
end end
......
# frozen_string_literal: true
module Types
module Projects
module ServiceType
include Types::BaseInterface
graphql_name 'Service'
# TODO: Add all the fields that we want to expose for the project services intergrations
# https://gitlab.com/gitlab-org/gitlab/-/issues/213088
field :type, GraphQL::STRING_TYPE, null: true,
description: 'Class name of the service'
field :active, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if the service is active'
definition_methods do
def resolve_type(object, context)
if object.is_a?(::JiraService)
Types::Projects::Services::JiraServiceType
else
Types::Projects::Services::BaseServiceType
end
end
end
orphan_types Types::Projects::Services::BaseServiceType, Types::Projects::Services::JiraServiceType
end
end
end
# frozen_string_literal: true
module Types
module Projects
class ServiceTypeEnum < BaseEnum
graphql_name 'ServiceType'
::Service.services_types.each do |service_type|
value service_type.underscore.upcase, value: service_type
end
end
end
end
# frozen_string_literal: true
module Types
module Projects
module Services
class BaseServiceType < BaseObject
graphql_name 'BaseService'
implements(Types::Projects::ServiceType)
authorize :admin_project
end
end
end
end
# frozen_string_literal: true
module Types
module Projects
module Services
class JiraServiceType < BaseObject
graphql_name 'JiraService'
implements(Types::Projects::ServiceType)
authorize :admin_project
# This is a placeholder for now for the actuall implementation of the JiraServiceType
# Here we will want to expose a field with jira_projects fetched through Jira Rest API
# MR implementing it https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28190
end
end
end
end
...@@ -8,6 +8,17 @@ class Service < ApplicationRecord ...@@ -8,6 +8,17 @@ class Service < ApplicationRecord
include ProjectServicesLoggable include ProjectServicesLoggable
include DataFields include DataFields
SERVICE_NAMES = %w[
alerts asana assembla bamboo bugzilla buildkite campfire custom_issue_tracker discord
drone_ci emails_on_push external_wiki flowdock hangouts_chat hipchat irker jira
mattermost mattermost_slash_commands microsoft_teams packagist pipelines_email
pivotaltracker prometheus pushover redmine slack slack_slash_commands teamcity unify_circuit youtrack
].freeze
DEV_SERVICE_NAMES = %w[
mock_ci mock_deployment mock_monitoring
].freeze
serialize :properties, JSON # rubocop:disable Cop/ActiveRecordSerialize serialize :properties, JSON # rubocop:disable Cop/ActiveRecordSerialize
default_value_for :active, false default_value_for :active, false
...@@ -46,6 +57,7 @@ class Service < ApplicationRecord ...@@ -46,6 +57,7 @@ class Service < ApplicationRecord
scope :active, -> { where(active: true) } scope :active, -> { where(active: true) }
scope :without_defaults, -> { where(default: false) } scope :without_defaults, -> { where(default: false) }
scope :by_type, -> (type) { where(type: type) } scope :by_type, -> (type) { where(type: type) }
scope :by_active_flag, -> (flag) { where(active: flag) }
scope :templates, -> { where(template: true, type: available_services_types) } scope :templates, -> { where(template: true, type: available_services_types) }
scope :instances, -> { where(instance: true, type: available_services_types) } scope :instances, -> { where(instance: true, type: available_services_types) }
...@@ -295,51 +307,30 @@ class Service < ApplicationRecord ...@@ -295,51 +307,30 @@ class Service < ApplicationRecord
end end
def self.available_services_names def self.available_services_names
service_names = %w[ service_names = services_names
alerts service_names += dev_services_names
asana
assembla
bamboo
bugzilla
buildkite
campfire
custom_issue_tracker
discord
drone_ci
emails_on_push
external_wiki
flowdock
hangouts_chat
hipchat
irker
jira
mattermost
mattermost_slash_commands
microsoft_teams
packagist
pipelines_email
pivotaltracker
prometheus
pushover
redmine
slack
slack_slash_commands
teamcity
unify_circuit
youtrack
]
if Rails.env.development?
service_names += %w[mock_ci mock_deployment mock_monitoring]
end
service_names.sort_by(&:downcase) service_names.sort_by(&:downcase)
end end
def self.services_names
SERVICE_NAMES
end
def self.dev_services_names
return [] unless Rails.env.development?
DEV_SERVICE_NAMES
end
def self.available_services_types def self.available_services_types
available_services_names.map { |service_name| "#{service_name}_service".camelize } available_services_names.map { |service_name| "#{service_name}_service".camelize }
end end
def self.services_types
services_names.map { |service_name| "#{service_name}_service".camelize }
end
def self.build_from_template(project_id, template) def self.build_from_template(project_id, template)
service = template.dup service = template.dup
......
---
title: Expose basic project services attributes through GraphQL
merge_request: 28234
author:
type: added
# Checks for duplicate words, like `the the` or `and and`.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: repetition
message: '"%s" is repeated.'
level: error
alpha: true
tokens:
- '[^\s]+'
...@@ -4,7 +4,7 @@ type: reference ...@@ -4,7 +4,7 @@ type: reference
# LDAP Additions in GitLab EE **(STARTER ONLY)** # LDAP Additions in GitLab EE **(STARTER ONLY)**
This section documents LDAP features specific to to GitLab Enterprise Edition This section documents LDAP features specific to GitLab Enterprise Edition
[Starter](https://about.gitlab.com/pricing/#self-managed) and above. [Starter](https://about.gitlab.com/pricing/#self-managed) and above.
For documentation relevant to both Community Edition and Enterprise Edition, For documentation relevant to both Community Edition and Enterprise Edition,
......
...@@ -227,7 +227,7 @@ uid: John ...@@ -227,7 +227,7 @@ uid: John
There's a lot here, so let's go over what could be helpful when debugging. There's a lot here, so let's go over what could be helpful when debugging.
First, GitLab will look for all users that have have previously First, GitLab will look for all users that have previously
logged in with LDAP and iterate on them. Each user's sync will start with logged in with LDAP and iterate on them. Each user's sync will start with
the following line that contains the user's username and email, as they the following line that contains the user's username and email, as they
exist in GitLab now: exist in GitLab now:
......
...@@ -498,7 +498,7 @@ the configuration option `lowercase_usernames`. By default, this configuration o ...@@ -498,7 +498,7 @@ the configuration option `lowercase_usernames`. By default, this configuration o
## Disable LDAP web sign in ## Disable LDAP web sign in
It can be be useful to prevent using LDAP credentials through the web UI when It can be useful to prevent using LDAP credentials through the web UI when
an alternative such as SAML is preferred. This allows LDAP to be used for group an alternative such as SAML is preferred. This allows LDAP to be used for group
sync, while also allowing your SAML identity provider to handle additional sync, while also allowing your SAML identity provider to handle additional
checks like custom 2FA. checks like custom 2FA.
......
...@@ -25,7 +25,7 @@ To enable external storage of merge request diffs, follow the instructions below ...@@ -25,7 +25,7 @@ To enable external storage of merge request diffs, follow the instructions below
gitlab_rails['external_diffs_enabled'] = true gitlab_rails['external_diffs_enabled'] = true
``` ```
1. _The external diffs will be stored in in 1. _The external diffs will be stored in
`/var/opt/gitlab/gitlab-rails/shared/external-diffs`._ To change the path, `/var/opt/gitlab/gitlab-rails/shared/external-diffs`._ To change the path,
for example, to `/mnt/storage/external-diffs`, edit `/etc/gitlab/gitlab.rb` for example, to `/mnt/storage/external-diffs`, edit `/etc/gitlab/gitlab.rb`
and add the following line: and add the following line:
......
...@@ -21,7 +21,7 @@ part of a source installation and their configuration instructions for scaling. ...@@ -21,7 +21,7 @@ part of a source installation and their configuration instructions for scaling.
|-----------|-------------|----------------------------| |-----------|-------------|----------------------------|
| [PostgreSQL](../../development/architecture.md#postgresql) | Database | [PostgreSQL configuration](https://docs.gitlab.com/omnibus/settings/database.html) | | [PostgreSQL](../../development/architecture.md#postgresql) | Database | [PostgreSQL configuration](https://docs.gitlab.com/omnibus/settings/database.html) |
| [Redis](../../development/architecture.md#redis) | Key/value store for fast data lookup and caching | [Redis configuration](../high_availability/redis.md) | | [Redis](../../development/architecture.md#redis) | Key/value store for fast data lookup and caching | [Redis configuration](../high_availability/redis.md) |
| [GitLab application services](../../development/architecture.md#unicorn) | Unicorn/Puma, Workhorse, GitLab Shell - serves front-end requests requests (UI, API, Git over HTTP/SSH) | [GitLab app scaling configuration](../high_availability/gitlab.md) | | [GitLab application services](../../development/architecture.md#unicorn) | Unicorn/Puma, Workhorse, GitLab Shell - serves front-end requests (UI, API, Git over HTTP/SSH) | [GitLab app scaling configuration](../high_availability/gitlab.md) |
| [PgBouncer](../../development/architecture.md#pgbouncer) | Database connection pooler | [PgBouncer configuration](../high_availability/pgbouncer.md#running-pgbouncer-as-part-of-a-non-ha-gitlab-installation) **(PREMIUM ONLY)** | | [PgBouncer](../../development/architecture.md#pgbouncer) | Database connection pooler | [PgBouncer configuration](../high_availability/pgbouncer.md#running-pgbouncer-as-part-of-a-non-ha-gitlab-installation) **(PREMIUM ONLY)** |
| [Sidekiq](../../development/architecture.md#sidekiq) | Asynchronous/background jobs | [Sidekiq configuration](../high_availability/sidekiq.md) | | [Sidekiq](../../development/architecture.md#sidekiq) | Asynchronous/background jobs | [Sidekiq configuration](../high_availability/sidekiq.md) |
| [Gitaly](../../development/architecture.md#gitaly) | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#running-gitaly-on-its-own-server) | | [Gitaly](../../development/architecture.md#gitaly) | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#running-gitaly-on-its-own-server) |
......
...@@ -241,7 +241,7 @@ separate Rails process to debug the issue: ...@@ -241,7 +241,7 @@ separate Rails process to debug the issue:
app.get 'https://gitlab.com/gitlab-org/gitlab-foss/issues/1?private_token=123456' app.get 'https://gitlab.com/gitlab-org/gitlab-foss/issues/1?private_token=123456'
``` ```
1. In a new window, run `top`. It should show this ruby process using 100% CPU. Write down the PID. 1. In a new window, run `top`. It should show this Ruby process using 100% CPU. Write down the PID.
1. Follow step 2 from the previous section on using gdb. 1. Follow step 2 from the previous section on using gdb.
### GitLab: API is not accessible ### GitLab: API is not accessible
...@@ -275,4 +275,4 @@ The output in `/tmp/unicorn.txt` may help diagnose the root cause. ...@@ -275,4 +275,4 @@ The output in `/tmp/unicorn.txt` may help diagnose the root cause.
## More information ## More information
- [Debugging Stuck Ruby Processes](https://blog.newrelic.com/engineering/debugging-stuck-ruby-processes-what-to-do-before-you-kill-9/) - [Debugging Stuck Ruby Processes](https://blog.newrelic.com/engineering/debugging-stuck-ruby-processes-what-to-do-before-you-kill-9/)
- [Cheatsheet of using gdb and ruby processes](gdb-stuck-ruby.txt) - [Cheatsheet of using gdb and Ruby processes](gdb-stuck-ruby.txt)
...@@ -111,7 +111,7 @@ statement_timeout = 15s ...@@ -111,7 +111,7 @@ statement_timeout = 15s
idle_in_transaction_session_timeout = 60s idle_in_transaction_session_timeout = 60s
``` ```
Quoting from from issue [#1](https://gitlab.com/gitlab-org/gitlab/issues/30528): Quoting from issue [#1](https://gitlab.com/gitlab-org/gitlab/issues/30528):
> "If a deadlock is hit, and we resolve it through aborting the transaction after a short period, then the retry mechanisms we already have will make the deadlocked piece of work try again, and it's unlikely we'll deadlock multiple times in a row." > "If a deadlock is hit, and we resolve it through aborting the transaction after a short period, then the retry mechanisms we already have will make the deadlocked piece of work try again, and it's unlikely we'll deadlock multiple times in a row."
......
...@@ -50,7 +50,7 @@ If you have the problems listed above, add your certificate to `/etc/gitlab/trus ...@@ -50,7 +50,7 @@ If you have the problems listed above, add your certificate to `/etc/gitlab/trus
Besides getting the errors mentioned in Besides getting the errors mentioned in
[Using an internal CA certificate with GitLab](ssl.md#using-an-internal-ca-certificate-with-gitlab), [Using an internal CA certificate with GitLab](ssl.md#using-an-internal-ca-certificate-with-gitlab),
your CI pipelines may stuck stuck in `Pending` status. In the runner logs you may see the below error: your CI pipelines may get stuck in `Pending` status. In the runner logs you may see the below error:
```shell ```shell
Dec 6 02:43:17 runner-host01 gitlab-runner[15131]: #033[0;33mWARNING: Checking for jobs... failed Dec 6 02:43:17 runner-host01 gitlab-runner[15131]: #033[0;33mWARNING: Checking for jobs... failed
......
...@@ -138,7 +138,7 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git ...@@ -138,7 +138,7 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git
These endpoints require group maintainer access or higher. These endpoints require group maintainer access or higher.
### List group deploy deploy tokens ### List group deploy tokens
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9. > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
......
...@@ -552,7 +552,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab ...@@ -552,7 +552,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab
### Create new epic thread ### Create new epic thread
Creates a new thread to a single group epic. This is similar to creating Creates a new thread to a single group epic. This is similar to creating
a note but but other comments (replies) can be added to it later. a note but other comments (replies) can be added to it later.
```plaintext ```plaintext
POST /groups/:id/epics/:epic_id/discussions POST /groups/:id/epics/:epic_id/discussions
......
...@@ -120,7 +120,7 @@ Example response: ...@@ -120,7 +120,7 @@ Example response:
## Create and assign a child epic ## Create and assign a child epic
Creates a a new epic and associates it with provided parent epic. The response is LinkedEpic object. Creates a new epic and associates it with provided parent epic. The response is LinkedEpic object.
```plaintext ```plaintext
POST /groups/:id/epics/:epic_iid/epics POST /groups/:id/epics/:epic_iid/epics
......
...@@ -73,7 +73,7 @@ Root-level queries are defined in ...@@ -73,7 +73,7 @@ Root-level queries are defined in
GitLab supports batching queries into a single request using GitLab supports batching queries into a single request using
[apollo-link-batch-http](https://www.apollographql.com/docs/link/links/batch-http/). More [apollo-link-batch-http](https://www.apollographql.com/docs/link/links/batch-http/). More
information about multiplexed queries is also available for information about multiplexed queries is also available for
[graphql-ruby](https://graphql-ruby.org/queries/multiplex.html) the [GraphQL Ruby](https://graphql-ruby.org/queries/multiplex.html), the
library GitLab uses on the backend. library GitLab uses on the backend.
## Reference ## Reference
......
...@@ -138,6 +138,18 @@ type AwardEmoji { ...@@ -138,6 +138,18 @@ type AwardEmoji {
user: User! user: User!
} }
type BaseService implements Service {
"""
Indicates if the service is active
"""
active: Boolean
"""
Class name of the service
"""
type: String
}
type Blob implements Entry { type Blob implements Entry {
""" """
Flat path of the entry Flat path of the entry
...@@ -4246,6 +4258,18 @@ type JiraImportStartPayload { ...@@ -4246,6 +4258,18 @@ type JiraImportStartPayload {
jiraImport: JiraImport jiraImport: JiraImport
} }
type JiraService implements Service {
"""
Indicates if the service is active
"""
active: Boolean
"""
Class name of the service
"""
type: String
}
type Label { type Label {
""" """
Background color of the label Background color of the label
...@@ -6410,6 +6434,41 @@ type Project { ...@@ -6410,6 +6434,41 @@ type Project {
""" """
serviceDeskEnabled: Boolean serviceDeskEnabled: Boolean
"""
Project services
"""
services(
"""
Indicates if the service is active
"""
active: Boolean
"""
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
"""
Class name of the service
"""
type: ServiceType
): ServiceConnection
""" """
Indicates if Shared Runners are enabled for the project Indicates if Shared Runners are enabled for the project
""" """
...@@ -7637,6 +7696,90 @@ type SentryErrorTags { ...@@ -7637,6 +7696,90 @@ type SentryErrorTags {
logger: String logger: String
} }
interface Service {
"""
Indicates if the service is active
"""
active: Boolean
"""
Class name of the service
"""
type: String
}
"""
The connection type for Service.
"""
type ServiceConnection {
"""
A list of edges.
"""
edges: [ServiceEdge]
"""
A list of nodes.
"""
nodes: [Service]
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type ServiceEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: Service
}
enum ServiceType {
ALERTS_SERVICE
ASANA_SERVICE
ASSEMBLA_SERVICE
BAMBOO_SERVICE
BUGZILLA_SERVICE
BUILDKITE_SERVICE
CAMPFIRE_SERVICE
CUSTOM_ISSUE_TRACKER_SERVICE
DISCORD_SERVICE
DRONE_CI_SERVICE
EMAILS_ON_PUSH_SERVICE
EXTERNAL_WIKI_SERVICE
FLOWDOCK_SERVICE
GITHUB_SERVICE
HANGOUTS_CHAT_SERVICE
HIPCHAT_SERVICE
IRKER_SERVICE
JENKINS_DEPRECATED_SERVICE
JENKINS_SERVICE
JIRA_SERVICE
MATTERMOST_SERVICE
MATTERMOST_SLASH_COMMANDS_SERVICE
MICROSOFT_TEAMS_SERVICE
PACKAGIST_SERVICE
PIPELINES_EMAIL_SERVICE
PIVOTALTRACKER_SERVICE
PROMETHEUS_SERVICE
PUSHOVER_SERVICE
REDMINE_SERVICE
SLACK_SERVICE
SLACK_SLASH_COMMANDS_SERVICE
TEAMCITY_SERVICE
UNIFY_CIRCUIT_SERVICE
YOUTRACK_SERVICE
}
""" """
Represents a snippet entry Represents a snippet entry
""" """
......
...@@ -408,6 +408,51 @@ ...@@ -408,6 +408,51 @@
"enumValues": null, "enumValues": null,
"possibleTypes": null "possibleTypes": null
}, },
{
"kind": "OBJECT",
"name": "BaseService",
"description": null,
"fields": [
{
"name": "active",
"description": "Indicates if the service is active",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "type",
"description": "Class name of the service",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
{
"kind": "INTERFACE",
"name": "Service",
"ofType": null
}
],
"enumValues": null,
"possibleTypes": null
},
{ {
"kind": "OBJECT", "kind": "OBJECT",
"name": "Blob", "name": "Blob",
...@@ -12061,6 +12106,51 @@ ...@@ -12061,6 +12106,51 @@
"enumValues": null, "enumValues": null,
"possibleTypes": null "possibleTypes": null
}, },
{
"kind": "OBJECT",
"name": "JiraService",
"description": null,
"fields": [
{
"name": "active",
"description": "Indicates if the service is active",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "type",
"description": "Class name of the service",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
{
"kind": "INTERFACE",
"name": "Service",
"ofType": null
}
],
"enumValues": null,
"possibleTypes": null
},
{ {
"kind": "OBJECT", "kind": "OBJECT",
"name": "Label", "name": "Label",
...@@ -19141,6 +19231,79 @@ ...@@ -19141,6 +19231,79 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "services",
"description": "Project services",
"args": [
{
"name": "active",
"description": "Indicates if the service is active",
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"defaultValue": null
},
{
"name": "type",
"description": "Class name of the service",
"type": {
"kind": "ENUM",
"name": "ServiceType",
"ofType": null
},
"defaultValue": null
},
{
"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": "ServiceConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "sharedRunnersEnabled", "name": "sharedRunnersEnabled",
"description": "Indicates if Shared Runners are enabled for the project", "description": "Indicates if Shared Runners are enabled for the project",
...@@ -23018,6 +23181,383 @@ ...@@ -23018,6 +23181,383 @@
"enumValues": null, "enumValues": null,
"possibleTypes": null "possibleTypes": null
}, },
{
"kind": "INTERFACE",
"name": "Service",
"description": null,
"fields": [
{
"name": "active",
"description": "Indicates if the service is active",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "type",
"description": "Class name of the service",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": null,
"enumValues": null,
"possibleTypes": [
{
"kind": "OBJECT",
"name": "BaseService",
"ofType": null
},
{
"kind": "OBJECT",
"name": "JiraService",
"ofType": null
}
]
},
{
"kind": "OBJECT",
"name": "ServiceConnection",
"description": "The connection type for Service.",
"fields": [
{
"name": "edges",
"description": "A list of edges.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "ServiceEdge",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "nodes",
"description": "A list of nodes.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "INTERFACE",
"name": "Service",
"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": "ServiceEdge",
"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": "INTERFACE",
"name": "Service",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "ENUM",
"name": "ServiceType",
"description": null,
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": [
{
"name": "ALERTS_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "ASANA_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "ASSEMBLA_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "BAMBOO_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "BUGZILLA_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "BUILDKITE_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "CAMPFIRE_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "CUSTOM_ISSUE_TRACKER_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "DISCORD_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "DRONE_CI_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "EMAILS_ON_PUSH_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "EXTERNAL_WIKI_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "FLOWDOCK_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "HANGOUTS_CHAT_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "HIPCHAT_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "IRKER_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "JIRA_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "MATTERMOST_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "MATTERMOST_SLASH_COMMANDS_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "MICROSOFT_TEAMS_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "PACKAGIST_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "PIPELINES_EMAIL_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "PIVOTALTRACKER_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "PROMETHEUS_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "PUSHOVER_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "REDMINE_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "SLACK_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "SLACK_SLASH_COMMANDS_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "TEAMCITY_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "UNIFY_CIRCUIT_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "YOUTRACK_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "GITHUB_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "JENKINS_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "JENKINS_DEPRECATED_SERVICE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
},
{ {
"kind": "OBJECT", "kind": "OBJECT",
"name": "Snippet", "name": "Snippet",
......
...@@ -49,6 +49,13 @@ An emoji awarded by a user. ...@@ -49,6 +49,13 @@ An emoji awarded by a user.
| `unicodeVersion` | String! | The unicode version for this emoji | | `unicodeVersion` | String! | The unicode version for this emoji |
| `user` | User! | The user who awarded the emoji | | `user` | User! | The user who awarded the emoji |
## BaseService
| Name | Type | Description |
| --- | ---- | ---------- |
| `active` | Boolean | Indicates if the service is active |
| `type` | String | Class name of the service |
## Blob ## Blob
| Name | Type | Description | | Name | Type | Description |
...@@ -624,6 +631,13 @@ Autogenerated return type of JiraImportStart ...@@ -624,6 +631,13 @@ Autogenerated return type of JiraImportStart
| `errors` | String! => Array | Reasons why the mutation failed. | | `errors` | String! => Array | Reasons why the mutation failed. |
| `jiraImport` | JiraImport | The Jira import data after mutation | | `jiraImport` | JiraImport | The Jira import data after mutation |
## JiraService
| Name | Type | Description |
| --- | ---- | ---------- |
| `active` | Boolean | Indicates if the service is active |
| `type` | String | Class name of the service |
## Label ## Label
| Name | Type | Description | | Name | Type | Description |
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41766) in GitLab 11.7. > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41766) in GitLab 11.7.
Using this API you can manipulate GitLab's [Release](../../user/project/releases/index.md) links. For manipulating other Release assets, see [Release API](index.md). Using this API you can manipulate GitLab's [Release](../../user/project/releases/index.md) links. For manipulating other Release assets, see [Release API](index.md).
GitLab supports links links to `http`, `https`, and `ftp` assets. GitLab supports links to `http`, `https`, and `ftp` assets.
## Get links ## Get links
......
...@@ -42,7 +42,7 @@ GET /runners?tag_list=tag1,tag2 ...@@ -42,7 +42,7 @@ GET /runners?tag_list=tag1,tag2
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided | | `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` | | `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` | | `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
| `tag_list` | string array | no | List of of the runner's tags | | `tag_list` | string array | no | List of the runner's tags |
```shell ```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/runners" curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/runners"
...@@ -93,7 +93,7 @@ GET /runners/all?tag_list=tag1,tag2 ...@@ -93,7 +93,7 @@ GET /runners/all?tag_list=tag1,tag2
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online`, `offline`; showing all runners if none provided | | `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online`, `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` | | `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` | | `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
| `tag_list` | string array | no | List of of the runner's tags | | `tag_list` | string array | no | List of the runner's tags |
```shell ```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/runners/all" curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/runners/all"
...@@ -385,7 +385,7 @@ GET /projects/:id/runners?tag_list=tag1,tag2 ...@@ -385,7 +385,7 @@ GET /projects/:id/runners?tag_list=tag1,tag2
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided | | `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` | | `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` | | `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
| `tag_list` | string array | no | List of of the runner's tags | | `tag_list` | string array | no | List of the runner's tags |
```shell ```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/9/runners" curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/9/runners"
...@@ -486,7 +486,7 @@ GET /groups/:id/runners?tag_list=tag1,tag2 ...@@ -486,7 +486,7 @@ GET /groups/:id/runners?tag_list=tag1,tag2
| `id` | integer | yes | The ID of the group owned by the authenticated user | | `id` | integer | yes | The ID of the group owned by the authenticated user |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` | | `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` | | `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
| `tag_list` | string array | no | List of of the runner's tags | | `tag_list` | string array | no | List of the runner's tags |
```shell ```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/9/runners" curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/9/runners"
......
...@@ -277,7 +277,7 @@ The `releases` directory will hold all our deployments: ...@@ -277,7 +277,7 @@ The `releases` directory will hold all our deployments:
... ...
``` ```
While our project grows, its Git history will be very very long over time. While our project grows, its Git history will be very long over time.
Since we are creating a directory per release, it might not be necessary to have the history of the project downloaded for each release. Since we are creating a directory per release, it might not be necessary to have the history of the project downloaded for each release.
The `--depth 1` option is a great solution which saves systems time and disk space as well. The `--depth 1` option is a great solution which saves systems time and disk space as well.
......
...@@ -77,6 +77,6 @@ gitlab-runner register \ ...@@ -77,6 +77,6 @@ gitlab-runner register \
--docker-services latest --docker-services latest
``` ```
With the command above, you create a Runner that uses the [ruby:2.6](https://hub.docker.com/_/ruby) image and uses a [PostgreSQL](https://hub.docker.com/_/postgres) database. With the command above, you create a Runner that uses the [`ruby:2.6`](https://hub.docker.com/_/ruby) image and uses a [PostgreSQL](https://hub.docker.com/_/postgres) database.
To access the PostgreSQL database, connect to `host: postgres` as user `postgres` with no password. To access the PostgreSQL database, connect to `host: postgres` as user `postgres` with no password.
...@@ -12,7 +12,7 @@ last_updated: 2019-03-06 ...@@ -12,7 +12,7 @@ last_updated: 2019-03-06
[Phoenix](https://www.phoenixframework.org/) is a web development framework written in [Elixir](https://elixir-lang.org), which is a [Phoenix](https://www.phoenixframework.org/) is a web development framework written in [Elixir](https://elixir-lang.org), which is a
functional language designed for productivity and maintainability that runs on the functional language designed for productivity and maintainability that runs on the
[Erlang VM](https://www.erlang.org). Erlang VM is really really fast and can handle very large numbers of [Erlang VM](https://www.erlang.org). Erlang VM is really fast and can handle very large numbers of
simultaneous users. simultaneous users.
That's why we're hearing so much about Phoenix today. That's why we're hearing so much about Phoenix today.
...@@ -389,7 +389,7 @@ source project being watched and contributed by the community, it is really impo ...@@ -389,7 +389,7 @@ source project being watched and contributed by the community, it is really impo
code permanently working. GitLab CI/CD is a time saving powerful tool to help us maintain our code code permanently working. GitLab CI/CD is a time saving powerful tool to help us maintain our code
organized and working. organized and working.
As we could see in this post, GitLab CI/CD is really really easy to configure and use. We have [many As we could see in this post, GitLab CI/CD is really easy to configure and use. We have [many
other reasons](https://about.gitlab.com/blog/2015/02/03/7-reasons-why-you-should-be-using-ci/) to keep other reasons](https://about.gitlab.com/blog/2015/02/03/7-reasons-why-you-should-be-using-ci/) to keep
using GitLab CI/CD. The benefits to our teams will be huge! using GitLab CI/CD. The benefits to our teams will be huge!
......
...@@ -475,7 +475,7 @@ to an updated status. ...@@ -475,7 +475,7 @@ to an updated status.
This functionality is only available: This functionality is only available:
- For users with at least Developer access. - For users with at least Developer access.
- If the the stage contains [manual actions](#manual-actions-from-pipeline-graphs). - If the stage contains [manual actions](#manual-actions-from-pipeline-graphs).
### Deleting a single pipeline ### Deleting a single pipeline
......
...@@ -117,7 +117,7 @@ job log using a regular expression. In the pipelines settings, search for the ...@@ -117,7 +117,7 @@ job log using a regular expression. In the pipelines settings, search for the
![Pipelines settings test coverage](img/pipelines_settings_test_coverage.png) ![Pipelines settings test coverage](img/pipelines_settings_test_coverage.png)
Leave blank if you want to disable it or enter a ruby regular expression. You Leave blank if you want to disable it or enter a Ruby regular expression. You
can use <https://rubular.com> to test your regex. can use <https://rubular.com> to test your regex.
If the pipeline succeeds, the coverage is shown in the merge request widget and If the pipeline succeeds, the coverage is shown in the merge request widget and
......
...@@ -429,7 +429,7 @@ Once you set them, they will be available for all subsequent pipelines. ...@@ -429,7 +429,7 @@ Once you set them, they will be available for all subsequent pipelines.
You can limit the environment scope of a variable by You can limit the environment scope of a variable by
[defining which environments](../environments.md) it can be available for. [defining which environments](../environments.md) it can be available for.
To learn more about about scoping environments, see [Scoping environments with specs](../environments.md#scoping-environments-with-specs). To learn more about scoping environments, see [Scoping environments with specs](../environments.md#scoping-environments-with-specs).
### Deployment environment variables ### Deployment environment variables
......
...@@ -318,25 +318,25 @@ For: ...@@ -318,25 +318,25 @@ For:
An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services). For more information, see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services).
#### `services:alias` #### `services:alias`
An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services). For more information, see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services).
#### `services:entrypoint` #### `services:entrypoint`
An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services). For more information, see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services).
#### `services:command` #### `services:command`
An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services). For more information, see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services).
### `before_script` and `after_script` ### `before_script` and `after_script`
...@@ -1630,7 +1630,7 @@ The `stop_review_app` job is **required** to have the following keywords defined ...@@ -1630,7 +1630,7 @@ The `stop_review_app` job is **required** to have the following keywords defined
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/20956) in GitLab 12.8. > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/20956) in GitLab 12.8.
The `auto_stop_in` keyword is for specifying life period of the environment, The `auto_stop_in` keyword is for specifying life period of the environment,
that when expired, GitLab GitLab automatically stops them. that when expired, GitLab automatically stops them.
For example, For example,
......
...@@ -4,7 +4,7 @@ This document outlines the styleguide for GitLab's [GraphQL API](../api/graphql/ ...@@ -4,7 +4,7 @@ This document outlines the styleguide for GitLab's [GraphQL API](../api/graphql/
## How GitLab implements GraphQL ## How GitLab implements GraphQL
We use the [graphql-ruby gem](https://graphql-ruby.org/) written by [Robert Mosolgo](https://github.com/rmosolgo/). We use the [GraphQL Ruby gem](https://graphql-ruby.org/) written by [Robert Mosolgo](https://github.com/rmosolgo/).
All GraphQL queries are directed to a single endpoint All GraphQL queries are directed to a single endpoint
([`app/controllers/graphql_controller.rb#execute`](https://gitlab.com/gitlab-org/gitlab/blob/master/app%2Fcontrollers%2Fgraphql_controller.rb)), ([`app/controllers/graphql_controller.rb#execute`](https://gitlab.com/gitlab-org/gitlab/blob/master/app%2Fcontrollers%2Fgraphql_controller.rb)),
...@@ -84,7 +84,7 @@ the context. ...@@ -84,7 +84,7 @@ the context.
### Nullable fields ### Nullable fields
GraphQL allows fields to be be "nullable" or "non-nullable". The former means GraphQL allows fields to be "nullable" or "non-nullable". The former means
that `null` may be returned instead of a value of the specified type. **In that `null` may be returned instead of a value of the specified type. **In
general**, you should prefer using nullable fields to non-nullable ones, for general**, you should prefer using nullable fields to non-nullable ones, for
the following reasons: the following reasons:
...@@ -865,7 +865,7 @@ the analyzer, and the final value is also available to you. ...@@ -865,7 +865,7 @@ the analyzer, and the final value is also available to you.
[Multiplex queries](https://graphql-ruby.org/queries/multiplex.html) enable [Multiplex queries](https://graphql-ruby.org/queries/multiplex.html) enable
multiple queries to be sent in a single request. This reduces the number of requests sent to the server. multiple queries to be sent in a single request. This reduces the number of requests sent to the server.
(there are custom Multiplex Query Analyzers and Multiplex Instrumentation provided by graphql-ruby). (there are custom Multiplex Query Analyzers and Multiplex Instrumentation provided by GraphQL Ruby).
### Query limits ### Query limits
...@@ -888,7 +888,7 @@ end ...@@ -888,7 +888,7 @@ end
``` ```
More about complexity: More about complexity:
[graphql-ruby docs](https://graphql-ruby.org/queries/complexity_and_depth.html) [GraphQL Ruby documentation](https://graphql-ruby.org/queries/complexity_and_depth.html).
## Documentation and Schema ## Documentation and Schema
......
...@@ -775,7 +775,7 @@ When referring to `~git` in the pictures it means the home directory of the Git ...@@ -775,7 +775,7 @@ When referring to `~git` in the pictures it means the home directory of the Git
GitLab is primarily installed within the `/home/git` user home directory as `git` user. Within the home directory is where the gitlabhq server software resides as well as the repositories (though the repository location is configurable). GitLab is primarily installed within the `/home/git` user home directory as `git` user. Within the home directory is where the gitlabhq server software resides as well as the repositories (though the repository location is configurable).
The bare repositories are located in `/home/git/repositories`. GitLab is a ruby on rails application so the particulars of the inner workings can be learned by studying how a ruby on rails application works. The bare repositories are located in `/home/git/repositories`. GitLab is a Ruby on rails application so the particulars of the inner workings can be learned by studying how a Ruby on rails application works.
To serve repositories over SSH there's an add-on application called GitLab Shell which is installed in `/home/git/gitlab-shell`. To serve repositories over SSH there's an add-on application called GitLab Shell which is installed in `/home/git/gitlab-shell`.
...@@ -794,7 +794,7 @@ GitLab has several components to operate. It requires a persistent database ...@@ -794,7 +794,7 @@ GitLab has several components to operate. It requires a persistent database
Unicorn. All these components should run as different system users to GitLab Unicorn. All these components should run as different system users to GitLab
(e.g., `postgres`, `redis` and `www-data`, instead of `git`). (e.g., `postgres`, `redis` and `www-data`, instead of `git`).
As the `git` user it starts Sidekiq and Unicorn (a simple ruby HTTP server As the `git` user it starts Sidekiq and Unicorn (a simple Ruby HTTP server
running on port `8080` by default). Under the GitLab user there are normally 4 running on port `8080` by default). Under the GitLab user there are normally 4
processes: `unicorn_rails master` (1 process), `unicorn_rails worker` processes: `unicorn_rails master` (1 process), `unicorn_rails worker`
(2 processes), `sidekiq` (1 process). (2 processes), `sidekiq` (1 process).
......
...@@ -422,7 +422,7 @@ Request help from the Technical Writing team if you: ...@@ -422,7 +422,7 @@ Request help from the Technical Writing team if you:
To request help: To request help:
1. Locate the the Technical Writer for the relevant 1. Locate the Technical Writer for the relevant
[DevOps stage group](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments). [DevOps stage group](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments).
1. Either: 1. Either:
- If urgent help is required, directly assign the Technical Writer in the issue or in the merge request. - If urgent help is required, directly assign the Technical Writer in the issue or in the merge request.
......
...@@ -98,7 +98,8 @@ Slack: ...@@ -98,7 +98,8 @@ Slack:
This will enable the feature for GitLab.com, with `new_navigation_bar` being the This will enable the feature for GitLab.com, with `new_navigation_bar` being the
name of the feature. name of the feature.
This command does *not* enable the feature for 25% of the total users. Instead, when the feature is checked with `enabled?`, it will return `true` 25% of the time. This command does *not* enable the feature for 25% of the total users.
Instead, when the feature is checked with `enabled?`, it will return `true` 25% of the time.
If you are not certain what percentages to use, simply use the following steps: If you are not certain what percentages to use, simply use the following steps:
......
...@@ -58,7 +58,7 @@ of Gitaly and `gitaly-proto` during testing and development. ...@@ -58,7 +58,7 @@ of Gitaly and `gitaly-proto` during testing and development.
- See [below](#running-tests-with-a-locally-modified-version-of-gitaly) for instructions on running GitLab CE tests with a modified version of Gitaly. - See [below](#running-tests-with-a-locally-modified-version-of-gitaly) for instructions on running GitLab CE tests with a modified version of Gitaly.
- In GDK run `gdk install` and restart `gdk run` (or `gdk run app`) to use a locally modified Gitaly version for development - In GDK run `gdk install` and restart `gdk run` (or `gdk run app`) to use a locally modified Gitaly version for development
### Gitaly-ruby ### `gitaly-ruby`
It is possible to implement and test RPC's in Gitaly using Ruby code, It is possible to implement and test RPC's in Gitaly using Ruby code,
in in
......
...@@ -37,7 +37,7 @@ For instance, it is common practice to use `before_script` to install system lib ...@@ -37,7 +37,7 @@ For instance, it is common practice to use `before_script` to install system lib
a particular project needs before performing SAST or Dependency Scanning. a particular project needs before performing SAST or Dependency Scanning.
Similarly, [`after_script`](../../ci/yaml/README.md#before_script-and-after_script) Similarly, [`after_script`](../../ci/yaml/README.md#before_script-and-after_script)
should not not be used in the job definition, because it may be overridden by users. should not be used in the job definition, because it may be overridden by users.
### Stage ### Stage
...@@ -403,7 +403,7 @@ It may also have an `end_line`, a `class`, and a `method`. ...@@ -403,7 +403,7 @@ It may also have an `end_line`, a `class`, and a `method`.
For instance, here is the `location` object for a security flaw found For instance, here is the `location` object for a security flaw found
at line `41` of `src/main/java/com/gitlab/example/App.java`, at line `41` of `src/main/java/com/gitlab/example/App.java`,
in the the `generateSecretToken` method of the `com.gitlab.security_products.tests.App` Java class: in the `generateSecretToken` method of the `com.gitlab.security_products.tests.App` Java class:
```json ```json
{ {
......
...@@ -375,7 +375,7 @@ Examples: ...@@ -375,7 +375,7 @@ Examples:
In such cases it's rather expected that this is either misuse In such cases it's rather expected that this is either misuse
or abuse of the feature. Lack of the upper limit can result or abuse of the feature. Lack of the upper limit can result
in service degradation as the system will try to process all schedules in service degradation as the system will try to process all schedules
assigned the the project. assigned the project.
1. GitLab CI/CD includes: We started with the limit of maximum of 50 nested includes. 1. GitLab CI/CD includes: We started with the limit of maximum of 50 nested includes.
We understood that performance of the feature was acceptable at that level. We understood that performance of the feature was acceptable at that level.
......
...@@ -16,7 +16,7 @@ Your feature flag can now be: ...@@ -16,7 +16,7 @@ Your feature flag can now be:
- [Made available to the frontend](../feature_flags/development.md#frontend) via the `gon` - [Made available to the frontend](../feature_flags/development.md#frontend) via the `gon`
- Queried in [tests](../feature_flags/development.md#specs) - Queried in [tests](../feature_flags/development.md#specs)
- Queried in HAML templates and ruby files via the `Feature.enabled?(:my_shiny_new_feature_flag)` method - Queried in HAML templates and Ruby files via the `Feature.enabled?(:my_shiny_new_feature_flag)` method
### More on feature flags ### More on feature flags
......
...@@ -270,4 +270,4 @@ To generate GraphQL schema files based on the GitLab schema, run: ...@@ -270,4 +270,4 @@ To generate GraphQL schema files based on the GitLab schema, run:
bundle exec rake gitlab:graphql:schema:dump bundle exec rake gitlab:graphql:schema:dump
``` ```
This uses graphql-ruby's built-in Rake tasks to generate files in both [IDL](https://www.prisma.io/blog/graphql-sdl-schema-definition-language-6755bcb9ce51) and JSON formats. This uses GraphQL Ruby's built-in Rake tasks to generate files in both [IDL](https://www.prisma.io/blog/graphql-sdl-schema-definition-language-6755bcb9ce51) and JSON formats.
...@@ -74,7 +74,10 @@ point of failure and so the screenshot would not be captured at the right moment ...@@ -74,7 +74,10 @@ point of failure and so the screenshot would not be captured at the right moment
All QA tests expect to be able to log in at the start of the test. All QA tests expect to be able to log in at the start of the test.
That's not possible if a test leaves the browser logged in when it finishes. Normally this isn't a problem because [Capybara resets the session after each test](https://github.com/teamcapybara/capybara/blob/9ebc5033282d40c73b0286e60217515fd1bb0b5d/lib/capybara/rspec.rb#L18). But Capybara does that in an `after` block, so when a test logs in in an `after(:context)` block, the browser returns to a logged in state *after* Capybara had logged it out. And so the next test will fail. That's not possible if a test leaves the browser logged in when it finishes. Normally this isn't a
problem because [Capybara resets the session after each test](https://github.com/teamcapybara/capybara/blob/9ebc5033282d40c73b0286e60217515fd1bb0b5d/lib/capybara/rspec.rb#L18).
But Capybara does that in an `after` block, so when a test logs in within an `after(:context)` block,
the browser returns to a logged in state *after* Capybara had logged it out. And so the next test will fail.
For an example see: <https://gitlab.com/gitlab-org/gitlab/issues/34736> For an example see: <https://gitlab.com/gitlab-org/gitlab/issues/34736>
......
...@@ -458,7 +458,7 @@ By defining the `api_get_path` method, we **would** allow for the [`ApiFabricato ...@@ -458,7 +458,7 @@ By defining the `api_get_path` method, we **would** allow for the [`ApiFabricato
By defining the `api_post_path` method, we allow for the [`ApiFabricator`](https://gitlab.com/gitlab-org/gitlab/blob/master/qa/qa/resource/api_fabricator.rb) module to know which path to use to create a new label in a specific project. By defining the `api_post_path` method, we allow for the [`ApiFabricator`](https://gitlab.com/gitlab-org/gitlab/blob/master/qa/qa/resource/api_fabricator.rb) module to know which path to use to create a new label in a specific project.
By defining the `api_post_body` method, we we allow for the [`ApiFabricator.api_post`](https://gitlab.com/gitlab-org/gitlab/blob/a9177ca1812bac57e2b2fa4560e1d5dd8ffac38b/qa/qa/resource/api_fabricator.rb#L68) method to know which data to send when making the `POST` request. By defining the `api_post_body` method, we allow for the [`ApiFabricator.api_post`](https://gitlab.com/gitlab-org/gitlab/blob/a9177ca1812bac57e2b2fa4560e1d5dd8ffac38b/qa/qa/resource/api_fabricator.rb#L68) method to know which data to send when making the `POST` request.
> Notice that we pass both `color` and `name` attributes in the `api_post_body` since [those are required](../../../api/labels.md#create-a-new-label). Also, notice that we keep them alphabetically organized. > Notice that we pass both `color` and `name` attributes in the `api_post_body` since [those are required](../../../api/labels.md#create-a-new-label). Also, notice that we keep them alphabetically organized.
......
# Uploads development documentation # Uploads development documentation
[GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) has special rules for handling uploads. [GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) has special rules for handling uploads.
To prevent occupying a ruby process on I/O operations, we process the upload in workhorse, where is cheaper. To prevent occupying a Ruby process on I/O operations, we process the upload in workhorse, where is cheaper.
This process can also directly upload to object storage. This process can also directly upload to object storage.
## The problem description ## The problem description
...@@ -40,7 +40,7 @@ We have three challenges here: performance, availability, and scalability. ...@@ -40,7 +40,7 @@ We have three challenges here: performance, availability, and scalability.
### Performance ### Performance
Rails process are expensive in terms of both CPU and memory. Ruby [global interpreter lock](https://en.wikipedia.org/wiki/Global_interpreter_lock) adds to cost too because the ruby process will spend time on I/O operations on step 3 causing incoming requests to pile up. Rails process are expensive in terms of both CPU and memory. Ruby [global interpreter lock](https://en.wikipedia.org/wiki/Global_interpreter_lock) adds to cost too because the Ruby process will spend time on I/O operations on step 3 causing incoming requests to pile up.
In order to improve this, [disk buffered upload](#disk-buffered-upload) was implemented. With this, Rails no longer deals with writing uploaded files to disk. In order to improve this, [disk buffered upload](#disk-buffered-upload) was implemented. With this, Rails no longer deals with writing uploaded files to disk.
......
...@@ -578,7 +578,7 @@ On the EC2 dashboard: ...@@ -578,7 +578,7 @@ On the EC2 dashboard:
1. Give your image a name and description (we'll use `GitLab-Source` for both). 1. Give your image a name and description (we'll use `GitLab-Source` for both).
1. Leave everything else as default and click **Create Image** 1. Leave everything else as default and click **Create Image**
Now we have a custom AMI that we'll use to create our launch configuration the the next step. Now we have a custom AMI that we'll use to create our launch configuration the next step.
## Deploying GitLab inside an auto scaling group ## Deploying GitLab inside an auto scaling group
......
...@@ -610,7 +610,7 @@ Here are some common pitfalls and how to overcome them: ...@@ -610,7 +610,7 @@ Here are some common pitfalls and how to overcome them:
- **My single node Elasticsearch cluster status never goes from `yellow` to `green` even though everything seems to be running properly** - **My single node Elasticsearch cluster status never goes from `yellow` to `green` even though everything seems to be running properly**
**For a single node Elasticsearch cluster the functional cluster health status will be yellow** (will never be green) because the primary shard is allocated but replicas can not be as there is no other node to which Elasticsearch can assign a replica. This also applies if you are using using the **For a single node Elasticsearch cluster the functional cluster health status will be yellow** (will never be green) because the primary shard is allocated but replicas can not be as there is no other node to which Elasticsearch can assign a replica. This also applies if you are using the
[Amazon Elasticsearch](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-handling-errors.html#aes-handling-errors-yellow-cluster-status) service. [Amazon Elasticsearch](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-handling-errors.html#aes-handling-errors-yellow-cluster-status) service.
CAUTION: **Warning**: Setting the number of replicas to `0` is not something that we recommend (this is not allowed in the GitLab Elasticsearch Integration menu). If you are planning to add more Elasticsearch nodes (for a total of more than 1 Elasticsearch) the number of replicas will need to be set to an integer value larger than `0`. Failure to do so will result in lack of redundancy (losing one node will corrupt the index). CAUTION: **Warning**: Setting the number of replicas to `0` is not something that we recommend (this is not allowed in the GitLab Elasticsearch Integration menu). If you are planning to add more Elasticsearch nodes (for a total of more than 1 Elasticsearch) the number of replicas will need to be set to an integer value larger than `0`. Failure to do so will result in lack of redundancy (losing one node will corrupt the index).
......
...@@ -6,16 +6,18 @@ If correctly set up, emails that require an action will be marked in Gmail. ...@@ -6,16 +6,18 @@ If correctly set up, emails that require an action will be marked in Gmail.
![gmail_actions_button.png](img/gmail_action_buttons_for_gitlab.png) ![gmail_actions_button.png](img/gmail_action_buttons_for_gitlab.png)
To get this functioning, you need to be registered with Google. To get this functioning, you need to be registered with Google. For instructions, see
[See how to register with Google in this document.](https://developers.google.com/gmail/markup/registering-with-google) [Register with Google](https://developers.google.com/gmail/markup/registering-with-google).
*This process has a lot of steps so make sure that you fulfill all requirements set by Google.* *This process has a lot of steps so make sure that you fulfill all requirements set by Google.*
*Your application will be rejected by Google if you fail to do so.* *Your application will be rejected by Google if you fail to do so.*
Pay close attention to: In particular, note:
- Email account used by GitLab to send notification emails needs to have "Consistent history of sending a high volume of mail from your domain (order of hundred emails a day minimum to Gmail) for a few weeks at least". - The email account used by GitLab to send notification emails must:
- "A very very low rate of spam complaints from users." - Have a "Consistent history of sending a high volume of mail from your domain
(order of hundred emails a day minimum to Gmail) for a few weeks at least".
- Have a very low rate of spam complaints from users.
- Emails must be authenticated via DKIM or SPF. - Emails must be authenticated via DKIM or SPF.
- Before sending the final form ("Gmail Schema Whitelist Request"), you must send a real email from your production server. This means that you will have to find a way to send this email from the email address you are registering. You can do this by, for example, forwarding the real email from the email address you are registering or going into the rails console on the GitLab server and triggering the email sending from there. - Before sending the final form ("Gmail Schema Whitelist Request"), you must send a real email from your production server. This means that you will have to find a way to send this email from the email address you are registering. You can do this by, for example, forwarding the real email from the email address you are registering or going into the rails console on the GitLab server and triggering the email sending from there.
......
...@@ -90,7 +90,7 @@ based on *all* of the following: ...@@ -90,7 +90,7 @@ based on *all* of the following:
1. Potentially affecting one or more strategic accounts due to a proven inability by the user to upgrade to the current stable version. 1. Potentially affecting one or more strategic accounts due to a proven inability by the user to upgrade to the current stable version.
If *all* of the above are satisfied, the backport releases can be created for If *all* of the above are satisfied, the backport releases can be created for
the current stable stable release, and two previous monthly releases. the current stable release, and two previous monthly releases.
For instance, if we release `11.2.1` with a fix for a severe bug introduced in For instance, if we release `11.2.1` with a fix for a severe bug introduced in
`11.0.0`, we could backport the fix to a new `11.0.x`, and `11.1.x` patch release. `11.0.0`, we could backport the fix to a new `11.0.x`, and `11.1.x` patch release.
...@@ -186,7 +186,7 @@ Check [our release posts](https://about.gitlab.com/releases/categories/releases/ ...@@ -186,7 +186,7 @@ Check [our release posts](https://about.gitlab.com/releases/categories/releases/
Each month, we publish either a major or minor release of GitLab. At the end Each month, we publish either a major or minor release of GitLab. At the end
of those release posts there are three sections to look for: deprecations, important notes, of those release posts there are three sections to look for: deprecations, important notes,
and upgrade barometer. These will will draw your attention to: and upgrade barometer. These will draw your attention to:
- Steps you need to perform as part of an upgrade. - Steps you need to perform as part of an upgrade.
For example [8.12](https://about.gitlab.com/releases/2016/09/22/gitlab-8-12-released/#upgrade-barometer) For example [8.12](https://about.gitlab.com/releases/2016/09/22/gitlab-8-12-released/#upgrade-barometer)
......
...@@ -18,6 +18,15 @@ or a `.buildpacks` file in your project: ...@@ -18,6 +18,15 @@ or a `.buildpacks` file in your project:
and add the URL of the buildpack to use on a line in the file. If you want to and add the URL of the buildpack to use on a line in the file. If you want to
use multiple buildpacks, you can enter them in, one on each line. use multiple buildpacks, you can enter them in, one on each line.
The buildpack URL can point to either a Git repository URL or a tarball URL.
For Git repositories, it is possible to point to a specific Git reference (for example,
commit SHA, tag name, or branch name) by appending `#<ref>` to the Git repository URL.
For example:
- The tag `v142`: `https://github.com/heroku/heroku-buildpack-ruby.git#v142`.
- The branch `mybranch`: `https://github.com/heroku/heroku-buildpack-ruby.git#mybranch`.
- The commit SHA `f97d8a8ab49`: `https://github.com/heroku/heroku-buildpack-ruby.git#f97d8a8ab49`.
### Multiple buildpacks ### Multiple buildpacks
Using multiple buildpacks isn't fully supported by Auto DevOps because, when using the `.buildpacks` Using multiple buildpacks isn't fully supported by Auto DevOps because, when using the `.buildpacks`
...@@ -291,7 +300,7 @@ applications. ...@@ -291,7 +300,7 @@ applications.
| `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME` | From GitLab 11.11, used to set a username to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD`. | | `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME` | From GitLab 11.11, used to set a username to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD`. |
| `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD` | From GitLab 11.11, used to set a password to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME`. | | `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD` | From GitLab 11.11, used to set a password to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME`. |
| `AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE` | From GitLab 12.5, used in combination with [Modsecurity feature flag](../../user/clusters/applications.md#web-application-firewall-modsecurity) to toggle [Modsecurity's `SecRuleEngine`](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecRuleEngine) behavior. Defaults to `DetectionOnly`. | | `AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE` | From GitLab 12.5, used in combination with [Modsecurity feature flag](../../user/clusters/applications.md#web-application-firewall-modsecurity) to toggle [Modsecurity's `SecRuleEngine`](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecRuleEngine) behavior. Defaults to `DetectionOnly`. |
| `BUILDPACK_URL` | Buildpack's full URL. Can point to either Git repositories or a tarball URL. For Git repositories, it is possible to point to a specific `ref`. For example `https://github.com/heroku/heroku-buildpack-ruby.git#v142`. | | `BUILDPACK_URL` | Buildpack's full URL. Can point to either [a Git repository URL or a tarball URL](#custom-buildpacks). |
| `CANARY_ENABLED` | From GitLab 11.0, used to define a [deploy policy for canary environments](#deploy-policy-for-canary-environments-premium). | | `CANARY_ENABLED` | From GitLab 11.0, used to define a [deploy policy for canary environments](#deploy-policy-for-canary-environments-premium). |
| `CANARY_PRODUCTION_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md) in the production environment. Takes precedence over `CANARY_REPLICAS`. Defaults to 1. | | `CANARY_PRODUCTION_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md) in the production environment. Takes precedence over `CANARY_REPLICAS`. Defaults to 1. |
| `CANARY_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md). Defaults to 1. | | `CANARY_REPLICAS` | Number of canary replicas to deploy for [Canary Deployments](../../user/project/canary_deployments.md). Defaults to 1. |
......
...@@ -420,7 +420,7 @@ spec: ...@@ -420,7 +420,7 @@ spec:
- Auto Build and Auto Test may fail in detecting your language/framework. There - Auto Build and Auto Test may fail in detecting your language/framework. There
may be no buildpack for your application, or your application may be missing the may be no buildpack for your application, or your application may be missing the
key files the buildpack is looking for. For example, for ruby apps, you must key files the buildpack is looking for. For example, for Ruby applications, you must
have a `Gemfile` to be properly detected, even though it is possible to write a have a `Gemfile` to be properly detected, even though it is possible to write a
Ruby app without a `Gemfile`. Try specifying a [custom Ruby app without a `Gemfile`. Try specifying a [custom
buildpack](customize.md#custom-buildpacks). buildpack](customize.md#custom-buildpacks).
......
...@@ -5,7 +5,7 @@ type: reference ...@@ -5,7 +5,7 @@ type: reference
# Useful Git commands # Useful Git commands
Here are some useful Git commands collected by the GitLab support team. You may not Here are some useful Git commands collected by the GitLab support team. You may not
need to use often, but they can can come in handy when needed. need to use often, but they can come in handy when needed.
## Remotes ## Remotes
......
...@@ -23,11 +23,11 @@ GitLab administrators can later override these settings in a project’s setting ...@@ -23,11 +23,11 @@ GitLab administrators can later override these settings in a project’s setting
Merge request approval rules that can be set at an instance level are: Merge request approval rules that can be set at an instance level are:
- **Prevent approval of merge requests by merge request author**. Prevents non-admins - **Prevent approval of merge requests by merge request author**. Prevents project
from allowing merge request authors to merge their own merge requests in individual maintainers from allowing request authors to merge their own merge requests.
projects. - **Prevent approval of merge requests by merge request committers**. Prevents project
- **Prevent approval of merge requests by merge request committers**. Prevents maintainers from allowing users to approve merge requests if they have submitted
non-admins from allowing merge request committers to merge merge requests they were any commits to the source branch.
committing to in individual projects. - **Prevent users from modifying merge request approvers list**. Prevents project
- **Prevent users from modifying merge request approvers list**. Prevents non-admins maintainers from allowing users to modify the approvers list in project settings
from modifying approvers list in project settings and in individual merge requests. or in individual merge requests.
...@@ -495,7 +495,7 @@ The DAST job can emit various reports. ...@@ -495,7 +495,7 @@ The DAST job can emit various reports.
CAUTION: **Caution:** CAUTION: **Caution:**
The JSON report artifacts are not a public API of DAST and their format is expected to change in the future. The JSON report artifacts are not a public API of DAST and their format is expected to change in the future.
The DAST tool always emits a JSON report report file called `gl-dast-report.json` and sample reports can be found in the [DAST repository](https://gitlab.com/gitlab-org/security-products/dast/-/tree/master/test/end-to-end/expect). The DAST tool always emits a JSON report file called `gl-dast-report.json` and sample reports can be found in the [DAST repository](https://gitlab.com/gitlab-org/security-products/dast/-/tree/master/test/end-to-end/expect).
There are two formats of data in the JSON report that are used side by side: the proprietary ZAP format which will be eventually deprecated, and a "common" format which will be the default in the future. There are two formats of data in the JSON report that are used side by side: the proprietary ZAP format which will be eventually deprecated, and a "common" format which will be the default in the future.
......
...@@ -352,7 +352,7 @@ analyzer containers: `DOCKER_`, `CI`, `GITLAB_`, `FF_`, `HOME`, `PWD`, `OLDPWD`, ...@@ -352,7 +352,7 @@ analyzer containers: `DOCKER_`, `CI`, `GITLAB_`, `FF_`, `HOME`, `PWD`, `OLDPWD`,
CAUTION: **Caution:** CAUTION: **Caution:**
The JSON report artifacts are not a public API of SAST and their format may change in the future. The JSON report artifacts are not a public API of SAST and their format may change in the future.
The SAST tool emits a JSON report report file. Here is an example of the report structure with all important parts of The SAST tool emits a JSON report file. Here is an example of the report structure with all important parts of
it highlighted: it highlighted:
```json-doc ```json-doc
......
...@@ -27,7 +27,7 @@ Management projects are restricted to the following: ...@@ -27,7 +27,7 @@ Management projects are restricted to the following:
- For project-level clusters, the management project must be in the same - For project-level clusters, the management project must be in the same
namespace (or descendants) as the cluster's project. namespace (or descendants) as the cluster's project.
- For group-level clusters, the management project must be in the same - For group-level clusters, the management project must be in the same
group (or descendants) as as the cluster's group. group (or descendants) as the cluster's group.
- For instance-level clusters, there are no such restrictions. - For instance-level clusters, there are no such restrictions.
## Usage ## Usage
......
...@@ -281,7 +281,7 @@ GitLab [isn't limited to the SAML providers listed above](#my-identity-provider- ...@@ -281,7 +281,7 @@ GitLab [isn't limited to the SAML providers listed above](#my-identity-provider-
| Additional URLs | | You may need to use the `Identifier` or `Assertion consumer service URL` in other fields on some providers. | | Additional URLs | | You may need to use the `Identifier` or `Assertion consumer service URL` in other fields on some providers. |
| Single Sign Out URL | | Not supported | | Single Sign Out URL | | Not supported |
If the information information you need isn't listed above you may wish to check our [troubleshooting docs below](#i-need-additional-information-to-configure-my-identity-provider). If the information you need isn't listed above you may wish to check our [troubleshooting docs below](#i-need-additional-information-to-configure-my-identity-provider).
## Linking SAML to your existing GitLab.com account ## Linking SAML to your existing GitLab.com account
......
...@@ -244,7 +244,7 @@ Registry. ...@@ -244,7 +244,7 @@ Registry.
## Installing a package ## Installing a package
NPM packages are commonly installed using the the `npm` or `yarn` commands NPM packages are commonly installed using the `npm` or `yarn` commands
inside a JavaScript project. If you haven't already, you will need to set the inside a JavaScript project. If you haven't already, you will need to set the
URL for scoped packages. You can do this with the following command: URL for scoped packages. You can do this with the following command:
......
...@@ -222,7 +222,7 @@ The following table lists all GitLab-specific email headers: ...@@ -222,7 +222,7 @@ The following table lists all GitLab-specific email headers:
### X-GitLab-NotificationReason ### X-GitLab-NotificationReason
The `X-GitLab-NotificationReason` header contains the reason for the notification. The value is one of the the following, in order of priority: The `X-GitLab-NotificationReason` header contains the reason for the notification. The value is one of the following, in order of priority:
- `own_activity` - `own_activity`
- `assigned` - `assigned`
......
...@@ -245,7 +245,7 @@ To add an existing EKS cluster to your project, group, or instance: ...@@ -245,7 +245,7 @@ To add an existing EKS cluster to your project, group, or instance:
token: <authentication_token> token: <authentication_token>
``` ```
1. Locate the the API server endpoint so GitLab can connect to the cluster. This is displayed on 1. Locate the API server endpoint so GitLab can connect to the cluster. This is displayed on
the AWS EKS console, when viewing the EKS cluster details. the AWS EKS console, when viewing the EKS cluster details.
1. Navigate to your: 1. Navigate to your:
- Project's **{cloud-gear}** **Operations > Kubernetes** page, for a project-level cluster. - Project's **{cloud-gear}** **Operations > Kubernetes** page, for a project-level cluster.
......
...@@ -10,7 +10,7 @@ If GitLab is guessing wrong, you can override its choice of language using the ` ...@@ -10,7 +10,7 @@ If GitLab is guessing wrong, you can override its choice of language using the `
When you check in and push that change, all `*.pl` files in your project will be highlighted as Prolog. When you check in and push that change, all `*.pl` files in your project will be highlighted as Prolog.
The paths here are simply Git's built-in [`.gitattributes` interface](https://git-scm.com/docs/gitattributes). So, if you were to invent a file format called a `Nicefile` at the root of your project that used ruby syntax, all you need is: The paths here are simply Git's built-in [`.gitattributes` interface](https://git-scm.com/docs/gitattributes). So, if you were to invent a file format called a `Nicefile` at the root of your project that used Ruby syntax, all you need is:
``` conf ``` conf
/Nicefile gitlab-language=ruby /Nicefile gitlab-language=ruby
......
...@@ -397,7 +397,7 @@ Starting in [version 12.8](https://gitlab.com/gitlab-org/gitlab/issues/202696), ...@@ -397,7 +397,7 @@ Starting in [version 12.8](https://gitlab.com/gitlab-org/gitlab/issues/202696),
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16530) in GitLab 12.5. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16530) in GitLab 12.5.
To add an anomaly chart panel type to a dashboard, add add a panel with *exactly* 3 metrics. To add an anomaly chart panel type to a dashboard, add a panel with *exactly* 3 metrics.
The first metric represents the current state, and the second and third metrics represent the upper and lower limit respectively: The first metric represents the current state, and the second and third metrics represent the upper and lower limit respectively:
......
...@@ -28,7 +28,7 @@ button and start a merge request from there. ...@@ -28,7 +28,7 @@ button and start a merge request from there.
## New Merge Request page ## New Merge Request page
On the **New Merge Request** page, start by filling in the title On the **New Merge Request** page, start by filling in the title
and description for the merge request. If there are are already and description for the merge request. If there are already
commits on the branch, the title will be prefilled with the first commits on the branch, the title will be prefilled with the first
line of the first commit message, and the description will be line of the first commit message, and the description will be
prefilled with any additional lines in the commit message. prefilled with any additional lines in the commit message.
......
...@@ -175,10 +175,10 @@ a number of community contributed libraries. ...@@ -175,10 +175,10 @@ a number of community contributed libraries.
Official clients: Official clients:
- [unleash/unleash-client-java](https://github.com/unleash/unleash-client-java) - [Unleash client SDK for Java](https://github.com/unleash/unleash-client-java)
- [unleash/unleash-client-node](https://github.com/unleash/unleash-client-node) - [Unleash client SDK for Node.js](https://github.com/unleash/unleash-client-node)
- [unleash/unleash-client-go](https://github.com/unleash/unleash-client-go) - [Unleash client for Go](https://github.com/unleash/unleash-client-go)
- [unleash/unleash-client-ruby](https://github.com/unleash/unleash-client-ruby) - [Unleash client for Ruby](https://github.com/unleash/unleash-client-ruby)
Community contributed clients: Community contributed clients:
......
...@@ -19172,6 +19172,30 @@ msgstr "" ...@@ -19172,6 +19172,30 @@ msgstr ""
msgid "Static Application Security Testing (SAST)" msgid "Static Application Security Testing (SAST)"
msgstr "" msgstr ""
msgid "StaticSiteEditor|A merge request was created:"
msgstr ""
msgid "StaticSiteEditor|A new branch was created:"
msgstr ""
msgid "StaticSiteEditor|Return to site"
msgstr ""
msgid "StaticSiteEditor|Success!"
msgstr ""
msgid "StaticSiteEditor|Summary of changes"
msgstr ""
msgid "StaticSiteEditor|View merge request"
msgstr ""
msgid "StaticSiteEditor|Your changes have been submitted and a merge request has been created. The changes won’t be visible on the site until the merge request has been accepted."
msgstr ""
msgid "StaticSiteEditor|Your changes were committed to it:"
msgstr ""
msgid "Statistics" msgid "Statistics"
msgstr "" msgstr ""
......
import { shallowMount } from '@vue/test-utils';
import SavedChangesMessage from '~/static_site_editor/components/saved_changes_message.vue';
describe('~/static_site_editor/components/saved_changes_message.vue', () => {
let wrapper;
const props = {
branch: {
label: '123-the-branch',
url: 'https://gitlab.com/gitlab-org/gitlab/-/tree/123-the-branch',
},
commit: {
label: 'a123',
url: 'https://gitlab.com/gitlab-org/gitlab/-/commit/a123',
},
mergeRequest: {
label: '123',
url: 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123',
},
returnUrl: 'https://www.the-static-site.com/post',
};
const findReturnToSiteButton = () => wrapper.find({ ref: 'returnToSiteButton' });
const findMergeRequestButton = () => wrapper.find({ ref: 'mergeRequestButton' });
const findBranchLink = () => wrapper.find({ ref: 'branchLink' });
const findCommitLink = () => wrapper.find({ ref: 'commitLink' });
const findMergeRequestLink = () => wrapper.find({ ref: 'mergeRequestLink' });
beforeEach(() => {
wrapper = shallowMount(SavedChangesMessage, {
propsData: props,
});
});
afterEach(() => {
wrapper.destroy();
});
it.each`
text | findEl | url
${'Return to site'} | ${findReturnToSiteButton} | ${props.returnUrl}
${'View merge request'} | ${findMergeRequestButton} | ${props.mergeRequest.url}
`('renders "$text" button link', ({ text, findEl, url }) => {
const btn = findEl();
expect(btn.exists()).toBe(true);
expect(btn.text()).toBe(text);
expect(btn.attributes('href')).toBe(url);
});
it.each`
desc | findEl | prop
${'branch'} | ${findBranchLink} | ${props.branch}
${'commit'} | ${findCommitLink} | ${props.commit}
${'merge request'} | ${findMergeRequestLink} | ${props.mergeRequest}
`('renders $desc link', ({ findEl, prop }) => {
const el = findEl();
expect(el.exists()).toBe(true);
expect(el.attributes('href')).toBe(prop.url);
expect(el.text()).toBe(prop.label);
});
});
# frozen_string_literal: true
require 'spec_helper'
describe Resolvers::Projects::ServicesResolver do
include GraphqlHelpers
describe '#resolve' do
let_it_be(:user) { create(:user) }
context 'when project does not have services' do
let_it_be(:project) { create(:project, :private) }
context 'when user cannot access services' do
context 'when anonymous user' do
it_behaves_like 'cannot access project services'
end
context 'when user developer' do
before do
project.add_developer(user)
end
it_behaves_like 'cannot access project services'
end
end
context 'when user can read project services' do
before do
project.add_maintainer(user)
end
it_behaves_like 'no project services'
end
end
context 'when project has services' do
let_it_be(:project) { create(:project, :private) }
let_it_be(:jira_service) { create(:jira_service, project: project) }
context 'when user cannot access services' do
context 'when anonymous user' do
it_behaves_like 'cannot access project services'
end
context 'when user developer' do
before do
project.add_developer(user)
end
it_behaves_like 'cannot access project services'
end
end
context 'when user can read project services' do
before do
project.add_maintainer(user)
end
it 'returns project services' do
services = resolve_services
expect(services.size).to eq 1
end
end
end
end
def resolve_services(args = {}, context = { current_user: user })
resolve(described_class, obj: project, args: args, ctx: context)
end
end
...@@ -24,7 +24,7 @@ describe GitlabSchema.types['Project'] do ...@@ -24,7 +24,7 @@ describe GitlabSchema.types['Project'] do
namespace group statistics repository merge_requests merge_request issues namespace group statistics repository merge_requests merge_request issues
issue pipelines removeSourceBranchAfterMerge sentryDetailedError snippets issue pipelines removeSourceBranchAfterMerge sentryDetailedError snippets
grafanaIntegration autocloseReferencedIssues suggestion_commit_message environments grafanaIntegration autocloseReferencedIssues suggestion_commit_message environments
boards jira_import_status jira_imports boards jira_import_status jira_imports services
] ]
expect(described_class).to include_graphql_fields(*expected_fields) expect(described_class).to include_graphql_fields(*expected_fields)
...@@ -84,4 +84,16 @@ describe GitlabSchema.types['Project'] do ...@@ -84,4 +84,16 @@ describe GitlabSchema.types['Project'] do
it { is_expected.to have_graphql_type(Types::BoardType.connection_type) } it { is_expected.to have_graphql_type(Types::BoardType.connection_type) }
end end
describe 'jira_imports field' do
subject { described_class.fields['jiraImports'] }
it { is_expected.to have_graphql_type(Types::JiraImportType.connection_type) }
end
describe 'services field' do
subject { described_class.fields['services'] }
it { is_expected.to have_graphql_type(Types::Projects::ServiceType.connection_type) }
end
end end
# frozen_string_literal: true
require 'spec_helper'
describe GitlabSchema.types['BaseService'] do
it { expect(described_class.graphql_name).to eq('BaseService') }
it 'has basic expected fields' do
expect(described_class).to have_graphql_fields(:type, :active)
end
it { expect(described_class).to require_graphql_authorizations(:admin_project) }
end
# frozen_string_literal: true
require 'spec_helper'
describe GitlabSchema.types['JiraService'] do
it { expect(described_class.graphql_name).to eq('JiraService') }
it 'has basic expected fields' do
expect(described_class).to have_graphql_fields(:type, :active)
end
it { expect(described_class).to require_graphql_authorizations(:admin_project) }
end
# frozen_string_literal: true
require 'spec_helper'
describe Types::Projects::ServiceType do
it { expect(described_class).to have_graphql_fields(:type, :active) }
describe ".resolve_type" do
it 'resolves the corresponding type for objects' do
expect(described_class.resolve_type(build(:jira_service), {})).to eq(Types::Projects::Services::JiraServiceType)
expect(described_class.resolve_type(build(:service), {})).to eq(Types::Projects::Services::BaseServiceType)
expect(described_class.resolve_type(build(:alerts_service), {})).to eq(Types::Projects::Services::BaseServiceType)
expect(described_class.resolve_type(build(:custom_issue_tracker_service), {})).to eq(Types::Projects::Services::BaseServiceType)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe GitlabSchema.types['ServiceType'] do
it { expect(described_class.graphql_name).to eq('ServiceType') }
it 'exposes all the existing project services' do
expect(described_class.values.keys).to match_array(available_services_enum)
end
end
def available_services_enum
::Service.services_types.map(&:underscore).map(&:upcase)
end
# frozen_string_literal: true
require 'spec_helper'
describe 'query Jira service' do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:jira_service) { create(:jira_service, project: project) }
let_it_be(:bugzilla_service) { create(:bugzilla_service, project: project) }
let_it_be(:redmine_service) { create(:redmine_service, project: project) }
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
services {
nodes {
type
active
}
}
}
}
)
end
let(:services) { graphql_data.dig('project', 'services', 'nodes')}
it_behaves_like 'unauthorized users cannot read services'
context 'when user can access project services' do
before do
project.add_maintainer(current_user)
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
it 'retuns list of jira imports' do
service_types = services.map { |s| s['type'] }
expect(service_types).to match_array(%w(BugzillaService JiraService RedmineService))
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe 'query Jira service' do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:jira_service) { create(:jira_service, project: project) }
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
services(active: true, type: JIRA_SERVICE) {
nodes {
type
}
}
}
}
)
end
let(:services) { graphql_data.dig('project', 'services', 'nodes')}
it_behaves_like 'unauthorized users cannot read services'
context 'when user can access project services' do
before do
project.add_maintainer(current_user)
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
it 'retuns list of jira imports' do
service = services.first
expect(service['type']).to eq('JiraService')
end
end
end
...@@ -9,9 +9,29 @@ describe 'getting project information' do ...@@ -9,9 +9,29 @@ describe 'getting project information' do
let(:current_user) { create(:user) } let(:current_user) { create(:user) }
let(:query) do let(:query) do
graphql_query_for(
'project',
{ 'fullPath' => project.full_path },
all_graphql_fields_for('project'.to_s.classify, excluded: %w(jiraImports services))
)
end
context 'when the user has full access to the project' do
let(:full_access_query) do
graphql_query_for('project', 'fullPath' => project.full_path) graphql_query_for('project', 'fullPath' => project.full_path)
end end
before do
project.add_maintainer(current_user)
end
it 'includes the project' do
post_graphql(query, current_user: current_user)
expect(graphql_data['project']).not_to be_nil
end
end
context 'when the user has access to the project' do context 'when the user has access to the project' do
before do before do
project.add_developer(current_user) project.add_developer(current_user)
......
...@@ -149,7 +149,7 @@ module GraphqlHelpers ...@@ -149,7 +149,7 @@ module GraphqlHelpers
FIELDS FIELDS
end end
def all_graphql_fields_for(class_name, parent_types = Set.new, max_depth: 3) def all_graphql_fields_for(class_name, parent_types = Set.new, max_depth: 3, excluded: [])
# pulling _all_ fields can generate a _huge_ query (like complexity 180,000), # pulling _all_ fields can generate a _huge_ query (like complexity 180,000),
# and significantly increase spec runtime. so limit the depth by default # and significantly increase spec runtime. so limit the depth by default
return if max_depth <= 0 return if max_depth <= 0
...@@ -165,6 +165,7 @@ module GraphqlHelpers ...@@ -165,6 +165,7 @@ module GraphqlHelpers
type.fields.map do |name, field| type.fields.map do |name, field|
# We can't guess arguments, so skip fields that require them # We can't guess arguments, so skip fields that require them
next if required_arguments?(field) next if required_arguments?(field)
next if excluded.include?(name)
singular_field_type = field_type(field) singular_field_type = field_type(field)
......
# frozen_string_literal: true
shared_examples 'no project services' do
it 'returns empty collection' do
expect(resolve_services).to eq []
end
end
shared_examples 'cannot access project services' do
it 'raises error' do
expect do
resolve_services
end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
# frozen_string_literal: true
shared_examples 'unauthorized users cannot read services' do
before do
post_graphql(query, current_user: current_user)
end
context 'when anonymous user' do
let(:current_user) { nil }
it { expect(services).to be nil }
end
context 'when user developer' do
before do
project.add_developer(current_user)
end
it { expect(services).to be nil }
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment