Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-07-14 00:09:46 +00:00
parent 0698388e65
commit b941629bbf
32 changed files with 336 additions and 52 deletions

View file

@ -1 +1 @@
a75309cec88ed34f594a4f6514bb0bb2aef7fcd5
fdd1fe70085c1a20b10553680d88a967a4cfbfae

View file

@ -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>

View file

@ -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']">

View file

@ -1,4 +1,5 @@
export default (initialState = {}) => ({
ancestorHelperPath: initialState.ancestorHelpPath,
endpoint: initialState.endpoint,
hasAncestorClusters: false,
clusters: [],

View file

@ -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

View file

@ -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') },

View file

@ -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?

View file

@ -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

View file

@ -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 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')
- if Feature.enabled?(:clusters_list_redesign)
#js-clusters-list-app{ data: js_clusters_list_data(clusterable.index_path(format: :json)) }
- else
.clusters-table.js-clusters-list
.gl-responsive-table-row.table-row-header{ role: "row" }
.table-section.section-60{ role: "rowheader" }

View file

@ -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.

View file

@ -0,0 +1,5 @@
---
title: Add GitLab username and name to the import users from Jira mutation response
merge_request: 35542
author:
type: changed

View file

@ -0,0 +1,5 @@
---
title: Change PrometheusMetrics identifier index
merge_request: 35912
author:
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Fail jobs that fail to render registration response
merge_request: 36274
author:
type: fixed

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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.

View file

@ -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.

View file

@ -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
"""

View file

@ -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",

View file

@ -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 |

View file

@ -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. |

View file

@ -112,6 +112,7 @@ Patterns:
- `"'((?:\\'|[^']|\\')*)'"`: 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}\d_]+)'`: letters, numbers and underscores are the most common tokens in programming. Always capture them greedily regardless of context.
## Gotchas

View file

@ -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

View file

@ -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

View file

@ -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 ""

View file

@ -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);
});
});
});

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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