Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
0698388e65
commit
b941629bbf
32 changed files with 336 additions and 52 deletions
|
@ -1 +1 @@
|
|||
a75309cec88ed34f594a4f6514bb0bb2aef7fcd5
|
||||
fdd1fe70085c1a20b10553680d88a967a4cfbfae
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<script>
|
||||
import { GlLink, GlSprintf } from '@gitlab/ui';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
},
|
||||
computed: {
|
||||
...mapState(['ancestorHelperPath', 'hasAncestorClusters']),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="hasAncestorClusters" class="bs-callout bs-callout-info">
|
||||
<p>
|
||||
<gl-sprintf
|
||||
:message="
|
||||
s__(
|
||||
'ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters. %{linkStart}More information%{linkEnd}',
|
||||
)
|
||||
"
|
||||
>
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="ancestorHelperPath">
|
||||
<strong>{{ content }}</strong>
|
||||
</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
|
@ -9,6 +9,7 @@ import {
|
|||
GlSprintf,
|
||||
GlTable,
|
||||
} from '@gitlab/ui';
|
||||
import AncestorNotice from './ancestor_notice.vue';
|
||||
import tooltip from '~/vue_shared/directives/tooltip';
|
||||
import { CLUSTER_TYPES, STATUSES } from '../constants';
|
||||
import { __, sprintf } from '~/locale';
|
||||
|
@ -17,6 +18,7 @@ export default {
|
|||
nodeMemoryText: __('%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)'),
|
||||
nodeCpuText: __('%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)'),
|
||||
components: {
|
||||
AncestorNotice,
|
||||
GlBadge,
|
||||
GlLink,
|
||||
GlLoadingIcon,
|
||||
|
@ -195,6 +197,8 @@ export default {
|
|||
<gl-loading-icon v-if="loadingClusters" size="md" class="gl-mt-3" />
|
||||
|
||||
<section v-else>
|
||||
<ancestor-notice />
|
||||
|
||||
<gl-table :items="clusters" :fields="fields" stacked="md" class="qa-clusters-table">
|
||||
<template #cell(name)="{ item }">
|
||||
<div :class="[contentAlignClasses, 'js-status']">
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export default (initialState = {}) => ({
|
||||
ancestorHelperPath: initialState.ancestorHelpPath,
|
||||
endpoint: initialState.endpoint,
|
||||
hasAncestorClusters: false,
|
||||
clusters: [],
|
||||
|
|
|
@ -13,7 +13,11 @@ module Types
|
|||
field :jira_email, GraphQL::STRING_TYPE, null: true,
|
||||
description: 'Email of the Jira user, returned only for users with public emails'
|
||||
field :gitlab_id, GraphQL::INT_TYPE, null: true,
|
||||
description: 'Id of the matched GitLab user'
|
||||
description: 'ID of the matched GitLab user'
|
||||
field :gitlab_username, GraphQL::STRING_TYPE, null: true,
|
||||
description: 'Username of the matched GitLab user'
|
||||
field :gitlab_name, GraphQL::STRING_TYPE, null: true,
|
||||
description: 'Name of the matched GitLab user'
|
||||
end
|
||||
# rubocop: enable Graphql/AuthorizeTypes
|
||||
end
|
||||
|
|
|
@ -18,6 +18,7 @@ module ClustersHelper
|
|||
|
||||
def js_clusters_list_data(path = nil)
|
||||
{
|
||||
ancestor_help_path: help_page_path('user/group/clusters/index', anchor: 'cluster-precedence'),
|
||||
endpoint: path,
|
||||
img_tags: {
|
||||
aws: { path: image_path('illustrations/logos/amazon_eks.svg'), text: s_('ClusterIntegration|Amazon EKS') },
|
||||
|
|
|
@ -11,7 +11,7 @@ module Ci
|
|||
METRICS_SHARD_TAG_PREFIX = 'metrics_shard::'.freeze
|
||||
DEFAULT_METRICS_SHARD = 'default'.freeze
|
||||
|
||||
Result = Struct.new(:build, :valid?)
|
||||
Result = Struct.new(:build, :build_json, :valid?)
|
||||
|
||||
def initialize(runner)
|
||||
@runner = runner
|
||||
|
@ -59,7 +59,7 @@ module Ci
|
|||
end
|
||||
|
||||
register_failure
|
||||
Result.new(nil, valid)
|
||||
Result.new(nil, nil, valid)
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
|
@ -71,7 +71,7 @@ module Ci
|
|||
# In case when 2 runners try to assign the same build, second runner will be declined
|
||||
# with StateMachines::InvalidTransition or StaleObjectError when doing run! or save method.
|
||||
if assign_runner!(build, params)
|
||||
Result.new(build, true)
|
||||
present_build!(build)
|
||||
end
|
||||
rescue StateMachines::InvalidTransition, ActiveRecord::StaleObjectError
|
||||
# We are looping to find another build that is not conflicting
|
||||
|
@ -83,8 +83,10 @@ module Ci
|
|||
# In case we hit the concurrency-access lock,
|
||||
# we still have to return 409 in the end,
|
||||
# to make sure that this is properly handled by runner.
|
||||
Result.new(nil, false)
|
||||
Result.new(nil, nil, false)
|
||||
rescue => ex
|
||||
# If an error (e.g. GRPC::DeadlineExceeded) occurred constructing
|
||||
# the result, consider this as a failure to be retried.
|
||||
scheduler_failure!(build)
|
||||
track_exception_for_build(ex, build)
|
||||
|
||||
|
@ -92,6 +94,15 @@ module Ci
|
|||
nil
|
||||
end
|
||||
|
||||
# Force variables evaluation to occur now
|
||||
def present_build!(build)
|
||||
# We need to use the presenter here because Gitaly calls in the presenter
|
||||
# may fail, and we need to ensure the response has been generated.
|
||||
presented_build = ::Ci::BuildRunnerPresenter.new(build) # rubocop:disable CodeReuse/Presenter
|
||||
build_json = ::API::Entities::JobRequest::Response.new(presented_build).to_json
|
||||
Result.new(build, build_json, true)
|
||||
end
|
||||
|
||||
def assign_runner!(build, params)
|
||||
build.runner_id = runner.id
|
||||
build.runner_session_attributes = params[:session] if params[:session].present?
|
||||
|
|
|
@ -14,9 +14,8 @@ module JiraImport
|
|||
{
|
||||
jira_account_id: jira_user['accountId'],
|
||||
jira_display_name: jira_user['displayName'],
|
||||
jira_email: jira_user['emailAddress'],
|
||||
gitlab_id: match_user(jira_user)
|
||||
}
|
||||
jira_email: jira_user['emailAddress']
|
||||
}.merge(match_user(jira_user))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -25,7 +24,7 @@ module JiraImport
|
|||
# TODO: Matching user by email and displayName will be done as the part
|
||||
# of follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/219023
|
||||
def match_user(jira_user)
|
||||
nil
|
||||
{ gitlab_id: nil, gitlab_username: nil, gitlab_name: nil }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,15 +12,14 @@
|
|||
= s_('ClusterIntegration|Kubernetes clusters can be used to deploy applications and to provide Review Apps for this project')
|
||||
= render 'clusters/clusters/buttons'
|
||||
|
||||
- if @has_ancestor_clusters
|
||||
.bs-callout.bs-callout-info
|
||||
= s_('ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters.')
|
||||
%strong
|
||||
= link_to _('More information'), help_page_path('user/group/clusters/index', anchor: 'cluster-precedence')
|
||||
|
||||
- if Feature.enabled?(:clusters_list_redesign)
|
||||
#js-clusters-list-app{ data: js_clusters_list_data(clusterable.index_path(format: :json)) }
|
||||
- else
|
||||
- if @has_ancestor_clusters
|
||||
.bs-callout.bs-callout-info
|
||||
= s_('ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters.')
|
||||
%strong
|
||||
= link_to _('More information'), help_page_path('user/group/clusters/index', anchor: 'cluster-precedence')
|
||||
.clusters-table.js-clusters-list
|
||||
.gl-responsive-table-row.table-row-header{ role: "row" }
|
||||
.table-section.section-60{ role: "rowheader" }
|
||||
|
|
|
@ -60,8 +60,6 @@ module Reenqueuer
|
|||
5.seconds
|
||||
end
|
||||
|
||||
# We intend to get rid of sleep:
|
||||
# https://gitlab.com/gitlab-org/gitlab/issues/121697
|
||||
module ReenqueuerSleeper
|
||||
# The block will run, and then sleep until the minimum duration. Returns the
|
||||
# block's return value.
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add GitLab username and name to the import users from Jira mutation response
|
||||
merge_request: 35542
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Change PrometheusMetrics identifier index
|
||||
merge_request: 35912
|
||||
author:
|
||||
type: fixed
|
5
changelogs/unreleased/sh-requeue-failed-job-register.yml
Normal file
5
changelogs/unreleased/sh-requeue-failed-job-register.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fail jobs that fail to render registration response
|
||||
merge_request: 36274
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ChangePrometheusMetricsIdentifierIndex < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
NEW_INDEX = :index_prometheus_metrics_on_identifier_and_null_project
|
||||
OLD_INDEX = :index_prometheus_metrics_on_identifier
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_index :prometheus_metrics, :identifier, name: NEW_INDEX, unique: true, where: 'project_id IS NULL'
|
||||
remove_concurrent_index_by_name :prometheus_metrics, OLD_INDEX
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_index :prometheus_metrics, :identifier, name: OLD_INDEX, unique: true
|
||||
remove_concurrent_index_by_name :prometheus_metrics, NEW_INDEX
|
||||
end
|
||||
end
|
|
@ -20025,7 +20025,7 @@ CREATE INDEX index_prometheus_metrics_on_common ON public.prometheus_metrics USI
|
|||
|
||||
CREATE INDEX index_prometheus_metrics_on_group ON public.prometheus_metrics USING btree ("group");
|
||||
|
||||
CREATE UNIQUE INDEX index_prometheus_metrics_on_identifier ON public.prometheus_metrics USING btree (identifier);
|
||||
CREATE UNIQUE INDEX index_prometheus_metrics_on_identifier_and_null_project ON public.prometheus_metrics USING btree (identifier) WHERE (project_id IS NULL);
|
||||
|
||||
CREATE UNIQUE INDEX index_prometheus_metrics_on_identifier_and_project_id ON public.prometheus_metrics USING btree (identifier, project_id);
|
||||
|
||||
|
@ -23718,6 +23718,7 @@ COPY "schema_migrations" (version) FROM STDIN;
|
|||
20200701093859
|
||||
20200701205710
|
||||
20200702123805
|
||||
20200702201039
|
||||
20200703064117
|
||||
20200703121557
|
||||
20200703154822
|
||||
|
|
|
@ -35,7 +35,8 @@ The availability objectives for Gitaly clusters are:
|
|||
Writes are replicated asynchronously. Any writes that have not been replicated
|
||||
to the newly promoted primary are lost.
|
||||
|
||||
[Strong consistency](#strong-consistency) can be used to improve this to "no loss".
|
||||
[Strong consistency](#strong-consistency) can be used to avoid loss in some
|
||||
circumstances.
|
||||
|
||||
- **Recovery Time Objective (RTO):** Less than 10 seconds.
|
||||
|
||||
|
@ -886,8 +887,8 @@ after the write to the primary Gitaly node has happened.
|
|||
Praefect can instead provide strong consistency by creating a transaction and writing
|
||||
changes to all Gitaly nodes at once. Strong consistency is currently in
|
||||
[alpha](https://about.gitlab.com/handbook/product/#alpha-beta-ga) and not enabled by
|
||||
default. For more information, see the
|
||||
[strong consistency epic](https://gitlab.com/groups/gitlab-org/-/epics/1189).
|
||||
default. If enabled, transactions are only available for a subset of RPCs. For more
|
||||
information, see the [strong consistency epic](https://gitlab.com/groups/gitlab-org/-/epics/1189).
|
||||
|
||||
To enable strong consistency:
|
||||
|
||||
|
|
|
@ -119,6 +119,49 @@ For `<project>.git` you'll need to
|
|||
[translate your project name into the hashed storage format](repository_storage_types.md#translating-hashed-storage-paths)
|
||||
that GitLab uses.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
The following set of environment variables are available to server hooks.
|
||||
|
||||
### GitLab Environment Variables
|
||||
|
||||
| Envirnment Variable | purpose |
|
||||
|---------------------|---------------------------------------------------------|
|
||||
| GL_ID | GitLab identifier eg: user-2234 that initiated the push |
|
||||
| GL_PROJECT_PATH (available starting 13.2) | GitLab project path |
|
||||
| GL_PROTOCOL (available starting 13.2) | Protocol used with push |
|
||||
| GL_REPOSITORY | project-<id> where id of the project |
|
||||
| GL_USERNAME | GitLab username that initiated the push |
|
||||
|
||||
Pre-receive and post-receive server hooks can also access the following Git environment variables.
|
||||
|
||||
| Environment variable | Description |
|
||||
|:-----------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `GIT_ALTERNATE_OBJECT_DIRECTORIES` | Alternate object directories in the quarantine environment. See [Git `receive-pack` documentation](https://git-scm.com/docs/git-receive-pack#_quarantine_environment). |
|
||||
| `GIT_OBJECT_DIRECTORY` | GitLab project path in the quarantine environment. See [Git `receive-pack` documentation](https://git-scm.com/docs/git-receive-pack#_quarantine_environment). |
|
||||
| `GIT_PUSH_OPTION_COUNT` | Number of push options. See [Git `pre-receive` documentation](https://git-scm.com/docs/githooks#pre-receive). |
|
||||
| `GIT_PUSH_OPTION_<i>` | Value of push options where `i` is from `0` to `GIT_PUSH_OPTION_COUNT - 1`. See [Git `pre-receive` documentation](https://git-scm.com/docs/githooks#pre-receive). |
|
||||
|
||||
NOTE: **Note:**
|
||||
While other environment variables can be passed to server hooks, your application
|
||||
should not rely on them as they can change.
|
||||
|
||||
## Transition to Go
|
||||
|
||||
> Introduced in GitLab 13.2 using feature flags.
|
||||
|
||||
The following server hooks have been reimplemented in Go:
|
||||
|
||||
- `pre-receive`, with the Go implementation used by default. To use the Ruby
|
||||
implementation instead, [disable](../operations/feature_flags.md#enable-or-disable-feature-flag-strategies)
|
||||
the `:gitaly_go_preceive_hook` feature flag.
|
||||
- `update`, with the Go implementation used by default. To use the Ruby implementation
|
||||
instead, [disable](../operations/feature_flags.md#enable-or-disable-feature-flag-strategies)
|
||||
the `:gitaly_go_update_hook` feature flag.
|
||||
- `post-receive`, however the Ruby implementation is used by default. To use the Go
|
||||
implementation instead, [enabled](../operations/feature_flags.md#enable-or-disable-feature-flag-strategies)
|
||||
the `:gitaly_go_postreceive_hook` feature flag.
|
||||
|
||||
## Custom error messages
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5073) in GitLab 8.10.
|
||||
|
|
|
@ -423,7 +423,7 @@ Status: 200 OK
|
|||
```
|
||||
|
||||
CAUTION: **Deprecation:**
|
||||
The `Links` Header will be removed in GitLab 14.0 to be aligned with the [W3C specification](https://www.w3.org/wiki/LinkHeader)
|
||||
The `Links` Header will be removed in GitLab 14.0 to be aligned with the [W3C `Link` specification](https://www.w3.org/wiki/LinkHeader)
|
||||
|
||||
The link to the next page contains an additional filter `id_after=42` which excludes records we have retrieved already.
|
||||
Note the type of filter depends on the `order_by` option used and we may have more than one additional filter.
|
||||
|
|
|
@ -6656,10 +6656,20 @@ type JiraService implements Service {
|
|||
|
||||
type JiraUser {
|
||||
"""
|
||||
Id of the matched GitLab user
|
||||
ID of the matched GitLab user
|
||||
"""
|
||||
gitlabId: Int
|
||||
|
||||
"""
|
||||
Name of the matched GitLab user
|
||||
"""
|
||||
gitlabName: String
|
||||
|
||||
"""
|
||||
Username of the matched GitLab user
|
||||
"""
|
||||
gitlabUsername: String
|
||||
|
||||
"""
|
||||
Account id of the Jira user
|
||||
"""
|
||||
|
|
|
@ -18439,7 +18439,7 @@
|
|||
"fields": [
|
||||
{
|
||||
"name": "gitlabId",
|
||||
"description": "Id of the matched GitLab user",
|
||||
"description": "ID of the matched GitLab user",
|
||||
"args": [
|
||||
|
||||
],
|
||||
|
@ -18451,6 +18451,34 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "gitlabName",
|
||||
"description": "Name of the matched GitLab user",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "gitlabUsername",
|
||||
"description": "Username of the matched GitLab user",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "jiraAccountId",
|
||||
"description": "Account id of the Jira user",
|
||||
|
|
|
@ -1007,7 +1007,9 @@ Autogenerated return type of JiraImportUsers
|
|||
|
||||
| Name | Type | Description |
|
||||
| --- | ---- | ---------- |
|
||||
| `gitlabId` | Int | Id of the matched GitLab user |
|
||||
| `gitlabId` | Int | ID of the matched GitLab user |
|
||||
| `gitlabName` | String | Name of the matched GitLab user |
|
||||
| `gitlabUsername` | String | Username of the matched GitLab user |
|
||||
| `jiraAccountId` | String! | Account id of the Jira user |
|
||||
| `jiraDisplayName` | String! | Display name of the Jira user |
|
||||
| `jiraEmail` | String | Email of the Jira user, returned only for users with public emails |
|
||||
|
|
|
@ -48,7 +48,7 @@ Example response:
|
|||
"sign_in_text" : null,
|
||||
"container_expiration_policies_enable_historic_entries": true,
|
||||
"container_registry_token_expire_delay": 5,
|
||||
"repository_storages": ["default"],
|
||||
"repository_storages_weighted": {"default": 100},
|
||||
"plantuml_enabled": false,
|
||||
"plantuml_url": null,
|
||||
"terminal_max_session_time": 0,
|
||||
|
@ -314,7 +314,8 @@ are listed in the descriptions of the relevant settings.
|
|||
| `receive_max_input_size` | integer | no | Maximum push size (MB). |
|
||||
| `repository_checks_enabled` | boolean | no | GitLab will periodically run `git fsck` in all project and wiki repositories to look for silent disk corruption issues. |
|
||||
| `repository_size_limit` | integer | no | **(PREMIUM)** Size limit per repository (MB) |
|
||||
| `repository_storages` | array of strings | no | A list of names of enabled storage paths, taken from `gitlab.yml`. New projects will be created in one of these stores, chosen at random. |
|
||||
| `repository_storages` | array of strings | no | (GitLab 13.0 and earlier) List of names of enabled storage paths, taken from `gitlab.yml`. New projects are created in one of these stores, chosen at random. |
|
||||
| `repository_storages_weighted` | hash of strings to integers | no | (GitLab 13.1 and later) Hash of names of taken from `gitlab.yml` to weights. New projects are created in one of these stores, chosen by a weighted random selection. |
|
||||
| `require_two_factor_authentication` | boolean | no | (**If enabled, requires:** `two_factor_grace_period`) Require all users to set up Two-factor authentication. |
|
||||
| `restricted_visibility_levels` | array of strings | no | Selected levels cannot be used by non-admin users for groups, projects or snippets. Can take `private`, `internal` and `public` as a parameter. Default is `null` which means there is no restriction. |
|
||||
| `rsa_key_restriction` | integer | no | The minimum allowed bit length of an uploaded RSA key. Default is `0` (no restriction). `-1` disables RSA keys. |
|
||||
|
|
|
@ -111,7 +111,8 @@ Patterns:
|
|||
- `'"((?:\\"|[^"]|\\")*)"'`: captures terms inside quotes, removing the quotes
|
||||
- `"'((?:\\'|[^']|\\')*)'"`: same as above, for single-quotes
|
||||
- `'\.([^.]+)(?=\.|\s|\Z)'`: separate terms with periods in-between
|
||||
- `'([\p{L}_.-]+)'` : some common chars in file names to keep the whole filename intact (eg. `my_file-ñame.txt`)
|
||||
- `'([\p{L}_.-]+)'`: some common chars in file names to keep the whole filename intact (eg. `my_file-ñame.txt`)
|
||||
- `'([\p{L}\d_]+)'`: letters, numbers and underscores are the most common tokens in programming. Always capture them greedily regardless of context.
|
||||
|
||||
## Gotchas
|
||||
|
||||
|
|
|
@ -53,14 +53,14 @@ Be sure to read about [page-specific JavaScript](./performance.md#page-specific-
|
|||
|
||||
#### Providing data from HAML to JavaScript
|
||||
|
||||
While mounting a Vue application may be a need to provide data from Rails to JavaScript.
|
||||
To do that, provide the data through `data` attributes in the HTML element and query them while mounting the application.
|
||||
While mounting a Vue application, you might need to provide data from Rails to JavaScript.
|
||||
To do that, you can use the `data` attributes in the HTML element and query them while mounting the application.
|
||||
|
||||
_Note:_ You should only do this while initializing the application, because the mounted element will be replaced with Vue-generated DOM.
|
||||
|
||||
The advantage of providing data from the DOM to the Vue instance through `props` in the `render` function
|
||||
instead of querying the DOM inside the main Vue component is that makes tests easier by avoiding the need to
|
||||
create a fixture or an HTML element in the unit test. See the following example:
|
||||
instead of querying the DOM inside the main Vue component is avoiding the need to create a fixture or an HTML element in the unit test,
|
||||
which will make the tests easier. See the following example:
|
||||
|
||||
```javascript
|
||||
// haml
|
||||
|
@ -134,7 +134,7 @@ This approach has a few benefits:
|
|||
intermediate components being aware of it (c.f. passing the flag down via
|
||||
props).
|
||||
- Good testability, since the flag can be provided to `mount`/`shallowMount`
|
||||
from `vue-test-utils` as easily as a prop.
|
||||
from `vue-test-utils` simply as a prop.
|
||||
|
||||
```javascript
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
|
@ -155,7 +155,7 @@ This folder holds all components that are specific of this new feature.
|
|||
If you need to use or create a component that will probably be used somewhere
|
||||
else, please refer to `vue_shared/components`.
|
||||
|
||||
A good thumb rule to know when you should create a component is to think if
|
||||
A good rule of thumb to know when you should create a component is to think if
|
||||
it will be reusable elsewhere.
|
||||
|
||||
For example, tables are used in a quite amount of places across GitLab, a table
|
||||
|
@ -321,7 +321,7 @@ We should verify an event has been fired by asserting against the result of the
|
|||
|
||||
## Vue.js Expert Role
|
||||
|
||||
One should apply to be a Vue.js expert by opening an MR when the Merge Request's they create and review show:
|
||||
You should only apply to be a Vue.js expert when your own merge requests and your reviews show:
|
||||
|
||||
- Deep understanding of Vue and Vuex reactivity
|
||||
- Vue and Vuex code are structured according to both official and our guidelines
|
||||
|
|
|
@ -108,6 +108,20 @@ module API
|
|||
end
|
||||
optional :job_age, type: Integer, desc: %q(Job should be older than passed age in seconds to be ran on runner)
|
||||
end
|
||||
|
||||
# Since we serialize the build output ourselves to ensure Gitaly
|
||||
# gRPC calls succeed, we need a custom Grape format to handle
|
||||
# this:
|
||||
# 1. Grape will ordinarily call `JSON.dump` when Content-Type is set
|
||||
# to application/json. To avoid this, we need to define a custom type in
|
||||
# `content_type` and a custom formatter to go with it.
|
||||
# 2. Grape will parse the request input with the parser defined for
|
||||
# `content_type`. If no such parser exists, it will be treated as text. We
|
||||
# reuse the existing JSON parser to preserve the previous behavior.
|
||||
content_type :build_json, 'application/json'
|
||||
formatter :build_json, ->(object, _) { object }
|
||||
parser :build_json, ::Grape::Parser::Json
|
||||
|
||||
post '/request' do
|
||||
authenticate_runner!
|
||||
|
||||
|
@ -128,9 +142,10 @@ module API
|
|||
result = ::Ci::RegisterJobService.new(current_runner).execute(runner_params)
|
||||
|
||||
if result.valid?
|
||||
if result.build
|
||||
if result.build_json
|
||||
Gitlab::Metrics.add_event(:build_found)
|
||||
present ::Ci::BuildRunnerPresenter.new(result.build), with: Entities::JobRequest::Response
|
||||
env['api.format'] = :build_json
|
||||
body result.build_json
|
||||
else
|
||||
Gitlab::Metrics.add_event(:build_not_found)
|
||||
header 'X-GitLab-Last-Update', new_update
|
||||
|
|
|
@ -5054,6 +5054,9 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters. %{linkStart}More information%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Copy API URL"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import AncestorNotice from '~/clusters_list/components/ancestor_notice.vue';
|
||||
import ClusterStore from '~/clusters_list/store';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { GlLink, GlSprintf } from '@gitlab/ui';
|
||||
|
||||
describe('ClustersAncestorNotice', () => {
|
||||
let store;
|
||||
let wrapper;
|
||||
|
||||
const createWrapper = () => {
|
||||
store = ClusterStore({ ancestorHelperPath: '/some/ancestor/path' });
|
||||
wrapper = shallowMount(AncestorNotice, { store, stubs: { GlSprintf } });
|
||||
return wrapper.vm.$nextTick();
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
return createWrapper();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
describe('when cluster does not have ancestors', () => {
|
||||
beforeEach(() => {
|
||||
store.state.hasAncestorClusters = false;
|
||||
return wrapper.vm.$nextTick();
|
||||
});
|
||||
|
||||
it('displays no notice', () => {
|
||||
expect(wrapper.isEmpty()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when cluster has ancestors', () => {
|
||||
beforeEach(() => {
|
||||
store.state.hasAncestorClusters = true;
|
||||
return wrapper.vm.$nextTick();
|
||||
});
|
||||
|
||||
it('displays notice text', () => {
|
||||
expect(wrapper.text()).toContain(
|
||||
'Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters.',
|
||||
);
|
||||
});
|
||||
|
||||
it('displays link', () => {
|
||||
expect(wrapper.contains(GlLink)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
13
spec/graphql/types/jira_user_type_spec.rb
Normal file
13
spec/graphql/types/jira_user_type_spec.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['JiraUser'] do
|
||||
specify { expect(described_class.graphql_name).to eq('JiraUser') }
|
||||
|
||||
it 'has the expected fields' do
|
||||
expect(described_class).to have_graphql_fields(
|
||||
:jira_account_id, :jira_display_name, :jira_email, :gitlab_id, :gitlab_username, :gitlab_name
|
||||
)
|
||||
end
|
||||
end
|
|
@ -60,18 +60,24 @@ RSpec.describe ClustersHelper do
|
|||
end
|
||||
|
||||
describe '#js_clusters_list_data' do
|
||||
it 'displays endpoint path and images' do
|
||||
js_data = helper.js_clusters_list_data('/path')
|
||||
subject { helper.js_clusters_list_data('/path') }
|
||||
|
||||
expect(js_data[:endpoint]).to eq('/path')
|
||||
it 'displays endpoint path' do
|
||||
expect(subject[:endpoint]).to eq('/path')
|
||||
end
|
||||
|
||||
expect(js_data.dig(:img_tags, :aws, :path)).to match(%r(/illustrations/logos/amazon_eks|svg))
|
||||
expect(js_data.dig(:img_tags, :default, :path)).to match(%r(/illustrations/logos/kubernetes|svg))
|
||||
expect(js_data.dig(:img_tags, :gcp, :path)).to match(%r(/illustrations/logos/google_gke|svg))
|
||||
it 'generates svg image data', :aggregate_failures do
|
||||
expect(subject.dig(:img_tags, :aws, :path)).to match(%r(/illustrations/logos/amazon_eks|svg))
|
||||
expect(subject.dig(:img_tags, :default, :path)).to match(%r(/illustrations/logos/kubernetes|svg))
|
||||
expect(subject.dig(:img_tags, :gcp, :path)).to match(%r(/illustrations/logos/google_gke|svg))
|
||||
|
||||
expect(js_data.dig(:img_tags, :aws, :text)).to eq('Amazon EKS')
|
||||
expect(js_data.dig(:img_tags, :default, :text)).to eq('Kubernetes Cluster')
|
||||
expect(js_data.dig(:img_tags, :gcp, :text)).to eq('Google GKE')
|
||||
expect(subject.dig(:img_tags, :aws, :text)).to eq('Amazon EKS')
|
||||
expect(subject.dig(:img_tags, :default, :text)).to eq('Kubernetes Cluster')
|
||||
expect(subject.dig(:img_tags, :gcp, :text)).to eq('Google GKE')
|
||||
end
|
||||
|
||||
it 'displays and ancestor_help_path' do
|
||||
expect(subject[:ancestor_help_path]).to eq('/help/user/group/clusters/index#cluster-precedence')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -518,6 +518,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
|
|||
request_job info: { platform: :darwin }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:created)
|
||||
expect(response.headers['Content-Type']).to eq('application/json')
|
||||
expect(response.headers).not_to have_key('X-GitLab-Last-Update')
|
||||
expect(runner.reload.platform).to eq('darwin')
|
||||
expect(json_response['id']).to eq(job.id)
|
||||
|
@ -569,6 +570,24 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when a Gitaly exception is thrown during response' do
|
||||
before do
|
||||
allow_next_instance_of(Ci::BuildRunnerPresenter) do |instance|
|
||||
allow(instance).to receive(:artifacts).and_raise(GRPC::DeadlineExceeded)
|
||||
end
|
||||
end
|
||||
|
||||
it 'fails the job as a scheduler failure' do
|
||||
request_job
|
||||
|
||||
expect(response).to have_gitlab_http_status(:no_content)
|
||||
expect(job.reload.failed?).to be_truthy
|
||||
expect(job.failure_reason).to eq('scheduler_failure')
|
||||
expect(job.runner_id).to eq(runner.id)
|
||||
expect(job.runner_session).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when GIT_DEPTH is not specified and there is no default git depth for the project' do
|
||||
before do
|
||||
project.update!(ci_default_git_depth: nil)
|
||||
|
@ -1090,7 +1109,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
|
|||
|
||||
def request_job(token = runner.token, **params)
|
||||
new_params = params.merge(token: token, last_update: last_update)
|
||||
post api('/jobs/request'), params: new_params, headers: { 'User-Agent' => user_agent }
|
||||
post api('/jobs/request'), params: new_params.to_json, headers: { 'User-Agent' => user_agent, 'Content-Type': 'application/json' }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -109,12 +109,14 @@ module Ci
|
|||
end
|
||||
|
||||
context 'shared runner' do
|
||||
let(:build) { execute(shared_runner) }
|
||||
let(:response) { described_class.new(shared_runner).execute }
|
||||
let(:build) { response.build }
|
||||
|
||||
it { expect(build).to be_kind_of(Build) }
|
||||
it { expect(build).to be_valid }
|
||||
it { expect(build).to be_running }
|
||||
it { expect(build.runner).to eq(shared_runner) }
|
||||
it { expect(Gitlab::Json.parse(response.build_json)['id']).to eq(build.id) }
|
||||
end
|
||||
|
||||
context 'specific runner' do
|
||||
|
|
|
@ -29,9 +29,9 @@ RSpec.describe JiraImport::UsersMapper do
|
|||
# mapping is tracked in https://gitlab.com/gitlab-org/gitlab/-/issues/219023
|
||||
let(:mapped_users) do
|
||||
[
|
||||
{ jira_account_id: 'abcd', jira_display_name: 'user1', jira_email: nil, gitlab_id: nil },
|
||||
{ jira_account_id: 'efg', jira_display_name: nil, jira_email: nil, gitlab_id: nil },
|
||||
{ jira_account_id: 'hij', jira_display_name: 'user3', jira_email: 'user3@example.com', gitlab_id: nil }
|
||||
{ jira_account_id: 'abcd', jira_display_name: 'user1', jira_email: nil, gitlab_id: nil, gitlab_username: nil, gitlab_name: nil },
|
||||
{ jira_account_id: 'efg', jira_display_name: nil, jira_email: nil, gitlab_id: nil, gitlab_username: nil, gitlab_name: nil },
|
||||
{ jira_account_id: 'hij', jira_display_name: 'user3', jira_email: 'user3@example.com', gitlab_id: nil, gitlab_username: nil, gitlab_name: nil }
|
||||
]
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue