summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-10 06:09:41 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-10 06:09:41 +0000
commit187ee320b39af22929d74c5a2d9b0650bf50a09b (patch)
treeff04eab6c7914f6408c4f637f863fc07aa409cdc
parenta7dc052b7e01aee680d130274c79da9bfa459272 (diff)
downloadgitlab-ce-187ee320b39af22929d74c5a2d9b0650bf50a09b.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/reports/components/summary_row.vue16
-rw-r--r--app/assets/javascripts/static_site_editor/components/publish_toolbar.vue15
-rw-r--r--app/assets/javascripts/static_site_editor/components/static_site_editor.vue10
-rw-r--r--app/assets/javascripts/static_site_editor/index.js2
-rw-r--r--app/assets/javascripts/static_site_editor/services/submit_content_changes.js4
-rw-r--r--app/assets/javascripts/static_site_editor/store/actions.js12
-rw-r--r--app/assets/javascripts/static_site_editor/store/mutation_types.js3
-rw-r--r--app/assets/javascripts/static_site_editor/store/mutations.js11
-rw-r--r--app/assets/javascripts/static_site_editor/store/state.js1
-rw-r--r--changelogs/unreleased/update-docker-to-19-03-8-in-auto-devops.yml5
-rw-r--r--doc/README.md2
-rw-r--r--doc/api/groups.md10
-rw-r--r--doc/ci/jenkins/index.md2
-rw-r--r--doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md2
-rw-r--r--doc/ci/multi_project_pipelines.md2
-rw-r--r--doc/ci/pipelines/img/job_group_v12_10.pngbin0 -> 21609 bytes
-rw-r--r--doc/ci/pipelines/index.md616
-rw-r--r--doc/ci/variables/README.md4
-rw-r--r--doc/topics/autodevops/customize.md2
-rw-r--r--doc/user/permissions.md2
-rw-r--r--doc/user/project/index.md2
-rw-r--r--doc/user/project/merge_requests/index.md2
-rw-r--r--doc/user/project/protected_branches.md2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml4
-rw-r--r--locale/gitlab.pot8
-rw-r--r--spec/frontend/static_site_editor/components/publish_toolbar_spec.js29
-rw-r--r--spec/frontend/static_site_editor/components/static_site_editor_spec.js30
-rw-r--r--spec/frontend/static_site_editor/mock_data.js18
-rw-r--r--spec/frontend/static_site_editor/store/actions_spec.js60
-rw-r--r--spec/frontend/static_site_editor/store/mutations_spec.js85
32 files changed, 576 insertions, 393 deletions
diff --git a/app/assets/javascripts/reports/components/summary_row.vue b/app/assets/javascripts/reports/components/summary_row.vue
index 1191e43d0d9..9cbe2a690a0 100644
--- a/app/assets/javascripts/reports/components/summary_row.vue
+++ b/app/assets/javascripts/reports/components/summary_row.vue
@@ -53,11 +53,19 @@ export default {
/>
<ci-icon v-else :status="iconStatus" :size="24" />
</div>
-
<div class="report-block-list-issue-description">
- <div class="report-block-list-issue-description-text">{{ summary }}</div>
-
- <popover v-if="popoverOptions" :options="popoverOptions" />
+ <div class="report-block-list-issue-description-text">
+ {{ summary
+ }}<span v-if="popoverOptions" class="text-nowrap"
+ >&nbsp;<popover v-if="popoverOptions" :options="popoverOptions" class="align-top" />
+ </span>
+ </div>
+ </div>
+ <div
+ v-if="$slots.default"
+ class="text-right flex-fill d-flex justify-content-end flex-column flex-sm-row"
+ >
+ <slot></slot>
</div>
</div>
</template>
diff --git a/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue b/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue
index 83b50b2f8eb..7f00fb71b04 100644
--- a/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue
+++ b/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue
@@ -1,9 +1,10 @@
<script>
-import { GlNewButton } from '@gitlab/ui';
+import { GlNewButton, GlLoadingIcon } from '@gitlab/ui';
export default {
components: {
GlNewButton,
+ GlLoadingIcon,
},
props: {
saveable: {
@@ -11,12 +12,22 @@ export default {
required: false,
default: false,
},
+ savingChanges: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
};
</script>
<template>
<div class="d-flex bg-light border-top justify-content-between align-items-center py-3 px-4">
- <gl-new-button variant="success" :disabled="!saveable">
+ <gl-loading-icon :class="{ invisible: !savingChanges }" size="md" />
+ <gl-new-button
+ variant="success"
+ :disabled="!saveable || savingChanges"
+ @click="$emit('submit')"
+ >
{{ __('Submit Changes') }}
</gl-new-button>
</div>
diff --git a/app/assets/javascripts/static_site_editor/components/static_site_editor.vue b/app/assets/javascripts/static_site_editor/components/static_site_editor.vue
index 80a55d5ee11..e711510ba44 100644
--- a/app/assets/javascripts/static_site_editor/components/static_site_editor.vue
+++ b/app/assets/javascripts/static_site_editor/components/static_site_editor.vue
@@ -12,14 +12,14 @@ export default {
Toolbar,
},
computed: {
- ...mapState(['content', 'isLoadingContent']),
+ ...mapState(['content', 'isLoadingContent', 'isSavingChanges']),
...mapGetters(['isContentLoaded', 'contentChanged']),
},
mounted() {
this.loadContent();
},
methods: {
- ...mapActions(['loadContent', 'setContent']),
+ ...mapActions(['loadContent', 'setContent', 'submitChanges']),
},
};
</script>
@@ -41,7 +41,11 @@ export default {
:value="content"
@input="setContent"
/>
- <toolbar :saveable="contentChanged" />
+ <toolbar
+ :saveable="contentChanged"
+ :saving-changes="isSavingChanges"
+ @submit="submitChanges"
+ />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/static_site_editor/index.js b/app/assets/javascripts/static_site_editor/index.js
index 22f96a60df0..3d40f3918a4 100644
--- a/app/assets/javascripts/static_site_editor/index.js
+++ b/app/assets/javascripts/static_site_editor/index.js
@@ -6,7 +6,7 @@ const initStaticSiteEditor = el => {
const { projectId, path: sourcePath } = el.dataset;
const store = createStore({
- initialState: { projectId, sourcePath },
+ initialState: { projectId, sourcePath, username: window.gon.current_username },
});
return new Vue({
diff --git a/app/assets/javascripts/static_site_editor/services/submit_content_changes.js b/app/assets/javascripts/static_site_editor/services/submit_content_changes.js
new file mode 100644
index 00000000000..6b0d8c74ff7
--- /dev/null
+++ b/app/assets/javascripts/static_site_editor/services/submit_content_changes.js
@@ -0,0 +1,4 @@
+// TODO implement
+const submitContentChanges = () => new Promise(resolve => setTimeout(resolve, 1000));
+
+export default submitContentChanges;
diff --git a/app/assets/javascripts/static_site_editor/store/actions.js b/app/assets/javascripts/static_site_editor/store/actions.js
index 141148de1e0..c57ef86f6ef 100644
--- a/app/assets/javascripts/static_site_editor/store/actions.js
+++ b/app/assets/javascripts/static_site_editor/store/actions.js
@@ -3,6 +3,7 @@ import { __ } from '~/locale';
import * as mutationTypes from './mutation_types';
import loadSourceContent from '~/static_site_editor/services/load_source_content';
+import submitContentChanges from '~/static_site_editor/services/submit_content_changes';
export const loadContent = ({ commit, state: { sourcePath, projectId } }) => {
commit(mutationTypes.LOAD_CONTENT);
@@ -19,4 +20,15 @@ export const setContent = ({ commit }, content) => {
commit(mutationTypes.SET_CONTENT, content);
};
+export const submitChanges = ({ state: { projectId, content, sourcePath, username }, commit }) => {
+ commit(mutationTypes.SUBMIT_CHANGES);
+
+ return submitContentChanges({ content, projectId, sourcePath, username })
+ .then(data => commit(mutationTypes.SUBMIT_CHANGES_SUCCESS, data))
+ .catch(error => {
+ commit(mutationTypes.SUBMIT_CHANGES_ERROR);
+ createFlash(error.message);
+ });
+};
+
export default () => {};
diff --git a/app/assets/javascripts/static_site_editor/store/mutation_types.js b/app/assets/javascripts/static_site_editor/store/mutation_types.js
index 2bb201f5d24..35eb35ebbe9 100644
--- a/app/assets/javascripts/static_site_editor/store/mutation_types.js
+++ b/app/assets/javascripts/static_site_editor/store/mutation_types.js
@@ -2,3 +2,6 @@ export const LOAD_CONTENT = 'loadContent';
export const RECEIVE_CONTENT_SUCCESS = 'receiveContentSuccess';
export const RECEIVE_CONTENT_ERROR = 'receiveContentError';
export const SET_CONTENT = 'setContent';
+export const SUBMIT_CHANGES = 'submitChanges';
+export const SUBMIT_CHANGES_SUCCESS = 'submitChangesSuccess';
+export const SUBMIT_CHANGES_ERROR = 'submitChangesError';
diff --git a/app/assets/javascripts/static_site_editor/store/mutations.js b/app/assets/javascripts/static_site_editor/store/mutations.js
index 8b8bacf35c2..f98177bbc18 100644
--- a/app/assets/javascripts/static_site_editor/store/mutations.js
+++ b/app/assets/javascripts/static_site_editor/store/mutations.js
@@ -16,4 +16,15 @@ export default {
[types.SET_CONTENT](state, content) {
state.content = content;
},
+ [types.SUBMIT_CHANGES](state) {
+ state.isSavingChanges = true;
+ },
+ [types.SUBMIT_CHANGES_SUCCESS](state, meta) {
+ state.savedContentMeta = meta;
+ state.isSavingChanges = false;
+ state.originalContent = state.content;
+ },
+ [types.SUBMIT_CHANGES_ERROR](state) {
+ state.isSavingChanges = false;
+ },
};
diff --git a/app/assets/javascripts/static_site_editor/store/state.js b/app/assets/javascripts/static_site_editor/store/state.js
index 1ae11b3343d..e457fde591a 100644
--- a/app/assets/javascripts/static_site_editor/store/state.js
+++ b/app/assets/javascripts/static_site_editor/store/state.js
@@ -1,4 +1,5 @@
const createState = (initialState = {}) => ({
+ username: null,
projectId: null,
sourcePath: null,
diff --git a/changelogs/unreleased/update-docker-to-19-03-8-in-auto-devops.yml b/changelogs/unreleased/update-docker-to-19-03-8-in-auto-devops.yml
new file mode 100644
index 00000000000..ec173c5f76d
--- /dev/null
+++ b/changelogs/unreleased/update-docker-to-19-03-8-in-auto-devops.yml
@@ -0,0 +1,5 @@
+---
+title: Update Auto DevOps docker version to 19.03.8
+merge_request: 29081
+author:
+type: changed
diff --git a/doc/README.md b/doc/README.md
index bcb3140887d..6b863436ce2 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -238,7 +238,7 @@ The following documentation relates to the DevOps **Verify** stage:
| [GitLab CI/CD](ci/README.md) | Explore the features and capabilities of Continuous Integration with GitLab. |
| [JUnit test reports](ci/junit_test_reports.md) | Display JUnit test reports on merge requests. |
| [Multi-project pipelines](ci/multi_project_pipelines.md) **(PREMIUM)** | Visualize entire pipelines that span multiple projects, including all cross-project inter-dependencies. |
-| [Pipeline Graphs](ci/pipelines/index.md#visualizing-pipelines) | Visualize builds. |
+| [Pipeline Graphs](ci/pipelines/index.md#visualize-pipelines) | Visualize builds. |
| [Review Apps](ci/review_apps/index.md) | Preview changes to your application right from a merge request. |
<div align="right">
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 33a3c2305d5..1809ddfa47f 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -240,6 +240,10 @@ Example response:
]
```
+NOTE: **Note:**
+
+To distinguish between a project in the group and a project shared to the group, the `namespace` attribute can be used. When a project has been shared to the group, its `namespace` will be different from the group the request is being made for.
+
## Details of a group
Get all details of a group. This endpoint can be accessed without authentication
@@ -255,7 +259,7 @@ Parameters:
| ------------------------ | -------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user. |
| `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (admins only). |
-| `with_projects` | boolean | no | Include details from projects that belong to the specified group (defaults to `true`). |
+| `with_projects` | boolean | no | Include details from projects that belong to the specified group (defaults to `true`). (Deprecated, [will be removed in 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213797). To get the details of all projects within a group, use the [list a group's projects endpoint](#list-a-groups-projects).) |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4
@@ -578,6 +582,10 @@ This endpoint returns:
and later. To get the details of all projects within a group, use the
[list a group's projects endpoint](#list-a-groups-projects) instead.
+NOTE: **Note:**
+
+The `projects` and `shared_projects` attributes [will be deprecated in GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213797). To get the details of all projects within a group, use the [list a group's projects endpoint](#list-a-groups-projects) instead.
+
Example response:
```json
diff --git a/doc/ci/jenkins/index.md b/doc/ci/jenkins/index.md
index 9b72d0bfb5e..551e32ac816 100644
--- a/doc/ci/jenkins/index.md
+++ b/doc/ci/jenkins/index.md
@@ -50,7 +50,7 @@ There are some high level differences between the products worth mentioning:
- on push
- on [schedule](../pipelines/schedules.md)
- - from the [GitLab UI](../pipelines/index.md#manually-executing-pipelines)
+ - from the [GitLab UI](../pipelines/index.md#run-a-pipeline-manually)
- by [API call](../triggers/README.md)
- by [webhook](../triggers/README.md#triggering-a-pipeline-from-a-webhook)
- by [ChatOps](../chatops/README.md)
diff --git a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md
index 7983dded814..5a732248ec1 100644
--- a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md
+++ b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md
@@ -116,7 +116,7 @@ unexpected timing. For example, when a source or target branch is advanced.
In this case, the pipeline fails because of `fatal: reference is not a tree:` error,
which indicates that the checkout-SHA is not found in the merge ref.
-This behavior was improved at GitLab 12.4 by introducing [Persistent pipeline refs](../../pipelines/index.md#persistent-pipeline-refs).
+This behavior was improved at GitLab 12.4 by introducing [Persistent pipeline refs](../../pipelines/index.md#troubleshooting-fatal-reference-is-not-a-tree).
You should be able to create pipelines at any timings without concerning the error.
## Using Merge Trains **(PREMIUM)**
diff --git a/doc/ci/multi_project_pipelines.md b/doc/ci/multi_project_pipelines.md
index 14277b6b55b..2627f83c043 100644
--- a/doc/ci/multi_project_pipelines.md
+++ b/doc/ci/multi_project_pipelines.md
@@ -38,7 +38,7 @@ With Multi-Project Pipelines you can visualize the entire pipeline, including al
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/2121) in [GitLab Premium 9.3](https://about.gitlab.com/releases/2017/06/22/gitlab-9-3-released/#multi-project-pipeline-graphs).
When you configure GitLab CI/CD for your project, you can visualize the stages of your
-[jobs](pipelines/index.md#configuring-pipelines) on a [pipeline graph](pipelines/index.md#visualizing-pipelines).
+[jobs](pipelines/index.md#configure-a-pipeline) on a [pipeline graph](pipelines/index.md#visualize-pipelines).
![Multi-project pipeline graph](img/multi_project_pipeline_graph.png)
diff --git a/doc/ci/pipelines/img/job_group_v12_10.png b/doc/ci/pipelines/img/job_group_v12_10.png
new file mode 100644
index 00000000000..0ce121ab572
--- /dev/null
+++ b/doc/ci/pipelines/img/job_group_v12_10.png
Binary files differ
diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md
index 5ce4e1649bc..91908d6c5e4 100644
--- a/doc/ci/pipelines/index.md
+++ b/doc/ci/pipelines/index.md
@@ -3,183 +3,193 @@ disqus_identifier: 'https://docs.gitlab.com/ee/ci/pipelines.html'
type: reference
---
-# Creating and using CI/CD pipelines
+# CI/CD pipelines
> Introduced in GitLab 8.8.
NOTE: **Tip:**
-Watch our
+Watch the
["Mastering continuous software development"](https://about.gitlab.com/webcast/mastering-ci-cd/)
-webcast to see a comprehensive demo of GitLab CI/CD pipeline.
+webcast to see a comprehensive demo of a GitLab CI/CD pipeline.
Pipelines are the top-level component of continuous integration, delivery, and deployment.
Pipelines comprise:
-- Jobs that define what to run. For example, code compilation or test runs.
-- Stages that define when and how to run. For example, that tests run only after code compilation.
+- Jobs, which define *what* to do. For example, jobs that compile or test code.
+- Stages, which define *when* to run the jobs. For example, stages that run tests after stages that compile the code.
-Multiple jobs in the same stage are executed by [Runners](../runners/README.md) in parallel, if there are enough concurrent [Runners](../runners/README.md).
+Jobs are executed by [Runners](../runners/README.md). Multiple jobs in the same stage are executed in parallel,
+if there are enough concurrent runners.
If all the jobs in a stage:
- Succeed, the pipeline moves on to the next stage.
- Fail, the next stage is not (usually) executed and the pipeline ends early.
+In general, pipelines are executed automatically and require no intervention once created. However, there are
+also times when you can manually interact with a pipeline.
+
+A typical pipeline might consist of four stages, executed in the following order:
+
+- A `build` stage, with a job called `compile`.
+- A `test` stage, with two jobs called `test1` and `test2`.
+- A `staging` stage, with a job called `deploy-to-stage`.
+- A `production` stage, with a job called `deploy-to-prod`.
+
NOTE: **Note:**
If you have a [mirrored repository that GitLab pulls from](../../user/project/repository/repository_mirroring.md#pulling-from-a-remote-repository-starter),
you may need to enable pipeline triggering in your project's
**Settings > Repository > Pull from a remote repository > Trigger pipelines for mirror updates**.
-## Simple pipeline example
+## Types of pipelines
-As an example, imagine a pipeline consisting of four stages, executed in the following order:
+Pipelines can be configured in many different ways:
-- `build`, with a job called `compile`.
-- `test`, with two jobs called `test` and `test2`.
-- `staging`, with a job called `deploy-to-stage`.
-- `production`, with a job called `deploy-to-prod`.
+- [Multi-project pipelines](../multi_project_pipelines.md) combine pipelines for different projects together.
+- [Parent-Child pipelines](../parent_child_pipelines.md) break down complex pipelines
+ into one parent pipeline that can trigger multiple child sub-pipelines, which all
+ run in the same project and with the same SHA.
+- [Pipelines for Merge Requests](../merge_request_pipelines/index.md) run for merge
+ requests only (rather than for every commit).
+- [Pipelines for Merged Results](../merge_request_pipelines/pipelines_for_merged_results/index.md)
+ are merge request pipelines that act as though the changes from the source branch have
+ already been merged into the target branch.
+- [Merge Trains](../merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md)
+ use pipelines for merged results to queue merges one after the other.
-## Visualizing pipelines
+## Configure a pipeline
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5742) in GitLab 8.11.
+Pipelines and their component jobs and stages are defined in the CI/CD pipeline configuration file for each project.
-Pipelines can be complex structures with many sequential and parallel jobs.
-
-To make it easier to understand the flow of a pipeline, GitLab has pipeline graphs for viewing pipelines
-and their statuses.
-
-Pipeline graphs can be displayed in two different ways, depending on the page you
-access the graph from.
+- Jobs are the [basic configuration](../yaml/README.md#introduction) component.
+- Stages are defined by using the [`stages`](../yaml/README.md#stages) keyword.
-NOTE: **Note:**
-GitLab capitalizes the stages' names when shown in the pipeline graphs (below).
+For a list of configuration options in the CI pipeline file, see the [GitLab CI/CD Pipeline Configuration Reference](../yaml/README.md).
-### Regular pipeline graphs
+You can also configure specific aspects of your pipelines through the GitLab UI. For example:
-Regular pipeline graphs show the names of the jobs of each stage. Regular pipeline graphs can
-be found when you are on a [single pipeline page](#accessing-pipelines). For example:
+- [Pipeline settings](settings.md) for each project.
+- [Pipeline schedules](schedules.md).
+- [Custom CI/CD variables](../variables/README.md#creating-a-custom-environment-variable).
-![Pipelines example](img/pipelines.png)
+### View pipelines
-### Pipeline mini graphs
+You can find the current and historical pipeline runs under your project's
+**CI/CD > Pipelines** page. You can also access pipelines for a merge request by navigating
+to its **Pipelines** tab.
-Pipeline mini graphs take less space and can tell you at a
-quick glance if all jobs passed or something failed. The pipeline mini graph can
-be found when you navigate to:
+![Pipelines index page](img/pipelines_index.png)
-- The pipelines index page.
-- A single commit page.
-- A merge request page.
+Clicking a pipeline will bring you to the **Pipeline Details** page and show
+the jobs that were run for that pipeline. From here you can cancel a running pipeline,
+retry jobs on a failed pipeline, or [delete a pipeline](#delete-a-pipeline).
-Pipeline mini graphs allow you to see all related jobs for a single commit and the net result
-of each stage of your pipeline. This allows you to quickly see what failed and
-fix it.
+[Starting in GitLab 12.3](https://gitlab.com/gitlab-org/gitlab-foss/issues/50499), a link to the
+latest pipeline for the last commit of a given branch is available at `/project/pipelines/[branch]/latest`.
+Also, `/project/pipelines/latest` will redirect you to the latest pipeline for the last commit
+on the project's default branch.
-Stages in pipeline mini graphs are collapsible. Hover your mouse over them and click to expand their jobs.
+### Run a pipeline manually
-| Mini graph | Mini graph expanded |
-|:-------------------------------------------------------------|:---------------------------------------------------------------|
-| ![Pipelines mini graph](img/pipelines_mini_graph_simple.png) | ![Pipelines mini graph extended](img/pipelines_mini_graph.png) |
+Pipelines can be manually executed, with predefined or manually-specified [variables](../variables/README.md).
-### Job ordering in pipeline graphs
+You might do this if the results of a pipeline (for example, a code build) are required outside the normal
+operation of the pipeline.
-Job ordering depends on the type of pipeline graph. For [regular pipeline graphs](#regular-pipeline-graphs), jobs are sorted by name.
+To execute a pipeline manually:
-For [pipeline mini graphs](#pipeline-mini-graphs) ([introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9760)
-in GitLab 9.0), jobs are sorted by severity and then by name.
+1. Navigate to your project's **CI/CD > Pipelines**.
+1. Click on the **Run Pipeline** button.
+1. On the **Run Pipeline** page:
+ 1. Select the branch to run the pipeline for in the **Create for** field.
+ 1. Enter any [environment variables](../variables/README.md) required for the pipeline run.
+ 1. Click the **Create pipeline** button.
-The order of severity is:
+The pipeline will execute the jobs as configured.
-- failed
-- warning
-- pending
-- running
-- manual
-- scheduled
-- canceled
-- success
-- skipped
-- created
+### Run a pipeline by using a URL query string
-For example:
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/24146) in GitLab 12.5.
-![Pipeline mini graph sorting](img/pipelines_mini_graph_sorting.png)
+You can use a query string to pre-populate the **Run Pipeline** page. For example, the query string
+`.../pipelines/new?ref=my_branch&var[foo]=bar&file_var[file_foo]=file_bar` will pre-populate the
+**Run Pipeline** page with:
-### Expanding and collapsing job log sections
+- **Run for** field: `my_branch`.
+- **Variables** section:
+ - Variable:
+ - Key: `foo`
+ - Value: `bar`
+ - File:
+ - Key: `file_foo`
+ - Value: `file_bar`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/14664) in GitLab 12.0.
+The format of the `pipelines/new` URL is:
-Job logs are divided into sections that can be collapsed or expanded. Each section will display
-the duration.
+```plaintext
+.../pipelines/new?ref=<branch>&var[<variable_key>]=<value>&file_var[<file_key>]=<value>
+```
-In the following example:
+The following parameters are supported:
-- Two sections are collapsed and can be expanded.
-- Three sections are expanded and can be collapsed.
+- `ref`: specify the branch to populate the **Run for** field with.
+- `var`: specify a `Variable` variable.
+- `file_var`: specify a `File` variable.
-![Collapsible sections](img/collapsible_log_v12_6.png)
+For each `var` or `file_var`, a key and value are required.
-#### Custom collapsible sections
+### Add manual interaction to your pipeline
-You can create collapsible sections in job logs by manually outputting special codes
-that GitLab will use to determine what sections to collapse:
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/7931) in GitLab 8.15.
-- Section start marker: `section_start:UNIX_TIMESTAMP:SECTION_NAME\r\e[0K` + `TEXT_OF_SECTION_HEADER`
-- Section end marker: `section_end:UNIX_TIMESTAMP:SECTION_NAME\r\e[0K`
+Manual actions, configured using the [`when:manual`](../yaml/README.md#whenmanual) parameter,
+allow you to require manual interaction before moving forward in the pipeline.
-You must add these codes to the script section of the CI configuration. For example,
-using `echo`:
+You can do this straight from the pipeline graph. Just click the play button
+to execute that particular job.
-```yaml
-job1:
- script:
- - echo -e "section_start:`date +%s`:my_first_section\r\e[0KHeader of the 1st collapsible section"
- - echo 'this line should be hidden when collapsed'
- - echo -e "section_end:`date +%s`:my_first_section\r\e[0K"
-```
+For example, your pipeline might start automatically, but it requires manual action to
+[deploy to production](../environments.md#configuring-manual-deployments). In the example below, the `production`
+stage has a job with a manual action.
-In the example above:
+![Pipelines example](img/pipelines.png)
-- `date +%s`: The Unix timestamp (for example `1560896352`).
-- `my_first_section`: The name given to the section.
-- `\r\e[0K`: Prevents the section markers from displaying in the rendered (colored)
- job log, but they are displayed in the raw job log. To see them, in the top right
- of the job log, click **{doc-text}** (**Show complete raw**).
- - `\r`: carriage return.
- - `\e[0K`: clear line ANSI escape code.
+#### Start multiple manual actions in a stage
-Sample raw job log:
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27188) in GitLab 11.11.
-```plaintext
-section_start:1560896352:my_first_section\r\e[0KHeader of the 1st collapsible section
-this line should be hidden when collapsed
-section_end:1560896353:my_first_section\r\e[0K
-```
+Multiple manual actions in a single stage can be started at the same time using the "Play all manual" button.
+Once the user clicks this button, each individual manual action will be triggered and refreshed
+to an updated status.
-### Pipeline success and duration charts
+This functionality is only available:
-> - Introduced in GitLab 3.1.1 as Commit Stats, and later renamed to Pipeline Charts.
-> - [Renamed](https://gitlab.com/gitlab-org/gitlab/issues/38318) to CI / CD Analytics in GitLab 12.8.
+- For users with at least Developer access.
+- If the stage contains [manual actions](#add-manual-interaction-to-your-pipeline).
-GitLab tracks the history of your pipeline successes and failures, as well as how long each pipeline ran. To view this information, go to **Analytics > CI / CD Analytics**.
+### Delete a pipeline
-View successful pipelines:
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/24851) in GitLab 12.7.
-![Successful pipelines](img/pipelines_success_chart.png)
+Users with [owner permissions](../../user/permissions.md) in a project can delete a pipeline
+by clicking on the pipeline in the **CI/CD > Pipelines** to get to the **Pipeline Details**
+page, then using the **Delete** button.
-View pipeline duration history:
+![Pipeline Delete Button](img/pipeline-delete.png)
-![Pipeline duration](img/pipelines_duration_chart.png)
+CAUTION: **Warning:**
+Deleting a pipeline will expire all pipeline caches, and delete all related objects,
+such as builds, logs, artifacts, and triggers. **This action cannot be undone.**
-## Pipeline quotas
+### Pipeline quotas
Each user has a personal pipeline quota that tracks the usage of shared runners in all personal projects.
Each group has a [usage quota](../../subscriptions/index.md#ci-pipeline-minutes) that tracks the usage of shared runners for all projects created within the group.
When a pipeline is triggered, regardless of who triggered it, the pipeline quota for the project owner's [namespace](../../user/group/index.md#namespaces) is used. In this case, the namespace can be the user or group that owns the project.
-### How pipeline duration is calculated
+#### How pipeline duration is calculated
Total running time for a given pipeline excludes retries and pending
(queued) time.
@@ -216,245 +226,285 @@ The union of A, B, and C is (1, 4) and (6, 7). Therefore, the total running time
(4 - 1) + (7 - 6) => 4
```
-## Configuring pipelines
+### Pipeline security on protected branches
-Pipelines, and their component jobs and stages, are defined in the [`.gitlab-ci.yml`](../yaml/README.md) file for each project.
+A strict security model is enforced when pipelines are executed on
+[protected branches](../../user/project/protected_branches.md).
-In particular:
+The following actions are allowed on protected branches only if the user is
+[allowed to merge or push](../../user/project/protected_branches.md#using-the-allowed-to-merge-and-allowed-to-push-settings)
+on that specific branch:
-- Jobs are the [basic configuration](../yaml/README.md#introduction) component.
-- Stages are defined using the [`stages`](../yaml/README.md#stages) keyword.
+- Run manual pipelines (using the [Web UI](#run-a-pipeline-manually) or [pipelines API](#pipelines-api)).
+- Run scheduled pipelines.
+- Run pipelines using triggers.
+- Trigger manual actions on existing pipelines.
+- Retry or cancel existing jobs (using the Web UI or pipelines API).
-For all available configuration options, see the [GitLab CI/CD Pipeline Configuration Reference](../yaml/README.md).
+**Variables** marked as **protected** are accessible only to jobs that
+run on protected branches, preventing untrusted users getting unintended access to
+sensitive information like deployment credentials and tokens.
-### Settings and schedules
+**Runners** marked as **protected** can run jobs only on protected
+branches, preventing untrusted code from executing on the protected runner and
+preserving deployment keys and other credentials from being unintentionally
+accessed. In order to ensure that jobs intended to be executed on protected
+runners will not use regular runners, they must be tagged accordingly.
-In addition to configuring jobs through `.gitlab-ci.yml`, additional configuration options are available
-through the GitLab UI:
+## View jobs in a pipeline
-- Pipeline settings for each project. For more information, see [Pipeline settings](settings.md).
-- Schedules for pipelines. For more information, see [Pipeline schedules](schedules.md).
+When you access a pipeline, you can see the related jobs for that pipeline.
-### Grouping jobs
+Clicking an individual job will show you its job log, and allow you to:
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/6242) in GitLab 8.12.
+- Cancel the job.
+- Retry the job.
+- Erase the job log.
-If you have many similar jobs, your [pipeline graph](#visualizing-pipelines) becomes long and hard
-to read.
+### See why a job failed
-For that reason, similar jobs can automatically be grouped together.
-If the job names are formatted in certain ways, they will be collapsed into
-a single group in regular pipeline graphs (not the mini graphs).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17782) in GitLab 10.7.
-You'll know when a pipeline has grouped jobs if you don't see the retry or
-cancel button inside them. Hovering over them will show the number of grouped
-jobs. Click to expand them.
+When a pipeline fails or is allowed to fail, there are several places where you
+can find the reason:
-![Grouped pipelines](img/pipelines_grouped.png)
+- In the [pipeline graph](#visualize-pipelines), on the pipeline detail view.
+- In the pipeline widgets, in the merge requests and commit pages.
+- In the job views, in the global and detailed views of a job.
-#### Configuring grouping
+In each place, if you hover over the failed job you can see the reason it failed.
-In the pipeline [configuration file](../yaml/README.md), job names must include two numbers separated with one of
-the following (you can even use them interchangeably):
+![Pipeline detail](img/job_failure_reason.png)
-- A space.
-- A slash (`/`).
-- A colon (`:`).
+In [GitLab 10.8](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17814) and later,
+you can also see the reason it failed on the Job detail page.
-NOTE: **Note:**
-More specifically, it uses [this](https://gitlab.com/gitlab-org/gitlab/blob/2f3dc314f42dbd79813e6251792853bc231e69dd/app/models/commit_status.rb#L99) regular expression: `\d+[\s:\/\\]+\d+\s*`.
+### The order of jobs in a pipeline
-#### How grouping works
+The order of jobs in a pipeline depends on the type of pipeline graph.
-The jobs will be ordered by comparing those two numbers from left to right. You
-usually want the first to be the index and the second the total.
+- For [regular pipeline graphs](#regular-pipeline-graphs), jobs are sorted by name.
+- For [pipeline mini graphs](#pipeline-mini-graphs), jobs are sorted by severity and then by name.
-For example, the following jobs will be grouped under a job named `test`:
+The order of severity is:
-- `test 0 3`
-- `test 1 3`
-- `test 2 3`
+- failed
+- warning
+- pending
+- running
+- manual
+- scheduled
+- canceled
+- success
+- skipped
+- created
-The following jobs will be grouped under a job named `test ruby`:
+For example:
-- `test 1:2 ruby`
-- `test 2:2 ruby`
+![Pipeline mini graph sorting](img/pipelines_mini_graph_sorting.png)
-The following jobs will be grouped under a job named `test ruby` as well:
+### Group jobs in a pipeline
-- `1/3 test ruby`
-- `2/3 test ruby`
-- `3/3 test ruby`
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/6242) in GitLab 8.12.
-### Pipelines for merge requests
+If you have many similar jobs, your [pipeline graph](#visualize-pipelines) becomes long and hard
+to read.
-GitLab supports configuring pipelines that run only for merge requests. For more information, see
-[Pipelines for merge requests](../merge_request_pipelines/index.md).
+You can automatically group similar jobs together. If the job names are formatted in a certain way,
+they will be collapsed into a single group in regular pipeline graphs (not the mini graphs).
-### Badges
+You'll know when a pipeline has grouped jobs if you don't see the retry or
+cancel button inside them. Hovering over them will show the number of grouped
+jobs. Click to expand them.
-Pipeline status and test coverage report badges are available and configurable for each project.
+![Grouped pipelines](img/pipelines_grouped.png)
-For information on adding pipeline badges to projects, see [Pipeline badges](settings.md#pipeline-badges).
+To create a group of jobs, in the [CI/CD pipeline configuration file](../yaml/README.md),
+separate each job name with a number and one of the following:
-## Multi-project pipelines
+- A slash (`/`), for example, `test 1/3`, `test 2/3`, `test 3/3`.
+- A colon (`:`), for example, `test 1:3`, `test 2:3`, `test 3:3`.
+- A space, for example `test 0 3`, `test 1 3`, `test 2 3`.
-Pipelines for different projects can be combined together into [Multi-project pipelines](../multi_project_pipelines.md).
+You can use these symbols interchangeably.
-[Multi-project pipeline graphs](../multi_project_pipelines.md#multi-project-pipeline-visualization-premium) help
-you visualize the entire pipeline, including all cross-project inter-dependencies. **(PREMIUM)**
+For example, these three jobs will be in a group named `build ruby`:
-## Parent-child pipelines
+```yaml
+build ruby 1/3:
+ stage: build
+ script:
+ - echo "ruby1"
-Complex pipelines can be broken down into one parent pipeline that can trigger
-multiple child sub-pipelines, which all run in the same project and with the same SHA.
+build ruby 2/3:
+ stage: build
+ script:
+ - echo "ruby2"
+
+build ruby 3/3:
+ stage: build
+ script:
+ - echo "ruby3"
+```
-For more information, see [Parent-Child pipelines](../parent_child_pipelines.md).
+In the pipeline, the result is a group named `build ruby` with three jobs:
-## Working with pipelines
+![Job group](img/job_group_v12_10.png)
-In general, pipelines are executed automatically and require no intervention once created.
+The jobs will be ordered by comparing the numbers from left to right. You
+usually want the first number to be the index and the second number to be the total.
-However, there are instances where you'll need to interact with pipelines. These are documented below.
+[This regular expression](https://gitlab.com/gitlab-org/gitlab/blob/2f3dc314f42dbd79813e6251792853bc231e69dd/app/models/commit_status.rb#L99)
+evaluates the job names: `\d+[\s:\/\\]+\d+\s*`.
-### Manually executing pipelines
+### Specifying variables when running manual jobs
-Pipelines can be manually executed, with predefined or manually-specified [variables](../variables/README.md).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30485) in GitLab 12.2.
-You might do this if the results of a pipeline (for example, a code build) is required outside the normal
-operation of the pipeline.
+When running manual jobs you can supply additional job specific variables.
-To execute a pipeline manually:
+You can do this from the job page of the manual job you want to run with
+additional variables.
-1. Navigate to your project's **CI/CD > Pipelines**.
-1. Click on the **Run Pipeline** button.
-1. On the **Run Pipeline** page:
- 1. Select the branch to run the pipeline for in the **Create for** field.
- 1. Enter any [environment variables](../variables/README.md) required for the pipeline run.
- 1. Click the **Create pipeline** button.
+This is useful when you want to alter the execution of a job by using
+environment variables.
-The pipeline will execute the jobs as configured.
+![Manual job variables](img/manual_job_variables.png)
-#### Using a query string
+### Delay a job
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/24146) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/21767) in GitLab 11.4.
-Variables on the **Run Pipeline** page can be pre-populated by passing variable keys and values
-in a query string appended to the `pipelines/new` URL. The format is:
+When you do not want to run a job immediately, you can use the [`when:delayed`](../yaml/README.md#whendelayed) parameter to
+delay a job's execution for a certain period.
-```plaintext
-.../pipelines/new?ref=<branch>&var[<variable_key>]=<value>&file_var[<file_key>]=<value>
-```
+This is especially useful for timed incremental rollout where new code is rolled out gradually.
-The following parameters are supported:
+For example, if you start rolling out new code and:
-- `ref`: specify the branch to populate the **Run for** field with.
-- `var`: specify a `Variable` variable.
-- `file_var`: specify a `File` variable.
+- Users do not experience trouble, GitLab can automatically complete the deployment from 0% to 100%.
+- Users experience trouble with the new code, you can stop the timed incremental rollout by canceling the pipeline
+ and [rolling](../environments.md#retrying-and-rolling-back) back to the last stable version.
-For each `var` or `file_var`, a key and value are required.
+![Pipelines example](img/pipeline_incremental_rollout.png)
-For example, the query string
-`.../pipelines/new?ref=my_branch&var[foo]=bar&file_var[file_foo]=file_bar` will pre-populate the
-**Run Pipeline** page as follows:
+### Expand and collapse job log sections
-- **Run for** field: `my_branch`.
-- **Variables** section:
- - Variable:
- - Key: `foo`
- - Value: `bar`
- - File:
- - Key: `file_foo`
- - Value: `file_bar`
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/14664) in GitLab 12.0.
-### Accessing pipelines
+Job logs are divided into sections that can be collapsed or expanded. Each section will display
+the duration.
-You can find the current and historical pipeline runs under your project's
-**CI/CD > Pipelines** page. You can also access pipelines for a merge request by navigating
-to its **Pipelines** tab.
+In the following example:
-![Pipelines index page](img/pipelines_index.png)
+- Two sections are collapsed and can be expanded.
+- Three sections are expanded and can be collapsed.
-Clicking on a pipeline will bring you to the **Pipeline Details** page and show
-the jobs that were run for that pipeline. From here you can cancel a running pipeline,
-retry jobs on a failed pipeline, or [delete a pipeline](#deleting-a-single-pipeline).
+![Collapsible sections](img/collapsible_log_v12_6.png)
-### Accessing individual jobs
+#### Custom collapsible sections
-When you access a pipeline, you can see the related jobs for that pipeline.
+You can create collapsible sections in job logs by manually outputting special codes
+that GitLab will use to determine what sections to collapse:
-Clicking on an individual job will show you its job log, and allow you to:
+- Section start marker: `section_start:UNIX_TIMESTAMP:SECTION_NAME\r\e[0K` + `TEXT_OF_SECTION_HEADER`
+- Section end marker: `section_end:UNIX_TIMESTAMP:SECTION_NAME\r\e[0K`
-- Cancel the job.
-- Retry the job.
-- Erase the job log.
+You must add these codes to the script section of the CI configuration. For example,
+using `echo`:
-### Seeing the failure reason for jobs
+```yaml
+job1:
+ script:
+ - echo -e "section_start:`date +%s`:my_first_section\r\e[0KHeader of the 1st collapsible section"
+ - echo 'this line should be hidden when collapsed'
+ - echo -e "section_end:`date +%s`:my_first_section\r\e[0K"
+```
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17782) in GitLab 10.7.
+In the example above:
-When a pipeline fails or is allowed to fail, there are several places where you
-can quickly check the reason it failed:
+- `date +%s`: The Unix timestamp (for example `1560896352`).
+- `my_first_section`: The name given to the section.
+- `\r\e[0K`: Prevents the section markers from displaying in the rendered (colored)
+ job log, but they are displayed in the raw job log. To see them, in the top right
+ of the job log, click **{doc-text}** (**Show complete raw**).
+ - `\r`: carriage return.
+ - `\e[0K`: clear line ANSI escape code.
-- In the pipeline graph, on the pipeline detail view.
-- In the pipeline widgets, in the merge requests and commit pages.
-- In the job views, in the global and detailed views of a job.
+Sample raw job log:
-In each place, if you hover over the failed job you can see the reason it failed.
+```plaintext
+section_start:1560896352:my_first_section\r\e[0KHeader of the 1st collapsible section
+this line should be hidden when collapsed
+section_end:1560896353:my_first_section\r\e[0K
+```
-![Pipeline detail](img/job_failure_reason.png)
+## Visualize pipelines
-From [GitLab 10.8](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17814),
-you can also see the reason it failed on the Job detail page.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5742) in GitLab 8.11.
-### Manual actions from pipeline graphs
+Pipelines can be complex structures with many sequential and parallel jobs.
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/7931) in GitLab 8.15.
+To make it easier to understand the flow of a pipeline, GitLab has pipeline graphs for viewing pipelines
+and their statuses.
-Manual actions, configured using the [`when:manual`](../yaml/README.md#whenmanual) parameter,
-allow you to require manual interaction before moving forward in the pipeline.
+Pipeline graphs can be displayed in two different ways, depending on the page you
+access the graph from.
-You can do this straight from the pipeline graph. Just click on the play button
-to execute that particular job.
+NOTE: **Note:**
+GitLab capitalizes the stages' names in the pipeline graphs.
-For example, your pipeline start automatically, but require manual action to
-[deploy to production](../environments.md#configuring-manual-deployments). In the example below, the `production`
-stage has a job with a manual action.
+### Regular pipeline graphs
+
+Regular pipeline graphs show the names of the jobs in each stage. Regular pipeline graphs can
+be found when you are on a [single pipeline page](#view-pipelines). For example:
![Pipelines example](img/pipelines.png)
-### Specifying variables when running manual jobs
+[Multi-project pipeline graphs](../multi_project_pipelines.md#multi-project-pipeline-visualization-premium) help
+you visualize the entire pipeline, including all cross-project inter-dependencies. **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30485) in GitLab 12.2.
+### Pipeline mini graphs
-When running manual jobs you can supply additional job specific variables.
+Pipeline mini graphs take less space and can tell you at a
+quick glance if all jobs passed or something failed. The pipeline mini graph can
+be found when you navigate to:
-You can do this from the job page of the manual job you want to run with
-additional variables.
+- The pipelines index page.
+- A single commit page.
+- A merge request page.
-This is useful when you want to alter the execution of a job by using
-environment variables.
+Pipeline mini graphs allow you to see all related jobs for a single commit and the net result
+of each stage of your pipeline. This allows you to quickly see what failed and
+fix it.
-![Manual job variables](img/manual_job_variables.png)
+Stages in pipeline mini graphs are collapsible. Hover your mouse over them and click to expand their jobs.
-### Delay a job in a pipeline graph
+| Mini graph | Mini graph expanded |
+|:-------------------------------------------------------------|:---------------------------------------------------------------|
+| ![Pipelines mini graph](img/pipelines_mini_graph_simple.png) | ![Pipelines mini graph extended](img/pipelines_mini_graph.png) |
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/21767) in GitLab 11.4.
+### Pipeline success and duration charts
-When you do not want to run a job immediately, you can use the [`when:delayed`](../yaml/README.md#whendelayed) parameter to
-delay a job's execution for a certain period.
+> - Introduced in GitLab 3.1.1 as Commit Stats, and later renamed to Pipeline Charts.
+> - [Renamed](https://gitlab.com/gitlab-org/gitlab/issues/38318) to CI / CD Analytics in GitLab 12.8.
-This is especially useful for timed incremental rollout where new code is rolled out gradually.
+GitLab tracks the history of your pipeline successes and failures, as well as how long each pipeline ran. To view this information, go to **Analytics > CI / CD Analytics**.
-For example, if you start rolling out new code and:
+View successful pipelines:
-- Users do not experience trouble, GitLab can automatically complete the deployment from 0% to 100%.
-- Users experience trouble with the new code, you can stop the timed incremental rollout by canceling the pipeline
- and [rolling](../environments.md#retrying-and-rolling-back) back to the last stable version.
+![Successful pipelines](img/pipelines_success_chart.png)
-![Pipelines example](img/pipeline_incremental_rollout.png)
+View pipeline duration history:
+
+![Pipeline duration](img/pipelines_duration_chart.png)
+
+### Pipeline badges
+
+Pipeline status and test coverage report badges are available and configurable for each project.
+For information on adding pipeline badges to projects, see [Pipeline badges](settings.md#pipeline-badges).
-### Using the API
+## Pipelines API
GitLab provides API endpoints to:
@@ -464,65 +514,7 @@ GitLab provides API endpoints to:
- [Triggering pipelines through the API](../triggers/README.md).
- [Pipeline triggers API](../../api/pipeline_triggers.md).
-### Start multiple manual actions in a stage
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27188) in GitLab 11.11.
-
-Multiple manual actions in a single stage can be started at the same time using the "Play all manual" button.
-Once the user clicks this button, each individual manual action will be triggered and refreshed
-to an updated status.
-
-This functionality is only available:
-
-- For users with at least Developer access.
-- If the stage contains [manual actions](#manual-actions-from-pipeline-graphs).
-
-### Deleting a single pipeline
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/24851) in GitLab 12.7.
-
-Users with [owner permissions](../../user/permissions.md) in a project can delete a pipeline
-by clicking on the pipeline in the **CI/CD > Pipelines** to get to the **Pipeline Details**
-page, then using the **Delete** button.
-
-![Pipeline Delete Button](img/pipeline-delete.png)
-
-CAUTION: **Warning:**
-Deleting a pipeline will expire all pipeline caches, and delete all related objects,
-such as builds, logs, artifacts, and triggers. **This action cannot be undone.**
-
-## Most Recent Pipeline
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/50499) in GitLab 12.3.
-
-There's a link to the latest pipeline for the last commit of a given branch at `/project/pipelines/[branch]/latest`. Also, `/project/pipelines/latest` will redirect you to the latest pipeline for the last commit on the project's default branch.
-
-## Security on protected branches
-
-A strict security model is enforced when pipelines are executed on
-[protected branches](../../user/project/protected_branches.md).
-
-The following actions are allowed on protected branches only if the user is
-[allowed to merge or push](../../user/project/protected_branches.md#using-the-allowed-to-merge-and-allowed-to-push-settings)
-on that specific branch:
-
-- Run manual pipelines (using the [Web UI](#manually-executing-pipelines) or pipelines API).
-- Run scheduled pipelines.
-- Run pipelines using triggers.
-- Trigger manual actions on existing pipelines.
-- Retry or cancel existing jobs (using the Web UI or pipelines API).
-
-**Variables** marked as **protected** are accessible only to jobs that
-run on protected branches, preventing untrusted users getting unintended access to
-sensitive information like deployment credentials and tokens.
-
-**Runners** marked as **protected** can run jobs only on protected
-branches, avoiding untrusted code to be executed on the protected runner and
-preserving deployment keys and other credentials from being unintentionally
-accessed. In order to ensure that jobs intended to be executed on protected
-runners will not use regular runners, they must be tagged accordingly.
-
-## Persistent pipeline refs
+## Troubleshooting `fatal: reference is not a tree:`
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17043) in GitLab 12.4.
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index 2f4408aaa6c..e619a32b90f 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -465,7 +465,7 @@ limitations with the current Auto DevOps scripting environment.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/44059) in GitLab 10.8.
-[Manually triggered pipelines](../pipelines/index.md#manually-executing-pipelines) allow you to override the value of a current variable.
+[Manually triggered pipelines](../pipelines/index.md#run-a-pipeline-manually) allow you to override the value of a current variable.
For instance, suppose you added a
[custom variable `$TEST`](#creating-a-custom-environment-variable)
@@ -621,7 +621,7 @@ variables that were set, etc.
Before enabling this, you should ensure jobs are visible to
[team members only](../../user/permissions.md#project-features). You should
-also [erase](../pipelines/index.md#accessing-individual-jobs) all generated job logs
+also [erase](../pipelines/index.md#view-jobs-in-a-pipeline) all generated job logs
before making them visible again.
To enable debug logs (traces), set the `CI_DEBUG_TRACE` variable to `true`:
diff --git a/doc/topics/autodevops/customize.md b/doc/topics/autodevops/customize.md
index 7efe2c3bdcf..28abd73ef97 100644
--- a/doc/topics/autodevops/customize.md
+++ b/doc/topics/autodevops/customize.md
@@ -521,7 +521,7 @@ increasing the rollout up to 100%.
If `INCREMENTAL_ROLLOUT_MODE` is set to `manual` in your project, then instead
of the standard `production` job, 4 different
-[manual jobs](../../ci/pipelines/index.md#manual-actions-from-pipeline-graphs)
+[manual jobs](../../ci/pipelines/index.md#add-manual-interaction-to-your-pipeline)
will be created:
1. `rollout 10%`
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index fabe6fd40c9..59867f492b8 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -425,7 +425,7 @@ read through the documentation on the [new CI/CD permissions model](project/new_
The permission to merge or push to protected branches is used to define if a user can
run CI/CD pipelines and execute actions on jobs that are related to those branches.
-See [Security on protected branches](../ci/pipelines/index.md#security-on-protected-branches)
+See [Security on protected branches](../ci/pipelines/index.md#pipeline-security-on-protected-branches)
for details about the pipelines security model.
## LDAP users permissions
diff --git a/doc/user/project/index.md b/doc/user/project/index.md
index 3e1c3007e00..99050f823c5 100644
--- a/doc/user/project/index.md
+++ b/doc/user/project/index.md
@@ -70,7 +70,7 @@ When you create a project in GitLab, you'll have access to a large number of
your GitLab CI/CD pipelines from the UI
- [Scheduled Pipelines](../../ci/pipelines/schedules.md): Schedule a pipeline
to start at a chosen time
- - [Pipeline Graphs](../../ci/pipelines/index.md#visualizing-pipelines): View your
+ - [Pipeline Graphs](../../ci/pipelines/index.md#visualize-pipelines): View your
entire pipeline from the UI
- [Job artifacts](../../ci/pipelines/job_artifacts.md): Define,
browse, and download job artifacts
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index 9d288d5da92..2038414dab8 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -101,7 +101,7 @@ or link to useful information directly in the merge request page:
| [Metrics Reports](../../../ci/metrics_reports.md) **(PREMIUM)** | Display the Metrics Report on the merge request so that it's fast and easy to identify changes to important metrics. |
| [Multi-Project pipelines](../../../ci/multi_project_pipelines.md) **(PREMIUM)** | When you set up GitLab CI/CD across multiple projects, you can visualize the entire pipeline, including all cross-project interdependencies. |
| [Pipelines for merge requests](../../../ci/merge_request_pipelines/index.md) | Customize a specific pipeline structure for merge requests in order to speed the cycle up by running only important jobs. |
-| [Pipeline Graphs](../../../ci/pipelines/index.md#visualizing-pipelines) | View the status of pipelines within the merge request, including the deployment process. |
+| [Pipeline Graphs](../../../ci/pipelines/index.md#visualize-pipelines) | View the status of pipelines within the merge request, including the deployment process. |
| [Test Coverage visualization](test_coverage_visualization.md) | See test coverage results for merge requests, within the file diff. |
### Security Reports **(ULTIMATE)**
diff --git a/doc/user/project/protected_branches.md b/doc/user/project/protected_branches.md
index 14feb189964..e2ee0dd47fe 100644
--- a/doc/user/project/protected_branches.md
+++ b/doc/user/project/protected_branches.md
@@ -187,7 +187,7 @@ Additionally, direct pushes to the protected branch are denied if a rule is matc
The permission to merge or push to protected branches is used to define if a user can
run CI/CD pipelines and execute actions on jobs that are related to those branches.
-See [Security on protected branches](../../ci/pipelines/index.md#security-on-protected-branches)
+See [Security on protected branches](../../ci/pipelines/index.md#pipeline-security-on-protected-branches)
for details about the pipelines security model.
## Changelog
diff --git a/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
index 20063cf6a69..d85078c0a40 100644
--- a/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
@@ -1,11 +1,11 @@
performance:
stage: performance
- image: docker:19.03.5
+ image: docker:19.03.8
allow_failure: true
variables:
DOCKER_TLS_CERTDIR: ""
services:
- - docker:19.03.5-dind
+ - docker:19.03.8-dind
script:
- |
if ! docker info &>/dev/null; then
diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
index ceaa8115c3d..6b72db951ed 100644
--- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
@@ -1,10 +1,10 @@
build:
stage: build
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v0.2.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v0.2.1"
variables:
DOCKER_TLS_CERTDIR: ""
services:
- - docker:19.03.5-dind
+ - docker:19.03.8-dind
script:
- |
if [[ -z "$CI_COMMIT_TAG" ]]; then
diff --git a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
index a6338ff6925..9c4699f1f44 100644
--- a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
@@ -1,9 +1,9 @@
code_quality:
stage: test
- image: docker:19.03.5
+ image: docker:19.03.8
allow_failure: true
services:
- - docker:19.03.5-dind
+ - docker:19.03.8-dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index f4e75cefb67..92df6cf3135 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -71,6 +71,11 @@ msgstr ""
msgid "\"%{path}\" did not exist on \"%{ref}\""
msgstr ""
+msgid "%d URL scanned"
+msgid_plural "%d URLs scanned"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -22624,6 +22629,9 @@ msgstr ""
msgid "View deployment"
msgstr ""
+msgid "View details"
+msgstr ""
+
msgid "View details: %{details_url}"
msgstr ""
diff --git a/spec/frontend/static_site_editor/components/publish_toolbar_spec.js b/spec/frontend/static_site_editor/components/publish_toolbar_spec.js
index 55e30825621..0edc3f4c920 100644
--- a/spec/frontend/static_site_editor/components/publish_toolbar_spec.js
+++ b/spec/frontend/static_site_editor/components/publish_toolbar_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import { GlNewButton } from '@gitlab/ui';
+import { GlNewButton, GlLoadingIcon } from '@gitlab/ui';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
@@ -16,6 +16,7 @@ describe('Static Site Editor Toolbar', () => {
};
const findSaveChangesButton = () => wrapper.find(GlNewButton);
+ const findLoadingIndicator = () => wrapper.find(GlLoadingIcon);
beforeEach(() => {
buildWrapper();
@@ -33,6 +34,10 @@ describe('Static Site Editor Toolbar', () => {
expect(findSaveChangesButton().attributes('disabled')).toBe('true');
});
+ it('does not display saving changes indicator', () => {
+ expect(findLoadingIndicator().classes()).toContain('invisible');
+ });
+
describe('when saveable', () => {
it('enables Submit Changes button', () => {
buildWrapper({ saveable: true });
@@ -40,4 +45,26 @@ describe('Static Site Editor Toolbar', () => {
expect(findSaveChangesButton().attributes('disabled')).toBeFalsy();
});
});
+
+ describe('when saving changes', () => {
+ beforeEach(() => {
+ buildWrapper({ saveable: true, savingChanges: true });
+ });
+
+ it('disables Submit Changes button', () => {
+ expect(findSaveChangesButton().attributes('disabled')).toBe('true');
+ });
+
+ it('displays saving changes indicator', () => {
+ expect(findLoadingIndicator().classes()).not.toContain('invisible');
+ });
+ });
+
+ it('emits submit event when submit button is clicked', () => {
+ buildWrapper({ saveable: true });
+
+ findSaveChangesButton().vm.$emit('click');
+
+ expect(wrapper.emitted('submit')).toHaveLength(1);
+ });
});
diff --git a/spec/frontend/static_site_editor/components/static_site_editor_spec.js b/spec/frontend/static_site_editor/components/static_site_editor_spec.js
index ec984102250..a40f8edbeb2 100644
--- a/spec/frontend/static_site_editor/components/static_site_editor_spec.js
+++ b/spec/frontend/static_site_editor/components/static_site_editor_spec.js
@@ -9,6 +9,8 @@ import StaticSiteEditor from '~/static_site_editor/components/static_site_editor
import EditArea from '~/static_site_editor/components/edit_area.vue';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
+import { sourceContent } from '../mock_data';
+
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -18,10 +20,12 @@ describe('StaticSiteEditor', () => {
let store;
let loadContentActionMock;
let setContentActionMock;
+ let submitChangesActionMock;
const buildStore = ({ initialState, getters } = {}) => {
loadContentActionMock = jest.fn();
setContentActionMock = jest.fn();
+ submitChangesActionMock = jest.fn();
store = new Vuex.Store({
state: createState(initialState),
@@ -33,6 +37,7 @@ describe('StaticSiteEditor', () => {
actions: {
loadContent: loadContentActionMock,
setContent: setContentActionMock,
+ submitChanges: submitChangesActionMock,
},
});
};
@@ -119,18 +124,35 @@ describe('StaticSiteEditor', () => {
expect(findSkeletonLoader().exists()).toBe(true);
});
+ it('sets toolbar as saving when saving changes', () => {
+ buildContentLoadedStore({
+ initialState: {
+ isSavingChanges: true,
+ },
+ });
+ buildWrapper();
+
+ expect(findPublishToolbar().props('savingChanges')).toBe(true);
+ });
+
it('dispatches load content action', () => {
expect(loadContentActionMock).toHaveBeenCalled();
});
it('dispatches setContent action when edit area emits input event', () => {
- const content = 'new content';
-
buildContentLoadedStore();
buildWrapper();
- findEditArea().vm.$emit('input', content);
+ findEditArea().vm.$emit('input', sourceContent);
+
+ expect(setContentActionMock).toHaveBeenCalledWith(expect.anything(), sourceContent, undefined);
+ });
+
+ it('dispatches submitChanges action when toolbar emits submit event', () => {
+ buildContentLoadedStore();
+ buildWrapper();
+ findPublishToolbar().vm.$emit('submit');
- expect(setContentActionMock).toHaveBeenCalledWith(expect.anything(), content, undefined);
+ expect(submitChangesActionMock).toHaveBeenCalled();
});
});
diff --git a/spec/frontend/static_site_editor/mock_data.js b/spec/frontend/static_site_editor/mock_data.js
index 0b2a69420d8..9e1c14515e6 100644
--- a/spec/frontend/static_site_editor/mock_data.js
+++ b/spec/frontend/static_site_editor/mock_data.js
@@ -14,5 +14,23 @@ twitter_image: '/images/tweets/handbook-gitlab.png'
export const sourceContentTitle = 'Handbook';
+export const username = 'gitlabuser';
export const projectId = '123456';
export const sourcePath = 'foobar.md.html';
+
+export const savedContentMeta = {
+ branch: {
+ label: 'foobar',
+ url: 'foobar/-/tree/foorbar',
+ },
+ commit: {
+ label: 'c1461b08 ',
+ url: 'foobar/-/c1461b08',
+ },
+ mergeRequest: {
+ label: '123',
+ url: 'foobar/-/merge_requests/123',
+ },
+};
+
+export const submitChangesError = 'Could not save changes';
diff --git a/spec/frontend/static_site_editor/store/actions_spec.js b/spec/frontend/static_site_editor/store/actions_spec.js
index 4ad1e798ccd..a9c039517b7 100644
--- a/spec/frontend/static_site_editor/store/actions_spec.js
+++ b/spec/frontend/static_site_editor/store/actions_spec.js
@@ -3,18 +3,23 @@ import createState from '~/static_site_editor/store/state';
import * as actions from '~/static_site_editor/store/actions';
import * as mutationTypes from '~/static_site_editor/store/mutation_types';
import loadSourceContent from '~/static_site_editor/services/load_source_content';
+import submitContentChanges from '~/static_site_editor/services/submit_content_changes';
import createFlash from '~/flash';
import {
+ username,
projectId,
sourcePath,
sourceContentTitle as title,
sourceContent as content,
+ savedContentMeta,
+ submitChangesError,
} from '../mock_data';
jest.mock('~/flash');
jest.mock('~/static_site_editor/services/load_source_content', () => jest.fn());
+jest.mock('~/static_site_editor/services/submit_content_changes', () => jest.fn());
describe('Static Site Editor Store actions', () => {
let state;
@@ -84,4 +89,59 @@ describe('Static Site Editor Store actions', () => {
]);
});
});
+
+ describe('submitChanges', () => {
+ describe('on success', () => {
+ beforeEach(() => {
+ state = createState({
+ projectId,
+ content,
+ username,
+ sourcePath,
+ });
+ submitContentChanges.mockResolvedValueOnce(savedContentMeta);
+ });
+
+ it('commits submitChangesSuccess mutation', () => {
+ testAction(
+ actions.submitChanges,
+ null,
+ state,
+ [
+ { type: mutationTypes.SUBMIT_CHANGES },
+ { type: mutationTypes.SUBMIT_CHANGES_SUCCESS, payload: savedContentMeta },
+ ],
+ [],
+ );
+
+ expect(submitContentChanges).toHaveBeenCalledWith({
+ username,
+ projectId,
+ content,
+ sourcePath,
+ });
+ });
+ });
+
+ describe('on error', () => {
+ const expectedMutations = [
+ { type: mutationTypes.SUBMIT_CHANGES },
+ { type: mutationTypes.SUBMIT_CHANGES_ERROR },
+ ];
+
+ beforeEach(() => {
+ submitContentChanges.mockRejectedValueOnce(new Error(submitChangesError));
+ });
+
+ it('dispatches receiveContentError', () => {
+ testAction(actions.submitChanges, null, state, expectedMutations);
+ });
+
+ it('displays flash communicating error', () => {
+ return testAction(actions.submitChanges, null, state, expectedMutations).then(() => {
+ expect(createFlash).toHaveBeenCalledWith(submitChangesError);
+ });
+ });
+ });
+ });
});
diff --git a/spec/frontend/static_site_editor/store/mutations_spec.js b/spec/frontend/static_site_editor/store/mutations_spec.js
index db3a1081af5..1fd687eed4a 100644
--- a/spec/frontend/static_site_editor/store/mutations_spec.js
+++ b/spec/frontend/static_site_editor/store/mutations_spec.js
@@ -1,61 +1,50 @@
import createState from '~/static_site_editor/store/state';
import mutations from '~/static_site_editor/store/mutations';
import * as types from '~/static_site_editor/store/mutation_types';
-import { sourceContentTitle as title, sourceContent as content } from '../mock_data';
+import {
+ sourceContentTitle as title,
+ sourceContent as content,
+ savedContentMeta,
+} from '../mock_data';
describe('Static Site Editor Store mutations', () => {
let state;
+ const contentLoadedPayload = { title, content };
beforeEach(() => {
state = createState();
});
- describe('loadContent', () => {
- beforeEach(() => {
- mutations[types.LOAD_CONTENT](state);
- });
-
- it('sets isLoadingContent to true', () => {
- expect(state.isLoadingContent).toBe(true);
- });
- });
-
- describe('receiveContentSuccess', () => {
- const payload = { title, content };
-
- beforeEach(() => {
- mutations[types.RECEIVE_CONTENT_SUCCESS](state, payload);
- });
-
- it('sets current state to LOADING', () => {
- expect(state.isLoadingContent).toBe(false);
- });
-
- it('sets title', () => {
- expect(state.title).toBe(payload.title);
- });
-
- it('sets originalContent and content', () => {
- expect(state.content).toBe(payload.content);
- expect(state.originalContent).toBe(payload.content);
- });
- });
-
- describe('receiveContentError', () => {
- beforeEach(() => {
- mutations[types.RECEIVE_CONTENT_ERROR](state);
- });
-
- it('sets current state to LOADING_ERROR', () => {
- expect(state.isLoadingContent).toBe(false);
- });
- });
-
- describe('setContent', () => {
- it('sets content', () => {
- mutations[types.SET_CONTENT](state, content);
-
- expect(state.content).toBe(content);
- });
+ it.each`
+ mutation | stateProperty | payload | expectedValue
+ ${types.LOAD_CONTENT} | ${'isLoadingContent'} | ${undefined} | ${true}
+ ${types.RECEIVE_CONTENT_SUCCESS} | ${'isLoadingContent'} | ${contentLoadedPayload} | ${false}
+ ${types.RECEIVE_CONTENT_SUCCESS} | ${'title'} | ${contentLoadedPayload} | ${title}
+ ${types.RECEIVE_CONTENT_SUCCESS} | ${'content'} | ${contentLoadedPayload} | ${content}
+ ${types.RECEIVE_CONTENT_SUCCESS} | ${'originalContent'} | ${contentLoadedPayload} | ${content}
+ ${types.RECEIVE_CONTENT_ERROR} | ${'isLoadingContent'} | ${undefined} | ${false}
+ ${types.SET_CONTENT} | ${'content'} | ${content} | ${content}
+ ${types.SUBMIT_CHANGES} | ${'isSavingChanges'} | ${undefined} | ${true}
+ ${types.SUBMIT_CHANGES_SUCCESS} | ${'savedContentMeta'} | ${savedContentMeta} | ${savedContentMeta}
+ ${types.SUBMIT_CHANGES_SUCCESS} | ${'isSavingChanges'} | ${savedContentMeta} | ${false}
+ ${types.SUBMIT_CHANGES_ERROR} | ${'isSavingChanges'} | ${undefined} | ${false}
+ `(
+ '$mutation sets $stateProperty to $expectedValue',
+ ({ mutation, stateProperty, payload, expectedValue }) => {
+ mutations[mutation](state, payload);
+ expect(state[stateProperty]).toBe(expectedValue);
+ },
+ );
+
+ it(`${types.SUBMIT_CHANGES_SUCCESS} sets originalContent to content current value`, () => {
+ const editedContent = `${content} plus something else`;
+
+ state = createState({
+ originalContent: content,
+ content: editedContent,
+ });
+ mutations[types.SUBMIT_CHANGES_SUCCESS](state);
+
+ expect(state.originalContent).toBe(state.content);
});
});