Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-07 12:09:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-07 12:09:51 +0300
commitd8803c7e40bd35d883ef007ddc56907bd837a748 (patch)
treee65de9306d46d111222b03ef29aafbe57adf86ac /doc
parentb6a92c969b16549683ef276f1db7ba9a41dc85bb (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'doc')
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql42
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json104
-rw-r--r--doc/development/README.md1
-rw-r--r--doc/development/fe_guide/vue.md2
-rw-r--r--doc/development/fe_guide/vuex.md79
-rw-r--r--doc/development/multi_version_compatibility.md62
-rw-r--r--doc/development/pipelines.md3
7 files changed, 247 insertions, 46 deletions
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index c483743a303..9f08e8ebf58 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -4157,6 +4157,11 @@ type Group {
first: Int
"""
+ Returns only the projects which have vulnerabilities
+ """
+ hasVulnerabilities: Boolean = false
+
+ """
Include also subgroup projects
"""
includeSubgroups: Boolean = false
@@ -4319,6 +4324,33 @@ enum HealthStatus {
onTrack
}
+type InstanceSecurityDashboard {
+ """
+ Projects selected in Instance Security Dashboard
+ """
+ projects(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): ProjectConnection!
+}
+
"""
State of a GitLab issue or merge request
"""
@@ -6295,6 +6327,11 @@ type Namespace {
first: Int
"""
+ Returns only the projects which have vulnerabilities
+ """
+ hasVulnerabilities: Boolean = false
+
+ """
Include also subgroup projects
"""
includeSubgroups: Boolean = false
@@ -8022,6 +8059,11 @@ type Query {
): Group
"""
+ Fields related to Instance Security Dashboard
+ """
+ instanceSecurityDashboard: InstanceSecurityDashboard
+
+ """
Metadata about GitLab
"""
metadata: Metadata
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 661a7cec50c..1b6d719acd6 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -11539,6 +11539,16 @@
"defaultValue": "false"
},
{
+ "name": "hasVulnerabilities",
+ "description": "Returns only the projects which have vulnerabilities",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "defaultValue": "false"
+ },
+ {
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
@@ -12026,6 +12036,76 @@
"possibleTypes": null
},
{
+ "kind": "OBJECT",
+ "name": "InstanceSecurityDashboard",
+ "description": null,
+ "fields": [
+ {
+ "name": "projects",
+ "description": "Projects selected in Instance Security Dashboard",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ProjectConnection",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "SCALAR",
"name": "Int",
"description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
@@ -18704,6 +18784,16 @@
"defaultValue": "false"
},
{
+ "name": "hasVulnerabilities",
+ "description": "Returns only the projects which have vulnerabilities",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "defaultValue": "false"
+ },
+ {
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
@@ -23716,6 +23806,20 @@
"deprecationReason": null
},
{
+ "name": "instanceSecurityDashboard",
+ "description": "Fields related to Instance Security Dashboard",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "InstanceSecurityDashboard",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "metadata",
"description": "Metadata about GitLab",
"args": [
diff --git a/doc/development/README.md b/doc/development/README.md
index 0dd00525e0c..22644b77c06 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -218,6 +218,7 @@ Complementary reads:
- [Defining relations between files using projections](projections.md)
- [Reference processing](./reference_processing.md)
+- [Compatibility with multiple versions of the application running at the same time](multi_version_compatibility.md)
## Other GitLab Development Kit (GDK) guides
diff --git a/doc/development/fe_guide/vue.md b/doc/development/fe_guide/vue.md
index 83871f5c98e..ce5e14bfe87 100644
--- a/doc/development/fe_guide/vue.md
+++ b/doc/development/fe_guide/vue.md
@@ -321,7 +321,7 @@ One should apply to be a Vue.js expert by opening an MR when the Merge Request's
- Deep understanding of Vue and Vuex reactivity
- Vue and Vuex code are structured according to both official and our guidelines
- Full understanding of testing a Vue and Vuex application
-- Vuex code follows the [documented pattern](vuex.md#actions-pattern-request-and-receive-namespaces)
+- Vuex code follows the [documented pattern](vuex.md#naming-pattern-request-and-receive-namespaces)
- Knowledge about the existing Vue and Vuex applications and existing reusable components
## Vue 2 -> Vue 3 Migration
diff --git a/doc/development/fe_guide/vuex.md b/doc/development/fe_guide/vuex.md
index ea59c3c7a2b..e7be67b8da5 100644
--- a/doc/development/fe_guide/vuex.md
+++ b/doc/development/fe_guide/vuex.md
@@ -86,71 +86,35 @@ You can use `mapState` to access state properties in the components.
An action is a payload of information to send data from our application to our store.
-An action is usually composed by a `type` and a `payload` and they describe what happened.
-Enforcing that every change is described as an action lets us have a clear understanding of what is going on in the app.
+An action is usually composed by a `type` and a `payload` and they describe what happened. Unlike [mutations](#mutationsjs), actions can contain asynchronous operations - that's why we always need to handle asynchronous logic in actions.
-In this file, we will write the actions that will call the respective mutations:
+In this file, we will write the actions that will call mutations for handling a list of users:
```javascript
import * as types from './mutation_types';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
- export const requestUsers = ({ commit }) => commit(types.REQUEST_USERS);
- export const receiveUsersSuccess = ({ commit }, data) => commit(types.RECEIVE_USERS_SUCCESS, data);
- export const receiveUsersError = ({ commit }, error) => commit(types.RECEIVE_USERS_ERROR, error);
-
export const fetchUsers = ({ state, dispatch }) => {
- dispatch('requestUsers');
+ commit(types.REQUEST_USERS);
axios.get(state.endpoint)
- .then(({ data }) => dispatch('receiveUsersSuccess', data))
+ .then(({ data }) => commit(types.RECEIVE_USERS_SUCCESS, data))
.catch((error) => {
- dispatch('receiveUsersError', error)
+ commit(types.RECEIVE_USERS_ERROR, error)
createFlash('There was an error')
});
}
- export const requestAddUser = ({ commit }) => commit(types.REQUEST_ADD_USER);
- export const receiveAddUserSuccess = ({ commit }, data) => commit(types.RECEIVE_ADD_USER_SUCCESS, data);
- export const receiveAddUserError = ({ commit }, error) => commit(types.REQUEST_ADD_USER_ERROR, error);
-
export const addUser = ({ state, dispatch }, user) => {
- dispatch('requestAddUser');
+ commit(types.REQUEST_ADD_USER);
axios.post(state.endpoint, user)
- .then(({ data }) => dispatch('receiveAddUserSuccess', data))
- .catch((error) => dispatch('receiveAddUserError', error));
+ .then(({ data }) => commit(types.RECEIVE_ADD_USER_SUCCESS, data))
+ .catch((error) => commit(types.REQUEST_ADD_USER_ERROR, error));
}
```
-#### Actions Pattern: `request` and `receive` namespaces
-
-When a request is made we often want to show a loading state to the user.
-
-Instead of creating an action to toggle the loading state and dispatch it in the component,
-create:
-
-1. An action `requestSomething`, to toggle the loading state
-1. An action `receiveSomethingSuccess`, to handle the success callback
-1. An action `receiveSomethingError`, to handle the error callback
-1. An action `fetchSomething` to make the request.
- 1. In case your application does more than a `GET` request you can use these as examples:
- - `POST`: `createSomething`
- - `PUT`: `updateSomething`
- - `DELETE`: `deleteSomething`
-
-The component MUST only dispatch the `fetchNamespace` action. Actions namespaced with `request` or `receive` should not be called from the component
-The `fetch` action will be responsible to dispatch `requestNamespace`, `receiveNamespaceSuccess` and `receiveNamespaceError`
-
-By following this pattern we guarantee:
-
-1. All applications follow the same pattern, making it easier for anyone to maintain the code
-1. All data in the application follows the same lifecycle pattern
-1. Actions are contained and human friendly
-1. Unit tests are easier
-1. Actions are simple and straightforward
-
#### Dispatching actions
To dispatch an action from a component, use the `mapActions` helper:
@@ -181,6 +145,8 @@ Remember that actions only describe that something happened, they don't describe
**Never commit a mutation directly from a component**
+Instead, you should create an action that will commit a mutation.
+
```javascript
import * as types from './mutation_types';
@@ -210,6 +176,31 @@ Remember that actions only describe that something happened, they don't describe
};
```
+#### Naming Pattern: `REQUEST` and `RECEIVE` namespaces
+
+When a request is made we often want to show a loading state to the user.
+
+Instead of creating an mutation to toggle the loading state, we should:
+
+1. A mutation with type `REQUEST_SOMETHING`, to toggle the loading state
+1. A mutation with type `RECEIVE_SOMETHING_SUCCESS`, to handle the success callback
+1. A mutation with type `RECEIVE_SOMETHING_ERROR`, to handle the error callback
+1. An action `fetchSomething` to make the request and commit mutations on mentioned cases
+ 1. In case your application does more than a `GET` request you can use these as examples:
+ - `POST`: `createSomething`
+ - `PUT`: `updateSomething`
+ - `DELETE`: `deleteSomething`
+
+As a result, we can dispatch the `fetchNamespace` action from the component and it will be responsible to commit `REQUEST_NAMESPACE`, `RECEIVE_NAMESPACE_SUCCESS` and `RECEIVE_NAMESPACE_ERROR` mutations.
+
+> Previously, we were dispatching actions from the `fetchNamespace` action instead of committing mutation, so please don't be confused if you find a different pattern in the older parts of the codebase. However, we encourage leveraging a new pattern whenever you write new Vuex stores
+
+By following this pattern we guarantee:
+
+1. All applications follow the same pattern, making it easier for anyone to maintain the code
+1. All data in the application follows the same lifecycle pattern
+1. Unit tests are easier
+
### `getters.js`
Sometimes we may need to get derived state based on store state, like filtering for a specific prop.
diff --git a/doc/development/multi_version_compatibility.md b/doc/development/multi_version_compatibility.md
new file mode 100644
index 00000000000..aedd5c1ffb7
--- /dev/null
+++ b/doc/development/multi_version_compatibility.md
@@ -0,0 +1,62 @@
+# Compatibility with multiple versions of the application running at the same time
+
+When adding or changing features, we must be aware that there may be multiple versions of the application running
+at the same time and connected to the same PostgreSQL and Redis databases. This could happen during a rolling deploy
+when the servers are updated one by one.
+
+During a rolling deploy, post-deployment DB migrations are run after all the servers have been updated. This means the
+servers could be in these intermediate states:
+
+1. Old application code running with new DB migrations already executed
+1. New application code running with new DB migrations but without new post-deployment DB migrations
+
+We must make sure that the application works properly in these states.
+
+For GitLab.com, we also run a set of canary servers which run a more recent version of the application. Users with
+the canary cookie set would be handled by these servers. Some URL patterns may also be forced to the canary servers,
+even without the cookie being set. This also means that some pages may match the pattern and get handled by canary servers,
+but AJAX requests to URLs (like the GraphQL endpoint) won't match the pattern.
+
+With this canary setup, we'd be in this mixed-versions state for an extended period of time until canary is promoted to
+production and post-deployment migrations run.
+
+## Examples of previous incidents
+
+### Some links to issues and MRs were broken
+
+When we moved MR routes, users on the new servers were redirected to the new URLs. When these users shared these new URLs in
+Markdown (or anywhere else), they were broken links for users on the old servers.
+
+For more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/118840).
+
+### Stale cache in issue or merge request descriptions and comments
+
+We bumped the Markdown cache version and found a bug when a user edited a description or comment which was generated from a different Markdown
+cache version. The cached HTML wasn't generated properly after saving. In most cases, this wouldn't have happened because users would have
+viewed the Markdown before clicking **Edit** and that would mean the Markdown cache is refreshed. But because we run mixed versions, this is
+more likely to happen. Another user on a different version could view the same page and refresh the cache to the other version behind the scenes.
+
+For more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/208255).
+
+### Project service templates incorrectly copied
+
+We changed the column which indicates whether a service is a template. When we create services, we copy attributes from the template
+and set this column to `false`. The old servers were still updating the old column, but that was fine because we had a DB trigger
+that updated the new column from the old one. For the new servers though, they were only updating the new column and that same trigger
+was now working against us and setting it back to the wrong value.
+
+For more information, see [the relevant issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/9176).
+
+### Sidebar wasn't loading for some users
+
+We changed the data type of one GraphQL field. When a user opened an issue page from the new servers and the GraphQL AJAX request went
+to the old servers, a type mismatch happened, which resulted in a JavaScript error that prevented the sidebar from loading.
+
+For more information, see [the relevant issue](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/1772).
+
+### CI artifact uploads were failing
+
+We added a `NOT NULL` constraint to a column and marked it as a `NOT VALID` constraint so that it is not enforced on existing rows.
+But even with that, this was still a problem because the old servers were still inserting new rows with null values.
+
+For more information, see [the relevant issue](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/1944).
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index 701262dbf1f..d15ac8d5320 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -132,6 +132,7 @@ and included in `rules` definitions via [YAML anchors](../ci/yaml/README.md#anch
| `changes:` patterns | Description |
|------------------------------|--------------------------------------------------------------------------|
+| `ci-patterns` | Only create job for CI config-related changes. |
| `yaml-patterns` | Only create job for YAML-related changes. |
| `docs-patterns` | Only create job for docs-related changes. |
| `frontend-dependency-patterns` | Only create job when frontend dependencies are updated (i.e. `package.json`, and `yarn.lock`). changes. |
@@ -384,7 +385,7 @@ graph RL;
subgraph "Needs `gitlab:assets:compile`";
2_3-1 --> 1-5
end
-
+
subgraph "Needs `build-qa-image` & `build-assets-image`";
2_4-1["package-and-qa (manual)"] --> 1-2 & 2_3-1;
click 2_4-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914305&udv=0"