Add latest changes from gitlab-org/gitlab@master
|
|
@ -203,6 +203,8 @@
|
||||||
- name: postgres:9.6
|
- name: postgres:9.6
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- name: redis:alpine
|
- name: redis:alpine
|
||||||
|
variables:
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
.use-pg10:
|
.use-pg10:
|
||||||
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.5-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-10-graphicsmagick-1.3.34"
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.5-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-10-graphicsmagick-1.3.34"
|
||||||
|
|
@ -210,6 +212,8 @@
|
||||||
- name: postgres:10.9
|
- name: postgres:10.9
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- name: redis:alpine
|
- name: redis:alpine
|
||||||
|
variables:
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
.use-pg9-ee:
|
.use-pg9-ee:
|
||||||
services:
|
services:
|
||||||
|
|
@ -217,6 +221,8 @@
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- name: redis:alpine
|
- name: redis:alpine
|
||||||
- name: elasticsearch:6.4.2
|
- name: elasticsearch:6.4.2
|
||||||
|
variables:
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
.use-pg10-ee:
|
.use-pg10-ee:
|
||||||
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.5-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-10-graphicsmagick-1.3.34"
|
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.5-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-10-graphicsmagick-1.3.34"
|
||||||
|
|
@ -225,6 +231,8 @@
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- name: redis:alpine
|
- name: redis:alpine
|
||||||
- name: elasticsearch:6.4.2
|
- name: elasticsearch:6.4.2
|
||||||
|
variables:
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
|
||||||
.only-ee:
|
.only-ee:
|
||||||
only:
|
only:
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { gqClient, parseEnvironmentsResponse, removeLeadingSlash } from './utils
|
||||||
import trackDashboardLoad from '../monitoring_tracking_helper';
|
import trackDashboardLoad from '../monitoring_tracking_helper';
|
||||||
import getEnvironments from '../queries/getEnvironments.query.graphql';
|
import getEnvironments from '../queries/getEnvironments.query.graphql';
|
||||||
import statusCodes from '../../lib/utils/http_status';
|
import statusCodes from '../../lib/utils/http_status';
|
||||||
import { backOff } from '../../lib/utils/common_utils';
|
import { backOff, convertObjectPropsToCamelCase } from '../../lib/utils/common_utils';
|
||||||
import { s__, sprintf } from '../../locale';
|
import { s__, sprintf } from '../../locale';
|
||||||
|
|
||||||
import { PROMETHEUS_TIMEOUT } from '../constants';
|
import { PROMETHEUS_TIMEOUT } from '../constants';
|
||||||
|
|
@ -52,6 +52,8 @@ export const requestMetricsDashboard = ({ commit }) => {
|
||||||
export const receiveMetricsDashboardSuccess = ({ commit, dispatch }, { response, params }) => {
|
export const receiveMetricsDashboardSuccess = ({ commit, dispatch }, { response, params }) => {
|
||||||
commit(types.SET_ALL_DASHBOARDS, response.all_dashboards);
|
commit(types.SET_ALL_DASHBOARDS, response.all_dashboards);
|
||||||
commit(types.RECEIVE_METRICS_DATA_SUCCESS, response.dashboard);
|
commit(types.RECEIVE_METRICS_DATA_SUCCESS, response.dashboard);
|
||||||
|
commit(types.SET_ENDPOINTS, convertObjectPropsToCamelCase(response.metrics_data));
|
||||||
|
|
||||||
return dispatch('fetchPrometheusMetrics', params);
|
return dispatch('fetchPrometheusMetrics', params);
|
||||||
};
|
};
|
||||||
export const receiveMetricsDashboardFailure = ({ commit }, error) => {
|
export const receiveMetricsDashboardFailure = ({ commit }, error) => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import pick from 'lodash/pick';
|
||||||
import { slugify } from '~/lib/utils/text_utility';
|
import { slugify } from '~/lib/utils/text_utility';
|
||||||
import * as types from './mutation_types';
|
import * as types from './mutation_types';
|
||||||
import { normalizeMetric, normalizeQueryResult } from './utils';
|
import { normalizeMetric, normalizeQueryResult } from './utils';
|
||||||
|
|
@ -174,15 +175,19 @@ export default {
|
||||||
state: emptyStateFromError(error),
|
state: emptyStateFromError(error),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
[types.SET_ENDPOINTS](state, endpoints = {}) {
|
||||||
[types.SET_ENDPOINTS](state, endpoints) {
|
const endpointKeys = [
|
||||||
state.metricsEndpoint = endpoints.metricsEndpoint;
|
'metricsEndpoint',
|
||||||
state.deploymentsEndpoint = endpoints.deploymentsEndpoint;
|
'deploymentsEndpoint',
|
||||||
state.dashboardEndpoint = endpoints.dashboardEndpoint;
|
'dashboardEndpoint',
|
||||||
state.dashboardsEndpoint = endpoints.dashboardsEndpoint;
|
'dashboardsEndpoint',
|
||||||
state.currentDashboard = endpoints.currentDashboard;
|
'currentDashboard',
|
||||||
state.projectPath = endpoints.projectPath;
|
'projectPath',
|
||||||
state.logsPath = endpoints.logsPath || state.logsPath;
|
'logsPath',
|
||||||
|
];
|
||||||
|
Object.entries(pick(endpoints, endpointKeys)).forEach(([key, value]) => {
|
||||||
|
state[key] = value;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[types.SET_TIME_RANGE](state, timeRange) {
|
[types.SET_TIME_RANGE](state, timeRange) {
|
||||||
state.timeRange = timeRange;
|
state.timeRange = timeRange;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import ZenMode from '~/zen_mode';
|
import ZenMode from '~/zen_mode';
|
||||||
import initEditRelease from '~/releases/detail';
|
import initEditRelease from '~/releases/mount_edit';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
new ZenMode(); // eslint-disable-line no-new
|
new ZenMode(); // eslint-disable-line no-new
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
import initReleases from '~/releases/list';
|
import initReleases from '~/releases/mount_index';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', initReleases);
|
document.addEventListener('DOMContentLoaded', initReleases);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import MarkdownField from '~/vue_shared/components/markdown/field.vue';
|
||||||
import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
|
import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ReleaseDetailApp',
|
name: 'ReleaseEditApp',
|
||||||
components: {
|
components: {
|
||||||
GlFormInput,
|
GlFormInput,
|
||||||
GlFormGroup,
|
GlFormGroup,
|
||||||
|
|
@ -18,7 +18,7 @@ export default {
|
||||||
autofocusonshow,
|
autofocusonshow,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
...mapState('detail', [
|
||||||
'isFetchingRelease',
|
'isFetchingRelease',
|
||||||
'fetchError',
|
'fetchError',
|
||||||
'markdownDocsPath',
|
'markdownDocsPath',
|
||||||
|
|
@ -42,7 +42,7 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
tagName() {
|
tagName() {
|
||||||
return this.$store.state.release.tagName;
|
return this.$store.state.detail.release.tagName;
|
||||||
},
|
},
|
||||||
tagNameHintText() {
|
tagNameHintText() {
|
||||||
return sprintf(
|
return sprintf(
|
||||||
|
|
@ -60,7 +60,7 @@ export default {
|
||||||
},
|
},
|
||||||
releaseTitle: {
|
releaseTitle: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.release.name;
|
return this.$store.state.detail.release.name;
|
||||||
},
|
},
|
||||||
set(title) {
|
set(title) {
|
||||||
this.updateReleaseTitle(title);
|
this.updateReleaseTitle(title);
|
||||||
|
|
@ -68,7 +68,7 @@ export default {
|
||||||
},
|
},
|
||||||
releaseNotes: {
|
releaseNotes: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.release.description;
|
return this.$store.state.detail.release.description;
|
||||||
},
|
},
|
||||||
set(notes) {
|
set(notes) {
|
||||||
this.updateReleaseNotes(notes);
|
this.updateReleaseNotes(notes);
|
||||||
|
|
@ -79,7 +79,7 @@ export default {
|
||||||
this.fetchRelease();
|
this.fetchRelease();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions([
|
...mapActions('detail', [
|
||||||
'fetchRelease',
|
'fetchRelease',
|
||||||
'updateRelease',
|
'updateRelease',
|
||||||
'updateReleaseTitle',
|
'updateReleaseTitle',
|
||||||
|
|
@ -32,7 +32,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['isLoading', 'releases', 'hasError', 'pageInfo']),
|
...mapState('list', ['isLoading', 'releases', 'hasError', 'pageInfo']),
|
||||||
shouldRenderEmptyState() {
|
shouldRenderEmptyState() {
|
||||||
return !this.releases.length && !this.hasError && !this.isLoading;
|
return !this.releases.length && !this.hasError && !this.isLoading;
|
||||||
},
|
},
|
||||||
|
|
@ -47,7 +47,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['fetchReleases']),
|
...mapActions('list', ['fetchReleases']),
|
||||||
onChangePage(page) {
|
onChangePage(page) {
|
||||||
historyPushState(buildUrlWithCurrentLocation(`?page=${page}`));
|
historyPushState(buildUrlWithCurrentLocation(`?page=${page}`));
|
||||||
this.fetchReleases({ page, projectId: this.projectId });
|
this.fetchReleases({ page, projectId: this.projectId });
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
import Vue from 'vue';
|
|
||||||
import ReleaseDetailApp from './components/app.vue';
|
|
||||||
import createStore from './store';
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const el = document.getElementById('js-edit-release-page');
|
|
||||||
|
|
||||||
const store = createStore();
|
|
||||||
store.dispatch('setInitialState', el.dataset);
|
|
||||||
|
|
||||||
return new Vue({
|
|
||||||
el,
|
|
||||||
store,
|
|
||||||
components: { ReleaseDetailApp },
|
|
||||||
render(createElement) {
|
|
||||||
return createElement('release-detail-app');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
import Vue from 'vue';
|
|
||||||
import Vuex from 'vuex';
|
|
||||||
import * as actions from './actions';
|
|
||||||
import mutations from './mutations';
|
|
||||||
import state from './state';
|
|
||||||
|
|
||||||
Vue.use(Vuex);
|
|
||||||
|
|
||||||
export default () =>
|
|
||||||
new Vuex.Store({
|
|
||||||
actions,
|
|
||||||
mutations,
|
|
||||||
state,
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import Vue from 'vue';
|
|
||||||
import App from './components/app.vue';
|
|
||||||
import createStore from './store';
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const element = document.getElementById('js-releases-page');
|
|
||||||
|
|
||||||
return new Vue({
|
|
||||||
el: element,
|
|
||||||
store: createStore(),
|
|
||||||
components: {
|
|
||||||
App,
|
|
||||||
},
|
|
||||||
render(createElement) {
|
|
||||||
return createElement('app', {
|
|
||||||
props: {
|
|
||||||
projectId: element.dataset.projectId,
|
|
||||||
documentationLink: element.dataset.documentationPath,
|
|
||||||
illustrationPath: element.dataset.illustrationPath,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
import Vue from 'vue';
|
|
||||||
import Vuex from 'vuex';
|
|
||||||
import state from './state';
|
|
||||||
import * as actions from './actions';
|
|
||||||
import mutations from './mutations';
|
|
||||||
|
|
||||||
Vue.use(Vuex);
|
|
||||||
|
|
||||||
export default () =>
|
|
||||||
new Vuex.Store({
|
|
||||||
actions,
|
|
||||||
mutations,
|
|
||||||
state: state(),
|
|
||||||
});
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
import ReleaseEditApp from './components/app_edit.vue';
|
||||||
|
import createStore from './stores';
|
||||||
|
import detailModule from './stores/modules/detail';
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const el = document.getElementById('js-edit-release-page');
|
||||||
|
|
||||||
|
const store = createStore({ detail: detailModule });
|
||||||
|
store.dispatch('setInitialState', el.dataset);
|
||||||
|
|
||||||
|
return new Vue({
|
||||||
|
el,
|
||||||
|
store,
|
||||||
|
render: h => h(ReleaseEditApp),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
import ReleaseListApp from './components/app_index.vue';
|
||||||
|
import createStore from './stores';
|
||||||
|
import listModule from './stores/modules/list';
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const el = document.getElementById('js-releases-page');
|
||||||
|
|
||||||
|
return new Vue({
|
||||||
|
el,
|
||||||
|
store: createStore({ list: listModule }),
|
||||||
|
render: h =>
|
||||||
|
h(ReleaseListApp, {
|
||||||
|
props: {
|
||||||
|
projectId: el.dataset.projectId,
|
||||||
|
documentationLink: el.dataset.documentationPath,
|
||||||
|
illustrationPath: el.dataset.illustrationPath,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
export default modules => new Vuex.Store({ modules });
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import * as actions from './actions';
|
||||||
|
import mutations from './mutations';
|
||||||
|
import state from './state';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
actions,
|
||||||
|
mutations,
|
||||||
|
state,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import state from './state';
|
||||||
|
import * as actions from './actions';
|
||||||
|
import mutations from './mutations';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
actions,
|
||||||
|
mutations,
|
||||||
|
state,
|
||||||
|
};
|
||||||
|
|
@ -56,7 +56,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def clear_repository_check_states
|
def clear_repository_check_states
|
||||||
RepositoryCheck::ClearWorker.perform_async
|
RepositoryCheck::ClearWorker.perform_async # rubocop:disable CodeReuse/Worker
|
||||||
|
|
||||||
redirect_to(
|
redirect_to(
|
||||||
general_admin_application_settings_path,
|
general_admin_application_settings_path,
|
||||||
|
|
@ -73,7 +73,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
||||||
|
|
||||||
# Specs are in spec/requests/self_monitoring_project_spec.rb
|
# Specs are in spec/requests/self_monitoring_project_spec.rb
|
||||||
def create_self_monitoring_project
|
def create_self_monitoring_project
|
||||||
job_id = SelfMonitoringProjectCreateWorker.perform_async
|
job_id = SelfMonitoringProjectCreateWorker.perform_async # rubocop:disable CodeReuse/Worker
|
||||||
|
|
||||||
render status: :accepted, json: {
|
render status: :accepted, json: {
|
||||||
job_id: job_id,
|
job_id: job_id,
|
||||||
|
|
@ -92,7 +92,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
if SelfMonitoringProjectCreateWorker.in_progress?(job_id)
|
if SelfMonitoringProjectCreateWorker.in_progress?(job_id) # rubocop:disable CodeReuse/Worker
|
||||||
::Gitlab::PollingInterval.set_header(response, interval: 3_000)
|
::Gitlab::PollingInterval.set_header(response, interval: 3_000)
|
||||||
|
|
||||||
return render status: :accepted, json: {
|
return render status: :accepted, json: {
|
||||||
|
|
@ -112,7 +112,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
||||||
|
|
||||||
# Specs are in spec/requests/self_monitoring_project_spec.rb
|
# Specs are in spec/requests/self_monitoring_project_spec.rb
|
||||||
def delete_self_monitoring_project
|
def delete_self_monitoring_project
|
||||||
job_id = SelfMonitoringProjectDeleteWorker.perform_async
|
job_id = SelfMonitoringProjectDeleteWorker.perform_async # rubocop:disable CodeReuse/Worker
|
||||||
|
|
||||||
render status: :accepted, json: {
|
render status: :accepted, json: {
|
||||||
job_id: job_id,
|
job_id: job_id,
|
||||||
|
|
@ -131,7 +131,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
if SelfMonitoringProjectDeleteWorker.in_progress?(job_id)
|
if SelfMonitoringProjectDeleteWorker.in_progress?(job_id) # rubocop:disable CodeReuse/Worker
|
||||||
::Gitlab::PollingInterval.set_header(response, interval: 3_000)
|
::Gitlab::PollingInterval.set_header(response, interval: 3_000)
|
||||||
|
|
||||||
return render status: :accepted, json: {
|
return render status: :accepted, json: {
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class Admin::ProjectsController < Admin::ApplicationController
|
||||||
# rubocop: enable CodeReuse/ActiveRecord
|
# rubocop: enable CodeReuse/ActiveRecord
|
||||||
|
|
||||||
def repository_check
|
def repository_check
|
||||||
RepositoryCheck::SingleRepositoryWorker.perform_async(@project.id)
|
RepositoryCheck::SingleRepositoryWorker.perform_async(@project.id) # rubocop:disable CodeReuse/Worker
|
||||||
|
|
||||||
redirect_to(
|
redirect_to(
|
||||||
admin_project_path(@project),
|
admin_project_path(@project),
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class Admin::ServicesController < Admin::ApplicationController
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if service.update(service_params[:service])
|
if service.update(service_params[:service])
|
||||||
PropagateServiceTemplateWorker.perform_async(service.id) if service.active?
|
PropagateServiceTemplateWorker.perform_async(service.id) if service.active? # rubocop:disable CodeReuse/Worker
|
||||||
|
|
||||||
redirect_to admin_application_settings_services_path,
|
redirect_to admin_application_settings_services_path,
|
||||||
notice: 'Application settings saved successfully'
|
notice: 'Application settings saved successfully'
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||||
|
|
||||||
def import_csv
|
def import_csv
|
||||||
if uploader = UploadService.new(project, params[:file]).execute
|
if uploader = UploadService.new(project, params[:file]).execute
|
||||||
ImportIssuesCsvWorker.perform_async(current_user.id, project.id, uploader.upload.id)
|
ImportIssuesCsvWorker.perform_async(current_user.id, project.id, uploader.upload.id) # rubocop:disable CodeReuse/Worker
|
||||||
|
|
||||||
flash[:notice] = _("Your issues are being imported. Once finished, you'll get a confirmation email.")
|
flash[:notice] = _("Your issues are being imported. Once finished, you'll get a confirmation email.")
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def play
|
def play
|
||||||
job_id = RunPipelineScheduleWorker.perform_async(schedule.id, current_user.id)
|
job_id = RunPipelineScheduleWorker.perform_async(schedule.id, current_user.id) # rubocop:disable CodeReuse/Worker
|
||||||
|
|
||||||
if job_id
|
if job_id
|
||||||
pipelines_link_start = "<a href=\"#{project_pipelines_path(@project)}\">"
|
pipelines_link_start = "<a href=\"#{project_pipelines_path(@project)}\">"
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ module Projects
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
DeleteContainerRepositoryWorker.perform_async(current_user.id, image.id)
|
DeleteContainerRepositoryWorker.perform_async(current_user.id, image.id) # rubocop:disable CodeReuse/Worker
|
||||||
track_event(:delete_repository)
|
track_event(:delete_repository)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,9 @@ module Projects
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# rubocop:disable CodeReuse/Worker
|
||||||
CreatePipelineWorker.perform_async(project.id, current_user.id, project.default_branch, :web, ignore_skip_ci: true, save_on_errors: false)
|
CreatePipelineWorker.perform_async(project.id, current_user.id, project.default_branch, :web, ignore_skip_ci: true, save_on_errors: false)
|
||||||
|
# rubocop:enable CodeReuse/Worker
|
||||||
|
|
||||||
pipelines_link_start = '<a href="%{url}">'.html_safe % { url: project_pipelines_path(@project) }
|
pipelines_link_start = '<a href="%{url}">'.html_safe % { url: project_pipelines_path(@project) }
|
||||||
flash[:toast] = _("A new Auto DevOps pipeline has been created, go to %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details") % { pipelines_link_start: pipelines_link_start, pipelines_link_end: "</a>".html_safe }
|
flash[:toast] = _("A new Auto DevOps pipeline has been created, go to %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details") % { pipelines_link_start: pipelines_link_start, pipelines_link_end: "</a>".html_safe }
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ module Projects
|
||||||
result = Projects::UpdateService.new(project, current_user, cleanup_params).execute
|
result = Projects::UpdateService.new(project, current_user, cleanup_params).execute
|
||||||
|
|
||||||
if result[:status] == :success
|
if result[:status] == :success
|
||||||
RepositoryCleanupWorker.perform_async(project.id, current_user.id)
|
RepositoryCleanupWorker.perform_async(project.id, current_user.id) # rubocop:disable CodeReuse/Worker
|
||||||
flash[:notice] = _('Repository cleanup has started. You will receive an email once the cleanup operation is complete.')
|
flash[:notice] = _('Repository cleanup has started. You will receive an email once the cleanup operation is complete.')
|
||||||
else
|
else
|
||||||
flash[:alert] = _('Failed to upload object map file')
|
flash[:alert] = _('Failed to upload object map file')
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ module Repositories
|
||||||
return unless repo_type.project?
|
return unless repo_type.project?
|
||||||
return unless project&.daily_statistics_enabled?
|
return unless project&.daily_statistics_enabled?
|
||||||
|
|
||||||
ProjectDailyStatisticsWorker.perform_async(project.id)
|
ProjectDailyStatisticsWorker.perform_async(project.id) # rubocop:disable CodeReuse/Worker
|
||||||
end
|
end
|
||||||
|
|
||||||
def access
|
def access
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ module AnalyticsNavbarHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def cycle_analytics_navbar_link(project, current_user)
|
def cycle_analytics_navbar_link(project, current_user)
|
||||||
return unless Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, project)
|
return unless Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, project, default_enabled: true)
|
||||||
return unless project_nav_tab?(:cycle_analytics)
|
return unless project_nav_tab?(:cycle_analytics)
|
||||||
|
|
||||||
navbar_sub_item(
|
navbar_sub_item(
|
||||||
|
|
@ -43,7 +43,7 @@ module AnalyticsNavbarHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository_analytics_navbar_link(project, current_user)
|
def repository_analytics_navbar_link(project, current_user)
|
||||||
return if Feature.disabled?(:analytics_pages_under_project_analytics_sidebar, project)
|
return if Feature.disabled?(:analytics_pages_under_project_analytics_sidebar, project, default_enabled: true)
|
||||||
return if project.empty_repo?
|
return if project.empty_repo?
|
||||||
|
|
||||||
navbar_sub_item(
|
navbar_sub_item(
|
||||||
|
|
@ -55,7 +55,7 @@ module AnalyticsNavbarHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def ci_cd_analytics_navbar_link(project, current_user)
|
def ci_cd_analytics_navbar_link(project, current_user)
|
||||||
return unless Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, project)
|
return unless Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, project, default_enabled: true)
|
||||||
return unless project_nav_tab?(:pipelines)
|
return unless project_nav_tab?(:pipelines)
|
||||||
return unless project.feature_available?(:builds, current_user) || !project.empty_repo?
|
return unless project.feature_available?(:builds, current_user) || !project.empty_repo?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
module Ci
|
module Ci
|
||||||
class ProcessBuildService < BaseService
|
class ProcessBuildService < BaseService
|
||||||
def execute(build, current_status)
|
def execute(build, current_status)
|
||||||
if valid_statuses_for_when(build.when).include?(current_status)
|
if valid_statuses_for_build(build).include?(current_status)
|
||||||
if build.schedulable?
|
if build.schedulable?
|
||||||
build.schedule
|
build.schedule
|
||||||
elsif build.action?
|
elsif build.action?
|
||||||
|
|
@ -25,10 +25,10 @@ module Ci
|
||||||
build.enqueue
|
build.enqueue
|
||||||
end
|
end
|
||||||
|
|
||||||
def valid_statuses_for_when(value)
|
def valid_statuses_for_build(build)
|
||||||
case value
|
case build.when
|
||||||
when 'on_success'
|
when 'on_success'
|
||||||
%w[success skipped]
|
build.scheduling_type_dag? ? %w[success] : %w[success skipped]
|
||||||
when 'on_failure'
|
when 'on_failure'
|
||||||
%w[failed]
|
%w[failed]
|
||||||
when 'always'
|
when 'always'
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@
|
||||||
= link_to navbar_links.first.link do
|
= link_to navbar_links.first.link do
|
||||||
.nav-icon-container
|
.nav-icon-container
|
||||||
= sprite_icon('chart')
|
= sprite_icon('chart')
|
||||||
%span.nav-item-name
|
%span.nav-item-name{ data: { qa_selector: 'analytics_link' } }
|
||||||
= _('Analytics')
|
= _('Analytics')
|
||||||
|
|
||||||
%ul.sidebar-sub-level-items
|
%ul.sidebar-sub-level-items{ data: { qa_selector: 'analytics_sidebar_submenu' } }
|
||||||
- navbar_links.each do |menu_item|
|
- navbar_links.each do |menu_item|
|
||||||
= nav_link(path: menu_item.path) do
|
= nav_link(path: menu_item.path) do
|
||||||
= link_to(menu_item.link, menu_item.link_to_options) do
|
= link_to(menu_item.link, menu_item.link_to_options) do
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
- should_display_analytics_pages_in_sidebar = Feature.enabled?(:analytics_pages_under_group_analytics_sidebar, @group)
|
- should_display_analytics_pages_in_sidebar = Feature.enabled?(:analytics_pages_under_group_analytics_sidebar, @group, default_enabled: true)
|
||||||
- issues_count = group_issues_count(state: 'opened')
|
- issues_count = group_issues_count(state: 'opened')
|
||||||
- merge_requests_count = group_merge_requests_count(state: 'opened')
|
- merge_requests_count = group_merge_requests_count(state: 'opened')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
- should_display_analytics_pages_in_sidebar = Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, @project)
|
- should_display_analytics_pages_in_sidebar = Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, @project, default_enabled: true)
|
||||||
|
|
||||||
.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) }
|
.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) }
|
||||||
.nav-sidebar-inner-scroll
|
.nav-sidebar-inner-scroll
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
= project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile', width: 40, height: 40)
|
= project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile', width: 40, height: 40)
|
||||||
.sidebar-context-title
|
.sidebar-context-title
|
||||||
= @project.name
|
= @project.name
|
||||||
%ul.sidebar-top-level-items
|
%ul.sidebar-top-level-items.qa-project-sidebar
|
||||||
- paths = sidebar_projects_paths
|
- paths = sidebar_projects_paths
|
||||||
- paths << 'cycle_analytics#show' unless should_display_analytics_pages_in_sidebar
|
- paths << 'cycle_analytics#show' unless should_display_analytics_pages_in_sidebar
|
||||||
= nav_link(path: paths, html_options: { class: 'home' }) do
|
= nav_link(path: paths, html_options: { class: 'home' }) do
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Prevent DAG builds to run after skipped need build
|
||||||
|
merge_request: 23405
|
||||||
|
author:
|
||||||
|
type: fixed
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Backfill LfsObjectsProject records of forks
|
||||||
|
merge_request: 24767
|
||||||
|
author:
|
||||||
|
type: other
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Fix Group Import existing objects lookup when description attribute is an empty
|
||||||
|
string
|
||||||
|
merge_request: 25187
|
||||||
|
author:
|
||||||
|
type: fixed
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Update cluster-applications to v0.8.0
|
||||||
|
merge_request: 25138
|
||||||
|
author:
|
||||||
|
type: changed
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Move analytics pages under the sidebar for projects and groups
|
||||||
|
merge_request: 24470
|
||||||
|
author:
|
||||||
|
type: changed
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class ScheduleLinkLfsObjects < ActiveRecord::Migration[6.0]
|
||||||
|
include Gitlab::Database::MigrationHelpers
|
||||||
|
|
||||||
|
DOWNTIME = false
|
||||||
|
MIGRATION = 'LinkLfsObjects'
|
||||||
|
BATCH_SIZE = 1_000
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
class Project < ActiveRecord::Base
|
||||||
|
include EachBatch
|
||||||
|
|
||||||
|
self.table_name = 'projects'
|
||||||
|
end
|
||||||
|
|
||||||
|
def up
|
||||||
|
fork_network_members =
|
||||||
|
Gitlab::BackgroundMigration::LinkLfsObjects::ForkNetworkMember
|
||||||
|
.select(1)
|
||||||
|
.with_non_existing_lfs_objects
|
||||||
|
.where('fork_network_members.project_id = projects.id')
|
||||||
|
|
||||||
|
forks = Project.where('EXISTS (?)', fork_network_members)
|
||||||
|
|
||||||
|
queue_background_migration_jobs_by_range_at_intervals(
|
||||||
|
forks,
|
||||||
|
MIGRATION,
|
||||||
|
BackgroundMigrationWorker.minimum_interval,
|
||||||
|
batch_size: BATCH_SIZE
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
# no-op
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -16,7 +16,7 @@ group:
|
||||||
- Merge requests
|
- Merge requests
|
||||||
- Push events
|
- Push events
|
||||||
|
|
||||||
To view the Contribution Analytics, go to your group's **Overview > Contribution Analytics**
|
To view the Contribution Analytics, go to your group's **Analytics > Contribution Analytics**
|
||||||
page.
|
page.
|
||||||
|
|
||||||
## Use cases
|
## Use cases
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
|
@ -14,10 +14,10 @@ requests to be merged and much more.
|
||||||
|
|
||||||
## View your group's Insights
|
## View your group's Insights
|
||||||
|
|
||||||
You can access your group's Insights by clicking the **Overview > Insights**
|
You can access your group's Insights by clicking the **Analytics > Insights**
|
||||||
link in the left sidebar:
|
link in the left sidebar:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Configure your Insights
|
## Configure your Insights
|
||||||
|
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
|
@ -10,7 +10,7 @@ Issues Analytics is a bar graph which illustrates the number of issues created e
|
||||||
The default timespan is 13 months, which includes the current month, and the 12 months
|
The default timespan is 13 months, which includes the current month, and the 12 months
|
||||||
prior.
|
prior.
|
||||||
|
|
||||||
To access the chart, navigate to a group's sidebar and select **Issues > Analytics**.
|
To access the chart, navigate to a group's sidebar and select **Analytics > Issues Analytics**.
|
||||||
|
|
||||||
Hover over each bar to see the total number of issues.
|
Hover over each bar to see the total number of issues.
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ You can change the total number of months displayed by setting a URL parameter.
|
||||||
For example, `https://gitlab.com/groups/gitlab-org/-/issues_analytics?months_back=15`
|
For example, `https://gitlab.com/groups/gitlab-org/-/issues_analytics?months_back=15`
|
||||||
shows a total of 15 months for the chart in the GitLab.org group.
|
shows a total of 15 months for the chart in the GitLab.org group.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
<!-- ## Troubleshooting
|
<!-- ## Troubleshooting
|
||||||
|
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
|
@ -13,10 +13,10 @@ This feature is [also available at the group level](../../group/insights/index.m
|
||||||
|
|
||||||
## View your project's Insights
|
## View your project's Insights
|
||||||
|
|
||||||
You can access your project's Insights by clicking the **Project > Insights**
|
You can access your project's Insights by clicking the **Analytics > Insights**
|
||||||
link in the left sidebar:
|
link in the left sidebar:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Configure your Insights
|
## Configure your Insights
|
||||||
|
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
|
@ -285,7 +285,9 @@ Note the following properties:
|
||||||
| type | string | no | Type of panel to be rendered. Optional for area panel types |
|
| type | string | no | Type of panel to be rendered. Optional for area panel types |
|
||||||
| query_range | string | required | For area panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |
|
| query_range | string | required | For area panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
Starting in [version 12.8](https://gitlab.com/gitlab-org/gitlab/issues/202696), the y-axis values will automatically scale according to the data. Previously, it always started from 0.
|
||||||
|
|
||||||
##### Anomaly chart
|
##### Anomaly chart
|
||||||
|
|
||||||
|
|
@ -329,7 +331,7 @@ Note the following properties:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Column
|
##### Column chart
|
||||||
|
|
||||||
To add a column panel type to a dashboard, look at the following sample dashboard file:
|
To add a column panel type to a dashboard, look at the following sample dashboard file:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ relatively quickly to work, and they will take you to another page in the projec
|
||||||
| <kbd>t</kbd> | Go to the project file search page. (**Repository > Files**, click **Find Files**). |
|
| <kbd>t</kbd> | Go to the project file search page. (**Repository > Files**, click **Find Files**). |
|
||||||
| <kbd>g</kbd> + <kbd>c</kbd> | Go to the project commits list (**Repository > Commits**). |
|
| <kbd>g</kbd> + <kbd>c</kbd> | Go to the project commits list (**Repository > Commits**). |
|
||||||
| <kbd>g</kbd> + <kbd>n</kbd> | Go to the [repository graph](#repository-graph) page (**Repository > Graph**). |
|
| <kbd>g</kbd> + <kbd>n</kbd> | Go to the [repository graph](#repository-graph) page (**Repository > Graph**). |
|
||||||
| <kbd>g</kbd> + <kbd>d</kbd> | Go to repository charts (**Repository > Charts**). |
|
| <kbd>g</kbd> + <kbd>d</kbd> | Go to repository charts (**Analytics > Repository Analytics**). |
|
||||||
| <kbd>g</kbd> + <kbd>i</kbd> | Go to the project issues list (**Issues > List**). |
|
| <kbd>g</kbd> + <kbd>i</kbd> | Go to the project issues list (**Issues > List**). |
|
||||||
| <kbd>i</kbd> | Go to the New Issue page (**Issues**, click **New Issue** ). |
|
| <kbd>i</kbd> | Go to the New Issue page (**Issues**, click **New Issue** ). |
|
||||||
| <kbd>g</kbd> + <kbd>b</kbd> | Go to the project issue boards list (**Issues > Boards**). |
|
| <kbd>g</kbd> + <kbd>b</kbd> | Go to the project issue boards list (**Issues > Boards**). |
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ module API
|
||||||
detail 'This feature was introduced in GitLab 12.5.'
|
detail 'This feature was introduced in GitLab 12.5.'
|
||||||
end
|
end
|
||||||
post ':id/export' do
|
post ':id/export' do
|
||||||
GroupExportWorker.perform_async(current_user.id, user_group.id, params)
|
GroupExportWorker.perform_async(current_user.id, user_group.id, params) # rubocop:disable CodeReuse/Worker
|
||||||
|
|
||||||
accepted!
|
accepted!
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ module API
|
||||||
group = ::Groups::CreateService.new(current_user, group_params).execute
|
group = ::Groups::CreateService.new(current_user, group_params).execute
|
||||||
|
|
||||||
if group.persisted?
|
if group.persisted?
|
||||||
GroupImportWorker.perform_async(current_user.id, group.id)
|
GroupImportWorker.perform_async(current_user.id, group.id) # rubocop:disable CodeReuse/Worker
|
||||||
|
|
||||||
accepted!
|
accepted!
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ module API
|
||||||
post ':id/pipeline_schedules/:pipeline_schedule_id/play' do
|
post ':id/pipeline_schedules/:pipeline_schedule_id/play' do
|
||||||
authorize! :play_pipeline_schedule, pipeline_schedule
|
authorize! :play_pipeline_schedule, pipeline_schedule
|
||||||
|
|
||||||
job_id = RunPipelineScheduleWorker
|
job_id = RunPipelineScheduleWorker # rubocop:disable CodeReuse/Worker
|
||||||
.perform_async(pipeline_schedule.id, current_user.id)
|
.perform_async(pipeline_schedule.id, current_user.id)
|
||||||
|
|
||||||
if job_id
|
if job_id
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ module API
|
||||||
delete ':id/registry/repositories/:repository_id', requirements: REPOSITORY_ENDPOINT_REQUIREMENTS do
|
delete ':id/registry/repositories/:repository_id', requirements: REPOSITORY_ENDPOINT_REQUIREMENTS do
|
||||||
authorize_admin_container_image!
|
authorize_admin_container_image!
|
||||||
|
|
||||||
DeleteContainerRepositoryWorker.perform_async(current_user.id, repository.id)
|
DeleteContainerRepositoryWorker.perform_async(current_user.id, repository.id) # rubocop:disable CodeReuse/Worker
|
||||||
track_event('delete_repository')
|
track_event('delete_repository')
|
||||||
|
|
||||||
status :accepted
|
status :accepted
|
||||||
|
|
@ -79,8 +79,10 @@ module API
|
||||||
message = 'This request has already been made. You can run this at most once an hour for a given container repository'
|
message = 'This request has already been made. You can run this at most once an hour for a given container repository'
|
||||||
render_api_error!(message, 400) unless obtain_new_cleanup_container_lease
|
render_api_error!(message, 400) unless obtain_new_cleanup_container_lease
|
||||||
|
|
||||||
|
# rubocop:disable CodeReuse/Worker
|
||||||
CleanupContainerRepositoryWorker.perform_async(current_user.id, repository.id,
|
CleanupContainerRepositoryWorker.perform_async(current_user.id, repository.id,
|
||||||
declared_params.except(:repository_id).merge(container_expiration_policy: false))
|
declared_params.except(:repository_id).merge(container_expiration_policy: false))
|
||||||
|
# rubocop:enable CodeReuse/Worker
|
||||||
|
|
||||||
track_event('delete_tag_bulk')
|
track_event('delete_tag_bulk')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,9 +170,9 @@ module API
|
||||||
return if release.historical_release?
|
return if release.historical_release?
|
||||||
|
|
||||||
if release.upcoming_release?
|
if release.upcoming_release?
|
||||||
CreateEvidenceWorker.perform_at(release.released_at, release.id)
|
CreateEvidenceWorker.perform_at(release.released_at, release.id) # rubocop:disable CodeReuse/Worker
|
||||||
else
|
else
|
||||||
CreateEvidenceWorker.perform_async(release.id)
|
CreateEvidenceWorker.perform_async(release.id) # rubocop:disable CodeReuse/Worker
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
module BackgroundMigration
|
||||||
|
# Create missing LfsObjectsProject records for forks
|
||||||
|
class LinkLfsObjects
|
||||||
|
# Model definition used for migration
|
||||||
|
class ForkNetworkMember < ActiveRecord::Base
|
||||||
|
self.table_name = 'fork_network_members'
|
||||||
|
|
||||||
|
def self.with_non_existing_lfs_objects
|
||||||
|
joins('JOIN lfs_objects_projects lop ON fork_network_members.forked_from_project_id = lop.project_id')
|
||||||
|
.where(
|
||||||
|
<<~SQL
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM lfs_objects_projects
|
||||||
|
WHERE lfs_objects_projects.project_id = fork_network_members.project_id
|
||||||
|
AND lfs_objects_projects.lfs_object_id = lop.lfs_object_id
|
||||||
|
)
|
||||||
|
SQL
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform(start_id, end_id)
|
||||||
|
select_query =
|
||||||
|
ForkNetworkMember
|
||||||
|
.select('lop.lfs_object_id, fork_network_members.project_id')
|
||||||
|
.with_non_existing_lfs_objects
|
||||||
|
.where(project_id: start_id..end_id)
|
||||||
|
|
||||||
|
return if select_query.empty?
|
||||||
|
|
||||||
|
execute <<-SQL
|
||||||
|
INSERT INTO lfs_objects_projects (lfs_object_id, project_id)
|
||||||
|
#{select_query.to_sql}
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def execute(sql)
|
||||||
|
::ActiveRecord::Base.connection.execute(sql)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
apply:
|
apply:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.7.0"
|
image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.8.0"
|
||||||
environment:
|
environment:
|
||||||
name: production
|
name: production
|
||||||
variables:
|
variables:
|
||||||
|
|
@ -12,6 +12,8 @@ apply:
|
||||||
GITLAB_RUNNER_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/gitlab-runner/values.yaml
|
GITLAB_RUNNER_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/gitlab-runner/values.yaml
|
||||||
CILIUM_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/cilium/values.yaml
|
CILIUM_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/cilium/values.yaml
|
||||||
JUPYTERHUB_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/jupyterhub/values.yaml
|
JUPYTERHUB_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/jupyterhub/values.yaml
|
||||||
|
PROMETHEUS_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/prometheus/values.yaml
|
||||||
|
ELASTIC_STACK_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/elastic-stack/values.yaml
|
||||||
script:
|
script:
|
||||||
- gitlab-managed-apps /usr/local/share/gitlab-managed-apps/helmfile.yaml
|
- gitlab-managed-apps /usr/local/share/gitlab-managed-apps/helmfile.yaml
|
||||||
only:
|
only:
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,21 @@ module Gitlab
|
||||||
super
|
super
|
||||||
|
|
||||||
@group = @attributes['group']
|
@group = @attributes['group']
|
||||||
|
|
||||||
|
update_description
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
attr_reader :group
|
attr_reader :group
|
||||||
|
|
||||||
|
# Convert description empty string to nil
|
||||||
|
# due to existing object being saved with description: nil
|
||||||
|
# Which makes object lookup to fail since nil != ''
|
||||||
|
def update_description
|
||||||
|
attributes['description'] = nil if attributes['description'] == ''
|
||||||
|
end
|
||||||
|
|
||||||
def where_clauses
|
def where_clauses
|
||||||
[
|
[
|
||||||
where_clause_base,
|
where_clause_base,
|
||||||
|
|
|
||||||
4
qa/qa.rb
|
|
@ -159,6 +159,10 @@ module QA
|
||||||
autoload :Validator, 'qa/page/validator'
|
autoload :Validator, 'qa/page/validator'
|
||||||
autoload :Validatable, 'qa/page/validatable'
|
autoload :Validatable, 'qa/page/validatable'
|
||||||
|
|
||||||
|
module SubMenus
|
||||||
|
autoload :Common, 'qa/page/sub_menus/common'
|
||||||
|
end
|
||||||
|
|
||||||
module Main
|
module Main
|
||||||
autoload :Login, 'qa/page/main/login'
|
autoload :Login, 'qa/page/main/login'
|
||||||
autoload :Menu, 'qa/page/main/menu'
|
autoload :Menu, 'qa/page/main/menu'
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,22 @@ module QA
|
||||||
element :contribution_analytics_link
|
element :contribution_analytics_link
|
||||||
end
|
end
|
||||||
|
|
||||||
|
view 'app/views/layouts/nav/sidebar/_analytics_links.html.haml' do
|
||||||
|
element :analytics_link
|
||||||
|
element :analytics_sidebar_submenu
|
||||||
|
end
|
||||||
|
|
||||||
def click_group_members_item
|
def click_group_members_item
|
||||||
within_sidebar do
|
within_sidebar do
|
||||||
click_element(:group_members_item)
|
click_element(:group_members_item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_group_analytics_item
|
def click_contribution_analytics_item
|
||||||
within_sidebar do
|
hover_element(:analytics_link) do
|
||||||
click_element(:contribution_analytics_link)
|
within_submenu(:analytics_sidebar_submenu) do
|
||||||
|
click_element(:contribution_analytics_link)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ module QA
|
||||||
module Group
|
module Group
|
||||||
module SubMenus
|
module SubMenus
|
||||||
module Common
|
module Common
|
||||||
|
include QA::Page::SubMenus::Common
|
||||||
|
|
||||||
def self.included(base)
|
def self.included(base)
|
||||||
base.class_eval do
|
base.class_eval do
|
||||||
view 'app/views/layouts/nav/sidebar/_group.html.haml' do
|
view 'app/views/layouts/nav/sidebar/_group.html.haml' do
|
||||||
|
|
@ -13,23 +15,10 @@ module QA
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def hover_element(element)
|
private
|
||||||
within_sidebar do
|
|
||||||
find_element(element).hover
|
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def within_sidebar
|
def sidebar_element
|
||||||
within_element(:group_sidebar) do
|
:group_sidebar
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def within_submenu(element)
|
|
||||||
within_element(element) do
|
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,12 @@ module QA
|
||||||
module Project
|
module Project
|
||||||
module SubMenus
|
module SubMenus
|
||||||
module Common
|
module Common
|
||||||
def within_sidebar
|
include QA::Page::SubMenus::Common
|
||||||
within('.sidebar-top-level-items') do
|
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def within_submenu
|
private
|
||||||
if has_css?('.fly-out-list')
|
|
||||||
within('.fly-out-list') do
|
def sidebar_element
|
||||||
yield
|
:project_sidebar
|
||||||
end
|
|
||||||
else
|
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module QA
|
||||||
|
module Page
|
||||||
|
module SubMenus
|
||||||
|
module Common
|
||||||
|
def hover_element(element)
|
||||||
|
within_sidebar do
|
||||||
|
find_element(element).hover
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def within_sidebar
|
||||||
|
within_element(sidebar_element) do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def within_submenu(element = nil)
|
||||||
|
if element
|
||||||
|
within_element(element) do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
else
|
||||||
|
within_submenu_without_element do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def within_submenu_without_element
|
||||||
|
if has_css?('.fly-out-list')
|
||||||
|
within('.fly-out-list') do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
else
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def sidebar_element
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -55,6 +55,7 @@ require_relative 'cop/code_reuse/service_class'
|
||||||
require_relative 'cop/code_reuse/presenter'
|
require_relative 'cop/code_reuse/presenter'
|
||||||
require_relative 'cop/code_reuse/serializer'
|
require_relative 'cop/code_reuse/serializer'
|
||||||
require_relative 'cop/code_reuse/active_record'
|
require_relative 'cop/code_reuse/active_record'
|
||||||
|
require_relative 'cop/code_reuse/worker'
|
||||||
require_relative 'cop/group_public_or_visible_to_user'
|
require_relative 'cop/group_public_or_visible_to_user'
|
||||||
require_relative 'cop/inject_enterprise_edition_module'
|
require_relative 'cop/inject_enterprise_edition_module'
|
||||||
require_relative 'cop/graphql/authorize_types'
|
require_relative 'cop/graphql/authorize_types'
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ describe 'Internal Group access' do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/issues' do
|
describe 'GET /groups/:path/-/issues' do
|
||||||
subject { issues_group_path(group) }
|
subject { issues_group_path(group) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -51,7 +51,7 @@ describe 'Internal Group access' do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/merge_requests' do
|
describe 'GET /groups/:path/-/merge_requests' do
|
||||||
let(:project) { create(:project, :internal, :repository, group: group) }
|
let(:project) { create(:project, :internal, :repository, group: group) }
|
||||||
|
|
||||||
subject { merge_requests_group_path(group) }
|
subject { merge_requests_group_path(group) }
|
||||||
|
|
@ -68,7 +68,7 @@ describe 'Internal Group access' do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/group_members' do
|
describe 'GET /groups/:path/-/group_members' do
|
||||||
subject { group_group_members_path(group) }
|
subject { group_group_members_path(group) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -83,7 +83,7 @@ describe 'Internal Group access' do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/edit' do
|
describe 'GET /groups/:path/-/edit' do
|
||||||
subject { edit_group_path(group) }
|
subject { edit_group_path(group) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ describe 'Private Group access' do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/issues' do
|
describe 'GET /groups/:path/-/issues' do
|
||||||
subject { issues_group_path(group) }
|
subject { issues_group_path(group) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -51,7 +51,7 @@ describe 'Private Group access' do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/merge_requests' do
|
describe 'GET /groups/:path/-/merge_requests' do
|
||||||
let(:project) { create(:project, :private, :repository, group: group) }
|
let(:project) { create(:project, :private, :repository, group: group) }
|
||||||
|
|
||||||
subject { merge_requests_group_path(group) }
|
subject { merge_requests_group_path(group) }
|
||||||
|
|
@ -68,7 +68,7 @@ describe 'Private Group access' do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/group_members' do
|
describe 'GET /groups/:path/-/group_members' do
|
||||||
subject { group_group_members_path(group) }
|
subject { group_group_members_path(group) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -83,7 +83,7 @@ describe 'Private Group access' do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/edit' do
|
describe 'GET /groups/:path/-/edit' do
|
||||||
subject { edit_group_path(group) }
|
subject { edit_group_path(group) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ describe 'Public Group access' do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/issues' do
|
describe 'GET /groups/:path/-/issues' do
|
||||||
subject { issues_group_path(group) }
|
subject { issues_group_path(group) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -51,7 +51,7 @@ describe 'Public Group access' do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/merge_requests' do
|
describe 'GET /groups/:path/-/merge_requests' do
|
||||||
let(:project) { create(:project, :public, :repository, group: group) }
|
let(:project) { create(:project, :public, :repository, group: group) }
|
||||||
|
|
||||||
subject { merge_requests_group_path(group) }
|
subject { merge_requests_group_path(group) }
|
||||||
|
|
@ -68,7 +68,7 @@ describe 'Public Group access' do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/group_members' do
|
describe 'GET /groups/:path/-/group_members' do
|
||||||
subject { group_group_members_path(group) }
|
subject { group_group_members_path(group) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -83,7 +83,7 @@ describe 'Public Group access' do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /groups/:path/edit' do
|
describe 'GET /groups/:path/-/edit' do
|
||||||
subject { edit_group_path(group) }
|
subject { edit_group_path(group) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ describe "Internal Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/tree/master" do
|
describe "GET /:project_path/-/tree/master" do
|
||||||
subject { project_tree_path(project, project.repository.root_ref) }
|
subject { project_tree_path(project, project.repository.root_ref) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -43,7 +43,7 @@ describe "Internal Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/commits/master" do
|
describe "GET /:project_path/-/commits/master" do
|
||||||
subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
|
subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -57,7 +57,7 @@ describe "Internal Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/commit/:sha" do
|
describe "GET /:project_path/-/commit/:sha" do
|
||||||
subject { project_commit_path(project, project.repository.commit) }
|
subject { project_commit_path(project, project.repository.commit) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -71,7 +71,7 @@ describe "Internal Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/compare" do
|
describe "GET /:project_path/-/compare" do
|
||||||
subject { project_compare_index_path(project) }
|
subject { project_compare_index_path(project) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -127,7 +127,7 @@ describe "Internal Project Access" do
|
||||||
it { is_expected.to be_denied_for(:external) }
|
it { is_expected.to be_denied_for(:external) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/blob" do
|
describe "GET /:project_path/-/blob" do
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.repository.commit }
|
||||||
|
|
||||||
subject { project_blob_path(project, File.join(commit.id, '.gitignore')) }
|
subject { project_blob_path(project, File.join(commit.id, '.gitignore')) }
|
||||||
|
|
@ -229,7 +229,7 @@ describe "Internal Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/merge_requests" do
|
describe "GET /:project_path/-/merge_requests" do
|
||||||
subject { project_merge_requests_path(project) }
|
subject { project_merge_requests_path(project) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -243,7 +243,7 @@ describe "Internal Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/merge_requests/new" do
|
describe "GET /:project_path/-/merge_requests/new" do
|
||||||
subject { project_new_merge_request_path(project) }
|
subject { project_new_merge_request_path(project) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -257,7 +257,7 @@ describe "Internal Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/branches" do
|
describe "GET /:project_path/-/branches" do
|
||||||
subject { project_branches_path(project) }
|
subject { project_branches_path(project) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
@ -278,7 +278,7 @@ describe "Internal Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/tags" do
|
describe "GET /:project_path/-/tags" do
|
||||||
subject { project_tags_path(project) }
|
subject { project_tags_path(project) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ describe "Private Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/tree/master" do
|
describe "GET /:project_path/-/tree/master" do
|
||||||
subject { project_tree_path(project, project.repository.root_ref) }
|
subject { project_tree_path(project, project.repository.root_ref) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -43,7 +43,7 @@ describe "Private Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/commits/master" do
|
describe "GET /:project_path/-/commits/master" do
|
||||||
subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
|
subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -57,7 +57,7 @@ describe "Private Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/commit/:sha" do
|
describe "GET /:project_path/-/commit/:sha" do
|
||||||
subject { project_commit_path(project, project.repository.commit) }
|
subject { project_commit_path(project, project.repository.commit) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -71,7 +71,7 @@ describe "Private Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/compare" do
|
describe "GET /:project_path/-/compare" do
|
||||||
subject { project_compare_index_path(project) }
|
subject { project_compare_index_path(project) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -127,7 +127,7 @@ describe "Private Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/blob" do
|
describe "GET /:project_path/-/blob" do
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.repository.commit }
|
||||||
|
|
||||||
subject { project_blob_path(project, File.join(commit.id, '.gitignore')) }
|
subject { project_blob_path(project, File.join(commit.id, '.gitignore')) }
|
||||||
|
|
@ -215,7 +215,7 @@ describe "Private Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/merge_requests" do
|
describe "GET /:project_path/-/merge_requests" do
|
||||||
subject { project_merge_requests_path(project) }
|
subject { project_merge_requests_path(project) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -229,7 +229,7 @@ describe "Private Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/branches" do
|
describe "GET /:project_path/-/branches" do
|
||||||
subject { project_branches_path(project) }
|
subject { project_branches_path(project) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
@ -250,7 +250,7 @@ describe "Private Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/tags" do
|
describe "GET /:project_path/-/tags" do
|
||||||
subject { project_tags_path(project) }
|
subject { project_tags_path(project) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ describe "Public Project Access" do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/tree/master" do
|
describe "GET /:project_path/-/tree/master" do
|
||||||
subject { project_tree_path(project, project.repository.root_ref) }
|
subject { project_tree_path(project, project.repository.root_ref) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -43,7 +43,7 @@ describe "Public Project Access" do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/commits/master" do
|
describe "GET /:project_path/-/commits/master" do
|
||||||
subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
|
subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -57,7 +57,7 @@ describe "Public Project Access" do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/commit/:sha" do
|
describe "GET /:project_path/-/commit/:sha" do
|
||||||
subject { project_commit_path(project, project.repository.commit) }
|
subject { project_commit_path(project, project.repository.commit) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -71,7 +71,7 @@ describe "Public Project Access" do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/compare" do
|
describe "GET /:project_path/-/compare" do
|
||||||
subject { project_compare_index_path(project) }
|
subject { project_compare_index_path(project) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -345,7 +345,7 @@ describe "Public Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/blob" do
|
describe "GET /:project_path/-/blob" do
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.repository.commit }
|
||||||
|
|
||||||
subject { project_blob_path(project, File.join(commit.id, '.gitignore')) }
|
subject { project_blob_path(project, File.join(commit.id, '.gitignore')) }
|
||||||
|
|
@ -446,7 +446,7 @@ describe "Public Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/merge_requests" do
|
describe "GET /:project_path/-/merge_requests" do
|
||||||
subject { project_merge_requests_path(project) }
|
subject { project_merge_requests_path(project) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -460,7 +460,7 @@ describe "Public Project Access" do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/merge_requests/new" do
|
describe "GET /:project_path/-/merge_requests/new" do
|
||||||
subject { project_new_merge_request_path(project) }
|
subject { project_new_merge_request_path(project) }
|
||||||
|
|
||||||
it { is_expected.to be_allowed_for(:admin) }
|
it { is_expected.to be_allowed_for(:admin) }
|
||||||
|
|
@ -474,7 +474,7 @@ describe "Public Project Access" do
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/branches" do
|
describe "GET /:project_path/-/branches" do
|
||||||
subject { project_branches_path(project) }
|
subject { project_branches_path(project) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
@ -495,7 +495,7 @@ describe "Public Project Access" do
|
||||||
it { is_expected.to be_allowed_for(:visitor) }
|
it { is_expected.to be_allowed_for(:visitor) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /:project_path/tags" do
|
describe "GET /:project_path/-/tags" do
|
||||||
subject { project_tags_path(project) }
|
subject { project_tags_path(project) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
|
||||||
|
|
@ -91,16 +91,37 @@ describe('Monitoring mutations', () => {
|
||||||
expect(stateCopy.projectPath).toEqual('/gitlab-org/gitlab-foss');
|
expect(stateCopy.projectPath).toEqual('/gitlab-org/gitlab-foss');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not remove default value of logsPath', () => {
|
it('should not remove previously set properties', () => {
|
||||||
const defaultLogsPath = stateCopy.logsPath;
|
const defaultLogsPath = stateCopy.logsPath;
|
||||||
|
|
||||||
|
mutations[types.SET_ENDPOINTS](stateCopy, {
|
||||||
|
logsPath: defaultLogsPath,
|
||||||
|
});
|
||||||
mutations[types.SET_ENDPOINTS](stateCopy, {
|
mutations[types.SET_ENDPOINTS](stateCopy, {
|
||||||
dashboardEndpoint: 'dashboard.json',
|
dashboardEndpoint: 'dashboard.json',
|
||||||
});
|
});
|
||||||
|
mutations[types.SET_ENDPOINTS](stateCopy, {
|
||||||
|
projectPath: '/gitlab-org/gitlab-foss',
|
||||||
|
});
|
||||||
|
|
||||||
expect(stateCopy.logsPath).toBe(defaultLogsPath);
|
expect(stateCopy).toMatchObject({
|
||||||
|
logsPath: defaultLogsPath,
|
||||||
|
dashboardEndpoint: 'dashboard.json',
|
||||||
|
projectPath: '/gitlab-org/gitlab-foss',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not update unknown properties', () => {
|
||||||
|
mutations[types.SET_ENDPOINTS](stateCopy, {
|
||||||
|
dashboardEndpoint: 'dashboard.json',
|
||||||
|
someOtherProperty: 'some invalid value', // someOtherProperty is not allowed
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(stateCopy.dashboardEndpoint).toBe('dashboard.json');
|
||||||
|
expect(stateCopy.someOtherProperty).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Individual panel/metric results', () => {
|
describe('Individual panel/metric results', () => {
|
||||||
const metricId = '12_system_metrics_kubernetes_container_memory_total';
|
const metricId = '12_system_metrics_kubernetes_container_memory_total';
|
||||||
const result = [
|
const result = [
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import Vuex from 'vuex';
|
import Vuex from 'vuex';
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import ReleaseDetailApp from '~/releases/detail/components/app.vue';
|
import ReleaseEditApp from '~/releases/components/app_edit.vue';
|
||||||
import { release } from '../../mock_data';
|
import { release } from '../mock_data';
|
||||||
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
describe('Release detail component', () => {
|
describe('Release edit component', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
let releaseClone;
|
let releaseClone;
|
||||||
let actions;
|
let actions;
|
||||||
|
|
@ -27,9 +27,17 @@ describe('Release detail component', () => {
|
||||||
navigateToReleasesPage: jest.fn(),
|
navigateToReleasesPage: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const store = new Vuex.Store({ actions, state });
|
const store = new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
detail: {
|
||||||
|
namespaced: true,
|
||||||
|
actions,
|
||||||
|
state,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
wrapper = mount(ReleaseDetailApp, {
|
wrapper = mount(ReleaseEditApp, {
|
||||||
store,
|
store,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -2,8 +2,8 @@ import { mount } from '@vue/test-utils';
|
||||||
import { GlLink } from '@gitlab/ui';
|
import { GlLink } from '@gitlab/ui';
|
||||||
import { truncateSha } from '~/lib/utils/text_utility';
|
import { truncateSha } from '~/lib/utils/text_utility';
|
||||||
import Icon from '~/vue_shared/components/icon.vue';
|
import Icon from '~/vue_shared/components/icon.vue';
|
||||||
import { release } from '../../mock_data';
|
import { release } from '../mock_data';
|
||||||
import EvidenceBlock from '~/releases/list/components/evidence_block.vue';
|
import EvidenceBlock from '~/releases/components/evidence_block.vue';
|
||||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||||
|
|
||||||
describe('Evidence Block', () => {
|
describe('Evidence Block', () => {
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import { GlLink } from '@gitlab/ui';
|
import { GlLink } from '@gitlab/ui';
|
||||||
import { trimText } from 'helpers/text_helper';
|
import { trimText } from 'helpers/text_helper';
|
||||||
import ReleaseBlockFooter from '~/releases/list/components/release_block_footer.vue';
|
import ReleaseBlockFooter from '~/releases/components/release_block_footer.vue';
|
||||||
import Icon from '~/vue_shared/components/icon.vue';
|
import Icon from '~/vue_shared/components/icon.vue';
|
||||||
import { release } from '../../mock_data';
|
import { release } from '../mock_data';
|
||||||
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
jest.mock('~/vue_shared/mixins/timeago', () => ({
|
jest.mock('~/vue_shared/mixins/timeago', () => ({
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { cloneDeep, merge } from 'lodash';
|
import { cloneDeep, merge } from 'lodash';
|
||||||
import { GlLink } from '@gitlab/ui';
|
import { GlLink } from '@gitlab/ui';
|
||||||
import ReleaseBlockHeader from '~/releases/list/components/release_block_header.vue';
|
import ReleaseBlockHeader from '~/releases/components/release_block_header.vue';
|
||||||
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
||||||
import { release as originalRelease } from '../../mock_data';
|
import { release as originalRelease } from '../mock_data';
|
||||||
|
|
||||||
describe('Release block header', () => {
|
describe('Release block header', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import { GlProgressBar, GlLink, GlBadge, GlButton } from '@gitlab/ui';
|
import { GlProgressBar, GlLink, GlBadge, GlButton } from '@gitlab/ui';
|
||||||
import { trimText } from 'helpers/text_helper';
|
import { trimText } from 'helpers/text_helper';
|
||||||
import ReleaseBlockMilestoneInfo from '~/releases/list/components/release_block_milestone_info.vue';
|
import ReleaseBlockMilestoneInfo from '~/releases/components/release_block_milestone_info.vue';
|
||||||
import { milestones } from '../../mock_data';
|
import { milestones } from '../mock_data';
|
||||||
import { MAX_MILESTONES_TO_DISPLAY } from '~/releases/list/constants';
|
import { MAX_MILESTONES_TO_DISPLAY } from '~/releases/constants';
|
||||||
|
|
||||||
describe('Release block milestone info', () => {
|
describe('Release block milestone info', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import { first } from 'underscore';
|
import { first } from 'underscore';
|
||||||
import EvidenceBlock from '~/releases/list/components/evidence_block.vue';
|
import EvidenceBlock from '~/releases/components/evidence_block.vue';
|
||||||
import ReleaseBlock from '~/releases/list/components/release_block.vue';
|
import ReleaseBlock from '~/releases/components/release_block.vue';
|
||||||
import ReleaseBlockFooter from '~/releases/list/components/release_block_footer.vue';
|
import ReleaseBlockFooter from '~/releases/components/release_block_footer.vue';
|
||||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||||
import { release } from '../../mock_data';
|
import { release } from '../mock_data';
|
||||||
import Icon from '~/vue_shared/components/icon.vue';
|
import Icon from '~/vue_shared/components/icon.vue';
|
||||||
import { scrollToElement } from '~/lib/utils/common_utils';
|
import { scrollToElement } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import MockAdapter from 'axios-mock-adapter';
|
import MockAdapter from 'axios-mock-adapter';
|
||||||
import testAction from 'helpers/vuex_action_helper';
|
import testAction from 'helpers/vuex_action_helper';
|
||||||
import * as actions from '~/releases/detail/store/actions';
|
import * as actions from '~/releases/stores/modules/detail/actions';
|
||||||
import * as types from '~/releases/detail/store/mutation_types';
|
import * as types from '~/releases/stores/modules/detail/mutation_types';
|
||||||
import { release } from '../../mock_data';
|
import { release } from '../../../mock_data';
|
||||||
import state from '~/releases/detail/store/state';
|
import state from '~/releases/stores/modules/detail/state';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import { redirectTo } from '~/lib/utils/url_utility';
|
import { redirectTo } from '~/lib/utils/url_utility';
|
||||||
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
||||||
|
|
@ -5,10 +5,10 @@
|
||||||
* is resolved
|
* is resolved
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import state from '~/releases/detail/store/state';
|
import state from '~/releases/stores/modules/detail/state';
|
||||||
import mutations from '~/releases/detail/store/mutations';
|
import mutations from '~/releases/stores/modules/detail/mutations';
|
||||||
import * as types from '~/releases/detail/store/mutation_types';
|
import * as types from '~/releases/stores/modules/detail/mutation_types';
|
||||||
import { release } from '../../mock_data';
|
import { release } from '../../../mock_data';
|
||||||
|
|
||||||
describe('Release detail mutations', () => {
|
describe('Release detail mutations', () => {
|
||||||
let stateClone;
|
let stateClone;
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
import _ from 'underscore';
|
import _ from 'underscore';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
|
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
|
||||||
import app from '~/releases/list/components/app.vue';
|
import app from '~/releases/components/app_index.vue';
|
||||||
import createStore from '~/releases/list/store';
|
import createStore from '~/releases/stores';
|
||||||
|
import listModule from '~/releases/stores/modules/list';
|
||||||
import api from '~/api';
|
import api from '~/api';
|
||||||
import { resetStore } from '../store/helpers';
|
import { resetStore } from '../stores/modules/list/helpers';
|
||||||
import {
|
import {
|
||||||
pageInfoHeadersWithoutPagination,
|
pageInfoHeadersWithoutPagination,
|
||||||
pageInfoHeadersWithPagination,
|
pageInfoHeadersWithPagination,
|
||||||
release,
|
release,
|
||||||
releases,
|
releases,
|
||||||
} from '../../mock_data';
|
} from '../mock_data';
|
||||||
|
|
||||||
describe('Releases App ', () => {
|
describe('Releases App ', () => {
|
||||||
const Component = Vue.extend(app);
|
const Component = Vue.extend(app);
|
||||||
|
|
@ -25,7 +26,7 @@ describe('Releases App ', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
store = createStore();
|
store = createStore({ list: listModule });
|
||||||
releasesPagination = _.range(21).map(index => ({ ...release, tag_name: `${index}.00` }));
|
releasesPagination = _.range(21).map(index => ({ ...release, tag_name: `${index}.00` }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -4,12 +4,12 @@ import {
|
||||||
fetchReleases,
|
fetchReleases,
|
||||||
receiveReleasesSuccess,
|
receiveReleasesSuccess,
|
||||||
receiveReleasesError,
|
receiveReleasesError,
|
||||||
} from '~/releases/list/store/actions';
|
} from '~/releases/stores/modules/list/actions';
|
||||||
import state from '~/releases/list/store/state';
|
import state from '~/releases/stores/modules/list/state';
|
||||||
import * as types from '~/releases/list/store/mutation_types';
|
import * as types from '~/releases/stores/modules/list/mutation_types';
|
||||||
import api from '~/api';
|
import api from '~/api';
|
||||||
import { parseIntPagination } from '~/lib/utils/common_utils';
|
import { parseIntPagination } from '~/lib/utils/common_utils';
|
||||||
import { pageInfoHeadersWithoutPagination, releases } from '../../mock_data';
|
import { pageInfoHeadersWithoutPagination, releases } from '../../../mock_data';
|
||||||
|
|
||||||
describe('Releases State actions', () => {
|
describe('Releases State actions', () => {
|
||||||
let mockedState;
|
let mockedState;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import state from '~/releases/list/store/state';
|
import state from '~/releases/stores/modules/list/state';
|
||||||
|
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
export const resetStore = store => {
|
export const resetStore = store => {
|
||||||