summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-14 21:09:08 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-14 21:09:08 +0000
commit866ca4e49ff74ffadf8e6f6ff663a168489c2aba (patch)
treecc3135b1bae11dbd1cb3a30cb547473ad89a5551
parent26a50872e9da9509c52c70f74dc21698fec906db (diff)
downloadgitlab-ce-866ca4e49ff74ffadf8e6f6ff663a168489c2aba.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/global.gitlab-ci.yml8
-rw-r--r--app/assets/javascripts/monitoring/stores/actions.js4
-rw-r--r--app/assets/javascripts/monitoring/stores/mutations.js23
-rw-r--r--app/assets/javascripts/pages/projects/releases/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/releases/index/index.js2
-rw-r--r--app/assets/javascripts/releases/components/app_edit.vue (renamed from app/assets/javascripts/releases/detail/components/app.vue)12
-rw-r--r--app/assets/javascripts/releases/components/app_index.vue (renamed from app/assets/javascripts/releases/list/components/app.vue)4
-rw-r--r--app/assets/javascripts/releases/components/evidence_block.vue (renamed from app/assets/javascripts/releases/list/components/evidence_block.vue)0
-rw-r--r--app/assets/javascripts/releases/components/release_block.vue (renamed from app/assets/javascripts/releases/list/components/release_block.vue)0
-rw-r--r--app/assets/javascripts/releases/components/release_block_assets.vue (renamed from app/assets/javascripts/releases/list/components/release_block_assets.vue)0
-rw-r--r--app/assets/javascripts/releases/components/release_block_author.vue (renamed from app/assets/javascripts/releases/list/components/release_block_author.vue)0
-rw-r--r--app/assets/javascripts/releases/components/release_block_footer.vue (renamed from app/assets/javascripts/releases/list/components/release_block_footer.vue)0
-rw-r--r--app/assets/javascripts/releases/components/release_block_header.vue (renamed from app/assets/javascripts/releases/list/components/release_block_header.vue)0
-rw-r--r--app/assets/javascripts/releases/components/release_block_metadata.vue (renamed from app/assets/javascripts/releases/list/components/release_block_metadata.vue)0
-rw-r--r--app/assets/javascripts/releases/components/release_block_milestone_info.vue (renamed from app/assets/javascripts/releases/list/components/release_block_milestone_info.vue)0
-rw-r--r--app/assets/javascripts/releases/components/release_block_milestones.vue (renamed from app/assets/javascripts/releases/list/components/release_block_milestones.vue)0
-rw-r--r--app/assets/javascripts/releases/constants.js (renamed from app/assets/javascripts/releases/list/constants.js)0
-rw-r--r--app/assets/javascripts/releases/detail/index.js19
-rw-r--r--app/assets/javascripts/releases/detail/store/index.js14
-rw-r--r--app/assets/javascripts/releases/list/index.js24
-rw-r--r--app/assets/javascripts/releases/list/store/index.js14
-rw-r--r--app/assets/javascripts/releases/mount_edit.js17
-rw-r--r--app/assets/javascripts/releases/mount_index.js21
-rw-r--r--app/assets/javascripts/releases/stores/index.js6
-rw-r--r--app/assets/javascripts/releases/stores/modules/detail/actions.js (renamed from app/assets/javascripts/releases/detail/store/actions.js)0
-rw-r--r--app/assets/javascripts/releases/stores/modules/detail/index.js10
-rw-r--r--app/assets/javascripts/releases/stores/modules/detail/mutation_types.js (renamed from app/assets/javascripts/releases/detail/store/mutation_types.js)0
-rw-r--r--app/assets/javascripts/releases/stores/modules/detail/mutations.js (renamed from app/assets/javascripts/releases/detail/store/mutations.js)0
-rw-r--r--app/assets/javascripts/releases/stores/modules/detail/state.js (renamed from app/assets/javascripts/releases/detail/store/state.js)0
-rw-r--r--app/assets/javascripts/releases/stores/modules/list/actions.js (renamed from app/assets/javascripts/releases/list/store/actions.js)0
-rw-r--r--app/assets/javascripts/releases/stores/modules/list/index.js10
-rw-r--r--app/assets/javascripts/releases/stores/modules/list/mutation_types.js (renamed from app/assets/javascripts/releases/list/store/mutation_types.js)0
-rw-r--r--app/assets/javascripts/releases/stores/modules/list/mutations.js (renamed from app/assets/javascripts/releases/list/store/mutations.js)0
-rw-r--r--app/assets/javascripts/releases/stores/modules/list/state.js (renamed from app/assets/javascripts/releases/list/store/state.js)0
-rw-r--r--app/controllers/admin/application_settings_controller.rb10
-rw-r--r--app/controllers/admin/projects_controller.rb2
-rw-r--r--app/controllers/admin/services_controller.rb2
-rw-r--r--app/controllers/projects/issues_controller.rb2
-rw-r--r--app/controllers/projects/pipeline_schedules_controller.rb2
-rw-r--r--app/controllers/projects/registry/repositories_controller.rb2
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb2
-rw-r--r--app/controllers/projects/settings/repository_controller.rb2
-rw-r--r--app/controllers/repositories/git_http_controller.rb2
-rw-r--r--app/helpers/analytics_navbar_helper.rb6
-rw-r--r--app/services/ci/process_build_service.rb8
-rw-r--r--app/views/layouts/nav/sidebar/_analytics_links.html.haml4
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml4
-rw-r--r--changelogs/unreleased/31526-skip-if-needed-job-skipped.yml5
-rw-r--r--changelogs/unreleased/55487-backfill-lfs-objects-projects-sql.yml5
-rw-r--r--changelogs/unreleased/georgekoltsov-object_builder_convert_empty_strings.yml6
-rw-r--r--changelogs/unreleased/jcunha-update-managed-apps-template.yml5
-rw-r--r--changelogs/unreleased/toggle-analytics-navbar-feature-flags.yml5
-rw-r--r--db/post_migrate/20200210062432_schedule_link_lfs_objects.rb38
-rw-r--r--doc/user/group/contribution_analytics/index.md2
-rw-r--r--doc/user/group/insights/img/insights_sidebar_link.pngbin12327 -> 0 bytes
-rw-r--r--doc/user/group/insights/img/insights_sidebar_link_v12_8.pngbin0 -> 7773 bytes
-rw-r--r--doc/user/group/insights/index.md4
-rw-r--r--doc/user/group/issues_analytics/img/issues_created_per_month.pngbin28508 -> 0 bytes
-rw-r--r--doc/user/group/issues_analytics/img/issues_created_per_month_v12_8.pngbin0 -> 66854 bytes
-rw-r--r--doc/user/group/issues_analytics/index.md4
-rw-r--r--doc/user/project/insights/img/insights_sidebar_link.pngbin13776 -> 0 bytes
-rw-r--r--doc/user/project/insights/img/insights_sidebar_link_v12_8.pngbin0 -> 11194 bytes
-rw-r--r--doc/user/project/insights/index.md4
-rw-r--r--doc/user/project/integrations/img/prometheus_dashboard_area_panel_type.pngbin19349 -> 0 bytes
-rw-r--r--doc/user/project/integrations/img/prometheus_dashboard_area_panel_type_v12_8.pngbin0 -> 53370 bytes
-rw-r--r--doc/user/project/integrations/prometheus.md6
-rw-r--r--doc/user/shortcuts.md2
-rw-r--r--lib/api/group_export.rb2
-rw-r--r--lib/api/group_import.rb2
-rw-r--r--lib/api/pipeline_schedules.rb2
-rw-r--r--lib/api/project_container_repositories.rb4
-rw-r--r--lib/api/releases.rb4
-rw-r--r--lib/gitlab/background_migration/link_lfs_objects.rb48
-rw-r--r--lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml4
-rw-r--r--lib/gitlab/import_export/group_object_builder.rb9
-rw-r--r--qa/qa.rb4
-rw-r--r--qa/qa/page/group/menu.rb13
-rw-r--r--qa/qa/page/group/sub_menus/common.rb21
-rw-r--r--qa/qa/page/project/sub_menus/common.rb18
-rw-r--r--qa/qa/page/sub_menus/common.rb50
-rw-r--r--rubocop/rubocop.rb1
-rw-r--r--spec/features/security/group/internal_access_spec.rb8
-rw-r--r--spec/features/security/group/private_access_spec.rb8
-rw-r--r--spec/features/security/group/public_access_spec.rb8
-rw-r--r--spec/features/security/project/internal_access_spec.rb18
-rw-r--r--spec/features/security/project/private_access_spec.rb16
-rw-r--r--spec/features/security/project/public_access_spec.rb18
-rw-r--r--spec/frontend/monitoring/store/mutations_spec.js25
-rw-r--r--spec/frontend/releases/components/app_edit_spec.js (renamed from spec/frontend/releases/detail/components/app_spec.js)18
-rw-r--r--spec/frontend/releases/components/evidence_block_spec.js (renamed from spec/frontend/releases/list/components/evidence_block_spec.js)4
-rw-r--r--spec/frontend/releases/components/release_block_footer_spec.js (renamed from spec/frontend/releases/list/components/release_block_footer_spec.js)4
-rw-r--r--spec/frontend/releases/components/release_block_header_spec.js (renamed from spec/frontend/releases/list/components/release_block_header_spec.js)4
-rw-r--r--spec/frontend/releases/components/release_block_milestone_info_spec.js (renamed from spec/frontend/releases/list/components/release_block_milestone_info_spec.js)6
-rw-r--r--spec/frontend/releases/components/release_block_spec.js (renamed from spec/frontend/releases/list/components/release_block_spec.js)8
-rw-r--r--spec/frontend/releases/stores/modules/detail/actions_spec.js (renamed from spec/frontend/releases/detail/store/actions_spec.js)8
-rw-r--r--spec/frontend/releases/stores/modules/detail/mutations_spec.js (renamed from spec/frontend/releases/detail/store/mutations_spec.js)8
-rw-r--r--spec/javascripts/releases/components/app_index_spec.js (renamed from spec/javascripts/releases/list/components/app_spec.js)11
-rw-r--r--spec/javascripts/releases/stores/modules/list/actions_spec.js (renamed from spec/javascripts/releases/list/store/actions_spec.js)8
-rw-r--r--spec/javascripts/releases/stores/modules/list/helpers.js (renamed from spec/javascripts/releases/list/store/helpers.js)2
-rw-r--r--spec/javascripts/releases/stores/modules/list/mutations_spec.js (renamed from spec/javascripts/releases/list/store/mutations_spec.js)8
-rw-r--r--spec/lib/gitlab/background_migration/link_lfs_objects_spec.rb66
-rw-r--r--spec/lib/gitlab/import_export/group_object_builder_spec.rb22
-rw-r--r--spec/migrations/schedule_link_lfs_objects_spec.rb82
-rw-r--r--spec/routing/project_routing_spec.rb16
-rw-r--r--spec/services/ci/pipeline_processing/shared_processing_service.rb25
-rw-r--r--spec/services/ci/process_build_service_spec.rb31
107 files changed, 688 insertions, 252 deletions
diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml
index c18453b778c..7171f94decc 100644
--- a/.gitlab/ci/global.gitlab-ci.yml
+++ b/.gitlab/ci/global.gitlab-ci.yml
@@ -203,6 +203,8 @@
- name: postgres:9.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:alpine
+ variables:
+ POSTGRES_HOST_AUTH_METHOD: trust
.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"
@@ -210,6 +212,8 @@
- name: postgres:10.9
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:alpine
+ variables:
+ POSTGRES_HOST_AUTH_METHOD: trust
.use-pg9-ee:
services:
@@ -217,6 +221,8 @@
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:alpine
- name: elasticsearch:6.4.2
+ variables:
+ POSTGRES_HOST_AUTH_METHOD: trust
.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"
@@ -225,6 +231,8 @@
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:alpine
- name: elasticsearch:6.4.2
+ variables:
+ POSTGRES_HOST_AUTH_METHOD: trust
.only-ee:
only:
diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js
index 3a052200ab9..8bb5047ef04 100644
--- a/app/assets/javascripts/monitoring/stores/actions.js
+++ b/app/assets/javascripts/monitoring/stores/actions.js
@@ -6,7 +6,7 @@ import { gqClient, parseEnvironmentsResponse, removeLeadingSlash } from './utils
import trackDashboardLoad from '../monitoring_tracking_helper';
import getEnvironments from '../queries/getEnvironments.query.graphql';
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 { PROMETHEUS_TIMEOUT } from '../constants';
@@ -52,6 +52,8 @@ export const requestMetricsDashboard = ({ commit }) => {
export const receiveMetricsDashboardSuccess = ({ commit, dispatch }, { response, params }) => {
commit(types.SET_ALL_DASHBOARDS, response.all_dashboards);
commit(types.RECEIVE_METRICS_DATA_SUCCESS, response.dashboard);
+ commit(types.SET_ENDPOINTS, convertObjectPropsToCamelCase(response.metrics_data));
+
return dispatch('fetchPrometheusMetrics', params);
};
export const receiveMetricsDashboardFailure = ({ commit }, error) => {
diff --git a/app/assets/javascripts/monitoring/stores/mutations.js b/app/assets/javascripts/monitoring/stores/mutations.js
index 5f559290ff7..8bd53a24b61 100644
--- a/app/assets/javascripts/monitoring/stores/mutations.js
+++ b/app/assets/javascripts/monitoring/stores/mutations.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+import pick from 'lodash/pick';
import { slugify } from '~/lib/utils/text_utility';
import * as types from './mutation_types';
import { normalizeMetric, normalizeQueryResult } from './utils';
@@ -174,15 +175,19 @@ export default {
state: emptyStateFromError(error),
});
},
-
- [types.SET_ENDPOINTS](state, endpoints) {
- state.metricsEndpoint = endpoints.metricsEndpoint;
- state.deploymentsEndpoint = endpoints.deploymentsEndpoint;
- state.dashboardEndpoint = endpoints.dashboardEndpoint;
- state.dashboardsEndpoint = endpoints.dashboardsEndpoint;
- state.currentDashboard = endpoints.currentDashboard;
- state.projectPath = endpoints.projectPath;
- state.logsPath = endpoints.logsPath || state.logsPath;
+ [types.SET_ENDPOINTS](state, endpoints = {}) {
+ const endpointKeys = [
+ 'metricsEndpoint',
+ 'deploymentsEndpoint',
+ 'dashboardEndpoint',
+ 'dashboardsEndpoint',
+ 'currentDashboard',
+ 'projectPath',
+ 'logsPath',
+ ];
+ Object.entries(pick(endpoints, endpointKeys)).forEach(([key, value]) => {
+ state[key] = value;
+ });
},
[types.SET_TIME_RANGE](state, timeRange) {
state.timeRange = timeRange;
diff --git a/app/assets/javascripts/pages/projects/releases/edit/index.js b/app/assets/javascripts/pages/projects/releases/edit/index.js
index 98ec196fc37..efa059dcd6d 100644
--- a/app/assets/javascripts/pages/projects/releases/edit/index.js
+++ b/app/assets/javascripts/pages/projects/releases/edit/index.js
@@ -1,5 +1,5 @@
import ZenMode from '~/zen_mode';
-import initEditRelease from '~/releases/detail';
+import initEditRelease from '~/releases/mount_edit';
document.addEventListener('DOMContentLoaded', () => {
new ZenMode(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/releases/index/index.js b/app/assets/javascripts/pages/projects/releases/index/index.js
index 6402023149f..24c9cd528b3 100644
--- a/app/assets/javascripts/pages/projects/releases/index/index.js
+++ b/app/assets/javascripts/pages/projects/releases/index/index.js
@@ -1,3 +1,3 @@
-import initReleases from '~/releases/list';
+import initReleases from '~/releases/mount_index';
document.addEventListener('DOMContentLoaded', initReleases);
diff --git a/app/assets/javascripts/releases/detail/components/app.vue b/app/assets/javascripts/releases/components/app_edit.vue
index 073cfcd7694..bdc2b3abb8c 100644
--- a/app/assets/javascripts/releases/detail/components/app.vue
+++ b/app/assets/javascripts/releases/components/app_edit.vue
@@ -7,7 +7,7 @@ import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
export default {
- name: 'ReleaseDetailApp',
+ name: 'ReleaseEditApp',
components: {
GlFormInput,
GlFormGroup,
@@ -18,7 +18,7 @@ export default {
autofocusonshow,
},
computed: {
- ...mapState([
+ ...mapState('detail', [
'isFetchingRelease',
'fetchError',
'markdownDocsPath',
@@ -42,7 +42,7 @@ export default {
);
},
tagName() {
- return this.$store.state.release.tagName;
+ return this.$store.state.detail.release.tagName;
},
tagNameHintText() {
return sprintf(
@@ -60,7 +60,7 @@ export default {
},
releaseTitle: {
get() {
- return this.$store.state.release.name;
+ return this.$store.state.detail.release.name;
},
set(title) {
this.updateReleaseTitle(title);
@@ -68,7 +68,7 @@ export default {
},
releaseNotes: {
get() {
- return this.$store.state.release.description;
+ return this.$store.state.detail.release.description;
},
set(notes) {
this.updateReleaseNotes(notes);
@@ -79,7 +79,7 @@ export default {
this.fetchRelease();
},
methods: {
- ...mapActions([
+ ...mapActions('detail', [
'fetchRelease',
'updateRelease',
'updateReleaseTitle',
diff --git a/app/assets/javascripts/releases/list/components/app.vue b/app/assets/javascripts/releases/components/app_index.vue
index eb63e709ebd..f602c9fdda2 100644
--- a/app/assets/javascripts/releases/list/components/app.vue
+++ b/app/assets/javascripts/releases/components/app_index.vue
@@ -32,7 +32,7 @@ export default {
},
},
computed: {
- ...mapState(['isLoading', 'releases', 'hasError', 'pageInfo']),
+ ...mapState('list', ['isLoading', 'releases', 'hasError', 'pageInfo']),
shouldRenderEmptyState() {
return !this.releases.length && !this.hasError && !this.isLoading;
},
@@ -47,7 +47,7 @@ export default {
});
},
methods: {
- ...mapActions(['fetchReleases']),
+ ...mapActions('list', ['fetchReleases']),
onChangePage(page) {
historyPushState(buildUrlWithCurrentLocation(`?page=${page}`));
this.fetchReleases({ page, projectId: this.projectId });
diff --git a/app/assets/javascripts/releases/list/components/evidence_block.vue b/app/assets/javascripts/releases/components/evidence_block.vue
index d9abd195fee..d9abd195fee 100644
--- a/app/assets/javascripts/releases/list/components/evidence_block.vue
+++ b/app/assets/javascripts/releases/components/evidence_block.vue
diff --git a/app/assets/javascripts/releases/list/components/release_block.vue b/app/assets/javascripts/releases/components/release_block.vue
index e6bb5325120..e6bb5325120 100644
--- a/app/assets/javascripts/releases/list/components/release_block.vue
+++ b/app/assets/javascripts/releases/components/release_block.vue
diff --git a/app/assets/javascripts/releases/list/components/release_block_assets.vue b/app/assets/javascripts/releases/components/release_block_assets.vue
index 06b7f97a8de..06b7f97a8de 100644
--- a/app/assets/javascripts/releases/list/components/release_block_assets.vue
+++ b/app/assets/javascripts/releases/components/release_block_assets.vue
diff --git a/app/assets/javascripts/releases/list/components/release_block_author.vue b/app/assets/javascripts/releases/components/release_block_author.vue
index e7075d4d67a..e7075d4d67a 100644
--- a/app/assets/javascripts/releases/list/components/release_block_author.vue
+++ b/app/assets/javascripts/releases/components/release_block_author.vue
diff --git a/app/assets/javascripts/releases/list/components/release_block_footer.vue b/app/assets/javascripts/releases/components/release_block_footer.vue
index 8533fc17ffd..8533fc17ffd 100644
--- a/app/assets/javascripts/releases/list/components/release_block_footer.vue
+++ b/app/assets/javascripts/releases/components/release_block_footer.vue
diff --git a/app/assets/javascripts/releases/list/components/release_block_header.vue b/app/assets/javascripts/releases/components/release_block_header.vue
index b459418aef2..b459418aef2 100644
--- a/app/assets/javascripts/releases/list/components/release_block_header.vue
+++ b/app/assets/javascripts/releases/components/release_block_header.vue
diff --git a/app/assets/javascripts/releases/list/components/release_block_metadata.vue b/app/assets/javascripts/releases/components/release_block_metadata.vue
index f0aad594062..f0aad594062 100644
--- a/app/assets/javascripts/releases/list/components/release_block_metadata.vue
+++ b/app/assets/javascripts/releases/components/release_block_metadata.vue
diff --git a/app/assets/javascripts/releases/list/components/release_block_milestone_info.vue b/app/assets/javascripts/releases/components/release_block_milestone_info.vue
index d3e354d6157..d3e354d6157 100644
--- a/app/assets/javascripts/releases/list/components/release_block_milestone_info.vue
+++ b/app/assets/javascripts/releases/components/release_block_milestone_info.vue
diff --git a/app/assets/javascripts/releases/list/components/release_block_milestones.vue b/app/assets/javascripts/releases/components/release_block_milestones.vue
index a3dff75b828..a3dff75b828 100644
--- a/app/assets/javascripts/releases/list/components/release_block_milestones.vue
+++ b/app/assets/javascripts/releases/components/release_block_milestones.vue
diff --git a/app/assets/javascripts/releases/list/constants.js b/app/assets/javascripts/releases/constants.js
index defcd917465..defcd917465 100644
--- a/app/assets/javascripts/releases/list/constants.js
+++ b/app/assets/javascripts/releases/constants.js
diff --git a/app/assets/javascripts/releases/detail/index.js b/app/assets/javascripts/releases/detail/index.js
deleted file mode 100644
index 0dab90a1ede..00000000000
--- a/app/assets/javascripts/releases/detail/index.js
+++ /dev/null
@@ -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');
- },
- });
-};
diff --git a/app/assets/javascripts/releases/detail/store/index.js b/app/assets/javascripts/releases/detail/store/index.js
deleted file mode 100644
index e8623a49356..00000000000
--- a/app/assets/javascripts/releases/detail/store/index.js
+++ /dev/null
@@ -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,
- });
diff --git a/app/assets/javascripts/releases/list/index.js b/app/assets/javascripts/releases/list/index.js
deleted file mode 100644
index adbed3cb8e2..00000000000
--- a/app/assets/javascripts/releases/list/index.js
+++ /dev/null
@@ -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,
- },
- });
- },
- });
-};
diff --git a/app/assets/javascripts/releases/list/store/index.js b/app/assets/javascripts/releases/list/store/index.js
deleted file mode 100644
index 968b94f0e0d..00000000000
--- a/app/assets/javascripts/releases/list/store/index.js
+++ /dev/null
@@ -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(),
- });
diff --git a/app/assets/javascripts/releases/mount_edit.js b/app/assets/javascripts/releases/mount_edit.js
new file mode 100644
index 00000000000..343de8c56d3
--- /dev/null
+++ b/app/assets/javascripts/releases/mount_edit.js
@@ -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),
+ });
+};
diff --git a/app/assets/javascripts/releases/mount_index.js b/app/assets/javascripts/releases/mount_index.js
new file mode 100644
index 00000000000..6fcb6d802e4
--- /dev/null
+++ b/app/assets/javascripts/releases/mount_index.js
@@ -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,
+ },
+ }),
+ });
+};
diff --git a/app/assets/javascripts/releases/stores/index.js b/app/assets/javascripts/releases/stores/index.js
new file mode 100644
index 00000000000..aa607906a0e
--- /dev/null
+++ b/app/assets/javascripts/releases/stores/index.js
@@ -0,0 +1,6 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+
+Vue.use(Vuex);
+
+export default modules => new Vuex.Store({ modules });
diff --git a/app/assets/javascripts/releases/detail/store/actions.js b/app/assets/javascripts/releases/stores/modules/detail/actions.js
index c9749582f5c..c9749582f5c 100644
--- a/app/assets/javascripts/releases/detail/store/actions.js
+++ b/app/assets/javascripts/releases/stores/modules/detail/actions.js
diff --git a/app/assets/javascripts/releases/stores/modules/detail/index.js b/app/assets/javascripts/releases/stores/modules/detail/index.js
new file mode 100644
index 00000000000..243c2389d8c
--- /dev/null
+++ b/app/assets/javascripts/releases/stores/modules/detail/index.js
@@ -0,0 +1,10 @@
+import * as actions from './actions';
+import mutations from './mutations';
+import state from './state';
+
+export default {
+ namespaced: true,
+ actions,
+ mutations,
+ state,
+};
diff --git a/app/assets/javascripts/releases/detail/store/mutation_types.js b/app/assets/javascripts/releases/stores/modules/detail/mutation_types.js
index 75e1d78a645..75e1d78a645 100644
--- a/app/assets/javascripts/releases/detail/store/mutation_types.js
+++ b/app/assets/javascripts/releases/stores/modules/detail/mutation_types.js
diff --git a/app/assets/javascripts/releases/detail/store/mutations.js b/app/assets/javascripts/releases/stores/modules/detail/mutations.js
index d739978d755..d739978d755 100644
--- a/app/assets/javascripts/releases/detail/store/mutations.js
+++ b/app/assets/javascripts/releases/stores/modules/detail/mutations.js
diff --git a/app/assets/javascripts/releases/detail/store/state.js b/app/assets/javascripts/releases/stores/modules/detail/state.js
index 7e3d975f1ae..7e3d975f1ae 100644
--- a/app/assets/javascripts/releases/detail/store/state.js
+++ b/app/assets/javascripts/releases/stores/modules/detail/state.js
diff --git a/app/assets/javascripts/releases/list/store/actions.js b/app/assets/javascripts/releases/stores/modules/list/actions.js
index b15fb69226f..b15fb69226f 100644
--- a/app/assets/javascripts/releases/list/store/actions.js
+++ b/app/assets/javascripts/releases/stores/modules/list/actions.js
diff --git a/app/assets/javascripts/releases/stores/modules/list/index.js b/app/assets/javascripts/releases/stores/modules/list/index.js
new file mode 100644
index 00000000000..e4633b15a0c
--- /dev/null
+++ b/app/assets/javascripts/releases/stores/modules/list/index.js
@@ -0,0 +1,10 @@
+import state from './state';
+import * as actions from './actions';
+import mutations from './mutations';
+
+export default {
+ namespaced: true,
+ actions,
+ mutations,
+ state,
+};
diff --git a/app/assets/javascripts/releases/list/store/mutation_types.js b/app/assets/javascripts/releases/stores/modules/list/mutation_types.js
index a74bf15c515..a74bf15c515 100644
--- a/app/assets/javascripts/releases/list/store/mutation_types.js
+++ b/app/assets/javascripts/releases/stores/modules/list/mutation_types.js
diff --git a/app/assets/javascripts/releases/list/store/mutations.js b/app/assets/javascripts/releases/stores/modules/list/mutations.js
index 99fc096264a..99fc096264a 100644
--- a/app/assets/javascripts/releases/list/store/mutations.js
+++ b/app/assets/javascripts/releases/stores/modules/list/mutations.js
diff --git a/app/assets/javascripts/releases/list/store/state.js b/app/assets/javascripts/releases/stores/modules/list/state.js
index c251f56c9c5..c251f56c9c5 100644
--- a/app/assets/javascripts/releases/list/store/state.js
+++ b/app/assets/javascripts/releases/stores/modules/list/state.js
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 8a583e16c0b..54c9bde067d 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -56,7 +56,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
end
def clear_repository_check_states
- RepositoryCheck::ClearWorker.perform_async
+ RepositoryCheck::ClearWorker.perform_async # rubocop:disable CodeReuse/Worker
redirect_to(
general_admin_application_settings_path,
@@ -73,7 +73,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
# Specs are in spec/requests/self_monitoring_project_spec.rb
def create_self_monitoring_project
- job_id = SelfMonitoringProjectCreateWorker.perform_async
+ job_id = SelfMonitoringProjectCreateWorker.perform_async # rubocop:disable CodeReuse/Worker
render status: :accepted, json: {
job_id: job_id,
@@ -92,7 +92,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
}
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)
return render status: :accepted, json: {
@@ -112,7 +112,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
# Specs are in spec/requests/self_monitoring_project_spec.rb
def delete_self_monitoring_project
- job_id = SelfMonitoringProjectDeleteWorker.perform_async
+ job_id = SelfMonitoringProjectDeleteWorker.perform_async # rubocop:disable CodeReuse/Worker
render status: :accepted, json: {
job_id: job_id,
@@ -131,7 +131,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
}
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)
return render status: :accepted, json: {
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index cdedc34e634..7015da8bd50 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -55,7 +55,7 @@ class Admin::ProjectsController < Admin::ApplicationController
# rubocop: enable CodeReuse/ActiveRecord
def repository_check
- RepositoryCheck::SingleRepositoryWorker.perform_async(@project.id)
+ RepositoryCheck::SingleRepositoryWorker.perform_async(@project.id) # rubocop:disable CodeReuse/Worker
redirect_to(
admin_project_path(@project),
diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb
index e31e0e09978..50b79cde5c5 100644
--- a/app/controllers/admin/services_controller.rb
+++ b/app/controllers/admin/services_controller.rb
@@ -19,7 +19,7 @@ class Admin::ServicesController < Admin::ApplicationController
def update
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,
notice: 'Application settings saved successfully'
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 0944d7b47bf..35f803302eb 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -188,7 +188,7 @@ class Projects::IssuesController < Projects::ApplicationController
def import_csv
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.")
else
diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb
index 6a7e2b69652..ead839e8441 100644
--- a/app/controllers/projects/pipeline_schedules_controller.rb
+++ b/app/controllers/projects/pipeline_schedules_controller.rb
@@ -47,7 +47,7 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
end
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
pipelines_link_start = "<a href=\"#{project_pipelines_path(@project)}\">"
diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb
index b31a74540e2..e524d1c29a2 100644
--- a/app/controllers/projects/registry/repositories_controller.rb
+++ b/app/controllers/projects/registry/repositories_controller.rb
@@ -32,7 +32,7 @@ module Projects
end
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)
respond_to do |format|
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index 6af815b8daa..bf0c2d885f8 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -69,7 +69,9 @@ module Projects
return
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)
+ # rubocop:enable CodeReuse/Worker
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 }
diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb
index 0c634bbea03..63f5d5073a7 100644
--- a/app/controllers/projects/settings/repository_controller.rb
+++ b/app/controllers/projects/settings/repository_controller.rb
@@ -25,7 +25,7 @@ module Projects
result = Projects::UpdateService.new(project, current_user, cleanup_params).execute
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.')
else
flash[:alert] = _('Failed to upload object map file')
diff --git a/app/controllers/repositories/git_http_controller.rb b/app/controllers/repositories/git_http_controller.rb
index 82431ae286a..75c79881264 100644
--- a/app/controllers/repositories/git_http_controller.rb
+++ b/app/controllers/repositories/git_http_controller.rb
@@ -80,7 +80,7 @@ module Repositories
return unless repo_type.project?
return unless project&.daily_statistics_enabled?
- ProjectDailyStatisticsWorker.perform_async(project.id)
+ ProjectDailyStatisticsWorker.perform_async(project.id) # rubocop:disable CodeReuse/Worker
end
def access
diff --git a/app/helpers/analytics_navbar_helper.rb b/app/helpers/analytics_navbar_helper.rb
index bbb7470d1fd..021b9bb10cd 100644
--- a/app/helpers/analytics_navbar_helper.rb
+++ b/app/helpers/analytics_navbar_helper.rb
@@ -31,7 +31,7 @@ module AnalyticsNavbarHelper
end
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)
navbar_sub_item(
@@ -43,7 +43,7 @@ module AnalyticsNavbarHelper
end
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?
navbar_sub_item(
@@ -55,7 +55,7 @@ module AnalyticsNavbarHelper
end
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.feature_available?(:builds, current_user) || !project.empty_repo?
diff --git a/app/services/ci/process_build_service.rb b/app/services/ci/process_build_service.rb
index eb92c7d1a27..12cdca24066 100644
--- a/app/services/ci/process_build_service.rb
+++ b/app/services/ci/process_build_service.rb
@@ -3,7 +3,7 @@
module Ci
class ProcessBuildService < BaseService
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?
build.schedule
elsif build.action?
@@ -25,10 +25,10 @@ module Ci
build.enqueue
end
- def valid_statuses_for_when(value)
- case value
+ def valid_statuses_for_build(build)
+ case build.when
when 'on_success'
- %w[success skipped]
+ build.scheduling_type_dag? ? %w[success] : %w[success skipped]
when 'on_failure'
%w[failed]
when 'always'
diff --git a/app/views/layouts/nav/sidebar/_analytics_links.html.haml b/app/views/layouts/nav/sidebar/_analytics_links.html.haml
index b859a1ade66..e87cf92374a 100644
--- a/app/views/layouts/nav/sidebar/_analytics_links.html.haml
+++ b/app/views/layouts/nav/sidebar/_analytics_links.html.haml
@@ -6,10 +6,10 @@
= link_to navbar_links.first.link do
.nav-icon-container
= sprite_icon('chart')
- %span.nav-item-name
+ %span.nav-item-name{ data: { qa_selector: 'analytics_link' } }
= _('Analytics')
- %ul.sidebar-sub-level-items
+ %ul.sidebar-sub-level-items{ data: { qa_selector: 'analytics_sidebar_submenu' } }
- navbar_links.each do |menu_item|
= nav_link(path: menu_item.path) do
= link_to(menu_item.link, menu_item.link_to_options) do
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index 60c5ef3877f..c00c48b623c 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -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')
- merge_requests_count = group_merge_requests_count(state: 'opened')
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index c587d0ca053..b9324f0596c 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -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-inner-scroll
@@ -9,7 +9,7 @@
= project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile', width: 40, height: 40)
.sidebar-context-title
= @project.name
- %ul.sidebar-top-level-items
+ %ul.sidebar-top-level-items.qa-project-sidebar
- paths = sidebar_projects_paths
- paths << 'cycle_analytics#show' unless should_display_analytics_pages_in_sidebar
= nav_link(path: paths, html_options: { class: 'home' }) do
diff --git a/changelogs/unreleased/31526-skip-if-needed-job-skipped.yml b/changelogs/unreleased/31526-skip-if-needed-job-skipped.yml
new file mode 100644
index 00000000000..27b2e5f9b8e
--- /dev/null
+++ b/changelogs/unreleased/31526-skip-if-needed-job-skipped.yml
@@ -0,0 +1,5 @@
+---
+title: Prevent DAG builds to run after skipped need build
+merge_request: 23405
+author:
+type: fixed
diff --git a/changelogs/unreleased/55487-backfill-lfs-objects-projects-sql.yml b/changelogs/unreleased/55487-backfill-lfs-objects-projects-sql.yml
new file mode 100644
index 00000000000..45dd3c6e9f5
--- /dev/null
+++ b/changelogs/unreleased/55487-backfill-lfs-objects-projects-sql.yml
@@ -0,0 +1,5 @@
+---
+title: Backfill LfsObjectsProject records of forks
+merge_request: 24767
+author:
+type: other
diff --git a/changelogs/unreleased/georgekoltsov-object_builder_convert_empty_strings.yml b/changelogs/unreleased/georgekoltsov-object_builder_convert_empty_strings.yml
new file mode 100644
index 00000000000..31eca8a2653
--- /dev/null
+++ b/changelogs/unreleased/georgekoltsov-object_builder_convert_empty_strings.yml
@@ -0,0 +1,6 @@
+---
+title: Fix Group Import existing objects lookup when description attribute is an empty
+ string
+merge_request: 25187
+author:
+type: fixed
diff --git a/changelogs/unreleased/jcunha-update-managed-apps-template.yml b/changelogs/unreleased/jcunha-update-managed-apps-template.yml
new file mode 100644
index 00000000000..145a15c6ae0
--- /dev/null
+++ b/changelogs/unreleased/jcunha-update-managed-apps-template.yml
@@ -0,0 +1,5 @@
+---
+title: Update cluster-applications to v0.8.0
+merge_request: 25138
+author:
+type: changed
diff --git a/changelogs/unreleased/toggle-analytics-navbar-feature-flags.yml b/changelogs/unreleased/toggle-analytics-navbar-feature-flags.yml
new file mode 100644
index 00000000000..506e4fffdbb
--- /dev/null
+++ b/changelogs/unreleased/toggle-analytics-navbar-feature-flags.yml
@@ -0,0 +1,5 @@
+---
+title: Move analytics pages under the sidebar for projects and groups
+merge_request: 24470
+author:
+type: changed
diff --git a/db/post_migrate/20200210062432_schedule_link_lfs_objects.rb b/db/post_migrate/20200210062432_schedule_link_lfs_objects.rb
new file mode 100644
index 00000000000..c955639c259
--- /dev/null
+++ b/db/post_migrate/20200210062432_schedule_link_lfs_objects.rb
@@ -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
diff --git a/doc/user/group/contribution_analytics/index.md b/doc/user/group/contribution_analytics/index.md
index 4411c7834a4..1bbc40a14a4 100644
--- a/doc/user/group/contribution_analytics/index.md
+++ b/doc/user/group/contribution_analytics/index.md
@@ -16,7 +16,7 @@ group:
- Merge requests
- 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.
## Use cases
diff --git a/doc/user/group/insights/img/insights_sidebar_link.png b/doc/user/group/insights/img/insights_sidebar_link.png
deleted file mode 100644
index f7b0c2daae3..00000000000
--- a/doc/user/group/insights/img/insights_sidebar_link.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/insights/img/insights_sidebar_link_v12_8.png b/doc/user/group/insights/img/insights_sidebar_link_v12_8.png
new file mode 100644
index 00000000000..9a6d6bae766
--- /dev/null
+++ b/doc/user/group/insights/img/insights_sidebar_link_v12_8.png
Binary files differ
diff --git a/doc/user/group/insights/index.md b/doc/user/group/insights/index.md
index 7e933c66789..edbb85962ed 100644
--- a/doc/user/group/insights/index.md
+++ b/doc/user/group/insights/index.md
@@ -14,10 +14,10 @@ requests to be merged and much more.
## 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:
-![Insights sidebar link](img/insights_sidebar_link.png)
+![Insights sidebar link](img/insights_sidebar_link_v12_8.png)
## Configure your Insights
diff --git a/doc/user/group/issues_analytics/img/issues_created_per_month.png b/doc/user/group/issues_analytics/img/issues_created_per_month.png
deleted file mode 100644
index 96f0d36c917..00000000000
--- a/doc/user/group/issues_analytics/img/issues_created_per_month.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/issues_analytics/img/issues_created_per_month_v12_8.png b/doc/user/group/issues_analytics/img/issues_created_per_month_v12_8.png
new file mode 100644
index 00000000000..b7dc2d3da8d
--- /dev/null
+++ b/doc/user/group/issues_analytics/img/issues_created_per_month_v12_8.png
Binary files differ
diff --git a/doc/user/group/issues_analytics/index.md b/doc/user/group/issues_analytics/index.md
index f84a3a3c286..6c710885b98 100644
--- a/doc/user/group/issues_analytics/index.md
+++ b/doc/user/group/issues_analytics/index.md
@@ -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
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.
@@ -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`
shows a total of 15 months for the chart in the GitLab.org group.
-![Issues created per month](img/issues_created_per_month.png)
+![Issues created per month](img/issues_created_per_month_v12_8.png)
<!-- ## Troubleshooting
diff --git a/doc/user/project/insights/img/insights_sidebar_link.png b/doc/user/project/insights/img/insights_sidebar_link.png
deleted file mode 100644
index 9fc449baf68..00000000000
--- a/doc/user/project/insights/img/insights_sidebar_link.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/insights/img/insights_sidebar_link_v12_8.png b/doc/user/project/insights/img/insights_sidebar_link_v12_8.png
new file mode 100644
index 00000000000..b07ecc5286a
--- /dev/null
+++ b/doc/user/project/insights/img/insights_sidebar_link_v12_8.png
Binary files differ
diff --git a/doc/user/project/insights/index.md b/doc/user/project/insights/index.md
index 3fb661f9349..4af6f47ce7b 100644
--- a/doc/user/project/insights/index.md
+++ b/doc/user/project/insights/index.md
@@ -13,10 +13,10 @@ This feature is [also available at the group level](../../group/insights/index.m
## 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:
-![Insights sidebar link](img/insights_sidebar_link.png)
+![Insights sidebar link](img/insights_sidebar_link_v12_8.png)
## Configure your Insights
diff --git a/doc/user/project/integrations/img/prometheus_dashboard_area_panel_type.png b/doc/user/project/integrations/img/prometheus_dashboard_area_panel_type.png
deleted file mode 100644
index 9fdb6dfddac..00000000000
--- a/doc/user/project/integrations/img/prometheus_dashboard_area_panel_type.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/integrations/img/prometheus_dashboard_area_panel_type_v12_8.png b/doc/user/project/integrations/img/prometheus_dashboard_area_panel_type_v12_8.png
new file mode 100644
index 00000000000..8c5663fef12
--- /dev/null
+++ b/doc/user/project/integrations/img/prometheus_dashboard_area_panel_type_v12_8.png
Binary files differ
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index cf98c002331..210ce4ffe56 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -285,7 +285,9 @@ Note the following properties:
| 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) |
-![area panel type](img/prometheus_dashboard_area_panel_type.png)
+![area panel chart](img/prometheus_dashboard_area_panel_type_v12_8.png)
+
+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
@@ -329,7 +331,7 @@ Note the following properties:
![anomaly panel type](img/prometheus_dashboard_anomaly_panel_type.png)
-#### Column
+##### Column chart
To add a column panel type to a dashboard, look at the following sample dashboard file:
diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md
index 54e7938d8f7..e7cb5e59be8 100644
--- a/doc/user/shortcuts.md
+++ b/doc/user/shortcuts.md
@@ -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>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>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>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**). |
diff --git a/lib/api/group_export.rb b/lib/api/group_export.rb
index 4d32212b8eb..6fe72458da2 100644
--- a/lib/api/group_export.rb
+++ b/lib/api/group_export.rb
@@ -27,7 +27,7 @@ module API
detail 'This feature was introduced in GitLab 12.5.'
end
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!
end
diff --git a/lib/api/group_import.rb b/lib/api/group_import.rb
index 3531abb2604..ed52506de14 100644
--- a/lib/api/group_import.rb
+++ b/lib/api/group_import.rb
@@ -76,7 +76,7 @@ module API
group = ::Groups::CreateService.new(current_user, group_params).execute
if group.persisted?
- GroupImportWorker.perform_async(current_user.id, group.id)
+ GroupImportWorker.perform_async(current_user.id, group.id) # rubocop:disable CodeReuse/Worker
accepted!
else
diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb
index 61c40c54d69..445a37a70c0 100644
--- a/lib/api/pipeline_schedules.rb
+++ b/lib/api/pipeline_schedules.rb
@@ -120,7 +120,7 @@ module API
post ':id/pipeline_schedules/:pipeline_schedule_id/play' do
authorize! :play_pipeline_schedule, pipeline_schedule
- job_id = RunPipelineScheduleWorker
+ job_id = RunPipelineScheduleWorker # rubocop:disable CodeReuse/Worker
.perform_async(pipeline_schedule.id, current_user.id)
if job_id
diff --git a/lib/api/project_container_repositories.rb b/lib/api/project_container_repositories.rb
index e2963c0de22..70c913bea98 100644
--- a/lib/api/project_container_repositories.rb
+++ b/lib/api/project_container_repositories.rb
@@ -41,7 +41,7 @@ module API
delete ':id/registry/repositories/:repository_id', requirements: REPOSITORY_ENDPOINT_REQUIREMENTS do
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')
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'
render_api_error!(message, 400) unless obtain_new_cleanup_container_lease
+ # rubocop:disable CodeReuse/Worker
CleanupContainerRepositoryWorker.perform_async(current_user.id, repository.id,
declared_params.except(:repository_id).merge(container_expiration_policy: false))
+ # rubocop:enable CodeReuse/Worker
track_event('delete_tag_bulk')
diff --git a/lib/api/releases.rb b/lib/api/releases.rb
index b1f23d9837f..6e7a99bf0bb 100644
--- a/lib/api/releases.rb
+++ b/lib/api/releases.rb
@@ -170,9 +170,9 @@ module API
return if release.historical_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
- CreateEvidenceWorker.perform_async(release.id)
+ CreateEvidenceWorker.perform_async(release.id) # rubocop:disable CodeReuse/Worker
end
end
end
diff --git a/lib/gitlab/background_migration/link_lfs_objects.rb b/lib/gitlab/background_migration/link_lfs_objects.rb
new file mode 100644
index 00000000000..014bebc4258
--- /dev/null
+++ b/lib/gitlab/background_migration/link_lfs_objects.rb
@@ -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
diff --git a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
index a133c5e0485..73ae63c3092 100644
--- a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
@@ -1,6 +1,6 @@
apply:
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:
name: production
variables:
@@ -12,6 +12,8 @@ apply:
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
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:
- gitlab-managed-apps /usr/local/share/gitlab-managed-apps/helmfile.yaml
only:
diff --git a/lib/gitlab/import_export/group_object_builder.rb b/lib/gitlab/import_export/group_object_builder.rb
index fa426e32b60..9796bfa07d4 100644
--- a/lib/gitlab/import_export/group_object_builder.rb
+++ b/lib/gitlab/import_export/group_object_builder.rb
@@ -18,12 +18,21 @@ module Gitlab
super
@group = @attributes['group']
+
+ update_description
end
private
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
[
where_clause_base,
diff --git a/qa/qa.rb b/qa/qa.rb
index 53a43e8da64..fb0c06e33aa 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -159,6 +159,10 @@ module QA
autoload :Validator, 'qa/page/validator'
autoload :Validatable, 'qa/page/validatable'
+ module SubMenus
+ autoload :Common, 'qa/page/sub_menus/common'
+ end
+
module Main
autoload :Login, 'qa/page/main/login'
autoload :Menu, 'qa/page/main/menu'
diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb
index 2b3b872aff4..230511ce6f6 100644
--- a/qa/qa/page/group/menu.rb
+++ b/qa/qa/page/group/menu.rb
@@ -13,15 +13,22 @@ module QA
element :contribution_analytics_link
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
within_sidebar do
click_element(:group_members_item)
end
end
- def click_group_analytics_item
- within_sidebar do
- click_element(:contribution_analytics_link)
+ def click_contribution_analytics_item
+ hover_element(:analytics_link) do
+ within_submenu(:analytics_sidebar_submenu) do
+ click_element(:contribution_analytics_link)
+ end
end
end
diff --git a/qa/qa/page/group/sub_menus/common.rb b/qa/qa/page/group/sub_menus/common.rb
index a378db80e4b..96efc8da98d 100644
--- a/qa/qa/page/group/sub_menus/common.rb
+++ b/qa/qa/page/group/sub_menus/common.rb
@@ -5,6 +5,8 @@ module QA
module Group
module SubMenus
module Common
+ include QA::Page::SubMenus::Common
+
def self.included(base)
base.class_eval do
view 'app/views/layouts/nav/sidebar/_group.html.haml' do
@@ -13,23 +15,10 @@ module QA
end
end
- def hover_element(element)
- within_sidebar do
- find_element(element).hover
- yield
- end
- end
+ private
- def within_sidebar
- within_element(:group_sidebar) do
- yield
- end
- end
-
- def within_submenu(element)
- within_element(element) do
- yield
- end
+ def sidebar_element
+ :group_sidebar
end
end
end
diff --git a/qa/qa/page/project/sub_menus/common.rb b/qa/qa/page/project/sub_menus/common.rb
index 3c9e8085748..da759398cff 100644
--- a/qa/qa/page/project/sub_menus/common.rb
+++ b/qa/qa/page/project/sub_menus/common.rb
@@ -5,20 +5,12 @@ module QA
module Project
module SubMenus
module Common
- def within_sidebar
- within('.sidebar-top-level-items') do
- yield
- end
- end
+ include QA::Page::SubMenus::Common
+
+ private
- def within_submenu
- if has_css?('.fly-out-list')
- within('.fly-out-list') do
- yield
- end
- else
- yield
- end
+ def sidebar_element
+ :project_sidebar
end
end
end
diff --git a/qa/qa/page/sub_menus/common.rb b/qa/qa/page/sub_menus/common.rb
new file mode 100644
index 00000000000..0eb1b100bd7
--- /dev/null
+++ b/qa/qa/page/sub_menus/common.rb
@@ -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
diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb
index 9305153dc7d..1c314976b4e 100644
--- a/rubocop/rubocop.rb
+++ b/rubocop/rubocop.rb
@@ -55,6 +55,7 @@ require_relative 'cop/code_reuse/service_class'
require_relative 'cop/code_reuse/presenter'
require_relative 'cop/code_reuse/serializer'
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/inject_enterprise_edition_module'
require_relative 'cop/graphql/authorize_types'
diff --git a/spec/features/security/group/internal_access_spec.rb b/spec/features/security/group/internal_access_spec.rb
index 8dd15789cd1..114bc1a1f0c 100644
--- a/spec/features/security/group/internal_access_spec.rb
+++ b/spec/features/security/group/internal_access_spec.rb
@@ -36,7 +36,7 @@ describe 'Internal Group access' do
it { is_expected.to be_denied_for(:visitor) }
end
- describe 'GET /groups/:path/issues' do
+ describe 'GET /groups/:path/-/issues' do
subject { issues_group_path(group) }
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) }
end
- describe 'GET /groups/:path/merge_requests' do
+ describe 'GET /groups/:path/-/merge_requests' do
let(:project) { create(:project, :internal, :repository, group: group) }
subject { merge_requests_group_path(group) }
@@ -68,7 +68,7 @@ describe 'Internal Group access' do
it { is_expected.to be_denied_for(:visitor) }
end
- describe 'GET /groups/:path/group_members' do
+ describe 'GET /groups/:path/-/group_members' do
subject { group_group_members_path(group) }
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) }
end
- describe 'GET /groups/:path/edit' do
+ describe 'GET /groups/:path/-/edit' do
subject { edit_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
diff --git a/spec/features/security/group/private_access_spec.rb b/spec/features/security/group/private_access_spec.rb
index 0720302b03b..3362b9a9e9e 100644
--- a/spec/features/security/group/private_access_spec.rb
+++ b/spec/features/security/group/private_access_spec.rb
@@ -36,7 +36,7 @@ describe 'Private Group access' do
it { is_expected.to be_denied_for(:visitor) }
end
- describe 'GET /groups/:path/issues' do
+ describe 'GET /groups/:path/-/issues' do
subject { issues_group_path(group) }
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) }
end
- describe 'GET /groups/:path/merge_requests' do
+ describe 'GET /groups/:path/-/merge_requests' do
let(:project) { create(:project, :private, :repository, group: group) }
subject { merge_requests_group_path(group) }
@@ -68,7 +68,7 @@ describe 'Private Group access' do
it { is_expected.to be_denied_for(:visitor) }
end
- describe 'GET /groups/:path/group_members' do
+ describe 'GET /groups/:path/-/group_members' do
subject { group_group_members_path(group) }
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) }
end
- describe 'GET /groups/:path/edit' do
+ describe 'GET /groups/:path/-/edit' do
subject { edit_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
diff --git a/spec/features/security/group/public_access_spec.rb b/spec/features/security/group/public_access_spec.rb
index 0a18a0ff812..bf05f276cc6 100644
--- a/spec/features/security/group/public_access_spec.rb
+++ b/spec/features/security/group/public_access_spec.rb
@@ -36,7 +36,7 @@ describe 'Public Group access' do
it { is_expected.to be_allowed_for(:visitor) }
end
- describe 'GET /groups/:path/issues' do
+ describe 'GET /groups/:path/-/issues' do
subject { issues_group_path(group) }
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) }
end
- describe 'GET /groups/:path/merge_requests' do
+ describe 'GET /groups/:path/-/merge_requests' do
let(:project) { create(:project, :public, :repository, group: group) }
subject { merge_requests_group_path(group) }
@@ -68,7 +68,7 @@ describe 'Public Group access' do
it { is_expected.to be_allowed_for(:visitor) }
end
- describe 'GET /groups/:path/group_members' do
+ describe 'GET /groups/:path/-/group_members' do
subject { group_group_members_path(group) }
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) }
end
- describe 'GET /groups/:path/edit' do
+ describe 'GET /groups/:path/-/edit' do
subject { edit_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index 5c74b566ef0..ed1dbe15d65 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -29,7 +29,7 @@ describe "Internal Project Access" do
it { is_expected.to be_denied_for(:visitor) }
end
- describe "GET /:project_path/tree/master" do
+ describe "GET /:project_path/-/tree/master" do
subject { project_tree_path(project, project.repository.root_ref) }
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) }
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) }
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) }
end
- describe "GET /:project_path/commit/:sha" do
+ describe "GET /:project_path/-/commit/:sha" do
subject { project_commit_path(project, project.repository.commit) }
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) }
end
- describe "GET /:project_path/compare" do
+ describe "GET /:project_path/-/compare" do
subject { project_compare_index_path(project) }
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) }
end
- describe "GET /:project_path/blob" do
+ describe "GET /:project_path/-/blob" do
let(:commit) { project.repository.commit }
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) }
end
- describe "GET /:project_path/merge_requests" do
+ describe "GET /:project_path/-/merge_requests" do
subject { project_merge_requests_path(project) }
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) }
end
- describe "GET /:project_path/merge_requests/new" do
+ describe "GET /:project_path/-/merge_requests/new" do
subject { project_new_merge_request_path(project) }
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) }
end
- describe "GET /:project_path/branches" do
+ describe "GET /:project_path/-/branches" do
subject { project_branches_path(project) }
before do
@@ -278,7 +278,7 @@ describe "Internal Project Access" do
it { is_expected.to be_denied_for(:visitor) }
end
- describe "GET /:project_path/tags" do
+ describe "GET /:project_path/-/tags" do
subject { project_tags_path(project) }
before do
diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb
index 2404b7cc69d..97e6b3bd4ff 100644
--- a/spec/features/security/project/private_access_spec.rb
+++ b/spec/features/security/project/private_access_spec.rb
@@ -29,7 +29,7 @@ describe "Private Project Access" do
it { is_expected.to be_denied_for(:visitor) }
end
- describe "GET /:project_path/tree/master" do
+ describe "GET /:project_path/-/tree/master" do
subject { project_tree_path(project, project.repository.root_ref) }
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) }
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) }
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) }
end
- describe "GET /:project_path/commit/:sha" do
+ describe "GET /:project_path/-/commit/:sha" do
subject { project_commit_path(project, project.repository.commit) }
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) }
end
- describe "GET /:project_path/compare" do
+ describe "GET /:project_path/-/compare" do
subject { project_compare_index_path(project) }
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) }
end
- describe "GET /:project_path/blob" do
+ describe "GET /:project_path/-/blob" do
let(:commit) { project.repository.commit }
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) }
end
- describe "GET /:project_path/merge_requests" do
+ describe "GET /:project_path/-/merge_requests" do
subject { project_merge_requests_path(project) }
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) }
end
- describe "GET /:project_path/branches" do
+ describe "GET /:project_path/-/branches" do
subject { project_branches_path(project) }
before do
@@ -250,7 +250,7 @@ describe "Private Project Access" do
it { is_expected.to be_denied_for(:visitor) }
end
- describe "GET /:project_path/tags" do
+ describe "GET /:project_path/-/tags" do
subject { project_tags_path(project) }
before do
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index 8e07af61c8b..24bbb8d9b9e 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -29,7 +29,7 @@ describe "Public Project Access" do
it { is_expected.to be_allowed_for(:visitor) }
end
- describe "GET /:project_path/tree/master" do
+ describe "GET /:project_path/-/tree/master" do
subject { project_tree_path(project, project.repository.root_ref) }
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) }
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) }
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) }
end
- describe "GET /:project_path/commit/:sha" do
+ describe "GET /:project_path/-/commit/:sha" do
subject { project_commit_path(project, project.repository.commit) }
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) }
end
- describe "GET /:project_path/compare" do
+ describe "GET /:project_path/-/compare" do
subject { project_compare_index_path(project) }
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) }
end
- describe "GET /:project_path/blob" do
+ describe "GET /:project_path/-/blob" do
let(:commit) { project.repository.commit }
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) }
end
- describe "GET /:project_path/merge_requests" do
+ describe "GET /:project_path/-/merge_requests" do
subject { project_merge_requests_path(project) }
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) }
end
- describe "GET /:project_path/merge_requests/new" do
+ describe "GET /:project_path/-/merge_requests/new" do
subject { project_new_merge_request_path(project) }
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) }
end
- describe "GET /:project_path/branches" do
+ describe "GET /:project_path/-/branches" do
subject { project_branches_path(project) }
before do
@@ -495,7 +495,7 @@ describe "Public Project Access" do
it { is_expected.to be_allowed_for(:visitor) }
end
- describe "GET /:project_path/tags" do
+ describe "GET /:project_path/-/tags" do
subject { project_tags_path(project) }
before do
diff --git a/spec/frontend/monitoring/store/mutations_spec.js b/spec/frontend/monitoring/store/mutations_spec.js
index b0ac42e0e5f..d9aebafb9ec 100644
--- a/spec/frontend/monitoring/store/mutations_spec.js
+++ b/spec/frontend/monitoring/store/mutations_spec.js
@@ -91,16 +91,37 @@ describe('Monitoring mutations', () => {
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;
mutations[types.SET_ENDPOINTS](stateCopy, {
+ logsPath: defaultLogsPath,
+ });
+ mutations[types.SET_ENDPOINTS](stateCopy, {
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', () => {
const metricId = '12_system_metrics_kubernetes_container_memory_total';
const result = [
diff --git a/spec/frontend/releases/detail/components/app_spec.js b/spec/frontend/releases/components/app_edit_spec.js
index 894cd3a8f14..cb940facbd6 100644
--- a/spec/frontend/releases/detail/components/app_spec.js
+++ b/spec/frontend/releases/components/app_edit_spec.js
@@ -1,10 +1,10 @@
import Vuex from 'vuex';
import { mount } from '@vue/test-utils';
-import ReleaseDetailApp from '~/releases/detail/components/app.vue';
-import { release } from '../../mock_data';
+import ReleaseEditApp from '~/releases/components/app_edit.vue';
+import { release } from '../mock_data';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-describe('Release detail component', () => {
+describe('Release edit component', () => {
let wrapper;
let releaseClone;
let actions;
@@ -27,9 +27,17 @@ describe('Release detail component', () => {
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,
});
diff --git a/spec/frontend/releases/list/components/evidence_block_spec.js b/spec/frontend/releases/components/evidence_block_spec.js
index 39f3975f665..7b896575965 100644
--- a/spec/frontend/releases/list/components/evidence_block_spec.js
+++ b/spec/frontend/releases/components/evidence_block_spec.js
@@ -2,8 +2,8 @@ import { mount } from '@vue/test-utils';
import { GlLink } from '@gitlab/ui';
import { truncateSha } from '~/lib/utils/text_utility';
import Icon from '~/vue_shared/components/icon.vue';
-import { release } from '../../mock_data';
-import EvidenceBlock from '~/releases/list/components/evidence_block.vue';
+import { release } from '../mock_data';
+import EvidenceBlock from '~/releases/components/evidence_block.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
describe('Evidence Block', () => {
diff --git a/spec/frontend/releases/list/components/release_block_footer_spec.js b/spec/frontend/releases/components/release_block_footer_spec.js
index 07f61303e33..4125d5c7e74 100644
--- a/spec/frontend/releases/list/components/release_block_footer_spec.js
+++ b/spec/frontend/releases/components/release_block_footer_spec.js
@@ -1,9 +1,9 @@
import { mount } from '@vue/test-utils';
import { GlLink } from '@gitlab/ui';
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 { release } from '../../mock_data';
+import { release } from '../mock_data';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
jest.mock('~/vue_shared/mixins/timeago', () => ({
diff --git a/spec/frontend/releases/list/components/release_block_header_spec.js b/spec/frontend/releases/components/release_block_header_spec.js
index 1f2331635d6..157df15ff3c 100644
--- a/spec/frontend/releases/list/components/release_block_header_spec.js
+++ b/spec/frontend/releases/components/release_block_header_spec.js
@@ -1,9 +1,9 @@
import { shallowMount } from '@vue/test-utils';
import { cloneDeep, merge } from 'lodash';
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 { release as originalRelease } from '../../mock_data';
+import { release as originalRelease } from '../mock_data';
describe('Release block header', () => {
let wrapper;
diff --git a/spec/frontend/releases/list/components/release_block_milestone_info_spec.js b/spec/frontend/releases/components/release_block_milestone_info_spec.js
index 8a63dbbdca7..5a3204a4ce2 100644
--- a/spec/frontend/releases/list/components/release_block_milestone_info_spec.js
+++ b/spec/frontend/releases/components/release_block_milestone_info_spec.js
@@ -1,9 +1,9 @@
import { mount } from '@vue/test-utils';
import { GlProgressBar, GlLink, GlBadge, GlButton } from '@gitlab/ui';
import { trimText } from 'helpers/text_helper';
-import ReleaseBlockMilestoneInfo from '~/releases/list/components/release_block_milestone_info.vue';
-import { milestones } from '../../mock_data';
-import { MAX_MILESTONES_TO_DISPLAY } from '~/releases/list/constants';
+import ReleaseBlockMilestoneInfo from '~/releases/components/release_block_milestone_info.vue';
+import { milestones } from '../mock_data';
+import { MAX_MILESTONES_TO_DISPLAY } from '~/releases/constants';
describe('Release block milestone info', () => {
let wrapper;
diff --git a/spec/frontend/releases/list/components/release_block_spec.js b/spec/frontend/releases/components/release_block_spec.js
index 0e8d569f326..aba1b8aff41 100644
--- a/spec/frontend/releases/list/components/release_block_spec.js
+++ b/spec/frontend/releases/components/release_block_spec.js
@@ -1,11 +1,11 @@
import $ from 'jquery';
import { mount } from '@vue/test-utils';
import { first } from 'underscore';
-import EvidenceBlock from '~/releases/list/components/evidence_block.vue';
-import ReleaseBlock from '~/releases/list/components/release_block.vue';
-import ReleaseBlockFooter from '~/releases/list/components/release_block_footer.vue';
+import EvidenceBlock from '~/releases/components/evidence_block.vue';
+import ReleaseBlock from '~/releases/components/release_block.vue';
+import ReleaseBlockFooter from '~/releases/components/release_block_footer.vue';
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 { scrollToElement } from '~/lib/utils/common_utils';
diff --git a/spec/frontend/releases/detail/store/actions_spec.js b/spec/frontend/releases/stores/modules/detail/actions_spec.js
index 5a1447aa4fc..0c2763822c9 100644
--- a/spec/frontend/releases/detail/store/actions_spec.js
+++ b/spec/frontend/releases/stores/modules/detail/actions_spec.js
@@ -1,10 +1,10 @@
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper';
-import * as actions from '~/releases/detail/store/actions';
-import * as types from '~/releases/detail/store/mutation_types';
-import { release } from '../../mock_data';
-import state from '~/releases/detail/store/state';
+import * as actions from '~/releases/stores/modules/detail/actions';
+import * as types from '~/releases/stores/modules/detail/mutation_types';
+import { release } from '../../../mock_data';
+import state from '~/releases/stores/modules/detail/state';
import createFlash from '~/flash';
import { redirectTo } from '~/lib/utils/url_utility';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
diff --git a/spec/frontend/releases/detail/store/mutations_spec.js b/spec/frontend/releases/stores/modules/detail/mutations_spec.js
index 106a40c812e..81b2dde75ab 100644
--- a/spec/frontend/releases/detail/store/mutations_spec.js
+++ b/spec/frontend/releases/stores/modules/detail/mutations_spec.js
@@ -5,10 +5,10 @@
* is resolved
*/
-import state from '~/releases/detail/store/state';
-import mutations from '~/releases/detail/store/mutations';
-import * as types from '~/releases/detail/store/mutation_types';
-import { release } from '../../mock_data';
+import state from '~/releases/stores/modules/detail/state';
+import mutations from '~/releases/stores/modules/detail/mutations';
+import * as types from '~/releases/stores/modules/detail/mutation_types';
+import { release } from '../../../mock_data';
describe('Release detail mutations', () => {
let stateClone;
diff --git a/spec/javascripts/releases/list/components/app_spec.js b/spec/javascripts/releases/components/app_index_spec.js
index de6208ab1fd..bcf062f357a 100644
--- a/spec/javascripts/releases/list/components/app_spec.js
+++ b/spec/javascripts/releases/components/app_index_spec.js
@@ -1,16 +1,17 @@
import _ from 'underscore';
import Vue from 'vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import app from '~/releases/list/components/app.vue';
-import createStore from '~/releases/list/store';
+import app from '~/releases/components/app_index.vue';
+import createStore from '~/releases/stores';
+import listModule from '~/releases/stores/modules/list';
import api from '~/api';
-import { resetStore } from '../store/helpers';
+import { resetStore } from '../stores/modules/list/helpers';
import {
pageInfoHeadersWithoutPagination,
pageInfoHeadersWithPagination,
release,
releases,
-} from '../../mock_data';
+} from '../mock_data';
describe('Releases App ', () => {
const Component = Vue.extend(app);
@@ -25,7 +26,7 @@ describe('Releases App ', () => {
};
beforeEach(() => {
- store = createStore();
+ store = createStore({ list: listModule });
releasesPagination = _.range(21).map(index => ({ ...release, tag_name: `${index}.00` }));
});
diff --git a/spec/javascripts/releases/list/store/actions_spec.js b/spec/javascripts/releases/stores/modules/list/actions_spec.js
index f03e019b95c..037c9d8d54a 100644
--- a/spec/javascripts/releases/list/store/actions_spec.js
+++ b/spec/javascripts/releases/stores/modules/list/actions_spec.js
@@ -4,12 +4,12 @@ import {
fetchReleases,
receiveReleasesSuccess,
receiveReleasesError,
-} from '~/releases/list/store/actions';
-import state from '~/releases/list/store/state';
-import * as types from '~/releases/list/store/mutation_types';
+} from '~/releases/stores/modules/list/actions';
+import state from '~/releases/stores/modules/list/state';
+import * as types from '~/releases/stores/modules/list/mutation_types';
import api from '~/api';
import { parseIntPagination } from '~/lib/utils/common_utils';
-import { pageInfoHeadersWithoutPagination, releases } from '../../mock_data';
+import { pageInfoHeadersWithoutPagination, releases } from '../../../mock_data';
describe('Releases State actions', () => {
let mockedState;
diff --git a/spec/javascripts/releases/list/store/helpers.js b/spec/javascripts/releases/stores/modules/list/helpers.js
index fbc89ec2148..435ca36047e 100644
--- a/spec/javascripts/releases/list/store/helpers.js
+++ b/spec/javascripts/releases/stores/modules/list/helpers.js
@@ -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
export const resetStore = store => {
diff --git a/spec/javascripts/releases/list/store/mutations_spec.js b/spec/javascripts/releases/stores/modules/list/mutations_spec.js
index d756c69d53b..3035b916ff6 100644
--- a/spec/javascripts/releases/list/store/mutations_spec.js
+++ b/spec/javascripts/releases/stores/modules/list/mutations_spec.js
@@ -1,8 +1,8 @@
-import state from '~/releases/list/store/state';
-import mutations from '~/releases/list/store/mutations';
-import * as types from '~/releases/list/store/mutation_types';
+import state from '~/releases/stores/modules/list/state';
+import mutations from '~/releases/stores/modules/list/mutations';
+import * as types from '~/releases/stores/modules/list/mutation_types';
import { parseIntPagination } from '~/lib/utils/common_utils';
-import { pageInfoHeadersWithoutPagination, releases } from '../../mock_data';
+import { pageInfoHeadersWithoutPagination, releases } from '../../../mock_data';
describe('Releases Store Mutations', () => {
let stateCopy;
diff --git a/spec/lib/gitlab/background_migration/link_lfs_objects_spec.rb b/spec/lib/gitlab/background_migration/link_lfs_objects_spec.rb
new file mode 100644
index 00000000000..2a33af2c644
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/link_lfs_objects_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::BackgroundMigration::LinkLfsObjects, :migration, schema: 2020_02_10_062432 do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:fork_networks) { table(:fork_networks) }
+ let(:fork_network_members) { table(:fork_network_members) }
+ let(:lfs_objects) { table(:lfs_objects) }
+ let(:lfs_objects_projects) { table(:lfs_objects_projects) }
+ let(:namespace) { namespaces.create(name: 'GitLab', path: 'gitlab') }
+ let(:source_project) { projects.create(namespace_id: namespace.id) }
+ let(:another_source_project) { projects.create(namespace_id: namespace.id) }
+ let(:project) { projects.create(namespace_id: namespace.id) }
+ let(:another_project) { projects.create(namespace_id: namespace.id) }
+ let(:other_project) { projects.create(namespace_id: namespace.id) }
+ let(:linked_project) { projects.create(namespace_id: namespace.id) }
+ let(:fork_network) { fork_networks.create(root_project_id: source_project.id) }
+ let(:another_fork_network) { fork_networks.create(root_project_id: another_source_project.id) }
+ let(:lfs_object) { lfs_objects.create(oid: 'abc123', size: 100) }
+ let(:another_lfs_object) { lfs_objects.create(oid: 'def456', size: 200) }
+
+ before do
+ # Create links between projects
+ fork_network_members.create(fork_network_id: fork_network.id, project_id: source_project.id, forked_from_project_id: nil)
+
+ [project, another_project, linked_project].each do |p|
+ fork_network_members.create(
+ fork_network_id: fork_network.id,
+ project_id: p.id,
+ forked_from_project_id: fork_network.root_project_id
+ )
+ end
+
+ fork_network_members.create(fork_network_id: another_fork_network.id, project_id: another_source_project.id, forked_from_project_id: nil)
+ fork_network_members.create(fork_network_id: another_fork_network.id, project_id: other_project.id, forked_from_project_id: another_fork_network.root_project_id)
+
+ # Links LFS objects to some projects
+ [source_project, another_source_project, linked_project].each do |p|
+ lfs_objects_projects.create(lfs_object_id: lfs_object.id, project_id: p.id)
+ lfs_objects_projects.create(lfs_object_id: another_lfs_object.id, project_id: p.id)
+ end
+ end
+
+ it 'creates LfsObjectsProject records for forks within the specified range of project IDs' do
+ expect { subject.perform(project.id, other_project.id) }.to change { lfs_objects_projects.count }.by(6)
+
+ expect(lfs_object_ids_for(project)).to match_array(lfs_object_ids_for(source_project))
+ expect(lfs_object_ids_for(another_project)).to match_array(lfs_object_ids_for(source_project))
+ expect(lfs_object_ids_for(other_project)).to match_array(lfs_object_ids_for(another_source_project))
+
+ expect { subject.perform(project.id, other_project.id) }.not_to change { lfs_objects_projects.count }
+ end
+
+ context 'when it is not necessary to create LfsObjectProject records' do
+ it 'does not create LfsObjectProject records' do
+ expect { subject.perform(linked_project.id, linked_project.id) }
+ .not_to change { lfs_objects_projects.count }
+ end
+ end
+
+ def lfs_object_ids_for(project)
+ lfs_objects_projects.where(project_id: project.id).pluck(:lfs_object_id)
+ end
+end
diff --git a/spec/lib/gitlab/import_export/group_object_builder_spec.rb b/spec/lib/gitlab/import_export/group_object_builder_spec.rb
index 7950a937608..08b2dae1147 100644
--- a/spec/lib/gitlab/import_export/group_object_builder_spec.rb
+++ b/spec/lib/gitlab/import_export/group_object_builder_spec.rb
@@ -26,6 +26,16 @@ describe Gitlab::ImportExport::GroupObjectBuilder do
expect(label.persisted?).to be true
end
+
+ context 'when description is an empty string' do
+ let(:label_attributes) { base_attributes.merge('type' => 'GroupLabel', 'description' => '') }
+
+ it 'finds the existing group label' do
+ group_label = create(:group_label, label_attributes)
+
+ expect(described_class.build(Label, label_attributes)).to eq(group_label)
+ end
+ end
end
context 'milestones' do
@@ -41,4 +51,16 @@ describe Gitlab::ImportExport::GroupObjectBuilder do
expect(milestone.persisted?).to be true
end
end
+
+ describe '#initialize' do
+ context 'when attributes contain description as empty string' do
+ let(:attributes) { base_attributes.merge('description' => '') }
+
+ it 'converts empty string to nil' do
+ builder = described_class.new(Label, attributes)
+
+ expect(builder.send(:attributes)).to include({ 'description' => nil })
+ end
+ end
+ end
end
diff --git a/spec/migrations/schedule_link_lfs_objects_spec.rb b/spec/migrations/schedule_link_lfs_objects_spec.rb
new file mode 100644
index 00000000000..87632bc7648
--- /dev/null
+++ b/spec/migrations/schedule_link_lfs_objects_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20200210062432_schedule_link_lfs_objects.rb')
+
+describe ScheduleLinkLfsObjects, :migration, :sidekiq do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:fork_networks) { table(:fork_networks) }
+ let(:fork_network_members) { table(:fork_network_members) }
+ let(:lfs_objects) { table(:lfs_objects) }
+ let(:lfs_objects_projects) { table(:lfs_objects_projects) }
+ let(:namespace) { namespaces.create(name: 'GitLab', path: 'gitlab') }
+ let(:fork_network) { fork_networks.create(root_project_id: source_project.id) }
+ let(:another_fork_network) { fork_networks.create(root_project_id: another_source_project.id) }
+ let(:source_project) { projects.create(namespace_id: namespace.id) }
+ let(:another_source_project) { projects.create(namespace_id: namespace.id) }
+ let(:project) { projects.create(namespace_id: namespace.id) }
+ let(:another_project) { projects.create(namespace_id: namespace.id) }
+ let(:other_project) { projects.create(namespace_id: namespace.id) }
+ let(:linked_project) { projects.create(namespace_id: namespace.id) }
+ let(:lfs_object) { lfs_objects.create(oid: 'abc123', size: 100) }
+ let(:another_lfs_object) { lfs_objects.create(oid: 'def456', size: 200) }
+
+ before do
+ # Create links between projects
+ fork_network_members.create(fork_network_id: fork_network.id, project_id: source_project.id, forked_from_project_id: nil)
+
+ [project, another_project, linked_project].each do |p|
+ fork_network_members.create(
+ fork_network_id: fork_network.id,
+ project_id: p.id,
+ forked_from_project_id: fork_network.root_project_id
+ )
+ end
+
+ fork_network_members.create(fork_network_id: another_fork_network.id, project_id: another_source_project.id, forked_from_project_id: nil)
+ fork_network_members.create(fork_network_id: another_fork_network.id, project_id: other_project.id, forked_from_project_id: another_fork_network.root_project_id)
+ end
+
+ context 'when there are forks to be backfilled' do
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 2)
+
+ # Links LFS objects to some projects
+ [source_project, another_source_project, linked_project].each do |p|
+ lfs_objects_projects.create(lfs_object_id: lfs_object.id, project_id: p.id)
+ lfs_objects_projects.create(lfs_object_id: another_lfs_object.id, project_id: p.id)
+ end
+ end
+
+ it 'schedules background migration to link LFS objects' do
+ Sidekiq::Testing.fake! do
+ migrate!
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(2.minutes, project.id, another_project.id)
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(4.minutes, other_project.id, other_project.id)
+ end
+ end
+ end
+
+ context 'when there are no forks to be backfilled' do
+ before do
+ # Links LFS objects to all projects
+ projects.all.each do |p|
+ lfs_objects_projects.create(lfs_object_id: lfs_object.id, project_id: p.id)
+ lfs_objects_projects.create(lfs_object_id: another_lfs_object.id, project_id: p.id)
+ end
+ end
+
+ it 'does not schedule any job' do
+ Sidekiq::Testing.fake! do
+ migrate!
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(0)
+ end
+ end
+ end
+end
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 40c9dd565ff..e503f1a4231 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -577,7 +577,7 @@ describe 'project routing' do
end
end
- # project_blob GET /:project_id/blob/:id(.:format) blob#show {id: /[^\0]+/, project_id: /[^\/]+/}
+ # project_blob GET /:project_id/-/blob/:id(.:format) blob#show {id: /[^\0]+/, project_id: /[^\/]+/}
describe Projects::BlobController, 'routing' do
it 'to #show' do
expect(get('/gitlab/gitlabhq/-/blob/master/app/models/project.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
@@ -600,7 +600,7 @@ describe 'project routing' do
end
end
- # project_tree GET /:project_id/tree/:id(.:format) tree#show {id: /[^\0]+/, project_id: /[^\/]+/}
+ # project_tree GET /:project_id/-/tree/:id(.:format) tree#show {id: /[^\0]+/, project_id: /[^\/]+/}
describe Projects::TreeController, 'routing' do
it 'to #show' do
expect(get('/gitlab/gitlabhq/-/tree/master/app/models/project.rb')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
@@ -621,8 +621,8 @@ describe 'project routing' do
end
end
- # project_find_file GET /:namespace_id/:project_id/find_file/*id(.:format) projects/find_file#show {:id=>/[^\0]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/html/}
- # project_files GET /:namespace_id/:project_id/files/*id(.:format) projects/find_file#list {:id=>/(?:[^.]|\.(?!json$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/json/}
+ # project_find_file GET /:namespace_id/:project_id/-/find_file/*id(.:format) projects/find_file#show {:id=>/[^\0]+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/html/}
+ # project_files GET /:namespace_id/:project_id/-/files/*id(.:format) projects/find_file#list {:id=>/(?:[^.]|\.(?!json$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/json/}
describe Projects::FindFileController, 'routing' do
it 'to #show' do
expect(get('/gitlab/gitlabhq/-/find_file/master')).to route_to('projects/find_file#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
@@ -677,7 +677,7 @@ describe 'project routing' do
end
end
- # project_raw GET /:project_id/raw/:id(.:format) raw#show {id: /[^\0]+/, project_id: /[^\/]+/}
+ # project_raw GET /:project_id/-/raw/:id(.:format) raw#show {id: /[^\0]+/, project_id: /[^\/]+/}
describe Projects::RawController, 'routing' do
it 'to #show' do
newline_file = "new\n\nline.txt"
@@ -694,9 +694,9 @@ describe 'project routing' do
end
end
- # project_compare_index GET /:project_id/compare(.:format) compare#index {id: /[^\/]+/, project_id: /[^\/]+/}
- # POST /:project_id/compare(.:format) compare#create {id: /[^\/]+/, project_id: /[^\/]+/}
- # project_compare /:project_id/compare/:from...:to(.:format) compare#show {from: /.+/, to: /.+/, id: /[^\/]+/, project_id: /[^\/]+/}
+ # project_compare_index GET /:project_id/-/compare(.:format) compare#index {id: /[^\/]+/, project_id: /[^\/]+/}
+ # POST /:project_id/-/compare(.:format) compare#create {id: /[^\/]+/, project_id: /[^\/]+/}
+ # project_compare /:project_id/-/compare/:from...:to(.:format) compare#show {from: /.+/, to: /.+/, id: /[^\/]+/, project_id: /[^\/]+/}
describe Projects::CompareController, 'routing' do
it 'to #index' do
expect(get('/gitlab/gitlabhq/-/compare')).to route_to('projects/compare#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
diff --git a/spec/services/ci/pipeline_processing/shared_processing_service.rb b/spec/services/ci/pipeline_processing/shared_processing_service.rb
index 2349dedf370..ca003299535 100644
--- a/spec/services/ci/pipeline_processing/shared_processing_service.rb
+++ b/spec/services/ci/pipeline_processing/shared_processing_service.rb
@@ -880,6 +880,31 @@ shared_examples 'Pipeline Processing Service' do
end
end
+ context 'when a needed job is skipped', :sidekiq_inline do
+ let!(:linux_build) { create_build('linux:build', stage: 'build', stage_idx: 0) }
+ let!(:linux_rspec) { create_build('linux:rspec', stage: 'test', stage_idx: 1) }
+ let!(:deploy) do
+ create_build('deploy', stage: 'deploy', stage_idx: 2, scheduling_type: :dag, needs: [
+ create(:ci_build_need, name: 'linux:rspec')
+ ])
+ end
+
+ it 'skips the jobs depending on it' do
+ expect(process_pipeline).to be_truthy
+
+ expect(stages).to eq(%w(pending created created))
+ expect(all_builds.pending).to contain_exactly(linux_build)
+
+ linux_build.reset.drop!
+
+ expect(stages).to eq(%w(failed skipped skipped))
+ expect(all_builds.failed).to contain_exactly(linux_build)
+ expect(all_builds.skipped).to contain_exactly(linux_rspec, deploy)
+ end
+ end
+
+ private
+
def all_builds
pipeline.builds.order(:stage_idx, :id)
end
diff --git a/spec/services/ci/process_build_service_spec.rb b/spec/services/ci/process_build_service_spec.rb
index 704685417bb..abc5c18a523 100644
--- a/spec/services/ci/process_build_service_spec.rb
+++ b/spec/services/ci/process_build_service_spec.rb
@@ -22,6 +22,14 @@ describe Ci::ProcessBuildService, '#execute' do
end
end
+ context 'when current status is skipped' do
+ let(:current_status) { 'skipped' }
+
+ it 'changes the build status' do
+ expect { subject }.to change { build.status }.to('pending')
+ end
+ end
+
context 'when current status is failed' do
let(:current_status) { 'failed' }
@@ -114,4 +122,27 @@ describe Ci::ProcessBuildService, '#execute' do
end
end
end
+
+ context 'when build is scheduled with DAG' do
+ let(:pipeline) { create(:ci_pipeline, ref: 'master', project: project) }
+ let!(:build) { create(:ci_build, :created, when: :on_success, pipeline: pipeline, scheduling_type: :dag) }
+ let!(:other_build) { create(:ci_build, :created, when: :on_success, pipeline: pipeline) }
+ let!(:build_on_other_build) { create(:ci_build_need, build: build, name: other_build.name) }
+
+ context 'when current status is success' do
+ let(:current_status) { 'success' }
+
+ it 'enqueues the build' do
+ expect { subject }.to change { build.status }.to('pending')
+ end
+ end
+
+ context 'when current status is skipped' do
+ let(:current_status) { 'skipped' }
+
+ it 'skips the build' do
+ expect { subject }.to change { build.status }.to('skipped')
+ end
+ end
+ end
end