Standardize markdown in dev and workflow
Delete trailing whitespace, fix blockquotes, fix note boxes, with indentation, clean up tables, etc.
This commit is contained in:
parent
a749fcbea7
commit
3bc0a1185c
13 changed files with 331 additions and 328 deletions
|
@ -21,31 +21,31 @@ See [our current .eslintrc](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/
|
|||
1. **Never Ever EVER** disable eslint globally for a file
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
/* eslint-disable */
|
||||
// bad
|
||||
/* eslint-disable */
|
||||
|
||||
// better
|
||||
/* eslint-disable some-rule, some-other-rule */
|
||||
// better
|
||||
/* eslint-disable some-rule, some-other-rule */
|
||||
|
||||
// best
|
||||
// nothing :)
|
||||
// best
|
||||
// nothing :)
|
||||
```
|
||||
|
||||
1. If you do need to disable a rule for a single violation, try to do it as locally as possible
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
/* eslint-disable no-new */
|
||||
// bad
|
||||
/* eslint-disable no-new */
|
||||
|
||||
import Foo from 'foo';
|
||||
import Foo from 'foo';
|
||||
|
||||
new Foo();
|
||||
new Foo();
|
||||
|
||||
// better
|
||||
import Foo from 'foo';
|
||||
// better
|
||||
import Foo from 'foo';
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new Foo();
|
||||
// eslint-disable-next-line no-new
|
||||
new Foo();
|
||||
```
|
||||
|
||||
1. There are few rules that we need to disable due to technical debt. Which are:
|
||||
|
@ -56,16 +56,16 @@ See [our current .eslintrc](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/
|
|||
followed by any global declarations, then a blank newline prior to any imports or code.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
/* global Foo */
|
||||
/* eslint-disable no-new */
|
||||
import Bar from './bar';
|
||||
// bad
|
||||
/* global Foo */
|
||||
/* eslint-disable no-new */
|
||||
import Bar from './bar';
|
||||
|
||||
// good
|
||||
/* eslint-disable no-new */
|
||||
/* global Foo */
|
||||
// good
|
||||
/* eslint-disable no-new */
|
||||
/* global Foo */
|
||||
|
||||
import Bar from './bar';
|
||||
import Bar from './bar';
|
||||
```
|
||||
|
||||
1. **Never** disable the `no-undef` rule. Declare globals with `/* global Foo */` instead.
|
||||
|
@ -73,23 +73,23 @@ See [our current .eslintrc](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/
|
|||
1. When declaring multiple globals, always use one `/* global [name] */` line per variable.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
/* globals Flash, Cookies, jQuery */
|
||||
// bad
|
||||
/* globals Flash, Cookies, jQuery */
|
||||
|
||||
// good
|
||||
/* global Flash */
|
||||
/* global Cookies */
|
||||
/* global jQuery */
|
||||
// good
|
||||
/* global Flash */
|
||||
/* global Cookies */
|
||||
/* global jQuery */
|
||||
```
|
||||
|
||||
1. Use up to 3 parameters for a function or class. If you need more accept an Object instead.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
fn(p1, p2, p3, p4) {}
|
||||
// bad
|
||||
fn(p1, p2, p3, p4) {}
|
||||
|
||||
// good
|
||||
fn(options) {}
|
||||
// good
|
||||
fn(options) {}
|
||||
```
|
||||
|
||||
#### Modules, Imports, and Exports
|
||||
|
@ -97,32 +97,32 @@ See [our current .eslintrc](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/
|
|||
1. Use ES module syntax to import modules
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
const SomeClass = require('some_class');
|
||||
// bad
|
||||
const SomeClass = require('some_class');
|
||||
|
||||
// good
|
||||
import SomeClass from 'some_class';
|
||||
// good
|
||||
import SomeClass from 'some_class';
|
||||
|
||||
// bad
|
||||
module.exports = SomeClass;
|
||||
// bad
|
||||
module.exports = SomeClass;
|
||||
|
||||
// good
|
||||
export default SomeClass;
|
||||
// good
|
||||
export default SomeClass;
|
||||
```
|
||||
|
||||
Import statements are following usual naming guidelines, for example object literals use camel case:
|
||||
|
||||
```javascript
|
||||
// some_object file
|
||||
export default {
|
||||
key: 'value',
|
||||
};
|
||||
// some_object file
|
||||
export default {
|
||||
key: 'value',
|
||||
};
|
||||
|
||||
// bad
|
||||
import ObjectLiteral from 'some_object';
|
||||
// bad
|
||||
import ObjectLiteral from 'some_object';
|
||||
|
||||
// good
|
||||
import objectLiteral from 'some_object';
|
||||
// good
|
||||
import objectLiteral from 'some_object';
|
||||
```
|
||||
|
||||
1. Relative paths: when importing a module in the same directory, a child
|
||||
|
@ -171,22 +171,22 @@ See [our current .eslintrc](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/
|
|||
1. Avoid adding to the global namespace.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
window.MyClass = class { /* ... */ };
|
||||
// bad
|
||||
window.MyClass = class { /* ... */ };
|
||||
|
||||
// good
|
||||
export default class MyClass { /* ... */ }
|
||||
// good
|
||||
export default class MyClass { /* ... */ }
|
||||
```
|
||||
|
||||
1. Side effects are forbidden in any script which contains export
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
export default class MyClass { /* ... */ }
|
||||
// bad
|
||||
export default class MyClass { /* ... */ }
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
new MyClass();
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
new MyClass();
|
||||
}
|
||||
```
|
||||
|
||||
#### Data Mutation and Pure functions
|
||||
|
@ -257,17 +257,17 @@ See [our current .eslintrc](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/
|
|||
`.reduce` or `.filter`
|
||||
|
||||
```javascript
|
||||
const users = [ { name: 'Foo' }, { name: 'Bar' } ];
|
||||
const users = [ { name: 'Foo' }, { name: 'Bar' } ];
|
||||
|
||||
// bad
|
||||
users.forEach((user, index) => {
|
||||
user.id = index;
|
||||
});
|
||||
// bad
|
||||
users.forEach((user, index) => {
|
||||
user.id = index;
|
||||
});
|
||||
|
||||
// good
|
||||
const usersWithId = users.map((user, index) => {
|
||||
return Object.assign({}, user, { id: index });
|
||||
});
|
||||
// good
|
||||
const usersWithId = users.map((user, index) => {
|
||||
return Object.assign({}, user, { id: index });
|
||||
});
|
||||
```
|
||||
|
||||
#### Parse Strings into Numbers
|
||||
|
@ -275,14 +275,14 @@ See [our current .eslintrc](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/
|
|||
1. `parseInt()` is preferable over `Number()` or `+`
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
+'10' // 10
|
||||
// bad
|
||||
+'10' // 10
|
||||
|
||||
// good
|
||||
Number('10') // 10
|
||||
// good
|
||||
Number('10') // 10
|
||||
|
||||
// better
|
||||
parseInt('10', 10);
|
||||
// better
|
||||
parseInt('10', 10);
|
||||
```
|
||||
|
||||
#### CSS classes used for JavaScript
|
||||
|
@ -290,15 +290,15 @@ See [our current .eslintrc](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/
|
|||
1. If the class is being used in Javascript it needs to be prepend with `js-`
|
||||
|
||||
```html
|
||||
// bad
|
||||
<button class="add-user">
|
||||
Add User
|
||||
</button>
|
||||
// bad
|
||||
<button class="add-user">
|
||||
Add User
|
||||
</button>
|
||||
|
||||
// good
|
||||
<button class="js-add-user">
|
||||
Add User
|
||||
</button>
|
||||
// good
|
||||
<button class="js-add-user">
|
||||
Add User
|
||||
</button>
|
||||
```
|
||||
|
||||
### Vue.js
|
||||
|
@ -315,41 +315,41 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
|
|||
1. Use a function in the bundle file to instantiate the Vue component:
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
class {
|
||||
init() {
|
||||
new Component({})
|
||||
}
|
||||
// bad
|
||||
class {
|
||||
init() {
|
||||
new Component({})
|
||||
}
|
||||
}
|
||||
|
||||
// good
|
||||
document.addEventListener('DOMContentLoaded', () => new Vue({
|
||||
el: '#element',
|
||||
components: {
|
||||
componentName
|
||||
},
|
||||
render: createElement => createElement('component-name'),
|
||||
}));
|
||||
// good
|
||||
document.addEventListener('DOMContentLoaded', () => new Vue({
|
||||
el: '#element',
|
||||
components: {
|
||||
componentName
|
||||
},
|
||||
render: createElement => createElement('component-name'),
|
||||
}));
|
||||
```
|
||||
|
||||
1. Do not use a singleton for the service or the store
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
class Store {
|
||||
constructor() {
|
||||
if (!this.prototype.singleton) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// good
|
||||
class Store {
|
||||
constructor() {
|
||||
// bad
|
||||
class Store {
|
||||
constructor() {
|
||||
if (!this.prototype.singleton) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// good
|
||||
class Store {
|
||||
constructor() {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Use `.vue` for Vue templates. Do not use `%template` in HAML.
|
||||
|
@ -360,36 +360,36 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
|
|||
1. **Reference Naming**: Use PascalCase for their instances:
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
import cardBoard from 'cardBoard.vue'
|
||||
// bad
|
||||
import cardBoard from 'cardBoard.vue'
|
||||
|
||||
components: {
|
||||
cardBoard,
|
||||
};
|
||||
components: {
|
||||
cardBoard,
|
||||
};
|
||||
|
||||
// good
|
||||
import CardBoard from 'cardBoard.vue'
|
||||
// good
|
||||
import CardBoard from 'cardBoard.vue'
|
||||
|
||||
components: {
|
||||
CardBoard,
|
||||
};
|
||||
components: {
|
||||
CardBoard,
|
||||
};
|
||||
```
|
||||
|
||||
1. **Props Naming:** Avoid using DOM component prop names.
|
||||
1. **Props Naming:** Use kebab-case instead of camelCase to provide props in templates.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
<component class="btn">
|
||||
// bad
|
||||
<component class="btn">
|
||||
|
||||
// good
|
||||
<component css-class="btn">
|
||||
// good
|
||||
<component css-class="btn">
|
||||
|
||||
// bad
|
||||
<component myProp="prop" />
|
||||
// bad
|
||||
<component myProp="prop" />
|
||||
|
||||
// good
|
||||
<component my-prop="prop" />
|
||||
// good
|
||||
<component my-prop="prop" />
|
||||
```
|
||||
|
||||
[#34371]: https://gitlab.com/gitlab-org/gitlab-ce/issues/34371
|
||||
|
@ -401,37 +401,37 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
|
|||
1. With more than one attribute, all attributes should be on a new line:
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
<component v-if="bar"
|
||||
param="baz" />
|
||||
// bad
|
||||
<component v-if="bar"
|
||||
param="baz" />
|
||||
|
||||
<button class="btn">Click me</button>
|
||||
<button class="btn">Click me</button>
|
||||
|
||||
// good
|
||||
<component
|
||||
v-if="bar"
|
||||
param="baz"
|
||||
/>
|
||||
// good
|
||||
<component
|
||||
v-if="bar"
|
||||
param="baz"
|
||||
/>
|
||||
|
||||
<button class="btn">
|
||||
Click me
|
||||
</button>
|
||||
<button class="btn">
|
||||
Click me
|
||||
</button>
|
||||
```
|
||||
|
||||
1. The tag can be inline if there is only one attribute:
|
||||
|
||||
```javascript
|
||||
// good
|
||||
<component bar="bar" />
|
||||
// good
|
||||
<component bar="bar" />
|
||||
|
||||
// good
|
||||
<component
|
||||
bar="bar"
|
||||
/>
|
||||
// good
|
||||
<component
|
||||
bar="bar"
|
||||
/>
|
||||
|
||||
// bad
|
||||
<component
|
||||
bar="bar" />
|
||||
// bad
|
||||
<component
|
||||
bar="bar" />
|
||||
```
|
||||
|
||||
#### Quotes
|
||||
|
@ -439,15 +439,15 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
|
|||
1. Always use double quotes `"` inside templates and single quotes `'` for all other JS.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
template: `
|
||||
<button :class='style'>Button</button>
|
||||
`
|
||||
// bad
|
||||
template: `
|
||||
<button :class='style'>Button</button>
|
||||
`
|
||||
|
||||
// good
|
||||
template: `
|
||||
<button :class="style">Button</button>
|
||||
`
|
||||
// good
|
||||
template: `
|
||||
<button :class="style">Button</button>
|
||||
`
|
||||
```
|
||||
|
||||
#### Props
|
||||
|
@ -455,37 +455,37 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
|
|||
1. Props should be declared as an object
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
props: ['foo']
|
||||
// bad
|
||||
props: ['foo']
|
||||
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'bar'
|
||||
}
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'bar'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Required key should always be provided when declaring a prop
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
}
|
||||
// bad
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
}
|
||||
}
|
||||
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'bar'
|
||||
}
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'bar'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Default key should be provided if the prop is not required.
|
||||
|
@ -493,30 +493,30 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
|
|||
On those a default key should not be provided.
|
||||
|
||||
```javascript
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: false,
|
||||
}
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: false,
|
||||
}
|
||||
}
|
||||
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'bar'
|
||||
}
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'bar'
|
||||
}
|
||||
}
|
||||
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
// good
|
||||
props: {
|
||||
foo: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Data
|
||||
|
@ -524,17 +524,17 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
|
|||
1. `data` method should always be a function
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
data: {
|
||||
foo: 'foo'
|
||||
}
|
||||
// bad
|
||||
data: {
|
||||
foo: 'foo'
|
||||
}
|
||||
|
||||
// good
|
||||
data() {
|
||||
return {
|
||||
foo: 'foo'
|
||||
};
|
||||
}
|
||||
// good
|
||||
data() {
|
||||
return {
|
||||
foo: 'foo'
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### Directives
|
||||
|
@ -542,31 +542,31 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
|
|||
1. Shorthand `@` is preferable over `v-on`
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
<component v-on:click="eventHandler"/>
|
||||
// bad
|
||||
<component v-on:click="eventHandler"/>
|
||||
|
||||
// good
|
||||
<component @click="eventHandler"/>
|
||||
// good
|
||||
<component @click="eventHandler"/>
|
||||
```
|
||||
|
||||
1. Shorthand `:` is preferable over `v-bind`
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
<component v-bind:class="btn"/>
|
||||
// bad
|
||||
<component v-bind:class="btn"/>
|
||||
|
||||
// good
|
||||
<component :class="btn"/>
|
||||
// good
|
||||
<component :class="btn"/>
|
||||
```
|
||||
|
||||
1. Shorthand `#` is preferable over `v-slot`
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
<template v-slot:header></template>
|
||||
// bad
|
||||
<template v-slot:header></template>
|
||||
|
||||
// good
|
||||
<template #header></template>
|
||||
// good
|
||||
<template #header></template>
|
||||
```
|
||||
|
||||
#### Closing tags
|
||||
|
@ -574,11 +574,11 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
|
|||
1. Prefer self closing component tags
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
<component></component>
|
||||
// bad
|
||||
<component></component>
|
||||
|
||||
// good
|
||||
<component />
|
||||
// good
|
||||
<component />
|
||||
```
|
||||
|
||||
#### Ordering
|
||||
|
@ -610,48 +610,48 @@ When using `v-for` you need to provide a *unique* `:key` attribute for each item
|
|||
1. If the elements of the array being iterated have an unique `id` it is advised to use it:
|
||||
|
||||
```html
|
||||
<div
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
>
|
||||
<!-- content -->
|
||||
</div>
|
||||
<div
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
>
|
||||
<!-- content -->
|
||||
</div>
|
||||
```
|
||||
|
||||
1. When the elements being iterated don't have a unique id, you can use the array index as the `:key` attribute
|
||||
|
||||
```html
|
||||
<div
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
>
|
||||
<!-- content -->
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
>
|
||||
<!-- content -->
|
||||
</div>
|
||||
```
|
||||
|
||||
1. When using `v-for` with `template` and there is more than one child element, the `:key` values must be unique. It's advised to use `kebab-case` namespaces.
|
||||
|
||||
```html
|
||||
<template v-for="(item, index) in items">
|
||||
<span :key="`span-${index}`"></span>
|
||||
<button :key="`button-${index}`"></button>
|
||||
</template>
|
||||
<template v-for="(item, index) in items">
|
||||
<span :key="`span-${index}`"></span>
|
||||
<button :key="`button-${index}`"></button>
|
||||
</template>
|
||||
```
|
||||
|
||||
1. When dealing with nested `v-for` use the same guidelines as above.
|
||||
|
||||
```html
|
||||
<div
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
<div
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
>
|
||||
<span
|
||||
v-for="element in array"
|
||||
:key="element.id"
|
||||
>
|
||||
<span
|
||||
v-for="element in array"
|
||||
:key="element.id"
|
||||
>
|
||||
<!-- content -->
|
||||
</span>
|
||||
</div>
|
||||
<!-- content -->
|
||||
</span>
|
||||
</div>
|
||||
```
|
||||
|
||||
Useful links:
|
||||
|
@ -664,19 +664,19 @@ Useful links:
|
|||
1. Tooltips: Do not rely on `has-tooltip` class name for Vue components
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
<span
|
||||
class="has-tooltip"
|
||||
title="Some tooltip text">
|
||||
Text
|
||||
</span>
|
||||
// bad
|
||||
<span
|
||||
class="has-tooltip"
|
||||
title="Some tooltip text">
|
||||
Text
|
||||
</span>
|
||||
|
||||
// good
|
||||
<span
|
||||
v-tooltip
|
||||
title="Some tooltip text">
|
||||
Text
|
||||
</span>
|
||||
// good
|
||||
<span
|
||||
v-tooltip
|
||||
title="Some tooltip text">
|
||||
Text
|
||||
</span>
|
||||
```
|
||||
|
||||
1. Tooltips: When using a tooltip, include the tooltip directive, `./app/assets/javascripts/vue_shared/directives/tooltip.js`
|
||||
|
@ -684,13 +684,13 @@ Useful links:
|
|||
1. Don't change `data-original-title`.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
<span data-original-title="tooltip text">Foo</span>
|
||||
// bad
|
||||
<span data-original-title="tooltip text">Foo</span>
|
||||
|
||||
// good
|
||||
<span title="tooltip text">Foo</span>
|
||||
// good
|
||||
<span title="tooltip text">Foo</span>
|
||||
|
||||
$('span').tooltip('_fixTitle');
|
||||
$('span').tooltip('_fixTitle');
|
||||
```
|
||||
|
||||
### The Javascript/Vue Accord
|
||||
|
|
|
@ -313,7 +313,7 @@ export default {
|
|||
|
||||
1. Do not call a mutation directly. Always use an action to commit a mutation. Doing so will keep consistency throughout the application. From Vuex docs:
|
||||
|
||||
> why don't we just call store.commit('action') directly? Well, remember that mutations must be synchronous? Actions aren't. We can perform asynchronous operations inside an action.
|
||||
> Why don't we just call store.commit('action') directly? Well, remember that mutations must be synchronous? Actions aren't. We can perform asynchronous operations inside an action.
|
||||
|
||||
```javascript
|
||||
// component.vue
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Dirty Submit
|
||||
|
||||
> [Introduced][ce-21115] in GitLab 11.3.
|
||||
> [dirty_submit][dirty-submit]
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/21115) in GitLab 11.3.
|
||||
|
||||
## Summary
|
||||
|
||||
|
@ -9,6 +8,9 @@ Prevent submitting forms with no changes.
|
|||
|
||||
Currently handles `input`, `textarea` and `select` elements.
|
||||
|
||||
Also, see [the code](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/dirty_submit/)
|
||||
within the GitLab project.
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
|
@ -18,6 +20,3 @@ new DirtySubmitForm(document.querySelector('form'));
|
|||
// or
|
||||
new DirtySubmitForm(document.querySelectorAll('form'));
|
||||
```
|
||||
|
||||
[ce-21115]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/21115
|
||||
[dirty-submit]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/dirty_submit/
|
|
@ -192,4 +192,4 @@ rules only if you are invoking/instantiating existing code modules.
|
|||
- [class-method-use-this](http://eslint.org/docs/rules/class-methods-use-this)
|
||||
|
||||
> Note: Disable these rules on a per line basis. This makes it easier to refactor
|
||||
in the future. E.g. use `eslint-disable-next-line` or `eslint-disable-line`.
|
||||
> in the future. E.g. use `eslint-disable-next-line` or `eslint-disable-line`.
|
||||
|
|
|
@ -25,6 +25,7 @@ as much as possible. A language like Ruby or Python (if required for
|
|||
consistency with codebases that we leverage) is almost always a better choice.
|
||||
The high-level interpreted languages have more readable syntax, offer much more
|
||||
mature capabilities for unit-testing, linting, and error reporting.
|
||||
|
||||
Use shell scripts only if there's a strong restriction on project's
|
||||
dependencies size or any other requirements that are more important
|
||||
in a particular case.
|
||||
|
|
|
@ -255,8 +255,8 @@ that a machine will hit the "too many mount points" problem in the future.
|
|||
thousands of unused Docker images.**
|
||||
|
||||
> We have to start somewhere and improve later. Also, we're using the
|
||||
CNG-mirror project to store these Docker images so that we can just wipe out
|
||||
the registry at some point, and use a new fresh, empty one.
|
||||
> CNG-mirror project to store these Docker images so that we can just wipe out
|
||||
> the registry at some point, and use a new fresh, empty one.
|
||||
|
||||
**How do we secure this from abuse? Apps are open to the world so we need to
|
||||
find a way to limit it to only us.**
|
||||
|
|
|
@ -46,8 +46,7 @@ In `config/gitlab.yml`:
|
|||
|
||||
## Storing LFS objects in remote object storage
|
||||
|
||||
> [Introduced][ee-2760] in [GitLab Premium][eep] 10.0. Brought to GitLab Core
|
||||
in 10.7.
|
||||
> [Introduced][ee-2760] in [GitLab Premium][eep] 10.0. Brought to GitLab Core in 10.7.
|
||||
|
||||
It is possible to store LFS objects in remote object storage which allows you
|
||||
to offload local hard disk R/W operations, and free up disk space significantly.
|
||||
|
@ -91,7 +90,7 @@ Here is a configuration example with S3.
|
|||
| `aws_access_key_id` | AWS credentials, or compatible | `ABC123DEF456` |
|
||||
| `aws_secret_access_key` | AWS credentials, or compatible | `ABC123DEF456ABC123DEF456ABC123DEF456` |
|
||||
| `aws_signature_version` | AWS signature version to use. 2 or 4 are valid options. Digital Ocean Spaces and other providers may need 2. | 4 |
|
||||
| `enable_signature_v4_streaming` | Set to true to enable HTTP chunked transfers with AWS v4 signatures (https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html). Oracle Cloud S3 needs this to be false | true
|
||||
| `enable_signature_v4_streaming` | Set to true to enable HTTP chunked transfers with [AWS v4 signatures](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html). Oracle Cloud S3 needs this to be false | true |
|
||||
| `region` | AWS region | us-east-1 |
|
||||
| `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com |
|
||||
| `endpoint` | Can be used when configuring an S3 compatible service such as [Minio](https://www.minio.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) |
|
||||
|
@ -107,7 +106,9 @@ Here is a configuration example with GCS.
|
|||
| `google_client_email` | The email address of the service account | `foo@gcp-project-12345.iam.gserviceaccount.com` |
|
||||
| `google_json_key_location` | The json key path | `/path/to/gcp-project-12345-abcde.json` |
|
||||
|
||||
_NOTE: The service account must have permission to access the bucket. [See more](https://cloud.google.com/storage/docs/authentication)_
|
||||
NOTE: **Note:**
|
||||
The service account must have permission to access the bucket.
|
||||
[See more](https://cloud.google.com/storage/docs/authentication)
|
||||
|
||||
Here is a configuration example with Rackspace Cloud Files.
|
||||
|
||||
|
@ -119,7 +120,13 @@ Here is a configuration example with Rackspace Cloud Files.
|
|||
| `rackspace_region` | The Rackspace storage region to use, a three letter code from the [list of service access endpoints](https://developer.rackspace.com/docs/cloud-files/v1/general-api-info/service-access/) | `iad` |
|
||||
| `rackspace_temp_url_key` | The private key you have set in the Rackspace API for temporary URLs. Read more [here](https://developer.rackspace.com/docs/cloud-files/v1/use-cases/public-access-to-your-cloud-files-account/#tempurl) | `ABC123DEF456ABC123DEF456ABC123DE` |
|
||||
|
||||
_NOTES: Regardless of whether the container has public access enabled or disabled, Fog will use the TempURL method to grant access to LFS objects. If you see errors in logs referencing instantiating storage with a temp-url-key, ensure that you have set they key properly on the Rackspace API and in gitlab.rb. You can verify the value of the key Rackspace has set by sending a GET request with token header to the service access endpoint URL and comparing the output of the returned headers._
|
||||
NOTE: **Note:**
|
||||
Regardless of whether the container has public access enabled or disabled, Fog will
|
||||
use the TempURL method to grant access to LFS objects. If you see errors in logs referencing
|
||||
instantiating storage with a temp-url-key, ensure that you have set they key properly
|
||||
on the Rackspace API and in gitlab.rb. You can verify the value of the key Rackspace
|
||||
has set by sending a GET request with token header to the service access endpoint URL
|
||||
and comparing the output of the returned headers.
|
||||
|
||||
### Manual uploading to an object storage
|
||||
|
||||
|
@ -167,13 +174,13 @@ On Omnibus installations, the settings are prefixed by `lfs_object_store_`:
|
|||
1. Save the file and [reconfigure GitLab]s for the changes to take effect.
|
||||
1. Migrate any existing local LFS objects to the object storage:
|
||||
|
||||
```bash
|
||||
gitlab-rake gitlab:lfs:migrate
|
||||
```
|
||||
```bash
|
||||
gitlab-rake gitlab:lfs:migrate
|
||||
```
|
||||
|
||||
This will migrate existing LFS objects to object storage. New LFS objects
|
||||
will be forwarded to object storage unless
|
||||
`gitlab_rails['lfs_object_store_background_upload']` is set to false.
|
||||
This will migrate existing LFS objects to object storage. New LFS objects
|
||||
will be forwarded to object storage unless
|
||||
`gitlab_rails['lfs_object_store_background_upload']` is set to false.
|
||||
|
||||
### S3 for installations from source
|
||||
|
||||
|
@ -203,13 +210,13 @@ For source installations the settings are nested under `lfs:` and then
|
|||
1. Save the file and [restart GitLab][] for the changes to take effect.
|
||||
1. Migrate any existing local LFS objects to the object storage:
|
||||
|
||||
```bash
|
||||
sudo -u git -H bundle exec rake gitlab:lfs:migrate RAILS_ENV=production
|
||||
```
|
||||
```bash
|
||||
sudo -u git -H bundle exec rake gitlab:lfs:migrate RAILS_ENV=production
|
||||
```
|
||||
|
||||
This will migrate existing LFS objects to object storage. New LFS objects
|
||||
will be forwarded to object storage unless `background_upload` is set to
|
||||
false.
|
||||
This will migrate existing LFS objects to object storage. New LFS objects
|
||||
will be forwarded to object storage unless `background_upload` is set to
|
||||
false.
|
||||
|
||||
## Storage statistics
|
||||
|
||||
|
|
|
@ -35,9 +35,10 @@ Documentation for GitLab instance administrators is under [LFS administration do
|
|||
- Git LFS always assumes HTTPS so if you have GitLab server on HTTP you will have
|
||||
to add the URL to Git config manually (see [troubleshooting](#troubleshooting))
|
||||
|
||||
>**Note**: With 8.12 GitLab added LFS support to SSH. The Git LFS communication
|
||||
still goes over HTTP, but now the SSH client passes the correct credentials
|
||||
to the Git LFS client, so no action is required by the user.
|
||||
NOTE: **Note:**
|
||||
With 8.12 GitLab added LFS support to SSH. The Git LFS communication
|
||||
still goes over HTTP, but now the SSH client passes the correct credentials
|
||||
to the Git LFS client, so no action is required by the user.
|
||||
|
||||
## Using Git LFS
|
||||
|
||||
|
@ -61,12 +62,13 @@ git commit -am "Added Debian iso" # commit the file meta data
|
|||
git push origin master # sync the git repo and large file to the GitLab server
|
||||
```
|
||||
|
||||
> **Note**: Make sure that `.gitattributes` is tracked by git. Otherwise Git
|
||||
> LFS will not be working properly for people cloning the project.
|
||||
>
|
||||
> ```bash
|
||||
> git add .gitattributes
|
||||
> ```
|
||||
NOTE: **Note:**
|
||||
**Make sure** that `.gitattributes` is tracked by Git. Otherwise Git
|
||||
LFS will not be working properly for people cloning the project.
|
||||
|
||||
```bash
|
||||
git add .gitattributes
|
||||
```
|
||||
|
||||
Cloning the repository works the same as before. Git automatically detects the
|
||||
LFS-tracked files and clones them via HTTP. If you performed the git clone
|
||||
|
@ -216,9 +218,10 @@ git config --add lfs.url "http://gitlab.example.com/group/project.git/info/lfs"
|
|||
|
||||
### Credentials are always required when pushing an object
|
||||
|
||||
>**Note**: With 8.12 GitLab added LFS support to SSH. The Git LFS communication
|
||||
still goes over HTTP, but now the SSH client passes the correct credentials
|
||||
to the Git LFS client, so no action is required by the user.
|
||||
NOTE: **Note:**
|
||||
With 8.12 GitLab added LFS support to SSH. The Git LFS communication
|
||||
still goes over HTTP, but now the SSH client passes the correct credentials
|
||||
to the Git LFS client, so no action is required by the user.
|
||||
|
||||
Given that Git LFS uses HTTP Basic Authentication to authenticate the user pushing
|
||||
the LFS object on every push for every object, user HTTPS credentials are required.
|
||||
|
|
|
@ -76,7 +76,7 @@ Here you'll find a guide on
|
|||
Since Annex files are stored as objects with symlinks and cannot be directly
|
||||
modified, we need to first remove those symlinks.
|
||||
|
||||
>**Note:**
|
||||
NOTE: **Note:**
|
||||
Make sure the you read about the [`direct` mode][annex-direct] as it contains
|
||||
useful information that may fit in your use case. Note that `annex direct` is
|
||||
deprecated in Git Annex version 6, so you may need to upgrade your repository
|
||||
|
|
|
@ -37,8 +37,7 @@ The following are some possible use cases for repository mirroring:
|
|||
|
||||
## Pushing to a remote repository **(CORE)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/249) in GitLab Enterprise
|
||||
> Edition 8.7. [Moved to GitLab Core](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18715) in 10.8.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/249) in GitLab Enterprise Edition 8.7. [Moved to GitLab Core](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18715) in 10.8.
|
||||
|
||||
For an existing project, you can set up push mirroring as follows:
|
||||
|
||||
|
@ -67,8 +66,7 @@ section.
|
|||
|
||||
### Push only protected branches **(CORE)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3350) in
|
||||
> [GitLab Starter](https://about.gitlab.com/pricing/) 10.3. [Moved to GitLab Core](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18715) in 10.8.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3350) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3. [Moved to GitLab Core](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18715) in 10.8.
|
||||
|
||||
You can choose to only push your protected branches from GitLab to your remote repository.
|
||||
|
||||
|
@ -98,8 +96,7 @@ The repository will push soon. To force a push, click the appropriate button.
|
|||
|
||||
## Pulling from a remote repository **(STARTER)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/51) in GitLab Enterprise Edition 8.2.
|
||||
> [Added Git LFS support](https://gitlab.com/gitlab-org/gitlab-ee/issues/10871) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.11.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/51) in GitLab Enterprise Edition 8.2. [Added Git LFS support](https://gitlab.com/gitlab-org/gitlab-ee/issues/10871) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.11.
|
||||
|
||||
NOTE: **Note:** This feature [is available for free](https://gitlab.com/gitlab-org/gitlab-ee/issues/10361) to
|
||||
GitLab.com users until September 22nd, 2019.
|
||||
|
@ -157,8 +154,7 @@ Repository mirrors are updated as Sidekiq becomes available to process them. If
|
|||
|
||||
### SSH authentication
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2551) for Pull mirroring in [GitLab Starter](https://about.gitlab.com/pricing/) 9.5.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22982) for Push mirroring in [GitLab Core](https://about.gitlab.com/pricing/) 11.6
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2551) for Pull mirroring in [GitLab Starter](https://about.gitlab.com/pricing/) 9.5. [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22982) for Push mirroring in [GitLab Core](https://about.gitlab.com/pricing/) 11.6
|
||||
|
||||
SSH authentication is mutual:
|
||||
|
||||
|
@ -245,8 +241,7 @@ key to keep the mirror running.
|
|||
|
||||
### Overwrite diverged branches **(STARTER)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/4559) in
|
||||
> [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/4559) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
|
||||
|
||||
You can choose to always update your local branches with remote versions, even if they have
|
||||
diverged from the remote.
|
||||
|
@ -258,8 +253,7 @@ To use this option, check the **Overwrite diverged branches** box when creating
|
|||
|
||||
### Only mirror protected branches **(STARTER)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3326) in
|
||||
> [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3326) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
|
||||
|
||||
You can choose to pull mirror only the protected branches from your remote repository to GitLab.
|
||||
Non-protected branches are not mirrored and can diverge.
|
||||
|
@ -268,8 +262,7 @@ To use this option, check the **Only mirror protected branches** box when creati
|
|||
|
||||
### Hard failure **(STARTER)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3117) in
|
||||
> [GitLab Starter](https://about.gitlab.com/pricing/) 10.2.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3117) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.2.
|
||||
|
||||
Once the mirroring process is unsuccessfully retried 14 times in a row, it will get marked as hard
|
||||
failed. This will become visible in either the:
|
||||
|
@ -282,8 +275,7 @@ project mirroring again by [Forcing an update](#forcing-an-update-core).
|
|||
|
||||
### Trigger update using API **(STARTER)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3453) in
|
||||
[GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3453) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
|
||||
|
||||
Pull mirroring uses polling to detect new branches and commits added upstream, often minutes
|
||||
afterwards. If you notify GitLab by [API](../api/projects.md#start-the-pull-mirroring-process-for-a-project-starter),
|
||||
|
@ -325,9 +317,10 @@ protected branches.
|
|||
|
||||
### Preventing conflicts using a `pre-receive` hook
|
||||
|
||||
> **Warning:** The solution proposed will negatively impact the performance of
|
||||
> Git push operations because they will be proxied to the upstream Git
|
||||
> repository.
|
||||
CAUTION: **Warning:**
|
||||
The solution proposed will negatively impact the performance of
|
||||
Git push operations because they will be proxied to the upstream Git
|
||||
repository.
|
||||
|
||||
A server-side `pre-receive` hook can be used to prevent the race condition
|
||||
described above by only accepting the push after first pushing the commit to
|
||||
|
|
Loading…
Reference in a new issue