Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
5d3eac1cf8
commit
c1f785fe21
|
@ -5,6 +5,7 @@ tasks:
|
||||||
- name: GDK
|
- name: GDK
|
||||||
command: |
|
command: |
|
||||||
echo START_TIME_IN_SECONDS="$(date +%s)" | tee /workspace/gitpod_start_time.sh
|
echo START_TIME_IN_SECONDS="$(date +%s)" | tee /workspace/gitpod_start_time.sh
|
||||||
|
gp sync-done gitpod-start
|
||||||
gp sync-await gdk-copied && cd /workspace/gitlab-development-kit && gdk help
|
gp sync-await gdk-copied && cd /workspace/gitlab-development-kit && gdk help
|
||||||
|
|
||||||
- init: |
|
- init: |
|
||||||
|
@ -35,9 +36,10 @@ tasks:
|
||||||
)
|
)
|
||||||
command: |
|
command: |
|
||||||
(
|
(
|
||||||
|
gp sync-await gitpod-start
|
||||||
set -e
|
set -e
|
||||||
gp sync-done gdk-copied
|
gp sync-done gdk-copied
|
||||||
source /workspace/gitpod_start_time.sh
|
[[ -f /workspace/gitpod_start_time.sh ]] && source /workspace/gitpod_start_time.sh
|
||||||
SECONDS=0
|
SECONDS=0
|
||||||
cd /workspace/gitlab-development-kit
|
cd /workspace/gitlab-development-kit
|
||||||
# update GDK
|
# update GDK
|
||||||
|
@ -72,7 +74,7 @@ tasks:
|
||||||
git checkout db/structure.sql
|
git checkout db/structure.sql
|
||||||
cd /workspace/gitlab-development-kit
|
cd /workspace/gitlab-development-kit
|
||||||
# Waiting for GitLab ...
|
# Waiting for GitLab ...
|
||||||
gp await-port 3000
|
gp ports await 3000
|
||||||
printf "Waiting for GitLab at $(gp url 3000) ..."
|
printf "Waiting for GitLab at $(gp url 3000) ..."
|
||||||
# Check /-/readiness which returns JSON, but we're only interested in the exit code
|
# Check /-/readiness which returns JSON, but we're only interested in the exit code
|
||||||
#
|
#
|
||||||
|
@ -84,7 +86,7 @@ tasks:
|
||||||
printf "$(date) – GitLab is up (took ~%.1f minutes)\n" "$((10*$SECONDS/60))e-1" | tee -a /workspace/startup.log
|
printf "$(date) – GitLab is up (took ~%.1f minutes)\n" "$((10*$SECONDS/60))e-1" | tee -a /workspace/startup.log
|
||||||
gp preview $(gp url 3000) || true
|
gp preview $(gp url 3000) || true
|
||||||
PREBUILD_LOG=(/workspace/.gitpod/prebuild-log-*)
|
PREBUILD_LOG=(/workspace/.gitpod/prebuild-log-*)
|
||||||
printf "Took %.1f minutes from https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitpod.yml being executed through to completion %s\n" "$((10*(($(date +%s)-${START_TIME_IN_SECONDS}))/60))e-1" "$([[ -f "$PREBUILD_LOG" ]] && echo "With Prebuilds")"
|
[[ -f /workspace/gitpod_start_time.sh ]] && printf "Took %.1f minutes from https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitpod.yml being executed through to completion %s\n" "$((10*(($(date +%s)-${START_TIME_IN_SECONDS}))/60))e-1" "$([[ -f "$PREBUILD_LOG" ]] && echo "With Prebuilds")"
|
||||||
)
|
)
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
<script>
|
|
||||||
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
GlButton,
|
|
||||||
},
|
|
||||||
directives: {
|
|
||||||
GlTooltip: GlTooltipDirective,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
scrollUpButtonDisabled: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
scrollDownButtonDisabled: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
scrollUpAvailable: Boolean(this.$listeners.scrollUp),
|
|
||||||
scrollDownAvailable: Boolean(this.$listeners.scrollDown),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleRefreshClick() {
|
|
||||||
this.$emit('refresh');
|
|
||||||
},
|
|
||||||
handleScrollUp() {
|
|
||||||
this.$emit('scrollUp');
|
|
||||||
},
|
|
||||||
handleScrollDown() {
|
|
||||||
this.$emit('scrollDown');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
v-if="scrollUpAvailable"
|
|
||||||
v-gl-tooltip
|
|
||||||
class="controllers-buttons"
|
|
||||||
:title="__('Scroll to top')"
|
|
||||||
aria-labelledby="scroll-to-top"
|
|
||||||
>
|
|
||||||
<gl-button
|
|
||||||
id="scroll-to-top"
|
|
||||||
class="js-scroll-to-top gl-mr-2 btn-blank"
|
|
||||||
:aria-label="__('Scroll to top')"
|
|
||||||
:disabled="scrollUpButtonDisabled"
|
|
||||||
icon="scroll_up"
|
|
||||||
category="primary"
|
|
||||||
variant="default"
|
|
||||||
@click="handleScrollUp()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="scrollDownAvailable"
|
|
||||||
v-gl-tooltip
|
|
||||||
:disabled="scrollUpButtonDisabled"
|
|
||||||
class="controllers-buttons"
|
|
||||||
:title="__('Scroll to bottom')"
|
|
||||||
aria-labelledby="scroll-to-bottom"
|
|
||||||
>
|
|
||||||
<gl-button
|
|
||||||
id="scroll-to-bottom"
|
|
||||||
class="js-scroll-to-bottom gl-mr-2 btn-blank"
|
|
||||||
:aria-label="__('Scroll to bottom')"
|
|
||||||
:v-if="scrollDownAvailable"
|
|
||||||
:disabled="scrollDownButtonDisabled"
|
|
||||||
icon="scroll_down"
|
|
||||||
category="primary"
|
|
||||||
variant="default"
|
|
||||||
@click="handleScrollDown()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<gl-button
|
|
||||||
id="refresh-log"
|
|
||||||
v-gl-tooltip
|
|
||||||
class="js-refresh-log"
|
|
||||||
:title="__('Refresh')"
|
|
||||||
:aria-label="__('Refresh')"
|
|
||||||
icon="retry"
|
|
||||||
category="primary"
|
|
||||||
variant="default"
|
|
||||||
@click="handleRefreshClick"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,68 +0,0 @@
|
||||||
<script>
|
|
||||||
import { GlDropdown, GlDropdownSectionHeader, GlDropdownItem } from '@gitlab/ui';
|
|
||||||
import { mapActions, mapState } from 'vuex';
|
|
||||||
import { s__ } from '~/locale';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
GlDropdown,
|
|
||||||
GlDropdownSectionHeader,
|
|
||||||
GlDropdownItem,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchQuery: '',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState('environmentLogs', ['pods']),
|
|
||||||
|
|
||||||
podDropdownText() {
|
|
||||||
return this.pods.current || s__('Environments|No pod selected');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions('environmentLogs', ['showPodLogs']),
|
|
||||||
isCurrentPod(podName) {
|
|
||||||
return podName === this.pods.current;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<gl-dropdown
|
|
||||||
ref="podsDropdown"
|
|
||||||
:text="podDropdownText"
|
|
||||||
:disabled="disabled"
|
|
||||||
class="gl-mr-3 gl-mb-3 gl-display-flex gl-md-display-block qa-pods-dropdown"
|
|
||||||
>
|
|
||||||
<gl-dropdown-section-header>
|
|
||||||
{{ s__('Environments|Select pod') }}
|
|
||||||
</gl-dropdown-section-header>
|
|
||||||
|
|
||||||
<gl-dropdown-item v-if="!pods.options.length" disabled>
|
|
||||||
<span ref="noPodsMsg" class="text-muted">
|
|
||||||
{{ s__('Environments|No pods to display') }}
|
|
||||||
</span>
|
|
||||||
</gl-dropdown-item>
|
|
||||||
<gl-dropdown-item
|
|
||||||
v-for="podName in pods.options"
|
|
||||||
:key="podName"
|
|
||||||
:is-check-item="true"
|
|
||||||
:is-checked="isCurrentPod(podName)"
|
|
||||||
class="text-nowrap"
|
|
||||||
@click="showPodLogs(podName)"
|
|
||||||
>
|
|
||||||
{{ podName }}
|
|
||||||
</gl-dropdown-item>
|
|
||||||
</gl-dropdown>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,30 +0,0 @@
|
||||||
<script>
|
|
||||||
import { GlFilteredSearchToken, GlLoadingIcon } from '@gitlab/ui';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
GlFilteredSearchToken,
|
|
||||||
GlLoadingIcon,
|
|
||||||
},
|
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
|
||||||
config: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<gl-filtered-search-token :config="config" v-bind="{ ...$attrs }" v-on="$listeners">
|
|
||||||
<template #suggestions>
|
|
||||||
<div class="m-1">
|
|
||||||
<gl-loading-icon v-if="config.loading" size="sm" />
|
|
||||||
<div v-else class="py-1 px-2 text-muted">
|
|
||||||
{{ config.noOptionsText }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</gl-filtered-search-token>
|
|
||||||
</template>
|
|
|
@ -1,26 +0,0 @@
|
||||||
export const SET_PROJECT_ENVIRONMENT = 'SET_PROJECT_ENVIRONMENT';
|
|
||||||
export const SET_SEARCH = 'SET_SEARCH';
|
|
||||||
export const SET_MANAGED_APP = 'SET_MANAGED_APP';
|
|
||||||
|
|
||||||
export const SET_TIME_RANGE = 'SET_TIME_RANGE';
|
|
||||||
export const SHOW_TIME_RANGE_INVALID_WARNING = 'SHOW_TIME_RANGE_INVALID_WARNING';
|
|
||||||
export const HIDE_TIME_RANGE_INVALID_WARNING = 'HIDE_TIME_RANGE_INVALID_WARNING';
|
|
||||||
|
|
||||||
export const SET_CURRENT_POD_NAME = 'SET_CURRENT_POD_NAME';
|
|
||||||
|
|
||||||
export const REQUEST_ENVIRONMENTS_DATA = 'REQUEST_ENVIRONMENTS_DATA';
|
|
||||||
export const RECEIVE_ENVIRONMENTS_DATA_SUCCESS = 'RECEIVE_ENVIRONMENTS_DATA_SUCCESS';
|
|
||||||
export const RECEIVE_ENVIRONMENTS_DATA_ERROR = 'RECEIVE_ENVIRONMENTS_DATA_ERROR';
|
|
||||||
export const HIDE_REQUEST_ENVIRONMENTS_ERROR = 'HIDE_REQUEST_ENVIRONMENTS_ERROR';
|
|
||||||
|
|
||||||
export const REQUEST_LOGS_DATA = 'REQUEST_LOGS_DATA';
|
|
||||||
export const RECEIVE_LOGS_DATA_SUCCESS = 'RECEIVE_LOGS_DATA_SUCCESS';
|
|
||||||
export const RECEIVE_LOGS_DATA_ERROR = 'RECEIVE_LOGS_DATA_ERROR';
|
|
||||||
export const REQUEST_LOGS_DATA_PREPEND = 'REQUEST_LOGS_DATA_PREPEND';
|
|
||||||
export const RECEIVE_LOGS_DATA_PREPEND_SUCCESS = 'RECEIVE_LOGS_DATA_PREPEND_SUCCESS';
|
|
||||||
export const RECEIVE_LOGS_DATA_PREPEND_ERROR = 'RECEIVE_LOGS_DATA_PREPEND_ERROR';
|
|
||||||
export const HIDE_REQUEST_LOGS_ERROR = 'HIDE_REQUEST_LOGS_ERROR';
|
|
||||||
export const REFRESH_POD_LOGS = 'REFRESH_POD_LOGS';
|
|
||||||
|
|
||||||
export const RECEIVE_PODS_DATA_SUCCESS = 'RECEIVE_PODS_DATA_SUCCESS';
|
|
||||||
export const RECEIVE_PODS_DATA_ERROR = 'RECEIVE_PODS_DATA_ERROR';
|
|
|
@ -1,110 +0,0 @@
|
||||||
import { convertToFixedRange } from '~/lib/utils/datetime_range';
|
|
||||||
import * as types from './mutation_types';
|
|
||||||
|
|
||||||
const mapLine = ({ timestamp, pod, message }) => ({
|
|
||||||
timestamp,
|
|
||||||
pod,
|
|
||||||
message,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// Search Data
|
|
||||||
[types.SET_SEARCH](state, searchQuery) {
|
|
||||||
state.search = searchQuery;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Time Range Data
|
|
||||||
[types.SET_TIME_RANGE](state, timeRange) {
|
|
||||||
state.timeRange.selected = timeRange;
|
|
||||||
state.timeRange.current = convertToFixedRange(timeRange);
|
|
||||||
},
|
|
||||||
[types.SHOW_TIME_RANGE_INVALID_WARNING](state) {
|
|
||||||
state.timeRange.invalidWarning = true;
|
|
||||||
},
|
|
||||||
[types.HIDE_TIME_RANGE_INVALID_WARNING](state) {
|
|
||||||
state.timeRange.invalidWarning = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Environments Data
|
|
||||||
[types.SET_PROJECT_ENVIRONMENT](state, environmentName) {
|
|
||||||
state.environments.current = environmentName;
|
|
||||||
|
|
||||||
// Clear current pod options
|
|
||||||
state.pods.current = null;
|
|
||||||
state.pods.options = [];
|
|
||||||
},
|
|
||||||
[types.REQUEST_ENVIRONMENTS_DATA](state) {
|
|
||||||
state.environments.options = [];
|
|
||||||
state.environments.isLoading = true;
|
|
||||||
},
|
|
||||||
[types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS](state, environmentOptions) {
|
|
||||||
state.environments.options = environmentOptions;
|
|
||||||
state.environments.isLoading = false;
|
|
||||||
},
|
|
||||||
[types.RECEIVE_ENVIRONMENTS_DATA_ERROR](state) {
|
|
||||||
state.environments.options = [];
|
|
||||||
state.environments.isLoading = false;
|
|
||||||
state.environments.fetchError = true;
|
|
||||||
},
|
|
||||||
[types.HIDE_REQUEST_ENVIRONMENTS_ERROR](state) {
|
|
||||||
state.environments.fetchError = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Logs data
|
|
||||||
[types.REQUEST_LOGS_DATA](state) {
|
|
||||||
state.timeRange.current = convertToFixedRange(state.timeRange.selected);
|
|
||||||
|
|
||||||
state.logs.lines = [];
|
|
||||||
state.logs.isLoading = true;
|
|
||||||
|
|
||||||
// start pagination from the beginning
|
|
||||||
state.logs.cursor = null;
|
|
||||||
state.logs.isComplete = false;
|
|
||||||
},
|
|
||||||
[types.RECEIVE_LOGS_DATA_SUCCESS](state, { logs = [], cursor }) {
|
|
||||||
state.logs.lines = logs.map(mapLine);
|
|
||||||
state.logs.isLoading = false;
|
|
||||||
state.logs.cursor = cursor;
|
|
||||||
|
|
||||||
if (!cursor) {
|
|
||||||
state.logs.isComplete = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[types.RECEIVE_LOGS_DATA_ERROR](state) {
|
|
||||||
state.logs.lines = [];
|
|
||||||
state.logs.isLoading = false;
|
|
||||||
state.logs.fetchError = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
[types.REQUEST_LOGS_DATA_PREPEND](state) {
|
|
||||||
state.logs.isLoading = true;
|
|
||||||
},
|
|
||||||
[types.RECEIVE_LOGS_DATA_PREPEND_SUCCESS](state, { logs = [], cursor }) {
|
|
||||||
const lines = logs.map(mapLine);
|
|
||||||
state.logs.lines = lines.concat(state.logs.lines);
|
|
||||||
state.logs.isLoading = false;
|
|
||||||
state.logs.cursor = cursor;
|
|
||||||
|
|
||||||
if (!cursor) {
|
|
||||||
state.logs.isComplete = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[types.RECEIVE_LOGS_DATA_PREPEND_ERROR](state) {
|
|
||||||
state.logs.isLoading = false;
|
|
||||||
state.logs.fetchError = true;
|
|
||||||
},
|
|
||||||
[types.HIDE_REQUEST_LOGS_ERROR](state) {
|
|
||||||
state.logs.fetchError = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Pods data
|
|
||||||
[types.SET_CURRENT_POD_NAME](state, podName) {
|
|
||||||
state.pods.current = podName;
|
|
||||||
},
|
|
||||||
[types.RECEIVE_PODS_DATA_SUCCESS](state, podOptions) {
|
|
||||||
state.pods.options = podOptions;
|
|
||||||
},
|
|
||||||
[types.RECEIVE_PODS_DATA_ERROR](state) {
|
|
||||||
state.pods.options = [];
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,56 +0,0 @@
|
||||||
import { convertToFixedRange } from '~/lib/utils/datetime_range';
|
|
||||||
import { timeRanges, defaultTimeRange } from '~/vue_shared/constants';
|
|
||||||
|
|
||||||
export default () => ({
|
|
||||||
/**
|
|
||||||
* Full text search
|
|
||||||
*/
|
|
||||||
search: '',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time range (Show last)
|
|
||||||
*/
|
|
||||||
timeRange: {
|
|
||||||
options: timeRanges,
|
|
||||||
// Selected time range, can be fixed or relative
|
|
||||||
selected: defaultTimeRange,
|
|
||||||
// Current time range, must be fixed
|
|
||||||
current: convertToFixedRange(defaultTimeRange),
|
|
||||||
|
|
||||||
invalidWarning: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Environments list information
|
|
||||||
*/
|
|
||||||
environments: {
|
|
||||||
options: [],
|
|
||||||
isLoading: false,
|
|
||||||
current: null,
|
|
||||||
fetchError: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Jobs with logs
|
|
||||||
*/
|
|
||||||
logs: {
|
|
||||||
lines: [],
|
|
||||||
isLoading: false,
|
|
||||||
/**
|
|
||||||
* Logs `cursor` represents the current pagination position,
|
|
||||||
* Should be sent in next batch (page) of logs to be fetched
|
|
||||||
*/
|
|
||||||
cursor: null,
|
|
||||||
isComplete: false,
|
|
||||||
|
|
||||||
fetchError: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pods list information
|
|
||||||
*/
|
|
||||||
pods: {
|
|
||||||
options: [],
|
|
||||||
current: null,
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { GlToast } from '@gitlab/ui';
|
import { GlToast } from '@gitlab/ui';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
|
||||||
import Translate from '~/vue_shared/translate';
|
import Translate from '~/vue_shared/translate';
|
||||||
import SettingsApp from './components/group_settings_app.vue';
|
import SettingsApp from './components/group_settings_app.vue';
|
||||||
import { apolloProvider } from './graphql';
|
import { apolloProvider } from './graphql';
|
||||||
|
@ -20,7 +19,6 @@ export default () => {
|
||||||
provide: {
|
provide: {
|
||||||
groupPath: el.dataset.groupPath,
|
groupPath: el.dataset.groupPath,
|
||||||
groupDependencyProxyPath: el.dataset.groupDependencyProxyPath,
|
groupDependencyProxyPath: el.dataset.groupDependencyProxyPath,
|
||||||
defaultExpanded: parseBoolean(el.dataset.defaultExpanded),
|
|
||||||
},
|
},
|
||||||
render(createElement) {
|
render(createElement) {
|
||||||
return createElement(SettingsApp);
|
return createElement(SettingsApp);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlToggle, GlSprintf, GlLink } from '@gitlab/ui';
|
import { GlToggle, GlSprintf, GlLink } from '@gitlab/ui';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
|
import SettingsBlock from '~/packages_and_registries/shared/components/settings_block.vue';
|
||||||
import updateDependencyProxySettings from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_settings.mutation.graphql';
|
import updateDependencyProxySettings from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_settings.mutation.graphql';
|
||||||
import updateDependencyProxyImageTtlGroupPolicy from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_image_ttl_group_policy.mutation.graphql';
|
import updateDependencyProxyImageTtlGroupPolicy from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_image_ttl_group_policy.mutation.graphql';
|
||||||
import { updateGroupPackageSettings } from '~/packages_and_registries/settings/group/graphql/utils/cache_update';
|
import { updateGroupPackageSettings } from '~/packages_and_registries/settings/group/graphql/utils/cache_update';
|
||||||
|
@ -39,7 +39,7 @@ export default {
|
||||||
links: {
|
links: {
|
||||||
DEPENDENCY_PROXY_DOCS_PATH,
|
DEPENDENCY_PROXY_DOCS_PATH,
|
||||||
},
|
},
|
||||||
inject: ['defaultExpanded', 'groupPath', 'groupDependencyProxyPath'],
|
inject: ['groupPath', 'groupDependencyProxyPath'],
|
||||||
props: {
|
props: {
|
||||||
dependencyProxySettings: {
|
dependencyProxySettings: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -129,10 +129,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<settings-block
|
<settings-block data-qa-selector="dependency_proxy_settings_content">
|
||||||
:default-expanded="defaultExpanded"
|
|
||||||
data-qa-selector="dependency_proxy_settings_content"
|
|
||||||
>
|
|
||||||
<template #title> {{ $options.i18n.DEPENDENCY_PROXY_HEADER }} </template>
|
<template #title> {{ $options.i18n.DEPENDENCY_PROXY_HEADER }} </template>
|
||||||
<template #description> {{ $options.i18n.DEPENDENCY_PROXY_DESCRIPTION }} </template>
|
<template #description> {{ $options.i18n.DEPENDENCY_PROXY_DESCRIPTION }} </template>
|
||||||
<template #default>
|
<template #default>
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
import updateNamespacePackageSettings from '~/packages_and_registries/settings/group/graphql/mutations/update_group_packages_settings.mutation.graphql';
|
import updateNamespacePackageSettings from '~/packages_and_registries/settings/group/graphql/mutations/update_group_packages_settings.mutation.graphql';
|
||||||
import { updateGroupPackageSettings } from '~/packages_and_registries/settings/group/graphql/utils/cache_update';
|
import { updateGroupPackageSettings } from '~/packages_and_registries/settings/group/graphql/utils/cache_update';
|
||||||
import { updateGroupPackagesSettingsOptimisticResponse } from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses';
|
import { updateGroupPackagesSettingsOptimisticResponse } from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses';
|
||||||
import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
|
import SettingsBlock from '~/packages_and_registries/shared/components/settings_block.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PackageSettings',
|
name: 'PackageSettings',
|
||||||
|
@ -23,7 +23,7 @@ export default {
|
||||||
GenericSettings,
|
GenericSettings,
|
||||||
DuplicatesSettings,
|
DuplicatesSettings,
|
||||||
},
|
},
|
||||||
inject: ['defaultExpanded', 'groupPath'],
|
inject: ['groupPath'],
|
||||||
props: {
|
props: {
|
||||||
packageSettings: {
|
packageSettings: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -84,10 +84,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<settings-block
|
<settings-block data-qa-selector="package_registry_settings_content">
|
||||||
:default-expanded="defaultExpanded"
|
|
||||||
data-qa-selector="package_registry_settings_content"
|
|
||||||
>
|
|
||||||
<template #title> {{ $options.i18n.PACKAGE_SETTINGS_HEADER }}</template>
|
<template #title> {{ $options.i18n.PACKAGE_SETTINGS_HEADER }}</template>
|
||||||
<template #description>
|
<template #description>
|
||||||
<span data-testid="description">
|
<span data-testid="description">
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<template>
|
||||||
|
<section class="settings gl-py-7">
|
||||||
|
<div class="gl-lg-display-flex">
|
||||||
|
<div class="gl-lg-w-half gl-pr-10">
|
||||||
|
<h4>
|
||||||
|
<slot name="title"></slot>
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
<slot name="description"></slot>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="gl-lg-w-half gl-pt-3">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
padding-top: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ module Ci
|
||||||
raise NotSupportedAdapterError, 'This file format requires a dedicated adapter'
|
raise NotSupportedAdapterError, 'This file format requires a dedicated adapter'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
::Gitlab::ApplicationContext.push(artifact: file.model)
|
||||||
|
|
||||||
file.open do |stream|
|
file.open do |stream|
|
||||||
file_format_adapter_class.new(stream).each_blob(&blk)
|
file_format_adapter_class.new(stream).each_blob(&blk)
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
- help_path = local_assigns.fetch(:help_path)
|
- help_path = local_assigns.fetch(:help_path)
|
||||||
- label = local_assigns.fetch(:label)
|
- label = local_assigns.fetch(:label)
|
||||||
- last = local_assigns.fetch(:last, false)
|
- last = local_assigns.fetch(:last, false)
|
||||||
- classes = ["btn btn-confirm gl-button btn-confirm-secondary gl-flex-direction-column gl-w-half"]
|
- classes = ["btn btn-confirm gl-button btn-confirm-secondary gl-flex-direction-column gl-flex-basis-0 gl-flex-grow-1 gl-min-w-0"]
|
||||||
- conditional_classes = [("gl-mr-5" unless last)]
|
- conditional_classes = [("gl-mr-5" unless last)]
|
||||||
|
|
||||||
= link_to help_path, class: classes + conditional_classes do
|
= link_to help_path, class: classes + conditional_classes do
|
||||||
.svg-content.gl-p-3= image_tag logo_path, alt: label, class: "gl-w-64 gl-h-64"
|
%span.gl-display-flex.gl-align-items-center.gl-m-3.gl-h-64
|
||||||
%span
|
= image_tag logo_path, alt: label, class: "gl-w-15 gl-max-h-full gl-max-w-full"
|
||||||
|
%span.gl-white-space-normal
|
||||||
= label
|
= label
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
- gke_label = s_('ClusterIntegration|Google GKE')
|
- gke_label = s_('ClusterIntegration|Google GKE')
|
||||||
- eks_label = s_('ClusterIntegration|Amazon EKS')
|
- eks_label = s_('ClusterIntegration|Amazon EKS')
|
||||||
|
- civo_label = s_('ClusterIntegration|Civo Kubernetes')
|
||||||
- create_cluster_label = s_('ClusterIntegration|Where do you want to create a cluster?')
|
- create_cluster_label = s_('ClusterIntegration|Where do you want to create a cluster?')
|
||||||
- eks_help_path = help_page_path('user/infrastructure/clusters/connect/new_eks_cluster')
|
- eks_help_path = help_page_path('user/infrastructure/clusters/connect/new_eks_cluster.md')
|
||||||
- gke_help_path = help_page_path('user/infrastructure/clusters/connect/new_gke_cluster')
|
- gke_help_path = help_page_path('user/infrastructure/clusters/connect/new_gke_cluster.md')
|
||||||
|
- civo_help_path = help_page_path('user/infrastructure/clusters/connect/new_civo_cluster.md')
|
||||||
|
|
||||||
.gl-p-5
|
.gl-py-5.gl-md-pl-5.gl-md-pr-5
|
||||||
%h4.gl-mb-5
|
%h4.gl-mb-5
|
||||||
= create_cluster_label
|
= create_cluster_label
|
||||||
.gl-display-flex
|
.gl-display-flex
|
||||||
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
|
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
|
||||||
locals: { label: eks_label, logo_path: 'illustrations/logos/amazon_eks.svg', help_path: eks_help_path }
|
locals: { label: eks_label, logo_path: 'illustrations/logos/amazon_eks.svg', help_path: eks_help_path }
|
||||||
|
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
|
||||||
|
locals: { label: civo_label, logo_path: 'illustrations/third-party-logos/civo.svg', help_path: civo_help_path }
|
||||||
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
|
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
|
||||||
locals: { label: gke_label, logo_path: 'illustrations/logos/google_gke.svg', help_path: gke_help_path, last: true }
|
locals: { label: gke_label, logo_path: 'illustrations/logos/google_gke.svg', help_path: gke_help_path, last: true }
|
||||||
|
|
|
@ -2,6 +2,5 @@
|
||||||
- page_title _('Packages & Registries')
|
- page_title _('Packages & Registries')
|
||||||
- @content_class = 'limit-container-width' unless fluid_layout
|
- @content_class = 'limit-container-width' unless fluid_layout
|
||||||
|
|
||||||
%section#js-packages-and-registries-settings{ data: { default_expanded: expanded_by_default?.to_s,
|
%section#js-packages-and-registries-settings{ data: { group_path: @group.full_path,
|
||||||
group_path: @group.full_path,
|
|
||||||
group_dependency_proxy_path: group_dependency_proxy_path(@group) } }
|
group_dependency_proxy_path: group_dependency_proxy_path(@group) } }
|
||||||
|
|
|
@ -9,11 +9,15 @@ end
|
||||||
if log_deprecations?
|
if log_deprecations?
|
||||||
# Log deprecation warnings emitted through Kernel#warn, such as from gems or
|
# Log deprecation warnings emitted through Kernel#warn, such as from gems or
|
||||||
# the Ruby VM.
|
# the Ruby VM.
|
||||||
Warning.process(/.+is deprecated$/) do |warning|
|
actions = {
|
||||||
Gitlab::DeprecationJsonLogger.info(message: warning.strip, source: 'ruby')
|
/.+is deprecated$/ => lambda do |warning|
|
||||||
# Returning :default means we continue emitting this to stderr as well.
|
Gitlab::DeprecationJsonLogger.info(message: warning.strip, source: 'ruby')
|
||||||
:default
|
# Returning :default means we continue emitting this to stderr as well.
|
||||||
end
|
:default
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
Warning.process('', actions)
|
||||||
|
|
||||||
# Log deprecation warnings emitted from Rails (see ActiveSupport::Deprecation).
|
# Log deprecation warnings emitted from Rails (see ActiveSupport::Deprecation).
|
||||||
ActiveSupport::Notifications.subscribe('deprecation.rails') do |name, start, finish, id, payload|
|
ActiveSupport::Notifications.subscribe('deprecation.rails') do |name, start, finish, id, payload|
|
||||||
|
|
|
@ -6,19 +6,91 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
||||||
|
|
||||||
# Configure an external Sidekiq instance **(FREE SELF)**
|
# Configure an external Sidekiq instance **(FREE SELF)**
|
||||||
|
|
||||||
You can configure an external Sidekiq instance by using the Sidekiq that's
|
You can configure an external Sidekiq instance by using the Sidekiq that's bundled in the GitLab package. Sidekiq requires connection to the Redis,
|
||||||
bundled in the GitLab package. Sidekiq requires connection to the Redis,
|
|
||||||
PostgreSQL, and Gitaly instances.
|
PostgreSQL, and Gitaly instances.
|
||||||
|
|
||||||
## Required configuration
|
## Configure TCP access for PostgreSQL, Gitaly, and Redis
|
||||||
|
|
||||||
To configure Sidekiq:
|
By default, GitLab uses UNIX sockets and is not set up to communicate via TCP. To change this:
|
||||||
|
|
||||||
|
1. Edit the `/etc/gitlab/gitlab.rb` file on your GitLab instance and add the following:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
|
||||||
|
## PostgreSQL
|
||||||
|
|
||||||
|
# Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
|
||||||
|
postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
|
||||||
|
postgresql['listen_address'] = '0.0.0.0'
|
||||||
|
postgresql['port'] = 5432
|
||||||
|
|
||||||
|
# Add the Sidekiq nodes to PostgreSQL's trusted addresses.
|
||||||
|
# In the following example, 10.10.1.30/32 is the private IP
|
||||||
|
# of the Sidekiq server.
|
||||||
|
postgresql['md5_auth_cidr_addresses'] = %w(127.0.0.1/32 10.10.1.30/32)
|
||||||
|
postgresql['trust_auth_cidr_addresses'] = %w(127.0.0.1/32 10.10.1.30/32)
|
||||||
|
|
||||||
|
## Gitaly
|
||||||
|
|
||||||
|
# Make Gitaly accept connections on all network interfaces
|
||||||
|
gitaly['listen_addr'] = "0.0.0.0:8075"
|
||||||
|
## Set up the Gitaly token as a form of authentication since you are accessing Gitaly over the network
|
||||||
|
## https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#about-the-gitaly-token
|
||||||
|
gitaly['auth_token'] = 'abc123secret'
|
||||||
|
praefect['auth_token'] = 'abc123secret'
|
||||||
|
gitlab_rails['gitaly_token'] = 'abc123secret'
|
||||||
|
|
||||||
|
## Redis configuration
|
||||||
|
|
||||||
|
redis['bind'] = '0.0.0.0'
|
||||||
|
redis['port'] = 6379
|
||||||
|
# Password to Authenticate Redis
|
||||||
|
redis['password'] = 'redis-password-goes-here'
|
||||||
|
|
||||||
|
gitlab_rails['auto_migrate'] = false
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Run `reconfigure`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo gitlab-ctl reconfigure
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Restart the `PostgreSQL` server:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo gitlab-ctl restart postgresql
|
||||||
|
```
|
||||||
|
|
||||||
|
1. After the restart, set `auto_migrate` to `true` or comment to use the default settings:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
gitlab_rails['auto_migrate'] = true
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Run `reconfigure` again:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo gitlab-ctl reconfigure
|
||||||
|
```
|
||||||
|
|
||||||
|
## Set up Sidekiq instance
|
||||||
|
|
||||||
1. SSH into the Sidekiq server.
|
1. SSH into the Sidekiq server.
|
||||||
|
|
||||||
|
1. Confirm that you can access the PostgreSQL, Gitaly, and Redis ports:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
telnet <GitLab host> 5432 # PostgreSQL
|
||||||
|
telnet <GitLab host> 8075 # Gitaly
|
||||||
|
telnet <GitLab host> 6379 # Redis
|
||||||
|
```
|
||||||
|
|
||||||
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab package
|
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab package
|
||||||
using steps 1 and 2. **Do not complete any other steps.**
|
using steps 1 and 2. **Do not complete any other steps.**
|
||||||
1. Edit `/etc/gitlab/gitlab.rb` with the following information and make sure
|
|
||||||
to replace with your values:
|
1. Copy the `/etc/gitlab/gitlab.rb` file from the GitLab instance and add the following settings. Make sure
|
||||||
|
to replace them with your values:
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Updates to example must be made at:
|
Updates to example must be made at:
|
||||||
|
@ -59,15 +131,24 @@ Updates to example must be made at:
|
||||||
##
|
##
|
||||||
external_url 'https://gitlab.example.com'
|
external_url 'https://gitlab.example.com'
|
||||||
|
|
||||||
|
# Configure the gitlab-shell API callback URL. Without this, `git push` will
|
||||||
|
# fail. This can be your 'front door' GitLab URL or an internal load
|
||||||
|
# balancer.
|
||||||
|
gitlab_rails['internal_api_url'] = 'GITLAB_URL'
|
||||||
|
gitlab_shell['secret_token'] = 'SHELL_TOKEN'
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
#### Redis ###
|
#### Redis ###
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
## Must be the same in every sentinel node
|
## Must be the same in every sentinel node.
|
||||||
redis['master_name'] = 'gitlab-redis'
|
redis['master_name'] = 'gitlab-redis' # Required if you have setup redis cluster
|
||||||
|
|
||||||
## The same password for Redis authentication you set up for the master node.
|
## The same password for Redis authentication you set up for the master node.
|
||||||
redis['master_password'] = '<redis_master_password>'
|
redis['master_password'] = '<redis_master_password>'
|
||||||
|
|
||||||
|
### If redis is running on the main Gitlab instance and you have opened the TCP port as above add the following
|
||||||
|
gitlab_rails['redis_host'] = '<gitlab host>'
|
||||||
|
gitlab_rails['redis_port'] = 6379
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
### Gitaly ###
|
### Gitaly ###
|
||||||
|
@ -78,7 +159,7 @@ Updates to example must be made at:
|
||||||
git_data_dirs({
|
git_data_dirs({
|
||||||
"default" => {
|
"default" => {
|
||||||
"gitaly_address" => "tcp://gitaly:8075",
|
"gitaly_address" => "tcp://gitaly:8075",
|
||||||
"gitaly_token" => "<gitaly_token>"
|
"gitaly_token" => "<gitaly_token>"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -90,12 +171,6 @@ Updates to example must be made at:
|
||||||
gitlab_rails['db_host'] = '<database_host>'
|
gitlab_rails['db_host'] = '<database_host>'
|
||||||
gitlab_rails['db_port'] = '5432'
|
gitlab_rails['db_port'] = '5432'
|
||||||
gitlab_rails['db_password'] = '<database_password>'
|
gitlab_rails['db_password'] = '<database_password>'
|
||||||
|
|
||||||
# Add the Sidekiq nodes to PostgreSQL's trusted addresses.
|
|
||||||
# In the following example, 10.10.1.30/32 is the private IP
|
|
||||||
# of the Sidekiq server.
|
|
||||||
postgresql['trust_auth_cidr_addresses'] = %w(127.0.0.1/32 10.10.1.30/32)
|
|
||||||
|
|
||||||
## Prevent database migrations from running on upgrade automatically
|
## Prevent database migrations from running on upgrade automatically
|
||||||
gitlab_rails['auto_migrate'] = false
|
gitlab_rails['auto_migrate'] = false
|
||||||
|
|
||||||
|
@ -112,13 +187,15 @@ Updates to example must be made at:
|
||||||
sidekiq['max_concurrency'] = 10
|
sidekiq['max_concurrency'] = 10
|
||||||
```
|
```
|
||||||
|
|
||||||
|
1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the GitLab instance and replace the file in the Sidekiq instance.
|
||||||
|
|
||||||
1. Reconfigure GitLab:
|
1. Reconfigure GitLab:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
sudo gitlab-ctl reconfigure
|
sudo gitlab-ctl reconfigure
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Restart the Sidekiq nodes after completing the process and finishing the database migrations.
|
1. Restart the Sidekiq instance after completing the process and finishing the database migrations.
|
||||||
|
|
||||||
## Configure multiple Sidekiq nodes with shared storage
|
## Configure multiple Sidekiq nodes with shared storage
|
||||||
|
|
||||||
|
@ -218,7 +295,7 @@ To make health checks available from `localhost:8092`:
|
||||||
|
|
||||||
1. Edit `/etc/gitlab/gitlab.rb`:
|
1. Edit `/etc/gitlab/gitlab.rb`:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
sidekiq['health_checks_enabled'] = true
|
sidekiq['health_checks_enabled'] = true
|
||||||
sidekiq['health_checks_listen_address'] = "localhost"
|
sidekiq['health_checks_listen_address'] = "localhost"
|
||||||
sidekiq['health_checks_listen_port'] = "8092"
|
sidekiq['health_checks_listen_port'] = "8092"
|
||||||
|
|
|
@ -199,7 +199,7 @@ module Gitlab
|
||||||
field_name = field.try(:attribute_name) || field
|
field_name = field.try(:attribute_name) || field
|
||||||
field_value = node[field_name]
|
field_value = node[field_name]
|
||||||
ordering[field_name] = if field_value.is_a?(Time)
|
ordering[field_name] = if field_value.is_a?(Time)
|
||||||
field_value.strftime('%Y-%m-%d %H:%M:%S.%N %Z')
|
field_value.to_s(:inspect)
|
||||||
else
|
else
|
||||||
field_value.to_s
|
field_value.to_s
|
||||||
end
|
end
|
||||||
|
|
|
@ -96,7 +96,9 @@ module Gitlab
|
||||||
column_definitions.each_with_object({}.with_indifferent_access) do |column_definition, hash|
|
column_definitions.each_with_object({}.with_indifferent_access) do |column_definition, hash|
|
||||||
field_value = node[column_definition.attribute_name]
|
field_value = node[column_definition.attribute_name]
|
||||||
hash[column_definition.attribute_name] = if field_value.is_a?(Time)
|
hash[column_definition.attribute_name] = if field_value.is_a?(Time)
|
||||||
field_value.strftime('%Y-%m-%d %H:%M:%S.%N %Z')
|
# use :inspect formatter to provide specific timezone info
|
||||||
|
# eg 2022-07-05 21:57:56.041499000 +0800
|
||||||
|
field_value.to_s(:inspect)
|
||||||
elsif field_value.nil?
|
elsif field_value.nil?
|
||||||
nil
|
nil
|
||||||
elsif lower_named_function?(column_definition)
|
elsif lower_named_function?(column_definition)
|
||||||
|
|
|
@ -8812,6 +8812,9 @@ msgstr ""
|
||||||
msgid "ClusterIntegration|Choose which of your environments will use this cluster."
|
msgid "ClusterIntegration|Choose which of your environments will use this cluster."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "ClusterIntegration|Civo Kubernetes"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "ClusterIntegration|Clear cluster cache"
|
msgid "ClusterIntegration|Clear cluster cache"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -14665,12 +14668,6 @@ msgstr ""
|
||||||
msgid "Environments|No deployments yet"
|
msgid "Environments|No deployments yet"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Environments|No pod selected"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Environments|No pods to display"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Environments|Note that this action will stop the environment, but it will %{emphasisStart}not%{emphasisEnd} have an effect on any existing deployment due to no “stop environment action” being defined in the %{ciConfigLinkStart}.gitlab-ci.yml%{ciConfigLinkEnd} file."
|
msgid "Environments|Note that this action will stop the environment, but it will %{emphasisStart}not%{emphasisEnd} have an effect on any existing deployment due to no “stop environment action” being defined in the %{ciConfigLinkStart}.gitlab-ci.yml%{ciConfigLinkEnd} file."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -14695,9 +14692,6 @@ msgstr ""
|
||||||
msgid "Environments|Rollback environment %{name}?"
|
msgid "Environments|Rollback environment %{name}?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Environments|Select pod"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Environments|Show all"
|
msgid "Environments|Show all"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -31748,9 +31742,6 @@ msgstr ""
|
||||||
msgid "Refine your search criteria (select a %{strong_open}group%{strong_close} and %{strong_open}project%{strong_close} when possible)"
|
msgid "Refine your search criteria (select a %{strong_open}group%{strong_close} and %{strong_open}project%{strong_close} when possible)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Refresh"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Refresh the page and try again."
|
msgid "Refresh the page and try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -34359,7 +34350,7 @@ msgstr ""
|
||||||
msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
|
msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "SecurityOrchestration|After enabling a group-level policy, this policy automatically applies to all projects in this group."
|
msgid "SecurityOrchestration|After enabling a group-level policy, this policy automatically applies to all projects and sub-groups in this group."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "SecurityOrchestration|All policies"
|
msgid "SecurityOrchestration|All policies"
|
||||||
|
|
|
@ -72,6 +72,10 @@ class PipelineTestReportBuilder
|
||||||
# Please see for more info: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69053#note_709939709
|
# Please see for more info: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69053#note_709939709
|
||||||
def test_report_for_build(pipeline, build_id)
|
def test_report_for_build(pipeline, build_id)
|
||||||
fetch("#{pipeline['web_url']}/tests/suite.json?build_ids[]=#{build_id}")
|
fetch("#{pipeline['web_url']}/tests/suite.json?build_ids[]=#{build_id}")
|
||||||
|
rescue Net::HTTPServerException => e
|
||||||
|
raise e unless e.response.code == 404
|
||||||
|
|
||||||
|
puts "Artifacts not found. They may have expired. Skipping this build."
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_test_report_json_for_pipeline(pipeline)
|
def build_test_report_json_for_pipeline(pipeline)
|
||||||
|
@ -92,7 +96,8 @@ class PipelineTestReportBuilder
|
||||||
test_report['suites'] ||= []
|
test_report['suites'] ||= []
|
||||||
|
|
||||||
failed_builds_for_test_stage.each do |failed_build|
|
failed_builds_for_test_stage.each do |failed_build|
|
||||||
test_report['suites'] << test_report_for_build(pipeline, failed_build['id'])
|
suite = test_report_for_build(pipeline, failed_build['id'])
|
||||||
|
test_report['suites'] << suite if suite
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,6 @@ RSpec.describe 'Group Packages & Registries settings' do
|
||||||
visit_settings_page
|
visit_settings_page
|
||||||
|
|
||||||
expect(page).to have_content('Duplicate packages')
|
expect(page).to have_content('Duplicate packages')
|
||||||
expect(page).to have_button('Collapse')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'automatically saves changes to the server', :js do
|
it 'automatically saves changes to the server', :js do
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
import { GlButton } from '@gitlab/ui';
|
|
||||||
import { shallowMount } from '@vue/test-utils';
|
|
||||||
import { nextTick } from 'vue';
|
|
||||||
import LogControlButtons from '~/logs/components/log_control_buttons.vue';
|
|
||||||
|
|
||||||
describe('LogControlButtons', () => {
|
|
||||||
let wrapper;
|
|
||||||
|
|
||||||
const findScrollToTop = () => wrapper.find('.js-scroll-to-top');
|
|
||||||
const findScrollToBottom = () => wrapper.find('.js-scroll-to-bottom');
|
|
||||||
const findRefreshBtn = () => wrapper.find('.js-refresh-log');
|
|
||||||
|
|
||||||
const initWrapper = (opts) => {
|
|
||||||
wrapper = shallowMount(LogControlButtons, {
|
|
||||||
listeners: {
|
|
||||||
scrollUp: () => {},
|
|
||||||
scrollDown: () => {},
|
|
||||||
},
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
if (wrapper) {
|
|
||||||
wrapper.destroy();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays UI elements', () => {
|
|
||||||
initWrapper();
|
|
||||||
|
|
||||||
expect(findScrollToTop().is(GlButton)).toBe(true);
|
|
||||||
expect(findScrollToBottom().is(GlButton)).toBe(true);
|
|
||||||
expect(findRefreshBtn().is(GlButton)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('emits a `refresh` event on click on `refresh` button', async () => {
|
|
||||||
initWrapper();
|
|
||||||
|
|
||||||
// An `undefined` value means no event was emitted
|
|
||||||
expect(wrapper.emitted('refresh')).toBe(undefined);
|
|
||||||
|
|
||||||
findRefreshBtn().vm.$emit('click');
|
|
||||||
|
|
||||||
await nextTick();
|
|
||||||
expect(wrapper.emitted('refresh')).toHaveLength(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when scrolling actions are enabled', () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
// mock scrolled to the middle of a long page
|
|
||||||
initWrapper();
|
|
||||||
await nextTick();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('click on "scroll to top" scrolls up', () => {
|
|
||||||
expect(findScrollToTop().attributes('disabled')).toBeUndefined();
|
|
||||||
|
|
||||||
findScrollToTop().vm.$emit('click');
|
|
||||||
|
|
||||||
expect(wrapper.emitted('scrollUp')).toHaveLength(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('click on "scroll to bottom" scrolls down', () => {
|
|
||||||
expect(findScrollToBottom().attributes('disabled')).toBeUndefined();
|
|
||||||
|
|
||||||
findScrollToBottom().vm.$emit('click');
|
|
||||||
|
|
||||||
expect(wrapper.emitted('scrollDown')).toHaveLength(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when scrolling actions are disabled', () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
initWrapper({ listeners: {} });
|
|
||||||
await nextTick();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('buttons are disabled', async () => {
|
|
||||||
await nextTick();
|
|
||||||
expect(findScrollToTop().exists()).toBe(false);
|
|
||||||
expect(findScrollToBottom().exists()).toBe(false);
|
|
||||||
// This should be enabled when gitlab-ui contains:
|
|
||||||
// https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/1149
|
|
||||||
// expect(findScrollToBottom().is('[disabled]')).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,71 +0,0 @@
|
||||||
import { GlFilteredSearchToken, GlLoadingIcon } from '@gitlab/ui';
|
|
||||||
import { shallowMount } from '@vue/test-utils';
|
|
||||||
|
|
||||||
import TokenWithLoadingState from '~/logs/components/tokens/token_with_loading_state.vue';
|
|
||||||
|
|
||||||
describe('TokenWithLoadingState', () => {
|
|
||||||
let wrapper;
|
|
||||||
|
|
||||||
const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
|
|
||||||
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
|
|
||||||
|
|
||||||
const initWrapper = (props = {}, options) => {
|
|
||||||
wrapper = shallowMount(TokenWithLoadingState, {
|
|
||||||
propsData: {
|
|
||||||
cursorPosition: 'start',
|
|
||||||
...props,
|
|
||||||
},
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {});
|
|
||||||
|
|
||||||
it('passes entire config correctly', () => {
|
|
||||||
const config = {
|
|
||||||
icon: 'pod',
|
|
||||||
type: 'pod',
|
|
||||||
title: 'Pod name',
|
|
||||||
unique: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
initWrapper({ config });
|
|
||||||
|
|
||||||
expect(findFilteredSearchToken().props('config')).toEqual(config);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('suggestions are replaced', () => {
|
|
||||||
let mockNoOptsText;
|
|
||||||
let config;
|
|
||||||
let stubs;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
mockNoOptsText = 'No suggestions available';
|
|
||||||
config = {
|
|
||||||
loading: false,
|
|
||||||
noOptionsText: mockNoOptsText,
|
|
||||||
};
|
|
||||||
stubs = {
|
|
||||||
GlFilteredSearchToken: {
|
|
||||||
template: `<div><slot name="suggestions"></slot></div>`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders a loading icon', () => {
|
|
||||||
config.loading = true;
|
|
||||||
|
|
||||||
initWrapper({ config }, { stubs });
|
|
||||||
|
|
||||||
expect(findLoadingIcon().exists()).toBe(true);
|
|
||||||
expect(wrapper.text()).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders an empty results message', () => {
|
|
||||||
initWrapper({ config }, { stubs });
|
|
||||||
|
|
||||||
expect(findLoadingIcon().exists()).toBe(false);
|
|
||||||
expect(wrapper.text()).toBe(mockNoOptsText);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,71 +0,0 @@
|
||||||
const mockProjectPath = 'root/autodevops-deploy';
|
|
||||||
|
|
||||||
export const mockEnvName = 'production';
|
|
||||||
export const mockEnvironmentsEndpoint = `${mockProjectPath}/environments.json`;
|
|
||||||
export const mockEnvId = '99';
|
|
||||||
export const mockDocumentationPath = '/documentation.md';
|
|
||||||
export const mockLogsEndpoint = '/dummy_logs_path.json';
|
|
||||||
export const mockCursor = 'MOCK_CURSOR';
|
|
||||||
export const mockNextCursor = 'MOCK_NEXT_CURSOR';
|
|
||||||
|
|
||||||
const makeMockEnvironment = (id, name, advancedQuerying) => ({
|
|
||||||
id,
|
|
||||||
project_path: mockProjectPath,
|
|
||||||
name,
|
|
||||||
logs_api_path: mockLogsEndpoint,
|
|
||||||
enable_advanced_logs_querying: advancedQuerying,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const mockEnvironment = makeMockEnvironment(mockEnvId, mockEnvName, true);
|
|
||||||
export const mockEnvironments = [
|
|
||||||
mockEnvironment,
|
|
||||||
makeMockEnvironment(101, 'staging', false),
|
|
||||||
makeMockEnvironment(102, 'review/a-feature', false),
|
|
||||||
];
|
|
||||||
|
|
||||||
export const mockPodName = 'production-764c58d697-aaaaa';
|
|
||||||
export const mockPods = [
|
|
||||||
mockPodName,
|
|
||||||
'production-764c58d697-bbbbb',
|
|
||||||
'production-764c58d697-ccccc',
|
|
||||||
'production-764c58d697-ddddd',
|
|
||||||
];
|
|
||||||
|
|
||||||
export const mockLogsResult = [
|
|
||||||
{
|
|
||||||
timestamp: '2019-12-13T13:43:18.2760123Z',
|
|
||||||
message: 'log line 1',
|
|
||||||
pod: 'foo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: '2019-12-13T13:43:18.2760123Z',
|
|
||||||
message: 'log line A',
|
|
||||||
pod: 'bar',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: '2019-12-13T13:43:26.8420123Z',
|
|
||||||
message: 'log line 2',
|
|
||||||
pod: 'foo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: '2019-12-13T13:43:26.8420123Z',
|
|
||||||
message: 'log line B',
|
|
||||||
pod: 'bar',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const mockTrace = [
|
|
||||||
'Dec 13 13:43:18.276 | foo | log line 1',
|
|
||||||
'Dec 13 13:43:18.276 | bar | log line A',
|
|
||||||
'Dec 13 13:43:26.842 | foo | log line 2',
|
|
||||||
'Dec 13 13:43:26.842 | bar | log line B',
|
|
||||||
];
|
|
||||||
|
|
||||||
export const mockResponse = {
|
|
||||||
pod_name: mockPodName,
|
|
||||||
pods: mockPods,
|
|
||||||
logs: mockLogsResult,
|
|
||||||
cursor: mockNextCursor,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const mockSearch = 'foo +bar';
|
|
|
@ -1,257 +0,0 @@
|
||||||
import * as types from '~/logs/stores/mutation_types';
|
|
||||||
import mutations from '~/logs/stores/mutations';
|
|
||||||
|
|
||||||
import logsPageState from '~/logs/stores/state';
|
|
||||||
import {
|
|
||||||
mockEnvName,
|
|
||||||
mockEnvironments,
|
|
||||||
mockPods,
|
|
||||||
mockPodName,
|
|
||||||
mockLogsResult,
|
|
||||||
mockSearch,
|
|
||||||
mockCursor,
|
|
||||||
mockNextCursor,
|
|
||||||
} from '../mock_data';
|
|
||||||
|
|
||||||
describe('Logs Store Mutations', () => {
|
|
||||||
let state;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
state = logsPageState();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('ensures mutation types are correctly named', () => {
|
|
||||||
Object.keys(types).forEach((k) => {
|
|
||||||
expect(k).toEqual(types[k]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('SET_PROJECT_ENVIRONMENT', () => {
|
|
||||||
it('sets the environment', () => {
|
|
||||||
mutations[types.SET_PROJECT_ENVIRONMENT](state, mockEnvName);
|
|
||||||
expect(state.environments.current).toEqual(mockEnvName);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('SET_SEARCH', () => {
|
|
||||||
it('sets the search', () => {
|
|
||||||
mutations[types.SET_SEARCH](state, mockSearch);
|
|
||||||
expect(state.search).toEqual(mockSearch);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('REQUEST_ENVIRONMENTS_DATA', () => {
|
|
||||||
it('inits data', () => {
|
|
||||||
mutations[types.REQUEST_ENVIRONMENTS_DATA](state);
|
|
||||||
expect(state.environments.options).toEqual([]);
|
|
||||||
expect(state.environments.isLoading).toEqual(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('RECEIVE_ENVIRONMENTS_DATA_SUCCESS', () => {
|
|
||||||
it('receives environments data and stores it as options', () => {
|
|
||||||
expect(state.environments.options).toEqual([]);
|
|
||||||
|
|
||||||
mutations[types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS](state, mockEnvironments);
|
|
||||||
|
|
||||||
expect(state.environments.options).toEqual(mockEnvironments);
|
|
||||||
expect(state.environments.isLoading).toEqual(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('RECEIVE_ENVIRONMENTS_DATA_ERROR', () => {
|
|
||||||
it('captures an error loading environments', () => {
|
|
||||||
mutations[types.RECEIVE_ENVIRONMENTS_DATA_ERROR](state);
|
|
||||||
|
|
||||||
expect(state.environments).toEqual({
|
|
||||||
options: [],
|
|
||||||
isLoading: false,
|
|
||||||
current: null,
|
|
||||||
fetchError: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('REQUEST_LOGS_DATA', () => {
|
|
||||||
it('starts loading for logs', () => {
|
|
||||||
mutations[types.REQUEST_LOGS_DATA](state);
|
|
||||||
|
|
||||||
expect(state.timeRange.current).toEqual({
|
|
||||||
start: expect.any(String),
|
|
||||||
end: expect.any(String),
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(state.logs).toEqual({
|
|
||||||
lines: [],
|
|
||||||
cursor: null,
|
|
||||||
fetchError: false,
|
|
||||||
isLoading: true,
|
|
||||||
isComplete: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('RECEIVE_LOGS_DATA_SUCCESS', () => {
|
|
||||||
it('receives logs lines and cursor', () => {
|
|
||||||
mutations[types.RECEIVE_LOGS_DATA_SUCCESS](state, {
|
|
||||||
logs: mockLogsResult,
|
|
||||||
cursor: mockCursor,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(state.logs).toEqual({
|
|
||||||
lines: mockLogsResult,
|
|
||||||
isLoading: false,
|
|
||||||
cursor: mockCursor,
|
|
||||||
isComplete: false,
|
|
||||||
fetchError: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('receives logs lines and a null cursor to indicate the end', () => {
|
|
||||||
mutations[types.RECEIVE_LOGS_DATA_SUCCESS](state, {
|
|
||||||
logs: mockLogsResult,
|
|
||||||
cursor: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(state.logs).toEqual({
|
|
||||||
lines: mockLogsResult,
|
|
||||||
isLoading: false,
|
|
||||||
cursor: null,
|
|
||||||
isComplete: true,
|
|
||||||
fetchError: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('RECEIVE_LOGS_DATA_ERROR', () => {
|
|
||||||
it('receives log data error and stops loading', () => {
|
|
||||||
mutations[types.RECEIVE_LOGS_DATA_ERROR](state);
|
|
||||||
|
|
||||||
expect(state.logs).toEqual({
|
|
||||||
lines: [],
|
|
||||||
isLoading: false,
|
|
||||||
cursor: null,
|
|
||||||
isComplete: false,
|
|
||||||
fetchError: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('REQUEST_LOGS_DATA_PREPEND', () => {
|
|
||||||
it('receives logs lines and cursor', () => {
|
|
||||||
mutations[types.REQUEST_LOGS_DATA_PREPEND](state);
|
|
||||||
|
|
||||||
expect(state.logs.isLoading).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('RECEIVE_LOGS_DATA_PREPEND_SUCCESS', () => {
|
|
||||||
it('receives logs lines and cursor', () => {
|
|
||||||
mutations[types.RECEIVE_LOGS_DATA_PREPEND_SUCCESS](state, {
|
|
||||||
logs: mockLogsResult,
|
|
||||||
cursor: mockCursor,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(state.logs).toEqual({
|
|
||||||
lines: mockLogsResult,
|
|
||||||
isLoading: false,
|
|
||||||
cursor: mockCursor,
|
|
||||||
isComplete: false,
|
|
||||||
fetchError: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('receives additional logs lines and a new cursor', () => {
|
|
||||||
mutations[types.RECEIVE_LOGS_DATA_PREPEND_SUCCESS](state, {
|
|
||||||
logs: mockLogsResult,
|
|
||||||
cursor: mockCursor,
|
|
||||||
});
|
|
||||||
|
|
||||||
mutations[types.RECEIVE_LOGS_DATA_PREPEND_SUCCESS](state, {
|
|
||||||
logs: mockLogsResult,
|
|
||||||
cursor: mockNextCursor,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(state.logs).toEqual({
|
|
||||||
lines: [...mockLogsResult, ...mockLogsResult],
|
|
||||||
isLoading: false,
|
|
||||||
cursor: mockNextCursor,
|
|
||||||
isComplete: false,
|
|
||||||
fetchError: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('receives logs lines and a null cursor to indicate is complete', () => {
|
|
||||||
mutations[types.RECEIVE_LOGS_DATA_PREPEND_SUCCESS](state, {
|
|
||||||
logs: mockLogsResult,
|
|
||||||
cursor: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(state.logs).toEqual({
|
|
||||||
lines: mockLogsResult,
|
|
||||||
isLoading: false,
|
|
||||||
cursor: null,
|
|
||||||
isComplete: true,
|
|
||||||
fetchError: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('RECEIVE_LOGS_DATA_PREPEND_ERROR', () => {
|
|
||||||
it('receives logs lines and cursor', () => {
|
|
||||||
mutations[types.RECEIVE_LOGS_DATA_PREPEND_ERROR](state);
|
|
||||||
|
|
||||||
expect(state.logs.isLoading).toBe(false);
|
|
||||||
expect(state.logs.fetchError).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('SET_CURRENT_POD_NAME', () => {
|
|
||||||
it('set current pod name', () => {
|
|
||||||
mutations[types.SET_CURRENT_POD_NAME](state, mockPodName);
|
|
||||||
|
|
||||||
expect(state.pods.current).toEqual(mockPodName);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('SET_TIME_RANGE', () => {
|
|
||||||
it('sets a default range', () => {
|
|
||||||
expect(state.timeRange.selected).toEqual(expect.any(Object));
|
|
||||||
expect(state.timeRange.current).toEqual(expect.any(Object));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sets a time range', () => {
|
|
||||||
const mockRange = {
|
|
||||||
start: '2020-01-10T18:00:00.000Z',
|
|
||||||
end: '2020-01-10T10:00:00.000Z',
|
|
||||||
};
|
|
||||||
mutations[types.SET_TIME_RANGE](state, mockRange);
|
|
||||||
|
|
||||||
expect(state.timeRange.selected).toEqual(mockRange);
|
|
||||||
expect(state.timeRange.current).toEqual(mockRange);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('RECEIVE_PODS_DATA_SUCCESS', () => {
|
|
||||||
it('receives pods data success', () => {
|
|
||||||
mutations[types.RECEIVE_PODS_DATA_SUCCESS](state, mockPods);
|
|
||||||
|
|
||||||
expect(state.pods).toEqual(
|
|
||||||
expect.objectContaining({
|
|
||||||
options: mockPods,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe('RECEIVE_PODS_DATA_ERROR', () => {
|
|
||||||
it('receives pods data error', () => {
|
|
||||||
mutations[types.RECEIVE_PODS_DATA_ERROR](state);
|
|
||||||
|
|
||||||
expect(state.pods).toEqual(
|
|
||||||
expect.objectContaining({
|
|
||||||
options: [],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -38,7 +38,6 @@ describe('DependencyProxySettings', () => {
|
||||||
let updateTtlPoliciesMutationResolver;
|
let updateTtlPoliciesMutationResolver;
|
||||||
|
|
||||||
const defaultProvide = {
|
const defaultProvide = {
|
||||||
defaultExpanded: false,
|
|
||||||
groupPath: 'foo_group_path',
|
groupPath: 'foo_group_path',
|
||||||
groupDependencyProxyPath: 'group_dependency_proxy_path',
|
groupDependencyProxyPath: 'group_dependency_proxy_path',
|
||||||
};
|
};
|
||||||
|
@ -109,12 +108,6 @@ describe('DependencyProxySettings', () => {
|
||||||
expect(findSettingsBlock().exists()).toBe(true);
|
expect(findSettingsBlock().exists()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('passes the correct props to settings block', () => {
|
|
||||||
mountComponent();
|
|
||||||
|
|
||||||
expect(findSettingsBlock().props('defaultExpanded')).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('has the correct header text and description', () => {
|
it('has the correct header text and description', () => {
|
||||||
mountComponent();
|
mountComponent();
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ describe('Group Settings App', () => {
|
||||||
let show;
|
let show;
|
||||||
|
|
||||||
const defaultProvide = {
|
const defaultProvide = {
|
||||||
defaultExpanded: false,
|
|
||||||
groupPath: 'foo_group_path',
|
groupPath: 'foo_group_path',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ describe('Packages Settings', () => {
|
||||||
let apolloProvider;
|
let apolloProvider;
|
||||||
|
|
||||||
const defaultProvide = {
|
const defaultProvide = {
|
||||||
defaultExpanded: false,
|
|
||||||
groupPath: 'foo_group_path',
|
groupPath: 'foo_group_path',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,12 +92,6 @@ describe('Packages Settings', () => {
|
||||||
expect(findSettingsBlock().exists()).toBe(true);
|
expect(findSettingsBlock().exists()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('passes the correct props to settings block', () => {
|
|
||||||
mountComponent();
|
|
||||||
|
|
||||||
expect(findSettingsBlock().props('defaultExpanded')).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('has the correct header text', () => {
|
it('has the correct header text', () => {
|
||||||
mountComponent();
|
mountComponent();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||||
|
import SettingsBlock from '~/packages_and_registries/shared/components/settings_block.vue';
|
||||||
|
|
||||||
|
describe('SettingsBlock', () => {
|
||||||
|
let wrapper;
|
||||||
|
|
||||||
|
const mountComponent = (propsData) => {
|
||||||
|
wrapper = shallowMountExtended(SettingsBlock, {
|
||||||
|
propsData,
|
||||||
|
slots: {
|
||||||
|
title: '<div data-testid="title-slot"></div>',
|
||||||
|
description: '<div data-testid="description-slot"></div>',
|
||||||
|
default: '<div data-testid="default-slot"></div>',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
wrapper.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
const findDefaultSlot = () => wrapper.findByTestId('default-slot');
|
||||||
|
const findTitleSlot = () => wrapper.findByTestId('title-slot');
|
||||||
|
const findDescriptionSlot = () => wrapper.findByTestId('description-slot');
|
||||||
|
|
||||||
|
it('has a default slot', () => {
|
||||||
|
mountComponent();
|
||||||
|
|
||||||
|
expect(findDefaultSlot().exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has a title slot', () => {
|
||||||
|
mountComponent();
|
||||||
|
|
||||||
|
expect(findTitleSlot().exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has a description slot', () => {
|
||||||
|
mountComponent();
|
||||||
|
|
||||||
|
expect(findDescriptionSlot().exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
|
@ -196,10 +196,10 @@ Object {
|
||||||
],
|
],
|
||||||
"paginationInfo": Object {
|
"paginationInfo": Object {
|
||||||
"__typename": "PageInfo",
|
"__typename": "PageInfo",
|
||||||
"endCursor": "eyJyZWxlYXNlZF9hdCI6IjIwMTgtMTItMTAgMDA6MDA6MDAuMDAwMDAwMDAwIFVUQyIsImlkIjoiMSJ9",
|
"endCursor": "eyJyZWxlYXNlZF9hdCI6IjIwMTgtMTItMTAgMDA6MDA6MDAuMDAwMDAwMDAwICswMDAwIiwiaWQiOiIxIn0",
|
||||||
"hasNextPage": false,
|
"hasNextPage": false,
|
||||||
"hasPreviousPage": false,
|
"hasPreviousPage": false,
|
||||||
"startCursor": "eyJyZWxlYXNlZF9hdCI6IjIwMTktMDEtMTAgMDA6MDA6MDAuMDAwMDAwMDAwIFVUQyIsImlkIjoiMiJ9",
|
"startCursor": "eyJyZWxlYXNlZF9hdCI6IjIwMTktMDEtMTAgMDA6MDA6MDAuMDAwMDAwMDAwICswMDAwIiwiaWQiOiIyIn0",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe '0_log_deprecations' do
|
RSpec.describe '0_log_deprecations' do
|
||||||
|
def setup_other_deprecations
|
||||||
|
Warning.process(__FILE__) { :raise }
|
||||||
|
end
|
||||||
|
|
||||||
def load_initializer
|
def load_initializer
|
||||||
load Rails.root.join('config/initializers/0_log_deprecations.rb')
|
load Rails.root.join('config/initializers/0_log_deprecations.rb')
|
||||||
end
|
end
|
||||||
|
@ -11,6 +15,7 @@ RSpec.describe '0_log_deprecations' do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
stub_env('GITLAB_LOG_DEPRECATIONS', env_var)
|
stub_env('GITLAB_LOG_DEPRECATIONS', env_var)
|
||||||
|
setup_other_deprecations
|
||||||
load_initializer
|
load_initializer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,7 +25,7 @@ RSpec.describe '0_log_deprecations' do
|
||||||
ActiveSupport::Notifications.unsubscribe('deprecation.rails')
|
ActiveSupport::Notifications.unsubscribe('deprecation.rails')
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for Ruby deprecations' do
|
describe 'Ruby deprecations' do
|
||||||
context 'when catching deprecations through Kernel#warn' do
|
context 'when catching deprecations through Kernel#warn' do
|
||||||
it 'also logs them to deprecation logger' do
|
it 'also logs them to deprecation logger' do
|
||||||
expect(Gitlab::DeprecationJsonLogger).to receive(:info).with(
|
expect(Gitlab::DeprecationJsonLogger).to receive(:info).with(
|
||||||
|
@ -32,7 +37,7 @@ RSpec.describe '0_log_deprecations' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for other messages from Kernel#warn' do
|
describe 'other messages from Kernel#warn' do
|
||||||
it 'does not log them to deprecation logger' do
|
it 'does not log them to deprecation logger' do
|
||||||
expect(Gitlab::DeprecationJsonLogger).not_to receive(:info)
|
expect(Gitlab::DeprecationJsonLogger).not_to receive(:info)
|
||||||
|
|
||||||
|
@ -51,7 +56,7 @@ RSpec.describe '0_log_deprecations' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for Rails deprecations' do
|
describe 'Rails deprecations' do
|
||||||
it 'logs them to deprecation logger' do
|
it 'logs them to deprecation logger' do
|
||||||
expect(Gitlab::DeprecationJsonLogger).to receive(:info).with(
|
expect(Gitlab::DeprecationJsonLogger).to receive(:info).with(
|
||||||
message: match(/^DEPRECATION WARNING: ABC will be removed/),
|
message: match(/^DEPRECATION WARNING: ABC will be removed/),
|
||||||
|
|
|
@ -79,7 +79,7 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do
|
||||||
let(:nodes) { Project.all.order(Gitlab::Pagination::Keyset::Order.build([column_order_updated_at, column_order_created_at, column_order_id])) }
|
let(:nodes) { Project.all.order(Gitlab::Pagination::Keyset::Order.build([column_order_updated_at, column_order_created_at, column_order_id])) }
|
||||||
|
|
||||||
it 'returns the encoded value of the order' do
|
it 'returns the encoded value of the order' do
|
||||||
expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.strftime('%Y-%m-%d %H:%M:%S.%N %Z'))
|
expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.to_s(:inspect))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -92,7 +92,7 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do
|
||||||
let(:nodes) { Project.order(:updated_at) }
|
let(:nodes) { Project.order(:updated_at) }
|
||||||
|
|
||||||
it 'returns the encoded value of the order' do
|
it 'returns the encoded value of the order' do
|
||||||
expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.strftime('%Y-%m-%d %H:%M:%S.%N %Z'))
|
expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.to_s(:inspect))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'includes the :id even when not specified in the order' do
|
it 'includes the :id even when not specified in the order' do
|
||||||
|
@ -104,7 +104,7 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do
|
||||||
let(:nodes) { Project.order(:updated_at).order(:created_at) }
|
let(:nodes) { Project.order(:updated_at).order(:created_at) }
|
||||||
|
|
||||||
it 'returns the encoded value of the order' do
|
it 'returns the encoded value of the order' do
|
||||||
expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.strftime('%Y-%m-%d %H:%M:%S.%N %Z'))
|
expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.to_s(:inspect))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do
|
||||||
let(:nodes) { Project.order(Arel.sql('projects.updated_at IS NULL')).order(:updated_at).order(:id) }
|
let(:nodes) { Project.order(Arel.sql('projects.updated_at IS NULL')).order(:updated_at).order(:id) }
|
||||||
|
|
||||||
it 'returns the encoded value of the order' do
|
it 'returns the encoded value of the order' do
|
||||||
expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.strftime('%Y-%m-%d %H:%M:%S.%N %Z'))
|
expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.to_s(:inspect))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -53,6 +53,15 @@ RSpec.describe Ci::Artifactable do
|
||||||
expect { |b| artifact.each_blob(&b) }.to raise_error(described_class::NotSupportedAdapterError)
|
expect { |b| artifact.each_blob(&b) }.to raise_error(described_class::NotSupportedAdapterError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'pushes artifact_size to application context' do
|
||||||
|
let(:artifact) { create(:ci_job_artifact, :junit) }
|
||||||
|
|
||||||
|
it 'logs artifact size', :aggregate_failures do
|
||||||
|
expect { |b| artifact.each_blob(&b) }.to yield_control.once
|
||||||
|
expect(Gitlab::ApplicationContext.current).to include("meta.artifact_size" => artifact.size)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'ActiveRecord scopes' do
|
context 'ActiveRecord scopes' do
|
||||||
|
|
|
@ -103,16 +103,18 @@ RSpec.describe PipelineTestReportBuilder do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#test_report_for_latest_pipeline' do
|
describe '#test_report_for_latest_pipeline' do
|
||||||
|
let(:failed_build_uri) { "#{failed_pipeline_url}/tests/suite.json?build_ids[]=#{failed_build_id}" }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(subject).to receive(:fetch).with(failed_build_uri).and_return(failed_builds_for_pipeline)
|
||||||
|
end
|
||||||
|
|
||||||
it 'fetches builds from pipeline related to MR' do
|
it 'fetches builds from pipeline related to MR' do
|
||||||
expect(subject).to receive(:fetch).with("#{failed_pipeline_url}/tests/suite.json?build_ids[]=#{failed_build_id}").and_return(failed_builds_for_pipeline)
|
expected = { "suites" => [failed_builds_for_pipeline] }.to_json
|
||||||
subject.test_report_for_latest_pipeline
|
expect(subject.test_report_for_latest_pipeline).to eq(expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'canonical pipeline' do
|
context 'canonical pipeline' do
|
||||||
before do
|
|
||||||
allow(subject).to receive(:test_report_for_build).and_return(test_report_for_build)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'no previous pipeline' do
|
context 'no previous pipeline' do
|
||||||
let(:mr_pipelines) { [] }
|
let(:mr_pipelines) { [] }
|
||||||
|
|
||||||
|
@ -171,6 +173,10 @@ RSpec.describe PipelineTestReportBuilder do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'failed pipeline and failed test builds' do
|
context 'failed pipeline and failed test builds' do
|
||||||
|
before do
|
||||||
|
allow(subject).to receive(:fetch).with(failed_build_uri).and_return(test_report_for_build)
|
||||||
|
end
|
||||||
|
|
||||||
it 'returns populated test list for suites' do
|
it 'returns populated test list for suites' do
|
||||||
actual = subject.test_report_for_latest_pipeline
|
actual = subject.test_report_for_latest_pipeline
|
||||||
expected = {
|
expected = {
|
||||||
|
@ -180,6 +186,36 @@ RSpec.describe PipelineTestReportBuilder do
|
||||||
expect(actual).to eq(expected)
|
expect(actual).to eq(expected)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when receiving a server error' do
|
||||||
|
let(:response) { instance_double('Net::HTTPResponse') }
|
||||||
|
let(:error) { Net::HTTPServerException.new('server error', response) }
|
||||||
|
let(:test_report_for_latest_pipeline) { subject.test_report_for_latest_pipeline }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(response).to receive(:code).and_return(response_code)
|
||||||
|
allow(subject).to receive(:fetch).with(failed_build_uri).and_raise(error)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when response code is 404' do
|
||||||
|
let(:response_code) { 404 }
|
||||||
|
|
||||||
|
it 'continues without the missing reports' do
|
||||||
|
expected = { 'suites' => [] }.to_json
|
||||||
|
|
||||||
|
expect { test_report_for_latest_pipeline }.not_to raise_error
|
||||||
|
expect(test_report_for_latest_pipeline).to eq(expected)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when response code is unexpected' do
|
||||||
|
let(:response_code) { 500 }
|
||||||
|
|
||||||
|
it 'raises HTTPServerException' do
|
||||||
|
expect { test_report_for_latest_pipeline }.to raise_error(error)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue