Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
0cc7fe66f5
commit
c3fcd33976
51 changed files with 636 additions and 352 deletions
|
@ -82,11 +82,6 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
installedVia: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
version: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
@ -336,11 +331,7 @@ export default {
|
|||
>
|
||||
<span v-else class="js-cluster-application-title">{{ title }}</span>
|
||||
</strong>
|
||||
<span
|
||||
v-if="installedVia"
|
||||
class="js-cluster-application-installed-via"
|
||||
v-html="installedVia"
|
||||
></span>
|
||||
<slot name="installedVia"></slot>
|
||||
<div>
|
||||
<slot name="description"></slot>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script>
|
||||
import { escape } from 'lodash';
|
||||
import helmInstallIllustration from '@gitlab/svgs/dist/illustrations/kubernetes-installation.svg';
|
||||
import { GlLoadingIcon, GlSprintf, GlLink } from '@gitlab/ui';
|
||||
import gitlabLogo from 'images/cluster_app_logos/gitlab.png';
|
||||
|
@ -12,7 +11,6 @@ import knativeLogo from 'images/cluster_app_logos/knative.png';
|
|||
import prometheusLogo from 'images/cluster_app_logos/prometheus.png';
|
||||
import elasticStackLogo from 'images/cluster_app_logos/elastic_stack.png';
|
||||
import fluentdLogo from 'images/cluster_app_logos/fluentd.png';
|
||||
import { s__, sprintf } from '../../locale';
|
||||
import applicationRow from './application_row.vue';
|
||||
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
||||
import KnativeDomainEditor from './knative_domain_editor.vue';
|
||||
|
@ -129,22 +127,6 @@ export default {
|
|||
cloudRun() {
|
||||
return this.providerType === PROVIDER_TYPE.GCP && this.preInstalledKnative;
|
||||
},
|
||||
installedVia() {
|
||||
if (this.cloudRun) {
|
||||
return sprintf(
|
||||
escape(s__(`ClusterIntegration|installed via %{installed_via}`)),
|
||||
{
|
||||
installed_via: `<a href="${
|
||||
this.cloudRunHelpPath
|
||||
}" target="_blank" rel="noopener noreferrer">${escape(
|
||||
s__('ClusterIntegration|Cloud Run'),
|
||||
)}</a>`,
|
||||
},
|
||||
false,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
ingress() {
|
||||
return this.applications.ingress;
|
||||
},
|
||||
|
@ -320,17 +302,17 @@ export default {
|
|||
</template>
|
||||
<template v-else>
|
||||
<div class="bs-callout bs-callout-info">
|
||||
<strong>
|
||||
<strong data-testid="ingressCostWarning">
|
||||
<gl-sprintf
|
||||
:message="
|
||||
s__(
|
||||
'ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{pricingLink}.',
|
||||
'ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{linkStart}pricing%{linkEnd}.',
|
||||
)
|
||||
"
|
||||
>
|
||||
<template #pricingLink>
|
||||
<template #link="{ content }">
|
||||
<gl-link href="https://cloud.google.com/compute/pricing#lb" target="_blank">{{
|
||||
s__('ClusterIntegration|pricing')
|
||||
content
|
||||
}}</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
|
@ -357,18 +339,16 @@ export default {
|
|||
title-link="https://cert-manager.readthedocs.io/en/latest/#"
|
||||
>
|
||||
<template #description>
|
||||
<p>
|
||||
<p data-testid="certManagerDescription">
|
||||
<gl-sprintf
|
||||
:message="
|
||||
s__(`ClusterIntegration|Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates.
|
||||
Installing Cert-Manager on your cluster will issue a certificate by %{letsEncrypt} and ensure that certificates
|
||||
Installing Cert-Manager on your cluster will issue a certificate by %{linkStart}Let's Encrypt%{linkEnd} and ensure that certificates
|
||||
are valid and up-to-date.`)
|
||||
"
|
||||
>
|
||||
<template #letsEncrypt>
|
||||
<gl-link href="https://letsencrypt.org/" target="_blank">{{
|
||||
s__(`ClusterIntegration|Let's Encrypt`)
|
||||
}}</gl-link>
|
||||
<template #link="{ content }">
|
||||
<gl-link href="https://letsencrypt.org/" target="_blank">{{ content }}</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</p>
|
||||
|
@ -388,7 +368,7 @@ export default {
|
|||
<p class="form-text text-muted">
|
||||
{{
|
||||
s__(`ClusterIntegration|Issuers represent a certificate authority.
|
||||
You must provide an email address for your Issuer. `)
|
||||
You must provide an email address for your Issuer.`)
|
||||
}}
|
||||
<gl-link
|
||||
href="http://docs.cert-manager.io/en/latest/reference/issuers.html?highlight=email"
|
||||
|
@ -417,20 +397,22 @@ export default {
|
|||
title-link="https://prometheus.io/docs/introduction/overview/"
|
||||
>
|
||||
<template #description>
|
||||
<gl-sprintf
|
||||
:message="
|
||||
s__(`ClusterIntegration|Prometheus is an open-source monitoring system
|
||||
with %{gitlabIntegrationLink} to monitor deployed applications.`)
|
||||
"
|
||||
>
|
||||
<template #gitlabIntegrationLink>
|
||||
<gl-link
|
||||
href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html"
|
||||
target="_blank"
|
||||
>{{ s__('ClusterIntegration|Gitlab Integration') }}</gl-link
|
||||
>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
<span data-testid="prometheusDescription">
|
||||
<gl-sprintf
|
||||
:message="
|
||||
s__(`ClusterIntegration|Prometheus is an open-source monitoring system
|
||||
with %{linkStart}GitLab Integration%{linkEnd} to monitor deployed applications.`)
|
||||
"
|
||||
>
|
||||
<template #link="{ content }">
|
||||
<gl-link
|
||||
href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html"
|
||||
target="_blank"
|
||||
>{{ content }}</gl-link
|
||||
>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</span>
|
||||
</template>
|
||||
</application-row>
|
||||
<application-row
|
||||
|
@ -481,11 +463,11 @@ export default {
|
|||
title-link="https://crossplane.io"
|
||||
>
|
||||
<template #description>
|
||||
<p>
|
||||
<p data-testid="crossplaneDescription">
|
||||
<gl-sprintf
|
||||
:message="
|
||||
s__(
|
||||
`ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}.
|
||||
`ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{linkStart}GitLab Integration%{linkEnd}.
|
||||
Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on.`,
|
||||
)
|
||||
"
|
||||
|
@ -493,11 +475,11 @@ export default {
|
|||
<template #code="{content}">
|
||||
<code>{{ content }}</code>
|
||||
</template>
|
||||
<template #gitlabIntegrationLink>
|
||||
<template #link="{ content }">
|
||||
<gl-link
|
||||
href="https://docs.gitlab.com/ee/user/clusters/applications.html#crossplane"
|
||||
target="_blank"
|
||||
>{{ s__('ClusterIntegration|Gitlab Integration') }}</gl-link
|
||||
>{{ content }}</gl-link
|
||||
>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
|
@ -584,7 +566,6 @@ export default {
|
|||
hostname: applications.knative.hostname,
|
||||
pages_domain_id: applications.knative.pagesDomain && applications.knative.pagesDomain.id,
|
||||
}"
|
||||
:installed-via="installedVia"
|
||||
:uninstallable="applications.knative.uninstallable"
|
||||
:uninstall-successful="applications.knative.uninstallSuccessful"
|
||||
:uninstall-failed="applications.knative.uninstallFailed"
|
||||
|
@ -618,6 +599,17 @@ export default {
|
|||
@set="setKnativeDomain"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="cloudRun" #installedVia>
|
||||
<span data-testid="installedVia">
|
||||
<gl-sprintf
|
||||
:message="s__('ClusterIntegration|installed via %{linkStart}Cloud Run%{linkEnd}')"
|
||||
>
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="cloudRunHelpPath" target="_blank">{{ content }}</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</span>
|
||||
</template>
|
||||
</application-row>
|
||||
<application-row
|
||||
id="elastic_stack"
|
||||
|
|
|
@ -21,6 +21,21 @@ const chartGridLeft = 75;
|
|||
|
||||
// Axis options
|
||||
|
||||
/**
|
||||
* Axis types
|
||||
* @see https://echarts.apache.org/en/option.html#xAxis.type
|
||||
*/
|
||||
export const axisTypes = {
|
||||
/**
|
||||
* Category axis, suitable for discrete category data.
|
||||
*/
|
||||
category: 'category',
|
||||
/**
|
||||
* Time axis, suitable for continuous time series data.
|
||||
*/
|
||||
time: 'time',
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts .yml parameters to echarts axis options for data axis
|
||||
* @param {Object} param - Dashboard .yml definition options
|
||||
|
@ -61,7 +76,7 @@ export const getYAxisOptions = ({
|
|||
|
||||
export const getTimeAxisOptions = ({ timezone = timezones.LOCAL } = {}) => ({
|
||||
name: __('Time'),
|
||||
type: 'time',
|
||||
type: axisTypes.time,
|
||||
axisLabel: {
|
||||
formatter: date => formatDate(date, { format: formats.shortTime, timezone }),
|
||||
},
|
||||
|
|
|
@ -4,6 +4,8 @@ import { GlStackedColumnChart } from '@gitlab/ui/dist/charts';
|
|||
import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
|
||||
import { chartHeight } from '../../constants';
|
||||
import { graphDataValidatorForValues } from '../../utils';
|
||||
import { getTimeAxisOptions, axisTypes } from './options';
|
||||
import { timezones } from '../../format_date';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -18,6 +20,11 @@ export default {
|
|||
required: true,
|
||||
validator: graphDataValidatorForValues.bind(null, false),
|
||||
},
|
||||
timezone: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: timezones.LOCAL,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -28,7 +35,14 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
chartData() {
|
||||
return this.graphData.metrics.map(metric => metric.result[0].values.map(val => val[1]));
|
||||
return this.graphData.metrics.map(({ result }) => {
|
||||
// This needs a fix. Not only metrics[0] should be shown.
|
||||
// See https://gitlab.com/gitlab-org/gitlab/-/issues/220492
|
||||
if (!result || result.length === 0) {
|
||||
return [];
|
||||
}
|
||||
return result[0].values.map(val => val[1]);
|
||||
});
|
||||
},
|
||||
xAxisTitle() {
|
||||
return this.graphData.x_label !== undefined ? this.graphData.x_label : '';
|
||||
|
@ -37,10 +51,17 @@ export default {
|
|||
return this.graphData.y_label !== undefined ? this.graphData.y_label : '';
|
||||
},
|
||||
xAxisType() {
|
||||
return this.graphData.x_type !== undefined ? this.graphData.x_type : 'category';
|
||||
// stacked-column component requires the x-axis to be of type `category`
|
||||
return axisTypes.category;
|
||||
},
|
||||
groupBy() {
|
||||
return this.graphData.metrics[0].result[0].values.map(val => val[0]);
|
||||
// This needs a fix. Not only metrics[0] should be shown.
|
||||
// See https://gitlab.com/gitlab-org/gitlab/-/issues/220492
|
||||
const { result } = this.graphData.metrics[0];
|
||||
if (!result || result.length === 0) {
|
||||
return [];
|
||||
}
|
||||
return result[0].values.map(val => val[0]);
|
||||
},
|
||||
dataZoomConfig() {
|
||||
const handleIcon = this.svgs['scroll-handle'];
|
||||
|
@ -49,11 +70,15 @@ export default {
|
|||
},
|
||||
chartOptions() {
|
||||
return {
|
||||
dataZoom: this.dataZoomConfig,
|
||||
xAxis: {
|
||||
...getTimeAxisOptions({ timezone: this.timezone }),
|
||||
type: this.xAxisType,
|
||||
},
|
||||
dataZoom: [this.dataZoomConfig],
|
||||
};
|
||||
},
|
||||
seriesNames() {
|
||||
return this.graphData.metrics.map(metric => metric.series_name);
|
||||
return this.graphData.metrics.map(metric => metric.label);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
|
|
@ -46,6 +46,14 @@ export default {
|
|||
isApplying() {
|
||||
return this.isApplyingSingle || this.isApplyingBatch;
|
||||
},
|
||||
tooltipMessage() {
|
||||
return this.canApply
|
||||
? __('This also resolves the discussion')
|
||||
: __("Can't apply as this line has changed or the suggestion already matches its content.");
|
||||
},
|
||||
isDisableButton() {
|
||||
return this.isApplying || !this.canApply;
|
||||
},
|
||||
applyingSuggestionsMessage() {
|
||||
if (this.isApplyingSingle || this.batchSuggestionsCount < 2) {
|
||||
return __('Applying suggestion...');
|
||||
|
@ -110,23 +118,24 @@ export default {
|
|||
</span>
|
||||
</gl-deprecated-button>
|
||||
</div>
|
||||
<div v-else-if="canApply" class="d-flex align-items-center">
|
||||
<div v-else class="d-flex align-items-center">
|
||||
<gl-deprecated-button
|
||||
class="btn-inverted js-add-to-batch-btn btn-grouped"
|
||||
:disabled="isApplying"
|
||||
:disabled="isDisableButton"
|
||||
@click="addSuggestionToBatch"
|
||||
>
|
||||
{{ __('Add suggestion to batch') }}
|
||||
</gl-deprecated-button>
|
||||
<gl-deprecated-button
|
||||
v-gl-tooltip.viewport="__('This also resolves the thread')"
|
||||
class="btn-inverted js-apply-btn btn-grouped"
|
||||
:disabled="isApplying"
|
||||
variant="success"
|
||||
@click="applySuggestion"
|
||||
>
|
||||
{{ __('Apply suggestion') }}
|
||||
</gl-deprecated-button>
|
||||
<span v-gl-tooltip.viewport="tooltipMessage" tabindex="0">
|
||||
<gl-deprecated-button
|
||||
class="btn-inverted js-apply-btn btn-grouped"
|
||||
:disabled="isDisableButton"
|
||||
variant="success"
|
||||
@click="applySuggestion"
|
||||
>
|
||||
{{ __('Apply suggestion') }}
|
||||
</gl-deprecated-button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add date time format to the monitor stacked-column chart
|
||||
merge_request: 33814
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Show disabled suggestion button with tooltip message
|
||||
merge_request: 33357
|
||||
author:
|
||||
type: changed
|
|
@ -106,10 +106,5 @@ Doorkeeper.configure do
|
|||
# WWW-Authenticate Realm (default "Doorkeeper").
|
||||
# realm "Doorkeeper"
|
||||
|
||||
# Allow dynamic query parameters (disabled by default)
|
||||
# Some applications require dynamic query parameters on their request_uri
|
||||
# set to true if you want this to be allowed
|
||||
# wildcard_redirect_uri false
|
||||
|
||||
base_controller '::Gitlab::BaseDoorkeeperController'
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ Alibaba
|
|||
allowlist
|
||||
allowlisting
|
||||
allowlists
|
||||
anonymized
|
||||
Ansible
|
||||
Anthos
|
||||
API
|
||||
|
@ -62,8 +63,11 @@ burndown
|
|||
cacheable
|
||||
CAS
|
||||
CentOS
|
||||
Certbot
|
||||
chai
|
||||
Chatops
|
||||
chatbot
|
||||
chatbots
|
||||
ChatOps
|
||||
checksummed
|
||||
checksumming
|
||||
Citrix
|
||||
|
@ -96,6 +100,7 @@ deduplicated
|
|||
deduplicates
|
||||
deduplicating
|
||||
deduplication
|
||||
deliverables
|
||||
denylist
|
||||
denylisting
|
||||
denylists
|
||||
|
@ -105,6 +110,9 @@ deprovision
|
|||
deprovisioned
|
||||
deprovisioning
|
||||
deprovisions
|
||||
dequarantine
|
||||
dequarantined
|
||||
dequarantining
|
||||
DevOps
|
||||
discoverability
|
||||
Disqus
|
||||
|
@ -133,6 +141,7 @@ failovers
|
|||
failsafe
|
||||
fastlane
|
||||
favicon
|
||||
Filebeat
|
||||
Fio
|
||||
firewalled
|
||||
Flawfinder
|
||||
|
@ -199,12 +208,14 @@ jsdom
|
|||
JupyterHub
|
||||
kanban
|
||||
kanbans
|
||||
Kaniko
|
||||
Karma
|
||||
Kerberos
|
||||
Kibana
|
||||
Kinesis
|
||||
Knative
|
||||
Kramdown
|
||||
kubectl
|
||||
Kubernetes
|
||||
Kubesec
|
||||
Laravel
|
||||
|
@ -226,6 +237,8 @@ Makefile
|
|||
Makefiles
|
||||
Markdown
|
||||
markdownlint
|
||||
matcher
|
||||
matchers
|
||||
Mattermost
|
||||
mbox
|
||||
memoization
|
||||
|
@ -260,6 +273,8 @@ nameservers
|
|||
namespace
|
||||
namespaced
|
||||
namespaces
|
||||
namespacing
|
||||
namespacings
|
||||
Nanoc
|
||||
NGINX
|
||||
Nokogiri
|
||||
|
@ -278,6 +293,7 @@ Packagist
|
|||
parallelization
|
||||
parallelizations
|
||||
passwordless
|
||||
Patroni
|
||||
performant
|
||||
phaser
|
||||
phasers
|
||||
|
@ -327,6 +343,8 @@ Redcarpet
|
|||
Redis
|
||||
Redmine
|
||||
reCAPTCHA
|
||||
redirection
|
||||
redirections
|
||||
refactorings
|
||||
referer
|
||||
referers
|
||||
|
@ -343,6 +361,7 @@ requeue
|
|||
requeued
|
||||
requeues
|
||||
reusability
|
||||
Restlet
|
||||
resynced
|
||||
resyncing
|
||||
resyncs
|
||||
|
@ -368,6 +387,8 @@ Salesforce
|
|||
SAML
|
||||
sandboxing
|
||||
sbt
|
||||
scatterplot
|
||||
scatterplots
|
||||
Sendmail
|
||||
Sentry
|
||||
serverless
|
||||
|
@ -421,6 +442,7 @@ substrings
|
|||
syslog
|
||||
tcpdump
|
||||
Tiller
|
||||
timecop
|
||||
todos
|
||||
tokenizer
|
||||
Tokenizers
|
||||
|
@ -432,13 +454,15 @@ tooltips
|
|||
Trello
|
||||
triaging
|
||||
TypeScript
|
||||
Twilio
|
||||
Twitter
|
||||
Ubuntu
|
||||
unarchive
|
||||
unarchived
|
||||
unarchives
|
||||
Unassign
|
||||
Unassigns
|
||||
unarchiving
|
||||
unassign
|
||||
unassigns
|
||||
uncheck
|
||||
unchecked
|
||||
unchecking
|
||||
|
@ -482,10 +506,12 @@ unresolve
|
|||
unresolved
|
||||
unresolving
|
||||
unschedule
|
||||
unscoped
|
||||
unstage
|
||||
unstaged
|
||||
unstages
|
||||
unstaging
|
||||
unstarted
|
||||
unstash
|
||||
unstashed
|
||||
unstashing
|
||||
|
@ -504,6 +530,8 @@ validator
|
|||
validators
|
||||
vendored
|
||||
versionless
|
||||
viewport
|
||||
viewports
|
||||
virtualized
|
||||
virtualizing
|
||||
Vue
|
||||
|
|
|
@ -30,10 +30,6 @@ The GitLab **primary** node where the write operations happen will connect to
|
|||
the **primary** database server, and **secondary** nodes will
|
||||
connect to their own database servers (which are also read-only).
|
||||
|
||||
NOTE: **Note:**
|
||||
In database documentation, you may see "**primary**" being referenced as "master"
|
||||
and "**secondary**" as either "slave" or "standby" server (read-only).
|
||||
|
||||
We recommend using [PostgreSQL replication slots](https://medium.com/@tk512/replication-slots-in-postgresql-b4b03d277c75)
|
||||
to ensure that the **primary** node retains all the data necessary for the **secondary** nodes to
|
||||
recover. See below for more details.
|
||||
|
|
|
@ -147,7 +147,7 @@ To run several tests inside one directory:
|
|||
|
||||
### Speed up tests, Rake tasks, and migrations
|
||||
|
||||
[Spring](https://github.com/rails/spring) is a Rails application preloader. It
|
||||
[Spring](https://github.com/rails/spring) is a Rails application pre-loader. It
|
||||
speeds up development by keeping your application running in the background so
|
||||
you don't need to boot it every time you run a test, Rake task or migration.
|
||||
|
||||
|
@ -203,9 +203,9 @@ To generate a sprite file containing all the Emoji, run:
|
|||
bundle exec rake gemojione:sprite
|
||||
```
|
||||
|
||||
If new emoji are added, the spritesheet may change size. To compensate for
|
||||
such changes, first generate the `emoji.png` spritesheet with the above Rake
|
||||
task, then check the dimensions of the new spritesheet and update the
|
||||
If new emoji are added, the sprite sheet may change size. To compensate for
|
||||
such changes, first generate the `emoji.png` sprite sheet with the above Rake
|
||||
task, then check the dimensions of the new sprite sheet and update the
|
||||
`SPRITESHEET_WIDTH` and `SPRITESHEET_HEIGHT` constants accordingly.
|
||||
|
||||
## Update project templates
|
||||
|
|
|
@ -76,6 +76,6 @@ To get started, see an [example merge request](https://gitlab.com/gitlab-org/git
|
|||
|
||||
## Useful links
|
||||
|
||||
- [Routing improvements masterplan](https://gitlab.com/gitlab-org/gitlab/-/issues/215362)
|
||||
- [Routing improvements master plan](https://gitlab.com/gitlab-org/gitlab/-/issues/215362)
|
||||
- [Scoped routing explained](https://gitlab.com/gitlab-org/gitlab/-/issues/214217)
|
||||
- [Removal of deprecated routes](https://gitlab.com/gitlab-org/gitlab/-/issues/28848)
|
||||
|
|
|
@ -8,8 +8,8 @@ The measuring module is a tool that allows to measure a service's execution, and
|
|||
|
||||
- Service class name
|
||||
- Execution time
|
||||
- Number of sql calls
|
||||
- Detailed gc stats and diffs
|
||||
- Number of SQL calls
|
||||
- Detailed `gc` stats and diffs
|
||||
- RSS memory usage
|
||||
- Server worker ID
|
||||
|
||||
|
@ -74,7 +74,7 @@ In the following example, the `:gitlab_service_measuring_projects_import_service
|
|||
[feature flag](feature_flags/development.md#enabling-a-feature-flag-in-development) is used to enable the measuring feature
|
||||
for `Projects::ImportService`.
|
||||
|
||||
From chatops:
|
||||
From ChatOps:
|
||||
|
||||
```shell
|
||||
/chatops run feature set gitlab_service_measuring_projects_import_service true
|
||||
|
|
|
@ -78,7 +78,7 @@ As a general rule, a worker can be considered idempotent if:
|
|||
|
||||
- It can safely run multiple times with the same arguments.
|
||||
- Application side-effects are expected to happen only once
|
||||
(or side-effects of a second run are not impactful).
|
||||
(or side-effects of a second run do not have an effect).
|
||||
|
||||
A good example of that would be a cache expiration worker.
|
||||
|
||||
|
@ -156,7 +156,7 @@ named `disable_<queue name>_deduplication`. For example to disable
|
|||
deduplication for the `AuthorizedProjectsWorker`, we would enable the
|
||||
feature flag `disable_authorized_projects_deduplication`.
|
||||
|
||||
From chatops:
|
||||
From ChatOps:
|
||||
|
||||
```shell
|
||||
/chatops run feature set disable_authorized_projects_deduplication true
|
||||
|
@ -272,10 +272,10 @@ annotated with the `worker_resource_boundary` method.
|
|||
|
||||
Most workers tend to spend most of their time blocked, wait on network responses
|
||||
from other services such as Redis, PostgreSQL, and Gitaly. Since Sidekiq is a
|
||||
multithreaded environment, these jobs can be scheduled with high concurrency.
|
||||
multi-threaded environment, these jobs can be scheduled with high concurrency.
|
||||
|
||||
Some workers, however, spend large amounts of time _on-CPU_ running logic in
|
||||
Ruby. Ruby MRI does not support true multithreading - it relies on the
|
||||
Ruby. Ruby MRI does not support true multi-threading - it relies on the
|
||||
[GIL](https://thoughtbot.com/blog/untangling-ruby-threads#the-global-interpreter-lock)
|
||||
to greatly simplify application development by only allowing one section of Ruby
|
||||
code in a process to run at a time, no matter how many cores the machine
|
||||
|
@ -427,7 +427,7 @@ isn't picked up by the cops. In any case, please leave a code-comment
|
|||
pointing to which context will be used when disabling the cops.
|
||||
|
||||
When you do provide objects to the context, please make sure that the
|
||||
route for namespaces and projects is preloaded. This can be done using
|
||||
route for namespaces and projects is pre-loaded. This can be done using
|
||||
the `.with_route` scope defined on all `Routable`s.
|
||||
|
||||
### Cron-Workers
|
||||
|
@ -591,7 +591,7 @@ to be merged and deployed before additional changes are merged.
|
|||
1. In a further merge request, update `ExampleWorker.perform_async` calls to
|
||||
use the new argument.
|
||||
|
||||
##### Parameter hash
|
||||
##### Parameter hash
|
||||
|
||||
This approach will not require multiple deployments if an existing worker already
|
||||
utilizes a parameter hash.
|
||||
|
|
|
@ -113,9 +113,9 @@ sequenceDiagram
|
|||
## How Usage Ping works
|
||||
|
||||
1. The Usage Ping [cron job](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/workers/gitlab_usage_ping_worker.rb#L30) is set in Sidekiq to run weekly.
|
||||
1. When the cron job runs, it calls [GitLab::UsageData.to_json](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/submit_usage_ping_service.rb#L22).
|
||||
1. GitLab::UsageData.to_json [cascades down](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb#L22) to ~400+ other counter method calls.
|
||||
1. The response of all methods calls are [merged together](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb#L14) into a single JSON payload in GitLab::UsageData.to_json.
|
||||
1. When the cron job runs, it calls [`GitLab::UsageData.to_json`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/submit_usage_ping_service.rb#L22).
|
||||
1. `GitLab::UsageData.to_json` [cascades down](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb#L22) to ~400+ other counter method calls.
|
||||
1. The response of all methods calls are [merged together](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb#L14) into a single JSON payload in `GitLab::UsageData.to_json`.
|
||||
1. The JSON payload is then [posted to the Versions application]( https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/submit_usage_ping_service.rb#L20).
|
||||
|
||||
## Implementing Usage Ping
|
||||
|
@ -136,12 +136,12 @@ For large tables, PostgreSQL can take a long time to count rows due to MVCC [(Mu
|
|||
|
||||
For GitLab.com, there are extremely large tables with 15 second query timeouts, so we use batch counting to avoid encountering timeouts. Here are the sizes of some GitLab.com tables:
|
||||
|
||||
| Table | Row counts in millions |
|
||||
|----------------------------|------------------------|
|
||||
| merge_request_diff_commits | 2280 |
|
||||
| ci_build_trace_sections | 1764 |
|
||||
| merge_request_diff_files | 1082 |
|
||||
| events | 514 |
|
||||
| Table | Row counts in millions |
|
||||
|------------------------------|------------------------|
|
||||
| `merge_request_diff_commits` | 2280 |
|
||||
| `ci_build_trace_sections` | 1764 |
|
||||
| `merge_request_diff_files` | 1082 |
|
||||
| `events` | 514 |
|
||||
|
||||
There are two batch counting methods provided, `Ordinary Batch Counters` and `Distinct Batch Counters`. Batch counting requires indexes on columns to calculate max, min, and range queries. In some cases, a specialized index may need to be added on the columns involved in a counter.
|
||||
|
||||
|
@ -204,7 +204,7 @@ Method: `redis_usage_data(counter, &block)`
|
|||
Arguments:
|
||||
|
||||
- `counter`: a counter from `Gitlab::UsageDataCounters`, that has `fallback_totals` method implemented
|
||||
- or a `block`: wich is evaluated
|
||||
- or a `block`: which is evaluated
|
||||
|
||||
Example of usage:
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ Feature.enabled?(:ci_live_trace) # => false
|
|||
If you wish to set up a test where a feature flag is enabled only
|
||||
for some actors and not others, you can specify this in options
|
||||
passed to the helper. For example, to enable the `ci_live_trace`
|
||||
feature flag for a specifc project:
|
||||
feature flag for a specific project:
|
||||
|
||||
```ruby
|
||||
project1, project2 = build_list(:project, 2)
|
||||
|
@ -347,7 +347,7 @@ This represents an actual behavior of FlipperGate:
|
|||
|
||||
1. You can enable an override for a specified actor to be enabled
|
||||
1. You can disable (remove) an override for a specified actor,
|
||||
fallbacking to default state
|
||||
falling back to default state
|
||||
1. There's no way to model that you explicitly disable a specified actor
|
||||
|
||||
```ruby
|
||||
|
@ -467,7 +467,7 @@ However, if a spec makes direct Redis calls, it should mark itself with the
|
|||
#### Background jobs / Sidekiq
|
||||
|
||||
By default, Sidekiq jobs are enqueued into a jobs array and aren't processed.
|
||||
If a test enqueues Sidekiq jobs and need them to be processed, the
|
||||
If a test queues Sidekiq jobs and need them to be processed, the
|
||||
`:sidekiq_inline` trait can be used.
|
||||
|
||||
The `:sidekiq_might_not_need_inline` trait was added when [Sidekiq inline mode was
|
||||
|
@ -723,7 +723,7 @@ module Spec
|
|||
end
|
||||
```
|
||||
|
||||
Helpers should not change the RSpec config. For instance, the helpers module
|
||||
Helpers should not change the RSpec configuration. For instance, the helpers module
|
||||
described above should not include:
|
||||
|
||||
```ruby
|
||||
|
@ -784,9 +784,9 @@ end
|
|||
This will create a repository containing two files, with default permissions and
|
||||
the specified content.
|
||||
|
||||
### Config
|
||||
### Configuration
|
||||
|
||||
RSpec config files are files that change the RSpec config (i.e.
|
||||
RSpec configuration files are files that change the RSpec configuration (i.e.
|
||||
`RSpec.configure do |config|` blocks). They should be placed under
|
||||
`spec/support/`.
|
||||
|
||||
|
@ -805,7 +805,7 @@ RSpec.configure do |config|
|
|||
end
|
||||
```
|
||||
|
||||
If a config file only consists of `config.include`, you can add these
|
||||
If a configuration file only consists of `config.include`, you can add these
|
||||
`config.include` directly in `spec/spec_helper.rb`.
|
||||
|
||||
For very generic helpers, consider including them in the `spec/support/rspec.rb`
|
||||
|
|
|
@ -89,7 +89,7 @@ end
|
|||
|
||||
### Defining Elements
|
||||
|
||||
The `view` DSL method will correspond to the rails View, partial, or vue component that renders the elements.
|
||||
The `view` DSL method will correspond to the rails View, partial, or Vue component that renders the elements.
|
||||
|
||||
The `element` DSL method in turn declares an element for which a corresponding
|
||||
`data-qa-selector=element_name_snaked` data attribute will need to be added to the view file.
|
||||
|
@ -134,7 +134,7 @@ view 'app/views/my/view.html.haml' do
|
|||
end
|
||||
```
|
||||
|
||||
To add these elements to the view, you must change the rails View, partial, or vue component by adding a `data-qa-selector` attribute
|
||||
To add these elements to the view, you must change the rails View, partial, or Vue component by adding a `data-qa-selector` attribute
|
||||
for each element defined.
|
||||
|
||||
In our case, `data-qa-selector="login_field"`, `data-qa-selector="password_field"` and `data-qa-selector="sign_in_button"`
|
||||
|
@ -149,7 +149,7 @@ In our case, `data-qa-selector="login_field"`, `data-qa-selector="password_field
|
|||
|
||||
Things to note:
|
||||
|
||||
- The name of the element and the qa_selector must match and be snake_cased
|
||||
- The name of the element and the `qa_selector` must match and be snake_cased
|
||||
- If the element appears on the page unconditionally, add `required: true` to the element. See
|
||||
[Dynamic element validation](dynamic_element_validation.md)
|
||||
- You may see `.qa-selector` classes in existing Page Objects. We should prefer the [`data-qa-selector`](#data-qa-selector-vs-qa-selector)
|
||||
|
@ -255,7 +255,7 @@ These steps ensure the sanity selectors check will detect problems properly.
|
|||
|
||||
For example, `qa/qa/ee/page/merge_request/show.rb` adds EE-specific methods to `qa/qa/page/merge_request/show.rb` (with
|
||||
`QA::Page::MergeRequest::Show.prepend_if_ee('QA::EE::Page::MergeRequest::Show')`) and following is how it's implemented
|
||||
(only showing the relevant part and refering to the 4 steps described above with inline comments):
|
||||
(only showing the relevant part and referring to the 4 steps described above with inline comments):
|
||||
|
||||
```ruby
|
||||
module QA
|
||||
|
|
|
@ -24,7 +24,7 @@ To run the tests from the `/qa` directory:
|
|||
CHROME_HEADLESS=false bin/qa Test::Instance::All http://localhost -- qa/specs/features/ee/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb
|
||||
```
|
||||
|
||||
The test will automatically spinup a Docker container for Jenkins and tear down once the test completes.
|
||||
The test will automatically spin up a Docker container for Jenkins and tear down once the test completes.
|
||||
|
||||
However, if you need to run Jenkins manually outside of the tests, use this command:
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ Notice that in the above example, before clicking the `:operations_environments_
|
|||
|
||||
When adding new elements to a page, it's important that we have a uniform element naming convention.
|
||||
|
||||
We follow a simple formula roughly based on hungarian notation.
|
||||
We follow a simple formula roughly based on Hungarian notation.
|
||||
|
||||
*Formula*: `element :<descriptor>_<type>`
|
||||
|
||||
|
@ -109,7 +109,7 @@ we use the name of the page object in [snake_case](https://en.wikipedia.org/wiki
|
|||
(all lowercase, with words separated by an underscore). See good and bad examples below.
|
||||
|
||||
While we prefer to follow the standard in most cases, it is also acceptable to
|
||||
use common abbreviations (e.g., mr) or other alternatives, as long as
|
||||
use common abbreviations (e.g., `mr`) or other alternatives, as long as
|
||||
the name is not ambiguous. This can include appending `_page` if it helps to
|
||||
avoid confusion or make the code more readable. For example, if a page object is
|
||||
named `New`, it could be confusing to name the block argument `new` because that
|
||||
|
|
|
@ -49,7 +49,7 @@ examples in a JSON report file on `master` (`retrieve-tests-metadata` and
|
|||
|
||||
This was originally implemented in: <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13021>.
|
||||
|
||||
If you want to enable retries locally, you can use the `RETRIES` env variable.
|
||||
If you want to enable retries locally, you can use the `RETRIES` environment variable.
|
||||
For instance `RETRIES=1 bin/rspec ...` would retry the failing examples once.
|
||||
|
||||
## Problems we had in the past at GitLab
|
||||
|
@ -79,11 +79,11 @@ For instance `RETRIES=1 bin/rspec ...` would retry the failing examples once.
|
|||
- [Bis](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34609#note_34048715): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12604>
|
||||
- [Bis](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34698#note_34276286): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12664>
|
||||
- [Assert against the underlying database state instead of against a page's content](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/31437): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10934>
|
||||
- In JS tests, shifting elements can cause Capybara to misclick when the element moves at the exact time Capybara sends the click
|
||||
- In JS tests, shifting elements can cause Capybara to mis-click when the element moves at the exact time Capybara sends the click
|
||||
- [Dropdowns rendering upward or downward due to window size and scroll position](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17660)
|
||||
- [Lazy loaded images can cause Capybara to misclick](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18713)
|
||||
- [Lazy loaded images can cause Capybara to mis-click](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18713)
|
||||
- [Triggering JS events before the event handlers are set up](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18742)
|
||||
- [Wait for the image to be lazy-loaded when asserting on a Markdown image's src attribute](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25408)
|
||||
- [Wait for the image to be lazy-loaded when asserting on a Markdown image's `src` attribute](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25408)
|
||||
|
||||
#### Capybara viewport size related issues
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@ subgraph "CNG-mirror pipeline"
|
|||
each component (e.g. `gitlab-rails-ee`, `gitlab-shell`, `gitaly` etc.)
|
||||
based on the commit from the [GitLab pipeline](https://gitlab.com/gitlab-org/gitlab/pipelines/125315730) and stores
|
||||
them in its [registry](https://gitlab.com/gitlab-org/build/CNG-mirror/container_registry).
|
||||
- We use the [`CNG-mirror`](https://gitlab.com/gitlab-org/build/CNG-mirror) project so that the `CNG`, (**C**loud
|
||||
**N**ative **G**itLab), project's registry is not overloaded with a
|
||||
- We use the [`CNG-mirror`](https://gitlab.com/gitlab-org/build/CNG-mirror) project so that the `CNG`, (Cloud
|
||||
Native GitLab), project's registry is not overloaded with a
|
||||
lot of transient Docker images.
|
||||
- Note that the official CNG images are built by the `cloud-native-image`
|
||||
job, which runs only for tags, and triggers itself a [`CNG`](https://gitlab.com/gitlab-org/build/CNG) pipeline.
|
||||
|
@ -139,8 +139,8 @@ browser performance testing using a
|
|||
The `review-apps-ee` and `review-apps-ce` clusters are currently set up with
|
||||
the following node pools:
|
||||
|
||||
- `review-apps-ee` of preemptible `e2-highcpu-16` (16 vCPU, 16 GB memory) nodes with autoscaling
|
||||
- `review-apps-ce` of preemptible `n1-standard-8` (8 vCPU, 16 GB memory) nodes with autoscaling
|
||||
- `review-apps-ee` of pre-emptible `e2-highcpu-16` (16 vCPU, 16 GB memory) nodes with autoscaling
|
||||
- `review-apps-ce` of pre-emptible `n1-standard-8` (8 vCPU, 16 GB memory) nodes with autoscaling
|
||||
|
||||
### Helm
|
||||
|
||||
|
@ -278,14 +278,14 @@ kubectl top pods | sort --key 2 --numeric
|
|||
|
||||
**Potential cause:**
|
||||
|
||||
This could be a sign that there are too many stale secrets and/or config maps.
|
||||
This could be a sign that there are too many stale secrets and/or configuration maps.
|
||||
|
||||
**Where to look for further debugging:**
|
||||
|
||||
Look at [the list of Configurations](https://console.cloud.google.com/kubernetes/config?project=gitlab-review-apps)
|
||||
or `kubectl get secret,cm --sort-by='{.metadata.creationTimestamp}' | grep 'review-'`.
|
||||
|
||||
Any secrets or config maps older than 5 days are suspect and should be deleted.
|
||||
Any secrets or configuration maps older than 5 days are suspect and should be deleted.
|
||||
|
||||
**Useful commands:**
|
||||
|
||||
|
@ -354,7 +354,7 @@ For the record, the debugging steps to find out this issue were:
|
|||
1. Web search for exact error message, following rabbit hole to [a relevant Kubernetes bug report](https://github.com/kubernetes/kubernetes/issues/57345)
|
||||
1. Access the node over SSH via the GCP console (**Computer Engine > VM
|
||||
instances** then click the "SSH" button for the node where the `dns-gitlab-review-app-external-dns` pod runs)
|
||||
1. In the node: `systemctl --version` => systemd 232
|
||||
1. In the node: `systemctl --version` => `systemd 232`
|
||||
1. Gather some more information:
|
||||
- `mount | grep kube | wc -l` => e.g. 290
|
||||
- `systemctl list-units --all | grep -i var-lib-kube | wc -l` => e.g. 142
|
||||
|
|
|
@ -198,8 +198,7 @@ There are quite a few different types of nodes, so we only cover some of the
|
|||
more common ones here.
|
||||
|
||||
A full list of all the available nodes and their descriptions can be found in
|
||||
the [PostgreSQL source file
|
||||
"plannodes.h"](https://gitlab.com/postgres/postgres/blob/master/src/include/nodes/plannodes.h)
|
||||
the [PostgreSQL source file `plannodes.h`](https://gitlab.com/postgres/postgres/blob/master/src/include/nodes/plannodes.h)
|
||||
|
||||
### Seq Scan
|
||||
|
||||
|
@ -686,11 +685,11 @@ Planning time: 0.411 ms
|
|||
Execution time: 0.113 ms
|
||||
```
|
||||
|
||||
### Chatops
|
||||
### ChatOps
|
||||
|
||||
[GitLab employees can also use our chatops solution, available in Slack using the
|
||||
[GitLab employees can also use our ChatOps solution, available in Slack using the
|
||||
`/chatops` slash command](chatops_on_gitlabcom.md).
|
||||
You can use chatops to get a query plan by running the following:
|
||||
You can use ChatOps to get a query plan by running the following:
|
||||
|
||||
```sql
|
||||
/chatops run explain SELECT COUNT(*) FROM projects WHERE visibility_level IN (0, 20)
|
||||
|
@ -719,7 +718,7 @@ with their own clone of the production database.
|
|||
Joe is available in the
|
||||
[`#database-lab`](https://gitlab.slack.com/archives/CLJMDRD8C) channel on Slack.
|
||||
|
||||
Unlike chatops, it gives you a way to execute DDL statements (like creating indexes and tables) and get query plan not only for `SELECT` but also `UPDATE` and `DELETE`.
|
||||
Unlike ChatOps, it gives you a way to execute DDL statements (like creating indexes and tables) and get query plan not only for `SELECT` but also `UPDATE` and `DELETE`.
|
||||
|
||||
For example, in order to test new index you can do the following:
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ We can identify three major use-cases for an upload:
|
|||
|
||||
1. **storage:** if we are uploading for storing a file (i.e. artifacts, packages, discussion attachments). In this case [direct upload](#direct-upload) is the proper level as it's the less resource-intensive operation. Additional information can be found on [File Storage in GitLab](file_storage.md).
|
||||
1. **in-controller/synchronous processing:** if we allow processing **small files** synchronously, using [disk buffered upload](#disk-buffered-upload) may speed up development.
|
||||
1. **Sidekiq/asynchronous processing:** Async processing must implement [direct upload](#direct-upload), the reason being that it's the only way to support Cloud Native deployments without a shared NFS.
|
||||
1. **Sidekiq/asynchronous processing:** Asynchronous processing must implement [direct upload](#direct-upload), the reason being that it's the only way to support Cloud Native deployments without a shared NFS.
|
||||
|
||||
For more details about currently broken feature see [epic &1802](https://gitlab.com/groups/gitlab-org/-/epics/1802).
|
||||
|
||||
|
@ -128,7 +128,7 @@ This is the default kind of upload, and it's most expensive in terms of resource
|
|||
|
||||
In this case, workhorse is unaware of files being uploaded and acts as a regular proxy.
|
||||
|
||||
When a multipart request reaches the rails application, `Rack::Multipart` leaves behind tempfiles in `/tmp` and uses valuable Ruby process time to copy files around.
|
||||
When a multipart request reaches the rails application, `Rack::Multipart` leaves behind temporary files in `/tmp` and uses valuable Ruby process time to copy files around.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
|
|
@ -49,7 +49,7 @@ Refer to: <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/mer
|
|||
|
||||
## `Override`
|
||||
|
||||
Refer to <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/override.rb>:
|
||||
Refer to [`override.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/override.rb):
|
||||
|
||||
- This utility can help you check if one method would override
|
||||
another or not. It is the same concept as Java's `@Override` annotation
|
||||
|
@ -153,7 +153,7 @@ Refer to <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/stro
|
|||
|
||||
## `RequestCache`
|
||||
|
||||
Refer to <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/cache/request_cache.rb>.
|
||||
Refer to [`request_cache.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/cache/request_cache.rb).
|
||||
|
||||
This module provides a simple way to cache values in RequestStore,
|
||||
and the cache key would be based on the class name, method name,
|
||||
|
|
|
@ -47,7 +47,7 @@ There is a chance that your Google Cloud group may already have an image
|
|||
built. Search the available images before you do the work to build your
|
||||
own.
|
||||
|
||||
Build a Google Cloud image with the above shared runners repo by doing the following:
|
||||
Build a Google Cloud image with the above shared runners repository by doing the following:
|
||||
|
||||
1. Install [Packer](https://www.packer.io/) (tested to work with version 1.5.1).
|
||||
1. Install Packer Windows Update Provisioner.
|
||||
|
@ -55,7 +55,7 @@ Build a Google Cloud image with the above shared runners repo by doing the follo
|
|||
1. Run the command `go build -o packer-provisioner-windows-update` (requires `go` to be installed).
|
||||
1. Verify `packer-provisioner-windows-update` is in the `PATH` environment variable.
|
||||
1. Add all [required environment variables](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/-/blob/master/packer.json#L2-10)
|
||||
in the `packer.json` file to your environment (perhaps use [direnv](https://direnv.net/)).
|
||||
in the `packer.json` file to your environment (perhaps use [`direnv`](https://direnv.net/)).
|
||||
1. Build the image by running the command: `packer build packer.json`.
|
||||
|
||||
## How to use a Windows image in GCP
|
||||
|
@ -96,7 +96,7 @@ Here are a few tips on GCP and Windows.
|
|||
### GCP cost savings
|
||||
|
||||
To minimise the cost of your GCP VM instance, stop it when you're not using it.
|
||||
If you do, you'll need to redownload the RDP file from the console as the IP
|
||||
If you do, you'll need to re-download the RDP file from the console as the IP
|
||||
address changes every time you stop and start it.
|
||||
|
||||
### chocolatey
|
||||
|
@ -119,13 +119,13 @@ You can install .NET version 3 support with the following `DISM` command:
|
|||
|
||||
`DISM /Online /Enable-Feature /FeatureName:NetFx3 /All`
|
||||
|
||||
### nix -> Windows cmd tips
|
||||
### nix -> Windows `cmd` tips
|
||||
|
||||
The first tip for using the Windows command shell is to open Powershell and use that instead.
|
||||
The first tip for using the Windows command shell is to open PowerShell and use that instead.
|
||||
|
||||
Start Powershell: `start powershell`.
|
||||
Start PowerShell: `start powershell`.
|
||||
|
||||
Powershell has aliases for all of the following commands so you don't have to learn the native commands:
|
||||
PowerShell has aliases for all of the following commands so you don't have to learn the native commands:
|
||||
|
||||
- `ls` ---> `dir`
|
||||
- `rm` ---> `del`
|
||||
|
|
|
@ -172,6 +172,8 @@ level with `NICENESS`. Below are the valid levels, but consult
|
|||
|
||||
## Remove expired ActiveSession lookup keys
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30668) in GitLab 12.2.
|
||||
|
||||
```shell
|
||||
# omnibus-gitlab
|
||||
sudo gitlab-rake gitlab:cleanup:sessions:active_sessions_lookup_keys
|
||||
|
|
|
@ -33,7 +33,7 @@ of the box through its main components:
|
|||
- [Serving](https://github.com/knative/serving): Request-driven compute that can scale to zero.
|
||||
- [Eventing](https://github.com/knative/eventing): Management and delivery of events.
|
||||
|
||||
For more information on Knative, visit the [Knative docs repo](https://github.com/knative/docs).
|
||||
For more information on Knative, visit the [Knative docs repository](https://github.com/knative/docs).
|
||||
|
||||
With GitLab Serverless, you can deploy both functions-as-a-service (FaaS) and serverless applications.
|
||||
|
||||
|
@ -61,14 +61,14 @@ To run Knative on GitLab, you will need:
|
|||
wildcard domain where your applications will be served. Configure your DNS server to use the
|
||||
external IP address or hostname for that domain.
|
||||
1. **`.gitlab-ci.yml`:** GitLab uses [Kaniko](https://github.com/GoogleContainerTools/kaniko)
|
||||
to build the application. We also use [gitlabktl](https://gitlab.com/gitlab-org/gitlabktl)
|
||||
to build the application. We also use [GitLab Knative tool](https://gitlab.com/gitlab-org/gitlabktl)
|
||||
CLI to simplify the deployment of services and functions to Knative.
|
||||
1. **`serverless.yml`** (for [functions only](#deploying-functions)): When using serverless to deploy functions, the `serverless.yml` file
|
||||
will contain the information for all the functions being hosted in the repository as well as a reference to the
|
||||
runtime being used.
|
||||
1. **`Dockerfile`** (for [applications only](#deploying-serverless-applications)): Knative requires a
|
||||
`Dockerfile` in order to build your applications. It should be included at the root of your
|
||||
project's repo and expose port `8080`. `Dockerfile` is not require if you plan to build serverless functions
|
||||
project's repository and expose port `8080`. `Dockerfile` is not require if you plan to build serverless functions
|
||||
using our [runtimes](https://gitlab.com/gitlab-org/serverless/runtimes).
|
||||
1. **Prometheus** (optional): Installing Prometheus allows you to monitor the scale and traffic of your serverless function/application.
|
||||
See [Installing Applications](../index.md#installing-applications) for more information.
|
||||
|
@ -97,9 +97,9 @@ The minimum recommended cluster size to run Knative is 3-nodes, 6 vCPUs, and 22.
|
|||
1. The Ingress is now available at this address and will route incoming requests to the proper service based on the DNS
|
||||
name in the request. To support this, a wildcard DNS record should be created for the desired domain name. For example,
|
||||
if your Knative base domain is `knative.info` then you need to create an A record or CNAME record with domain `*.knative.info`
|
||||
pointing the ip address or hostname of the Ingress.
|
||||
pointing the IP address or hostname of the Ingress.
|
||||
|
||||
![dns entry](img/dns-entry.png)
|
||||
![DNS entry](img/dns-entry.png)
|
||||
|
||||
NOTE: **Note:**
|
||||
You can deploy either [functions](#deploying-functions) or [serverless applications](#deploying-serverless-applications)
|
||||
|
@ -318,7 +318,7 @@ Explanation of the fields used above:
|
|||
|-----------|-------------|
|
||||
| `name` | Indicates which provider is used to execute the `serverless.yml` file. In this case, the TriggerMesh middleware. |
|
||||
| `envs` | Includes the environment variables to be passed as part of function execution for **all** functions in the file, where `FOO` is the variable name and `BAR` are the variable contents. You may replace this with your own variables. |
|
||||
| `secrets` | Includes the contents of the Kubernetes secret as environment variables accessible to be passed as part of function execution for **all** functions in the file. The secrets are expected in ini format. |
|
||||
| `secrets` | Includes the contents of the Kubernetes secret as environment variables accessible to be passed as part of function execution for **all** functions in the file. The secrets are expected in INI format. |
|
||||
|
||||
### `functions`
|
||||
|
||||
|
@ -332,7 +332,7 @@ subsequent lines contain the function attributes.
|
|||
| `runtime` (optional)| The runtime to be used to execute the function. This can be a runtime alias (see [Runtime aliases](#runtime-aliases)), or it can be a full URL to a custom runtime repository. When the runtime is not specified, we assume that `Dockerfile` is present in the function directory specified by `source`. |
|
||||
| `description` | A short description of the function. |
|
||||
| `envs` | Sets an environment variable for the specific function only. |
|
||||
| `secrets` | Includes the contents of the Kubernetes secret as environment variables accessible to be passed as part of function execution for the specific function only. The secrets are expected in ini format. |
|
||||
| `secrets` | Includes the contents of the Kubernetes secret as environment variables accessible to be passed as part of function execution for the specific function only. The secrets are expected in INI format. |
|
||||
|
||||
### Deployment
|
||||
|
||||
|
@ -384,7 +384,7 @@ The sample function can now be triggered from any HTTP client using a simple `PO
|
|||
http://functions-echo.functions-1.functions.example.com/
|
||||
```
|
||||
|
||||
1. Using a web-based tool (ie. postman, restlet, etc)
|
||||
1. Using a web-based tool (such as Postman or Restlet)
|
||||
|
||||
![function execution](img/function-execution.png)
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ For more information regarding the SubGit configuration options, refer to
|
|||
|
||||
### Initial translation
|
||||
|
||||
Now that SubGit has configured the Git/SVN repos, run `subgit` to perform the
|
||||
Now that SubGit has configured the Git/SVN repositories, run `subgit` to perform the
|
||||
initial translation of existing SVN revisions into the Git repository:
|
||||
|
||||
```shell
|
||||
|
|
|
@ -397,6 +397,7 @@ Read the documentation on [templating](#templating-variables-for-metrics-dashboa
|
|||
| -------- | ---- | -------- | ----------- |
|
||||
| `url` | string | yes | The address of the link. |
|
||||
| `title` | string | no | Display title for the link. |
|
||||
| `type` | string | no | Type of the link. Specifies the link type, can be: `grafana` |
|
||||
|
||||
Read the documentation on [links](#add-related-links-to-custom-dashboards).
|
||||
|
||||
|
@ -844,9 +845,14 @@ templating:
|
|||
Related links can be added to the top of your metrics dashboard, which can be used for quickly
|
||||
navigating between dashboards or external services. The links will open in the same tab.
|
||||
|
||||
The dashboard's time range is appended to the `url` as URL parameters.
|
||||
|
||||
The `url` attribute is required for the link but the `title` attribute is optional; if the `title`
|
||||
is missing then the full address of the URL will be displayed.
|
||||
|
||||
The `type` attribute is optional; if the `type` is `grafana`, the dashboard's time range values are
|
||||
converted to Grafana's time range format and appended to the `url`.
|
||||
|
||||
![Links UI](img/related_links_v13_1.png)
|
||||
|
||||
#### Links Syntax
|
||||
|
@ -857,6 +863,9 @@ links:
|
|||
url: https://gitlab.com
|
||||
- title: GitLab Documentation
|
||||
url: https://docs.gitlab.com
|
||||
- title: Public Grafana playground dashboard
|
||||
url: https://play.grafana.org/d/000000012/grafana-play-home?orgId=1
|
||||
type: grafana
|
||||
```
|
||||
|
||||
### View and edit the source file of a custom dashboard
|
||||
|
|
|
@ -4,7 +4,7 @@ You can configure GitLab to send notifications to a Webex Teams space.
|
|||
|
||||
## Create a webhook for the space
|
||||
|
||||
1. Go to the [Incoming Webooks app page](https://apphub.webex.com/teams/applications/incoming-webhooks-cisco-systems).
|
||||
1. Go to the [Incoming Webhooks app page](https://apphub.webex.com/teams/applications/incoming-webhooks-cisco-systems).
|
||||
1. Click **Connect** and log in to Webex Teams, if required.
|
||||
1. Enter a name for the webhook and select the space that will receive the notifications.
|
||||
1. Click **ADD**.
|
||||
|
|
|
@ -68,7 +68,7 @@ Navigate to the **Design Management** page from any issue by clicking the **Desi
|
|||
To upload design images, click the **Upload Designs** button and select images to upload.
|
||||
|
||||
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9,
|
||||
you can drag and drop designs onto the dedicated dropzone to upload them.
|
||||
you can drag and drop designs onto the dedicated drop zone to upload them.
|
||||
|
||||
![Drag and drop design uploads](img/design_drag_and_drop_uploads_v12_9.png)
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ context, such as past work, dependencies, or duplicates.
|
|||
|
||||
### Crosslinking issues
|
||||
|
||||
You can [crosslink issues](crosslinking_issues.md) by referencing an issue from another
|
||||
You can [cross-link issues](crosslinking_issues.md) by referencing an issue from another
|
||||
issue or merge request by including its URL or ID. The referenced issue displays a
|
||||
message in the Activity stream about the reference, with a link to the other issue or MR.
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ in a Merge Request. To do so, click the **...** button in the gutter of the Merg
|
|||
If you've set up [GitLab CI/CD](../../../ci/README.md) in your project,
|
||||
you will be able to see:
|
||||
|
||||
- Both pre and post-merge pipelines and the environment information if any.
|
||||
- Both pre-merge and post-merge pipelines and the environment information if any.
|
||||
- Which deployments are in progress.
|
||||
|
||||
If there's an [environment](../../../ci/environments/index.md) and the application is
|
||||
|
|
|
@ -52,5 +52,5 @@ You can take some **optional** further steps:
|
|||
|
||||
![Change repo's path](../img/change_path_v12_10.png)
|
||||
|
||||
- Now go to your SSG's config file and change the [base URL](../getting_started_part_one.md#urls-and-baseurls)
|
||||
- Now go to your SSG's configuration file and change the [base URL](../getting_started_part_one.md#urls-and-baseurls)
|
||||
from `"project-name"` to `""`. The project name setting varies by SSG and may not be in the config file.
|
||||
|
|
|
@ -55,7 +55,7 @@ To update a GitLab Pages website:
|
|||
|
||||
| Document | Description |
|
||||
| -------- | ----------- |
|
||||
| [GitLab Pages domain names, URLs, and baseurls](getting_started_part_one.md) | Learn about GitLab Pages default domains. |
|
||||
| [GitLab Pages domain names, URLs, and base URLs](getting_started_part_one.md) | Learn about GitLab Pages default domains. |
|
||||
| [Explore GitLab Pages](introduction.md) | Requirements, technical aspects, specific GitLab CI/CD configuration options, Access Control, custom 404 pages, limitations, FAQ. |
|
||||
| [Custom domains and SSL/TLS Certificates](custom_domains_ssl_tls_certification/index.md) | Custom domains and subdomains, DNS records, and SSL/TLS certificates. |
|
||||
| [Let's Encrypt integration](custom_domains_ssl_tls_certification/lets_encrypt_integration.md) | Secure your Pages sites with Let's Encrypt certificates, which are automatically obtained and renewed by GitLab. |
|
||||
|
|
|
@ -25,7 +25,7 @@ In brief, this is what you need to upload your website in GitLab Pages:
|
|||
1. Domain of the instance: domain name that is used for GitLab Pages
|
||||
(ask your administrator).
|
||||
1. GitLab CI/CD: a `.gitlab-ci.yml` file with a specific job named [`pages`](../../../ci/yaml/README.md#pages) in the root directory of your repository.
|
||||
1. A directory called `public` in your site's repo containing the content
|
||||
1. A directory called `public` in your site's repository containing the content
|
||||
to be published.
|
||||
1. GitLab Runner enabled for the project.
|
||||
|
||||
|
@ -87,7 +87,7 @@ will be deleted.
|
|||
|
||||
When using Pages under the general domain of a GitLab instance (`*.example.io`),
|
||||
you _cannot_ use HTTPS with sub-subdomains. That means that if your
|
||||
username/groupname contains a dot, for example `foo.bar`, the domain
|
||||
username or group name contains a dot, for example `foo.bar`, the domain
|
||||
`https://foo.bar.example.io` will _not_ work. This is a limitation of the
|
||||
[HTTP Over TLS protocol](https://tools.ietf.org/html/rfc2818#section-3.1). HTTP pages will continue to work provided you
|
||||
don't redirect HTTP to HTTPS.
|
||||
|
|
|
@ -105,7 +105,7 @@ operating systems the steps might be slightly different. Follow the
|
|||
therefore, it needs to be part of the website content under the
|
||||
repo's [`public`](index.md#how-it-works) folder.
|
||||
|
||||
1. Add, commit, and push the file into your repo in GitLab. Once the pipeline
|
||||
1. Add, commit, and push the file into your repository in GitLab. Once the pipeline
|
||||
passes, press **Enter** on your terminal to continue issuing your
|
||||
certificate. CertBot will then prompt you with the following message:
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ You can use [repository mirroring](repository_mirroring.md) to keep your fork sy
|
|||
|
||||
The main difference is that with repository mirroring your remote fork will be automatically kept up-to-date.
|
||||
|
||||
Without mirroring, to work locally you'll have to use `git pull` to update your local repo
|
||||
Without mirroring, to work locally you'll have to use `git pull` to update your local repository
|
||||
with the upstream project, then push the changes back to your fork to update it.
|
||||
|
||||
CAUTION: **Caution:**
|
||||
|
|
|
@ -27,7 +27,7 @@ that you [connect with GitLab via SSH](../../../ssh/README.md).
|
|||
|
||||
## Files
|
||||
|
||||
Use a repository to store your files in GitLab. From [GitLab 12.10 onwards](https://gitlab.com/gitlab-org/gitlab/-/issues/33806),
|
||||
Use a repository to store your files in GitLab. In [GitLab 12.10 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/33806),
|
||||
you'll see on the repository's file tree an icon next to the file name
|
||||
according to its extension:
|
||||
|
||||
|
@ -84,9 +84,9 @@ according to the markup language.
|
|||
| [AsciiDoc](../../asciidoc.md) | `adoc`, `ad`, `asciidoc` |
|
||||
| [Textile](https://textile-lang.com/) | `textile` |
|
||||
| [rdoc](http://rdoc.sourceforge.net/doc/index.html) | `rdoc` |
|
||||
| [Orgmode](https://orgmode.org/) | `org` |
|
||||
| [Org mode](https://orgmode.org/) | `org` |
|
||||
| [creole](http://www.wikicreole.org/) | `creole` |
|
||||
| [Mediawiki](https://www.mediawiki.org/wiki/MediaWiki) | `wiki`, `mediawiki` |
|
||||
| [MediaWiki](https://www.mediawiki.org/wiki/MediaWiki) | `wiki`, `mediawiki` |
|
||||
|
||||
### Repository README and index files
|
||||
|
||||
|
@ -219,7 +219,9 @@ vendored code, and most markup languages are excluded. This behavior can be
|
|||
adjusted by overriding the default. For example, to enable `.proto` files to be
|
||||
detected, add the following to `.gitattributes` in the root of your repository.
|
||||
|
||||
> *.proto linguist-detectable=true
|
||||
```plaintext
|
||||
*.proto linguist-detectable=true
|
||||
```
|
||||
|
||||
## Locked files **(PREMIUM)**
|
||||
|
||||
|
|
|
@ -27,8 +27,7 @@ project](../settings/import_export.html#exporting-a-project-and-its-data).
|
|||
To make cloning your project faster, rewrite branches and tags to remove
|
||||
unwanted files.
|
||||
|
||||
1. [Install `git
|
||||
filter-repo`](https://github.com/newren/git-filter-repo/blob/master/INSTALL.md)
|
||||
1. [Install `git filter-repo`](https://github.com/newren/git-filter-repo/blob/master/INSTALL.md)
|
||||
using a supported package manager, or from source.
|
||||
|
||||
1. Clone a fresh copy of the repository using `--bare`.
|
||||
|
@ -52,8 +51,7 @@ unwanted files.
|
|||
git filter-repo --path path/to/big/file.m4v --invert-paths
|
||||
```
|
||||
|
||||
See the [`git filter-repo`
|
||||
documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES)
|
||||
See the [`git filter-repo` documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES)
|
||||
for more examples, and the complete documentation.
|
||||
|
||||
1. Force push your changes to overwrite all branches on GitLab.
|
||||
|
@ -81,8 +79,7 @@ unwanted files.
|
|||
|
||||
To reduce the size of your repository in GitLab you will need to remove GitLab
|
||||
internal refs that reference commits contain large files. Before completing
|
||||
these steps, first [purged files from your repository
|
||||
history](#purging-files-from-your-repository-history).
|
||||
these steps, first [purged files from your repository history](#purging-files-from-your-repository-history).
|
||||
|
||||
As well as branches and tags, which are a type of Git ref, GitLab automatically
|
||||
creates other refs. These refs prevent dead links to commits, or missing diffs
|
||||
|
@ -97,12 +94,10 @@ fetching faster. The hidden refs to prevent commits with discussion from being
|
|||
deleted (`refs/keep-around/*`) cannot be fetched at all. These refs can,
|
||||
however, be accessed from the Git bundle inside the project export.
|
||||
|
||||
1. [Install `git
|
||||
filter-repo`](https://github.com/newren/git-filter-repo/blob/master/INSTALL.md)
|
||||
1. [Install `git filter-repo`](https://github.com/newren/git-filter-repo/blob/master/INSTALL.md)
|
||||
using a supported package manager, or from source.
|
||||
|
||||
1. Generate a fresh [export the
|
||||
project](../settings/import_export.html#exporting-a-project-and-its-data) and
|
||||
1. Generate a fresh [export from the project](../settings/import_export.md#exporting-a-project-and-its-data) and
|
||||
download to your computer.
|
||||
|
||||
1. Decompress the backup using `tar`
|
||||
|
@ -111,8 +106,7 @@ however, be accessed from the Git bundle inside the project export.
|
|||
tar xzf project-backup.tar.gz
|
||||
```
|
||||
|
||||
This will contain a `project.bundle` file, which was created by [`git
|
||||
bundle`](https://git-scm.com/docs/git-bundle)
|
||||
This will contain a `project.bundle` file, which was created by [`git bundle`](https://git-scm.com/docs/git-bundle)
|
||||
|
||||
1. Clone a fresh copy of the repository from the bundle.
|
||||
|
||||
|
@ -142,8 +136,7 @@ however, be accessed from the Git bundle inside the project export.
|
|||
git filter-repo --path path/to/big/file.m4v --invert-paths
|
||||
```
|
||||
|
||||
See the [`git filter-repo`
|
||||
documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES)
|
||||
See the [`git filter-repo` documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES)
|
||||
for more examples, and the complete documentation.
|
||||
|
||||
1. After running `git filter-repo`, the header and unchanged commits need to be
|
||||
|
|
|
@ -65,11 +65,11 @@ git config --global gpg.format x509
|
|||
|
||||
### Windows and MacOS
|
||||
|
||||
Install [smimesign](https://github.com/github/smimesign) by downloading the
|
||||
Install [S/MIME Sign](https://github.com/github/smimesign) by downloading the
|
||||
installer or via `brew install smimesign` on MacOS.
|
||||
|
||||
Get the ID of your certificate with `smimesign --list-keys` and set your
|
||||
signingkey `git config --global user.signingkey ID`, then configure X.509:
|
||||
signing key `git config --global user.signingkey ID`, then configure X.509:
|
||||
|
||||
```shell
|
||||
git config --global gpg.x509.program smimesign
|
||||
|
|
|
@ -3826,6 +3826,9 @@ msgstr ""
|
|||
msgid "Can override approvers and approvals required per merge request"
|
||||
msgstr ""
|
||||
|
||||
msgid "Can't apply as this line has changed or the suggestion already matches its content."
|
||||
msgstr ""
|
||||
|
||||
msgid "Can't create snippet: %{err}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4741,7 +4744,7 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Cert-Manager"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing Cert-Manager on your cluster will issue a certificate by %{letsEncrypt} and ensure that certificates are valid and up-to-date."
|
||||
msgid "ClusterIntegration|Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing Cert-Manager on your cluster will issue a certificate by %{linkStart}Let's Encrypt%{linkEnd} and ensure that certificates are valid and up-to-date."
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
|
||||
|
@ -4768,9 +4771,6 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Clear the local cache of namespace and service accounts. This is necessary if your integration has become out of sync. The cache is repopulated during the next CI job that requires namespace and service accounts."
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Cloud Run"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Cluster being created"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4855,7 +4855,7 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Crossplane"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
|
||||
msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{linkStart}GitLab Integration%{linkEnd}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
|
||||
|
@ -4939,9 +4939,6 @@ msgstr ""
|
|||
msgid "ClusterIntegration|GitLab-managed cluster"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Gitlab Integration"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Global default"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4987,7 +4984,7 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Ingress gives you a way to route requests to services based on the request host or path, centralizing a number of services into a single entrypoint."
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{pricingLink}."
|
||||
msgid "ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{linkStart}pricing%{linkEnd}."
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Instance cluster"
|
||||
|
@ -5002,7 +4999,7 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Issuer Email"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Issuers represent a certificate authority. You must provide an email address for your Issuer. "
|
||||
msgid "ClusterIntegration|Issuers represent a certificate authority. You must provide an email address for your Issuer."
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Jupyter Hostname"
|
||||
|
@ -5074,9 +5071,6 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Learn more about instance Kubernetes clusters"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Let's Encrypt"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Loading IAM Roles"
|
||||
msgstr ""
|
||||
|
||||
|
@ -5188,7 +5182,7 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Prometheus"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Prometheus is an open-source monitoring system with %{gitlabIntegrationLink} to monitor deployed applications."
|
||||
msgid "ClusterIntegration|Prometheus is an open-source monitoring system with %{linkStart}GitLab Integration%{linkEnd} to monitor deployed applications."
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Provider details"
|
||||
|
@ -5515,15 +5509,12 @@ msgstr ""
|
|||
msgid "ClusterIntegration|documentation"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|installed via %{installed_via}"
|
||||
msgid "ClusterIntegration|installed via %{linkStart}Cloud Run%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|meets the requirements"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|pricing"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|sign up"
|
||||
msgstr ""
|
||||
|
||||
|
@ -22639,7 +22630,7 @@ msgstr ""
|
|||
msgid "This also resolves all related threads"
|
||||
msgstr ""
|
||||
|
||||
msgid "This also resolves the thread"
|
||||
msgid "This also resolves the discussion"
|
||||
msgstr ""
|
||||
|
||||
msgid "This application was created by %{link_to_owner}."
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Applications Cert-Manager application shows the correct description 1`] = `
|
||||
<p
|
||||
data-testid="certManagerDescription"
|
||||
>
|
||||
Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing Cert-Manager on your cluster will issue a certificate by
|
||||
<a
|
||||
class="gl-link"
|
||||
href="https://letsencrypt.org/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Let's Encrypt
|
||||
</a>
|
||||
and ensure that certificates are valid and up-to-date.
|
||||
</p>
|
||||
`;
|
||||
|
||||
exports[`Applications Crossplane application shows the correct description 1`] = `
|
||||
<p
|
||||
data-testid="crossplaneDescription"
|
||||
>
|
||||
Crossplane enables declarative provisioning of managed services from your cloud of choice using
|
||||
<code>
|
||||
kubectl
|
||||
</code>
|
||||
or
|
||||
<a
|
||||
class="gl-link"
|
||||
href="https://docs.gitlab.com/ee/user/clusters/applications.html#crossplane"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
GitLab Integration
|
||||
</a>
|
||||
. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on.
|
||||
</p>
|
||||
`;
|
||||
|
||||
exports[`Applications Ingress application shows the correct warning message 1`] = `
|
||||
<strong
|
||||
data-testid="ingressCostWarning"
|
||||
>
|
||||
Installing Ingress may incur additional costs. Learn more about
|
||||
<a
|
||||
class="gl-link"
|
||||
href="https://cloud.google.com/compute/pricing#lb"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
pricing
|
||||
</a>
|
||||
.
|
||||
</strong>
|
||||
`;
|
||||
|
||||
exports[`Applications Knative application shows the correct description 1`] = `
|
||||
<span
|
||||
data-testid="installedVia"
|
||||
>
|
||||
installed via
|
||||
<a
|
||||
class="gl-link"
|
||||
href=""
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
>
|
||||
Cloud Run
|
||||
</a>
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`Applications Prometheus application shows the correct description 1`] = `
|
||||
<span
|
||||
data-testid="prometheusDescription"
|
||||
>
|
||||
Prometheus is an open-source monitoring system with
|
||||
<a
|
||||
class="gl-link"
|
||||
href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
GitLab Integration
|
||||
</a>
|
||||
to monitor deployed applications.
|
||||
</span>
|
||||
`;
|
|
@ -1,6 +1,6 @@
|
|||
import { shallowMount, mount } from '@vue/test-utils';
|
||||
import Applications from '~/clusters/components/applications.vue';
|
||||
import { CLUSTER_TYPE } from '~/clusters/constants';
|
||||
import { CLUSTER_TYPE, PROVIDER_TYPE } from '~/clusters/constants';
|
||||
import { APPLICATIONS_MOCK_STATE } from '../services/mock_data';
|
||||
import eventHub from '~/clusters/event_hub';
|
||||
import ApplicationRow from '~/clusters/components/application_row.vue';
|
||||
|
@ -30,7 +30,7 @@ describe('Applications', () => {
|
|||
};
|
||||
|
||||
const createShallowApp = options => createApp(options, true);
|
||||
|
||||
const findByTestId = id => wrapper.find(`[data-testid="${id}"]`);
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
@ -187,6 +187,11 @@ describe('Applications', () => {
|
|||
});
|
||||
|
||||
describe('Ingress application', () => {
|
||||
it('shows the correct warning message', () => {
|
||||
createApp();
|
||||
expect(findByTestId('ingressCostWarning').element).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('with nested component', () => {
|
||||
const propsData = {
|
||||
applications: {
|
||||
|
@ -280,113 +285,125 @@ describe('Applications', () => {
|
|||
expect(wrapper.find('.js-endpoint').exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Cert-Manager application', () => {
|
||||
describe('when not installed', () => {
|
||||
it('renders email & allows editing', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
cert_manager: {
|
||||
title: 'Cert-Manager',
|
||||
email: 'before@example.com',
|
||||
status: 'installable',
|
||||
},
|
||||
describe('Cert-Manager application', () => {
|
||||
it('shows the correct description', () => {
|
||||
createApp();
|
||||
expect(findByTestId('certManagerDescription').element).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('when not installed', () => {
|
||||
it('renders email & allows editing', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
cert_manager: {
|
||||
title: 'Cert-Manager',
|
||||
email: 'before@example.com',
|
||||
status: 'installable',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.find('.js-email').element.value).toEqual('before@example.com');
|
||||
expect(wrapper.find('.js-email').attributes('readonly')).toBe(undefined);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
describe('when installed', () => {
|
||||
it('renders email in readonly', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
cert_manager: {
|
||||
title: 'Cert-Manager',
|
||||
email: 'after@example.com',
|
||||
status: 'installed',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.find('.js-email').element.value).toEqual('after@example.com');
|
||||
expect(wrapper.find('.js-email').attributes('readonly')).toEqual('readonly');
|
||||
});
|
||||
expect(wrapper.find('.js-email').element.value).toEqual('before@example.com');
|
||||
expect(wrapper.find('.js-email').attributes('readonly')).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Jupyter application', () => {
|
||||
describe('with ingress installed with ip & jupyter installable', () => {
|
||||
it('renders hostname active input', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
ingress: {
|
||||
title: 'Ingress',
|
||||
status: 'installed',
|
||||
externalIp: '1.1.1.1',
|
||||
},
|
||||
describe('when installed', () => {
|
||||
it('renders email in readonly', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
cert_manager: {
|
||||
title: 'Cert-Manager',
|
||||
email: 'after@example.com',
|
||||
status: 'installed',
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
wrapper.find('.js-cluster-application-row-jupyter .js-hostname').attributes('readonly'),
|
||||
).toEqual(undefined);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
describe('with ingress installed without external ip', () => {
|
||||
it('does not render hostname input', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
ingress: { title: 'Ingress', status: 'installed' },
|
||||
expect(wrapper.find('.js-email').element.value).toEqual('after@example.com');
|
||||
expect(wrapper.find('.js-email').attributes('readonly')).toEqual('readonly');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Jupyter application', () => {
|
||||
describe('with ingress installed with ip & jupyter installable', () => {
|
||||
it('renders hostname active input', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
ingress: {
|
||||
title: 'Ingress',
|
||||
status: 'installed',
|
||||
externalIp: '1.1.1.1',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.find('.js-cluster-application-row-jupyter .js-hostname').exists()).toBe(
|
||||
false,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
wrapper.find('.js-cluster-application-row-jupyter .js-hostname').attributes('readonly'),
|
||||
).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with ingress installed without external ip', () => {
|
||||
it('does not render hostname input', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
ingress: { title: 'Ingress', status: 'installed' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.find('.js-cluster-application-row-jupyter .js-hostname').exists()).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with ingress & jupyter installed', () => {
|
||||
it('renders readonly input', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
ingress: { title: 'Ingress', status: 'installed', externalIp: '1.1.1.1' },
|
||||
jupyter: { title: 'JupyterHub', status: 'installed', hostname: '' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
wrapper.find('.js-cluster-application-row-jupyter .js-hostname').attributes('readonly'),
|
||||
).toEqual('readonly');
|
||||
});
|
||||
});
|
||||
|
||||
describe('without ingress installed', () => {
|
||||
beforeEach(() => {
|
||||
createApp();
|
||||
});
|
||||
|
||||
describe('with ingress & jupyter installed', () => {
|
||||
it('renders readonly input', () => {
|
||||
createApp({
|
||||
applications: {
|
||||
ingress: { title: 'Ingress', status: 'installed', externalIp: '1.1.1.1' },
|
||||
jupyter: { title: 'JupyterHub', status: 'installed', hostname: '' },
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
wrapper.find('.js-cluster-application-row-jupyter .js-hostname').attributes('readonly'),
|
||||
).toEqual('readonly');
|
||||
});
|
||||
it('does not render input', () => {
|
||||
expect(wrapper.find('.js-cluster-application-row-jupyter .js-hostname').exists()).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
describe('without ingress installed', () => {
|
||||
beforeEach(() => {
|
||||
createApp();
|
||||
});
|
||||
|
||||
it('does not render input', () => {
|
||||
expect(wrapper.find('.js-cluster-application-row-jupyter .js-hostname').exists()).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it('renders disabled install button', () => {
|
||||
expect(
|
||||
wrapper
|
||||
.find('.js-cluster-application-row-jupyter .js-cluster-application-install-button')
|
||||
.attributes('disabled'),
|
||||
).toEqual('disabled');
|
||||
});
|
||||
it('renders disabled install button', () => {
|
||||
expect(
|
||||
wrapper
|
||||
.find('.js-cluster-application-row-jupyter .js-cluster-application-install-button')
|
||||
.attributes('disabled'),
|
||||
).toEqual('disabled');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Prometheus application', () => {
|
||||
it('shows the correct description', () => {
|
||||
createApp();
|
||||
expect(findByTestId('prometheusDescription').element).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Knative application', () => {
|
||||
const availableDomain = {
|
||||
id: 4,
|
||||
|
@ -414,6 +431,18 @@ describe('Applications', () => {
|
|||
knativeDomainEditor = wrapper.find(KnativeDomainEditor);
|
||||
});
|
||||
|
||||
it('shows the correct description', async () => {
|
||||
createApp();
|
||||
wrapper.setProps({
|
||||
providerType: PROVIDER_TYPE.GCP,
|
||||
preInstalledKnative: true,
|
||||
});
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(findByTestId('installedVia').element).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('emits saveKnativeDomain event when knative domain editor emits save event', () => {
|
||||
propsData.applications.knative.hostname = availableDomain.domain;
|
||||
propsData.applications.knative.pagesDomain = availableDomain;
|
||||
|
@ -475,6 +504,11 @@ describe('Applications', () => {
|
|||
const crossplane = wrapper.find(CrossplaneProviderStack);
|
||||
expect(crossplane.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('shows the correct description', () => {
|
||||
createApp();
|
||||
expect(findByTestId('crossplaneDescription').element).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Elastic Stack application', () => {
|
||||
|
|
|
@ -1,45 +1,133 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import timezoneMock from 'timezone-mock';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { GlStackedColumnChart } from '@gitlab/ui/dist/charts';
|
||||
import StackedColumnChart from '~/monitoring/components/charts/stacked_column.vue';
|
||||
import { stackedColumnMockedData } from '../../mock_data';
|
||||
|
||||
jest.mock('~/lib/utils/icon_utils', () => ({
|
||||
getSvgIconPathContent: jest.fn().mockResolvedValue('mockSvgPathContent'),
|
||||
getSvgIconPathContent: jest.fn().mockImplementation(icon => Promise.resolve(`${icon}-content`)),
|
||||
}));
|
||||
|
||||
describe('Stacked column chart component', () => {
|
||||
let wrapper;
|
||||
const glStackedColumnChart = () => wrapper.find(GlStackedColumnChart);
|
||||
const findChart = () => wrapper.find(GlStackedColumnChart);
|
||||
|
||||
beforeEach(() => {
|
||||
const createWrapper = (props = {}) => {
|
||||
wrapper = shallowMount(StackedColumnChart, {
|
||||
propsData: {
|
||||
graphData: stackedColumnMockedData,
|
||||
...props,
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
describe('with graphData present', () => {
|
||||
it('is a Vue instance', () => {
|
||||
expect(glStackedColumnChart().exists()).toBe(true);
|
||||
describe('when graphData is present', () => {
|
||||
beforeEach(() => {
|
||||
createWrapper();
|
||||
return wrapper.vm.$nextTick();
|
||||
});
|
||||
|
||||
it('should contain the same number of elements in the seriesNames computed prop as the graphData metrics prop', () =>
|
||||
wrapper.vm
|
||||
.$nextTick()
|
||||
.then(expect(wrapper.vm.seriesNames).toHaveLength(stackedColumnMockedData.metrics.length)));
|
||||
it('chart is rendered', () => {
|
||||
expect(findChart().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should contain the same number of elements in the groupBy computed prop as the graphData result prop', () =>
|
||||
wrapper.vm
|
||||
.$nextTick()
|
||||
.then(
|
||||
expect(wrapper.vm.groupBy).toHaveLength(
|
||||
stackedColumnMockedData.metrics[0].result[0].values.length,
|
||||
),
|
||||
));
|
||||
it('data should match the graphData y value for each series', () => {
|
||||
const data = findChart().props('data');
|
||||
|
||||
data.forEach((series, index) => {
|
||||
const { values } = stackedColumnMockedData.metrics[index].result[0];
|
||||
expect(series).toEqual(values.map(value => value[1]));
|
||||
});
|
||||
});
|
||||
|
||||
it('series names should be the same as the graphData metrics labels', () => {
|
||||
const seriesNames = findChart().props('seriesNames');
|
||||
|
||||
expect(seriesNames).toHaveLength(stackedColumnMockedData.metrics.length);
|
||||
seriesNames.forEach((name, index) => {
|
||||
expect(stackedColumnMockedData.metrics[index].label).toBe(name);
|
||||
});
|
||||
});
|
||||
|
||||
it('group by should be the same as the graphData first metric results', () => {
|
||||
const groupBy = findChart().props('groupBy');
|
||||
|
||||
expect(groupBy).toEqual([
|
||||
'2020-01-30T12:00:00.000Z',
|
||||
'2020-01-30T12:01:00.000Z',
|
||||
'2020-01-30T12:02:00.000Z',
|
||||
]);
|
||||
});
|
||||
|
||||
it('chart options should configure data zoom and axis label ', () => {
|
||||
const chartOptions = findChart().props('option');
|
||||
const xAxisType = findChart().props('xAxisType');
|
||||
|
||||
expect(chartOptions).toMatchObject({
|
||||
dataZoom: [{ handleIcon: 'path://scroll-handle-content' }],
|
||||
xAxis: {
|
||||
axisLabel: { formatter: expect.any(Function) },
|
||||
},
|
||||
});
|
||||
|
||||
expect(xAxisType).toBe('category');
|
||||
});
|
||||
|
||||
it('chart options should configure category as x axis type', () => {
|
||||
const chartOptions = findChart().props('option');
|
||||
const xAxisType = findChart().props('xAxisType');
|
||||
|
||||
expect(chartOptions).toMatchObject({
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
},
|
||||
});
|
||||
expect(xAxisType).toBe('category');
|
||||
});
|
||||
|
||||
it('format date is correct', () => {
|
||||
const { xAxis } = findChart().props('option');
|
||||
expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('12:01 PM');
|
||||
});
|
||||
|
||||
describe('when in PT timezone', () => {
|
||||
beforeAll(() => {
|
||||
timezoneMock.register('US/Pacific');
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
timezoneMock.unregister();
|
||||
});
|
||||
|
||||
it('date is shown in local time', () => {
|
||||
const { xAxis } = findChart().props('option');
|
||||
expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('4:01 AM');
|
||||
});
|
||||
|
||||
it('date is shown in UTC', () => {
|
||||
wrapper.setProps({ timezone: 'UTC' });
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
const { xAxis } = findChart().props('option');
|
||||
expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('12:01 PM');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when graphData has results missing', () => {
|
||||
beforeEach(() => {
|
||||
const graphData = cloneDeep(stackedColumnMockedData);
|
||||
|
||||
graphData.metrics[0].result = null;
|
||||
|
||||
createWrapper({ graphData });
|
||||
return wrapper.vm.$nextTick();
|
||||
});
|
||||
|
||||
it('chart is rendered', () => {
|
||||
expect(findChart().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -467,9 +467,9 @@ export const stackedColumnMockedData = {
|
|||
{
|
||||
metric: {},
|
||||
values: [
|
||||
['2020-01-30 12:00:00', '5'],
|
||||
['2020-01-30 12:01:00', '10'],
|
||||
['2020-01-30 12:02:00', '15'],
|
||||
['2020-01-30T12:00:00.000Z', '5'],
|
||||
['2020-01-30T12:01:00.000Z', '10'],
|
||||
['2020-01-30T12:02:00.000Z', '15'],
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -485,9 +485,9 @@ export const stackedColumnMockedData = {
|
|||
{
|
||||
metric: {},
|
||||
values: [
|
||||
['2020-01-30 12:00:00', '20'],
|
||||
['2020-01-30 12:01:00', '25'],
|
||||
['2020-01-30 12:02:00', '30'],
|
||||
['2020-01-30T12:00:00.000Z', '20'],
|
||||
['2020-01-30T12:01:00.000Z', '25'],
|
||||
['2020-01-30T12:02:00.000Z', '30'],
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -88,21 +88,20 @@ describe('tags_table', () => {
|
|||
mountComponent();
|
||||
});
|
||||
|
||||
it('if selected adds item to selectedItems', () => {
|
||||
it('selecting and deselecting the checkbox works as intended', () => {
|
||||
findFirstRowItem('rowCheckbox').vm.$emit('change');
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
expect(wrapper.vm.selectedItems).toEqual([tags[0].name]);
|
||||
expect(findFirstRowItem('rowCheckbox').attributes('checked')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('if deselect remove name from selectedItems', () => {
|
||||
wrapper.setData({ selectedItems: [tags[0].name] });
|
||||
findFirstRowItem('rowCheckbox').vm.$emit('change');
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
expect(wrapper.vm.selectedItems.length).toBe(0);
|
||||
expect(findFirstRowItem('rowCheckbox').attributes('checked')).toBe(undefined);
|
||||
});
|
||||
return wrapper.vm
|
||||
.$nextTick()
|
||||
.then(() => {
|
||||
expect(wrapper.vm.selectedItems).toEqual([tags[0].name]);
|
||||
expect(findFirstRowItem('rowCheckbox').attributes('checked')).toBeTruthy();
|
||||
findFirstRowItem('rowCheckbox').vm.$emit('change');
|
||||
return wrapper.vm.$nextTick();
|
||||
})
|
||||
.then(() => {
|
||||
expect(wrapper.vm.selectedItems.length).toBe(0);
|
||||
expect(findFirstRowItem('rowCheckbox').attributes('checked')).toBe(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ describe('Image List', () => {
|
|||
});
|
||||
|
||||
it('emits a pageChange event when the page change', () => {
|
||||
wrapper.setData({ currentPage: 2 });
|
||||
findPagination().vm.$emit(GlPagination.model.event, 2);
|
||||
expect(wrapper.emitted('pageChange')).toEqual([[2]]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -174,7 +174,7 @@ describe('Details Page', () => {
|
|||
|
||||
it('fetch the data from the API when the v-model changes', () => {
|
||||
dispatchSpy.mockResolvedValue();
|
||||
wrapper.setData({ currentPage: 2 });
|
||||
findPagination().vm.$emit(GlPagination.model.event, 2);
|
||||
expect(store.dispatch).toHaveBeenCalledWith('requestTagsList', {
|
||||
params: wrapper.vm.$route.params.id,
|
||||
pagination: { page: 2 },
|
||||
|
|
|
@ -302,7 +302,7 @@ describe('List Page', () => {
|
|||
});
|
||||
|
||||
it('contains a description with the path of the item to delete', () => {
|
||||
wrapper.setData({ itemToDelete: { path: 'foo' } });
|
||||
findImageList().vm.$emit('delete', { path: 'foo' });
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
expect(findDeleteModal().html()).toContain('foo');
|
||||
});
|
||||
|
|
|
@ -63,11 +63,9 @@ describe('Suggestion Diff component', () => {
|
|||
expect(addToBatchBtn.html().includes('Add suggestion to batch')).toBe(true);
|
||||
});
|
||||
|
||||
it('does not render apply suggestion and add to batch buttons if `canApply` is set to false', () => {
|
||||
createComponent({ canApply: false });
|
||||
|
||||
expect(findApplyButton().exists()).toBe(false);
|
||||
expect(findAddToBatchButton().exists()).toBe(false);
|
||||
it('renders correct tooltip message for apply button', () => {
|
||||
createComponent();
|
||||
expect(wrapper.vm.tooltipMessage).toBe('This also resolves the discussion');
|
||||
});
|
||||
|
||||
describe('when apply suggestion is clicked', () => {
|
||||
|
@ -84,7 +82,7 @@ describe('Suggestion Diff component', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('hides apply suggestion and add to batch buttons', () => {
|
||||
it('does not render apply suggestion and add to batch buttons', () => {
|
||||
expect(findApplyButton().exists()).toBe(false);
|
||||
expect(findAddToBatchButton().exists()).toBe(false);
|
||||
});
|
||||
|
@ -205,4 +203,23 @@ describe('Suggestion Diff component', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('canApply is set to false', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ canApply: false });
|
||||
});
|
||||
|
||||
it('disables apply suggestion and add to batch buttons', () => {
|
||||
expect(findApplyButton().exists()).toBe(true);
|
||||
expect(findAddToBatchButton().exists()).toBe(true);
|
||||
expect(findApplyButton().attributes('disabled')).toBe('true');
|
||||
expect(findAddToBatchButton().attributes('disabled')).toBe('true');
|
||||
});
|
||||
|
||||
it('renders correct tooltip message for apply button', () => {
|
||||
expect(wrapper.vm.tooltipMessage).toBe(
|
||||
"Can't apply as this line has changed or the suggestion already matches its content.",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue