summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/dispatcher.js83
-rw-r--r--app/assets/javascripts/pages/projects/edit/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/find_file/show/index.js12
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/imports/show/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/issues/edit/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/issues/form.js16
-rw-r--r--app/assets/javascripts/pages/projects/issues/index/index.js18
-rw-r--r--app/assets/javascripts/pages/projects/issues/new/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/issues/show/index.js13
-rw-r--r--app/assets/javascripts/pages/projects/tags/new/index.js9
-rw-r--r--app/assets/javascripts/pages/projects/tree/show/index.js15
-rw-r--r--app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue127
-rw-r--r--app/assets/stylesheets/framework.scss1
-rw-r--r--app/assets/stylesheets/framework/stacked-progress-bar.scss54
-rw-r--r--app/views/projects/jobs/_empty_state.html.haml5
-rw-r--r--app/views/projects/jobs/show.html.haml7
-rw-r--r--changelogs/unreleased/38540-ssh-env-file.yml6
-rw-r--r--changelogs/unreleased/42025-fix-issue-api.yml5
-rw-r--r--doc/articles/numerous_undo_possibilities_in_git/index.md498
-rw-r--r--doc/ci/README.md23
-rw-r--r--doc/ci/examples/README.md13
-rw-r--r--doc/ci/examples/dast.md35
-rw-r--r--doc/ci/examples/sast_docker.md55
-rw-r--r--doc/topics/autodevops/index.md37
-rw-r--r--doc/topics/git/index.md2
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png (renamed from doc/articles/numerous_undo_possibilities_in_git/img/branching.png)bin26245 -> 26245 bytes
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png (renamed from doc/articles/numerous_undo_possibilities_in_git/img/rebase_reset.png)bin43609 -> 43609 bytes
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png (renamed from doc/articles/numerous_undo_possibilities_in_git/img/revert.png)bin28112 -> 28112 bytes
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/index.md497
-rw-r--r--lib/api/circuit_breakers.rb4
-rw-r--r--lib/api/helpers/common_helpers.rb6
-rw-r--r--lib/gitlab/gitaly_client/commit_service.rb2
-rw-r--r--lib/tasks/gitlab/shell.rake10
-rw-r--r--spec/features/projects/jobs_spec.rb14
-rw-r--r--spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js77
-rw-r--r--spec/requests/api/issues_spec.rb9
38 files changed, 1097 insertions, 586 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 328185caaeb..106d4ac0005 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-0.67.0
+0.69.0
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 28014946a39..afa1bc19790 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -1,7 +1,6 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, wrap-iife, no-shadow, consistent-return, one-var, one-var-declaration-per-line, camelcase, default-case, no-new, quotes, no-duplicate-case, no-case-declarations, no-fallthrough, max-len */
import { s__ } from './locale';
import projectSelect from './project_select';
-import IssuableIndex from './issuable_index';
import Milestone from './milestone';
import IssuableForm from './issuable_form';
import LabelsSelect from './labels_select';
@@ -11,34 +10,28 @@ import notificationsDropdown from './notifications_dropdown';
import groupAvatar from './group_avatar';
import GroupLabelSubscription from './group_label_subscription';
import LineHighlighter from './line_highlighter';
-import NewCommitForm from './new_commit_form';
import Project from './project';
import projectAvatar from './project_avatar';
import MergeRequest from './merge_request';
import Compare from './compare';
import initCompareAutocomplete from './compare_autocomplete';
-import ProjectFindFile from './project_find_file';
import ProjectNew from './project_new';
-import projectImport from './project_import';
import Labels from './labels';
import LabelManager from './label_manager';
import Sidebar from './right_sidebar';
import IssuableTemplateSelectors from './templates/issuable_template_selectors';
import Flash from './flash';
import CommitsList from './commits';
-import Issue from './issue';
import BindInOut from './behaviors/bind_in_out';
import SecretValues from './behaviors/secret_values';
import Group from './group';
import ProjectsList from './projects_list';
-import setupProjectEdit from './project_edit';
import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
import UserCallout from './user_callout';
import ShortcutsWiki from './shortcuts_wiki';
import BlobViewer from './blob/viewer/index';
import AutoWidthDropdownSelect from './issuable/auto_width_dropdown_select';
import UsersSelect from './users_select';
-import RefSelectDropdown from './ref_select_dropdown';
import GfmAutoComplete from './gfm_auto_complete';
import Star from './star';
import TreeView from './tree';
@@ -57,7 +50,6 @@ import GlFieldErrors from './gl_field_errors';
import GLForm from './gl_form';
import Shortcuts from './shortcuts';
import ShortcutsNavigation from './shortcuts_navigation';
-import ShortcutsFindFile from './shortcuts_find_file';
import ShortcutsIssuable from './shortcuts_issuable';
import U2FAuthenticate from './u2f/authenticate';
import Members from './members';
@@ -127,21 +119,16 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
shortcut_handler = true;
break;
case 'projects:issues:index':
- if (filteredSearchEnabled) {
- const filteredSearchManager = new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests');
- filteredSearchManager.setup();
- }
- const pagePrefix = page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_';
- new IssuableIndex(pagePrefix);
-
- shortcut_handler = new ShortcutsNavigation();
- new UsersSelect();
+ import('./pages/projects/issues/index')
+ .then(callDefault)
+ .catch(fail);
+ shortcut_handler = true;
break;
case 'projects:issues:show':
- new Issue();
- shortcut_handler = new ShortcutsIssuable();
- new ZenMode();
- initIssuableSidebar();
+ import('./pages/projects/issues/show')
+ .then(callDefault)
+ .catch(fail);
+ shortcut_handler = true;
break;
case 'dashboard:milestones:index':
import('./pages/dashboard/milestones/index')
@@ -232,13 +219,16 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
.catch(fail);
break;
case 'projects:issues:new':
+ import('./pages/projects/issues/new')
+ .then(callDefault)
+ .catch(fail);
+ shortcut_handler = true;
+ break;
case 'projects:issues:edit':
- shortcut_handler = new ShortcutsNavigation();
- new GLForm($('.issue-form'), true);
- new IssuableForm($('.issue-form'));
- new LabelsSelect();
- new MilestoneSelect();
- new IssuableTemplateSelectors();
+ import('./pages/projects/issues/edit')
+ .then(callDefault)
+ .catch(fail);
+ shortcut_handler = true;
break;
case 'projects:merge_requests:creations:new':
const mrNewCompareNode = document.querySelector('.js-merge-request-new-compare');
@@ -266,9 +256,9 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
new AutoWidthDropdownSelect($('.js-target-branch-select')).init();
break;
case 'projects:tags:new':
- new ZenMode();
- new GLForm($('.tag-form'), true);
- new RefSelectDropdown($('.js-branch-select'));
+ import('./pages/projects/tags/new')
+ .then(callDefault)
+ .catch(fail);
break;
case 'projects:snippets:show':
initNotes();
@@ -370,12 +360,14 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
});
break;
case 'projects:edit':
- setupProjectEdit();
- // Initialize expandable settings panels
- initSettingsPanels();
+ import('./pages/projects/edit')
+ .then(callDefault)
+ .catch(fail);
break;
case 'projects:imports:show':
- projectImport();
+ import('./pages/projects/imports/show')
+ .then(callDefault)
+ .catch(fail);
break;
case 'projects:pipelines:new':
case 'projects:pipelines:create':
@@ -435,22 +427,15 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
groupAvatar();
break;
case 'projects:tree:show':
- shortcut_handler = new ShortcutsNavigation();
- new TreeView();
- new BlobViewer();
- new NewCommitForm($('.js-create-dir-form'));
- $('#tree-slider').waitForImages(function() {
- ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath);
- });
+ import('./pages/projects/tree/show')
+ .then(callDefault)
+ .catch(fail);
+ shortcut_handler = true;
break;
case 'projects:find_file:show':
- const findElement = document.querySelector('.js-file-finder');
- const projectFindFile = new ProjectFindFile($(".file-finder-holder"), {
- url: findElement.dataset.fileFindUrl,
- treeUrl: findElement.dataset.findTreeUrl,
- blobUrlTemplate: findElement.dataset.blobUrlTemplate,
- });
- new ShortcutsFindFile(projectFindFile);
+ import('./pages/projects/find_file/show')
+ .then(callDefault)
+ .catch(fail);
shortcut_handler = true;
break;
case 'projects:blob:show':
@@ -504,7 +489,7 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
shortcut_handler = true;
break;
case 'projects:forks:new':
- import(/* webpackChunkName: 'project_fork' */ './project_fork')
+ import('./pages/projects/forks/new')
.then(callDefault)
.catch(fail);
break;
diff --git a/app/assets/javascripts/pages/projects/edit/index.js b/app/assets/javascripts/pages/projects/edit/index.js
new file mode 100644
index 00000000000..7f662ef6b6a
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/edit/index.js
@@ -0,0 +1,8 @@
+import initSettingsPanels from '~/settings_panels';
+import setupProjectEdit from '~/project_edit';
+
+export default () => {
+ setupProjectEdit();
+ // Initialize expandable settings panels
+ initSettingsPanels();
+};
diff --git a/app/assets/javascripts/pages/projects/find_file/show/index.js b/app/assets/javascripts/pages/projects/find_file/show/index.js
new file mode 100644
index 00000000000..42bde0ff779
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/find_file/show/index.js
@@ -0,0 +1,12 @@
+import ProjectFindFile from '~/project_find_file';
+import ShortcutsFindFile from '~/shortcuts_find_file';
+
+export default () => {
+ const findElement = document.querySelector('.js-file-finder');
+ const projectFindFile = new ProjectFindFile($('.file-finder-holder'), {
+ url: findElement.dataset.fileFindUrl,
+ treeUrl: findElement.dataset.findTreeUrl,
+ blobUrlTemplate: findElement.dataset.blobUrlTemplate,
+ });
+ new ShortcutsFindFile(projectFindFile); // eslint-disable-line no-new
+};
diff --git a/app/assets/javascripts/pages/projects/forks/new/index.js b/app/assets/javascripts/pages/projects/forks/new/index.js
new file mode 100644
index 00000000000..7825eb01949
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/forks/new/index.js
@@ -0,0 +1,5 @@
+import ProjectFork from '~/project_fork';
+
+export default () => {
+ new ProjectFork(); // eslint-disable-line no-new
+};
diff --git a/app/assets/javascripts/pages/projects/imports/show/index.js b/app/assets/javascripts/pages/projects/imports/show/index.js
new file mode 100644
index 00000000000..378f7b3f38b
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/imports/show/index.js
@@ -0,0 +1,5 @@
+import ProjectImport from '~/project_import';
+
+export default () => {
+ new ProjectImport(); // eslint-disable-line no-new
+};
diff --git a/app/assets/javascripts/pages/projects/issues/edit/index.js b/app/assets/javascripts/pages/projects/issues/edit/index.js
new file mode 100644
index 00000000000..7f27f379d8c
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/issues/edit/index.js
@@ -0,0 +1,5 @@
+import initForm from '../form';
+
+export default () => {
+ initForm();
+};
diff --git a/app/assets/javascripts/pages/projects/issues/form.js b/app/assets/javascripts/pages/projects/issues/form.js
new file mode 100644
index 00000000000..5c7daf84738
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/issues/form.js
@@ -0,0 +1,16 @@
+/* eslint-disable no-new */
+import GLForm from '~/gl_form';
+import IssuableForm from '~/issuable_form';
+import LabelsSelect from '~/labels_select';
+import MilestoneSelect from '~/milestone_select';
+import ShortcutsNavigation from '~/shortcuts_navigation';
+import IssuableTemplateSelectors from '~/templates/issuable_template_selectors';
+
+export default () => {
+ new ShortcutsNavigation();
+ new GLForm($('.issue-form'), true);
+ new IssuableForm($('.issue-form'));
+ new LabelsSelect();
+ new MilestoneSelect();
+ new IssuableTemplateSelectors();
+};
diff --git a/app/assets/javascripts/pages/projects/issues/index/index.js b/app/assets/javascripts/pages/projects/issues/index/index.js
new file mode 100644
index 00000000000..fd395a45f00
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/issues/index/index.js
@@ -0,0 +1,18 @@
+
+/* eslint-disable no-new */
+
+import IssuableIndex from '~/issuable_index';
+import ShortcutsNavigation from '~/shortcuts_navigation';
+import UsersSelect from '~/users_select';
+
+export default () => {
+ const filteredSearchEnabled = gl.FilteredSearchManager && document.querySelector('.filtered-search');
+ if (filteredSearchEnabled) {
+ const filteredSearchManager = new gl.FilteredSearchManager('issues');
+ filteredSearchManager.setup();
+ }
+ new IssuableIndex('issue_');
+
+ new ShortcutsNavigation();
+ new UsersSelect();
+};
diff --git a/app/assets/javascripts/pages/projects/issues/new/index.js b/app/assets/javascripts/pages/projects/issues/new/index.js
new file mode 100644
index 00000000000..7f27f379d8c
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/issues/new/index.js
@@ -0,0 +1,5 @@
+import initForm from '../form';
+
+export default () => {
+ initForm();
+};
diff --git a/app/assets/javascripts/pages/projects/issues/show/index.js b/app/assets/javascripts/pages/projects/issues/show/index.js
new file mode 100644
index 00000000000..48ed8fb2243
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/issues/show/index.js
@@ -0,0 +1,13 @@
+
+/* eslint-disable no-new */
+import initIssuableSidebar from '~/init_issuable_sidebar';
+import Issue from '~/issue';
+import ShortcutsIssuable from '~/shortcuts_issuable';
+import ZenMode from '~/zen_mode';
+
+export default () => {
+ new Issue();
+ new ShortcutsIssuable();
+ new ZenMode();
+ initIssuableSidebar();
+};
diff --git a/app/assets/javascripts/pages/projects/tags/new/index.js b/app/assets/javascripts/pages/projects/tags/new/index.js
new file mode 100644
index 00000000000..dacc2875c8c
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/tags/new/index.js
@@ -0,0 +1,9 @@
+import RefSelectDropdown from '../../../../ref_select_dropdown';
+import ZenMode from '../../../../zen_mode';
+import GLForm from '../../../../gl_form';
+
+export default () => {
+ new ZenMode(); // eslint-disable-line no-new
+ new GLForm($('.tag-form'), true); // eslint-disable-line no-new
+ new RefSelectDropdown($('.js-branch-select')); // eslint-disable-line no-new
+};
diff --git a/app/assets/javascripts/pages/projects/tree/show/index.js b/app/assets/javascripts/pages/projects/tree/show/index.js
new file mode 100644
index 00000000000..28a0160f47d
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/tree/show/index.js
@@ -0,0 +1,15 @@
+import TreeView from '../../../../tree';
+import ShortcutsNavigation from '../../../../shortcuts_navigation';
+import BlobViewer from '../../../../blob/viewer';
+import NewCommitForm from '../../../../new_commit_form';
+import { ajaxGet } from '../../../../lib/utils/common_utils';
+
+export default () => {
+ new ShortcutsNavigation(); // eslint-disable-line no-new
+ new TreeView(); // eslint-disable-line no-new
+ new BlobViewer(); // eslint-disable-line no-new
+ new NewCommitForm($('.js-create-dir-form')); // eslint-disable-line no-new
+ $('#tree-slider').waitForImages(() =>
+ ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath));
+};
+
diff --git a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
new file mode 100644
index 00000000000..86f06c8d266
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
@@ -0,0 +1,127 @@
+<script>
+import tooltip from '~/vue_shared/directives/tooltip';
+
+export default {
+ directives: {
+ tooltip,
+ },
+ props: {
+ cssClass: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ successLabel: {
+ type: String,
+ required: true,
+ },
+ failureLabel: {
+ type: String,
+ required: true,
+ },
+ neutralLabel: {
+ type: String,
+ required: true,
+ },
+ successCount: {
+ type: Number,
+ required: true,
+ },
+ failureCount: {
+ type: Number,
+ required: true,
+ },
+ totalCount: {
+ type: Number,
+ required: true,
+ },
+ },
+ computed: {
+ neutralCount() {
+ return this.totalCount - this.successCount - this.failureCount;
+ },
+ successPercent() {
+ return this.getPercent(this.successCount);
+ },
+ successBarStyle() {
+ return this.barStyle(this.successPercent);
+ },
+ successTooltip() {
+ return this.getTooltip(this.successLabel, this.successCount);
+ },
+ failurePercent() {
+ return this.getPercent(this.failureCount);
+ },
+ failureBarStyle() {
+ return this.barStyle(this.failurePercent);
+ },
+ failureTooltip() {
+ return this.getTooltip(this.failureLabel, this.failureCount);
+ },
+ neutralPercent() {
+ return this.getPercent(this.neutralCount);
+ },
+ neutralBarStyle() {
+ return this.barStyle(this.neutralPercent);
+ },
+ neutralTooltip() {
+ return this.getTooltip(this.neutralLabel, this.neutralCount);
+ },
+ },
+ methods: {
+ getPercent(count) {
+ return Math.ceil((count / this.totalCount) * 100);
+ },
+ barStyle(percent) {
+ return `width: ${percent}%;`;
+ },
+ getTooltip(label, count) {
+ return `${label}: ${count}`;
+ },
+ },
+};
+</script>
+
+<template>
+ <div
+ class="stacked-progress-bar"
+ :class="cssClass"
+ >
+ <span
+ v-if="!totalCount"
+ class="status-unavailable"
+ >
+ {{ __("Not available") }}
+ </span>
+ <span
+ v-tooltip
+ v-if="successPercent"
+ class="status-green"
+ data-placement="bottom"
+ :title="successTooltip"
+ :style="successBarStyle"
+ >
+ {{ successPercent }}%
+ </span>
+ <span
+ v-tooltip
+ v-if="neutralPercent"
+ class="status-neutral"
+ data-placement="bottom"
+ :title="neutralTooltip"
+ :style="neutralBarStyle"
+ >
+ {{ neutralPercent }}%
+ </span>
+ <span
+ v-tooltip
+ v-if="failurePercent"
+ class="status-red"
+ data-placement="bottom"
+ :title="failureTooltip"
+ :style="failureBarStyle"
+ >
+ {{ failurePercent }}%
+ </span>
+ </div>
+</template>
diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss
index 43b16d3cf7d..cff47ea76ec 100644
--- a/app/assets/stylesheets/framework.scss
+++ b/app/assets/stylesheets/framework.scss
@@ -59,3 +59,4 @@
@import "framework/snippets";
@import "framework/memory_graph";
@import "framework/responsive_tables";
+@import "framework/stacked-progress-bar";
diff --git a/app/assets/stylesheets/framework/stacked-progress-bar.scss b/app/assets/stylesheets/framework/stacked-progress-bar.scss
new file mode 100644
index 00000000000..4869cda73e5
--- /dev/null
+++ b/app/assets/stylesheets/framework/stacked-progress-bar.scss
@@ -0,0 +1,54 @@
+.stacked-progress-bar {
+ display: flex;
+ height: 16px;
+ border-radius: 10px;
+ overflow: hidden;
+ background-color: $theme-gray-100;
+
+ .status-unavailable,
+ .status-green,
+ .status-neutral,
+ .status-red, {
+ height: 100%;
+ min-width: 25px;
+ padding: 0 5px;
+ font-size: $tooltip-font-size;
+ font-weight: normal;
+ color: $white-light;
+ line-height: 16px;
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+
+ .status-unavailable {
+ padding: 0 10px;
+ color: $theme-gray-700;
+ }
+
+ .status-green {
+ background-color: $green-500;
+
+ &:hover {
+ background-color: $green-600;
+ }
+ }
+
+ .status-neutral {
+ background-color: $theme-gray-200;
+ color: $gl-gray-dark;
+
+ &:hover {
+ background-color: $theme-gray-300;
+ }
+ }
+
+ .status-red {
+ background-color: $red-500;
+
+ &:hover {
+ background-color: $red-600;
+ }
+ }
+}
diff --git a/app/views/projects/jobs/_empty_state.html.haml b/app/views/projects/jobs/_empty_state.html.haml
index c66313bdbf3..311934d9c33 100644
--- a/app/views/projects/jobs/_empty_state.html.haml
+++ b/app/views/projects/jobs/_empty_state.html.haml
@@ -1,7 +1,7 @@
- illustration = local_assigns.fetch(:illustration)
- illustration_size = local_assigns.fetch(:illustration_size)
- title = local_assigns.fetch(:title)
-- content = local_assigns.fetch(:content)
+- content = local_assigns.fetch(:content, nil)
- action = local_assigns.fetch(:action, nil)
.row.empty-state
@@ -11,7 +11,8 @@
.col-xs-12
.text-content
%h4.text-center= title
- %p= content
+ - if content
+ %p= content
- if action
.text-center
= action
diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml
index 8b05440fc78..1e6d6f67e66 100644
--- a/app/views/projects/jobs/show.html.haml
+++ b/app/views/projects/jobs/show.html.haml
@@ -93,14 +93,13 @@
illustration: 'illustrations/manual_action.svg',
illustration_size: 'svg-394',
title: _('This job requires a manual action'),
- content: _('This job depends on a user to trigger its process. Often they are used to deploy code to production environments.'),
- action: ( link_to _('Trigger this manual action'), play_project_job_path(@project, @build), class: 'btn btn-primary', title: _('Trigger this manual action') )
+ content: _('This job depends on a user to trigger its process. Often they are used to deploy code to production environments'),
+ action: ( link_to _('Trigger this manual action'), play_project_job_path(@project, @build), method: :post, class: 'btn btn-primary', title: _('Trigger this manual action') )
- else
= render 'empty_state',
illustration: 'illustrations/job_not_triggered.svg',
illustration_size: 'svg-306',
- title: _('This job has not been triggered yet'),
- content: _('This job depends on upstream jobs that need to succeed in order for this job to be triggered.')
+ title: _('This job has not been triggered yet')
= render "sidebar"
diff --git a/changelogs/unreleased/38540-ssh-env-file.yml b/changelogs/unreleased/38540-ssh-env-file.yml
new file mode 100644
index 00000000000..5ada0ede76d
--- /dev/null
+++ b/changelogs/unreleased/38540-ssh-env-file.yml
@@ -0,0 +1,6 @@
+---
+title: 'Closes #38540 - Remove .ssh/environment file that now breaks the gitlab:check
+ rake task'
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/42025-fix-issue-api.yml b/changelogs/unreleased/42025-fix-issue-api.yml
new file mode 100644
index 00000000000..abb83bb2fad
--- /dev/null
+++ b/changelogs/unreleased/42025-fix-issue-api.yml
@@ -0,0 +1,5 @@
+---
+title: "[API] Fix creating issue when assignee_id is empty"
+merge_request:
+author:
+type: fixed
diff --git a/doc/articles/numerous_undo_possibilities_in_git/index.md b/doc/articles/numerous_undo_possibilities_in_git/index.md
index 895bbccec08..3f46ee9a5e6 100644
--- a/doc/articles/numerous_undo_possibilities_in_git/index.md
+++ b/doc/articles/numerous_undo_possibilities_in_git/index.md
@@ -1,497 +1 @@
-# Numerous undo possibilities in Git
-
-> **Article [Type](../../development/writing_documentation.md#types-of-technical-articles):** tutorial ||
-> **Level:** intermediary ||
-> **Author:** [Crt Mori](https://gitlab.com/Letme) ||
-> **Publication date:** 2017-08-17
-
-## Introduction
-
-In this tutorial, we will show you different ways of undoing your work in Git, for which
-we will assume you have a basic working knowledge of. Check GitLab's
-[Git documentation](../../topics/git/index.md#git-documentation) for reference.
-Also, we will only provide some general info of the commands, which is enough
-to get you started for the easy cases/examples, but for anything more advanced please refer to the [Git book](https://git-scm.com/book/en/v2).
-
-We will explain a few different techniques to undo your changes based on the stage
-of the change in your current development. Also, keep in mind that [nothing in
-Git is really deleted.][git-autoclean-ref]
-This means that until Git automatically cleans detached commits (which cannot be
-accessed by branch or tag) it will be possible to view them with `git reflog` command
-and access them with direct commit-id. Read more about _[redoing the undo](#redoing-the-undo)_ on the section below.
-
-This guide is organized depending on the [stage of development][git-basics]
-where you want to undo your changes from and if they were shared with other developers
-or not. Because Git is tracking changes a created or edited file is in the unstaged state
-(if created it is untracked by Git). After you add it to a repository (`git add`) you put
-a file into the **staged** state, which is then committed (`git commit`) to your
-local repository. After that, file can be shared with other developers (`git push`).
-Here's what we'll cover in this tutorial:
-
- - [Undo local changes](#undo-local-changes) which were not pushed to remote repository
-
- - Before you commit, in both unstaged and staged state
- - After you committed
-
- - Undo changes after they are pushed to remote repository
-
- - [Without history modification](#undo-remote-changes-without-changing-history) (preferred way)
- - [With history modification](#undo-remote-changes-with-modifying-history) (requires
- coordination with team and force pushes).
-
- - [Usecases when modifying history is generally acceptable](#where-modifying-history-is-generally-acceptable)
- - [How to modify history](#how-modifying-history-is-done)
- - [How to remove sensitive information from repository](#deleting-sensitive-information-from-commits)
-
-
-### Branching strategy
-
-[Git][git-official] is a de-centralized version control system, which means that beside regular
-versioning of the whole repository, it has possibilities to exchange changes
-with other repositories. To avoid chaos with
-[multiple sources of truth][git-distributed], various
-development workflows have to be followed, and it depends on your internal
-workflow how certain changes or commits can be undone or changed.
-[GitLab Flow][gitlab-flow] provides a good
-balance between developers clashing with each other while
-developing the same feature and cooperating seamlessly, but it does not enable
-joined development of the same feature by multiple developers by default.
-When multiple developers develop the same feature on the same branch, clashing
-with every synchronization is unavoidable, but a proper or chosen Git Workflow will
-prevent that anything is lost or out of sync when feature is complete. You can also
-read through this blog post on [Git Tips & Tricks][gitlab-git-tips-n-tricks]
-to learn how to easily **do** things in Git.
-
-
-## Undo local changes
-
-Until you push your changes to any remote repository, they will only affect you.
-That broadens your options on how to handle undoing them. Still, local changes
-can be on various stages and each stage has a different approach on how to tackle them.
-
-
-### Unstaged local changes (before you commit)
-
-When a change is made, but it is not added to the staged tree, Git itself
-proposes a solution to discard changes to certain file.
-
-Suppose you edited a file to change the content using your favorite editor:
-
-```shell
-vim <file>
-```
-
-Since you did not `git add <file>` to staging, it should be under unstaged files (or
-untracked if file was created). You can confirm that with:
-
-```shell
-$ git status
-On branch master
-Your branch is up-to-date with 'origin/master'.
-Changes not staged for commit:
- (use "git add <file>..." to update what will be committed)
- (use "git checkout -- <file>..." to discard changes in working directory)
-
- modified: <file>
-no changes added to commit (use "git add" and/or "git commit -a")
-```
-
-At this point there are 3 options to undo the local changes you have:
-
- - Discard all local changes, but save them for possible re-use [later](#quickly-save-local-changes)
-
- ```shell
- git stash
- ```
-
- - Discarding local changes (permanently) to a file
-
- ```shell
- git checkout -- <file>
- ```
-
- - Discard all local changes to all files permanently
-
- ```shell
- git reset --hard
- ```
-
-
-Before executing `git reset --hard`, keep in mind that there is also a way to
-just temporary store the changes without committing them using `git stash`.
-This command resets the changes to all files, but it also saves them in case
-you would like to apply them at some later time. You can read more about it in
-[section below](#quickly-save-local-changes).
-
-### Quickly save local changes
-
-You are working on a feature when a boss drops by with an urgent task. Since your
-feature is not complete, but you need to swap to another branch, you can use
-`git stash` to save what you had done, swap to another branch, commit, push,
-test, then get back to previous feature branch, do `git stash pop` and continue
-where you left.
-
-The example above shows that discarding all changes is not always a preferred option,
-but Git provides a way to save them for later, while resetting the repository to state without
-them. This is achieved by Git stashing command `git stash`, which in fact saves your
-current work and runs `git reset --hard`, but it also has various
-additional options like:
-
- - `git stash save`, which enables including temporary commit message, which will help you identify changes, among with other options
- - `git stash list`, which lists all previously stashed commits (yes, there can be more) that were not `pop`ed
- - `git stash pop`, which redoes previously stashed changes and removes them from stashed list
- - `git stash apply`, which redoes previously stashed changes, but keeps them on stashed list
-
-### Staged local changes (before you commit)
-
-Let's say you have added some files to staging, but you want to remove them from the
-current commit, yet you want to retain those changes - just move them outside
-of the staging tree. You also have an option to discard all changes with
-`git reset --hard` or think about `git stash` [as described earlier.](#quickly-save-local-changes)
-
-Lets start the example by editing a file, with your favorite editor, to change the
-content and add it to staging
-
-```
-vim <file>
-git add <file>
-```
-
-The file is now added to staging as confirmed by `git status` command:
-
-```shell
-$ git status
-On branch master
-Your branch is up-to-date with 'origin/master'.
-Changes to be committed:
- (use "git reset HEAD <file>..." to unstage)
-
- new file: <file>
-```
-
-Now you have 4 options to undo your changes:
-
- - Unstage the file to current commit (HEAD)
-
- ```shell
- git reset HEAD <file>
- ```
-
- - Unstage everything - retain changes
-
- ```shell
- git reset
- ```
-
- - Discard all local changes, but save them for [later](#quickly-save-local-changes)
-
- ```shell
- git stash
- ```
-
- - Discard everything permanently
-
- ```shell
- git reset --hard
- ```
-
-## Committed local changes
-
-Once you commit, your changes are recorded by the version control system.
-Because you haven't pushed to your remote repository yet, your changes are
-still not public (or shared with other developers). At this point, undoing
-things is a lot easier, we have quite some workaround options. Once you push
-your code, you'll have less options to troubleshoot your work.
-
-### Without modifying history
-
-Through the development process some of the previously committed changes do not
-fit anymore in the end solution, or are source of the bugs. Once you find the
-commit which triggered bug, or once you have a faulty commit, you can simply
-revert it with `git revert commit-id`. This command inverts (swaps) the additions and
-deletions in that commit, so that it does not modify history. Retaining history
-can be helpful in future to notice that some changes have been tried
-unsuccessfully in the past.
-
-In our example we will assume there are commits `A`,`B`,`C`,`D`,`E` committed in this order: `A-B-C-D-E`,
-and `B` is the commit you want to undo. There are many different ways to identify commit
-`B` as bad, one of them is to pass a range to `git bisect` command. The provided range includes
-last known good commit (we assume `A`) and first known bad commit (where bug was detected - we will assume `E`).
-
-```shell
-git bisect A..E
-```
-
-Bisect will provide us with commit-id of the middle commit to test, and then guide us
-through simple bisection process. You can read more about it [in official Git Tools][git-debug]
-In our example we will end up with commit `B`, that introduced bug/error. We have
-4 options on how to remove it (or part of it) from our repository.
-
-- Undo (swap additions and deletions) changes introduced by commit `B`.
-
- ```shell
- git revert commit-B-id
- ```
-
-- Undo changes on a single file or directory from commit `B`, but retain them in the staged state
-
- ```shell
- git checkout commit-B-id <file>
- ```
-
-- Undo changes on a single file or directory from commit `B`, but retain them in the unstaged state
-
- ```shell
- git reset commit-B-id <file>
- ```
-
- - There is one command we also must not forget: **creating a new branch**
- from the point where changes are not applicable or where the development has hit a
- dead end. For example you have done commits `A-B-C-D` on your feature-branch
- and then you figure `C` and `D` are wrong. At this point you either reset to `B`
- and do commit `F` (which will cause problems with pushing and if forced pushed also with other developers)
- since branch now looks `A-B-F`, which clashes with what other developers have locally (you will
- [change history](#with-history-modification)), or you simply checkout commit `B` create
- a new branch and do commit `F`. In the last case, everyone else can still do their work while you
- have your new way to get it right and merge it back in later. Alternatively, with GitLab,
- you can [cherry-pick](../../user/project/merge_requests/cherry_pick_changes.md#cherry-picking-a-commit)
- that commit into a new merge request.
-
- ![Create a new branch to avoid clashing](img/branching.png)
-
- ```shell
- git checkout commit-B-id
- git checkout -b new-path-of-feature
- # Create <commit F>
- git commit -a
- ```
-
-### With history modification
-
-There is one command for history modification and that is `git rebase`. Command
-provides interactive mode (`-i` flag) which enables you to:
-
- - **reword** commit messages (there is also `git commit --amend` for editing
- last commit message)
- - **edit** the commit content (changes introduced by commit) and message
- - **squash** multiple commits into a single one, and have a custom or aggregated
- commit message
- - **drop** commits - simply delete them
- - and few more options
-
-Let us check few examples. Again there are commits `A-B-C-D` where you want to
-delete commit `B`.
-
-- Rebase the range from current commit D to A:
-
- ```shell
- git rebase -i A
- ```
-
-- Command opens your favorite editor where you write `drop` in front of commit
- `B`, but you leave default `pick` with all other commits. Save and exit the
- editor to perform a rebase. Remember: if you want to cancel delete whole
- file content before saving and exiting the editor
-
-In case you want to modify something introduced in commit `B`.
-
-- Rebase the range from current commit D to A:
-
- ```shell
- git rebase -i A
- ```
-
-- Command opens your favorite text editor where you write `edit` in front of commit
- `B`, but leave default `pick` with all other commits. Save and exit the editor to
- perform a rebase
-
-- Now do your edits and commit changes:
-
- ```shell
- git commit -a
- ```
-
-You can find some more examples in [below section where we explain how to modify
-history](#how-modifying-history-is-done)
-
-
-### Redoing the Undo
-
-Sometimes you realize that the changes you undid were useful and you want them
-back. Well because of first paragraph you are in luck. Command `git reflog`
-enables you to *recall* detached local commits by referencing or applying them
-via commit-id. Although, do not expect to see really old commits in reflog, because
-Git regularly [cleans the commits which are *unreachable* by branches or tags][git-autoclean-ref].
-
-To view repository history and to track older commits you can use below command:
-
-```shell
-$ git reflog show
-
-# Example output:
-b673187 HEAD@{4}: merge 6e43d5987921bde189640cc1e37661f7f75c9c0b: Merge made by the 'recursive' strategy.
-eb37e74 HEAD@{5}: rebase -i (finish): returning to refs/heads/master
-eb37e74 HEAD@{6}: rebase -i (pick): Commit C
-97436c6 HEAD@{7}: rebase -i (start): checkout 97436c6eec6396c63856c19b6a96372705b08b1b
-...
-88f1867 HEAD@{12}: commit: Commit D
-97436c6 HEAD@{13}: checkout: moving from 97436c6eec6396c63856c19b6a96372705b08b1b to test
-97436c6 HEAD@{14}: checkout: moving from master to 97436c6
-05cc326 HEAD@{15}: commit: Commit C
-6e43d59 HEAD@{16}: commit: Commit B
-```
-
-Output of command shows repository history. In first column there is commit-id,
-in following column, number next to `HEAD` indicates how many commits ago something
-was made, after that indicator of action that was made (commit, rebase, merge, ...)
-and then on end description of that action.
-
-## Undo remote changes without changing history
-
-This topic is roughly same as modifying committed local changes without modifying
-history. **It should be the preferred way of undoing changes on any remote repository
-or public branch.** Keep in mind that branching is the best solution when you want
-to retain the history of faulty development, yet start anew from certain point. Branching
-enables you to include the existing changes in new development (by merging) and
-it also provides a clear timeline and development structure.
-
-![Use revert to keep branch flowing](img/revert.png)
-
-If you want to revert changes introduced in certain `commit-id` you can simply
-revert that `commit-id` (swap additions and deletions) in newly created commit:
-You can do this with
-
-```shell
-git revert commit-id
-```
-
-or creating a new branch:
-
-```shell
-git checkout commit-id
-git checkout -b new-path-of-feature
-```
-
-## Undo remote changes with modifying history
-
-This is useful when you want to *hide* certain things - like secret keys,
-passwords, SSH keys, etc. It is and should not be used to hide mistakes, as
-it will make it harder to debug in case there are some other bugs. The main
-reason for this is that you loose the real development progress. **Also keep in
-mind that, even with modified history, commits are just detached and can still be
-accessed through commit-id** - at least until all repositories perform
-the cleanup of detached commits (happens automatically).
-
-![Modifying history causes problems on remote branch](img/rebase_reset.png)
-
-### Where modifying history is generally acceptable
-
-Modified history breaks the development chain of other developers, as changed
-history does not have matching commits'ids. For that reason it should not
-be used on any public branch or on branch that *might* be used by other
-developers. When contributing to big open source repositories (e.g. [GitLab CE][gitlab-ce]),
-it is acceptable to *squash* commits into a single one, to present
-a nicer history of your contribution.
-Keep in mind that this also removes the comments attached to certain commits
-in merge requests, so if you need to retain traceability in GitLab, then
-modifying history is not acceptable.
-A feature-branch of a merge request is a public branch and might be used by
-other developers, but project process and rules might allow or require
-you to use `git rebase` (command that changes history) to reduce number of
-displayed commits on target branch after reviews are done (for example
-GitLab). There is a `git merge --squash` command which does exactly that
-(squashes commits on feature-branch to a single commit on target branch
-at merge).
-
->**Note:**
-Never modify the commit history of `master` or shared branch
-
-### How modifying history is done
-
-After you know what you want to modify (how far in history or how which range of
-old commits), use `git rebase -i commit-id`. This command will then display all the commits from
-current version to chosen commit-id and allow modification, squashing, deletion
-of that commits.
-
-```shell
-$ git rebase -i commit1-id..commit3-id
-pick <commit1-id> <commit1-commit-message>
-pick <commit2-id> <commit2-commit-message>
-pick <commit3-id> <commit3-commit-message>
-
-# Rebase commit1-id..commit3-id onto <commit4-id> (3 command(s))
-#
-# Commands:
-# p, pick = use commit
-# r, reword = use commit, but edit the commit message
-# e, edit = use commit, but stop for amending
-# s, squash = use commit, but meld into previous commit
-# f, fixup = like "squash", but discard this commit's log message
-# x, exec = run command (the rest of the line) using shell
-# d, drop = remove commit
-#
-# These lines can be re-ordered; they are executed from top to bottom.
-#
-# If you remove a line here THAT COMMIT WILL BE LOST.
-#
-# However, if you remove everything, the rebase will be aborted.
-#
-# Note that empty commits are commented out
-```
-
->**Note:**
-It is important to notice that comment from the output clearly states that, if
-you decide to abort, then do not just close your editor (as that will in-fact
-modify history), but remove all uncommented lines and save.
-
-That is one of the reasons why `git rebase` should be used carefully on
-shared and remote branches. But don't worry, there will be nothing broken until
-you push back to the remote repository (so you can freely explore the
-different outcomes locally).
-
-```shell
-# Modify history from commit-id to HEAD (current commit)
-git rebase -i commit-id
-```
-
-### Deleting sensitive information from commits
-
-Git also enables you to delete sensitive information from your past commits and
-it does modify history in the progress. That is why we have included it in this
-section and not as a standalone topic. To do so, you should run the
-`git filter-branch`, which enables you to rewrite history with
-[certain filters][git-filters-manual].
-This command uses rebase to modify history and if you want to remove certain
-file from history altogether use:
-
-```shell
-git filter-branch --tree-filter 'rm filename' HEAD
-```
-
-Since `git filter-branch` command might be slow on big repositories, there are
-tools that can use some of Git specifics to enable faster execution of common
-tasks (which is exactly what removing sensitive information file is about).
-An alternative is [BFG Repo-cleaner][bfg-repo-cleaner]. Keep in mind that these
-tools are faster because they do not provide a same fully feature set as `git filter-branch`
-does, but focus on specific usecases.
-
-## Conclusion
-
-There are various options of undoing your work with any version control system, but
-because of de-centralized nature of Git, these options are multiplied (or limited)
-depending on the stage of your process. Git also enables rewriting history, but that
-should be avoided as it might cause problems when multiple developers are
-contributing to the same codebase.
-
-<!-- Identifiers, in alphabetical order -->
-
-[bfg-repo-cleaner]: https://rtyley.github.io/bfg-repo-cleaner/
-[git-autoclean-ref]: https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery
-[git-basics]: https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository
-[git-debug]: https://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git
-[git-distributed]: https://git-scm.com/about/distributed
-[git-filters-manual]: https://git-scm.com/docs/git-filter-branch#_options
-[git-official]: https://git-scm.com/
-[gitlab-ce]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#contribution-acceptance-criteria
-[gitlab-flow]: https://about.gitlab.com/2014/09/29/gitlab-flow/
-[gitlab-git-tips-n-tricks]: https://about.gitlab.com/2016/12/08/git-tips-and-tricks/
+This document was moved to [another location](../../topics/git/numerous_undo_possibilities_in_git/index.md).
diff --git a/doc/ci/README.md b/doc/ci/README.md
index 3a10365af77..e2cf55490c7 100644
--- a/doc/ci/README.md
+++ b/doc/ci/README.md
@@ -93,17 +93,6 @@ Leverage the power of Docker to run your CI pipelines.
See the documentation on [GitLab Pages](../user/project/pages/index.md).
-## Special configuration (GitLab admin)
-
-As a GitLab administrator, you can change the default behavior of GitLab CI/CD in
-your whole GitLab instance as well as in each project.
-
-- **Project specific:**
- - [Pipelines settings](../user/project/pipelines/settings.md)
- - [Learn how to enable or disable GitLab CI](enable_or_disable_ci.md)
-- **Affecting the whole GitLab instance:**
- - [Continuous Integration admin settings](../user/admin_area/settings/continuous_integration.md)
-
## Examples
Check the [GitLab CI/CD examples](examples/README.md) for a collection of tutorials and guides on setting up your CI/CD pipeline for various programming languages, frameworks,
@@ -115,6 +104,18 @@ and operating systems.
- Article (2016-05-05): [Getting Started with GitLab and Shippable Continuous Integration](https://about.gitlab.com/2016/05/05/getting-started-gitlab-and-shippable/)
- Article (2016-04-19): [GitLab Partners with DigitalOcean to make Continuous Integration faster, safer, and more affordable](https://about.gitlab.com/2016/04/19/gitlab-partners-with-digitalocean-to-make-continuous-integration-faster-safer-and-more-affordable/)
+## Special configuration (GitLab admin)
+
+As a GitLab administrator, you can change the default behavior of GitLab CI/CD in
+your whole GitLab instance as well as in each project.
+
+- [Continuous Integration admin settings](../administration/index.md#continuous-integration-settings)
+- **Project specific:**
+ - [Pipelines settings](../user/project/pipelines/settings.md)
+ - [Learn how to enable or disable GitLab CI](enable_or_disable_ci.md)
+- **Affecting the whole GitLab instance:**
+ - [Continuous Integration admin settings](../user/admin_area/settings/continuous_integration.md)
+
## Breaking changes
- [CI variables renaming for GitLab 9.0](variables/README.md#9-0-renaming) Read about the
diff --git a/doc/ci/examples/README.md b/doc/ci/examples/README.md
index b53bd79f39e..0109e77935a 100644
--- a/doc/ci/examples/README.md
+++ b/doc/ci/examples/README.md
@@ -41,6 +41,19 @@ There's also a collection of repositories with [example projects](https://gitlab
[Analyze code quality with the Code Climate CLI](code_climate.md).
+### Static Application Security Testing (SAST)
+
+- **(EEU)** [Scan your code for vulnerabilities](https://docs.gitlab.com/ee/ci/examples/sast.html)
+- [Scan your Docker images for vulnerabilities](sast_docker.md)
+
+### Dynamic Application Security Testing (DAST)
+
+Scan your app for vulnerabilities with GitLab [Dynamic Application Security Testing (DAST)](dast.md).
+
+### Browser Performance Testing with Sitespeed.io
+
+Analyze your [browser performance with Sitespeed.io](browser_performance.md).
+
### GitLab CI/CD for Review Apps
- [Example project](https://gitlab.com/gitlab-examples/review-apps-nginx/) that shows how to use GitLab CI/CD for [Review Apps](../review_apps/index.html).
diff --git a/doc/ci/examples/dast.md b/doc/ci/examples/dast.md
new file mode 100644
index 00000000000..16ff8d5bb3e
--- /dev/null
+++ b/doc/ci/examples/dast.md
@@ -0,0 +1,35 @@
+# Dynamic Application Security Testing with GitLab CI/CD
+
+This example shows how to run
+[Dynamic Application Security Testing (DAST)](https://en.wikipedia.org/wiki/Dynamic_program_analysis)
+on your project's source code by using GitLab CI/CD.
+
+DAST is using the popular open source tool
+[OWASP ZAProxy](https://github.com/zaproxy/zaproxy) to perform an analysis.
+
+All you need is a GitLab Runner with the Docker executor (the shared Runners on
+GitLab.com will work fine). You can then add a new job to `.gitlab-ci.yml`,
+called `dast`:
+
+```yaml
+dast:
+ image: owasp/zap2docker-stable
+ script:
+ - mkdir /zap/wrk/
+ - /zap/zap-baseline.py -J gl-dast-report.json -t https://example.com || true
+ - cp /zap/wrk/gl-dast-report.json .
+ artifacts:
+ paths: [gl-dast-report.json]
+```
+
+The above example will create a `dast` job in your CI pipeline and will allow
+you to download and analyze the report artifact in JSON format.
+
+TIP: **Tip:**
+Starting with [GitLab Enterprise Edition Ultimate][ee] 10.4, this information will
+be automatically extracted and shown right in the merge request widget. To do
+so, the CI job must be named `dast` and the artifact path must be
+`gl-dast-report.json`.
+[Learn more on dynamic application security testing results shown in merge requests](https://docs.gitlab.com/ee/user/project/merge_requests/dast.html).
+
+[ee]: https://about.gitlab.com/gitlab-ee/
diff --git a/doc/ci/examples/sast_docker.md b/doc/ci/examples/sast_docker.md
new file mode 100644
index 00000000000..d99cfe93afa
--- /dev/null
+++ b/doc/ci/examples/sast_docker.md
@@ -0,0 +1,55 @@
+# Static Application Security Testing for Docker containers with GitLab CI/CD
+
+You can check your Docker images (or more precisely the containers) for known
+vulnerabilities by using [Clair](https://github.com/coreos/clair) and
+[clair-scanner](https://github.com/arminc/clair-scanner), two open source tools
+for Vulnerability Static Analysis for containers.
+
+All you need is a GitLab Runner with the Docker executor (the shared Runners on
+GitLab.com will work fine). You can then add a new job to `.gitlab-ci.yml`,
+called `sast:container`:
+
+```yaml
+sast:container:
+ image: docker:latest
+ variables:
+ DOCKER_DRIVER: overlay2
+ ## Define two new variables based on GitLab's CI/CD predefined variables
+ ## https://docs.gitlab.com/ee/ci/variables/#predefined-variables-environment-variables
+ CI_APPLICATION_REPOSITORY: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG
+ CI_APPLICATION_TAG: $CI_COMMIT_SHA
+ allow_failure: true
+ services:
+ - docker:dind
+ script:
+ - docker run -d --name db arminc/clair-db:latest
+ - docker run -p 6060:6060 --link db:postgres -d --name clair arminc/clair-local-scan:v2.0.1
+ - apk add -U wget ca-certificates
+ - docker pull ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG}
+ - wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64
+ - mv clair-scanner_linux_amd64 clair-scanner
+ - chmod +x clair-scanner
+ - touch clair-whitelist.yml
+ - ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r gl-sast-container-report.json -l clair.log -w clair-whitelist.yml ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} || true
+ artifacts:
+ paths: [gl-sast-container-report.json]
+```
+
+The above example will create a `sast:container` job in your CI/CD pipeline, pull
+the image from the [Container Registry](../../user/project/container_registry.md)
+(whose name is defined from the two `CI_APPLICATION_` variables) and scan it
+for possible vulnerabilities. The report will be saved as an artifact that you
+can later download and analyze.
+
+If you want to whitelist some specific vulnerabilities, you can do so by defining
+them in a [YAML file](https://github.com/arminc/clair-scanner/blob/master/README.md#example-whitelist-yaml-file),
+in our case its named `clair-whitelist.yml`.
+
+TIP: **Tip:**
+Starting with [GitLab Enterprise Edition Ultimate][ee] 10.4, this information will
+be automatically extracted and shown right in the merge request widget. To do
+so, the CI/CD job must be named `sast:container` and the artifact path must be
+`gl-sast-container-report.json`.
+[Learn more on application security testing results shown in merge requests](https://docs.gitlab.com/ee/user/project/merge_requests/sast_docker.html).
+
+[ee]: https://about.gitlab.com/gitlab-ee/
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index e23c73f46fb..7e3d418ca6c 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -20,6 +20,8 @@ project in an easy and automatic way:
1. [Auto Test](#auto-test)
1. [Auto Code Quality](#auto-code-quality)
1. [Auto SAST (Static Application Security Testing)](#auto-sast)
+1. [Auto SAST for Docker images](#auto-sast-for-docker-images)
+1. [Auto DAST (Dynamic Application Security Testing)](#auto-dast)
1. [Auto Browser Performance Testing](#auto-browser-performance-testing)
1. [Auto Review Apps](#auto-review-apps)
1. [Auto Deploy](#auto-deploy)
@@ -193,8 +195,10 @@ Auto Code Quality uses the open source
[`codeclimate` image](https://hub.docker.com/r/codeclimate/codeclimate/) to run
static analysis and other code checks on the current code. The report is
created, and is uploaded as an artifact which you can later download and check
-out. In GitLab Enterprise Edition Starter, differences between the source and
-target branches are
+out.
+
+In GitLab Enterprise Edition Starter, differences between the source and
+target branches are also
[shown in the merge request widget](https://docs.gitlab.com/ee/user/project/merge_requests/code_quality_diff.html).
### Auto SAST
@@ -207,7 +211,34 @@ analysis on the current code and checks for potential security issues. Once the
report is created, it's uploaded as an artifact which you can later download and
check out.
-Any security warnings are also [shown in the merge request widget](https://docs.gitlab.com/ee/user/project/merge_requests/sast.html).
+In GitLab Enterprise Edition Ultimate, any security warnings are also
+[shown in the merge request widget](https://docs.gitlab.com/ee/user/project/merge_requests/sast.html).
+
+### Auto SAST for Docker images
+
+> Introduced in GitLab 10.4.
+
+Vulnerability Static Analysis for containers uses
+[Clair](https://github.com/coreos/clair) to run static analysis on a
+Docker image and checks for potential security issues. Once the report is
+created, it's uploaded as an artifact which you can later download and
+check out.
+
+In GitLab Enterprise Edition Ultimate, any security warnings are also
+[shown in the merge request widget](https://docs.gitlab.com/ee/user/project/merge_requests/sast_docker.html).
+
+### Auto DAST
+
+> Introduced in [GitLab Enterprise Edition Ultimate][ee] 10.4.
+
+Dynamic Application Security Testing (DAST) uses the
+popular open source tool [OWASP ZAProxy](https://github.com/zaproxy/zaproxy)
+to perform an analysis on the current code and checks for potential security
+issues. Once the report is created, it's uploaded as an artifact which you can
+later download and check out.
+
+In GitLab Enterprise Edition Ultimate, any security warnings are also
+[shown in the merge request widget](https://docs.gitlab.com/ee/user/project/merge_requests/dast.html).
### Auto Browser Performance Testing
diff --git a/doc/topics/git/index.md b/doc/topics/git/index.md
index f69e2e49f0c..2ca2bf743fb 100644
--- a/doc/topics/git/index.md
+++ b/doc/topics/git/index.md
@@ -44,7 +44,7 @@ We've gathered some resources to help you to get the best from Git with GitLab.
## Troubleshooting Git
-- [Numerous _undo_ possibilities in Git](../../articles/numerous_undo_possibilities_in_git/index.md)
+- [Numerous _undo_ possibilities in Git](numerous_undo_possibilities_in_git/index.md)
- Learn a few [Git troubleshooting](troubleshooting_git.md) techniques to help you out.
## Branching strategies
diff --git a/doc/articles/numerous_undo_possibilities_in_git/img/branching.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png
index 9a80c211c99..9a80c211c99 100644
--- a/doc/articles/numerous_undo_possibilities_in_git/img/branching.png
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png
Binary files differ
diff --git a/doc/articles/numerous_undo_possibilities_in_git/img/rebase_reset.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png
index ac7ea9ecddc..ac7ea9ecddc 100644
--- a/doc/articles/numerous_undo_possibilities_in_git/img/rebase_reset.png
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png
Binary files differ
diff --git a/doc/articles/numerous_undo_possibilities_in_git/img/revert.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png
index 13b3a35ca45..13b3a35ca45 100644
--- a/doc/articles/numerous_undo_possibilities_in_git/img/revert.png
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png
Binary files differ
diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/index.md b/doc/topics/git/numerous_undo_possibilities_in_git/index.md
new file mode 100644
index 00000000000..6a2f7b30dd3
--- /dev/null
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/index.md
@@ -0,0 +1,497 @@
+# Numerous undo possibilities in Git
+
+> **[Article Type](../../../development/writing_documentation.md#types-of-technical-articles):** tutorial ||
+> **Level:** intermediary ||
+> **Author:** [Crt Mori](https://gitlab.com/Letme) ||
+> **Publication date:** 2017-08-17
+
+## Introduction
+
+In this tutorial, we will show you different ways of undoing your work in Git, for which
+we will assume you have a basic working knowledge of. Check GitLab's
+[Git documentation](../index.md#git-documentation) for reference.
+Also, we will only provide some general info of the commands, which is enough
+to get you started for the easy cases/examples, but for anything more advanced please refer to the [Git book](https://git-scm.com/book/en/v2).
+
+We will explain a few different techniques to undo your changes based on the stage
+of the change in your current development. Also, keep in mind that [nothing in
+Git is really deleted.][git-autoclean-ref]
+This means that until Git automatically cleans detached commits (which cannot be
+accessed by branch or tag) it will be possible to view them with `git reflog` command
+and access them with direct commit-id. Read more about _[redoing the undo](#redoing-the-undo)_ on the section below.
+
+This guide is organized depending on the [stage of development][git-basics]
+where you want to undo your changes from and if they were shared with other developers
+or not. Because Git is tracking changes a created or edited file is in the unstaged state
+(if created it is untracked by Git). After you add it to a repository (`git add`) you put
+a file into the **staged** state, which is then committed (`git commit`) to your
+local repository. After that, file can be shared with other developers (`git push`).
+Here's what we'll cover in this tutorial:
+
+ - [Undo local changes](#undo-local-changes) which were not pushed to remote repository
+
+ - Before you commit, in both unstaged and staged state
+ - After you committed
+
+ - Undo changes after they are pushed to remote repository
+
+ - [Without history modification](#undo-remote-changes-without-changing-history) (preferred way)
+ - [With history modification](#undo-remote-changes-with-modifying-history) (requires
+ coordination with team and force pushes).
+
+ - [Usecases when modifying history is generally acceptable](#where-modifying-history-is-generally-acceptable)
+ - [How to modify history](#how-modifying-history-is-done)
+ - [How to remove sensitive information from repository](#deleting-sensitive-information-from-commits)
+
+
+### Branching strategy
+
+[Git][git-official] is a de-centralized version control system, which means that beside regular
+versioning of the whole repository, it has possibilities to exchange changes
+with other repositories. To avoid chaos with
+[multiple sources of truth][git-distributed], various
+development workflows have to be followed, and it depends on your internal
+workflow how certain changes or commits can be undone or changed.
+[GitLab Flow][gitlab-flow] provides a good
+balance between developers clashing with each other while
+developing the same feature and cooperating seamlessly, but it does not enable
+joined development of the same feature by multiple developers by default.
+When multiple developers develop the same feature on the same branch, clashing
+with every synchronization is unavoidable, but a proper or chosen Git Workflow will
+prevent that anything is lost or out of sync when feature is complete. You can also
+read through this blog post on [Git Tips & Tricks][gitlab-git-tips-n-tricks]
+to learn how to easily **do** things in Git.
+
+
+## Undo local changes
+
+Until you push your changes to any remote repository, they will only affect you.
+That broadens your options on how to handle undoing them. Still, local changes
+can be on various stages and each stage has a different approach on how to tackle them.
+
+
+### Unstaged local changes (before you commit)
+
+When a change is made, but it is not added to the staged tree, Git itself
+proposes a solution to discard changes to certain file.
+
+Suppose you edited a file to change the content using your favorite editor:
+
+```shell
+vim <file>
+```
+
+Since you did not `git add <file>` to staging, it should be under unstaged files (or
+untracked if file was created). You can confirm that with:
+
+```shell
+$ git status
+On branch master
+Your branch is up-to-date with 'origin/master'.
+Changes not staged for commit:
+ (use "git add <file>..." to update what will be committed)
+ (use "git checkout -- <file>..." to discard changes in working directory)
+
+ modified: <file>
+no changes added to commit (use "git add" and/or "git commit -a")
+```
+
+At this point there are 3 options to undo the local changes you have:
+
+ - Discard all local changes, but save them for possible re-use [later](#quickly-save-local-changes)
+
+ ```shell
+ git stash
+ ```
+
+ - Discarding local changes (permanently) to a file
+
+ ```shell
+ git checkout -- <file>
+ ```
+
+ - Discard all local changes to all files permanently
+
+ ```shell
+ git reset --hard
+ ```
+
+
+Before executing `git reset --hard`, keep in mind that there is also a way to
+just temporary store the changes without committing them using `git stash`.
+This command resets the changes to all files, but it also saves them in case
+you would like to apply them at some later time. You can read more about it in
+[section below](#quickly-save-local-changes).
+
+### Quickly save local changes
+
+You are working on a feature when a boss drops by with an urgent task. Since your
+feature is not complete, but you need to swap to another branch, you can use
+`git stash` to save what you had done, swap to another branch, commit, push,
+test, then get back to previous feature branch, do `git stash pop` and continue
+where you left.
+
+The example above shows that discarding all changes is not always a preferred option,
+but Git provides a way to save them for later, while resetting the repository to state without
+them. This is achieved by Git stashing command `git stash`, which in fact saves your
+current work and runs `git reset --hard`, but it also has various
+additional options like:
+
+ - `git stash save`, which enables including temporary commit message, which will help you identify changes, among with other options
+ - `git stash list`, which lists all previously stashed commits (yes, there can be more) that were not `pop`ed
+ - `git stash pop`, which redoes previously stashed changes and removes them from stashed list
+ - `git stash apply`, which redoes previously stashed changes, but keeps them on stashed list
+
+### Staged local changes (before you commit)
+
+Let's say you have added some files to staging, but you want to remove them from the
+current commit, yet you want to retain those changes - just move them outside
+of the staging tree. You also have an option to discard all changes with
+`git reset --hard` or think about `git stash` [as described earlier.](#quickly-save-local-changes)
+
+Lets start the example by editing a file, with your favorite editor, to change the
+content and add it to staging
+
+```
+vim <file>
+git add <file>
+```
+
+The file is now added to staging as confirmed by `git status` command:
+
+```shell
+$ git status
+On branch master
+Your branch is up-to-date with 'origin/master'.
+Changes to be committed:
+ (use "git reset HEAD <file>..." to unstage)
+
+ new file: <file>
+```
+
+Now you have 4 options to undo your changes:
+
+ - Unstage the file to current commit (HEAD)
+
+ ```shell
+ git reset HEAD <file>
+ ```
+
+ - Unstage everything - retain changes
+
+ ```shell
+ git reset
+ ```
+
+ - Discard all local changes, but save them for [later](#quickly-save-local-changes)
+
+ ```shell
+ git stash
+ ```
+
+ - Discard everything permanently
+
+ ```shell
+ git reset --hard
+ ```
+
+## Committed local changes
+
+Once you commit, your changes are recorded by the version control system.
+Because you haven't pushed to your remote repository yet, your changes are
+still not public (or shared with other developers). At this point, undoing
+things is a lot easier, we have quite some workaround options. Once you push
+your code, you'll have less options to troubleshoot your work.
+
+### Without modifying history
+
+Through the development process some of the previously committed changes do not
+fit anymore in the end solution, or are source of the bugs. Once you find the
+commit which triggered bug, or once you have a faulty commit, you can simply
+revert it with `git revert commit-id`. This command inverts (swaps) the additions and
+deletions in that commit, so that it does not modify history. Retaining history
+can be helpful in future to notice that some changes have been tried
+unsuccessfully in the past.
+
+In our example we will assume there are commits `A`,`B`,`C`,`D`,`E` committed in this order: `A-B-C-D-E`,
+and `B` is the commit you want to undo. There are many different ways to identify commit
+`B` as bad, one of them is to pass a range to `git bisect` command. The provided range includes
+last known good commit (we assume `A`) and first known bad commit (where bug was detected - we will assume `E`).
+
+```shell
+git bisect A..E
+```
+
+Bisect will provide us with commit-id of the middle commit to test, and then guide us
+through simple bisection process. You can read more about it [in official Git Tools][git-debug]
+In our example we will end up with commit `B`, that introduced bug/error. We have
+4 options on how to remove it (or part of it) from our repository.
+
+- Undo (swap additions and deletions) changes introduced by commit `B`.
+
+ ```shell
+ git revert commit-B-id
+ ```
+
+- Undo changes on a single file or directory from commit `B`, but retain them in the staged state
+
+ ```shell
+ git checkout commit-B-id <file>
+ ```
+
+- Undo changes on a single file or directory from commit `B`, but retain them in the unstaged state
+
+ ```shell
+ git reset commit-B-id <file>
+ ```
+
+ - There is one command we also must not forget: **creating a new branch**
+ from the point where changes are not applicable or where the development has hit a
+ dead end. For example you have done commits `A-B-C-D` on your feature-branch
+ and then you figure `C` and `D` are wrong. At this point you either reset to `B`
+ and do commit `F` (which will cause problems with pushing and if forced pushed also with other developers)
+ since branch now looks `A-B-F`, which clashes with what other developers have locally (you will
+ [change history](#with-history-modification)), or you simply checkout commit `B` create
+ a new branch and do commit `F`. In the last case, everyone else can still do their work while you
+ have your new way to get it right and merge it back in later. Alternatively, with GitLab,
+ you can [cherry-pick](../../../user/project/merge_requests/cherry_pick_changes.md#cherry-picking-a-commit)
+ that commit into a new merge request.
+
+ ![Create a new branch to avoid clashing](img/branching.png)
+
+ ```shell
+ git checkout commit-B-id
+ git checkout -b new-path-of-feature
+ # Create <commit F>
+ git commit -a
+ ```
+
+### With history modification
+
+There is one command for history modification and that is `git rebase`. Command
+provides interactive mode (`-i` flag) which enables you to:
+
+ - **reword** commit messages (there is also `git commit --amend` for editing
+ last commit message)
+ - **edit** the commit content (changes introduced by commit) and message
+ - **squash** multiple commits into a single one, and have a custom or aggregated
+ commit message
+ - **drop** commits - simply delete them
+ - and few more options
+
+Let us check few examples. Again there are commits `A-B-C-D` where you want to
+delete commit `B`.
+
+- Rebase the range from current commit D to A:
+
+ ```shell
+ git rebase -i A
+ ```
+
+- Command opens your favorite editor where you write `drop` in front of commit
+ `B`, but you leave default `pick` with all other commits. Save and exit the
+ editor to perform a rebase. Remember: if you want to cancel delete whole
+ file content before saving and exiting the editor
+
+In case you want to modify something introduced in commit `B`.
+
+- Rebase the range from current commit D to A:
+
+ ```shell
+ git rebase -i A
+ ```
+
+- Command opens your favorite text editor where you write `edit` in front of commit
+ `B`, but leave default `pick` with all other commits. Save and exit the editor to
+ perform a rebase
+
+- Now do your edits and commit changes:
+
+ ```shell
+ git commit -a
+ ```
+
+You can find some more examples in [below section where we explain how to modify
+history](#how-modifying-history-is-done)
+
+
+### Redoing the Undo
+
+Sometimes you realize that the changes you undid were useful and you want them
+back. Well because of first paragraph you are in luck. Command `git reflog`
+enables you to *recall* detached local commits by referencing or applying them
+via commit-id. Although, do not expect to see really old commits in reflog, because
+Git regularly [cleans the commits which are *unreachable* by branches or tags][git-autoclean-ref].
+
+To view repository history and to track older commits you can use below command:
+
+```shell
+$ git reflog show
+
+# Example output:
+b673187 HEAD@{4}: merge 6e43d5987921bde189640cc1e37661f7f75c9c0b: Merge made by the 'recursive' strategy.
+eb37e74 HEAD@{5}: rebase -i (finish): returning to refs/heads/master
+eb37e74 HEAD@{6}: rebase -i (pick): Commit C
+97436c6 HEAD@{7}: rebase -i (start): checkout 97436c6eec6396c63856c19b6a96372705b08b1b
+...
+88f1867 HEAD@{12}: commit: Commit D
+97436c6 HEAD@{13}: checkout: moving from 97436c6eec6396c63856c19b6a96372705b08b1b to test
+97436c6 HEAD@{14}: checkout: moving from master to 97436c6
+05cc326 HEAD@{15}: commit: Commit C
+6e43d59 HEAD@{16}: commit: Commit B
+```
+
+Output of command shows repository history. In first column there is commit-id,
+in following column, number next to `HEAD` indicates how many commits ago something
+was made, after that indicator of action that was made (commit, rebase, merge, ...)
+and then on end description of that action.
+
+## Undo remote changes without changing history
+
+This topic is roughly same as modifying committed local changes without modifying
+history. **It should be the preferred way of undoing changes on any remote repository
+or public branch.** Keep in mind that branching is the best solution when you want
+to retain the history of faulty development, yet start anew from certain point. Branching
+enables you to include the existing changes in new development (by merging) and
+it also provides a clear timeline and development structure.
+
+![Use revert to keep branch flowing](img/revert.png)
+
+If you want to revert changes introduced in certain `commit-id` you can simply
+revert that `commit-id` (swap additions and deletions) in newly created commit:
+You can do this with
+
+```shell
+git revert commit-id
+```
+
+or creating a new branch:
+
+```shell
+git checkout commit-id
+git checkout -b new-path-of-feature
+```
+
+## Undo remote changes with modifying history
+
+This is useful when you want to *hide* certain things - like secret keys,
+passwords, SSH keys, etc. It is and should not be used to hide mistakes, as
+it will make it harder to debug in case there are some other bugs. The main
+reason for this is that you loose the real development progress. **Also keep in
+mind that, even with modified history, commits are just detached and can still be
+accessed through commit-id** - at least until all repositories perform
+the cleanup of detached commits (happens automatically).
+
+![Modifying history causes problems on remote branch](img/rebase_reset.png)
+
+### Where modifying history is generally acceptable
+
+Modified history breaks the development chain of other developers, as changed
+history does not have matching commits'ids. For that reason it should not
+be used on any public branch or on branch that *might* be used by other
+developers. When contributing to big open source repositories (e.g. [GitLab CE][gitlab-ce]),
+it is acceptable to *squash* commits into a single one, to present
+a nicer history of your contribution.
+Keep in mind that this also removes the comments attached to certain commits
+in merge requests, so if you need to retain traceability in GitLab, then
+modifying history is not acceptable.
+A feature-branch of a merge request is a public branch and might be used by
+other developers, but project process and rules might allow or require
+you to use `git rebase` (command that changes history) to reduce number of
+displayed commits on target branch after reviews are done (for example
+GitLab). There is a `git merge --squash` command which does exactly that
+(squashes commits on feature-branch to a single commit on target branch
+at merge).
+
+>**Note:**
+Never modify the commit history of `master` or shared branch
+
+### How modifying history is done
+
+After you know what you want to modify (how far in history or how which range of
+old commits), use `git rebase -i commit-id`. This command will then display all the commits from
+current version to chosen commit-id and allow modification, squashing, deletion
+of that commits.
+
+```shell
+$ git rebase -i commit1-id..commit3-id
+pick <commit1-id> <commit1-commit-message>
+pick <commit2-id> <commit2-commit-message>
+pick <commit3-id> <commit3-commit-message>
+
+# Rebase commit1-id..commit3-id onto <commit4-id> (3 command(s))
+#
+# Commands:
+# p, pick = use commit
+# r, reword = use commit, but edit the commit message
+# e, edit = use commit, but stop for amending
+# s, squash = use commit, but meld into previous commit
+# f, fixup = like "squash", but discard this commit's log message
+# x, exec = run command (the rest of the line) using shell
+# d, drop = remove commit
+#
+# These lines can be re-ordered; they are executed from top to bottom.
+#
+# If you remove a line here THAT COMMIT WILL BE LOST.
+#
+# However, if you remove everything, the rebase will be aborted.
+#
+# Note that empty commits are commented out
+```
+
+>**Note:**
+It is important to notice that comment from the output clearly states that, if
+you decide to abort, then do not just close your editor (as that will in-fact
+modify history), but remove all uncommented lines and save.
+
+That is one of the reasons why `git rebase` should be used carefully on
+shared and remote branches. But don't worry, there will be nothing broken until
+you push back to the remote repository (so you can freely explore the
+different outcomes locally).
+
+```shell
+# Modify history from commit-id to HEAD (current commit)
+git rebase -i commit-id
+```
+
+### Deleting sensitive information from commits
+
+Git also enables you to delete sensitive information from your past commits and
+it does modify history in the progress. That is why we have included it in this
+section and not as a standalone topic. To do so, you should run the
+`git filter-branch`, which enables you to rewrite history with
+[certain filters][git-filters-manual].
+This command uses rebase to modify history and if you want to remove certain
+file from history altogether use:
+
+```shell
+git filter-branch --tree-filter 'rm filename' HEAD
+```
+
+Since `git filter-branch` command might be slow on big repositories, there are
+tools that can use some of Git specifics to enable faster execution of common
+tasks (which is exactly what removing sensitive information file is about).
+An alternative is [BFG Repo-cleaner][bfg-repo-cleaner]. Keep in mind that these
+tools are faster because they do not provide a same fully feature set as `git filter-branch`
+does, but focus on specific usecases.
+
+## Conclusion
+
+There are various options of undoing your work with any version control system, but
+because of de-centralized nature of Git, these options are multiplied (or limited)
+depending on the stage of your process. Git also enables rewriting history, but that
+should be avoided as it might cause problems when multiple developers are
+contributing to the same codebase.
+
+<!-- Identifiers, in alphabetical order -->
+
+[bfg-repo-cleaner]: https://rtyley.github.io/bfg-repo-cleaner/
+[git-autoclean-ref]: https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery
+[git-basics]: https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository
+[git-debug]: https://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git
+[git-distributed]: https://git-scm.com/about/distributed
+[git-filters-manual]: https://git-scm.com/docs/git-filter-branch#_options
+[git-official]: https://git-scm.com/
+[gitlab-ce]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#contribution-acceptance-criteria
+[gitlab-flow]: https://about.gitlab.com/2014/09/29/gitlab-flow/
+[gitlab-git-tips-n-tricks]: https://about.gitlab.com/2016/12/08/git-tips-and-tricks/
diff --git a/lib/api/circuit_breakers.rb b/lib/api/circuit_breakers.rb
index 598c76f6168..c13154dc0ec 100644
--- a/lib/api/circuit_breakers.rb
+++ b/lib/api/circuit_breakers.rb
@@ -17,11 +17,11 @@ module API
end
def storage_health
- @failing_storage_health ||= Gitlab::Git::Storage::Health.for_all_storages
+ @storage_health ||= Gitlab::Git::Storage::Health.for_all_storages
end
end
- desc 'Get all failing git storages' do
+ desc 'Get all git storages' do
detail 'This feature was introduced in GitLab 9.5'
success Entities::RepositoryStorageHealth
end
diff --git a/lib/api/helpers/common_helpers.rb b/lib/api/helpers/common_helpers.rb
index 322624c6092..9993caa5249 100644
--- a/lib/api/helpers/common_helpers.rb
+++ b/lib/api/helpers/common_helpers.rb
@@ -3,8 +3,10 @@ module API
module CommonHelpers
def convert_parameters_from_legacy_format(params)
params.tap do |params|
- if params[:assignee_id].present?
- params[:assignee_ids] = [params.delete(:assignee_id)]
+ assignee_id = params.delete(:assignee_id)
+
+ if assignee_id.present?
+ params[:assignee_ids] = [assignee_id]
end
end
end
diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb
index fed05bb6c64..71b212023d6 100644
--- a/lib/gitlab/gitaly_client/commit_service.rb
+++ b/lib/gitlab/gitaly_client/commit_service.rb
@@ -177,7 +177,7 @@ module Gitlab
response = GitalyClient.call(@repository.storage, :commit_service, :list_commits_by_oid, request, timeout: GitalyClient.medium_timeout)
consume_commits_response(response)
- rescue GRPC::Unknown # If no repository is found, happens mainly during testing
+ rescue GRPC::NotFound # If no repository is found, happens mainly during testing
[]
end
diff --git a/lib/tasks/gitlab/shell.rake b/lib/tasks/gitlab/shell.rake
index 0e6aed32c52..12ae4199b69 100644
--- a/lib/tasks/gitlab/shell.rake
+++ b/lib/tasks/gitlab/shell.rake
@@ -54,16 +54,6 @@ namespace :gitlab do
# (Re)create hooks
Rake::Task['gitlab:shell:create_hooks'].invoke
- # Required for debian packaging with PKGR: Setup .ssh/environment with
- # the current PATH, so that the correct ruby version gets loaded
- # Requires to set "PermitUserEnvironment yes" in sshd config (should not
- # be an issue since it is more than likely that there are no "normal"
- # user accounts on a gitlab server). The alternative is for the admin to
- # install a ruby (1.9.3+) in the global path.
- File.open(File.join(user_home, ".ssh", "environment"), "w+") do |f|
- f.puts "PATH=#{ENV['PATH']}"
- end
-
Gitlab::Shell.ensure_secret_token!
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 9a6b27c00f8..a5cd858b11a 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -380,9 +380,18 @@ feature 'Jobs' do
it 'shows manual action empty state' do
expect(page).to have_content('This job requires a manual action')
- expect(page).to have_content('This job depends on a user to trigger its process. Often they are used to deploy code to production environments.')
+ expect(page).to have_content('This job depends on a user to trigger its process. Often they are used to deploy code to production environments')
expect(page).to have_link('Trigger this manual action')
end
+
+ it 'plays manual action', :js do
+ click_link 'Trigger this manual action'
+
+ wait_for_requests
+ expect(page).to have_content('This job has not been triggered')
+ expect(page).to have_content('This job is stuck, because the project doesn\'t have any runners online assigned to it.')
+ expect(page).to have_content('pending')
+ end
end
context 'Non triggered job' do
@@ -392,9 +401,8 @@ feature 'Jobs' do
visit project_job_path(project, job)
end
- it 'shows manual action empty state' do
+ it 'shows empty state' do
expect(page).to have_content('This job has not been triggered yet')
- expect(page).to have_content('This job depends on upstream jobs that need to succeed in order for this job to be triggered.')
end
end
end
diff --git a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
new file mode 100644
index 00000000000..6940b04573e
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
@@ -0,0 +1,77 @@
+import Vue from 'vue';
+
+import stackedProgressBarComponent from '~/vue_shared/components/stacked_progress_bar.vue';
+
+import mountComponent from '../../helpers/vue_mount_component_helper';
+
+const createComponent = (config) => {
+ const Component = Vue.extend(stackedProgressBarComponent);
+ const defaultConfig = Object.assign({}, {
+ successLabel: 'Synced',
+ failureLabel: 'Failed',
+ neutralLabel: 'Out of sync',
+ successCount: 10,
+ failureCount: 5,
+ totalCount: 20,
+ }, config);
+
+ return mountComponent(Component, defaultConfig);
+};
+
+describe('StackedProgressBarComponent', () => {
+ let vm;
+
+ beforeEach(() => {
+ vm = createComponent();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('computed', () => {
+ describe('neutralCount', () => {
+ it('returns neutralCount based on totalCount, successCount and failureCount', () => {
+ expect(vm.neutralCount).toBe(5); // 20 - 10 - 5
+ });
+ });
+ });
+
+ describe('methods', () => {
+ describe('getPercent', () => {
+ it('returns percentage from provided count based on `totalCount`', () => {
+ expect(vm.getPercent(10)).toBe(50);
+ });
+ });
+
+ describe('barStyle', () => {
+ it('returns style string based on percentage provided', () => {
+ expect(vm.barStyle(50)).toBe('width: 50%;');
+ });
+ });
+
+ describe('getTooltip', () => {
+ it('returns label string based on label and count provided', () => {
+ expect(vm.getTooltip('Synced', 10)).toBe('Synced: 10');
+ });
+ });
+ });
+
+ describe('template', () => {
+ it('renders container element', () => {
+ expect(vm.$el.classList.contains('stacked-progress-bar')).toBeTruthy();
+ });
+
+ it('renders empty state when count is unavailable', () => {
+ const vmX = createComponent({ totalCount: 0, successCount: 0, failureCount: 0 });
+ expect(vmX.$el.querySelectorAll('.status-unavailable').length).not.toBe(0);
+ vmX.$destroy();
+ });
+
+ it('renders bar elements when count is available', () => {
+ expect(vm.$el.querySelectorAll('.status-green').length).not.toBe(0);
+ expect(vm.$el.querySelectorAll('.status-neutral').length).not.toBe(0);
+ expect(vm.$el.querySelectorAll('.status-red').length).not.toBe(0);
+ });
+ });
+});
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 320217f2032..43218755f4f 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -847,6 +847,15 @@ describe API::Issues, :mailer do
expect(json_response['assignee']['name']).to eq(user2.name)
expect(json_response['assignees'].first['name']).to eq(user2.name)
end
+
+ it 'creates a new project issue when assignee_id is empty' do
+ post api("/projects/#{project.id}/issues", user),
+ title: 'new issue', assignee_id: ''
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['title']).to eq('new issue')
+ expect(json_response['assignee']).to be_nil
+ end
end
context 'single assignee restrictions' do