summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md5
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/dispatcher.js87
-rw-r--r--app/assets/javascripts/job.js13
-rw-r--r--app/assets/javascripts/jobs/components/header.vue1
-rw-r--r--app/assets/javascripts/merge_request.js8
-rw-r--r--app/assets/javascripts/pages/groups/milestones/edit/index.js3
-rw-r--r--app/assets/javascripts/pages/groups/milestones/new/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/clusters/index/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/clusters/show/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/commit/pipelines/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/commit/show/index.js22
-rw-r--r--app/assets/javascripts/pages/projects/commits/show/index.js9
-rw-r--r--app/assets/javascripts/pages/projects/compare/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/compare/show/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/milestones/edit/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/milestones/new/index.js3
-rw-r--r--app/assets/javascripts/pipelines/components/header_component.vue1
-rw-r--r--app/assets/javascripts/shared/milestones/form.js9
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js9
-rw-r--r--app/assets/javascripts/vue_shared/components/modal.vue4
-rw-r--r--app/assets/stylesheets/framework/modal.scss32
-rw-r--r--app/assets/stylesheets/framework/tw_bootstrap_variables.scss4
-rw-r--r--app/assets/stylesheets/framework/variables.scss5
-rw-r--r--app/assets/stylesheets/pages/xterm.scss29
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb6
-rw-r--r--app/helpers/blob_helper.rb2
-rw-r--r--app/models/commit.rb8
-rw-r--r--app/models/push_event.rb3
-rw-r--r--app/models/repository.rb8
-rw-r--r--app/services/system_note_service.rb23
-rw-r--r--app/views/dashboard/_activity_head.html.haml4
-rw-r--r--app/views/dashboard/_snippets_head.html.haml4
-rw-r--r--app/views/profiles/gpg_keys/index.html.haml4
-rw-r--r--app/views/projects/blob/_new_dir.html.haml2
-rw-r--r--app/views/projects/blob/_upload.html.haml2
-rw-r--r--app/views/projects/buttons/_dropdown.html.haml26
-rw-r--r--app/views/projects/forks/index.html.haml4
-rw-r--r--app/views/projects/jobs/_sidebar.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_diffs.html.haml6
-rw-r--r--app/views/shared/projects/_project.html.haml2
-rw-r--r--changelogs/unreleased/16301-update-removed-assignee-note-to-include-old-assignee-reference.yml5
-rw-r--r--changelogs/unreleased/36571-ignore-root-in-repo.yml5
-rw-r--r--changelogs/unreleased/37898-increase-readability-of-colored-text-in-job-output-log.yml5
-rw-r--r--changelogs/unreleased/40818-last-push-widget-does-not-appear-after-pushing-new-commit.yml5
-rw-r--r--changelogs/unreleased/41476-enable-project-milestons-deletion-via-api.yml5
-rw-r--r--changelogs/unreleased/41666-cannot-search-with-keyword-merge-2.yml5
-rw-r--r--changelogs/unreleased/41666-cannot-search-with-keyword-merge.yml6
-rw-r--r--changelogs/unreleased/42031-fix-links-to-uploads-in-wikis.yml5
-rw-r--r--changelogs/unreleased/42046-fork-icon.yml5
-rw-r--r--changelogs/unreleased/42047-pg-10-support.yml5
-rw-r--r--changelogs/unreleased/issue_41460.yml5
-rw-r--r--changelogs/unreleased/jej-lfs-rev-list-handles-non-utf-paths-41627.yml5
-rw-r--r--changelogs/unreleased/mr-status-box-update.yml5
-rw-r--r--changelogs/unreleased/winh-style-modals.yml5
-rw-r--r--config/initializers/ar5_pg_10_support.rb57
-rw-r--r--db/migrate/20171207185153_add_merge_request_state_index.rb18
-rw-r--r--db/schema.rb1
-rw-r--r--doc/api/milestones.md13
-rw-r--r--doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md5
-rw-r--r--doc/development/doc_styleguide.md2
-rw-r--r--doc/install/requirements.md2
-rw-r--r--lib/api/jobs.rb1
-rw-r--r--lib/api/project_milestones.rb9
-rw-r--r--lib/api/v3/builds.rb1
-rw-r--r--lib/backup/manager.rb9
-rw-r--r--lib/banzai/filter/wiki_link_filter/rewriter.rb4
-rw-r--r--lib/gitlab/git/commit.rb37
-rw-r--r--lib/gitlab/git/rev_list.rb2
-rw-r--r--lib/gitlab/project_search_results.rb13
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb42
-rw-r--r--spec/helpers/blob_helper_spec.rb7
-rw-r--r--spec/javascripts/job_spec.js5
-rw-r--r--spec/javascripts/merge_request_spec.js7
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js45
-rw-r--r--spec/lib/backup/manager_spec.rb6
-rw-r--r--spec/lib/banzai/filter/wiki_link_filter_spec.rb8
-rw-r--r--spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb4
-rw-r--r--spec/lib/gitlab/git/rev_list_spec.rb11
-rw-r--r--spec/lib/gitlab/project_search_results_spec.rb39
-rw-r--r--spec/models/commit_spec.rb24
-rw-r--r--spec/models/push_event_spec.rb26
-rw-r--r--spec/models/repository_spec.rb14
-rw-r--r--spec/requests/api/jobs_spec.rb27
-rw-r--r--spec/requests/api/project_milestones_spec.rb40
-rw-r--r--spec/requests/api/v3/builds_spec.rb27
-rw-r--r--spec/services/system_note_service_spec.rb2
-rw-r--r--vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml30
-rw-r--r--vendor/prometheus/values.yaml200
90 files changed, 837 insertions, 365 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c29c289310d..87260744190 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -992,6 +992,11 @@ entry.
- Added type to CHANGELOG entries. (Jacopo Beschi @jacopo-beschi)
- [BUGIFX] Improves subgroup creation permissions. !13418
+## 9.5.10 (2017-11-08)
+
+- [SECURITY] Add SSRF protections for hostnames that will never resolve but will still connect to localhost
+- [SECURITY] Include X-Content-Type-Options (XCTO) header into API responses
+
## 9.5.9 (2017-10-16)
- [SECURITY] Move project repositories between namespaces when renaming users.
diff --git a/Gemfile b/Gemfile
index 36da419ba92..9e1e0b3c0c6 100644
--- a/Gemfile
+++ b/Gemfile
@@ -115,7 +115,7 @@ gem 'google-api-client', '~> 0.13.6'
gem 'unf', '~> 0.1.4'
# Seed data
-gem 'seed-fu', '2.3.6' # Upgrade to > 2.3.7 once https://github.com/mbleigh/seed-fu/issues/123 is solved
+gem 'seed-fu', '~> 2.3.7'
# Markdown and HTML processing
gem 'html-pipeline', '~> 1.11.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index b83a3f0f7a4..10e2585a0e8 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -831,7 +831,7 @@ GEM
rake (>= 0.9, < 13)
sass (~> 3.5.3)
securecompare (1.0.0)
- seed-fu (2.3.6)
+ seed-fu (2.3.7)
activerecord (>= 3.1)
activesupport (>= 3.1)
select2-rails (3.5.9.3)
@@ -1170,7 +1170,7 @@ DEPENDENCIES
sanitize (~> 2.0)
sass-rails (~> 5.0.6)
scss_lint (~> 0.56.0)
- seed-fu (= 2.3.6)
+ seed-fu (~> 2.3.7)
select2-rails (~> 3.5.9)
selenium-webdriver (~> 3.5)
sentry-raven (~> 2.5.3)
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index afa1bc19790..1c6336073e9 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -1,5 +1,4 @@
/* 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 Milestone from './milestone';
import IssuableForm from './issuable_form';
@@ -14,19 +13,16 @@ import Project from './project';
import projectAvatar from './project_avatar';
import MergeRequest from './merge_request';
import Compare from './compare';
-import initCompareAutocomplete from './compare_autocomplete';
import ProjectNew from './project_new';
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 BindInOut from './behaviors/bind_in_out';
import SecretValues from './behaviors/secret_values';
import Group from './group';
import ProjectsList from './projects_list';
-import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
import UserCallout from './user_callout';
import ShortcutsWiki from './shortcuts_wiki';
import BlobViewer from './blob/viewer/index';
@@ -42,8 +38,6 @@ import PerformanceBar from './performance_bar';
import initNotes from './init_notes';
import initIssuableSidebar from './init_issuable_sidebar';
import initProjectVisibilitySelector from './project_visibility';
-import GpgBadges from './gpg_badges';
-import initChangesDropdown from './init_changes_dropdown';
import NewGroupChild from './groups/new_group_child';
import { ajaxGet, convertPermissionToBoolean } from './lib/utils/common_utils';
import GlFieldErrors from './gl_field_errors';
@@ -54,12 +48,10 @@ import ShortcutsIssuable from './shortcuts_issuable';
import U2FAuthenticate from './u2f/authenticate';
import Members from './members';
import memberExpirationDate from './member_expiration_date';
-import DueDateSelectors from './due_date_select';
import Diff from './diff';
import ProjectLabelSubscription from './project_label_subscription';
import SearchAutocomplete from './search_autocomplete';
import Activities from './activities';
-import { fetchCommitMergeRequests } from './commit_merge_requests';
(function() {
var Dispatcher;
@@ -185,23 +177,33 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
.catch(fail);
break;
case 'projects:milestones:new':
+ case 'projects:milestones:create':
+ import('./pages/projects/milestones/new')
+ .then(callDefault)
+ .catch(fail);
+ break;
case 'projects:milestones:edit':
case 'projects:milestones:update':
- new ZenMode();
- new DueDateSelectors();
- new GLForm($('.milestone-form'), true);
+ import('./pages/projects/milestones/edit')
+ .then(callDefault)
+ .catch(fail);
break;
case 'groups:milestones:new':
+ case 'groups:milestones:create':
+ import('./pages/groups/milestones/new')
+ .then(callDefault)
+ .catch(fail);
+ break;
case 'groups:milestones:edit':
case 'groups:milestones:update':
- new ZenMode();
- new DueDateSelectors();
- new GLForm($('.milestone-form'), false);
+ import('./pages/groups/milestones/edit')
+ .then(callDefault)
+ .catch(fail);
break;
case 'projects:compare:show':
- new Diff();
- const paddingTop = 16;
- initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - paddingTop);
+ import('./pages/projects/compare/show')
+ .then(callDefault)
+ .catch(fail);
break;
case 'projects:branches:new':
import('./pages/projects/branches/new')
@@ -315,23 +317,15 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
.catch(fail);
break;
case 'projects:commit:show':
- new Diff();
- new ZenMode();
- shortcut_handler = new ShortcutsNavigation();
- new MiniPipelineGraph({
- container: '.js-commit-pipeline-graph',
- }).bindEvents();
- initNotes();
- const stickyBarPaddingTop = 16;
- initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - stickyBarPaddingTop);
- $('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
- fetchCommitMergeRequests();
+ import('./pages/projects/commit/show')
+ .then(callDefault)
+ .catch(fail);
+ shortcut_handler = true;
break;
case 'projects:commit:pipelines':
- new MiniPipelineGraph({
- container: '.js-commit-pipeline-graph',
- }).bindEvents();
- $('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
+ import('./pages/projects/commit/pipelines')
+ .then(callDefault)
+ .catch(fail);
break;
case 'projects:activity':
import('./pages/projects/activity')
@@ -340,9 +334,10 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
shortcut_handler = true;
break;
case 'projects:commits:show':
- CommitsList.init(document.querySelector('.js-project-commits-show').dataset.commitsLimit);
- shortcut_handler = new ShortcutsNavigation();
- GpgBadges.fetch();
+ import('./pages/projects/commits/show')
+ .then(callDefault)
+ .catch(fail);
+ shortcut_handler = true;
break;
case 'projects:show':
shortcut_handler = new ShortcutsNavigation();
@@ -564,20 +559,14 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
.catch(fail);
break;
case 'projects:clusters:show':
- import(/* webpackChunkName: "clusters" */ './clusters/clusters_bundle')
- .then(cluster => new cluster.default()) // eslint-disable-line new-cap
- .catch((err) => {
- Flash(s__('ClusterIntegration|Problem setting up the cluster'));
- throw err;
- });
+ import('./pages/projects/clusters/show')
+ .then(callDefault)
+ .catch(fail);
break;
case 'projects:clusters:index':
- import(/* webpackChunkName: "clusters_index" */ './clusters/clusters_index')
- .then(clusterIndex => clusterIndex.default())
- .catch((err) => {
- Flash(s__('ClusterIntegration|Problem setting up the clusters list'));
- throw err;
- });
+ import('./pages/projects/clusters/index')
+ .then(callDefault)
+ .catch(fail);
break;
}
switch (path[0]) {
@@ -657,7 +646,9 @@ import { fetchCommitMergeRequests } from './commit_merge_requests';
projectAvatar();
switch (path[1]) {
case 'compare':
- initCompareAutocomplete();
+ import('./pages/projects/compare')
+ .then(callDefault)
+ .catch(fail);
break;
case 'edit':
shortcut_handler = new ShortcutsNavigation();
diff --git a/app/assets/javascripts/job.js b/app/assets/javascripts/job.js
index 8f32dcc94e2..9b5092c5e3f 100644
--- a/app/assets/javascripts/job.js
+++ b/app/assets/javascripts/job.js
@@ -3,7 +3,6 @@ import { visitUrl } from './lib/utils/url_utility';
import bp from './breakpoints';
import { numberToHumanSize } from './lib/utils/number_utils';
import { setCiStatusFavicon } from './lib/utils/common_utils';
-import { timeFor } from './lib/utils/datetime_utility';
export default class Job {
constructor(options) {
@@ -71,7 +70,6 @@ export default class Job {
.off('resize.build')
.on('resize.build', _.throttle(this.sidebarOnResize.bind(this), 100));
- this.updateArtifactRemoveDate();
this.initAffixTopArea();
this.getBuildTrace();
@@ -261,16 +259,7 @@ export default class Job {
sidebarOnClick() {
if (this.shouldHideSidebarForViewport()) this.toggleSidebar();
}
- // eslint-disable-next-line class-methods-use-this, consistent-return
- updateArtifactRemoveDate() {
- const $date = $('.js-artifacts-remove');
- if ($date.length) {
- const date = $date.text();
- return $date.text(
- timeFor(new Date(date.replace(/([0-9]+)-([0-9]+)-([0-9]+)/g, '$1/$2/$3'))),
- );
- }
- }
+
// eslint-disable-next-line class-methods-use-this
populateJobs(stage) {
$('.build-job').hide();
diff --git a/app/assets/javascripts/jobs/components/header.vue b/app/assets/javascripts/jobs/components/header.vue
index 321a4872ccc..357bc9aab17 100644
--- a/app/assets/javascripts/jobs/components/header.vue
+++ b/app/assets/javascripts/jobs/components/header.vue
@@ -76,6 +76,7 @@
<loading-icon
v-if="isLoading"
size="2"
+ class="prepend-top-default append-bottom-default"
/>
</div>
</template>
diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js
index cb3cdea8111..e26bf437efc 100644
--- a/app/assets/javascripts/merge_request.js
+++ b/app/assets/javascripts/merge_request.js
@@ -110,7 +110,7 @@ MergeRequest.prototype.initCommitMessageListeners = function() {
});
};
-MergeRequest.prototype.updateStatusText = function(classToRemove, classToAdd, newStatusText) {
+MergeRequest.updateStatusText = function(classToRemove, classToAdd, newStatusText) {
$('.detail-page-header .status-box')
.removeClass(classToRemove)
.addClass(classToAdd)
@@ -118,14 +118,14 @@ MergeRequest.prototype.updateStatusText = function(classToRemove, classToAdd, ne
.text(newStatusText);
};
-MergeRequest.prototype.decreaseCounter = function(by = 1) {
- const $el = $('.nav-links .js-merge-counter');
+MergeRequest.decreaseCounter = function(by = 1) {
+ const $el = $('.js-merge-counter');
const count = Math.max((parseInt($el.text().replace(/[^\d]/, ''), 10) - by), 0);
$el.text(addDelimiter(count));
};
-MergeRequest.prototype.hideCloseButton = function() {
+MergeRequest.hideCloseButton = function() {
const el = document.querySelector('.merge-request .js-issuable-actions');
const closeDropdownItem = el.querySelector('li.close-item');
if (closeDropdownItem) {
diff --git a/app/assets/javascripts/pages/groups/milestones/edit/index.js b/app/assets/javascripts/pages/groups/milestones/edit/index.js
new file mode 100644
index 00000000000..5c99c90e24d
--- /dev/null
+++ b/app/assets/javascripts/pages/groups/milestones/edit/index.js
@@ -0,0 +1,3 @@
+import initForm from '../../../../shared/milestones/form';
+
+export default () => initForm(false);
diff --git a/app/assets/javascripts/pages/groups/milestones/new/index.js b/app/assets/javascripts/pages/groups/milestones/new/index.js
new file mode 100644
index 00000000000..5c99c90e24d
--- /dev/null
+++ b/app/assets/javascripts/pages/groups/milestones/new/index.js
@@ -0,0 +1,3 @@
+import initForm from '../../../../shared/milestones/form';
+
+export default () => initForm(false);
diff --git a/app/assets/javascripts/pages/projects/clusters/index/index.js b/app/assets/javascripts/pages/projects/clusters/index/index.js
new file mode 100644
index 00000000000..d531ab81dc7
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/clusters/index/index.js
@@ -0,0 +1,5 @@
+import ClustersIndex from '~/clusters/clusters_index';
+
+export default () => {
+ new ClustersIndex(); // eslint-disable-line no-new
+};
diff --git a/app/assets/javascripts/pages/projects/clusters/show/index.js b/app/assets/javascripts/pages/projects/clusters/show/index.js
new file mode 100644
index 00000000000..0458c02a66f
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/clusters/show/index.js
@@ -0,0 +1,5 @@
+import ClustersBundle from '~/clusters/clusters_bundle';
+
+export default () => {
+ new ClustersBundle(); // eslint-disable-line no-new
+};
diff --git a/app/assets/javascripts/pages/projects/commit/pipelines/index.js b/app/assets/javascripts/pages/projects/commit/pipelines/index.js
new file mode 100644
index 00000000000..523ad567021
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/commit/pipelines/index.js
@@ -0,0 +1,8 @@
+import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
+
+export default () => {
+ new MiniPipelineGraph({
+ container: '.js-commit-pipeline-graph',
+ }).bindEvents();
+ $('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
+};
diff --git a/app/assets/javascripts/pages/projects/commit/show/index.js b/app/assets/javascripts/pages/projects/commit/show/index.js
new file mode 100644
index 00000000000..5ac38e6f278
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/commit/show/index.js
@@ -0,0 +1,22 @@
+/* eslint-disable no-new */
+import Diff from '~/diff';
+import ZenMode from '~/zen_mode';
+import ShortcutsNavigation from '~/shortcuts_navigation';
+import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
+import initNotes from '~/init_notes';
+import initChangesDropdown from '~/init_changes_dropdown';
+import { fetchCommitMergeRequests } from '~/commit_merge_requests';
+
+export default () => {
+ new Diff();
+ new ZenMode();
+ new ShortcutsNavigation();
+ new MiniPipelineGraph({
+ container: '.js-commit-pipeline-graph',
+ }).bindEvents();
+ initNotes();
+ const stickyBarPaddingTop = 16;
+ initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - stickyBarPaddingTop);
+ $('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
+ fetchCommitMergeRequests();
+};
diff --git a/app/assets/javascripts/pages/projects/commits/show/index.js b/app/assets/javascripts/pages/projects/commits/show/index.js
new file mode 100644
index 00000000000..90b5882a24f
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/commits/show/index.js
@@ -0,0 +1,9 @@
+import CommitsList from '~/commits';
+import GpgBadges from '~/gpg_badges';
+import ShortcutsNavigation from '~/shortcuts_navigation';
+
+export default () => {
+ CommitsList.init(document.querySelector('.js-project-commits-show').dataset.commitsLimit);
+ new ShortcutsNavigation(); // eslint-disable-line no-new
+ GpgBadges.fetch();
+};
diff --git a/app/assets/javascripts/pages/projects/compare/index.js b/app/assets/javascripts/pages/projects/compare/index.js
new file mode 100644
index 00000000000..890062eeee6
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/compare/index.js
@@ -0,0 +1,5 @@
+import initCompareAutocomplete from '~/compare_autocomplete';
+
+export default () => {
+ initCompareAutocomplete();
+};
diff --git a/app/assets/javascripts/pages/projects/compare/show/index.js b/app/assets/javascripts/pages/projects/compare/show/index.js
new file mode 100644
index 00000000000..6b8d4503568
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/compare/show/index.js
@@ -0,0 +1,8 @@
+import Diff from '~/diff';
+import initChangesDropdown from '~/init_changes_dropdown';
+
+export default () => {
+ new Diff(); // eslint-disable-line no-new
+ const paddingTop = 16;
+ initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - paddingTop);
+};
diff --git a/app/assets/javascripts/pages/projects/milestones/edit/index.js b/app/assets/javascripts/pages/projects/milestones/edit/index.js
new file mode 100644
index 00000000000..10e3979a36e
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/milestones/edit/index.js
@@ -0,0 +1,3 @@
+import initForm from '../../../../shared/milestones/form';
+
+export default () => initForm();
diff --git a/app/assets/javascripts/pages/projects/milestones/new/index.js b/app/assets/javascripts/pages/projects/milestones/new/index.js
new file mode 100644
index 00000000000..10e3979a36e
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/milestones/new/index.js
@@ -0,0 +1,3 @@
+import initForm from '../../../../shared/milestones/form';
+
+export default () => initForm();
diff --git a/app/assets/javascripts/pipelines/components/header_component.vue b/app/assets/javascripts/pipelines/components/header_component.vue
index 942acc8c412..e08c2092680 100644
--- a/app/assets/javascripts/pipelines/components/header_component.vue
+++ b/app/assets/javascripts/pipelines/components/header_component.vue
@@ -92,6 +92,7 @@
<loading-icon
v-if="isLoading"
size="2"
+ class="prepend-top-default append-bottom-default"
/>
</div>
</template>
diff --git a/app/assets/javascripts/shared/milestones/form.js b/app/assets/javascripts/shared/milestones/form.js
new file mode 100644
index 00000000000..db466f722c4
--- /dev/null
+++ b/app/assets/javascripts/shared/milestones/form.js
@@ -0,0 +1,9 @@
+import ZenMode from '../../zen_mode';
+import DueDateSelectors from '../../due_date_select';
+import GLForm from '../../gl_form';
+
+export default (initGFM = true) => {
+ new ZenMode(); // eslint-disable-line no-new
+ new DueDateSelectors(); // eslint-disable-line no-new
+ new GLForm($('.milestone-form'), initGFM); // eslint-disable-line no-new
+};
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
index e82fb979162..60f42c46ffe 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
@@ -1,6 +1,7 @@
import successSvg from 'icons/_icon_status_success.svg';
import warningSvg from 'icons/_icon_status_warning.svg';
import simplePoll from '~/lib/utils/simple_poll';
+import MergeRequest from '../../../merge_request';
import Flash from '../../../flash';
import statusIcon from '../mr_widget_status_icon';
import eventHub from '../../event_hub';
@@ -165,11 +166,9 @@ export default {
// If state is merged we should update the widget and stop the polling
eventHub.$emit('MRWidgetUpdateRequested');
eventHub.$emit('FetchActionsContent');
- if (window.mergeRequest) {
- window.mergeRequest.updateStatusText('status-box-open', 'status-box-merged', 'Merged');
- window.mergeRequest.hideCloseButton();
- window.mergeRequest.decreaseCounter();
- }
+ MergeRequest.updateStatusText('status-box-open', 'status-box-merged', 'Merged');
+ MergeRequest.hideCloseButton();
+ MergeRequest.decreaseCounter();
stopPolling();
// If user checked remove source branch and we didn't remove the branch yet
diff --git a/app/assets/javascripts/vue_shared/components/modal.vue b/app/assets/javascripts/vue_shared/components/modal.vue
index c103c45c7dd..8227428d8ba 100644
--- a/app/assets/javascripts/vue_shared/components/modal.vue
+++ b/app/assets/javascripts/vue_shared/components/modal.vue
@@ -122,7 +122,7 @@
>
<button
type="button"
- class="btn pull-left"
+ class="btn"
:class="btnCancelKindClass"
@click="emitCancel($event)"
data-dismiss="modal"
@@ -132,7 +132,7 @@
<button
v-if="primaryButtonLabel"
type="button"
- class="btn pull-right js-primary-button"
+ class="btn js-primary-button"
:disabled="submitDisabled"
:class="btnKindClass"
@click="emitSubmit($event)"
diff --git a/app/assets/stylesheets/framework/modal.scss b/app/assets/stylesheets/framework/modal.scss
index 1be66d0ab21..924472f2d7e 100644
--- a/app/assets/stylesheets/framework/modal.scss
+++ b/app/assets/stylesheets/framework/modal.scss
@@ -1,4 +1,5 @@
.modal-header {
+ background-color: $modal-body-bg;
padding: #{3 * $grid-size} #{2 * $grid-size};
.page-title {
@@ -8,6 +9,7 @@
.modal-body {
background-color: $modal-body-bg;
+ min-height: $modal-body-height;
position: relative;
padding: #{3 * $grid-size} #{2 * $grid-size};
@@ -20,6 +22,30 @@
}
}
+.modal-footer {
+ display: flex;
+ flex-direction: row;
+
+ .btn + .btn {
+ margin-left: $grid-size;
+ }
+
+ @media (max-width: $screen-xs-max) {
+ flex-direction: column;
+
+ .btn + .btn {
+ margin-left: 0;
+ margin-top: $grid-size;
+ }
+ }
+
+ @media (min-width: $screen-sm-min) {
+ .btn:first-of-type {
+ margin-left: auto;
+ }
+ }
+}
+
body.modal-open {
overflow: hidden;
}
@@ -32,12 +58,6 @@ body.modal-open {
}
}
-@media (min-width: $screen-md-min) {
- .modal-dialog {
- width: 860px;
- }
-}
-
@media (min-width: $screen-lg-min) {
.modal-full {
width: 98%;
diff --git a/app/assets/stylesheets/framework/tw_bootstrap_variables.scss b/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
index a23131e0818..d04e555769b 100644
--- a/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
+++ b/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
@@ -194,6 +194,6 @@ $modal-body-bg: $white-light;
//** Modal footer border color
// $modal-footer-border-color: $modal-header-border-color
-// $modal-lg: 900px
-// $modal-md: 600px
+$modal-lg: 860px;
+$modal-md: 540px;
// $modal-sm: 300px
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index ef1520f1f63..da18ddf78d3 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -733,3 +733,8 @@ $popup-box-shadow-color: rgba(90, 90, 90, 0.05);
Multi file editor
*/
$border-color-settings: #e1e1e1;
+
+/*
+Modals
+*/
+$modal-body-height: 134px;
diff --git a/app/assets/stylesheets/pages/xterm.scss b/app/assets/stylesheets/pages/xterm.scss
index c7297a34ad8..7d40c61da26 100644
--- a/app/assets/stylesheets/pages/xterm.scss
+++ b/app/assets/stylesheets/pages/xterm.scss
@@ -3,22 +3,21 @@
// see also: https://gist.github.com/jasonm23/2868981
$black: #000;
- $red: #cd0000;
- $green: #00cd00;
- $yellow: #cdcd00;
- $blue: #00e; // according to wikipedia, this is the xterm standard
- //$blue: #1e90ff; // this is used by all the terminals I tried (when configured with the xterm color profile)
- $magenta: #cd00cd;
- $cyan: #00cdcd;
- $white: #e5e5e5;
+ $red: #ea1010;
+ $green: #009900;
+ $yellow: #999900;
+ $blue: #0073e6;
+ $magenta: #d411d4;
+ $cyan: #009999;
+ $white: #ccc;
$l-black: #373b41;
- $l-red: #c66;
- $l-green: #b5bd68;
- $l-yellow: #f0c674;
- $l-blue: #81a2be;
- $l-magenta: #b294bb;
- $l-cyan: #8abeb7;
- $l-white: $gray-darkest;
+ $l-red: #ff6161;
+ $l-green: #00d600;
+ $l-yellow: #bdbd00;
+ $l-blue: #5797ff;
+ $l-magenta: #d96dd9;
+ $l-cyan: #00bdbd;
+ $l-white: #fff;
/*
* xterm colors
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index 3d2926d5d75..0df80fa700f 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -43,11 +43,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
end
def diffs
- @diffs = if @merge_request.can_be_created
- @merge_request.diffs(diff_options)
- else
- []
- end
+ @diffs = @merge_request.diffs(diff_options) if @merge_request.can_be_created
@diff_notes_disabled = true
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 5e3b2e5581c..a6e1de6ffdc 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -1,6 +1,8 @@
module BlobHelper
def highlight(blob_name, blob_content, repository: nil, plain: false)
+ plain ||= blob_content.length > Blob::MAXIMUM_TEXT_HIGHLIGHT_SIZE
highlighted = Gitlab::Highlight.highlight(blob_name, blob_content, plain: plain, repository: repository)
+
raw %(<pre class="code highlight"><code>#{highlighted}</code></pre>)
end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 21904c87f01..2d2d89af030 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -372,19 +372,19 @@ class Commit
# uri_type('doc/README.md') # => :blob
# uri_type('doc/logo.png') # => :raw
# uri_type('doc/api') # => :tree
- # uri_type('not/found') # => :nil
+ # uri_type('not/found') # => nil
#
# Returns a symbol
def uri_type(path)
- entry = @raw.rugged_tree_entry(path)
+ entry = @raw.tree_entry(path)
+ return unless entry
+
if entry[:type] == :blob
blob = ::Blob.decorate(Gitlab::Git::Blob.new(name: entry[:name]), @project)
blob.image? || blob.video? ? :raw : :blob
else
entry[:type]
end
- rescue Rugged::TreeError
- nil
end
def raw_diffs(*args)
diff --git a/app/models/push_event.rb b/app/models/push_event.rb
index 83ce9014094..90c085c888e 100644
--- a/app/models/push_event.rb
+++ b/app/models/push_event.rb
@@ -46,10 +46,11 @@ class PushEvent < Event
# Returns PushEvent instances for which no merge requests have been created.
def self.without_existing_merge_requests
- existing_mrs = MergeRequest.except(:order)
+ existing_mrs = MergeRequest.except(:order, :where)
.select(1)
.where('merge_requests.source_project_id = events.project_id')
.where('merge_requests.source_branch = push_event_payloads.ref')
+ .where(state: :opened)
# For reasons unknown the use of #eager_load will result in the
# "push_event_payload" association not being set. Because of this we're
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 2ffd9558ebc..b4bc0f87458 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -932,15 +932,17 @@ class Repository
return [] if empty? || query.blank?
offset = 2
- args = %W(grep -i -I -n --before-context #{offset} --after-context #{offset} -E -e #{Regexp.escape(query)} #{ref || root_ref})
+ args = %W(grep -i -I -n -z --before-context #{offset} --after-context #{offset} -E -e #{Regexp.escape(query)} #{ref || root_ref})
run_git(args).first.scrub.split(/^--$/)
end
def search_files_by_name(query, ref)
- return [] if empty? || query.blank?
+ safe_query = Regexp.escape(query.sub(/^\/*/, ""))
+
+ return [] if empty? || safe_query.blank?
- args = %W(ls-tree --full-tree -r #{ref || root_ref} --name-status | #{Regexp.escape(query)})
+ args = %W(ls-tree --full-tree -r #{ref || root_ref} --name-status | #{safe_query})
run_git(args).first.lines.map(&:strip)
end
diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb
index 30a5aab13bf..06b23cd7076 100644
--- a/app/services/system_note_service.rb
+++ b/app/services/system_note_service.rb
@@ -68,21 +68,14 @@ module SystemNoteService
#
# Returns the created Note object
def change_issue_assignees(issue, project, author, old_assignees)
- body =
- if issue.assignees.any? && old_assignees.any?
- unassigned_users = old_assignees - issue.assignees
- added_users = issue.assignees.to_a - old_assignees
-
- text_parts = []
- text_parts << "assigned to #{added_users.map(&:to_reference).to_sentence}" if added_users.any?
- text_parts << "unassigned #{unassigned_users.map(&:to_reference).to_sentence}" if unassigned_users.any?
-
- text_parts.join(' and ')
- elsif old_assignees.any?
- "removed assignee"
- elsif issue.assignees.any?
- "assigned to #{issue.assignees.map(&:to_reference).to_sentence}"
- end
+ unassigned_users = old_assignees - issue.assignees
+ added_users = issue.assignees.to_a - old_assignees
+
+ text_parts = []
+ text_parts << "assigned to #{added_users.map(&:to_reference).to_sentence}" if added_users.any?
+ text_parts << "unassigned #{unassigned_users.map(&:to_reference).to_sentence}" if unassigned_users.any?
+
+ body = text_parts.join(' and ')
create_note(NoteSummary.new(issue, project, author, body, action: 'assignee'))
end
diff --git a/app/views/dashboard/_activity_head.html.haml b/app/views/dashboard/_activity_head.html.haml
index ecdf76ef5c5..7a3f3667ac1 100644
--- a/app/views/dashboard/_activity_head.html.haml
+++ b/app/views/dashboard/_activity_head.html.haml
@@ -2,7 +2,7 @@
%ul.nav-links
%li{ class: active_when(params[:filter].nil?) }>
= link_to activity_dashboard_path, class: 'shortcuts-activity', data: {placement: 'right'} do
- Your Projects
+ Your projects
%li{ class: active_when(params[:filter] == 'starred') }>
= link_to activity_dashboard_path(filter: 'starred'), data: {placement: 'right'} do
- Starred Projects
+ Starred projects
diff --git a/app/views/dashboard/_snippets_head.html.haml b/app/views/dashboard/_snippets_head.html.haml
index 7330f4cb523..a9488df07bd 100644
--- a/app/views/dashboard/_snippets_head.html.haml
+++ b/app/views/dashboard/_snippets_head.html.haml
@@ -2,10 +2,10 @@
%ul.nav-links
= nav_link(page: dashboard_snippets_path, html_options: {class: 'home'}) do
= link_to dashboard_snippets_path, title: 'Your snippets', data: {placement: 'right'} do
- Your Snippets
+ Your snippets
= nav_link(page: explore_snippets_path) do
= link_to explore_snippets_path, title: 'Explore snippets', data: {placement: 'right'} do
- Explore Snippets
+ Explore snippets
- if current_user
.nav-controls.hidden-xs
diff --git a/app/views/profiles/gpg_keys/index.html.haml b/app/views/profiles/gpg_keys/index.html.haml
index 86ebec0179c..e44506ec9c9 100644
--- a/app/views/profiles/gpg_keys/index.html.haml
+++ b/app/views/profiles/gpg_keys/index.html.haml
@@ -3,12 +3,12 @@
= render 'profiles/head'
.row.prepend-top-default
- .col-lg-3.profile-settings-sidebar
+ .col-lg-4.profile-settings-sidebar
%h4.prepend-top-0
= page_title
%p
GPG keys allow you to verify signed commits.
- .col-lg-9
+ .col-lg-8
%h5.prepend-top-0
Add a GPG key
%p.profile-settings-content
diff --git a/app/views/projects/blob/_new_dir.html.haml b/app/views/projects/blob/_new_dir.html.haml
index 03ab1bb59e4..5d48a35dc4c 100644
--- a/app/views/projects/blob/_new_dir.html.haml
+++ b/app/views/projects/blob/_new_dir.html.haml
@@ -1,5 +1,5 @@
#modal-create-new-dir.modal
- .modal-dialog
+ .modal-dialog.modal-lg
.modal-content
.modal-header
%a.close{ href: "#", "data-dismiss" => "modal" } ×
diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml
index 05b7dfe2872..21b6aa4bad9 100644
--- a/app/views/projects/blob/_upload.html.haml
+++ b/app/views/projects/blob/_upload.html.haml
@@ -1,5 +1,5 @@
#modal-upload-blob.modal
- .modal-dialog
+ .modal-dialog.modal-lg
.modal-content
.modal-header
%a.close{ href: "#", "data-dismiss" => "modal" } ×
diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml
index 8e8c911185a..a94d9c14722 100644
--- a/app/views/projects/buttons/_dropdown.html.haml
+++ b/app/views/projects/buttons/_dropdown.html.haml
@@ -10,37 +10,28 @@
- if can_create_issue
%li
- = link_to new_project_issue_path(@project) do
- #{ _('New issue') }
-
+ = link_to _('New issue'), new_project_issue_path(@project)
- if merge_project
%li
- = link_to project_new_merge_request_path(merge_project) do
- #{ _('New merge request') }
-
+ = link_to _('New merge request'), project_new_merge_request_path(merge_project)
- if can_create_snippet
%li
- = link_to new_project_snippet_path(@project) do
- #{ _('New snippet') }
+ = link_to _('New snippet'), new_project_snippet_path(@project)
- if can_create_issue || merge_project || can_create_snippet
%li.divider
- if can?(current_user, :push_code, @project)
%li
- = link_to project_new_blob_path(@project, @project.default_branch || 'master') do
- #{ _('New file') }
+ = link_to _('New file'), project_new_blob_path(@project, @project.default_branch || 'master')
- unless @project.empty_repo?
%li
- = link_to new_project_branch_path(@project) do
- #{ _('New branch') }
+ = link_to _('New branch'), new_project_branch_path(@project)
%li
- = link_to new_project_tag_path(@project) do
- #{ _('New tag') }
+ = link_to _('New tag'), new_project_tag_path(@project)
- elsif current_user && current_user.already_forked?(@project)
%li
- = link_to project_new_blob_path(@project, @project.default_branch || 'master') do
- #{ _('New file') }
+ = link_to _('New file'), project_new_blob_path(@project, @project.default_branch || 'master')
- elsif can?(current_user, :fork_project, @project)
%li
- continue_params = { to: project_new_blob_path(@project, @project.default_branch || 'master'),
@@ -48,5 +39,4 @@
notice_now: edit_in_new_fork_notice_now }
- fork_path = project_forks_path(@project, namespace_key: current_user.namespace.id,
continue: continue_params)
- = link_to fork_path, method: :post do
- #{ _('New file') }
+ = link_to _('New file'), fork_path, method: :post
diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml
index 111cbcda266..21a4702a2a9 100644
--- a/app/views/projects/forks/index.html.haml
+++ b/app/views/projects/forks/index.html.haml
@@ -31,11 +31,11 @@
- if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn btn-new' do
- = custom_icon('icon_fork')
+ = sprite_icon('fork', size: 12)
%span Fork
- else
= link_to new_project_fork_path(@project), title: "Fork project", class: 'btn btn-new' do
- = custom_icon('icon_fork')
+ = sprite_icon('fork', size: 12)
%span Fork
diff --git a/app/views/projects/jobs/_sidebar.html.haml b/app/views/projects/jobs/_sidebar.html.haml
index a71333497e6..e779473c239 100644
--- a/app/views/projects/jobs/_sidebar.html.haml
+++ b/app/views/projects/jobs/_sidebar.html.haml
@@ -24,7 +24,7 @@
- elsif @build.has_expiring_artifacts?
%p.build-detail-row
The artifacts will be removed in
- %span.js-artifacts-remove= @build.artifacts_expire_at
+ %span= time_ago_in_words @build.artifacts_expire_at
- if @build.artifacts?
.btn-group.btn-group-justified{ role: :group }
diff --git a/app/views/projects/merge_requests/creations/_diffs.html.haml b/app/views/projects/merge_requests/creations/_diffs.html.haml
index 627fc4e9671..5b70e894b39 100644
--- a/app/views/projects/merge_requests/creations/_diffs.html.haml
+++ b/app/views/projects/merge_requests/creations/_diffs.html.haml
@@ -1 +1,5 @@
-= render "projects/diffs/diffs", diffs: @diffs, environment: @environment, show_whitespace_toggle: false
+- if @merge_request.can_be_created
+ = render "projects/diffs/diffs", diffs: @diffs, environment: @environment, show_whitespace_toggle: false
+- else
+ .nothing-here-block
+ This merge request cannot be created.
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index 63aa4e29ec9..2a75b46d376 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -52,7 +52,7 @@
= render_project_pipeline_status(project.pipeline_status)
- if forks
%span.prepend-left-10
- = sprite_icon('fork')
+ = sprite_icon('fork', size: 12)
= number_with_delimiter(project.forks_count)
- if stars
%span.prepend-left-10
diff --git a/changelogs/unreleased/16301-update-removed-assignee-note-to-include-old-assignee-reference.yml b/changelogs/unreleased/16301-update-removed-assignee-note-to-include-old-assignee-reference.yml
new file mode 100644
index 00000000000..e94b4f8bb26
--- /dev/null
+++ b/changelogs/unreleased/16301-update-removed-assignee-note-to-include-old-assignee-reference.yml
@@ -0,0 +1,5 @@
+---
+title: "Update 'removed assignee' note to include old assignee reference"
+merge_request: 16301
+author: Maurizio De Santis
+type: changed
diff --git a/changelogs/unreleased/36571-ignore-root-in-repo.yml b/changelogs/unreleased/36571-ignore-root-in-repo.yml
new file mode 100644
index 00000000000..396e82be51b
--- /dev/null
+++ b/changelogs/unreleased/36571-ignore-root-in-repo.yml
@@ -0,0 +1,5 @@
+---
+title: Ignore leading slashes when searching for files within context of repository.
+merge_request:
+author: Andrew McCallum
+type: fixed
diff --git a/changelogs/unreleased/37898-increase-readability-of-colored-text-in-job-output-log.yml b/changelogs/unreleased/37898-increase-readability-of-colored-text-in-job-output-log.yml
new file mode 100644
index 00000000000..813b9ab81fa
--- /dev/null
+++ b/changelogs/unreleased/37898-increase-readability-of-colored-text-in-job-output-log.yml
@@ -0,0 +1,5 @@
+---
+title: increase-readability-of-colored-text-in-job-output-log
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/40818-last-push-widget-does-not-appear-after-pushing-new-commit.yml b/changelogs/unreleased/40818-last-push-widget-does-not-appear-after-pushing-new-commit.yml
new file mode 100644
index 00000000000..c57caf31d10
--- /dev/null
+++ b/changelogs/unreleased/40818-last-push-widget-does-not-appear-after-pushing-new-commit.yml
@@ -0,0 +1,5 @@
+---
+title: Last push widget will show banner for new pushes to previously merged branch
+merge_request:
+author:
+type: changed
diff --git a/changelogs/unreleased/41476-enable-project-milestons-deletion-via-api.yml b/changelogs/unreleased/41476-enable-project-milestons-deletion-via-api.yml
new file mode 100644
index 00000000000..bb5c1fdf082
--- /dev/null
+++ b/changelogs/unreleased/41476-enable-project-milestons-deletion-via-api.yml
@@ -0,0 +1,5 @@
+---
+title: Enables Project Milestone Deletion via the API
+merge_request: 16478
+author: Jacopo Beschi @jacopo-beschi
+type: added
diff --git a/changelogs/unreleased/41666-cannot-search-with-keyword-merge-2.yml b/changelogs/unreleased/41666-cannot-search-with-keyword-merge-2.yml
new file mode 100644
index 00000000000..48893862071
--- /dev/null
+++ b/changelogs/unreleased/41666-cannot-search-with-keyword-merge-2.yml
@@ -0,0 +1,5 @@
+---
+title: Only highlight search results under the highlighting size limit
+merge_request: 16462
+author:
+type: performance
diff --git a/changelogs/unreleased/41666-cannot-search-with-keyword-merge.yml b/changelogs/unreleased/41666-cannot-search-with-keyword-merge.yml
new file mode 100644
index 00000000000..3a6fa425c9c
--- /dev/null
+++ b/changelogs/unreleased/41666-cannot-search-with-keyword-merge.yml
@@ -0,0 +1,6 @@
+---
+title: Fix file search results when they match file contents with a number between
+ two colons
+merge_request: 16462
+author:
+type: fixed
diff --git a/changelogs/unreleased/42031-fix-links-to-uploads-in-wikis.yml b/changelogs/unreleased/42031-fix-links-to-uploads-in-wikis.yml
new file mode 100644
index 00000000000..027cb414f23
--- /dev/null
+++ b/changelogs/unreleased/42031-fix-links-to-uploads-in-wikis.yml
@@ -0,0 +1,5 @@
+---
+title: Fix links to uploaded files on wiki pages
+merge_request: 16499
+author:
+type: fixed
diff --git a/changelogs/unreleased/42046-fork-icon.yml b/changelogs/unreleased/42046-fork-icon.yml
new file mode 100644
index 00000000000..def89ff7b08
--- /dev/null
+++ b/changelogs/unreleased/42046-fork-icon.yml
@@ -0,0 +1,5 @@
+---
+title: Fix giant fork icons on forks page
+merge_request: 16474
+author:
+type: fixed
diff --git a/changelogs/unreleased/42047-pg-10-support.yml b/changelogs/unreleased/42047-pg-10-support.yml
new file mode 100644
index 00000000000..f98e59329c3
--- /dev/null
+++ b/changelogs/unreleased/42047-pg-10-support.yml
@@ -0,0 +1,5 @@
+---
+title: Support PostgreSQL 10
+merge_request: 16471
+author:
+type: added
diff --git a/changelogs/unreleased/issue_41460.yml b/changelogs/unreleased/issue_41460.yml
new file mode 100644
index 00000000000..24d3eae6bf8
--- /dev/null
+++ b/changelogs/unreleased/issue_41460.yml
@@ -0,0 +1,5 @@
+---
+title: Fix error on changes tab when merge request cannot be created
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/jej-lfs-rev-list-handles-non-utf-paths-41627.yml b/changelogs/unreleased/jej-lfs-rev-list-handles-non-utf-paths-41627.yml
new file mode 100644
index 00000000000..24f18c07ac5
--- /dev/null
+++ b/changelogs/unreleased/jej-lfs-rev-list-handles-non-utf-paths-41627.yml
@@ -0,0 +1,5 @@
+---
+title: Prevent RevList failing on non utf8 paths
+merge_request: 16440
+author:
+type: fixed
diff --git a/changelogs/unreleased/mr-status-box-update.yml b/changelogs/unreleased/mr-status-box-update.yml
new file mode 100644
index 00000000000..68265be16a1
--- /dev/null
+++ b/changelogs/unreleased/mr-status-box-update.yml
@@ -0,0 +1,5 @@
+---
+title: Fixed merge request status badge not updating after merging
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/winh-style-modals.yml b/changelogs/unreleased/winh-style-modals.yml
new file mode 100644
index 00000000000..b7d0293960d
--- /dev/null
+++ b/changelogs/unreleased/winh-style-modals.yml
@@ -0,0 +1,5 @@
+---
+title: Adjust modal style to new design
+merge_request: 16310
+author:
+type: other
diff --git a/config/initializers/ar5_pg_10_support.rb b/config/initializers/ar5_pg_10_support.rb
new file mode 100644
index 00000000000..6fae770015c
--- /dev/null
+++ b/config/initializers/ar5_pg_10_support.rb
@@ -0,0 +1,57 @@
+raise "Vendored ActiveRecord 5 code! Delete #{__FILE__}!" if ActiveRecord::VERSION::MAJOR >= 5
+
+require 'active_record/connection_adapters/postgresql_adapter'
+require 'active_record/connection_adapters/postgresql/schema_statements'
+
+#
+# Monkey-patch the refused Rails 4.2 patch at https://github.com/rails/rails/pull/31330
+#
+# Updates sequence logic to support PostgreSQL 10.
+#
+# rubocop:disable all
+module ActiveRecord
+ module ConnectionAdapters
+
+ # We need #postgresql_version to be public as in ActiveRecord 5 for seed_fu
+ # to work. In ActiveRecord 4, it is protected.
+ # https://github.com/mbleigh/seed-fu/issues/123
+ class PostgreSQLAdapter
+ public :postgresql_version
+ end
+
+ module PostgreSQL
+ module SchemaStatements
+ # Resets the sequence of a table's primary key to the maximum value.
+ def reset_pk_sequence!(table, pk = nil, sequence = nil) #:nodoc:
+ unless pk and sequence
+ default_pk, default_sequence = pk_and_sequence_for(table)
+
+ pk ||= default_pk
+ sequence ||= default_sequence
+ end
+
+ if @logger && pk && !sequence
+ @logger.warn "#{table} has primary key #{pk} with no default sequence"
+ end
+
+ if pk && sequence
+ quoted_sequence = quote_table_name(sequence)
+ max_pk = select_value("SELECT MAX(#{quote_column_name pk}) FROM #{quote_table_name(table)}")
+ if max_pk.nil?
+ if postgresql_version >= 100000
+ minvalue = select_value("SELECT seqmin FROM pg_sequence WHERE seqrelid = #{quote(quoted_sequence)}::regclass")
+ else
+ minvalue = select_value("SELECT min_value FROM #{quoted_sequence}")
+ end
+ end
+
+ select_value <<-end_sql, 'SCHEMA'
+ SELECT setval(#{quote(quoted_sequence)}, #{max_pk ? max_pk : minvalue}, #{max_pk ? true : false})
+ end_sql
+ end
+ end
+ end
+ end
+ end
+end
+# rubocop:enable all
diff --git a/db/migrate/20171207185153_add_merge_request_state_index.rb b/db/migrate/20171207185153_add_merge_request_state_index.rb
new file mode 100644
index 00000000000..72f846c5c38
--- /dev/null
+++ b/db/migrate/20171207185153_add_merge_request_state_index.rb
@@ -0,0 +1,18 @@
+class AddMergeRequestStateIndex < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :merge_requests, [:source_project_id, :source_branch],
+ where: "state = 'opened'",
+ name: 'index_merge_requests_on_source_project_and_branch_state_opened'
+ end
+
+ def down
+ remove_concurrent_index_by_name :merge_requests,
+ 'index_merge_requests_on_source_project_and_branch_state_opened'
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f47accca21a..a32d20b8f28 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -1109,6 +1109,7 @@ ActiveRecord::Schema.define(version: 20180105212544) do
add_index "merge_requests", ["merge_user_id"], name: "index_merge_requests_on_merge_user_id", where: "(merge_user_id IS NOT NULL)", using: :btree
add_index "merge_requests", ["milestone_id"], name: "index_merge_requests_on_milestone_id", using: :btree
add_index "merge_requests", ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree
+ add_index "merge_requests", ["source_project_id", "source_branch"], name: "index_merge_requests_on_source_project_and_branch_state_opened", where: "((state)::text = 'opened'::text)", using: :btree
add_index "merge_requests", ["source_project_id", "source_branch"], name: "index_merge_requests_on_source_project_id_and_source_branch", using: :btree
add_index "merge_requests", ["target_branch"], name: "index_merge_requests_on_target_branch", using: :btree
add_index "merge_requests", ["target_project_id", "iid"], name: "index_merge_requests_on_target_project_id_and_iid", unique: true, using: :btree
diff --git a/doc/api/milestones.md b/doc/api/milestones.md
index 84930f0bdc9..d35e940d7b1 100644
--- a/doc/api/milestones.md
+++ b/doc/api/milestones.md
@@ -93,6 +93,19 @@ Parameters:
- `start_date` (optional) - The start date of the milestone
- `state_event` (optional) - The state event of the milestone (close|activate)
+## Delete project milestone
+
+Only for user with developer access to the project.
+
+```
+DELETE /projects/:id/milestones/:milestone_id
+```
+
+Parameters:
+
+- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
+- `milestone_id` (required) - The ID of the project's milestone
+
## Get all issues assigned to a single milestone
Gets all issues assigned to a single project milestone.
diff --git a/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md b/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md
index 10fd2616fab..7f9ab1f3a5e 100644
--- a/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md
+++ b/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md
@@ -10,6 +10,7 @@ This is what the `.gitlab-ci.yml` file looks like for this project:
```yaml
test:
+ stage: test
script:
- apt-get update -qy
- apt-get install -y nodejs
@@ -18,7 +19,7 @@ test:
- bundle exec rake test
staging:
- type: deploy
+ stage: deploy
script:
- gem install dpl
- dpl --provider=heroku --app=gitlab-ci-ruby-test-staging --api-key=$HEROKU_STAGING_API_KEY
@@ -26,7 +27,7 @@ staging:
- master
production:
- type: deploy
+ stage: deploy
script:
- gem install dpl
- dpl --provider=heroku --app=gitlab-ci-ruby-test-prod --api-key=$HEROKU_PRODUCTION_API_KEY
diff --git a/doc/development/doc_styleguide.md b/doc/development/doc_styleguide.md
index 8db617594e5..f41d31797af 100644
--- a/doc/development/doc_styleguide.md
+++ b/doc/development/doc_styleguide.md
@@ -201,7 +201,7 @@ You can combine one or more of the following:
- Keep all file names in lower case.
- Consider using PNG images instead of JPEG.
- Compress all images with <https://tinypng.com/> or similar tool.
-- Compress gifs with <https://ezgif.com/optimize> or similar toll.
+- Compress gifs with <https://ezgif.com/optimize> or similar tool.
- Images should be used (only when necessary) to _illustrate_ the description
of a process, not to _replace_ it.
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index baecf9455b0..272148033b5 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -121,7 +121,7 @@ Existing users using GitLab with MySQL/MariaDB are advised to
### PostgreSQL Requirements
-As of GitLab 10.0, PostgreSQL 9.6 or newer (but less than 10) is required, and earlier versions are
+As of GitLab 10.0, PostgreSQL 9.6 or newer is required, and earlier versions are
not supported. We highly recommend users to use PostgreSQL 9.6 as this
is the PostgreSQL version used for development and testing.
diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb
index a116ab3c9bd..9c205514b3a 100644
--- a/lib/api/jobs.rb
+++ b/lib/api/jobs.rb
@@ -38,6 +38,7 @@ module API
builds = user_project.builds.order('id DESC')
builds = filter_builds(builds, params[:scope])
+ builds = builds.preload(:user, :job_artifacts_archive, :runner, pipeline: :project)
present paginate(builds), with: Entities::Job
end
diff --git a/lib/api/project_milestones.rb b/lib/api/project_milestones.rb
index 0cb209a02d0..306dc0e63d7 100644
--- a/lib/api/project_milestones.rb
+++ b/lib/api/project_milestones.rb
@@ -60,6 +60,15 @@ module API
update_milestone_for(user_project)
end
+ desc 'Remove a project milestone'
+ delete ":id/milestones/:milestone_id" do
+ authorize! :admin_milestone, user_project
+
+ user_project.milestones.find(params[:milestone_id]).destroy
+
+ status(204)
+ end
+
desc 'Get all issues for a single project milestone' do
success Entities::IssueBasic
end
diff --git a/lib/api/v3/builds.rb b/lib/api/v3/builds.rb
index fa0bef39602..ac76fece931 100644
--- a/lib/api/v3/builds.rb
+++ b/lib/api/v3/builds.rb
@@ -36,6 +36,7 @@ module API
builds = user_project.builds.order('id DESC')
builds = filter_builds(builds, params[:scope])
+ builds = builds.preload(:user, :job_artifacts_archive, :runner, pipeline: :project)
present paginate(builds), with: ::API::V3::Entities::Build
end
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index 05aa79dc160..f27ce4d2b2b 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -108,7 +108,10 @@ module Backup
$progress.puts "Please make sure that file name ends with #{FILE_NAME_SUFFIX}"
exit 1
elsif backup_file_list.many? && ENV["BACKUP"].nil?
- $progress.puts 'Found more than one backup, please specify which one you want to restore:'
+ $progress.puts 'Found more than one backup:'
+ # print list of available backups
+ $progress.puts " " + available_timestamps.join("\n ")
+ $progress.puts 'Please specify which one you want to restore:'
$progress.puts 'rake gitlab:backup:restore BACKUP=timestamp_of_backup'
exit 1
end
@@ -169,6 +172,10 @@ module Backup
@backup_file_list ||= Dir.glob("*#{FILE_NAME_SUFFIX}")
end
+ def available_timestamps
+ @backup_file_list.map {|item| item.gsub("#{FILE_NAME_SUFFIX}", "")}
+ end
+
def connect_to_remote_directory(connection_settings)
# our settings use string keys, but Fog expects symbols
connection = ::Fog::Storage.new(connection_settings.symbolize_keys)
diff --git a/lib/banzai/filter/wiki_link_filter/rewriter.rb b/lib/banzai/filter/wiki_link_filter/rewriter.rb
index e7a1ec8457d..072d24e5a11 100644
--- a/lib/banzai/filter/wiki_link_filter/rewriter.rb
+++ b/lib/banzai/filter/wiki_link_filter/rewriter.rb
@@ -9,6 +9,10 @@ module Banzai
end
def apply_rules
+ # Special case: relative URLs beginning with `/uploads/` refer to
+ # user-uploaded files and will be handled elsewhere.
+ return @uri.to_s if @uri.relative? && @uri.path.starts_with?('/uploads/')
+
apply_file_link_rules!
apply_hierarchical_link_rules!
apply_relative_link_rules!
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
index 016437b2419..46e0c0e82a2 100644
--- a/lib/gitlab/git/commit.rb
+++ b/lib/gitlab/git/commit.rb
@@ -436,6 +436,16 @@ module Gitlab
parent_ids.size > 1
end
+ def tree_entry(path)
+ @repository.gitaly_migrate(:commit_tree_entry) do |is_migrated|
+ if is_migrated
+ gitaly_tree_entry(path)
+ else
+ rugged_tree_entry(path)
+ end
+ end
+ end
+
def to_gitaly_commit
return raw_commit if raw_commit.is_a?(Gitaly::GitCommit)
@@ -450,11 +460,6 @@ module Gitlab
)
end
- # Is this the same as Blob.find_entry_by_path ?
- def rugged_tree_entry(path)
- rugged_commit.tree.path(path)
- end
-
private
def init_from_hash(hash)
@@ -501,6 +506,28 @@ module Gitlab
SERIALIZE_KEYS
end
+ def gitaly_tree_entry(path)
+ # We're only interested in metadata, so limit actual data to 1 byte
+ # since Gitaly doesn't support "send no data" option.
+ entry = @repository.gitaly_commit_client.tree_entry(id, path, 1)
+ return unless entry
+
+ # To be compatible with the rugged format
+ entry = entry.to_h
+ entry.delete(:data)
+ entry[:name] = File.basename(path)
+ entry[:type] = entry[:type].downcase
+
+ entry
+ end
+
+ # Is this the same as Blob.find_entry_by_path ?
+ def rugged_tree_entry(path)
+ rugged_commit.tree.path(path)
+ rescue Rugged::TreeError
+ nil
+ end
+
def gitaly_commit_author_from_rugged(author_or_committer)
Gitaly::CommitAuthor.new(
name: author_or_committer[:name].b,
diff --git a/lib/gitlab/git/rev_list.rb b/lib/gitlab/git/rev_list.rb
index 4974205b8fd..f8b2e7e0e21 100644
--- a/lib/gitlab/git/rev_list.rb
+++ b/lib/gitlab/git/rev_list.rb
@@ -95,7 +95,7 @@ module Gitlab
object_output.map do |output_line|
sha, path = output_line.split(' ', 2)
- next if require_path && path.blank?
+ next if require_path && path.to_s.empty?
sha
end.reject(&:nil?)
diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb
index e2662fc362b..7771b15069b 100644
--- a/lib/gitlab/project_search_results.rb
+++ b/lib/gitlab/project_search_results.rb
@@ -44,25 +44,20 @@ module Gitlab
ref = nil
filename = nil
basename = nil
+ data = ""
startline = 0
- result.each_line.each_with_index do |line, index|
- matches = line.match(/^(?<ref>[^:]*):(?<filename>.*):(?<startline>\d+):/)
- if matches
+ result.strip.each_line.each_with_index do |line, index|
+ prefix ||= line.match(/^(?<ref>[^:]*):(?<filename>.*)\x00(?<startline>\d+)\x00/)&.tap do |matches|
ref = matches[:ref]
filename = matches[:filename]
startline = matches[:startline]
startline = startline.to_i - index
extname = Regexp.escape(File.extname(filename))
basename = filename.sub(/#{extname}$/, '')
- break
end
- end
-
- data = ""
- result.each_line do |line|
- data << line.sub(ref, '').sub(filename, '').sub(/^:-\d+-/, '').sub(/^::\d+:/, '')
+ data << line.sub(prefix.to_s, '')
end
FoundBlob.new(
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index 7e2366847f4..92db7284e0e 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -4,6 +4,16 @@ describe Projects::MergeRequests::CreationsController do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:fork_project) { create(:forked_project_with_submodules) }
+ let(:get_diff_params) do
+ {
+ namespace_id: fork_project.namespace.to_param,
+ project_id: fork_project,
+ merge_request: {
+ source_branch: 'remove-submodule',
+ target_branch: 'master'
+ }
+ }
+ end
before do
fork_project.add_master(user)
@@ -13,18 +23,23 @@ describe Projects::MergeRequests::CreationsController do
describe 'GET new' do
context 'merge request that removes a submodule' do
- render_views
-
it 'renders new merge request widget template' do
- get :new,
- namespace_id: fork_project.namespace.to_param,
- project_id: fork_project,
- merge_request: {
- source_branch: 'remove-submodule',
- target_branch: 'master'
- }
+ get :new, get_diff_params
+
+ expect(response).to be_success
+ end
+ end
+ end
+
+ describe 'GET diffs' do
+ context 'when merge request cannot be created' do
+ it 'does not assign diffs var' do
+ allow_any_instance_of(MergeRequest).to receive(:can_be_created).and_return(false)
+
+ get :diffs, get_diff_params.merge(format: 'json')
expect(response).to be_success
+ expect(assigns[:diffs]).to be_nil
end
end
end
@@ -37,14 +52,7 @@ describe Projects::MergeRequests::CreationsController do
end
it 'renders JSON including serialized pipelines' do
- get :pipelines,
- namespace_id: fork_project.namespace.to_param,
- project_id: fork_project,
- merge_request: {
- source_branch: 'remove-submodule',
- target_branch: 'master'
- },
- format: :json
+ get :pipelines, get_diff_params.merge(format: 'json')
expect(response).to be_ok
expect(json_response).to have_key 'pipelines'
diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb
index 04620f6d88c..a030796c54e 100644
--- a/spec/helpers/blob_helper_spec.rb
+++ b/spec/helpers/blob_helper_spec.rb
@@ -22,6 +22,13 @@ describe BlobHelper do
expect(result).to eq(%[<pre class="code highlight"><code><span id="LC1" class="line" lang="">:type "assem"))</span></code></pre>])
end
+ it 'returns plaintext for long blobs' do
+ stub_const('Blob::MAXIMUM_TEXT_HIGHLIGHT_SIZE', 1)
+ result = helper.highlight(blob_name, blob_content)
+
+ expect(result).to eq(%[<pre class="code highlight"><code><span id="LC1" class="line" lang="">(make-pathname :defaults name</span>\n<span id="LC2" class="line" lang="">:type "assem"))</span></code></pre>])
+ end
+
it 'highlights single block' do
expected = %Q[<pre class="code highlight"><code><span id="LC1" class="line" lang="common_lisp"><span class="p">(</span><span class="nb">make-pathname</span> <span class="ss">:defaults</span> <span class="nv">name</span></span>
<span id="LC2" class="line" lang="common_lisp"><span class="ss">:type</span> <span class="s">"assem"</span><span class="p">))</span></span></code></pre>]
diff --git a/spec/javascripts/job_spec.js b/spec/javascripts/job_spec.js
index b740c9ed893..feb341d22e6 100644
--- a/spec/javascripts/job_spec.js
+++ b/spec/javascripts/job_spec.js
@@ -52,11 +52,6 @@ describe('Job', () => {
expect($('.build-job[data-stage="test"]').is(':visible')).toBe(false);
expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false);
});
-
- it('displays the remove date correctly', () => {
- const removeDateElement = document.querySelector('.js-artifacts-remove');
- expect(removeDateElement.innerText.trim()).toBe('1 year remaining');
- });
});
describe('running build', () => {
diff --git a/spec/javascripts/merge_request_spec.js b/spec/javascripts/merge_request_spec.js
index 9d6ea3781bc..bae3219b043 100644
--- a/spec/javascripts/merge_request_spec.js
+++ b/spec/javascripts/merge_request_spec.js
@@ -70,8 +70,8 @@ import IssuablesHelper from '~/helpers/issuables_helper';
beforeEach(() => {
loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
this.el = document.querySelector('.js-issuable-actions');
- const merge = new MergeRequest();
- merge.hideCloseButton();
+ new MergeRequest(); // eslint-disable-line no-new
+ MergeRequest.hideCloseButton();
});
it('hides the dropdown close item and selects the next item', () => {
@@ -90,8 +90,7 @@ import IssuablesHelper from '~/helpers/issuables_helper';
beforeEach(() => {
loadFixtures('merge_requests/merge_request_of_current_user.html.raw');
this.el = document.querySelector('.js-issuable-actions');
- const merge = new MergeRequest();
- merge.hideCloseButton();
+ MergeRequest.hideCloseButton();
});
it('hides the close button', () => {
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
index 1127576617b..11858e45386 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -371,6 +371,10 @@ describe('MRWidgetReadyToMerge', () => {
});
});
+ beforeEach(() => {
+ loadFixtures('merge_requests/merge_request_of_current_user.html.raw');
+ });
+
it('should call start and stop polling when MR merged', (done) => {
spyOn(eventHub, '$emit');
spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
@@ -392,6 +396,47 @@ describe('MRWidgetReadyToMerge', () => {
}, 333);
});
+ it('updates status box', (done) => {
+ spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
+ spyOn(vm, 'initiateRemoveSourceBranchPolling');
+
+ vm.handleMergePolling(() => {}, () => {});
+
+ setTimeout(() => {
+ const statusBox = document.querySelector('.status-box');
+ expect(statusBox.classList.contains('status-box-merged')).toBeTruthy();
+ expect(statusBox.textContent).toContain('Merged');
+
+ done();
+ });
+ });
+
+ it('hides close button', (done) => {
+ spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
+ spyOn(vm, 'initiateRemoveSourceBranchPolling');
+
+ vm.handleMergePolling(() => {}, () => {});
+
+ setTimeout(() => {
+ expect(document.querySelector('.btn-close').classList.contains('hidden')).toBeTruthy();
+
+ done();
+ });
+ });
+
+ it('updates merge request count badge', (done) => {
+ spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
+ spyOn(vm, 'initiateRemoveSourceBranchPolling');
+
+ vm.handleMergePolling(() => {}, () => {});
+
+ setTimeout(() => {
+ expect(document.querySelector('.js-merge-counter').textContent).toBe('0');
+
+ done();
+ });
+ });
+
it('should continue polling until MR is merged', (done) => {
spyOn(vm.service, 'poll').and.returnValue(returnPromise('some_other_state'));
spyOn(vm, 'initiateRemoveSourceBranchPolling');
diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb
index b68301a066a..5100f5737c2 100644
--- a/spec/lib/backup/manager_spec.rb
+++ b/spec/lib/backup/manager_spec.rb
@@ -194,6 +194,12 @@ describe Backup::Manager do
)
end
+ it 'prints the list of available backups' do
+ expect { subject.unpack }.to raise_error SystemExit
+ expect(progress).to have_received(:puts)
+ .with(a_string_matching('1451606400_2016_01_01_1.2.3\n 1451520000_2015_12_31'))
+ end
+
it 'fails the operation and prints an error' do
expect { subject.unpack }.to raise_error SystemExit
expect(progress).to have_received(:puts)
diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
index 9596f004052..50d053011b3 100644
--- a/spec/lib/banzai/filter/wiki_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
@@ -10,15 +10,23 @@ describe Banzai::Filter::WikiLinkFilter do
it "doesn't rewrite absolute links" do
filtered_link = filter("<a href='http://example.com:8000/'>Link</a>", project_wiki: wiki).children[0]
+
expect(filtered_link.attribute('href').value).to eq('http://example.com:8000/')
end
+ it "doesn't rewrite links to project uploads" do
+ filtered_link = filter("<a href='/uploads/a.test'>Link</a>", project_wiki: wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to eq('/uploads/a.test')
+ end
+
describe "invalid links" do
invalid_links = ["http://:8080", "http://", "http://:8080/path"]
invalid_links.each do |invalid_link|
it "doesn't rewrite invalid invalid_links like #{invalid_link}" do
filtered_link = filter("<a href='#{invalid_link}'>Link</a>", project_wiki: wiki).children[0]
+
expect(filtered_link.attribute('href').value).to eq(invalid_link)
end
end
diff --git a/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb b/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
index 98730602863..d21183b668b 100644
--- a/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
+++ b/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
@@ -15,6 +15,10 @@ describe Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits, :t
.to receive(:commits_count=).and_return(nil)
end
+ after do
+ [Project, MergeRequest, MergeRequestDiff].each(&:reset_column_information)
+ end
+
def diffs_to_hashes(diffs)
diffs.as_json(only: Gitlab::Git::Diff::SERIALIZE_KEYS).map(&:with_indifferent_access)
end
diff --git a/spec/lib/gitlab/git/rev_list_spec.rb b/spec/lib/gitlab/git/rev_list_spec.rb
index eaf74951b0e..90fbef9d248 100644
--- a/spec/lib/gitlab/git/rev_list_spec.rb
+++ b/spec/lib/gitlab/git/rev_list_spec.rb
@@ -39,7 +39,7 @@ describe Gitlab::Git::RevList do
]
expect(rev_list).to receive(:popen).with(*params) do |*_, lazy_block:|
- lazy_block.call(output.split("\n").lazy)
+ lazy_block.call(output.lines.lazy.map(&:chomp))
end
end
@@ -64,6 +64,15 @@ describe Gitlab::Git::RevList do
expect(rev_list.new_objects(require_path: true)).to eq(%w[sha2])
end
+ it 'can handle non utf-8 paths' do
+ non_utf_char = [0x89].pack("c*").force_encoding("UTF-8")
+ stub_lazy_popen_rev_list('newrev', '--not', '--all', '--objects', output: "sha2 πå†h/†ø/ƒîlé#{non_utf_char}\nsha1")
+
+ rev_list.new_objects(require_path: true) do |object_ids|
+ expect(object_ids.force).to eq(%w[sha2])
+ end
+ end
+
it 'can yield a lazy enumerator' do
stub_lazy_popen_rev_list('newrev', '--not', '--all', '--objects', output: "sha1\nsha2")
diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb
index 17937726f2c..1ebb0105cf5 100644
--- a/spec/lib/gitlab/project_search_results_spec.rb
+++ b/spec/lib/gitlab/project_search_results_spec.rb
@@ -70,15 +70,6 @@ describe Gitlab::ProjectSearchResults do
subject { described_class.parse_search_result(search_result) }
- it 'can correctly parse filenames including ":"' do
- special_char_result = "\nmaster:testdata/project::function1.yaml-1----\nmaster:testdata/project::function1.yaml:2:test: data1\n"
-
- blob = described_class.parse_search_result(special_char_result)
-
- expect(blob.ref).to eq('master')
- expect(blob.filename).to eq('testdata/project::function1.yaml')
- end
-
it "returns a valid FoundBlob" do
is_expected.to be_an Gitlab::SearchResults::FoundBlob
expect(subject.id).to be_nil
@@ -90,8 +81,32 @@ describe Gitlab::ProjectSearchResults do
expect(subject.data.lines[2]).to eq(" - Feature: Replace teams with group membership\n")
end
+ context 'when the matching filename contains a colon' do
+ let(:search_result) { "\nmaster:testdata/project::function1.yaml\x001\x00---\n" }
+
+ it 'returns a valid FoundBlob' do
+ expect(subject.filename).to eq('testdata/project::function1.yaml')
+ expect(subject.basename).to eq('testdata/project::function1')
+ expect(subject.ref).to eq('master')
+ expect(subject.startline).to eq(1)
+ expect(subject.data).to eq('---')
+ end
+ end
+
+ context 'when the matching content contains a number surrounded by colons' do
+ let(:search_result) { "\nmaster:testdata/foo.txt\x001\x00blah:9:blah" }
+
+ it 'returns a valid FoundBlob' do
+ expect(subject.filename).to eq('testdata/foo.txt')
+ expect(subject.basename).to eq('testdata/foo')
+ expect(subject.ref).to eq('master')
+ expect(subject.startline).to eq(1)
+ expect(subject.data).to eq('blah:9:blah')
+ end
+ end
+
context "when filename has extension" do
- let(:search_result) { "master:CONTRIBUTE.md:5:- [Contribute to GitLab](#contribute-to-gitlab)\n" }
+ let(:search_result) { "master:CONTRIBUTE.md\x005\x00- [Contribute to GitLab](#contribute-to-gitlab)\n" }
it { expect(subject.path).to eq('CONTRIBUTE.md') }
it { expect(subject.filename).to eq('CONTRIBUTE.md') }
@@ -99,7 +114,7 @@ describe Gitlab::ProjectSearchResults do
end
context "when file under directory" do
- let(:search_result) { "master:a/b/c.md:5:a b c\n" }
+ let(:search_result) { "master:a/b/c.md\x005\x00a b c\n" }
it { expect(subject.path).to eq('a/b/c.md') }
it { expect(subject.filename).to eq('a/b/c.md') }
@@ -144,7 +159,7 @@ describe Gitlab::ProjectSearchResults do
end
it 'finds by content' do
- expect(results).to include("master:Title.md:1:Content\n")
+ expect(results).to include("master:Title.md\x001\x00Content\n")
end
end
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index d3826417762..f8a98b43e46 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -439,15 +439,25 @@ eos
end
describe '#uri_type' do
- it 'returns the URI type at the given path' do
- expect(commit.uri_type('files/html')).to be(:tree)
- expect(commit.uri_type('files/images/logo-black.png')).to be(:raw)
- expect(project.commit('video').uri_type('files/videos/intro.mp4')).to be(:raw)
- expect(commit.uri_type('files/js/application.js')).to be(:blob)
+ shared_examples 'URI type' do
+ it 'returns the URI type at the given path' do
+ expect(commit.uri_type('files/html')).to be(:tree)
+ expect(commit.uri_type('files/images/logo-black.png')).to be(:raw)
+ expect(project.commit('video').uri_type('files/videos/intro.mp4')).to be(:raw)
+ expect(commit.uri_type('files/js/application.js')).to be(:blob)
+ end
+
+ it "returns nil if the path doesn't exists" do
+ expect(commit.uri_type('this/path/doesnt/exist')).to be_nil
+ end
+ end
+
+ context 'when Gitaly commit_tree_entry feature is enabled' do
+ it_behaves_like 'URI type'
end
- it "returns nil if the path doesn't exists" do
- expect(commit.uri_type('this/path/doesnt/exist')).to be_nil
+ context 'when Gitaly commit_tree_entry feature is disabled', :disable_gitaly do
+ it_behaves_like 'URI type'
end
end
diff --git a/spec/models/push_event_spec.rb b/spec/models/push_event_spec.rb
index ad3c3a406d9..bfe7a30b96a 100644
--- a/spec/models/push_event_spec.rb
+++ b/spec/models/push_event_spec.rb
@@ -63,12 +63,14 @@ describe PushEvent do
let(:event2) { create(:push_event, project: project) }
let(:event3) { create(:push_event, project: project) }
let(:event4) { create(:push_event, project: project) }
+ let(:event5) { create(:push_event, project: project) }
before do
create(:push_event_payload, event: event1, ref: 'foo', action: :created)
create(:push_event_payload, event: event2, ref: 'bar', action: :created)
- create(:push_event_payload, event: event3, ref: 'baz', action: :removed)
- create(:push_event_payload, event: event4, ref: 'baz', ref_type: :tag)
+ create(:push_event_payload, event: event3, ref: 'qux', action: :created)
+ create(:push_event_payload, event: event4, ref: 'baz', action: :removed)
+ create(:push_event_payload, event: event5, ref: 'baz', ref_type: :tag)
project.repository.create_branch('bar', 'master')
@@ -78,6 +80,16 @@ describe PushEvent do
target_project: project,
source_branch: 'bar'
)
+
+ project.repository.create_branch('qux', 'master')
+
+ create(
+ :merge_request,
+ :closed,
+ source_project: project,
+ target_project: project,
+ source_branch: 'qux'
+ )
end
let(:relation) { described_class.without_existing_merge_requests }
@@ -86,16 +98,20 @@ describe PushEvent do
expect(relation).to include(event1)
end
- it 'does not include events that have a corresponding merge request' do
+ it 'does not include events that have a corresponding open merge request' do
expect(relation).not_to include(event2)
end
+ it 'includes events that has corresponding closed/merged merge requests' do
+ expect(relation).to include(event3)
+ end
+
it 'does not include events for removed refs' do
- expect(relation).not_to include(event3)
+ expect(relation).not_to include(event4)
end
it 'does not include events for pushing to tags' do
- expect(relation).not_to include(event4)
+ expect(relation).not_to include(event5)
end
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index f3456e5b354..baaa9e3ef44 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -657,7 +657,7 @@ describe Repository do
subject { results.first }
it { is_expected.to be_an String }
- it { expect(subject.lines[2]).to eq("master:CHANGELOG:190: - Feature: Replace teams with group membership\n") }
+ it { expect(subject.lines[2]).to eq("master:CHANGELOG\x00190\x00 - Feature: Replace teams with group membership\n") }
end
end
@@ -668,6 +668,18 @@ describe Repository do
expect(results.first).to eq('files/html/500.html')
end
+ it 'ignores leading slashes' do
+ results = repository.search_files_by_name('/files', 'master')
+
+ expect(results.first).to eq('files/html/500.html')
+ end
+
+ it 'properly handles when query is only slashes' do
+ results = repository.search_files_by_name('//', 'master')
+
+ expect(results).to match_array([])
+ end
+
it 'properly handles when query is not present' do
results = repository.search_files_by_name('', 'master')
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index 805496e4a54..e211c347266 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -25,8 +25,10 @@ describe API::Jobs do
describe 'GET /projects/:id/jobs' do
let(:query) { Hash.new }
- before do
- get api("/projects/#{project.id}/jobs", api_user), query
+ before do |example|
+ unless example.metadata[:skip_before_request]
+ get api("/projects/#{project.id}/jobs", api_user), query
+ end
end
context 'authorized user' do
@@ -51,6 +53,23 @@ describe API::Jobs do
expect(json_job['pipeline']['status']).to eq job.pipeline.status
end
+ it 'avoids N+1 queries', skip_before_request: true do
+ first_build = create(:ci_build, :artifacts, pipeline: pipeline)
+ first_build.runner = create(:ci_runner)
+ first_build.user = create(:user)
+ first_build.save
+
+ control_count = ActiveRecord::QueryRecorder.new { go }.count
+
+ second_pipeline = create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: project.default_branch)
+ second_build = create(:ci_build, :artifacts, pipeline: second_pipeline)
+ second_build.runner = create(:ci_runner)
+ second_build.user = create(:user)
+ second_build.save
+
+ expect { go }.not_to exceed_query_limit(control_count)
+ end
+
context 'filter project with one scope element' do
let(:query) { { 'scope' => 'pending' } }
@@ -83,6 +102,10 @@ describe API::Jobs do
expect(response).to have_gitlab_http_status(401)
end
end
+
+ def go
+ get api("/projects/#{project.id}/jobs", api_user), query
+ end
end
describe 'GET /projects/:id/pipelines/:pipeline_id/jobs' do
diff --git a/spec/requests/api/project_milestones_spec.rb b/spec/requests/api/project_milestones_spec.rb
index 08ea7314bb3..6c05c166bd6 100644
--- a/spec/requests/api/project_milestones_spec.rb
+++ b/spec/requests/api/project_milestones_spec.rb
@@ -14,6 +14,46 @@ describe API::ProjectMilestones do
let(:route) { "/projects/#{project.id}/milestones" }
end
+ describe 'DELETE /projects/:id/milestones/:milestone_id' do
+ let(:guest) { create(:user) }
+ let(:reporter) { create(:user) }
+
+ before do
+ project.add_reporter(reporter)
+ end
+
+ it 'returns 404 response when the project does not exists' do
+ delete api("/projects/999/milestones/#{milestone.id}", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ it 'returns 404 response when the milestone does not exists' do
+ delete api("/projects/#{project.id}/milestones/999", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ it "returns 404 from guest user deleting a milestone" do
+ delete api("/projects/#{project.id}/milestones/#{milestone.id}", guest)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ it "rejects a member with reporter access from deleting a milestone" do
+ delete api("/projects/#{project.id}/milestones/#{milestone.id}", reporter)
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+
+ it 'deletes the milestone when the user has developer access to the project' do
+ delete api("/projects/#{project.id}/milestones/#{milestone.id}", user)
+
+ expect(project.milestones.find_by_id(milestone.id)).to be_nil
+ expect(response).to have_gitlab_http_status(204)
+ end
+ end
+
describe 'PUT /projects/:id/milestones/:milestone_id to test observer on close' do
it 'creates an activity event when an milestone is closed' do
expect(Event).to receive(:create!)
diff --git a/spec/requests/api/v3/builds_spec.rb b/spec/requests/api/v3/builds_spec.rb
index a73bb456b52..cdbc5692e19 100644
--- a/spec/requests/api/v3/builds_spec.rb
+++ b/spec/requests/api/v3/builds_spec.rb
@@ -13,10 +13,12 @@ describe API::V3::Builds do
describe 'GET /projects/:id/builds ' do
let(:query) { '' }
- before do
+ before do |example|
create(:ci_build, :skipped, pipeline: pipeline)
- get v3_api("/projects/#{project.id}/builds?#{query}", api_user)
+ unless example.metadata[:skip_before_request]
+ get v3_api("/projects/#{project.id}/builds?#{query}", api_user)
+ end
end
context 'authorized user' do
@@ -40,6 +42,23 @@ describe API::V3::Builds do
expect(json_build['pipeline']['status']).to eq build.pipeline.status
end
+ it 'avoids N+1 queries', skip_before_request: true do
+ first_build = create(:ci_build, :artifacts, pipeline: pipeline)
+ first_build.runner = create(:ci_runner)
+ first_build.user = create(:user)
+ first_build.save
+
+ control_count = ActiveRecord::QueryRecorder.new { go }.count
+
+ second_pipeline = create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: project.default_branch)
+ second_build = create(:ci_build, :artifacts, pipeline: second_pipeline)
+ second_build.runner = create(:ci_runner)
+ second_build.user = create(:user)
+ second_build.save
+
+ expect { go }.not_to exceed_query_limit(control_count)
+ end
+
context 'filter project with one scope element' do
let(:query) { 'scope=pending' }
@@ -84,6 +103,10 @@ describe API::V3::Builds do
expect(response).to have_gitlab_http_status(401)
end
end
+
+ def go
+ get v3_api("/projects/#{project.id}/builds?#{query}", api_user)
+ end
end
describe 'GET /projects/:id/repository/commits/:sha/builds' do
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index 965fd39c967..ab3a257f36f 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -158,7 +158,7 @@ describe SystemNoteService do
end
it 'builds a correct phrase when assignee removed' do
- expect(build_note([assignee1], [])).to eq 'removed assignee'
+ expect(build_note([assignee1], [])).to eq "unassigned @#{assignee1.username}"
end
it 'builds a correct phrase when assignees changed' do
diff --git a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
index 75de266369d..eec356b9f47 100644
--- a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
+++ b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
@@ -90,10 +90,14 @@ codequality:
performance:
stage: performance
- image:
- name: sitespeedio/sitespeed.io:6.0.3
- entrypoint: [""]
+ image: docker:latest
+ variables:
+ DOCKER_DRIVER: overlay2
+ allow_failure: true
+ services:
+ - docker:dind
script:
+ - setup_docker
- performance
artifacts:
paths:
@@ -112,7 +116,7 @@ sast:
- sast .
artifacts:
paths: [gl-sast-report.json]
-
+
sast:container:
image: docker:latest
variables:
@@ -260,7 +264,7 @@ production:
export CI_APPLICATION_TAG=$CI_COMMIT_SHA
export CI_CONTAINER_NAME=ci_job_build_${CI_JOB_ID}
export TILLER_NAMESPACE=$KUBE_NAMESPACE
-
+
function sast_container() {
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
@@ -466,26 +470,26 @@ production:
--docker-email="$GITLAB_USER_EMAIL" \
-o yaml --dry-run | kubectl replace -n "$KUBE_NAMESPACE" --force -f -
}
-
+
function performance() {
export CI_ENVIRONMENT_URL=$(cat environment_url.txt)
-
+
mkdir gitlab-exporter
wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/10-3/index.js
-
+
mkdir sitespeed-results
-
+
if [ -f .gitlab-urls.txt ]
then
sed -i -e 's@^@'"$CI_ENVIRONMENT_URL"'@' .gitlab-urls.txt
- /start.sh --plugins.add gitlab-exporter --outputFolder sitespeed-results .gitlab-urls.txt
+ docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.0.3 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results .gitlab-urls.txt
else
- /start.sh --plugins.add gitlab-exporter --outputFolder sitespeed-results $CI_ENVIRONMENT_URL
+ docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.0.3 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL"
fi
-
+
mv sitespeed-results/data/performance.json performance.json
}
-
+
function persist_environment_url() {
echo $CI_ENVIRONMENT_URL > environment_url.txt
}
diff --git a/vendor/prometheus/values.yaml b/vendor/prometheus/values.yaml
index fdc687b8980..5249449c7f8 100644
--- a/vendor/prometheus/values.yaml
+++ b/vendor/prometheus/values.yaml
@@ -18,138 +18,100 @@ serverFiles:
rule_files:
- /etc/config/rules
- /etc/config/alerts
-
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- localhost:9090
-
- - job_name: 'kubernetes-apiservers'
-
- kubernetes_sd_configs:
- - role: endpoints
-
+ - job_name: kubernetes-cadvisor
scheme: https
-
tls_config:
- ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
+ ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
insecure_skip_verify: true
- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
+ bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token"
+ kubernetes_sd_configs:
+ - role: node
+ api_server: https://kubernetes.default.svc:443
+ tls_config:
+ ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
+ bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token"
relabel_configs:
- - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
- action: keep
- regex: default;kubernetes;https
-
- - job_name: 'kubernetes-nodes'
+ - action: labelmap
+ regex: __meta_kubernetes_node_label_(.+)
+ - target_label: __address__
+ replacement: kubernetes.default.svc:443
+ - source_labels:
+ - __meta_kubernetes_node_name
+ regex: "(.+)"
+ target_label: __metrics_path__
+ replacement: "/api/v1/nodes/${1}/proxy/metrics/cadvisor"
+ metric_relabel_configs:
+ - source_labels:
+ - pod_name
+ target_label: environment
+ regex: "(.+)-.+-.+"
+ - job_name: kubernetes-nodes
scheme: https
tls_config:
- ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
+ ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
insecure_skip_verify: true
- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
-
+ bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token"
kubernetes_sd_configs:
- - role: node
-
+ - role: node
+ api_server: https://kubernetes.default.svc:443
+ tls_config:
+ ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
+ bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token"
relabel_configs:
- - action: labelmap
- regex: __meta_kubernetes_node_label_(.+)
- - target_label: __address__
- replacement: kubernetes.default.svc:443
- - source_labels: [__meta_kubernetes_node_name]
- regex: (.+)
- target_label: __metrics_path__
- replacement: /api/v1/nodes/${1}/proxy/metrics
- - job_name: 'kubernetes-service-endpoints'
-
- kubernetes_sd_configs:
- - role: endpoints
-
- relabel_configs:
- - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
- action: keep
- regex: true
- - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
- action: replace
- target_label: __scheme__
- regex: (https?)
- - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
- action: replace
- target_label: __metrics_path__
- regex: (.+)
- - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
- action: replace
- target_label: __address__
- regex: (.+)(?::\d+);(\d+)
- replacement: $1:$2
- - action: labelmap
- regex: __meta_kubernetes_service_label_(.+)
- - source_labels: [__meta_kubernetes_namespace]
- action: replace
- target_label: kubernetes_namespace
- - source_labels: [__meta_kubernetes_service_name]
- action: replace
- target_label: kubernetes_name
-
- - job_name: 'prometheus-pushgateway'
- honor_labels: true
-
- kubernetes_sd_configs:
- - role: service
-
- relabel_configs:
- - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
- action: keep
- regex: pushgateway
- - job_name: 'kubernetes-services'
-
- metrics_path: /probe
- params:
- module: [http_2xx]
-
- kubernetes_sd_configs:
- - role: service
-
- relabel_configs:
- - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
- action: keep
- regex: true
- - source_labels: [__address__]
- target_label: __param_target
- - target_label: __address__
- replacement: blackbox
- - source_labels: [__param_target]
- target_label: instance
- - action: labelmap
- regex: __meta_kubernetes_service_label_(.+)
- - source_labels: [__meta_kubernetes_namespace]
- target_label: kubernetes_namespace
- - source_labels: [__meta_kubernetes_service_name]
- target_label: kubernetes_name
-
- - job_name: 'kubernetes-pods'
-
+ - action: labelmap
+ regex: __meta_kubernetes_node_label_(.+)
+ - target_label: __address__
+ replacement: kubernetes.default.svc:443
+ - source_labels:
+ - __meta_kubernetes_node_name
+ regex: "(.+)"
+ target_label: __metrics_path__
+ replacement: "/api/v1/nodes/${1}/proxy/metrics"
+ metric_relabel_configs:
+ - source_labels:
+ - pod_name
+ target_label: environment
+ regex: "(.+)-.+-.+"
+ - job_name: kubernetes-pods
+ tls_config:
+ ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
+ insecure_skip_verify: true
+ bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token"
kubernetes_sd_configs:
- - role: pod
-
+ - role: pod
+ api_server: https://kubernetes.default.svc:443
+ tls_config:
+ ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
+ bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token"
relabel_configs:
- - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
- action: keep
- regex: true
- - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
- action: replace
- target_label: __metrics_path__
- regex: (.+)
- - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
- action: replace
- regex: (.+):(?:\d+);(\d+)
- replacement: ${1}:${2}
- target_label: __address__
- - action: labelmap
- regex: __meta_kubernetes_pod_label_(.+)
- - source_labels: [__meta_kubernetes_namespace]
- action: replace
- target_label: kubernetes_namespace
- - source_labels: [__meta_kubernetes_pod_name]
- action: replace
- target_label: kubernetes_pod_name
+ - source_labels:
+ - __meta_kubernetes_pod_annotation_prometheus_io_scrape
+ action: keep
+ regex: 'true'
+ - source_labels:
+ - __meta_kubernetes_pod_annotation_prometheus_io_path
+ action: replace
+ target_label: __metrics_path__
+ regex: "(.+)"
+ - source_labels:
+ - __address__
+ - __meta_kubernetes_pod_annotation_prometheus_io_port
+ action: replace
+ regex: "([^:]+)(?::[0-9]+)?;([0-9]+)"
+ replacement: "$1:$2"
+ target_label: __address__
+ - action: labelmap
+ regex: __meta_kubernetes_pod_label_(.+)
+ - source_labels:
+ - __meta_kubernetes_namespace
+ action: replace
+ target_label: kubernetes_namespace
+ - source_labels:
+ - __meta_kubernetes_pod_name
+ action: replace
+ target_label: kubernetes_pod_name