Commit 8a68e849 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge remote-tracking branch 'ee/master' into ce-to-ee-2017-08-03

* ee/master:
  Add notes on when repository pulling and pushing where introduced in GitLab
  fixed specs
  EE port of 34060-simplified-general-project-settings
  Backport to CE for:
  Make new dropdown dividers full width
  Update EE doc about where to place the files
  Update JavaScript style guide according to:
  Handle project deletions in Geo::LogCursor
  Fix json schema definition
  Move the new files
  35659 Rename Pipelines tab to CI / CD in new navigation
  Move this spec to the right location and enable rubocop
  Move javascript files
  Move the new view files
  Move spec files
  Move views
  Also move models/concerns and lib
  Move EE-specific files to a standalone directory
parents 22476cad e012d8ca
/* global ListIssue */
import Vue from 'vue';
import queryData from '../../utils/query_data';
import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
import queryData from '~/boards/utils/query_data';
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import './header';
import './list';
import './footer';
......
......@@ -381,6 +381,9 @@ import initGroupAnalytics from './init_group_analytics';
new UsersSelect();
new GroupsSelect();
setupProjectEdit();
// Initialize expandable settings panels
initSettingsPanels();
new UsersSelect();
break;
case 'projects:imports:show':
new ProjectImport();
......
<script>
import GfmAutoComplete from '~/gfm_auto_complete';
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import eventHub from '../event_hub';
import issueToken from './issue_token.vue';
import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
export default {
name: 'AddIssuableForm',
......
<script>
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
import eventHub from '../event_hub';
import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
import tooltip from '../../../vue_shared/directives/tooltip';
import issueToken from './issue_token.vue';
import addIssuableForm from './add_issuable_form.vue';
......
<script>
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import linkedPipelinesColumn from './linked_pipelines_column.vue';
import stageColumnComponent from './stage_column_component.vue';
import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
export default {
props: {
......
/**
* This file is the centerpiece of an attempt to reduce potential conflicts
* between the CE and EE versions of the MR widget. EE additions to the MR widget should
* be contained in the ./vue_merge_request_widget/ee directory, and should **extend**
* be contained in the ee/vue_merge_request_widget directory, and should **extend**
* rather than mutate CE MR Widget code.
*
* This file should be the only source of conflicts between EE and CE. EE-only components should
......@@ -26,7 +26,7 @@ export { default as ConflictsState } from './components/states/mr_widget_conflic
export { default as NothingToMergeState } from './components/states/mr_widget_nothing_to_merge';
export { default as MissingBranchState } from './components/states/mr_widget_missing_branch';
export { default as NotAllowedState } from './components/states/mr_widget_not_allowed';
export { default as ReadyToMergeState } from './ee/components/states/mr_widget_ready_to_merge';
export { default as ReadyToMergeState } from 'ee/vue_merge_request_widget/components/states/mr_widget_ready_to_merge';
export { default as SHAMismatchState } from './components/states/mr_widget_sha_mismatch';
export { default as UnresolvedDiscussionsState } from './components/states/mr_widget_unresolved_discussions';
export { default as PipelineBlockedState } from './components/states/mr_widget_pipeline_blocked';
......@@ -34,11 +34,11 @@ export { default as PipelineFailedState } from './components/states/mr_widget_pi
export { default as MergeWhenPipelineSucceedsState } from './components/states/mr_widget_merge_when_pipeline_succeeds';
export { default as AutoMergeFailed } from './components/states/mr_widget_auto_merge_failed';
export { default as CheckingState } from './components/states/mr_widget_checking';
export { default as MRWidgetStore } from './ee/stores/mr_widget_store';
export { default as MRWidgetService } from './ee/services/mr_widget_service';
export { default as MRWidgetStore } from 'ee/vue_merge_request_widget/stores/mr_widget_store';
export { default as MRWidgetService } from 'ee/vue_merge_request_widget/services/mr_widget_service';
export { default as eventHub } from './event_hub';
export { default as getStateKey } from './ee/stores/get_state_key';
export { default as mrWidgetOptions } from './ee/mr_widget_options';
export { default as stateMaps } from './ee/stores/state_maps';
export { default as SquashBeforeMerge } from './ee/components/states/mr_widget_squash_before_merge';
export { default as getStateKey } from 'ee/vue_merge_request_widget/stores/get_state_key';
export { default as mrWidgetOptions } from 'ee/vue_merge_request_widget/mr_widget_options';
export { default as stateMaps } from 'ee/vue_merge_request_widget/stores/state_maps';
export { default as SquashBeforeMerge } from 'ee/vue_merge_request_widget/components/states/mr_widget_squash_before_merge';
export { default as notify } from '../lib/utils/notify';
......@@ -728,6 +728,10 @@
@mixin new-style-dropdown {
.dropdown-menu,
.dropdown-menu-nav {
.divider {
margin: 6px 0;
}
li {
padding: 0 1px;
......
......@@ -312,6 +312,10 @@ header.navbar-gitlab-new {
// TODO: fallback to global style
.dropdown-menu {
.divider {
margin: 6px 0;
}
li {
padding: 0 1px;
......
......@@ -36,7 +36,6 @@
}
select {
background: transparent;
transition: background 2s ease-out;
&.highlight-changes {
......
......@@ -54,8 +54,7 @@
.settings-content {
max-height: 1px;
overflow-y: scroll;
margin-right: -20px;
padding-right: 130px;
padding-right: 110px;
animation: collapseMaxHeight 300ms ease-out;
&.expanded {
......@@ -87,6 +86,23 @@
overflow: hidden;
margin-top: 20px;
}
.sub-section {
margin-bottom: 32px;
padding: 16px;
border: 1px solid $border-color;
background-color: $gray-light;
}
.bs-callout,
.checkbox:first-child,
.help-block {
margin-top: 0;
}
.label-light {
margin-bottom: 0;
}
}
.settings-list-icon {
......
# Shorter routing method for some project items
module GitlabRoutingHelper
include EE::GitlabRoutingHelper
extend ActiveSupport::Concern
included do
......
module IssuesHelper
include EE::IssuesHelper
def issue_css_classes(issue)
classes = "issue"
classes << " closed" if issue.closed?
......
module NamespacesHelper
include EE::NamespaceHelper
def namespace_id_from(params)
params.dig(:project, :namespace_id) || params[:namespace_id]
end
......
......@@ -91,8 +91,8 @@
Projects
= nav_link(controller: :ci_cd) do
= link_to group_settings_ci_cd_path(@group), title: 'Pipelines' do
= link_to group_settings_ci_cd_path(@group), title: 'CI / CD' do
%span
Pipelines
CI / CD
= render "groups/ee/settings_nav"
......@@ -122,11 +122,11 @@
- if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts]) do
= link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
= link_to project_pipelines_path(@project), title: 'CI / CD', class: 'shortcuts-pipelines' do
.nav-icon-container
= custom_icon('pipeline')
%span.nav-item-name
Pipelines
CI / CD
%ul.sidebar-sub-level-items
- if project_nav_tab? :pipelines
......@@ -205,9 +205,9 @@
Repository
- if @project.feature_available?(:builds, current_user)
= nav_link(controller: :ci_cd) do
= link_to project_settings_ci_cd_path(@project), title: 'Pipelines' do
= link_to project_settings_ci_cd_path(@project), title: 'CI / CD' do
%span
Pipelines
CI / CD
- if Gitlab.config.pages.enabled
= nav_link(controller: :pages) do
= link_to project_pages_path(@project), title: 'Pages' do
......
- form = local_assigns.fetch(:form)
%fieldset.features.merge-requests-feature.append-bottom-default
%hr
%h5.prepend-top-0
Merge Requests
= render 'projects/ee/merge_request_settings', form: form, project: @project
= render 'projects/ee/merge_request_settings', form: form, project: @project
= render 'projects/merge_request_merge_settings', form: form
= render 'projects/merge_request_merge_settings', form: form
This diff is collapsed.
- if @project.feature_available?(:issuable_default_templates)
%fieldset.features.append-bottom-0.issues-feature
%hr
%h5.prepend-top-0
Issues
.form-group
= form.label :issues_template, class: 'label-light' do
Default description template for issues
= link_to icon('question-circle'), help_page_path('user/project/description_templates', anchor: 'setting-a-default-template-for-issues-and-merge-requests'), target: '_blank'
= form.text_area :issues_template, class: "form-control", rows: 3
.hint
Description parsed with #{link_to "GitLab Flavored Markdown", help_page_path('user/markdown'), target: '_blank'}.
---
title: Rename Pipelines tab to CI / CD in new navigation
merge_request:
author:
......@@ -25,19 +25,32 @@ module Gitlab
# https://github.com/rails/rails/blob/v4.2.6/railties/lib/rails/engine.rb#L687
# This is a nice reference article on autoloading/eager loading:
# http://blog.arkency.com/2014/11/dont-forget-about-eager-load-when-extending-autoload
config.eager_load_paths.push(*%W(#{config.root}/lib
config.eager_load_paths.push(*%W[#{config.root}/lib
#{config.root}/app/models/hooks
#{config.root}/app/models/members
#{config.root}/app/models/project_services
#{config.root}/app/workers/concerns
#{config.root}/app/services/concerns
#{config.root}/app/uploaders/concerns
#{config.root}/app/finders/concerns))
#{config.root}/app/finders/concerns])
config.generators.templates.push("#{config.root}/generator_templates")
# EE specific paths.
config.eager_load_paths.push("#{config.root}/app/workers/concerns")
config.eager_load_paths.push(*%W[
#{config.root}/ee/lib
#{config.root}/ee/app/controllers
#{config.root}/ee/app/helpers
#{config.root}/ee/app/mailers
#{config.root}/ee/app/models
#{config.root}/ee/app/models/concerns
#{config.root}/ee/app/policies
#{config.root}/ee/app/services
#{config.root}/ee/app/workers
])
config.paths['app/views'].push(*%W[
#{config.root}/ee/app/views
])
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
......
require_dependency Rails.root.join('lib/gitlab') # Load Gitlab as soon as possible
require_dependency Rails.root.join('lib/ee') # Load EE as soon as possible
class Settings < Settingslogic
source ENV.fetch('GITLAB_CONFIG') { "#{Rails.root}/config/gitlab.yml" }
......
......@@ -66,9 +66,9 @@ var config = {
project_new: './projects/project_new.js',
prometheus_metrics: './prometheus_metrics',
protected_branches: './protected_branches',
ee_protected_branches: './protected_branches/ee',
ee_protected_branches: 'ee/protected_branches',
protected_tags: './protected_tags',
ee_protected_tags: './protected_tags/ee',
ee_protected_tags: 'ee/protected_tags',
service_desk: './projects/settings_service_desk/service_desk_bundle.js',
sidebar: './sidebar/sidebar_bundle.js',
schedule_form: './pipeline_schedules/pipeline_schedule_form_bundle.js',
......@@ -214,6 +214,7 @@ var config = {
resolve: {
extensions: ['.js'],
alias: {
'ee': path.join(ROOT_PATH, 'ee/app/assets/javascripts'),
'~': path.join(ROOT_PATH, 'app/assets/javascripts'),
'emojis': path.join(ROOT_PATH, 'fixtures/emojis'),
'empty_states': path.join(ROOT_PATH, 'app/views/shared/empty_states'),
......
......@@ -17,19 +17,19 @@ as much as possible.
Place EE-specific controllers, finders, helpers, mailers, models, policies,
serializers/entities, services, validators and workers in the top-level
`EE` module namespace, and in a specific `/ee/` sub-folder:
- `app/controllers/ee/foos_controller.rb`
- `app/finders/ee/foos_finder.rb`
- `app/helpers/ee/foos_helper.rb`
- `app/mailers/ee/foos_mailer.rb`
- `app/models/ee/foo.rb`
- `app/policies/ee/foo_policy.rb`
- `app/serializers/ee/foo_entity.rb`
- `app/serializers/ee/foo_serializer.rb`
- `app/services/ee/foo/create_service.rb`
- `app/validators/ee/foo_attr_validator.rb`
- `app/workers/ee/foo_worker.rb`
`EE` module namespace, and in the `ee/` specific sub-directory:
- `ee/app/controllers/ee/foos_controller.rb`
- `ee/app/finders/ee/foos_finder.rb`
- `ee/app/helpers/ee/foos_helper.rb`
- `ee/app/mailers/ee/foos_mailer.rb`
- `ee/app/models/ee/foo.rb`
- `ee/app/policies/ee/foo_policy.rb`
- `ee/app/serializers/ee/foo_entity.rb`
- `ee/app/serializers/ee/foo_serializer.rb`
- `ee/app/services/ee/foo/create_service.rb`
- `ee/app/validators/ee/foo_attr_validator.rb`
- `ee/app/workers/ee/foo_worker.rb`
If you modify an existing part of a CE controller, model, service, worker etc.
one simple solution is to use the `prepend` strategy ([presented below](#overriding-ce-methods)).
......@@ -58,7 +58,7 @@ class ApplicationController < ActionController::Base
end
module EE
class ApplicationController
class ApplicationController
def after_sign_out_path_for(resource)
raise NotImplementedError unless defined?(super)
......@@ -117,7 +117,7 @@ end
EE-specific models should `extend EE::Model`.
For example, if EE has a specific `Tanuki` model, you would
place it in `app/models/ee/tanuki.rb`.
place it in `ee/app/models/ee/tanuki.rb`.
#### Code in `app/views/`
......@@ -136,7 +136,7 @@ Place EE-specific logic in the top-level `EE` module namespace. Namespace the
class beneath the `EE` module just as you would normally.
For example, if CE has LDAP classes in `lib/gitlab/ldap/` then you would place
EE-specific LDAP classes in `lib/ee/gitlab/ldap`.
EE-specific LDAP classes in `ee/lib/ee/gitlab/ldap`.
### Classes vs. Module Mixins
......
......@@ -11,7 +11,7 @@ See [our current .eslintrc][eslintrc] for specific rules and patterns.
#### ESlint
1. **Never** disable eslint rules unless you have a good reason.
1. **Never** disable eslint rules unless you have a good reason.
You may see a lot of legacy files with `/* eslint-disable some-rule, some-other-rule */`
at the top, but legacy files are a special case. Any time you develop a new feature or
refactor an existing one, you should abide by the eslint rules.
......@@ -100,26 +100,44 @@ followed by any global declarations, then a blank newline prior to any imports o
export default Foo;
```
1. Relative paths: Unless you are writing a test, always reference other scripts using
relative paths instead of `~`
* In **app/assets/javascripts**:
1. Relative paths: when importing a module in the same directory, a child
directory, or an immediate parent directory prefer relative paths. When
importing a module which is two or more levels up, prefer either `~/` or `ee/`
.
```javascript
// bad
import Foo from '~/foo'
In **app/assets/javascripts/my-feature/subdir**:
// good
import Foo from '../foo';
```
* In **spec/javascripts**:
``` javascript
// bad
import Foo from '~/my-feature/foo';
import Bar from '~/my-feature/subdir/bar';
import Bin from '~/my-feature/subdir/lib/bin';
```javascript
// bad
import Foo from '../../app/assets/javascripts/foo'
// good
import Foo from '../foo';
import Bar from './bar';
import Bin from './lib/bin';
```
// good
import Foo from '~/foo';
```
In **spec/javascripts**:
``` javascript
// bad
import Foo from '../../app/assets/javascripts/my-feature/foo';
// good
import Foo from '~/my-feature/foo';
```
When referencing an **EE component**:
``` javascript
// bad
import Foo from '../../../../../ee/app/assets/javascripts/my-feature/ee-foo';
// good
import Foo from 'ee/my-feature/foo';
```
1. Avoid using IIFE. Although we have a lot of examples of files which wrap their
contents in IIFEs (immediately-invoked function expressions),
......@@ -465,7 +483,7 @@ A forEach will cause side effects, it will be mutating the array being iterated.
#### Vue and Boostrap
1. Tooltips: Do not rely on `has-tooltip` class name for Vue components
```javascript
```javascript
// bad
<span
class="has-tooltip"
......
# Repository mirroring
>[Introduced][ee-51] in GitLab Enterprise Edition 8.2.
Repository Mirroring is a way to mirror repositories from external sources.
It can be used to mirror all branches, tags, and commits that you have
......@@ -50,6 +49,8 @@ A few things/limitations to consider:
## Pulling from a remote repository
>[Introduced][ee-51] in GitLab Enterprise Edition 8.2.
You can set up a repository to automatically have its branches, tags, and commits
updated from an upstream repository. This is useful when a repository you're
interested in is located on a different server, and you want to be able to
......@@ -97,6 +98,8 @@ backoff period will be penalized each time it fails up to a maximum amount of ti
## Pushing to a remote repository
>[Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/249) in GitLab Enterprise Edition 8.7.
For an existing project, you can set up mirror pushing by visiting your project's
**Settings ➔ Repository** and searching for the "Push to a remote repository"
section. Check the "Remote mirror repository" box and fill in the Git URL of the
......
/* global Flash */
import MRWidgetAuthor from '../../../components/mr_widget_author';
import eventHub from '../../../event_hub';
import MRWidgetAuthor from '~/vue_merge_request_widget/components/mr_widget_author';
import eventHub from '~/vue_merge_request_widget/event_hub';
export default {
name: 'approvals-body',
......
/* global Flash */
import LinkToMemberAvatar from '~/vue_shared/components/link_to_member_avatar';
import eventHub from '../../../event_hub';
import eventHub from '~/vue_merge_request_widget/event_hub';
export default {
name: 'approvals-footer',
......
<script>
import successIcon from 'icons/_icon_status_success.svg';
import errorIcon from 'icons/_icon_status_failed.svg';
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import '~/lib/utils/text_utility';
import issuesBlock from './mr_widget_code_quality_issues.vue';
import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
import '../../../lib/utils/text_utility';
export default {
name: 'MRWidgetCodeQuality',
......
import eventHub from '../../../event_hub';
import ReadyToMergeState from '../../../components/states/mr_widget_ready_to_merge';
import eventHub from '~/vue_merge_request_widget/event_hub';
import ReadyToMergeState from '~/vue_merge_request_widget/components/states/mr_widget_ready_to_merge';
import SquashBeforeMerge from './mr_widget_squash_before_merge';
export default {
......
/* global Flash */
import simplePoll from '~/lib/utils/simple_poll';
import eventHub from '../../../event_hub';
import eventHub from '~/vue_merge_request_widget/event_hub';
export default {
props: {
......
import eventHub from '../../../event_hub';
import CESquashBeforeMerge from '../../components/states/mr_widget_squash_before_merge';
import eventHub from '~/vue_merge_request_widget/event_hub';
import CESquashBeforeMerge from '~/vue_merge_request_widget/components/states/mr_widget_squash_before_merge';
export default {
extends: CESquashBeforeMerge,
......
import CEWidgetOptions from '../mr_widget_options';
import CEWidgetOptions from '~/vue_merge_request_widget/mr_widget_options';
import WidgetApprovals from './components/approvals/mr_widget_approvals';
import GeoSecondaryNode from './components/states/mr_widget_secondary_geo_node';
import RebaseState from './components/states/mr_widget_rebase';
......
import Vue from 'vue';
import CEWidgetService from '../../services/mr_widget_service';
import CEWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
export default class MRWidgetService extends CEWidgetService {
constructor(mr) {
......
import CEGetStateKey from '../../stores/get_state_key';
import CEGetStateKey from '~/vue_merge_request_widget/stores/get_state_key';
export default function (data) {
if (this.isGeoSecondaryNode) {
......
import CEMergeRequestStore from '../../stores/mr_widget_store';
import CEMergeRequestStore from '~/vue_merge_request_widget/stores/mr_widget_store';
export default class MergeRequestStore extends CEMergeRequestStore {
constructor(data) {
......
import stateMaps from '../../stores/state_maps';
import stateMaps from '~/vue_merge_request_widget/stores/state_maps';
stateMaps.stateToComponentMap.geoSecondaryNode = 'mr-widget-geo-secondary-node';
stateMaps.stateToComponentMap.rebase = 'mr-widget-rebase';
......
......@@ -2,6 +2,8 @@ class Admin::GeoNodesController < Admin::ApplicationController
before_action :check_license, except: [:index, :destroy]
before_action :load_node, only: [:edit, :update, :destroy, :repair, :toggle, :status]
helper EE::GeoHelper
def index
@nodes = GeoNode.all.order(:id)
@node = GeoNode.new
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment