summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md4
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--GITLAB_WORKHORSE_VERSION2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock6
-rw-r--r--Gemfile.rails5.lock6
-rw-r--r--app/assets/javascripts/boards/components/modal/lists_dropdown.vue2
-rw-r--r--app/assets/javascripts/commons/gitlab_ui.js25
-rw-r--r--app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js7
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js5
-rw-r--r--app/assets/javascripts/ide/components/ide.vue12
-rw-r--r--app/assets/javascripts/ide/components/ide_side_bar.vue2
-rw-r--r--app/assets/javascripts/ide/components/ide_tree_list.vue2
-rw-r--r--app/assets/javascripts/ide/components/panes/right.vue92
-rw-r--r--app/assets/javascripts/ide/index.js8
-rw-r--r--app/assets/javascripts/job.js4
-rw-r--r--app/assets/javascripts/jobs/components/empty_state.vue4
-rw-r--r--app/assets/javascripts/jobs/components/erased_block.vue49
-rw-r--r--app/assets/javascripts/jobs/components/job_log.vue4
-rw-r--r--app/assets/javascripts/jobs/components/job_log_controllers.vue76
-rw-r--r--app/assets/javascripts/jobs/components/stuck_block.vue6
-rw-r--r--app/assets/javascripts/jobs/job_details_bundle.js45
-rw-r--r--app/assets/javascripts/jobs/job_details_mediator.js65
-rw-r--r--app/assets/javascripts/jobs/services/job_service.js11
-rw-r--r--app/assets/javascripts/jobs/store/mutations.js3
-rw-r--r--app/assets/javascripts/jobs/stores/job_store.js11
-rw-r--r--app/assets/javascripts/lib/utils/logoutput_behaviours.js17
-rw-r--r--app/assets/javascripts/lib/utils/scroll_utils.js24
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue35
-rw-r--r--app/assets/javascripts/monitoring/components/graph.vue13
-rw-r--r--app/assets/javascripts/notes.js2
-rw-r--r--app/assets/javascripts/notes/components/diff_with_note.vue2
-rw-r--r--app/assets/javascripts/performance_bar/components/performance_bar_app.vue2
-rw-r--r--app/assets/javascripts/performance_bar/components/simple_metric.vue37
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.js15
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue (renamed from app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue)0
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/dependencies.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/toolbar.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue2
-rw-r--r--app/assets/stylesheets/framework/typography.scss2
-rw-r--r--app/controllers/application_controller.rb7
-rw-r--r--app/controllers/dashboard_controller.rb2
-rw-r--r--app/finders/admin/runners_finder.rb18
-rw-r--r--app/models/ci/runner.rb27
-rw-r--r--app/models/clusters/applications/jupyter.rb5
-rw-r--r--app/serializers/build_details_entity.rb1
-rw-r--r--app/services/files/multi_service.rb2
-rw-r--r--app/services/quick_actions/interpret_service.rb31
-rw-r--r--app/views/admin/runners/index.html.haml9
-rw-r--r--app/views/groups/show.html.haml10
-rw-r--r--app/views/import/gitlab_projects/new.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml2
-rw-r--r--app/views/projects/_new_project_fields.html.haml2
-rw-r--r--app/views/shared/_event_filter.html.haml12
-rw-r--r--changelogs/unreleased/1801-allow-event_filter-to-be-set-in-the-url.yml5
-rw-r--r--changelogs/unreleased/43832-adds-chdmod-to-commits-actions-api.yml5
-rw-r--r--changelogs/unreleased/4907-improve-build-create-performance-for-license-management.yml5
-rw-r--r--changelogs/unreleased/50289-vendor-ci-yml-for-the-last-time.yml5
-rw-r--r--changelogs/unreleased/50904-update-scroll-utils.yml5
-rw-r--r--changelogs/unreleased/50904-use-vuex-store-job.yml5
-rw-r--r--changelogs/unreleased/51522-add-new-project-via-import-by-url-auto-populates-slug-but-not-project-name.yml5
-rw-r--r--changelogs/unreleased/51569-performance-bar.yml5
-rw-r--r--changelogs/unreleased/51925-expose-has_trace-in-job-api.yml5
-rw-r--r--changelogs/unreleased/dm-fix-assign-unassign-quick-actions.yml6
-rw-r--r--changelogs/unreleased/feature-add-public-email-to-users-api.yml5
-rw-r--r--changelogs/unreleased/feature-runner-type-filter-for-admin-view.yml5
-rw-r--r--changelogs/unreleased/jivl-fix-monitoring-dashboard-resizing-navbar.yml5
-rw-r--r--changelogs/unreleased/rename-squash-before-merge-vue-component.yml5
-rw-r--r--changelogs/unreleased/sh-guard-against-ldap-login-csrf-fail.yml5
-rw-r--r--changelogs/unreleased/toon-copy-meta-data-fix.yml5
-rw-r--r--changelogs/unreleased/winh-page-title-margin.yml5
-rw-r--r--config/initializers/warden.rb5
-rw-r--r--doc/administration/gitaly/index.md2
-rw-r--r--doc/administration/logs.md6
-rw-r--r--doc/administration/raketasks/maintenance.md6
-rw-r--r--doc/api/commits.md12
-rw-r--r--doc/api/deployments.md45
-rw-r--r--doc/api/jobs.md95
-rw-r--r--doc/api/keys.md8
-rw-r--r--doc/api/merge_requests.md5
-rw-r--r--doc/api/oauth2.md8
-rw-r--r--doc/api/runners.md23
-rw-r--r--doc/api/users.md4
-rw-r--r--doc/ci/README.md2
-rw-r--r--doc/ci/caching/index.md12
-rw-r--r--doc/ci/docker/using_docker_build.md4
-rw-r--r--doc/ci/examples/README.md6
-rw-r--r--doc/ci/examples/browser_performance.md2
-rw-r--r--doc/ci/examples/test-scala-application.md2
-rw-r--r--doc/ci/yaml/README.md3
-rw-r--r--doc/development/contributing/community_roles.md12
-rw-r--r--doc/development/contributing/design.md53
-rw-r--r--doc/development/contributing/index.md39
-rw-r--r--doc/development/contributing/issue_workflow.md54
-rw-r--r--doc/development/contributing/merge_request_workflow.md17
-rw-r--r--doc/development/documentation/index.md107
-rw-r--r--doc/development/documentation/styleguide.md2
-rw-r--r--doc/development/gitaly.md2
-rw-r--r--doc/development/testing_guide/review_apps.md2
-rw-r--r--doc/development/ux_guide/users.md4
-rw-r--r--doc/gitlab-basics/add-image.md2
-rw-r--r--doc/install/kubernetes/gitlab_chart.md2
-rw-r--r--doc/integration/github.md4
-rw-r--r--doc/raketasks/backup_restore.md3
-rw-r--r--doc/security/user_email_confirmation.md2
-rw-r--r--doc/topics/autodevops/index.md4
-rw-r--r--doc/university/README.md2
-rw-r--r--doc/user/gitlab_com/index.md2
-rw-r--r--doc/user/index.md2
-rw-r--r--doc/user/project/container_registry.md6
-rw-r--r--doc/user/project/integrations/webhooks.md2
-rw-r--r--doc/user/project/pipelines/job_artifacts.md14
-rw-r--r--lib/api/commits.rb21
-rw-r--r--lib/api/entities.rb2
-rw-r--r--lib/api/runners.rb31
-rw-r--r--lib/event_filter.rb86
-rw-r--r--lib/gitlab/ci/templates/Android.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Android.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml)18
-rw-r--r--lib/gitlab/ci/templates/Bash.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Bash.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/C++.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/C++.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Chef.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Chef.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Clojure.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Clojure.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Crystal.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Crystal.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Django.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Django.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Docker.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Docker.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Elixir.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Go.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Go.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Gradle.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Gradle.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Grails.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Grails.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Julia.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Julia.gitlab-ci.yml)54
-rw-r--r--lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/LaTeX.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Laravel.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Laravel.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Maven.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Maven.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Mono.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Mono.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/OpenShift.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/PHP.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/PHP.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Packer.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Packer.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Brunch.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Brunch.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Doxygen.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Doxygen.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Gatsby.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/HTML.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Harp.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Harp.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Hexo.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Hexo.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Hugo.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Hyde.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Hyde.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/JBake.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/JBake.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Jekyll.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Jigsaw.gitlab-ci.yml42
-rw-r--r--lib/gitlab/ci/templates/Pages/Lektor.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Lektor.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Metalsmith.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Metalsmith.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Middleman.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Middleman.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Nanoc.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Nanoc.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Octopress.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Octopress.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Pages/Pelican.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Pages/Pelican.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Python.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Python.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Ruby.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Rust.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Rust.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Scala.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Scala.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/Swift.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Swift.gitlab-ci.yml)2
-rw-r--r--lib/gitlab/ci/templates/Terraform.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/Terraform.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/ci/templates/dotNET.gitlab-ci.yml (renamed from vendor/gitlab-ci-yml/dotNET.gitlab-ci.yml)0
-rw-r--r--lib/gitlab/gitaly_client/operation_service.rb3
-rw-r--r--lib/gitlab/template/gitlab_ci_yml_template.rb2
-rw-r--r--lib/tasks/gitlab/artifacts/migrate.rake2
-rw-r--r--lib/tasks/gitlab/update_templates.rake4
-rw-r--r--locale/gitlab.pot3
-rw-r--r--package.json8
-rw-r--r--qa/qa/page/group/show.rb35
-rw-r--r--qa/qa/page/main/login.rb1
-rw-r--r--qa/qa/page/merge_request/show.rb2
-rw-r--r--qa/qa/page/project/activity.rb2
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb16
-rw-r--r--spec/factories/events.rb2
-rw-r--r--spec/features/admin/admin_runners_spec.rb74
-rw-r--r--spec/features/projects/activity/user_sees_activity_spec.rb12
-rw-r--r--spec/finders/admin/runners_finder_spec.rb8
-rw-r--r--spec/fixtures/api/schemas/job/job_details.json6
-rw-r--r--spec/javascripts/jobs/components/empty_state_spec.js2
-rw-r--r--spec/javascripts/jobs/components/erased_block_spec.js8
-rw-r--r--spec/javascripts/jobs/components/job_details_mediator_spec.js39
-rw-r--r--spec/javascripts/jobs/components/job_log_controllers_spec.js167
-rw-r--r--spec/javascripts/jobs/components/job_log_spec.js6
-rw-r--r--spec/javascripts/jobs/components/job_store_spec.js26
-rw-r--r--spec/javascripts/jobs/store/mutations_spec.js7
-rw-r--r--spec/javascripts/monitoring/dashboard_spec.js42
-rw-r--r--spec/javascripts/monitoring/graph_spec.js18
-rw-r--r--spec/lib/event_filter_spec.rb131
-rw-r--r--spec/lib/gitlab/ci/external/file/local_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/external/mapper_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/external/processor_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/templates/templates_spec.rb11
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb12
-rw-r--r--spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb2
-rw-r--r--spec/models/clusters/applications/jupyter_spec.rb7
-rw-r--r--spec/models/event_collection_spec.rb2
-rw-r--r--spec/requests/api/commits_spec.rb80
-rw-r--r--spec/requests/api/runners_spec.rb221
-rw-r--r--spec/services/files/multi_service_spec.rb36
-rw-r--r--spec/services/quick_actions/interpret_service_spec.rb9
-rw-r--r--vendor/gitlab-ci-yml/.gitlab-ci.yml4
-rw-r--r--vendor/gitlab-ci-yml/CONTRIBUTING.md46
-rw-r--r--vendor/gitlab-ci-yml/LICENSE25
-rw-r--r--yarn.lock40
206 files changed, 1661 insertions, 1155 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8596037afa3..81fc46c2b6f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -72,11 +72,13 @@ For a first-time step-by-step guide to the contribution process, please see
Looking for something to work on? Look for issues in the [Backlog (Accepting merge requests) milestone](#i-want-to-contribute).
-GitLab comes into two flavors, GitLab Community Edition (CE) our free and open
+GitLab comes in two flavors, GitLab Community Edition (CE) our free and open
source edition, and GitLab Enterprise Edition (EE) which is our commercial
edition. Throughout this guide you will see references to CE and EE for
abbreviation.
+To get an overview of GitLab community membership including those that would be reviewing or merging your contributions, please visit [the community roles page](doc/development/contributing/community_roles.md).
+
If you want to know how the GitLab [core team]
operates please see [the GitLab contributing process](PROCESS.md).
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 61825a7bf03..ee1e4d2aee5 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-0.121.0
+0.122.0
diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION
index dfda3e0b4f0..f3b5af39e43 100644
--- a/GITLAB_WORKHORSE_VERSION
+++ b/GITLAB_WORKHORSE_VERSION
@@ -1 +1 @@
-6.1.0
+6.1.1
diff --git a/Gemfile b/Gemfile
index 1b35e2110d5..35e83a530f0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -89,7 +89,7 @@ gem 'gitlab-gollum-rugged_adapter', '~> 0.4.4', require: false
gem 'github-linguist', '~> 5.3.3', require: 'linguist'
# API
-gem 'grape', '~> 1.0'
+gem 'grape', '~> 1.1'
gem 'grape-entity', '~> 0.7.1'
gem 'rack-cors', '~> 1.0.0', require: 'rack/cors'
diff --git a/Gemfile.lock b/Gemfile.lock
index 4de78f3ec44..d8eaaac99b1 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -343,7 +343,7 @@ GEM
signet (~> 0.7)
gpgme (2.0.13)
mini_portile2 (~> 2.1)
- grape (1.0.3)
+ grape (1.1.0)
activesupport
builder
mustermann-grape (~> 1.0.0)
@@ -501,7 +501,7 @@ GEM
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
- mustermann (1.0.2)
+ mustermann (1.0.3)
mustermann-grape (1.0.0)
mustermann (~> 1.0.0)
mysql2 (0.4.10)
@@ -1043,7 +1043,7 @@ DEPENDENCIES
google-api-client (~> 0.23)
google-protobuf (= 3.5.1)
gpgme
- grape (~> 1.0)
+ grape (~> 1.1)
grape-entity (~> 0.7.1)
grape-path-helpers (~> 1.0)
grape_logging (~> 1.7)
diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock
index 8f4e1550a52..ab35a4a399f 100644
--- a/Gemfile.rails5.lock
+++ b/Gemfile.rails5.lock
@@ -346,7 +346,7 @@ GEM
signet (~> 0.7)
gpgme (2.0.13)
mini_portile2 (~> 2.1)
- grape (1.0.3)
+ grape (1.1.0)
activesupport
builder
mustermann-grape (~> 1.0.0)
@@ -504,7 +504,7 @@ GEM
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
- mustermann (1.0.2)
+ mustermann (1.0.3)
mustermann-grape (1.0.0)
mustermann (~> 1.0.0)
mysql2 (0.4.10)
@@ -1052,7 +1052,7 @@ DEPENDENCIES
google-api-client (~> 0.23)
google-protobuf (= 3.5.1)
gpgme
- grape (~> 1.0)
+ grape (~> 1.1)
grape-entity (~> 0.7.1)
grape-path-helpers (~> 1.0)
grape_logging (~> 1.7)
diff --git a/app/assets/javascripts/boards/components/modal/lists_dropdown.vue b/app/assets/javascripts/boards/components/modal/lists_dropdown.vue
index 24f26169799..4f23e5db35c 100644
--- a/app/assets/javascripts/boards/components/modal/lists_dropdown.vue
+++ b/app/assets/javascripts/boards/components/modal/lists_dropdown.vue
@@ -1,5 +1,5 @@
<script>
-import Link from '@gitlab-org/gitlab-ui/dist/components/base/link';
+import { Link } from '@gitlab-org/gitlab-ui';
import ModalStore from '../../stores/modal_store';
export default {
diff --git a/app/assets/javascripts/commons/gitlab_ui.js b/app/assets/javascripts/commons/gitlab_ui.js
index aed26adfa5c..1411f7ffd5e 100644
--- a/app/assets/javascripts/commons/gitlab_ui.js
+++ b/app/assets/javascripts/commons/gitlab_ui.js
@@ -1,16 +1,17 @@
import Vue from 'vue';
-import Pagination from '@gitlab-org/gitlab-ui/dist/components/base/pagination';
-import progressBar from '@gitlab-org/gitlab-ui/dist/components/base/progress_bar';
-import modal from '@gitlab-org/gitlab-ui/dist/components/base/modal';
-import loadingIcon from '@gitlab-org/gitlab-ui/dist/components/base/loading_icon';
-
-import dModal from '@gitlab-org/gitlab-ui/dist/directives/modal';
-import dTooltip from '@gitlab-org/gitlab-ui/dist/directives/tooltip';
+import {
+ Pagination,
+ ProgressBar,
+ Modal,
+ LoadingIcon,
+ ModalDirective,
+ TooltipDirective,
+} from '@gitlab-org/gitlab-ui';
Vue.component('gl-pagination', Pagination);
-Vue.component('gl-progress-bar', progressBar);
-Vue.component('gl-ui-modal', modal);
-Vue.component('gl-loading-icon', loadingIcon);
+Vue.component('gl-progress-bar', ProgressBar);
+Vue.component('gl-ui-modal', Modal);
+Vue.component('gl-loading-icon', LoadingIcon);
-Vue.directive('gl-modal', dModal);
-Vue.directive('gl-tooltip', dTooltip);
+Vue.directive('gl-modal', ModalDirective);
+Vue.directive('gl-tooltip', TooltipDirective);
diff --git a/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js b/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js
index b4588cc1318..d7aa4ce597f 100644
--- a/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js
+++ b/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js
@@ -7,6 +7,13 @@ const tokenKeys = [{
symbol: '',
icon: 'messages',
tag: 'status',
+}, {
+ key: 'type',
+ type: 'string',
+ param: 'type',
+ symbol: '',
+ icon: 'cube',
+ tag: 'type',
}];
const AdminRunnersFilteredSearchTokenKeys = new FilteredSearchTokenKeys(tokenKeys);
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
index a750647f8be..207616b9de2 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
@@ -96,6 +96,11 @@ export default class FilteredSearchDropdownManager {
gl: NullDropdown,
element: this.container.querySelector('#js-dropdown-admin-runner-status'),
},
+ type: {
+ reference: null,
+ gl: NullDropdown,
+ element: this.container.querySelector('#js-dropdown-admin-runner-type'),
+ },
};
supportedTokens.forEach((type) => {
diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue
index a3add3b778f..ad6151e3bf6 100644
--- a/app/assets/javascripts/ide/components/ide.vue
+++ b/app/assets/javascripts/ide/components/ide.vue
@@ -1,4 +1,5 @@
<script>
+import Vue from 'vue';
import Mousetrap from 'mousetrap';
import { mapActions, mapState, mapGetters } from 'vuex';
import { __ } from '~/locale';
@@ -22,10 +23,16 @@ export default {
IdeStatusBar,
RepoEditor,
FindFile,
- RightPane,
ErrorMessage,
CommitEditorHeader,
},
+ props: {
+ rightPaneComponent: {
+ type: Vue.Component,
+ required: false,
+ default: () => RightPane,
+ },
+ },
computed: {
...mapState([
'openFiles',
@@ -143,7 +150,8 @@ export default {
</div>
</template>
</div>
- <right-pane
+ <component
+ :is="rightPaneComponent"
v-if="currentProjectId"
/>
</div>
diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue
index 5620d6a6244..f99ff6d6da8 100644
--- a/app/assets/javascripts/ide/components/ide_side_bar.vue
+++ b/app/assets/javascripts/ide/components/ide_side_bar.vue
@@ -1,6 +1,6 @@
<script>
import { mapState, mapGetters } from 'vuex';
-import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
+import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
import IdeTree from './ide_tree.vue';
import ResizablePanel from './resizable_panel.vue';
import ActivityBar from './activity_bar.vue';
diff --git a/app/assets/javascripts/ide/components/ide_tree_list.vue b/app/assets/javascripts/ide/components/ide_tree_list.vue
index ff53314d275..cfe25084b42 100644
--- a/app/assets/javascripts/ide/components/ide_tree_list.vue
+++ b/app/assets/javascripts/ide/components/ide_tree_list.vue
@@ -1,7 +1,7 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
-import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
+import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
import FileRow from '~/vue_shared/components/file_row.vue';
import NavDropdown from './nav_dropdown.vue';
import FileRowExtra from './file_row_extra.vue';
diff --git a/app/assets/javascripts/ide/components/panes/right.vue b/app/assets/javascripts/ide/components/panes/right.vue
index 79df225c432..75a9a9e9b8f 100644
--- a/app/assets/javascripts/ide/components/panes/right.vue
+++ b/app/assets/javascripts/ide/components/panes/right.vue
@@ -1,5 +1,6 @@
<script>
import { mapActions, mapState, mapGetters } from 'vuex';
+import { __ } from '~/locale';
import tooltip from '../../../vue_shared/directives/tooltip';
import Icon from '../../../vue_shared/components/icon.vue';
import { rightSidebarViews } from '../../constants';
@@ -21,6 +22,13 @@ export default {
MergeRequestInfo,
Clientside,
},
+ props: {
+ extensionTabs: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ },
computed: {
...mapState(['rightPane', 'currentMergeRequestId', 'clientsidePreviewEnabled']),
...mapGetters(['packageJson']),
@@ -33,6 +41,36 @@ export default {
showLivePreview() {
return this.packageJson && this.clientsidePreviewEnabled;
},
+ defaultTabs() {
+ return [
+ {
+ show: this.currentMergeRequestId,
+ title: __('Merge Request'),
+ isActive: this.rightPane === rightSidebarViews.mergeRequestInfo,
+ view: rightSidebarViews.mergeRequestInfo,
+ icon: 'text-description',
+ },
+ {
+ show: true,
+ title: __('Pipelines'),
+ isActive: this.pipelinesActive,
+ view: rightSidebarViews.pipelines,
+ icon: 'rocket',
+ },
+ {
+ show: this.showLivePreview,
+ title: __('Live preview'),
+ isActive: this.rightPane === rightSidebarViews.clientSidePreview,
+ view: rightSidebarViews.clientSidePreview,
+ icon: 'live-preview',
+ },
+ ];
+ },
+ tabs() {
+ return this.defaultTabs
+ .concat(this.extensionTabs)
+ .filter(tab => tab.show);
+ },
},
methods: {
...mapActions(['setRightPane']),
@@ -42,7 +80,6 @@ export default {
this.setRightPane(view);
},
},
- rightSidebarViews,
};
</script>
@@ -64,64 +101,25 @@ export default {
<nav class="ide-activity-bar">
<ul class="list-unstyled">
<li
- v-if="currentMergeRequestId"
+ v-for="tab of tabs"
+ :key="tab.title"
>
<button
v-tooltip
- :title="__('Merge Request')"
- :aria-label="__('Merge Request')"
- :class="{
- active: rightPane === $options.rightSidebarViews.mergeRequestInfo
- }"
- data-container="body"
- data-placement="left"
- class="ide-sidebar-link is-right"
- type="button"
- @click="clickTab($event, $options.rightSidebarViews.mergeRequestInfo)"
- >
- <icon
- :size="16"
- name="text-description"
- />
- </button>
- </li>
- <li>
- <button
- v-tooltip
- :title="__('Pipelines')"
- :aria-label="__('Pipelines')"
- :class="{
- active: pipelinesActive
- }"
- data-container="body"
- data-placement="left"
- class="ide-sidebar-link is-right"
- type="button"
- @click="clickTab($event, $options.rightSidebarViews.pipelines)"
- >
- <icon
- :size="16"
- name="rocket"
- />
- </button>
- </li>
- <li v-if="showLivePreview">
- <button
- v-tooltip
- :title="__('Live preview')"
- :aria-label="__('Live preview')"
+ :title="tab.title"
+ :aria-label="tab.title"
:class="{
- active: rightPane === $options.rightSidebarViews.clientSidePreview
+ active: tab.isActive
}"
data-container="body"
data-placement="left"
class="ide-sidebar-link is-right"
type="button"
- @click="clickTab($event, $options.rightSidebarViews.clientSidePreview)"
+ @click="clickTab($event, tab.view)"
>
<icon
:size="16"
- name="live-preview"
+ :name="tab.icon"
/>
</button>
</li>
diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js
index c90f8694326..c0550116633 100644
--- a/app/assets/javascripts/ide/index.js
+++ b/app/assets/javascripts/ide/index.js
@@ -15,21 +15,21 @@ Vue.use(Translate);
* @param {Object} options - Extra options for the IDE (Used by EE).
* @param {(e:Element) => Object} options.extraInitialData -
* Function that returns extra properties to seed initial data.
+ * @param {Component} options.rootComponent -
+ * Component that overrides the root component.
*/
export function initIde(el, options = {}) {
if (!el) return null;
const {
extraInitialData = () => ({}),
+ rootComponent = ide,
} = options;
return new Vue({
el,
store,
router,
- components: {
- ide,
- },
created() {
this.setEmptyStateSvgs({
emptyStateSvgPath: el.dataset.emptyStateSvgPath,
@@ -51,7 +51,7 @@ export function initIde(el, options = {}) {
...mapActions(['setEmptyStateSvgs', 'setLinks', 'setInitialData']),
},
render(createElement) {
- return createElement('ide');
+ return createElement(rootComponent);
},
});
}
diff --git a/app/assets/javascripts/job.js b/app/assets/javascripts/job.js
index d4f2a3ef7d3..0e71e705c13 100644
--- a/app/assets/javascripts/job.js
+++ b/app/assets/javascripts/job.js
@@ -6,7 +6,7 @@ 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 { isScrolledToBottom, scrollDown } from './lib/utils/scroll_utils';
+import { isScrolledToBottom, scrollDown, scrollUp } from './lib/utils/scroll_utils';
import LogOutputBehaviours from './lib/utils/logoutput_behaviours';
export default class Job extends LogOutputBehaviours {
@@ -80,7 +80,7 @@ export default class Job extends LogOutputBehaviours {
}
scrollToTop() {
- $(document).scrollTop(0);
+ scrollUp();
this.hasBeenScrolled = true;
this.toggleScroll();
}
diff --git a/app/assets/javascripts/jobs/components/empty_state.vue b/app/assets/javascripts/jobs/components/empty_state.vue
index 4faf08387fb..ff45a5b05f8 100644
--- a/app/assets/javascripts/jobs/components/empty_state.vue
+++ b/app/assets/javascripts/jobs/components/empty_state.vue
@@ -25,7 +25,7 @@
validator(value) {
return (
value === null ||
- (Object.prototype.hasOwnProperty.call(value, 'link') &&
+ (Object.prototype.hasOwnProperty.call(value, 'path') &&
Object.prototype.hasOwnProperty.call(value, 'method') &&
Object.prototype.hasOwnProperty.call(value, 'title'))
);
@@ -63,7 +63,7 @@
class="text-center"
>
<a
- :href="action.link"
+ :href="action.path"
:data-method="action.method"
class="js-job-empty-state-action btn btn-primary"
>
diff --git a/app/assets/javascripts/jobs/components/erased_block.vue b/app/assets/javascripts/jobs/components/erased_block.vue
index d688eebfa95..3d6d9ba4387 100644
--- a/app/assets/javascripts/jobs/components/erased_block.vue
+++ b/app/assets/javascripts/jobs/components/erased_block.vue
@@ -1,39 +1,36 @@
<script>
-import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+ import _ from 'underscore';
+ import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
-export default {
- components: {
- TimeagoTooltip,
- },
- props: {
- erasedByUser: {
- type: Boolean,
- required: true,
+ export default {
+ components: {
+ TimeagoTooltip,
},
- username: {
- type: String,
- required: false,
- default: null,
+ props: {
+ user: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
+ erasedAt: {
+ type: String,
+ required: true,
+ },
},
- linkToUser: {
- type: String,
- required: false,
- default: null,
+ computed: {
+ isErasedByUser() {
+ return !_.isEmpty(this.user);
+ },
},
- erasedAt: {
- type: String,
- required: true,
- },
- },
-};
+ };
</script>
<template>
<div class="prepend-top-default js-build-erased">
<div class="erased alert alert-warning">
- <template v-if="erasedByUser">
+ <template v-if="isErasedByUser">
{{ s__("Job|Job has been erased by") }}
- <a :href="linkToUser">
- {{ username }}
+ <a :href="user.web_url">
+ {{ user.username }}
</a>
</template>
<template v-else>
diff --git a/app/assets/javascripts/jobs/components/job_log.vue b/app/assets/javascripts/jobs/components/job_log.vue
index 3c4749d996b..b12e963b60c 100644
--- a/app/assets/javascripts/jobs/components/job_log.vue
+++ b/app/assets/javascripts/jobs/components/job_log.vue
@@ -6,7 +6,7 @@
type: String,
required: true,
},
- isReceivingBuildTrace: {
+ isComplete: {
type: Boolean,
required: true,
},
@@ -22,7 +22,7 @@
</code>
<div
- v-if="isReceivingBuildTrace"
+ v-if="isComplete"
class="js-log-animation build-loader-animation"
>
<div class="dot"></div>
diff --git a/app/assets/javascripts/jobs/components/job_log_controllers.vue b/app/assets/javascripts/jobs/components/job_log_controllers.vue
index 2cbf0f85266..3e62ababea3 100644
--- a/app/assets/javascripts/jobs/components/job_log_controllers.vue
+++ b/app/assets/javascripts/jobs/components/job_log_controllers.vue
@@ -1,8 +1,9 @@
<script>
+ import { polyfillSticky } from '~/lib/utils/sticky';
import Icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
import { numberToHumanSize } from '~/lib/utils/number_utils';
- import { s__, sprintf } from '~/locale';
+ import { sprintf } from '~/locale';
export default {
components: {
@@ -12,44 +13,48 @@
tooltip,
},
props: {
- canEraseJob: {
- type: Boolean,
- required: true,
+ erasePath: {
+ type: String,
+ required: false,
+ default: null,
},
size: {
type: Number,
required: true,
},
- rawTracePath: {
+ rawPath: {
type: String,
required: false,
default: null,
},
- canScrollToTop: {
+ isScrollTopDisabled: {
+ type: Boolean,
+ required: true,
+ },
+ isScrollBottomDisabled: {
+ type: Boolean,
+ required: true,
+ },
+ isScrollingDown: {
type: Boolean,
required: true,
},
- canScrollToBottom: {
+ isTraceSizeVisible: {
type: Boolean,
required: true,
},
},
computed: {
jobLogSize() {
- return sprintf('Showing last %{startSpanTag} %{size} %{endSpanTag} of log -', {
- startSpanTag: '<span class="s-truncated-info-size truncated-info-size">',
- endSpanTag: '</span>',
+ return sprintf('Showing last %{size} of log -', {
size: numberToHumanSize(this.size),
});
},
},
+ mounted() {
+ polyfillSticky(this.$el);
+ },
methods: {
- handleEraseJobClick() {
- // eslint-disable-next-line no-alert
- if (window.confirm(s__('Job|Are you sure you want to erase this job?'))) {
- this.$emit('eraseJob');
- }
- },
handleScrollToTop() {
this.$emit('scrollJobLogTop');
},
@@ -57,48 +62,52 @@
this.$emit('scrollJobLogBottom');
},
},
+
};
</script>
<template>
<div class="top-bar">
<!-- truncate information -->
<div class="js-truncated-info truncated-info d-none d-sm-block float-left">
- <p v-html="jobLogSize"></p>
+ <template v-if="isTraceSizeVisible">
+ {{ jobLogSize }}
- <a
- v-if="rawTracePath"
- :href="rawTracePath"
- class="js-raw-link raw-link"
- >
- {{ s__("Job|Complete Raw") }}
- </a>
+ <a
+ v-if="rawPath"
+ :href="rawPath"
+ class="js-raw-link raw-link"
+ >
+ {{ s__("Job|Complete Raw") }}
+ </a>
+ </template>
</div>
<!-- eo truncate information -->
<div class="controllers float-right">
<!-- links -->
<a
- v-if="rawTracePath"
+ v-if="rawPath"
v-tooltip
:title="s__('Job|Show complete raw')"
- :href="rawTracePath"
+ :href="rawPath"
class="js-raw-link-controller controllers-buttons"
data-container="body"
>
<icon name="doc-text" />
</a>
- <button
- v-if="canEraseJob"
+ <a
+ v-if="erasePath"
v-tooltip
:title="s__('Job|Erase job log')"
- type="button"
+ :href="erasePath"
+ data-confirm="__('Are you sure you want to erase this build?')"
class="js-erase-link controllers-buttons"
data-container="body"
- @click="handleEraseJobClick"
+ data-method="post"
>
<icon name="remove" />
- </button>
+ </a>
<!-- eo links -->
<!-- scroll buttons -->
@@ -109,7 +118,7 @@
data-container="body"
>
<button
- :disabled="!canScrollToTop"
+ :disabled="isScrollTopDisabled"
type="button"
class="js-scroll-top btn-scroll btn-transparent btn-blank"
@click="handleScrollToTop"
@@ -125,9 +134,10 @@
data-container="body"
>
<button
- :disabled="!canScrollToBottom"
+ :disabled="isScrollBottomDisabled"
type="button"
class="js-scroll-bottom btn-scroll btn-transparent btn-blank"
+ :class="{ animate: isScrollingDown }"
@click="handleScrollToBottom"
>
<icon name="scroll_down"/>
diff --git a/app/assets/javascripts/jobs/components/stuck_block.vue b/app/assets/javascripts/jobs/components/stuck_block.vue
index 18883fea950..a60643b2c65 100644
--- a/app/assets/javascripts/jobs/components/stuck_block.vue
+++ b/app/assets/javascripts/jobs/components/stuck_block.vue
@@ -24,14 +24,14 @@ export default {
<div class="bs-callout bs-callout-warning">
<p
v-if="hasNoRunnersForProject"
- class="js-stuck-no-runners"
+ class="js-stuck-no-runners append-bottom-0"
>
{{ s__(`Job|This job is stuck, because the project
doesn't have any runners online assigned to it.`) }}
</p>
<p
v-else-if="tags.length"
- class="js-stuck-with-tags"
+ class="js-stuck-with-tags append-bottom-0"
>
{{ s__(`This job is stuck, because you don't have
any active runners online with any of these tags assigned to them:`) }}
@@ -45,7 +45,7 @@ export default {
</p>
<p
v-else
- class="js-stuck-no-active-runner"
+ class="js-stuck-no-active-runner append-bottom-0"
>
{{ s__(`This job is stuck, because you don't
have any active runners that can run this job.`) }}
diff --git a/app/assets/javascripts/jobs/job_details_bundle.js b/app/assets/javascripts/jobs/job_details_bundle.js
index a84324f14b2..0136ec4d194 100644
--- a/app/assets/javascripts/jobs/job_details_bundle.js
+++ b/app/assets/javascripts/jobs/job_details_bundle.js
@@ -1,34 +1,36 @@
+import { mapState } from 'vuex';
import Vue from 'vue';
-import JobMediator from './job_details_mediator';
-import jobHeader from './components/header.vue';
-import detailsBlock from './components/sidebar_details_block.vue';
+import Job from '../job';
+import JobHeader from './components/header.vue';
+import DetailsBlock from './components/sidebar_details_block.vue';
+import createStore from './store';
export default () => {
const { dataset } = document.getElementById('js-job-details-vue');
- const mediator = new JobMediator({ endpoint: dataset.endpoint });
- mediator.fetchJob();
+ // eslint-disable-next-line no-new
+ new Job();
+
+ const store = createStore();
+ store.dispatch('setJobEndpoint', dataset.endpoint);
+ store.dispatch('fetchJob');
// Header
// eslint-disable-next-line no-new
new Vue({
el: '#js-build-header-vue',
components: {
- jobHeader,
- },
- data() {
- return {
- mediator,
- };
+ JobHeader,
},
- mounted() {
- this.mediator.initBuildClass();
+ store,
+ computed: {
+ ...mapState(['job', 'isLoading']),
},
render(createElement) {
return createElement('job-header', {
props: {
- isLoading: this.mediator.state.isLoading,
- job: this.mediator.store.state.job,
+ isLoading: this.isLoading,
+ job: this.job,
},
});
},
@@ -41,18 +43,17 @@ export default () => {
new Vue({
el: detailsBlockElement,
components: {
- detailsBlock,
+ DetailsBlock,
},
- data() {
- return {
- mediator,
- };
+ store,
+ computed: {
+ ...mapState(['job', 'isLoading']),
},
render(createElement) {
return createElement('details-block', {
props: {
- isLoading: this.mediator.state.isLoading,
- job: this.mediator.store.state.job,
+ isLoading: this.isLoading,
+ job: this.job,
runnerHelpUrl: dataset.runnerHelpUrl,
terminalPath: detailsBlockDataset.terminalPath,
},
diff --git a/app/assets/javascripts/jobs/job_details_mediator.js b/app/assets/javascripts/jobs/job_details_mediator.js
deleted file mode 100644
index 073e518baa0..00000000000
--- a/app/assets/javascripts/jobs/job_details_mediator.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import Visibility from 'visibilityjs';
-import Flash from '../flash';
-import Poll from '../lib/utils/poll';
-import JobStore from './stores/job_store';
-import JobService from './services/job_service';
-import Job from '../job';
-
-export default class JobMediator {
- constructor(options = {}) {
- this.options = options;
-
- this.store = new JobStore();
- this.service = new JobService(options.endpoint);
-
- this.state = {
- isLoading: false,
- };
- }
-
- initBuildClass() {
- this.build = new Job();
- }
-
- fetchJob() {
- this.poll = new Poll({
- resource: this.service,
- method: 'getJob',
- successCallback: response => this.successCallback(response),
- errorCallback: () => this.errorCallback(),
- });
-
- if (!Visibility.hidden()) {
- this.state.isLoading = true;
- this.poll.makeRequest();
- } else {
- this.getJob();
- }
-
- Visibility.change(() => {
- if (!Visibility.hidden()) {
- this.poll.restart();
- } else {
- this.poll.stop();
- }
- });
- }
-
- getJob() {
- return this.service
- .getJob()
- .then(response => this.successCallback(response))
- .catch(() => this.errorCallback());
- }
-
- successCallback(response) {
- this.state.isLoading = false;
- return this.store.storeJob(response.data);
- }
-
- errorCallback() {
- this.state.isLoading = false;
-
- return new Flash('An error occurred while fetching the job.');
- }
-}
diff --git a/app/assets/javascripts/jobs/services/job_service.js b/app/assets/javascripts/jobs/services/job_service.js
deleted file mode 100644
index b746489c45c..00000000000
--- a/app/assets/javascripts/jobs/services/job_service.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import axios from '../../lib/utils/axios_utils';
-
-export default class JobService {
- constructor(endpoint) {
- this.job = endpoint;
- }
-
- getJob() {
- return axios.get(this.job);
- }
-}
diff --git a/app/assets/javascripts/jobs/store/mutations.js b/app/assets/javascripts/jobs/store/mutations.js
index cd12ef87d40..c3f2359fa4d 100644
--- a/app/assets/javascripts/jobs/store/mutations.js
+++ b/app/assets/javascripts/jobs/store/mutations.js
@@ -1,6 +1,9 @@
import * as types from './mutation_types';
export default {
+ [types.SET_JOB_ENDPOINT](state, endpoint) {
+ state.jobEndpoint = endpoint;
+ },
[types.REQUEST_STATUS_FAVICON](state) {
state.fetchingStatusFavicon = true;
},
diff --git a/app/assets/javascripts/jobs/stores/job_store.js b/app/assets/javascripts/jobs/stores/job_store.js
deleted file mode 100644
index 766194b8387..00000000000
--- a/app/assets/javascripts/jobs/stores/job_store.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export default class JobStore {
- constructor() {
- this.state = {
- job: {},
- };
- }
-
- storeJob(job = {}) {
- this.state.job = job;
- }
-}
diff --git a/app/assets/javascripts/lib/utils/logoutput_behaviours.js b/app/assets/javascripts/lib/utils/logoutput_behaviours.js
index 1bf99d935ef..41b57025cc9 100644
--- a/app/assets/javascripts/lib/utils/logoutput_behaviours.js
+++ b/app/assets/javascripts/lib/utils/logoutput_behaviours.js
@@ -1,5 +1,11 @@
import $ from 'jquery';
-import { canScroll, isScrolledToBottom, toggleDisableButton } from './scroll_utils';
+import {
+ canScroll,
+ isScrolledToBottom,
+ isScrolledToTop,
+ isScrolledToMiddle,
+ toggleDisableButton,
+} from './scroll_utils';
export default class LogOutputBehaviours {
constructor() {
@@ -12,18 +18,13 @@ export default class LogOutputBehaviours {
}
toggleScroll() {
- const $document = $(document);
- const currentPosition = $document.scrollTop();
- const scrollHeight = $document.height();
-
- const windowHeight = $(window).height();
if (canScroll()) {
- if (currentPosition > 0 && scrollHeight - currentPosition !== windowHeight) {
+ if (isScrolledToMiddle()) {
// User is in the middle of the log
toggleDisableButton(this.$scrollTopBtn, false);
toggleDisableButton(this.$scrollBottomBtn, false);
- } else if (currentPosition === 0) {
+ } else if (isScrolledToTop()) {
// User is at Top of Log
toggleDisableButton(this.$scrollTopBtn, true);
diff --git a/app/assets/javascripts/lib/utils/scroll_utils.js b/app/assets/javascripts/lib/utils/scroll_utils.js
index 9313b570863..b4da1e16f08 100644
--- a/app/assets/javascripts/lib/utils/scroll_utils.js
+++ b/app/assets/javascripts/lib/utils/scroll_utils.js
@@ -4,6 +4,7 @@ export const canScroll = () => $(document).height() > $(window).height();
/**
* Checks if the entire page is scrolled down all the way to the bottom
+ * @returns {Boolean}
*/
export const isScrolledToBottom = () => {
const $document = $(document);
@@ -16,11 +17,34 @@ export const isScrolledToBottom = () => {
return scrollHeight - currentPosition === windowHeight;
};
+/**
+ * Checks if page is scrolled to the top
+ * @returns {Boolean}
+ */
+export const isScrolledToTop = () => $(document).scrollTop() === 0;
+
export const scrollDown = () => {
const $document = $(document);
$document.scrollTop($document.height());
};
+export const scrollUp = () => {
+ $(document).scrollTop(0);
+};
+
+/**
+ * Checks if scroll position is in the middle of the page
+ * @returns {Boolean}
+ */
+export const isScrolledToMiddle = () => {
+ const $document = $(document);
+ const currentPosition = $document.scrollTop();
+ const scrollHeight = $document.height();
+ const windowHeight = $(window).height();
+
+ return currentPosition > 0 && scrollHeight - currentPosition !== windowHeight;
+};
+
export const toggleDisableButton = ($button, disable) => {
if (disable && $button.prop('disabled')) return;
$button.prop('disabled', disable);
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index a07a0ecfc76..67338aa96c3 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -97,33 +97,45 @@ export default {
store: new MonitoringStore(),
state: 'gettingStarted',
showEmptyState: true,
- updateAspectRatio: false,
- updatedAspectRatios: 0,
hoverData: {},
- resizeThrottled: {},
+ elWidth: 0,
};
},
+ computed: {
+ forceRedraw() {
+ return this.elWidth;
+ },
+ },
created() {
this.service = new MonitoringService({
metricsEndpoint: this.metricsEndpoint,
deploymentEndpoint: this.deploymentEndpoint,
environmentsEndpoint: this.environmentsEndpoint,
});
- eventHub.$on('toggleAspectRatio', this.toggleAspectRatio);
+ this.mutationObserverConfig = {
+ attributes: true,
+ childList: false,
+ subtree: false,
+ };
eventHub.$on('hoverChanged', this.hoverChanged);
},
beforeDestroy() {
- eventHub.$off('toggleAspectRatio', this.toggleAspectRatio);
eventHub.$off('hoverChanged', this.hoverChanged);
window.removeEventListener('resize', this.resizeThrottled, false);
+ this.sidebarMutationObserver.disconnect();
},
mounted() {
- this.resizeThrottled = _.throttle(this.resize, 600);
+ this.resizeThrottled = _.debounce(this.resize, 100);
if (!this.hasMetrics) {
this.state = 'gettingStarted';
} else {
this.getGraphsData();
window.addEventListener('resize', this.resizeThrottled, false);
+
+ const sidebarEl = document.querySelector('.nav-sidebar');
+ // The sidebar listener
+ this.sidebarMutationObserver = new MutationObserver(this.resizeThrottled);
+ this.sidebarMutationObserver.observe(sidebarEl, this.mutationObserverConfig);
}
},
methods: {
@@ -153,14 +165,7 @@ export default {
});
},
resize() {
- this.updateAspectRatio = true;
- },
- toggleAspectRatio() {
- this.updatedAspectRatios += 1;
- if (this.store.getMetricsCount() === this.updatedAspectRatios) {
- this.updateAspectRatio = !this.updateAspectRatio;
- this.updatedAspectRatios = 0;
- }
+ this.elWidth = this.$el.clientWidth;
},
hoverChanged(data) {
this.hoverData = data;
@@ -172,6 +177,7 @@ export default {
<template>
<div
v-if="!showEmptyState"
+ :key="forceRedraw"
class="prometheus-graphs prepend-top-default"
>
<div class="environments d-flex align-items-center">
@@ -218,7 +224,6 @@ export default {
:key="graphIndex"
:graph-data="graphData"
:hover-data="hoverData"
- :update-aspect-ratio="updateAspectRatio"
:deployment-data="store.deploymentData"
:project-path="projectPath"
:tags-path="tagsPath"
diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue
index a13f30e6079..ff44f51b8f8 100644
--- a/app/assets/javascripts/monitoring/components/graph.vue
+++ b/app/assets/javascripts/monitoring/components/graph.vue
@@ -32,10 +32,6 @@ export default {
type: Object,
required: true,
},
- updateAspectRatio: {
- type: Boolean,
- required: true,
- },
deploymentData: {
type: Array,
required: true,
@@ -110,15 +106,6 @@ export default {
},
},
watch: {
- updateAspectRatio() {
- if (this.updateAspectRatio) {
- this.graphHeight = 450;
- this.graphWidth = 600;
- this.measurements = measurements.large;
- this.draw();
- eventHub.$emit('toggleAspectRatio');
- }
- },
hoverData() {
this.positionFlag();
},
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index e2f485e37eb..f301f093ef4 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -16,7 +16,7 @@ import 'vendor/jquery.atwho';
import AjaxCache from '~/lib/utils/ajax_cache';
import Vue from 'vue';
import syntaxHighlight from '~/syntax_highlight';
-import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
+import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
import axios from './lib/utils/axios_utils';
import { getLocationHash } from './lib/utils/url_utility';
import Flash from './flash';
diff --git a/app/assets/javascripts/notes/components/diff_with_note.vue b/app/assets/javascripts/notes/components/diff_with_note.vue
index d9161210fe6..353aa790743 100644
--- a/app/assets/javascripts/notes/components/diff_with_note.vue
+++ b/app/assets/javascripts/notes/components/diff_with_note.vue
@@ -3,7 +3,7 @@ import { mapState, mapActions } from 'vuex';
import imageDiffHelper from '~/image_diff/helpers/index';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
-import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
+import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
import { trimFirstCharOfLineContent } from '~/diffs/store/utils';
export default {
diff --git a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
index 7836d4f3b09..1522e2227e4 100644
--- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
+++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
@@ -42,7 +42,7 @@ export default {
keys: ['feature', 'request'],
},
],
- simpleMetrics: ['redis', 'sidekiq'],
+ simpleMetrics: ['redis'],
data() {
return { currentRequestId: '' };
},
diff --git a/app/assets/javascripts/performance_bar/components/simple_metric.vue b/app/assets/javascripts/performance_bar/components/simple_metric.vue
index b654bc66249..760ea8fe1e6 100644
--- a/app/assets/javascripts/performance_bar/components/simple_metric.vue
+++ b/app/assets/javascripts/performance_bar/components/simple_metric.vue
@@ -1,16 +1,29 @@
<script>
-export default {
- props: {
- currentRequest: {
- type: Object,
- required: true,
+ export default {
+ props: {
+ currentRequest: {
+ type: Object,
+ required: true,
+ },
+ metric: {
+ type: String,
+ required: true,
+ },
},
- metric: {
- type: String,
- required: true,
+ computed: {
+ duration() {
+ return (
+ this.currentRequest.details[this.metric] &&
+ this.currentRequest.details[this.metric].duration
+ );
+ },
+ calls() {
+ return (
+ this.currentRequest.details[this.metric] && this.currentRequest.details[this.metric].calls
+ );
+ },
},
- },
-};
+ };
</script>
<template>
<div
@@ -21,9 +34,9 @@ export default {
v-if="currentRequest.details"
class="bold"
>
- {{ currentRequest.details[metric].duration }}
+ {{ duration }}
/
- {{ currentRequest.details[metric].calls }}
+ {{ calls }}
</span>
{{ metric }}
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.js
deleted file mode 100644
index bf8628d18a6..00000000000
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
-The squash-before-merge button is EE only, but it's located right in the middle
-of the readyToMerge state component template.
-
-If we didn't declare this component in CE, we'd need to maintain a separate copy
-of the readyToMergeState template in EE, which is pretty big and likely to change.
-
-Instead, in CE, we declare the component, but it's hidden and is configured to do nothing.
-In EE, the configuration extends this object to add a functioning squash-before-merge
-button.
-*/
-
-export default {
- template: '',
-};
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
index 23c3284cd21..c8ad2aa30a6 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
@@ -6,7 +6,7 @@ import MergeRequest from '../../../merge_request';
import Flash from '../../../flash';
import statusIcon from '../mr_widget_status_icon.vue';
import eventHub from '../../event_hub';
-import SquashBeforeMerge from './mr_widget_squash_before_merge.vue';
+import SquashBeforeMerge from './squash_before_merge.vue';
export default {
name: 'ReadyToMerge',
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
index 25ad329e196..25ad329e196 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
diff --git a/app/assets/javascripts/vue_merge_request_widget/dependencies.js b/app/assets/javascripts/vue_merge_request_widget/dependencies.js
index 15097fa2a3f..a23496c6bf5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/dependencies.js
+++ b/app/assets/javascripts/vue_merge_request_widget/dependencies.js
@@ -40,7 +40,7 @@ export { default as MRWidgetService } from './services/mr_widget_service';
export { default as eventHub } from './event_hub';
export { default as getStateKey } from './stores/get_state_key';
export { default as stateMaps } from './stores/state_maps';
-export { default as SquashBeforeMerge } from './components/states/mr_widget_squash_before_merge.vue';
+export { default as SquashBeforeMerge } from './components/states/squash_before_merge.vue';
export { default as notify } from '../lib/utils/notify';
export { default as SourceBranchRemovalStatus } from './components/source_branch_removal_status.vue';
diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue
index 27689a55b67..807e049caf6 100644
--- a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue
+++ b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue
@@ -2,7 +2,7 @@
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
import $ from 'jquery';
-import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
+import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
const { CancelToken } = axios;
let axiosSource;
diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
index 9d25003ccb7..c45dafa9807 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
@@ -1,5 +1,5 @@
<script>
- import Link from '@gitlab-org/gitlab-ui/dist/components/base/link';
+ import { Link } from '@gitlab-org/gitlab-ui';
export default {
components: {
diff --git a/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue b/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue
index f11a7699f27..1d9c9220469 100644
--- a/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue
@@ -1,5 +1,5 @@
<script>
-import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
+import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
export default {
name: 'SkeletonNote',
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index 0c1b8b92de3..6d891e21556 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -286,7 +286,7 @@ body {
}
.page-title {
- margin-top: $gl-padding;
+ margin: #{2 * $grid-size} 0;
line-height: 1.3;
font-size: 1.25em;
font-weight: $gl-font-weight-bold;
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index fb2808edf47..b87034d10b6 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -273,9 +273,10 @@ class ApplicationController < ActionController::Base
end
def event_filter
- # Split using comma to maintain backward compatibility Ex/ "filter1,filter2"
- filters = cookies['event_filter'].split(',')[0] if cookies['event_filter'].present?
- @event_filter ||= EventFilter.new(filters)
+ @event_filter ||=
+ EventFilter.new(params[:event_filter].presence || cookies[:event_filter]).tap do |new_event_filter|
+ cookies[:event_filter] = new_event_filter.filter
+ end
end
# JSON for infinite scroll via Pager object
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 241753a505a..c032fb2efb5 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -40,7 +40,7 @@ class DashboardController < Dashboard::ApplicationController
end
@events = EventCollection
- .new(projects, offset: params[:offset].to_i, filter: @event_filter)
+ .new(projects, offset: params[:offset].to_i, filter: event_filter)
.to_a
Events::RenderService.new(current_user).execute(@events)
diff --git a/app/finders/admin/runners_finder.rb b/app/finders/admin/runners_finder.rb
index 3c2d7ee7d76..fbb1cfc5c66 100644
--- a/app/finders/admin/runners_finder.rb
+++ b/app/finders/admin/runners_finder.rb
@@ -10,6 +10,7 @@ class Admin::RunnersFinder < UnionFinder
def execute
search!
filter_by_status!
+ filter_by_runner_type!
sort!
paginate!
@@ -36,10 +37,11 @@ class Admin::RunnersFinder < UnionFinder
end
def filter_by_status!
- status = @params[:status_status]
- if status.present? && Ci::Runner::AVAILABLE_STATUSES.include?(status)
- @runners = @runners.public_send(status) # rubocop:disable GitlabSecurity/PublicSend
- end
+ filter_by!(:status_status, Ci::Runner::AVAILABLE_STATUSES)
+ end
+
+ def filter_by_runner_type!
+ filter_by!(:type_type, Ci::Runner::AVAILABLE_TYPES)
end
def sort!
@@ -49,4 +51,12 @@ class Admin::RunnersFinder < UnionFinder
def paginate!
@runners = @runners.page(@params[:page]).per(NUMBER_OF_RUNNERS_PER_PAGE)
end
+
+ def filter_by!(scope_name, available_scopes)
+ scope = @params[scope_name]
+
+ if scope.present? && available_scopes.include?(scope)
+ @runners = @runners.public_send(scope) # rubocop:disable GitlabSecurity/PublicSend
+ end
+ end
end
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 3e815937f4b..31330d0682e 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -9,12 +9,24 @@ module Ci
include ChronicDurationAttribute
include FromUnion
+ enum access_level: {
+ not_protected: 0,
+ ref_protected: 1
+ }
+
+ enum runner_type: {
+ instance_type: 1,
+ group_type: 2,
+ project_type: 3
+ }
+
RUNNER_QUEUE_EXPIRY_TIME = 60.minutes
ONLINE_CONTACT_TIMEOUT = 1.hour
UPDATE_DB_RUNNER_INFO_EVERY = 40.minutes
- AVAILABLE_TYPES = %w[specific shared].freeze
+ AVAILABLE_TYPES_LEGACY = %w[specific shared].freeze
+ AVAILABLE_TYPES = runner_types.keys.freeze
AVAILABLE_STATUSES = %w[active paused online offline].freeze
- AVAILABLE_SCOPES = (AVAILABLE_TYPES + AVAILABLE_STATUSES).freeze
+ AVAILABLE_SCOPES = (AVAILABLE_TYPES_LEGACY + AVAILABLE_TYPES + AVAILABLE_STATUSES).freeze
FORM_EDITABLE = %i[description tag_list active run_untagged locked access_level maximum_timeout_human_readable].freeze
ignore_column :is_shared
@@ -97,17 +109,6 @@ module Ci
after_destroy :cleanup_runner_queue
- enum access_level: {
- not_protected: 0,
- ref_protected: 1
- }
-
- enum runner_type: {
- instance_type: 1,
- group_type: 2,
- project_type: 3
- }
-
cached_attr_reader :version, :revision, :platform, :architecture, :ip_address, :contacted_at
chronic_duration_attr :maximum_timeout_human_readable, :maximum_timeout
diff --git a/app/models/clusters/applications/jupyter.rb b/app/models/clusters/applications/jupyter.rb
index 3d84eeed5a8..7be6a14f585 100644
--- a/app/models/clusters/applications/jupyter.rb
+++ b/app/models/clusters/applications/jupyter.rb
@@ -73,6 +73,11 @@ module Clusters
"clientSecret" => oauth_application.secret,
"callbackUrl" => callback_url
}
+ },
+ "singleuser" => {
+ "extraEnv" => {
+ "GITLAB_CLUSTER_ID" => cluster.id
+ }
}
}
end
diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb
index 00a441a9a1e..c85b1790e73 100644
--- a/app/serializers/build_details_entity.rb
+++ b/app/serializers/build_details_entity.rb
@@ -7,6 +7,7 @@ class BuildDetailsEntity < JobEntity
expose :coverage, :erased_at, :duration
expose :tag_list, as: :tags
+ expose :has_trace?, as: :has_trace
expose :user, using: UserEntity
expose :runner, using: RunnerEntity
expose :pipeline, using: PipelineEntity
diff --git a/app/services/files/multi_service.rb b/app/services/files/multi_service.rb
index 08088f8c592..c9d3ee31d82 100644
--- a/app/services/files/multi_service.rb
+++ b/app/services/files/multi_service.rb
@@ -2,7 +2,7 @@
module Files
class MultiService < Files::BaseService
- UPDATE_FILE_ACTIONS = %w(update move delete).freeze
+ UPDATE_FILE_ACTIONS = %w(update move delete chmod).freeze
def create_commit!
transformer = Lfs::FileTransformer.new(project, @branch_name)
diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb
index 02d68c3add3..8933bef29ee 100644
--- a/app/services/quick_actions/interpret_service.rb
+++ b/app/services/quick_actions/interpret_service.rb
@@ -126,18 +126,16 @@ module QuickActions
parse_params do |assignee_param|
extract_users(assignee_param)
end
- # rubocop: disable CodeReuse/ActiveRecord
command :assign do |users|
next if users.empty?
- @updates[:assignee_ids] =
- if issuable.allows_multiple_assignees?
- issuable.assignees.pluck(:id) + users.map(&:id)
- else
- [users.first.id]
- end
+ if issuable.allows_multiple_assignees?
+ @updates[:assignee_ids] ||= issuable.assignees.map(&:id)
+ @updates[:assignee_ids] += users.map(&:id)
+ else
+ @updates[:assignee_ids] = [users.first.id]
+ end
end
- # rubocop: enable CodeReuse/ActiveRecord
desc do
if issuable.allows_multiple_assignees?
@@ -164,16 +162,14 @@ module QuickActions
# When multiple users are assigned, all will be unassigned if multiple assignees are no longer allowed
extract_users(unassign_param) if issuable.allows_multiple_assignees?
end
- # rubocop: disable CodeReuse/ActiveRecord
command :unassign do |users = nil|
- @updates[:assignee_ids] =
- if users&.any?
- issuable.assignees.pluck(:id) - users.map(&:id)
- else
- []
- end
+ if issuable.allows_multiple_assignees? && users&.any?
+ @updates[:assignee_ids] ||= issuable.assignees.map(&:id)
+ @updates[:assignee_ids] -= users.map(&:id)
+ else
+ @updates[:assignee_ids] = []
+ end
end
- # rubocop: enable CodeReuse/ActiveRecord
desc 'Set milestone'
explanation do |milestone|
@@ -290,8 +286,7 @@ module QuickActions
end
params '#issue | !merge_request'
condition do
- issuable.persisted? &&
- current_user.can?(:"update_#{issuable.to_ability_name}", issuable)
+ current_user.can?(:"update_#{issuable.to_ability_name}", issuable)
end
parse_params do |issuable_param|
extract_references(issuable_param, :issue).first ||
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index ee2e1703fdb..a5326f4b909 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -83,12 +83,21 @@
{{hint}}
%span.js-filter-tag.dropdown-light-content
{{tag}}
+
#js-dropdown-admin-runner-status.filtered-search-input-dropdown-menu.dropdown-menu
%ul{ data: { dropdown: true } }
- Ci::Runner::AVAILABLE_STATUSES.each do |status|
%li.filter-dropdown-item{ data: { value: status } }
= button_tag class: %w[btn btn-link] do
= status.titleize
+
+ #js-dropdown-admin-runner-type.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul{ data: { dropdown: true } }
+ - Ci::Runner::AVAILABLE_TYPES.each do |runner_type|
+ %li.filter-dropdown-item{ data: { value: runner_type } }
+ = button_tag class: %w[btn btn-link] do
+ = runner_type.titleize
+
= button_tag class: %w[clear-search hidden] do
= icon('times')
.filter-dropdown-container
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index f1bd817f17a..6a293daaf95 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -15,12 +15,12 @@
- new_project_label = _("New project")
- new_subgroup_label = _("New subgroup")
- if can_create_subgroups
- .btn-group.new-project-subgroup.droplab-dropdown.js-new-project-subgroup{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } }
- %input.btn.btn-success.dropdown-primary.js-new-group-child{ type: "button", value: new_project_label, data: { action: "new-project" } }
- %button.btn.btn-success.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } }
+ .btn-group.new-project-subgroup.droplab-dropdown.js-new-project-subgroup.qa-new-project-or-subgroup-dropdown{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } }
+ %input.btn.btn-success.dropdown-primary.js-new-group-child.qa-new-in-group-button{ type: "button", value: new_project_label, data: { action: "new-project" } }
+ %button.btn.btn-success.dropdown-toggle.js-dropdown-toggle.qa-new-project-or-subgroup-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } }
= icon("caret-down", class: "dropdown-btn-icon")
%ul#new-project-or-subgroup-dropdown.dropdown-menu.dropdown-menu-right{ data: { dropdown: true } }
- %li.droplab-item-selected{ role: "button", data: { value: "new-project", text: new_project_label } }
+ %li.droplab-item-selected.qa-new-project-option{ role: "button", data: { value: "new-project", text: new_project_label } }
.menu-item
.icon-container
= icon("check", class: "list-item-checkmark")
@@ -28,7 +28,7 @@
%strong= new_project_label
%span= s_("GroupsTree|Create a project in this group.")
%li.divider.droplap-item-ignore
- %li{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } }
+ %li.qa-new-subgroup-option{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } }
.menu-item
.icon-container
= icon("check", class: "list-item-checkmark")
diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml
index 877d945a09b..5e4595d930b 100644
--- a/app/views/import/gitlab_projects/new.html.haml
+++ b/app/views/import/gitlab_projects/new.html.haml
@@ -10,7 +10,7 @@
.row
.form-group.project-name.col-sm-12
= label_tag :name, _('Project name'), class: 'label-bold'
- = text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control input-lg", autofocus: true, required: true
+ = text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control input-lg", autofocus: true
.form-group.col-12.col-sm-6
= label_tag :namespace_id, _('Project URL'), class: 'label-bold'
.form-group
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index 4158bb69452..43170587797 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -109,7 +109,7 @@
= link_to edit_group_path(@group) do
.nav-icon-container
= sprite_icon('settings')
- %span.nav-item-name
+ %span.nav-item-name.qa-settings-item
= _('Settings')
%ul.sidebar-sub-level-items
= nav_link(path: %w[groups#projects groups#edit badges#index ci_cd#show], html_options: { class: "fly-out-top-item" } ) do
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index db07c475866..cbf89fa8f02 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -7,7 +7,7 @@
.form-group.project-name.col-sm-12
= f.label :name, class: 'label-bold' do
%span= _("Project name")
- = f.text_field :name, placeholder: "My awesome project", class: "form-control input-lg", autofocus: true, required: true
+ = f.text_field :name, placeholder: "My awesome project", class: "form-control input-lg", autofocus: true
.form-group.project-path.col-sm-6
= f.label :namespace_id, class: 'label-bold' do
%span= s_("Project URL")
diff --git a/app/views/shared/_event_filter.html.haml b/app/views/shared/_event_filter.html.haml
index 7afb7b3a93b..6612497e7e2 100644
--- a/app/views/shared/_event_filter.html.haml
+++ b/app/views/shared/_event_filter.html.haml
@@ -2,13 +2,13 @@
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
%ul.nav-links.event-filter.scrolling-tabs.nav.nav-tabs
- = event_filter_link EventFilter.all, _('All'), s_('EventFilterBy|Filter by all')
+ = event_filter_link EventFilter::ALL, _('All'), s_('EventFilterBy|Filter by all')
- if event_filter_visible(:repository)
- = event_filter_link EventFilter.push, _('Push events'), s_('EventFilterBy|Filter by push events')
+ = event_filter_link EventFilter::PUSH, _('Push events'), s_('EventFilterBy|Filter by push events')
- if event_filter_visible(:merge_requests)
- = event_filter_link EventFilter.merged, _('Merge events'), s_('EventFilterBy|Filter by merge events')
+ = event_filter_link EventFilter::MERGED, _('Merge events'), s_('EventFilterBy|Filter by merge events')
- if event_filter_visible(:issues)
- = event_filter_link EventFilter.issue, _('Issue events'), s_('EventFilterBy|Filter by issue events')
+ = event_filter_link EventFilter::ISSUE, _('Issue events'), s_('EventFilterBy|Filter by issue events')
- if comments_visible?
- = event_filter_link EventFilter.comments, _('Comments'), s_('EventFilterBy|Filter by comments')
- = event_filter_link EventFilter.team, _('Team'), s_('EventFilterBy|Filter by team')
+ = event_filter_link EventFilter::COMMENTS, _('Comments'), s_('EventFilterBy|Filter by comments')
+ = event_filter_link EventFilter::TEAM, _('Team'), s_('EventFilterBy|Filter by team')
diff --git a/changelogs/unreleased/1801-allow-event_filter-to-be-set-in-the-url.yml b/changelogs/unreleased/1801-allow-event_filter-to-be-set-in-the-url.yml
new file mode 100644
index 00000000000..4ceaa7e3139
--- /dev/null
+++ b/changelogs/unreleased/1801-allow-event_filter-to-be-set-in-the-url.yml
@@ -0,0 +1,5 @@
+---
+title: "Allow events filter to be set in the URL in addition to cookie"
+merge_request: 21557
+author: Igor @igas
+type: added
diff --git a/changelogs/unreleased/43832-adds-chdmod-to-commits-actions-api.yml b/changelogs/unreleased/43832-adds-chdmod-to-commits-actions-api.yml
new file mode 100644
index 00000000000..cea1436ae8b
--- /dev/null
+++ b/changelogs/unreleased/43832-adds-chdmod-to-commits-actions-api.yml
@@ -0,0 +1,5 @@
+---
+title: Allows to chmod file with commits API
+merge_request: 21866
+author: Jacopo Beschi @jacopo-beschi
+type: added
diff --git a/changelogs/unreleased/4907-improve-build-create-performance-for-license-management.yml b/changelogs/unreleased/4907-improve-build-create-performance-for-license-management.yml
new file mode 100644
index 00000000000..e82bda6819f
--- /dev/null
+++ b/changelogs/unreleased/4907-improve-build-create-performance-for-license-management.yml
@@ -0,0 +1,5 @@
+---
+title: Dont create license_management build when not included in license
+merge_request: 21958
+author:
+type: performance
diff --git a/changelogs/unreleased/50289-vendor-ci-yml-for-the-last-time.yml b/changelogs/unreleased/50289-vendor-ci-yml-for-the-last-time.yml
new file mode 100644
index 00000000000..7aee8720888
--- /dev/null
+++ b/changelogs/unreleased/50289-vendor-ci-yml-for-the-last-time.yml
@@ -0,0 +1,5 @@
+---
+title: Update all gitlab CI templates from gitlab-org/gitlab-ci-yml
+merge_request: 21929
+author:
+type: added
diff --git a/changelogs/unreleased/50904-update-scroll-utils.yml b/changelogs/unreleased/50904-update-scroll-utils.yml
new file mode 100644
index 00000000000..e301de1a40b
--- /dev/null
+++ b/changelogs/unreleased/50904-update-scroll-utils.yml
@@ -0,0 +1,5 @@
+---
+title: Extracts scroll position check into reusable functions
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/50904-use-vuex-store-job.yml b/changelogs/unreleased/50904-use-vuex-store-job.yml
new file mode 100644
index 00000000000..5b1112a4f5b
--- /dev/null
+++ b/changelogs/unreleased/50904-use-vuex-store-job.yml
@@ -0,0 +1,5 @@
+---
+title: Uses Vuex store in job details page and removes old mediator pattern
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/51522-add-new-project-via-import-by-url-auto-populates-slug-but-not-project-name.yml b/changelogs/unreleased/51522-add-new-project-via-import-by-url-auto-populates-slug-but-not-project-name.yml
new file mode 100644
index 00000000000..06b7c9c7b34
--- /dev/null
+++ b/changelogs/unreleased/51522-add-new-project-via-import-by-url-auto-populates-slug-but-not-project-name.yml
@@ -0,0 +1,5 @@
+---
+title: Removes the 'required' attribute from the 'project name' field
+merge_request: 21770
+author:
+type: other
diff --git a/changelogs/unreleased/51569-performance-bar.yml b/changelogs/unreleased/51569-performance-bar.yml
new file mode 100644
index 00000000000..ab62e7d3b3e
--- /dev/null
+++ b/changelogs/unreleased/51569-performance-bar.yml
@@ -0,0 +1,5 @@
+---
+title: Fixes performance bar looking for a key in a undefined prop
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/51925-expose-has_trace-in-job-api.yml b/changelogs/unreleased/51925-expose-has_trace-in-job-api.yml
new file mode 100644
index 00000000000..eade86d97ac
--- /dev/null
+++ b/changelogs/unreleased/51925-expose-has_trace-in-job-api.yml
@@ -0,0 +1,5 @@
+---
+title: Expose has_trace in job API
+merge_request: 21950
+author:
+type: other
diff --git a/changelogs/unreleased/dm-fix-assign-unassign-quick-actions.yml b/changelogs/unreleased/dm-fix-assign-unassign-quick-actions.yml
new file mode 100644
index 00000000000..bfc1ff7b8af
--- /dev/null
+++ b/changelogs/unreleased/dm-fix-assign-unassign-quick-actions.yml
@@ -0,0 +1,6 @@
+---
+title: Don't ignore first action when assign and unassign quick actions are used in
+ the same comment
+merge_request: 21749
+author:
+type: fixed
diff --git a/changelogs/unreleased/feature-add-public-email-to-users-api.yml b/changelogs/unreleased/feature-add-public-email-to-users-api.yml
new file mode 100644
index 00000000000..1f5d3fb113d
--- /dev/null
+++ b/changelogs/unreleased/feature-add-public-email-to-users-api.yml
@@ -0,0 +1,5 @@
+---
+title: Adds the user's public_email attribute to the API
+merge_request: 21909
+author: Alexis Reigel
+type: added
diff --git a/changelogs/unreleased/feature-runner-type-filter-for-admin-view.yml b/changelogs/unreleased/feature-runner-type-filter-for-admin-view.yml
new file mode 100644
index 00000000000..e7812cd0944
--- /dev/null
+++ b/changelogs/unreleased/feature-runner-type-filter-for-admin-view.yml
@@ -0,0 +1,5 @@
+---
+title: Add a type filter to the admin runners view
+merge_request: 19649
+author: Alexis Reigel
+type: added
diff --git a/changelogs/unreleased/jivl-fix-monitoring-dashboard-resizing-navbar.yml b/changelogs/unreleased/jivl-fix-monitoring-dashboard-resizing-navbar.yml
new file mode 100644
index 00000000000..c21301bf6b3
--- /dev/null
+++ b/changelogs/unreleased/jivl-fix-monitoring-dashboard-resizing-navbar.yml
@@ -0,0 +1,5 @@
+---
+title: Fix resizing of monitoring dashboard
+merge_request: 21730
+author:
+type: fixed
diff --git a/changelogs/unreleased/rename-squash-before-merge-vue-component.yml b/changelogs/unreleased/rename-squash-before-merge-vue-component.yml
new file mode 100644
index 00000000000..66eeeb225dd
--- /dev/null
+++ b/changelogs/unreleased/rename-squash-before-merge-vue-component.yml
@@ -0,0 +1,5 @@
+---
+title: Rename squash before merge vue component
+merge_request: 21851
+author: George Tsiolis
+type: other
diff --git a/changelogs/unreleased/sh-guard-against-ldap-login-csrf-fail.yml b/changelogs/unreleased/sh-guard-against-ldap-login-csrf-fail.yml
new file mode 100644
index 00000000000..7233f6f3d7b
--- /dev/null
+++ b/changelogs/unreleased/sh-guard-against-ldap-login-csrf-fail.yml
@@ -0,0 +1,5 @@
+---
+title: Guard against a login attempt with invalid CSRF token
+merge_request: 21934
+author:
+type: fixed
diff --git a/changelogs/unreleased/toon-copy-meta-data-fix.yml b/changelogs/unreleased/toon-copy-meta-data-fix.yml
new file mode 100644
index 00000000000..f2f8a1a82a4
--- /dev/null
+++ b/changelogs/unreleased/toon-copy-meta-data-fix.yml
@@ -0,0 +1,5 @@
+---
+title: Allow /copy_metadata for new issues and MRs
+merge_request: 21953
+author:
+type: changed
diff --git a/changelogs/unreleased/winh-page-title-margin.yml b/changelogs/unreleased/winh-page-title-margin.yml
new file mode 100644
index 00000000000..f21f07d396b
--- /dev/null
+++ b/changelogs/unreleased/winh-page-title-margin.yml
@@ -0,0 +1,5 @@
+---
+title: Change vertical margin of page titles to 16px
+merge_request: 21888
+author:
+type: changed
diff --git a/config/initializers/warden.rb b/config/initializers/warden.rb
index 33f55069c3e..1d2bb2bce0a 100644
--- a/config/initializers/warden.rb
+++ b/config/initializers/warden.rb
@@ -31,6 +31,11 @@ Rails.application.configure do |config|
Warden::Manager.before_logout(scope: :user) do |user, auth, opts|
user ||= auth.user
+
+ # Rails CSRF protection may attempt to log out a user before that
+ # user even logs in
+ next unless user
+
activity = Gitlab::Auth::Activity.new(opts)
tracker = Gitlab::Auth::BlockedUserTracker.new(user, auth)
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index 49c6902bc42..b5e2b5448f7 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -219,7 +219,7 @@ repository from your GitLab server over HTTP.
If you are running Gitaly [as a remote
service](#running-gitaly-on-its-own-server) you may want to disable
-the local Gitaly service that runs on your Gitlab server by default.
+the local Gitaly service that runs on your GitLab server by default.
> 'Disabling Gitaly' only makes sense when you run GitLab in a custom
cluster configuration, where different services run on different
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index 98134075b94..a8cdd20581d 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -13,7 +13,7 @@ This guide talks about how to read and use these system log files.
This file lives in `/var/log/gitlab/gitlab-rails/production_json.log` for
Omnibus GitLab packages or in `/home/git/gitlab/log/production_json.log` for
-installations from source. (When Gitlab is running in an environment
+installations from source. (When GitLab is running in an environment
other than production, the corresponding logfile is shown here.)
It contains a structured log for Rails controller requests received from
@@ -42,7 +42,7 @@ In addition, the log contains the IP address from which the request originated
This file lives in `/var/log/gitlab/gitlab-rails/production.log` for
Omnibus GitLab packages or in `/home/git/gitlab/log/production.log` for
-installations from source. (When Gitlab is running in an environment
+installations from source. (When GitLab is running in an environment
other than production, the corresponding logfile is shown here.)
It contains information about all performed requests. You can see the
@@ -187,7 +187,7 @@ This file lives in `/var/log/gitlab/gitlab-shell/gitlab-shell.log` for
Omnibus GitLab packages or in `/home/git/gitlab-shell/gitlab-shell.log` for
installations from source.
-GitLab shell is used by Gitlab for executing Git commands and provide
+GitLab shell is used by GitLab for executing Git commands and provide
SSH access to Git repositories. For example:
```
diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md
index d3ce7b6f2df..29af07d12dc 100644
--- a/doc/administration/raketasks/maintenance.md
+++ b/doc/administration/raketasks/maintenance.md
@@ -58,9 +58,9 @@ Runs the following rake tasks:
It will check that each component was set up according to the installation guide and suggest fixes for issues found.
-You may also have a look at our Trouble Shooting Guides:
-- [Trouble Shooting Guide (GitLab)](http://docs.gitlab.com/ee/README.html#troubleshooting)
-- [Trouble Shooting Guide (Omnibus Gitlab)](http://docs.gitlab.com/omnibus/README.html#troubleshooting)
+You may also have a look at our Troubleshooting Guides:
+- [Troubleshooting Guide (GitLab)](http://docs.gitlab.com/ee/README.html#troubleshooting)
+- [Troubleshooting Guide (Omnibus Gitlab)](http://docs.gitlab.com/omnibus/README.html#troubleshooting)
**Omnibus Installation**
diff --git a/doc/api/commits.md b/doc/api/commits.md
index 624ed529009..5ff1e1f60e0 100644
--- a/doc/api/commits.md
+++ b/doc/api/commits.md
@@ -83,12 +83,13 @@ POST /projects/:id/repository/commits
| `actions[]` Attribute | Type | Required | Description |
| --------------------- | ---- | -------- | ----------- |
-| `action` | string | yes | The action to perform, `create`, `delete`, `move`, `update` |
+| `action` | string | yes | The action to perform, `create`, `delete`, `move`, `update`, `chmod`|
| `file_path` | string | yes | Full path to the file. Ex. `lib/class.rb` |
-| `previous_path` | string | no | Original full path to the file being moved. Ex. `lib/class1.rb` |
-| `content` | string | no | File content, required for all except `delete`. Optional for `move` |
+| `previous_path` | string | no | Original full path to the file being moved. Ex. `lib/class1.rb`. Only considered for `move` action. |
+| `content` | string | no | File content, required for all except `delete` and `chmod`. Optional for `move` |
| `encoding` | string | no | `text` or `base64`. `text` is default. |
| `last_commit_id` | string | no | Last known file commit id. Will be only considered in update, move and delete actions. |
+| `execute_filemode` | boolean | no | When `true/false` enables/disables the execute flag on the file. Only considered for `chmod` action. |
```bash
PAYLOAD=$(cat << 'JSON'
@@ -115,6 +116,11 @@ PAYLOAD=$(cat << 'JSON'
"action": "update",
"file_path": "foo/bar5",
"content": "new content"
+ },
+ {
+ "action": "chmod",
+ "file_path": "foo/bar5",
+ "execute_filemode": true
}
]
}
diff --git a/doc/api/deployments.md b/doc/api/deployments.md
index fd11894ea8f..1963b0a21de 100644
--- a/doc/api/deployments.md
+++ b/doc/api/deployments.md
@@ -46,19 +46,21 @@ Example of response
"status": "success",
"tag": false,
"user": {
+ "id": 1,
+ "name": "Administrator",
+ "username": "root",
+ "state": "active",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.dev/root",
+ "created_at": "2015-12-21T13:14:24.077Z",
"bio": null,
- "created_at": "2016-08-11T07:09:20.351Z",
- "id": 1,
- "linkedin": "",
"location": null,
- "name": "Administrator",
+ "public_email": "",
"skype": "",
- "state": "active",
+ "linkedin": "",
"twitter": "",
- "username": "root",
- "web_url": "http://localhost:3000/root",
- "website_url": ""
+ "website_url": "",
+ "organization": ""
}
},
"environment": {
@@ -103,19 +105,21 @@ Example of response
"status": "success",
"tag": false,
"user": {
+ "id": 1,
+ "name": "Administrator",
+ "username": "root",
+ "state": "active",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.dev/root",
+ "created_at": "2015-12-21T13:14:24.077Z",
"bio": null,
- "created_at": "2016-08-11T07:09:20.351Z",
- "id": 1,
- "linkedin": "",
"location": null,
- "name": "Administrator",
+ "public_email": "",
"skype": "",
- "state": "active",
+ "linkedin": "",
"twitter": "",
- "username": "root",
- "web_url": "http://localhost:3000/root",
- "website_url": ""
+ "website_url": "",
+ "organization": ""
}
},
"environment": {
@@ -188,19 +192,20 @@ Example of response
"started_at": null,
"finished_at": "2016-08-11T11:32:35.145Z",
"user": {
+ "id": 1,
"name": "Administrator",
"username": "root",
- "id": 1,
"state": "active",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "http://localhost:3000/root",
- "created_at": "2016-08-11T07:09:20.351Z",
+ "web_url": "http://gitlab.dev/root",
+ "created_at": "2015-12-21T13:14:24.077Z",
"bio": null,
"location": null,
"skype": "",
"linkedin": "",
"twitter": "",
- "website_url": ""
+ "website_url": "",
+ "organization": ""
},
"commit": {
"id": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
diff --git a/doc/api/jobs.md b/doc/api/jobs.md
index cf292adf150..aa290ff4cf8 100644
--- a/doc/api/jobs.md
+++ b/doc/api/jobs.md
@@ -53,18 +53,21 @@ Example of response
"tag": false,
"web_url": "https://example.com/foo/bar/-/jobs/6",
"user": {
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "bio": null,
- "created_at": "2015-12-21T13:14:24.077Z",
"id": 1,
- "linkedin": "",
"name": "Administrator",
- "skype": "",
- "state": "active",
- "twitter": "",
"username": "root",
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://gitlab.dev/root",
- "website_url": ""
+ "created_at": "2015-12-21T13:14:24.077Z",
+ "bio": null,
+ "location": null,
+ "public_email": "",
+ "skype": "",
+ "linkedin": "",
+ "twitter": "",
+ "website_url": "",
+ "organization": ""
}
},
{
@@ -109,18 +112,21 @@ Example of response
"tag": false,
"web_url": "https://example.com/foo/bar/-/jobs/7",
"user": {
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "bio": null,
- "created_at": "2015-12-21T13:14:24.077Z",
"id": 1,
- "linkedin": "",
"name": "Administrator",
- "skype": "",
- "state": "active",
- "twitter": "",
"username": "root",
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://gitlab.dev/root",
- "website_url": ""
+ "created_at": "2015-12-21T13:14:24.077Z",
+ "bio": null,
+ "location": null,
+ "public_email": "",
+ "skype": "",
+ "linkedin": "",
+ "twitter": "",
+ "website_url": "",
+ "organization": ""
}
}
]
@@ -180,18 +186,21 @@ Example of response
"tag": false,
"web_url": "https://example.com/foo/bar/-/jobs/6",
"user": {
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "bio": null,
- "created_at": "2015-12-21T13:14:24.077Z",
"id": 1,
- "linkedin": "",
"name": "Administrator",
- "skype": "",
- "state": "active",
- "twitter": "",
"username": "root",
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://gitlab.dev/root",
- "website_url": ""
+ "created_at": "2015-12-21T13:14:24.077Z",
+ "bio": null,
+ "location": null,
+ "public_email": "",
+ "skype": "",
+ "linkedin": "",
+ "twitter": "",
+ "website_url": "",
+ "organization": ""
}
},
{
@@ -236,18 +245,21 @@ Example of response
"tag": false,
"web_url": "https://example.com/foo/bar/-/jobs/7",
"user": {
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "bio": null,
- "created_at": "2015-12-21T13:14:24.077Z",
"id": 1,
- "linkedin": "",
"name": "Administrator",
- "skype": "",
- "state": "active",
- "twitter": "",
"username": "root",
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://gitlab.dev/root",
- "website_url": ""
+ "created_at": "2015-12-21T13:14:24.077Z",
+ "bio": null,
+ "location": null,
+ "public_email": "",
+ "skype": "",
+ "linkedin": "",
+ "twitter": "",
+ "website_url": "",
+ "organization": ""
}
}
]
@@ -305,18 +317,21 @@ Example of response
"tag": false,
"web_url": "https://example.com/foo/bar/-/jobs/8",
"user": {
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "bio": null,
- "created_at": "2015-12-21T13:14:24.077Z",
"id": 1,
- "linkedin": "",
"name": "Administrator",
- "skype": "",
- "state": "active",
- "twitter": "",
"username": "root",
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://gitlab.dev/root",
- "website_url": ""
+ "created_at": "2015-12-21T13:14:24.077Z",
+ "bio": null,
+ "location": null,
+ "public_email": "",
+ "skype": "",
+ "linkedin": "",
+ "twitter": "",
+ "website_url": "",
+ "organization": ""
}
}
```
diff --git a/doc/api/keys.md b/doc/api/keys.md
index ddcf7830621..06b31a67d6a 100644
--- a/doc/api/keys.md
+++ b/doc/api/keys.md
@@ -27,10 +27,16 @@ Parameters:
"web_url": "http://localhost:3000/john_smith",
"created_at": "2015-09-03T07:24:01.670Z",
"bio": null,
+ "location": null,
+ "public_email": "john@example.com",
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
+ "organization": null,
+ "last_sign_in_at": "2015-09-03T07:24:01.670Z",
+ "confirmed_at": "2015-09-03T07:24:01.670Z",
+ "last_activity_on": "2015-09-03",
"email": "john@example.com",
"theme_id": 2,
"color_scheme_id": 1,
@@ -40,6 +46,8 @@ Parameters:
"can_create_group": true,
"can_create_project": true,
"two_factor_enabled": false
+ "external": false,
+ "private_profile": null
}
}
```
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 9e6676d62fe..4c099581f07 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -437,6 +437,11 @@ Parameters:
"id" : 1,
"name" : "Administrator"
},
+ "diff_refs": {
+ "base_sha": "1111111111111111111111111111111111111111",
+ "head_sha": "2222222222222222222222222222222222222222",
+ "start_sha": "3333333333333333333333333333333333333333"
+ },
"diverged_commits_count": 2
}
```
diff --git a/doc/api/oauth2.md b/doc/api/oauth2.md
index 77bb7a55d8c..8a1e6b52092 100644
--- a/doc/api/oauth2.md
+++ b/doc/api/oauth2.md
@@ -1,6 +1,6 @@
# GitLab as an OAuth2 provider
-This document covers using the [OAuth2](https://oauth.net/2/) protocol to allow other services access Gitlab resources on user's behalf.
+This document covers using the [OAuth2](https://oauth.net/2/) protocol to allow other services access GitLab resources on user's behalf.
If you want GitLab to be an OAuth authentication service provider to sign into other services please see the [OAuth2 provider](../integration/oauth_provider.md)
documentation.
@@ -9,7 +9,7 @@ This functionality is based on [doorkeeper gem](https://github.com/doorkeeper-ge
## Supported OAuth2 Flows
-Gitlab currently supports following authorization flows:
+GitLab currently supports following authorization flows:
* *Web Application Flow* - Most secure and common type of flow, designed for the applications with secure server-side.
* *Implicit Flow* - This flow is designed for user-agent only apps (e.g. single page web application running on GitLab Pages).
@@ -76,7 +76,7 @@ Check [RFC spec](http://tools.ietf.org/html/rfc6749#section-4.2) for a detailed
Unlike the web flow, the client receives an `access token` immediately as a result of the authorization request. The flow does not use client secret
or authorization code because all of the application code and storage is easily accessible, therefore __secrets__ can leak easily.
->**Important:** Avoid using this flow for applications that store data outside of the Gitlab instance. If you do, make sure to verify `application id`
+>**Important:** Avoid using this flow for applications that store data outside of the GitLab instance. If you do, make sure to verify `application id`
associated with access token before granting access to the data
(see [/oauth/token/info](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples#get----oauthtokeninfo)).
@@ -146,7 +146,7 @@ access_token = client.password.get_token('user@example.com', 'secret')
puts access_token.token
```
-## Access Gitlab API with `access token`
+## Access GitLab API with `access token`
The `access token` allows you to make requests to the API on a behalf of a user. You can pass the token either as GET parameter
```
diff --git a/doc/api/runners.md b/doc/api/runners.md
index 66476e7db64..0bcbd0aebf0 100644
--- a/doc/api/runners.md
+++ b/doc/api/runners.md
@@ -11,11 +11,15 @@ Get a list of specific runners available to the user.
```
GET /runners
GET /runners?scope=active
+GET /runners?type=project_type
+GET /runners?status=active
```
| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
-| `scope` | string | no | The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided |
+| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided |
+| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
+| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/runners"
@@ -56,11 +60,15 @@ is restricted to users with `admin` privileges.
```
GET /runners/all
GET /runners/all?scope=online
+GET /runners/all?type=project_type
+GET /runners/all?status=active
```
| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
-| `scope` | string | no | The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online`, `offline`; showing all runners if none provided |
+| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online`, `offline`; showing all runners if none provided |
+| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
+| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/runners/all"
@@ -286,6 +294,7 @@ Example response:
"created_at": "2017-11-16T18:38:46.000Z",
"bio": null,
"location": null,
+ "public_email": "",
"skype": "",
"linkedin": "",
"twitter": "",
@@ -336,11 +345,17 @@ usage is enabled in the project's settings.
```
GET /projects/:id/runners
+GET /projects/:id/runners?scope=active
+GET /projects/:id/runners?type=project_type
+GET /projects/:id/runners?status=active
```
-| Attribute | Type | Required | Description |
-|-----------|---------|----------|---------------------|
+| Attribute | Type | Required | Description |
+|-----------|----------------|----------|---------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided |
+| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
+| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/9/runners"
diff --git a/doc/api/users.md b/doc/api/users.md
index b0ae455a025..762ea53edee 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -199,6 +199,7 @@ Parameters:
"created_at": "2012-05-23T08:00:58Z",
"bio": null,
"location": null,
+ "public_email": "john@example.com",
"skype": "",
"linkedin": "",
"twitter": "",
@@ -230,6 +231,7 @@ Parameters:
"is_admin": false,
"bio": null,
"location": null,
+ "public_email": "john@example.com",
"skype": "",
"linkedin": "",
"twitter": "",
@@ -367,6 +369,7 @@ GET /user
"created_at": "2012-05-23T08:00:58Z",
"bio": null,
"location": null,
+ "public_email": "john@example.com",
"skype": "",
"linkedin": "",
"twitter": "",
@@ -415,6 +418,7 @@ GET /user
"is_admin": false,
"bio": null,
"location": null,
+ "public_email": "john@example.com",
"skype": "",
"linkedin": "",
"twitter": "",
diff --git a/doc/ci/README.md b/doc/ci/README.md
index d782d64e971..dba1f38abe2 100644
--- a/doc/ci/README.md
+++ b/doc/ci/README.md
@@ -132,5 +132,3 @@ your whole GitLab instance as well as in each project.
- [New CI job permissions model](../user/project/new_ci_build_permissions_model.md)
Read about what changed in GitLab 8.12 and how that affects your jobs.
There's a new way to access your Git submodules and LFS objects in jobs.
-
-[gitlab-ci-templates]: https://gitlab.com/gitlab-org/gitlab-ci-yml
diff --git a/doc/ci/caching/index.md b/doc/ci/caching/index.md
index b41101695f6..f479dc74d1f 100644
--- a/doc/ci/caching/index.md
+++ b/doc/ci/caching/index.md
@@ -178,8 +178,8 @@ runs of jobs for things like dependencies and commonly used libraries
so they don't have to be re-fetched from the public internet.
NOTE: **Note:**
-For more examples, check the [GitLab CI Yml](https://gitlab.com/gitlab-org/gitlab-ci-yml)
-project.
+For more examples, check out our [GitLab CI/CD
+templates](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates).
### Caching Nodejs dependencies
@@ -190,7 +190,7 @@ Nodejs modules are installed in `node_modules/` and are cached per-branch:
```yaml
#
-# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Nodejs.gitlab-ci.yml
+# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
#
image: node:latest
@@ -217,7 +217,7 @@ are cached per-branch:
```yaml
#
-# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/PHP.gitlab-ci.yml
+# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
#
image: php:7.2
@@ -246,7 +246,7 @@ pip's cache is defined under `.cache/pip/` and both are cached per-branch:
```yaml
#
-# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Python.gitlab-ci.yml
+# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml
#
image: python:latest
@@ -286,7 +286,7 @@ jobs inherit it. Gems are installed in `vendor/ruby/` and are cached per-branch:
```yaml
#
-# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Ruby.gitlab-ci.yml
+# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
#
image: ruby:2.5
diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md
index aa997d15b64..0b64c8caba7 100644
--- a/doc/ci/docker/using_docker_build.md
+++ b/doc/ci/docker/using_docker_build.md
@@ -314,8 +314,8 @@ build:
stage: build
script:
- docker pull $CONTAINER_IMAGE:latest || true
- - docker build --cache-from $CONTAINER_IMAGE:latest --tag $CONTAINER_IMAGE:$CI_BUILD_REF --tag $CONTAINER_IMAGE:latest .
- - docker push $CONTAINER_IMAGE:$CI_BUILD_REF
+ - docker build --cache-from $CONTAINER_IMAGE:latest --tag $CONTAINER_IMAGE:$CI_COMMIT_SHA --tag $CONTAINER_IMAGE:latest .
+ - docker push $CONTAINER_IMAGE:$CI_COMMIT_SHA
- docker push $CONTAINER_IMAGE:latest
```
diff --git a/doc/ci/examples/README.md b/doc/ci/examples/README.md
index 8eb96ae10b2..fdf09d332a5 100644
--- a/doc/ci/examples/README.md
+++ b/doc/ci/examples/README.md
@@ -4,8 +4,8 @@ comments: false
# GitLab CI/CD Examples
-A collection of `.gitlab-ci.yml` template files is maintained at the [GitLab CI/CD YAML project][gitlab-ci-templates]. When you create a new file via the UI,
-GitLab will give you the option to choose one of the templates existent on this project.
+A collection of [`.gitlab-ci.yml` template files][gitlab-ci-templates] is maintained in GitLab. When you create a new file via the UI,
+GitLab will give you the option to choose one of these templates.
If your favorite programming language or framework are missing we would love your
help by sending a merge request with a new `.gitlab-ci.yml` to this project.
@@ -87,4 +87,4 @@ language users and GitLab by sending a merge request with a guide for that langu
You may want to apply for the [GitLab Community Writers Program](https://about.gitlab.com/community-writers/)
to get paid for writing complete articles for GitLab.
-[gitlab-ci-templates]: https://gitlab.com/gitlab-org/gitlab-ci-yml
+[gitlab-ci-templates]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates
diff --git a/doc/ci/examples/browser_performance.md b/doc/ci/examples/browser_performance.md
index 0dab07a7f80..d36e97ebfd3 100644
--- a/doc/ci/examples/browser_performance.md
+++ b/doc/ci/examples/browser_performance.md
@@ -110,4 +110,4 @@ performance:
- sitespeed-results/
```
-A complete example can be found in our [Auto DevOps CI YML](https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml).
+A complete example can be found in our [Auto DevOps CI YML](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml).
diff --git a/doc/ci/examples/test-scala-application.md b/doc/ci/examples/test-scala-application.md
index 09d83c33f95..b3961ec91f3 100644
--- a/doc/ci/examples/test-scala-application.md
+++ b/doc/ci/examples/test-scala-application.md
@@ -1,6 +1,6 @@
# Test and deploy to Heroku a Scala application
-This example demonstrates the integration of Gitlab CI with Scala
+This example demonstrates the integration of GitLab CI with Scala
applications using SBT. Checkout the example
[project](https://gitlab.com/gitlab-examples/scala-sbt) and
[build status](https://gitlab.com/gitlab-examples/scala-sbt/builds).
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 31a065bc196..e38628b288b 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -188,7 +188,7 @@ used for time of the job. The configuration of this feature is covered in
## `before_script` and `after_script`
-> Introduced in GitLab 8.7 and requires Gitlab Runner v1.2
+> Introduced in GitLab 8.7 and requires GitLab Runner v1.2
`before_script` is used to define the command that should be run before all
jobs, including deploy jobs, but after the restoration of [artifacts](#artifacts).
@@ -492,6 +492,7 @@ osx job:
`allow_failure` is used when you want to allow a job to fail without impacting
the rest of the CI suite. Failed jobs don't contribute to the commit status.
+The default value is `false`.
When enabled and the job fails, the pipeline will be successful/green for all
intents and purposes, but a "CI build passed with warnings" message will be
diff --git a/doc/development/contributing/community_roles.md b/doc/development/contributing/community_roles.md
new file mode 100644
index 00000000000..c508969f7f4
--- /dev/null
+++ b/doc/development/contributing/community_roles.md
@@ -0,0 +1,12 @@
+### Community members & roles
+
+GitLab community members and their privileges/responsibilities.
+
+| Roles | Responsibilities | Requirements |
+|-------|------------------|--------------|
+| Maintainer | Accepts merge requests on several GitLab projects | Added to the [team page](https://about.gitlab.com/team/). An expert on code reviews and knows the product/code base |
+| Reviewer | Performs code reviews on MRs | Added to the [team page](https://about.gitlab.com/team/) |
+| Developer |Has access to GitLab internal infrastructure & issues (e.g. HR-related) | GitLab employee or a Core Team member (with an NDA) |
+| Contributor | Can make contributions to all GitLab public projects | Have a GitLab.com account |
+
+[List of current reviewers/maintainers](https://about.gitlab.com/handbook/engineering/projects/#gitlab-ce) \ No newline at end of file
diff --git a/doc/development/contributing/design.md b/doc/development/contributing/design.md
index 45fe8c26591..be7891061f9 100644
--- a/doc/development/contributing/design.md
+++ b/doc/development/contributing/design.md
@@ -1,13 +1,4 @@
-<!-- START doctoc generated TOC please keep comment here to allow auto update -->
-<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
-**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
-
-- [Implement design & UI elements](#implement-design--ui-elements)
-- [Style guides](#style-guides)
-
-<!-- END doctoc generated TOC please keep comment here to allow auto update -->
-
-## Implement design & UI elements
+# Implement design & UI elements
For guidance on UX implementation at GitLab, please refer to our [Design System](https://design.gitlab.com/).
@@ -34,27 +25,27 @@ In order to complete a product discovery issue in a release, you must complete t
## Style guides
-1. [Ruby](https://github.com/bbatsov/ruby-style-guide).
- Important sections include [Source Code Layout][rss-source] and
- [Naming][rss-naming]. Use:
- - multi-line method chaining style **Option A**: dot `.` on the second line
- - string literal quoting style **Option A**: single quoted by default
-1. [Rails](https://github.com/bbatsov/rails-style-guide)
-1. [Newlines styleguide][newlines-styleguide]
-1. [Testing][testing]
-1. [JavaScript styleguide][js-styleguide]
-1. [SCSS styleguide][scss-styleguide]
-1. [Shell commands](../shell_commands.md) created by GitLab
- contributors to enhance security
-1. [Database Migrations](../migration_style_guide.md)
-1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
-1. [Documentation styleguide](https://docs.gitlab.com/ee/development/documentation/styleguide.html)
-1. Interface text should be written subjectively instead of objectively. It
- should be the GitLab core team addressing a person. It should be written in
- present time and never use past tense (has been/was). For example instead
- of _prohibited this user from being saved due to the following errors:_ the
- text should be _sorry, we could not create your account because:_
-1. Code should be written in [US English][us-english]
+1. [Ruby](https://github.com/bbatsov/ruby-style-guide).
+ Important sections include [Source Code Layout][rss-source] and
+ [Naming][rss-naming]. Use:
+ - multi-line method chaining style **Option A**: dot `.` on the second line
+ - string literal quoting style **Option A**: single quoted by default
+1. [Rails](https://github.com/bbatsov/rails-style-guide)
+1. [Newlines styleguide][newlines-styleguide]
+1. [Testing][testing]
+1. [JavaScript styleguide][js-styleguide]
+1. [SCSS styleguide][scss-styleguide]
+1. [Shell commands](../shell_commands.md) created by GitLab
+ contributors to enhance security
+1. [Database Migrations](../migration_style_guide.md)
+1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
+1. [Documentation styleguide](https://docs.gitlab.com/ee/development/documentation/styleguide.html)
+1. Interface text should be written subjectively instead of objectively. It
+ should be the GitLab core team addressing a person. It should be written in
+ present time and never use past tense (has been/was). For example instead
+ of _prohibited this user from being saved due to the following errors:_ the
+ text should be _sorry, we could not create your account because:_
+1. Code should be written in [US English][us-english]
This is also the style used by linting tools such as
[RuboCop](https://github.com/bbatsov/rubocop),
diff --git a/doc/development/contributing/index.md b/doc/development/contributing/index.md
index eac7cb44c40..f4486ae3549 100644
--- a/doc/development/contributing/index.md
+++ b/doc/development/contributing/index.md
@@ -1,41 +1,4 @@
-<!-- START doctoc generated TOC please keep comment here to allow auto update -->
-<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
-**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
-
-- [Contribute to GitLab](#contribute-to-gitlab)
-- [Security vulnerability disclosure](#security-vulnerability-disclosure)
-- [Code of conduct](#code-of-conduct)
-- [Closing policy for issues and merge requests](#closing-policy-for-issues-and-merge-requests)
-- [Helping others](#helping-others)
-- [I want to contribute!](#i-want-to-contribute)
-- [Contribution Flow](#contribution-flow)
-- [Workflow labels](#workflow-labels)
- - [Type labels](#type-labels)
- - [Subject labels](#subject-labels)
- - [Team labels](#team-labels)
- - [Milestone labels](#milestone-labels)
- - [Bug Priority labels](#bug-priority-labels)
- - [Bug Severity labels](#bug-severity-labels)
- - [Severity impact guidance](#severity-impact-guidance)
- - [Label for community contributors](#label-for-community-contributors)
-- [Implement design & UI elements](#implement-design--ui-elements)
-- [Issue tracker](#issue-tracker)
- - [Issue triaging](#issue-triaging)
- - [Feature proposals](#feature-proposals)
- - [Issue tracker guidelines](#issue-tracker-guidelines)
- - [Issue weight](#issue-weight)
- - [Regression issues](#regression-issues)
- - [Technical and UX debt](#technical-and-ux-debt)
- - [Stewardship](#stewardship)
-- [Merge requests](#merge-requests)
- - [Merge request guidelines](#merge-request-guidelines)
- - [Contribution acceptance criteria](#contribution-acceptance-criteria)
-- [Definition of done](#definition-of-done)
-- [Style guides](#style-guides)
-
-<!-- END doctoc generated TOC please keep comment here to allow auto update -->
-
-## Contribute to GitLab
+# Contribute to GitLab
For a first-time step-by-step guide to the contribution process, see
["Contributing to GitLab"](https://about.gitlab.com/contributing/).
diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md
index edd2d063458..7ba8e3dce95 100644
--- a/doc/development/contributing/issue_workflow.md
+++ b/doc/development/contributing/issue_workflow.md
@@ -1,27 +1,4 @@
-<!-- START doctoc generated TOC please keep comment here to allow auto update -->
-<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
-**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
-
-- [Workflow labels](#workflow-labels)
- - [Type labels](#type-labels)
- - [Subject labels](#subject-labels)
- - [Team labels](#team-labels)
- - [Release Scoping labels](#release-scoping-labels)
- - [Priority labels](#priority-labels)
- - [Severity labels](#severity-labels)
- - [Severity impact guidance](#severity-impact-guidance)
- - [Label for community contributors](#label-for-community-contributors)
- - [Issue triaging](#issue-triaging)
- - [Feature proposals](#feature-proposals)
- - [Issue tracker guidelines](#issue-tracker-guidelines)
- - [Issue weight](#issue-weight)
- - [Regression issues](#regression-issues)
- - [Technical and UX debt](#technical-and-ux-debt)
- - [Stewardship](#stewardship)
-
-<!-- END doctoc generated TOC please keep comment here to allow auto update -->
-
-## Workflow labels
+# Workflow labels
To allow for asynchronous issue handling, we use [milestones][milestones-page]
and [labels][labels-page]. Leads and product managers handle most of the
@@ -45,7 +22,7 @@ labels, you can _always_ add the team and type, and often also the subject.
[milestones-page]: https://gitlab.com/gitlab-org/gitlab-ce/milestones
[labels-page]: https://gitlab.com/gitlab-org/gitlab-ce/labels
-### Type labels
+## Type labels
Type labels are very important. They define what kind of issue this is. Every
issue should have one or more.
@@ -61,7 +38,7 @@ already reserved for subject labels).
The descriptions on the [labels page][labels-page] explain what falls under each type label.
-### Subject labels
+## Subject labels
Subject labels are labels that define what area or feature of GitLab this issue
hits. They are not always necessary, but very convenient.
@@ -75,7 +52,7 @@ issue is labeled with a subject label corresponding to your expertise.
Subject labels are always all-lowercase.
-### Team labels
+## Team labels
Team labels specify what team is responsible for this issue.
Assigning a team label makes sure issues get the attention of the appropriate
@@ -107,7 +84,7 @@ indicate if an issue needs backend work, frontend work, or both.
Team labels are always capitalized so that they show up as the first label for
any issue.
-### Release Scoping labels
+## Release Scoping labels
Release Scoping labels help us clearly communicate expectations of the work for the
release. There are three levels of Release Scoping labels:
@@ -138,7 +115,7 @@ This label documents the planned timeline & urgency which is used to measure aga
| ~P3 | Medium Priority | Within the next 3 releases (approx one quarter) |
| ~P4 | Low Priority | Anything outside the next 3 releases (approx beyond one quarter) |
-### Severity labels
+## Severity labels
Severity labels help us clearly communicate the impact of a ~bug on users.
@@ -149,7 +126,7 @@ Severity labels help us clearly communicate the impact of a ~bug on users.
| ~S3 | Major Severity | Broken Feature, workaround acceptable | Can create merge requests only from the Merge Requests page, not through the Issue. |
| ~S4 | Low Severity | Functionality inconvenience or cosmetic issue | Label colors are incorrect / not being displayed. |
-#### Severity impact guidance
+### Severity impact guidance
Severity levels can be applied further depending on the facet of the impact; e.g. Affected customers, GitLab.com availability, performance and etc. The below is a guideline.
@@ -160,7 +137,7 @@ Severity levels can be applied further depending on the facet of the impact; e.g
| ~S3 | A few users or a single paid customer affected | Limited impact on important portions of GitLab.com | Degradation is likely to occur in the near future |
| ~S4 | No paid users/customer affected, or expected to in the near future | Minor impact on on GitLab.com | Degradation _may_ occur but it's not likely |
-### Label for community contributors
+## Label for community contributors
Issues that are beneficial to our users, 'nice to haves', that we currently do
not have the capacity for or want to give the priority to, are labeled as
@@ -210,8 +187,7 @@ any potential community contributor to @-mention per above.
[up-for-grabs]: https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name=Accepting+Merge+Requests&scope=all&sort=weight_asc&state=opened
[firt-timers]: https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=Accepting+Merge+Requests&scope=all&sort=upvotes_desc&state=opened&weight=1
-
-### Issue triaging
+## Issue triaging
Our issue triage policies are [described in our handbook]. You are very welcome
to help the GitLab team triage issues. We also organize [issue bash events] once
@@ -233,7 +209,7 @@ project.
[scheduled pipeline]: https://gitlab.com/gitlab-org/quality/triage-ops/pipeline_schedules/10512/edit
[quality/triage-ops]: https://gitlab.com/gitlab-org/quality/triage-ops
-### Feature proposals
+## Feature proposals
To create a feature proposal for CE, open an issue on the
[issue tracker of CE][ce-tracker].
@@ -259,7 +235,7 @@ need to ask one of the [core team] members to add the label, if you do not have
If you want to create something yourself, consider opening an issue first to
discuss whether it is interesting to include this in GitLab.
-### Issue tracker guidelines
+## Issue tracker guidelines
**[Search the issue tracker][ce-tracker]** for similar entries before
submitting your own, there's a good chance somebody else had the same issue or
@@ -271,7 +247,7 @@ The text in the parenthesis is there to help you with what to include. Omit it
when submitting the actual issue. You can copy-paste it and then edit as you
see fit.
-### Issue weight
+## Issue weight
Issue weight allows us to get an idea of the amount of work required to solve
one or multiple issues. This makes it possible to schedule work more accurately.
@@ -293,7 +269,7 @@ is probably 1, adding a new Git Hook maybe 4 or 5, big features 7-9.
issues or chunks. You can simply not set the weight of a parent issue and set
weights to children issues.
-### Regression issues
+## Regression issues
Every monthly release has a corresponding issue on the CE issue tracker to keep
track of functionality broken by that release and any fixes that need to be
@@ -313,7 +289,7 @@ addressed.
[8.3 Regressions]: https://gitlab.com/gitlab-org/gitlab-ce/issues/4127
[update the notes]: https://gitlab.com/gitlab-org/release-tools/blob/master/doc/pro-tips.md#update-the-regression-issue
-### Technical and UX debt
+## Technical and UX debt
In order to track things that can be improved in GitLab's codebase,
we use the ~"technical debt" label in [GitLab's issue tracker][ce-tracker].
@@ -337,7 +313,7 @@ for a release by the appropriate person.
Make sure to mention the merge request that the ~"technical debt" issue or
~"UX debt" issue is associated with in the description of the issue.
-### Stewardship
+## Stewardship
For issues related to the open source stewardship of GitLab,
there is the ~"stewardship" label.
diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md
index 685287f7a0c..a286e74908c 100644
--- a/doc/development/contributing/merge_request_workflow.md
+++ b/doc/development/contributing/merge_request_workflow.md
@@ -1,15 +1,4 @@
-<!-- START doctoc generated TOC please keep comment here to allow auto update -->
-<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
-**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
-
-- [Merge requests](#merge-requests)
- - [Merge request guidelines](#merge-request-guidelines)
- - [Contribution acceptance criteria](#contribution-acceptance-criteria)
-- [Definition of done](#definition-of-done)
-
-<!-- END doctoc generated TOC please keep comment here to allow auto update -->
-
-## Merge requests
+# Merge requests
We welcome merge requests with fixes and improvements to GitLab code, tests,
and/or documentation. The issues that are specifically suitable for
@@ -36,7 +25,7 @@ some potentially easy issues.
To start with GitLab development download the [GitLab Development Kit][gdk] and
see the [Development section](../README.md) for some guidelines.
-### Merge request guidelines
+## Merge request guidelines
If you can, please submit a merge request with the fix or improvements
including tests. If you don't know how to fix the issue but can write a test
@@ -114,7 +103,7 @@ Please ensure that your merge request meets the contribution acceptance criteria
When having your code reviewed and when reviewing merge requests please take the
[code review guidelines](../code_review.md) into account.
-### Contribution acceptance criteria
+## Contribution acceptance criteria
1. The change is as small as possible
1. Include proper tests and make all tests pass (unless it contains a test
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index d6ae4cb39f0..2db78e4a365 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -43,13 +43,13 @@ how to structure GitLab docs.
Currently GitLab docs use Redcarpet as [markdown](../../user/markdown.md) engine, but there's an [open discussion](https://gitlab.com/gitlab-com/gitlab-docs/issues/50) for implementing Kramdown in the near future.
-All the docs follow the [documentation style guidelines](styleguide.md).
+All the docs follow the [documentation style guidelines](styleguide.md). See [Linting](#linting) for help to follow the guidelines.
## Documentation directory structure
The documentation is structured based on the GitLab UI structure itself,
separated by [`user`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/user),
-[`administrator`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/administration), and [`contributor`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/development).
+[`administrator`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/administration), and [`contributor`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/development).
In order to have a [solid site structure](https://searchengineland.com/seo-benefits-developing-solid-site-structure-277456) for our documentation,
all docs should be linked. Every new document should be cross-linked to its related documentation, and linked from its topic-related index, when existent.
@@ -223,6 +223,108 @@ redirect_from: 'https://docs.gitlab.com/my-old-location/README.html'
Note: it is necessary to include the file name in the `redirect_from` URL,
even if it's `index.html` or `README.html`.
+## Linting
+
+To help adhere to the [documentation style guidelines](styleguide.md), and to improve the content
+ added to documentation, consider locally installing and running documentation linters. This will
+ help you catch common issues before raising merge requests for review of documentation.
+
+The following are some suggested linters you can install locally and sample configuration:
+
+- `proselint`
+- `markdownlint`
+
+NOTE: **Note:**
+This list does not limit what other linters you can add to your local documentation writing
+ toolchain.
+
+### `proselint`
+
+`proselint` checks for common problems with English prose. It provides a
+ [plethora of checks](http://proselint.com/checks/) that are helpful for technical writing.
+
+`proselint` can be used [on the command line](http://proselint.com/utility/), either on a single
+ Markdown file or on all Markdown files in a project. For example, to run `proselint` on all
+ documentation in the [`gitlab-ce` project](https://gitlab.com/gitlab-org/gitlab-ce), run the
+ following commands from within the `gitlab-ce` project:
+
+```sh
+cd doc
+proselint **/*.md
+```
+
+`proselint` can also be run from within editors using plugins. For example, the following plugins
+ are available:
+
+- [Sublime Text](https://packagecontrol.io/packages/SublimeLinter-contrib-proselint)
+- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=PatrykPeszko.vscode-proselint)
+- [Others](https://github.com/amperser/proselint#plugins-for-other-software)
+
+#### Sample `proselint` configuration
+
+All of the checks are good to use. However, excluding the `typography.symbols` checks might reduce
+ noise. The following sample `proselint` configuration disables the `typography.symbols` checks:
+
+```json
+{
+ "checks": {
+ "typography.symbols": false
+ }
+}
+```
+
+A file with `proselint` configuration must be placed in a
+ [valid location](https://github.com/amperser/proselint#checks). For example, `~/.config/proselint/config`.
+
+### `markdownlint`
+
+`markdownlint` checks that certain rules ([example](https://github.com/DavidAnson/markdownlint/blob/master/README.md#rules--aliases))
+ are followed for Markdown syntax. Our [style guidelines](styleguide.md) elaborate on which choices
+ must be made when selecting Markdown syntax for GitLab documentation and this tool helps
+ catch deviations from those guidelines.
+
+`markdownlint` can be used [on the command line](https://github.com/igorshubovych/markdownlint-cli#markdownlint-cli--),
+ either on a single Markdown file or on all Markdown files in a project. For example, to run
+ `markdownlint` on all documentation in the [`gitlab-ce` project](https://gitlab.com/gitlab-org/gitlab-ce),
+ run the following commands from within the `gitlab-ce` project:
+
+```sh
+cd doc
+markdownlint **/*.md
+```
+
+`markdownlint` can also be run from within editors using plugins. For example, the following plugins
+ are available:
+
+- [Sublime Text](https://packagecontrol.io/packages/SublimeLinter-contrib-markdownlint)
+- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
+- [Others](https://github.com/DavidAnson/markdownlint#related)
+
+#### Sample `markdownlint` configuration
+
+The following sample `markdownlint` configuration modifies the available default rules to:
+
+- Adhere to the [style guidelines](styleguide.md).
+- Apply conventions found in the GitLab documentation.
+
+```json
+{
+ "default": true,
+ "header-style": { "style": "atx" },
+ "ul-style": { "style": "dash" },
+ "line-length": false,
+ "no-trailing-punctuation": false,
+ "ol-prefix": { "style": "one" },
+ "blanks-around-fences": false,
+ "hr-style": { "style": "---" },
+ "fenced-code-language": false
+}
+```
+
+For [`markdownlint`](https://gitahub.com/DavidAnson/markdownlint/), this configuration must be
+ placed in a [valid location](https://github.com/igorshubovych/markdownlint-cli#configuration). For
+ example, `~/.markdownlintrc`.
+
## Testing
We treat documentation as code, thus have implemented some testing.
@@ -278,7 +380,6 @@ for GitLab Team members.
- Label the MR `Documentation`
- Assign the correct milestone (see note below)
-
NOTE: **Note:**
If the release version you want to add the documentation to has already been
frozen or released, use the label `Pick into X.Y` to get it merged into
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index d4f7bb7ae74..c43f91278de 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -10,6 +10,8 @@ GitLab documentation. Check the
Check the GitLab handbook for the [writing styles guidelines](https://about.gitlab.com/handbook/communication/#writing-style-guidelines).
+For help adhering to the guidelines, see [Linting](index.md#linting).
+
## Files
- [Directory structure](index.md#location-and-naming-documents): place the docs
diff --git a/doc/development/gitaly.md b/doc/development/gitaly.md
index 4f9ca1920a5..f4784c19359 100644
--- a/doc/development/gitaly.md
+++ b/doc/development/gitaly.md
@@ -9,7 +9,7 @@ status of the migration.
## Developing new Git features
-Starting with Gitlab 10.8, all new Git features should be developed in
+Starting with GitLab 10.8, all new Git features should be developed in
Gitaly.
> This is a new process that is not clearly defined yet. If you want
diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md
index 38ea2f1dde1..25c6371f3d7 100644
--- a/doc/development/testing_guide/review_apps.md
+++ b/doc/development/testing_guide/review_apps.md
@@ -74,7 +74,7 @@ on making Review Apps automatically deployed by each pipeline, both in CE and EE
[review-apps-ee]: https://console.cloud.google.com/kubernetes/clusters/details/us-central1-b/review-apps-ee?project=gitlab-review-apps
[review-apps.sh]: https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/review_apps/review-apps.sh
[automated_cleanup.rb]: https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/review_apps/automated_cleanup.rb
-[Auto-DevOps.gitlab-ci.yml]: https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml
+[Auto-DevOps.gitlab-ci.yml]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
[gitlab-k8s-integration]: https://docs.gitlab.com/ee/user/project/clusters/index.html
---
diff --git a/doc/development/ux_guide/users.md b/doc/development/ux_guide/users.md
index 08f393132e8..f9c395b2dff 100644
--- a/doc/development/ux_guide/users.md
+++ b/doc/development/ux_guide/users.md
@@ -242,7 +242,7 @@ Some of GitLab EE's features are too basic, in particular, issues boards which d
James and his team use CI quite heavily for several projects. Whilst they've welcomed improvements to the builds and pipelines interface, they still have some difficulty following build process on the different tabs under Pipelines. Some confusion has arisen from not knowing where to find different pieces of information or how to get to the next stages logs from the current stage's log output screen. They feel more intuitive linking and flow may alleviate the problem. Generally, they feel GitLab's navigation needs to reviewed and optimized.
#### Permissions
->"There is no granular control over user or group permissions. The permissions for a project are too tightly coupled to the permissions for Gitlab CI/build pipelines."
+>"There is no granular control over user or group permissions. The permissions for a project are too tightly coupled to the permissions for GitLab CI/build pipelines."
### Goals
@@ -290,7 +290,7 @@ JavaScript and SQL
Web development, mobile development, UX, open source, gaming, and travel.
### Motivations
-Karolina has been using GitLab.com for around a year. She roughly spends 8 hours every week programming, of that, 2 hours is spent contributing to open source projects. Karolina contributes to open source projects to gain programming experience and to give back to the community. She likes GitLab.com for its free private repositories and range of features which provide her with everything she needs for her personal projects. Karolina is also a massive fan of GitLab's values and the fact that it isn't a "behemoth of a company". She explains that "displaying every single thing (doc, culture, assumptions, development...) in the open gives me greater confidence to choose Gitlab personally and to recommend it at work." She's also an avid reader of GitLab's blog.
+Karolina has been using GitLab.com for around a year. She roughly spends 8 hours every week programming, of that, 2 hours is spent contributing to open source projects. Karolina contributes to open source projects to gain programming experience and to give back to the community. She likes GitLab.com for its free private repositories and range of features which provide her with everything she needs for her personal projects. Karolina is also a massive fan of GitLab's values and the fact that it isn't a "behemoth of a company". She explains that "displaying every single thing (doc, culture, assumptions, development...) in the open gives me greater confidence to choose GitLab personally and to recommend it at work." She's also an avid reader of GitLab's blog.
Karolina works for a software development company which currently hires around 500 people. Karolina would love to use GitLab at work but the company has used GitHub Enterprise for a number of years. She describes management at her company as "old fashioned" and explains that it's "less of a technical issue and more of a cultural issue" to convince upper management to move to GitLab. Karolina is also relatively new to the company so she's apprehensive about pushing too hard to change version control platforms.
diff --git a/doc/gitlab-basics/add-image.md b/doc/gitlab-basics/add-image.md
index 1a44123aa81..17c210c43e0 100644
--- a/doc/gitlab-basics/add-image.md
+++ b/doc/gitlab-basics/add-image.md
@@ -5,7 +5,7 @@ in Windows, or...), put the image file into the GitLab project. You can find the
project as a regular folder in your files.
Go to your [shell](command-line-commands.md), and move into the folder of your
-Gitlab project. This usually means running the following command until you get
+GitLab project. This usually means running the following command until you get
to the desired destination:
```
diff --git a/doc/install/kubernetes/gitlab_chart.md b/doc/install/kubernetes/gitlab_chart.md
index 09f5aaa04a7..6d1bc4aedc4 100644
--- a/doc/install/kubernetes/gitlab_chart.md
+++ b/doc/install/kubernetes/gitlab_chart.md
@@ -93,7 +93,7 @@ You can access the GitLab instance by visiting the domain name beginning with
above, the URL would be `https://gitlab.example.com`.
If you manually created the secret for initial root password, you
-can use that to sign in as `root` user. If not, Gitlab automatically
+can use that to sign in as `root` user. If not, GitLab automatically
created a random password for `root` user. This can be extracted by the
following command (replace `<name>` by name of the release - which is `gitlab`
if you used the command above):
diff --git a/doc/integration/github.md b/doc/integration/github.md
index 680712f9e01..7a83b8e4b35 100644
--- a/doc/integration/github.md
+++ b/doc/integration/github.md
@@ -19,7 +19,7 @@ GitHub will generate an application ID and secret key for you to use.
- Application name: This can be anything. Consider something like `<Organization>'s GitLab` or `<Your Name>'s GitLab` or something else descriptive.
- Homepage URL: The URL to your GitLab installation. 'https://gitlab.company.com'
- Application description: Fill this in if you wish.
- - Authorization callback URL is 'http(s)://${YOUR_DOMAIN}'. Please make sure the port is included if your Gitlab instance is not configured on default port.
+ - Authorization callback URL is 'http(s)://${YOUR_DOMAIN}'. Please make sure the port is included if your GitLab instance is not configured on default port.
1. Select "Register application".
1. You should now see a Client ID and Client Secret near the top right of the page (see screenshot).
@@ -154,7 +154,7 @@ You will also need to disable Git SSL verification on the server hosting GitLab.
$ git config --global http.sslVerify false
```
-For the changes to take effect, [reconfigure Gitlab] if you installed
+For the changes to take effect, [reconfigure GitLab] if you installed
via Omnibus, or [restart GitLab] if you installed from source.
[reconfigure GitLab]: ../administration/restart_gitlab.md#omnibus-gitlab-reconfigure
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 98fce7efb0b..2b9cce6539f 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -591,10 +591,11 @@ This procedure assumes that:
First make sure your backup tar file is in the backup directory described in the
`gitlab.rb` configuration `gitlab_rails['backup_path']`. The default is
-`/var/opt/gitlab/backups`.
+`/var/opt/gitlab/backups`. It needs to be owned by the `git` user.
```shell
sudo cp 11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar /var/opt/gitlab/backups/
+sudo chown git.git /var/opt/gitlab/backups/11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar
```
Stop the processes that are connected to the database. Leave the rest of GitLab
diff --git a/doc/security/user_email_confirmation.md b/doc/security/user_email_confirmation.md
index 48c79cd4769..8c07e11dcb1 100644
--- a/doc/security/user_email_confirmation.md
+++ b/doc/security/user_email_confirmation.md
@@ -1,6 +1,6 @@
# User email confirmation at sign-up
-Gitlab admin can enable email confirmation on sign-up, if you want to confirm all
+GitLab admin can enable email confirmation on sign-up, if you want to confirm all
user emails before they are able to sign-in.
In the Admin area under **Settings** (`/admin/application_settings`), go to section
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index 421b5411a07..681dc8ff20d 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -145,7 +145,7 @@ When using Auto DevOps, you may want to deploy different environments to
different Kubernetes clusters. This is possible due to the 1:1 connection that
[exists between them](../../user/project/clusters/index.md#multiple-kubernetes-clusters).
-In the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml)
+In the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml)
(used behind the scenes by Auto DevOps), there are currently 3 defined environment names that you need to know:
- `review/` (every environment starting with `review/`)
@@ -832,6 +832,6 @@ curl --data "value=true" --header "PRIVATE-TOKEN: personal_access_token" https:/
[review-app]: ../../ci/review_apps/index.md
[container-registry]: ../../user/project/container_registry.md
[postgresql]: https://www.postgresql.org/
-[Auto DevOps template]: https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml
+[Auto DevOps template]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
[ee]: https://about.gitlab.com/pricing/
[ce-19507]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19507
diff --git a/doc/university/README.md b/doc/university/README.md
index 203981b85ec..5edf92b3b09 100644
--- a/doc/university/README.md
+++ b/doc/university/README.md
@@ -11,7 +11,7 @@ and [Blog Articles](https://about.gitlab.com/blog/).
Would you like to contribute to GitLab University? Then please take a look at our contribution [process](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/PROCESS.md) for more information.
-## Gitlab University Curriculum
+## GitLab University Curriculum
The curriculum is composed of GitLab videos, screencasts, presentations, projects and external GitLab content hosted on other services and has been organized into the following sections.
diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md
index 0b9395914f9..e14e716a5eb 100644
--- a/doc/user/gitlab_com/index.md
+++ b/doc/user/gitlab_com/index.md
@@ -221,7 +221,7 @@ and the following environment variables:
## Cron jobs
-Periodically executed jobs by Sidekiq, to self-heal Gitlab, do external
+Periodically executed jobs by Sidekiq, to self-heal GitLab, do external
synchronizations, run scheduled pipelines, etc.:
| Setting | GitLab.com | Default |
diff --git a/doc/user/index.md b/doc/user/index.md
index 649c0b664a5..08995032cb1 100644
--- a/doc/user/index.md
+++ b/doc/user/index.md
@@ -96,7 +96,7 @@ directly from GitLab. No third-party integrations needed.
- [GitLab Auto Deploy](../ci/autodeploy/index.md): Deploy your application out-of-the-box with GitLab Auto Deploy.
- [Review Apps](../ci/review_apps/index.md): Live-preview the changes introduced by a merge request with Review Apps.
- [GitLab Pages](project/pages/index.md): Publish your static site directly from
-GitLab with Gitlab Pages. You can build, test, and deploy any Static Site Generator with Pages.
+GitLab with GitLab Pages. You can build, test, and deploy any Static Site Generator with Pages.
- [GitLab Container Registry](project/container_registry.md): Build and deploy Docker
images with Container Registry.
diff --git a/doc/user/project/container_registry.md b/doc/user/project/container_registry.md
index 82cafcf432a..2709ebb6f05 100644
--- a/doc/user/project/container_registry.md
+++ b/doc/user/project/container_registry.md
@@ -27,7 +27,7 @@ to enable it.
1. First, ask your system administrator to enable GitLab Container Registry
following the [administration documentation](../../administration/container_registry.md).
If you are using GitLab.com, this is enabled by default so you can start using
- the Registry immediately. Currently there is a soft (10GB) size restriction for
+ the Registry immediately. Currently there is a soft (10GB) size restriction for
registry on GitLab.com, as part of the [repository size limit](repository/index.html#repository-size).
1. Go to your [project's General settings](settings/index.md#sharing-and-permissions)
and enable the **Container Registry** feature on your project. For new
@@ -216,7 +216,7 @@ needs to trust the mitmproxy SSL certificates for this to work.
The following installation instructions assume you are running Ubuntu:
-1. Install mitmproxy (see http://docs.mitmproxy.org/en/stable/install.html)
+1. [Install mitmproxy](https://docs.mitmproxy.org/stable/overview-installation/).
1. Run `mitmproxy --port 9000` to generate its certificates.
Enter <kbd>CTRL</kbd>-<kbd>C</kbd> to quit.
1. Install the certificate from `~/.mitmproxy` to your system:
@@ -293,4 +293,4 @@ Once the right permissions were set, the error will go away.
[docker-docs]: https://docs.docker.com/engine/userguide/intro/
[pat]: ../profile/personal_access_tokens.md
[pdt]: ../project/deploy_tokens/index.md
-[reconfigure]: ../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure \ No newline at end of file
+[reconfigure]: ../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index e22f8e976be..5a38f5d8aed 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -1170,7 +1170,7 @@ You can trigger the webhook manually. Sample data from the project will be used.
## Troubleshoot webhooks
-Gitlab stores each perform of the webhook.
+GitLab stores each perform of the webhook.
You can find records for last 2 days in "Recent Deliveries" section on the edit page of each webhook.
![Recent deliveries](img/webhook_logs.png)
diff --git a/doc/user/project/pipelines/job_artifacts.md b/doc/user/project/pipelines/job_artifacts.md
index fc3970e2014..a8b47558c99 100644
--- a/doc/user/project/pipelines/job_artifacts.md
+++ b/doc/user/project/pipelines/job_artifacts.md
@@ -151,6 +151,20 @@ For example:
https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/master/browse?job=coverage
```
+There is also a URL to specific files, including html files that
+are shown in [GitLab Pages](../../../administration/pages/index.md):
+
+```
+https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/file/<path>?job=<job_name>
+```
+
+For example, when a job `coverage` creates the artifact `htmlcov/index.html`,
+you can access it at:
+
+```
+https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/master/file/htmlcov/index.html?job=coverage
+```
+
The latest builds are also exposed in the UI in various places. Specifically,
look for the download button in:
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index fcaff35459e..5aeffc8fb99 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -73,7 +73,26 @@ module API
params do
requires :branch, type: String, desc: 'Name of the branch to commit into. To create a new branch, also provide `start_branch`.', allow_blank: false
requires :commit_message, type: String, desc: 'Commit message'
- requires :actions, type: Array[Hash], desc: 'Actions to perform in commit'
+ requires :actions, type: Array, desc: 'Actions to perform in commit' do
+ requires :action, type: String, desc: 'The action to perform, `create`, `delete`, `move`, `update`, `chmod`', values: %w[create update move delete chmod].freeze
+ requires :file_path, type: String, desc: 'Full path to the file. Ex. `lib/class.rb`'
+ given action: ->(action) { action == 'move' } do
+ requires :previous_path, type: String, desc: 'Original full path to the file being moved. Ex. `lib/class1.rb`'
+ end
+ given action: ->(action) { %w[create move].include? action } do
+ optional :content, type: String, desc: 'File content'
+ end
+ given action: ->(action) { action == 'update' } do
+ requires :content, type: String, desc: 'File content'
+ end
+ optional :encoding, type: String, desc: '`text` or `base64`', default: 'text', values: %w[text base64]
+ given action: ->(action) { %w[update move delete].include? action } do
+ optional :last_commit_id, type: String, desc: 'Last known file commit id'
+ end
+ given action: ->(action) { action == 'chmod' } do
+ requires :execute_filemode, type: Boolean, desc: 'When `true/false` enables/disables the execute flag on the file.'
+ end
+ end
optional :start_branch, type: String, desc: 'Name of the branch to start the new commit from'
optional :author_email, type: String, desc: 'Author email for commit'
optional :author_name, type: String, desc: 'Author name for commit'
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 0fec3dc3dc4..12c4340c1ba 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -53,7 +53,7 @@ module API
class User < UserBasic
expose :created_at, if: ->(user, opts) { Ability.allowed?(opts[:current_user], :read_user_profile, user) }
- expose :bio, :location, :skype, :linkedin, :twitter, :website_url, :organization
+ expose :bio, :location, :public_email, :skype, :linkedin, :twitter, :website_url, :organization
end
class UserActivity < Grape::Entity
diff --git a/lib/api/runners.rb b/lib/api/runners.rb
index 30abd0b63e9..9bcdfc8cb15 100644
--- a/lib/api/runners.rb
+++ b/lib/api/runners.rb
@@ -11,10 +11,18 @@ module API
params do
optional :scope, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
desc: 'The scope of specific runners to show'
+ optional :type, type: String, values: Ci::Runner::AVAILABLE_TYPES,
+ desc: 'The type of the runners to show'
+ optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
+ desc: 'The status of the runners to show'
use :pagination
end
get do
- runners = filter_runners(current_user.ci_owned_runners, params[:scope], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
+ runners = current_user.ci_owned_runners
+ runners = filter_runners(runners, params[:scope], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
+ runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES)
+ runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
+
present paginate(runners), with: Entities::Runner
end
@@ -24,11 +32,20 @@ module API
params do
optional :scope, type: String, values: Ci::Runner::AVAILABLE_SCOPES,
desc: 'The scope of specific runners to show'
+ optional :type, type: String, values: Ci::Runner::AVAILABLE_TYPES,
+ desc: 'The type of the runners to show'
+ optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
+ desc: 'The status of the runners to show'
use :pagination
end
get 'all' do
authenticated_as_admin!
- runners = filter_runners(Ci::Runner.all, params[:scope])
+
+ runners = Ci::Runner.all
+ runners = filter_runners(runners, params[:scope])
+ runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES)
+ runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
+
present paginate(runners), with: Entities::Runner
end
@@ -116,10 +133,18 @@ module API
params do
optional :scope, type: String, values: Ci::Runner::AVAILABLE_SCOPES,
desc: 'The scope of specific runners to show'
+ optional :type, type: String, values: Ci::Runner::AVAILABLE_TYPES,
+ desc: 'The type of the runners to show'
+ optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
+ desc: 'The status of the runners to show'
use :pagination
end
get ':id/runners' do
- runners = filter_runners(Ci::Runner.owned_or_instance_wide(user_project.id), params[:scope])
+ runners = Ci::Runner.owned_or_instance_wide(user_project.id)
+ runners = filter_runners(runners, params[:scope])
+ runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES)
+ runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
+
present paginate(runners), with: Entities::Runner
end
diff --git a/lib/event_filter.rb b/lib/event_filter.rb
index f756a211a12..24fdcd6fbb1 100644
--- a/lib/event_filter.rb
+++ b/lib/event_filter.rb
@@ -1,76 +1,42 @@
-class EventFilter
- attr_accessor :params
-
- class << self
- def all
- 'all'
- end
-
- def push
- 'push'
- end
-
- def merged
- 'merged'
- end
+# frozen_string_literal: true
- def issue
- 'issue'
- end
-
- def comments
- 'comments'
- end
-
- def team
- 'team'
- end
+class EventFilter
+ attr_accessor :filter
+
+ ALL = 'all'
+ PUSH = 'push'
+ MERGED = 'merged'
+ ISSUE = 'issue'
+ COMMENTS = 'comments'
+ TEAM = 'team'
+ FILTERS = [ALL, PUSH, MERGED, ISSUE, COMMENTS, TEAM].freeze
+
+ def initialize(filter)
+ # Split using comma to maintain backward compatibility Ex/ "filter1,filter2"
+ filter = filter.to_s.split(',')[0].to_s
+ @filter = FILTERS.include?(filter) ? filter : ALL
end
- def initialize(params)
- @params = if params
- params.dup
- else
- [] # EventFilter.default_filter
- end
+ def active?(key)
+ filter == key.to_s
end
# rubocop: disable CodeReuse/ActiveRecord
def apply_filter(events)
- return events if params.blank? || params == EventFilter.all
-
- case params
- when EventFilter.push
+ case filter
+ when PUSH
events.where(action: Event::PUSHED)
- when EventFilter.merged
+ when MERGED
events.where(action: Event::MERGED)
- when EventFilter.comments
+ when COMMENTS
events.where(action: Event::COMMENTED)
- when EventFilter.team
+ when TEAM
events.where(action: [Event::JOINED, Event::LEFT, Event::EXPIRED])
- when EventFilter.issue
+ when ISSUE
events.where(action: [Event::CREATED, Event::UPDATED, Event::CLOSED, Event::REOPENED])
- end
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- def options(key)
- filter = params.dup
-
- if filter.include? key
- filter.delete key
else
- filter << key
- end
-
- filter
- end
-
- def active?(key)
- if params.present?
- params.include? key
- else
- key == EventFilter.all
+ events
end
end
+ # rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/vendor/gitlab-ci-yml/Android.gitlab-ci.yml b/lib/gitlab/ci/templates/Android.gitlab-ci.yml
index 5f9d54ff574..5f9d54ff574 100644
--- a/vendor/gitlab-ci-yml/Android.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Android.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
index 33ae9c6ad7e..d8fcdfac266 100644
--- a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
@@ -49,7 +49,7 @@ variables:
POSTGRES_DB: $CI_ENVIRONMENT_SLUG
KUBERNETES_VERSION: 1.8.6
- HELM_VERSION: 2.6.1
+ HELM_VERSION: 2.10.0
DOCKER_DRIVER: overlay2
@@ -122,6 +122,9 @@ license_management:
paths: [gl-license-management-report.json]
only:
- branches
+ only:
+ variables:
+ - $GITLAB_FEATURES =~ /\blicense_management\b/
except:
variables:
- $LICENSE_MANAGEMENT_DISABLED
@@ -484,15 +487,11 @@ rollout 100%:
}
function license_management() {
- if echo $GITLAB_FEATURES |grep license_management > /dev/null ; then
- # Extract "MAJOR.MINOR" from CI_SERVER_VERSION and generate "MAJOR-MINOR-stable"
- LICENSE_MANAGEMENT_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
+ # Extract "MAJOR.MINOR" from CI_SERVER_VERSION and generate "MAJOR-MINOR-stable"
+ LICENSE_MANAGEMENT_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run --volume "$PWD:/code" \
- "registry.gitlab.com/gitlab-org/security-products/license-management:$LICENSE_MANAGEMENT_VERSION" analyze /code
- else
- echo "License management is not available in your subscription"
- fi
+ docker run --volume "$PWD:/code" \
+ "registry.gitlab.com/gitlab-org/security-products/license-management:$LICENSE_MANAGEMENT_VERSION" analyze /code
}
function sast() {
@@ -605,7 +604,6 @@ rollout 100%:
--set postgresql.postgresPassword="$POSTGRES_PASSWORD" \
--set postgresql.postgresDatabase="$POSTGRES_DB" \
--namespace="$KUBE_NAMESPACE" \
- --version="$CI_PIPELINE_ID-$CI_JOB_ID" \
"$name" \
chart/
diff --git a/vendor/gitlab-ci-yml/Bash.gitlab-ci.yml b/lib/gitlab/ci/templates/Bash.gitlab-ci.yml
index 2d218b2e164..2d218b2e164 100644
--- a/vendor/gitlab-ci-yml/Bash.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Bash.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/C++.gitlab-ci.yml b/lib/gitlab/ci/templates/C++.gitlab-ci.yml
index c83c49d8c95..c83c49d8c95 100644
--- a/vendor/gitlab-ci-yml/C++.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/C++.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Chef.gitlab-ci.yml b/lib/gitlab/ci/templates/Chef.gitlab-ci.yml
index 4d5b6484d6e..4d5b6484d6e 100644
--- a/vendor/gitlab-ci-yml/Chef.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Chef.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Clojure.gitlab-ci.yml b/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml
index f066285b1ad..f066285b1ad 100644
--- a/vendor/gitlab-ci-yml/Clojure.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Crystal.gitlab-ci.yml b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml
index 36386a19fdc..36386a19fdc 100644
--- a/vendor/gitlab-ci-yml/Crystal.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Django.gitlab-ci.yml b/lib/gitlab/ci/templates/Django.gitlab-ci.yml
index 57afcbbe8b5..57afcbbe8b5 100644
--- a/vendor/gitlab-ci-yml/Django.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Django.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml b/lib/gitlab/ci/templates/Docker.gitlab-ci.yml
index eeefadaa019..eeefadaa019 100644
--- a/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Docker.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml
index cf9c731637c..cf9c731637c 100644
--- a/vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Go.gitlab-ci.yml b/lib/gitlab/ci/templates/Go.gitlab-ci.yml
index d572d7a1edc..d572d7a1edc 100644
--- a/vendor/gitlab-ci-yml/Go.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Go.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Gradle.gitlab-ci.yml b/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml
index 48d98dddfad..48d98dddfad 100644
--- a/vendor/gitlab-ci-yml/Gradle.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Grails.gitlab-ci.yml b/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
index 7fc698d50cf..7fc698d50cf 100644
--- a/vendor/gitlab-ci-yml/Grails.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Julia.gitlab-ci.yml b/lib/gitlab/ci/templates/Julia.gitlab-ci.yml
index 140cb4635f3..04c21b4725d 100644
--- a/vendor/gitlab-ci-yml/Julia.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Julia.gitlab-ci.yml
@@ -1,4 +1,4 @@
-# An example .gitlab-ci.yml file to test (and optionally report the coverage
+# This is an example .gitlab-ci.yml file to test (and optionally report the coverage
# results of) your [Julia][1] packages. Please refer to the [documentation][2]
# for more information about package development in Julia.
#
@@ -6,7 +6,7 @@
# whatever name you have given to your package.
#
# [1]: http://julialang.org/
-# [2]: http://julia.readthedocs.org/
+# [2]: https://docs.julialang.org/en/v1/manual/documentation/index.html
# Below is the template to run your tests in Julia
.test_template: &test_definition
@@ -18,25 +18,30 @@
script:
# Let's run the tests. Substitute `coverage = false` below, if you do not
# want coverage results.
- - /opt/julia/bin/julia -e 'Pkg.clone(pwd()); Pkg.test("MyPackage",
- coverage = true)'
+ - julia -e 'using Pkg; Pkg.clone(pwd()); Pkg.build("MyPackage"); Pkg.test("MyPackage"; coverage = true)'
# Comment out below if you do not want coverage results.
- - /opt/julia/bin/julia -e 'Pkg.add("Coverage"); cd(Pkg.dir("MyPackage"));
+ - julia -e 'using Pkg; Pkg.add("Coverage");
+ import MyPackage; cd(joinpath(dirname(pathof(MyPackage)), ".."));
using Coverage; cl, tl = get_summary(process_folder());
println("(", cl/tl*100, "%) covered")'
# Name a test and select an appropriate image.
-test:0.4.6:
- image: julialang/julia:v0.4.6
+# images comes from Docker hub
+test:0.7:
+ image: julia:0.7
+ <<: *test_definition
+
+test:1.0:
+ image: julia:1.0
<<: *test_definition
# Maybe you would like to test your package against the development branch:
-test:0.5.0-dev:
- image: julialang/julia:v0.5.0-dev
- # ... allowing for failures, since we are testing against the development
- # branch:
- allow_failure: true
- <<: *test_definition
+# test:1.1-dev (not sure there is such an image in docker, so not tested yet):
+# image: julia:v1.1-dev
+# # ... allowing for failures, since we are testing against the development
+# # branch:
+# allow_failure: true
+# <<: *test_definition
# REMARK: Do not forget to enable the coverage feature for your project, if you
# are using code coverage reporting above. This can be done by
@@ -44,11 +49,28 @@ test:0.5.0-dev:
# - Navigating to the `CI/CD Pipelines` settings of your project,
# - Copying and pasting the default `Simplecov` regex example provided, i.e.,
# `\(\d+.\d+\%\) covered` in the `test coverage parsing` textfield.
-#
-# WARNING: This template is using the `julialang/julia` images from [Docker
+
+# Example documentation deployment
+pages:
+ image: julia:0.7
+ stage: deploy
+ script:
+ - apt-get update -qq && apt-get install -y git # needed by Documenter
+ - julia -e 'using Pkg; Pkg.clone(pwd()); Pkg.build("MyPackage");' # rebuild Julia (can be put somewhere else I'm sure
+ - julia -e 'using Pkg; import MyPackage; Pkg.add("Documenter")' # install Documenter
+ - julia --color=yes docs/make.jl # make documentation
+ - mv docs/build public # move to the directory picked up by Gitlab pages
+ artifacts:
+ paths:
+ - public
+ only:
+ - master
+
+
+# WARNING: This template is using the `julia` images from [Docker
# Hub][3]. One can use custom Julia images and/or the official ones found
# in the same place. However, care must be taken to correctly locate the binary
# file (`/opt/julia/bin/julia` above), which is usually given on the image's
# description page.
#
-# [3]: http://hub.docker.com/
+# [3]: https://hub.docker.com/_/julia/
diff --git a/vendor/gitlab-ci-yml/LaTeX.gitlab-ci.yml b/lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml
index a4aed36889e..a4aed36889e 100644
--- a/vendor/gitlab-ci-yml/LaTeX.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Laravel.gitlab-ci.yml b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml
index 0688f77a1d2..0688f77a1d2 100644
--- a/vendor/gitlab-ci-yml/Laravel.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml b/lib/gitlab/ci/templates/Maven.gitlab-ci.yml
index d61ff239e13..d61ff239e13 100644
--- a/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Maven.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Mono.gitlab-ci.yml b/lib/gitlab/ci/templates/Mono.gitlab-ci.yml
index 3585f99760f..3585f99760f 100644
--- a/vendor/gitlab-ci-yml/Mono.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Mono.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
index 41de1458582..41de1458582 100644
--- a/vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/OpenShift.gitlab-ci.yml b/lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml
index 290b9997084..290b9997084 100644
--- a/vendor/gitlab-ci-yml/OpenShift.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/PHP.gitlab-ci.yml b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
index 33f44ee9222..33f44ee9222 100644
--- a/vendor/gitlab-ci-yml/PHP.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Packer.gitlab-ci.yml b/lib/gitlab/ci/templates/Packer.gitlab-ci.yml
index fa296057c72..fa296057c72 100644
--- a/vendor/gitlab-ci-yml/Packer.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Packer.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Brunch.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Brunch.gitlab-ci.yml
index 7fcc0b436b5..7fcc0b436b5 100644
--- a/vendor/gitlab-ci-yml/Pages/Brunch.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Brunch.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Doxygen.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Doxygen.gitlab-ci.yml
index 791afdd23f1..791afdd23f1 100644
--- a/vendor/gitlab-ci-yml/Pages/Doxygen.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Doxygen.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Gatsby.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml
index 9df2a4797b2..9df2a4797b2 100644
--- a/vendor/gitlab-ci-yml/Pages/Gatsby.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/HTML.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml
index 249a168aa33..249a168aa33 100644
--- a/vendor/gitlab-ci-yml/Pages/HTML.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Harp.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Harp.gitlab-ci.yml
index dd3ef149668..dd3ef149668 100644
--- a/vendor/gitlab-ci-yml/Pages/Harp.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Harp.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Hexo.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Hexo.gitlab-ci.yml
index 02d02250bbf..02d02250bbf 100644
--- a/vendor/gitlab-ci-yml/Pages/Hexo.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Hexo.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Hugo.gitlab-ci.yml
index b8cfb0f56f6..b8cfb0f56f6 100644
--- a/vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Hugo.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Hyde.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Hyde.gitlab-ci.yml
index f5b40f2b9f1..f5b40f2b9f1 100644
--- a/vendor/gitlab-ci-yml/Pages/Hyde.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Hyde.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/JBake.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/JBake.gitlab-ci.yml
index 7abfaf53e8e..7abfaf53e8e 100644
--- a/vendor/gitlab-ci-yml/Pages/JBake.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/JBake.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Jekyll.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml
index 37f50554036..37f50554036 100644
--- a/vendor/gitlab-ci-yml/Pages/Jekyll.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml
diff --git a/lib/gitlab/ci/templates/Pages/Jigsaw.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Jigsaw.gitlab-ci.yml
new file mode 100644
index 00000000000..0e5fb410a4e
--- /dev/null
+++ b/lib/gitlab/ci/templates/Pages/Jigsaw.gitlab-ci.yml
@@ -0,0 +1,42 @@
+# Jigsaw is a simple static sites generator with Laravel's Blade.
+#
+# Full project: https://github.com/tightenco/jigsaw
+
+image: php:7.2
+
+# These folders are cached between builds
+cache:
+ paths:
+ - vendor/
+ - node_modules/
+
+before_script:
+ # Update packages
+ - apt-get update -yqq
+
+ # Install dependencies
+ - apt-get install -yqq gnupg zlib1g-dev libpng-dev
+
+ # Install Node 8
+ - curl -sL https://deb.nodesource.com/setup_8.x | bash -
+ - apt-get install -yqq nodejs
+
+ # Install php extensions
+ - docker-php-ext-install zip
+
+ # Install Composer and project dependencies.
+ - curl -sS https://getcomposer.org/installer | php
+ - php composer.phar install
+
+ # Install Node dependencies.
+ - npm install
+
+pages:
+ script:
+ - npm run production
+ - mv build_production public
+ artifacts:
+ paths:
+ - public
+ only:
+ - master
diff --git a/vendor/gitlab-ci-yml/Pages/Lektor.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Lektor.gitlab-ci.yml
index c5c44a5d86c..c5c44a5d86c 100644
--- a/vendor/gitlab-ci-yml/Pages/Lektor.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Lektor.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Metalsmith.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Metalsmith.gitlab-ci.yml
index 50e8b7ccd46..50e8b7ccd46 100644
--- a/vendor/gitlab-ci-yml/Pages/Metalsmith.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Metalsmith.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Middleman.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Middleman.gitlab-ci.yml
index 9f4cc0574d6..9f4cc0574d6 100644
--- a/vendor/gitlab-ci-yml/Pages/Middleman.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Middleman.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Nanoc.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Nanoc.gitlab-ci.yml
index b469b316ba5..b469b316ba5 100644
--- a/vendor/gitlab-ci-yml/Pages/Nanoc.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Nanoc.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Octopress.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Octopress.gitlab-ci.yml
index 4762ec9acfd..4762ec9acfd 100644
--- a/vendor/gitlab-ci-yml/Pages/Octopress.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Octopress.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Pages/Pelican.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Pelican.gitlab-ci.yml
index c5f3154f587..c5f3154f587 100644
--- a/vendor/gitlab-ci-yml/Pages/Pelican.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Pelican.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Python.gitlab-ci.yml b/lib/gitlab/ci/templates/Python.gitlab-ci.yml
index 2e0589de652..2e0589de652 100644
--- a/vendor/gitlab-ci-yml/Python.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Python.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
index 93cb31f48c0..93cb31f48c0 100644
--- a/vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Rust.gitlab-ci.yml b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
index cab087c48c7..cab087c48c7 100644
--- a/vendor/gitlab-ci-yml/Rust.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Scala.gitlab-ci.yml b/lib/gitlab/ci/templates/Scala.gitlab-ci.yml
index b4208ed9d7d..b4208ed9d7d 100644
--- a/vendor/gitlab-ci-yml/Scala.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Scala.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/Swift.gitlab-ci.yml b/lib/gitlab/ci/templates/Swift.gitlab-ci.yml
index b97bfd460f2..ba8a802ba4f 100644
--- a/vendor/gitlab-ci-yml/Swift.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Swift.gitlab-ci.yml
@@ -1,5 +1,5 @@
# Lifted from: https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/
-# This file assumes an own GitLab CI runner, set up on a macOS system.
+# This file assumes an own GitLab CI runner, setup on a macOS system.
stages:
- build
- archive
diff --git a/vendor/gitlab-ci-yml/Terraform.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml
index 7160fce26a8..7160fce26a8 100644
--- a/vendor/gitlab-ci-yml/Terraform.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml
diff --git a/vendor/gitlab-ci-yml/dotNET.gitlab-ci.yml b/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml
index fc3d4ecdbba..fc3d4ecdbba 100644
--- a/vendor/gitlab-ci-yml/dotNET.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml
diff --git a/lib/gitlab/gitaly_client/operation_service.rb b/lib/gitlab/gitaly_client/operation_service.rb
index 54c78fdb680..0f148614b20 100644
--- a/lib/gitlab/gitaly_client/operation_service.rb
+++ b/lib/gitlab/gitaly_client/operation_service.rb
@@ -333,7 +333,8 @@ module Gitlab
action: action[:action].upcase.to_sym,
file_path: encode_binary(action[:file_path]),
previous_path: encode_binary(action[:previous_path]),
- base64_content: action[:encoding] == 'base64'
+ base64_content: action[:encoding] == 'base64',
+ execute_filemode: !!action[:execute_filemode]
)
rescue RangeError
raise ArgumentError, "Unknown action '#{action[:action]}'"
diff --git a/lib/gitlab/template/gitlab_ci_yml_template.rb b/lib/gitlab/template/gitlab_ci_yml_template.rb
index fd040148a1e..deae53cc61b 100644
--- a/lib/gitlab/template/gitlab_ci_yml_template.rb
+++ b/lib/gitlab/template/gitlab_ci_yml_template.rb
@@ -20,7 +20,7 @@ module Gitlab
end
def base_dir
- Rails.root.join('vendor/gitlab-ci-yml')
+ Rails.root.join('lib/gitlab/ci/templates')
end
def finder(project = nil)
diff --git a/lib/tasks/gitlab/artifacts/migrate.rake b/lib/tasks/gitlab/artifacts/migrate.rake
index bfca4bfb3f7..e7634d2ed4f 100644
--- a/lib/tasks/gitlab/artifacts/migrate.rake
+++ b/lib/tasks/gitlab/artifacts/migrate.rake
@@ -15,7 +15,7 @@ namespace :gitlab do
build.artifacts_file.migrate!(ObjectStorage::Store::REMOTE)
build.artifacts_metadata.migrate!(ObjectStorage::Store::REMOTE)
- logger.info("Transferred artifacts of #{build.id} of #{build.artifacts_size} to object storage")
+ logger.info("Transferred artifact ID #{build.id} with size #{build.artifacts_size} to object storage")
rescue => e
logger.error("Failed to transfer artifacts of #{build.id} with error: #{e.message}")
end
diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake
index ef6a32d6730..abe10f5580e 100644
--- a/lib/tasks/gitlab/update_templates.rake
+++ b/lib/tasks/gitlab/update_templates.rake
@@ -100,10 +100,6 @@ namespace :gitlab do
/(\.{1,2}|LICENSE|Global|\.gitignore)\z/
),
Template.new(
- "https://gitlab.com/gitlab-org/gitlab-ci-yml.git",
- /(\.{1,2}|LICENSE|CONTRIBUTING.md|Pages|autodeploy|\.gitlab-ci.yml)\z/
- ),
- Template.new(
"https://gitlab.com/gitlab-org/Dockerfile.git",
/(\.{1,2}|LICENSE|CONTRIBUTING.md|\.Dockerfile)\z/
)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 4d8f05a81cc..a9c5e45f9fa 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3338,9 +3338,6 @@ msgstr ""
msgid "Jobs"
msgstr ""
-msgid "Job|Are you sure you want to erase this job?"
-msgstr ""
-
msgid "Job|Browse"
msgstr ""
diff --git a/package.json b/package.json
index 94707fe3587..714bdb285fe 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
},
"dependencies": {
"@gitlab-org/gitlab-svgs": "^1.29.0",
- "@gitlab-org/gitlab-ui": "^1.7.0",
+ "@gitlab-org/gitlab-ui": "^1.7.1",
"autosize": "^4.0.0",
"axios": "^0.17.1",
"babel-core": "^6.26.3",
@@ -94,11 +94,11 @@
"underscore": "^1.9.0",
"url-loader": "^1.1.1",
"visibilityjs": "^1.2.4",
- "vue": "^2.5.16",
- "vue-loader": "^15.2.4",
+ "vue": "^2.5.17",
+ "vue-loader": "^15.4.2",
"vue-resource": "^1.5.0",
"vue-router": "^3.0.1",
- "vue-template-compiler": "^2.5.16",
+ "vue-template-compiler": "^2.5.17",
"vue-virtual-scroll-list": "^1.2.5",
"vuex": "^3.0.1",
"webpack": "^4.19.1",
diff --git a/qa/qa/page/group/show.rb b/qa/qa/page/group/show.rb
index 6747f7f10b6..74d20df76ba 100644
--- a/qa/qa/page/group/show.rb
+++ b/qa/qa/page/group/show.rb
@@ -5,14 +5,11 @@ module QA
include Page::Component::GroupsFilter
view 'app/views/groups/show.html.haml' do
- element :new_project_or_subgroup_dropdown, '.new-project-subgroup'
- element :new_project_or_subgroup_dropdown_toggle, '.dropdown-toggle'
- element :new_project_option, /%li.*data:.*value: "new-project"/
- element :new_project_button, /%input.*data:.*action: "new-project"/
- element :new_subgroup_option, /%li.*data:.*value: "new-subgroup"/
-
- # data-value and data-action get modified by JS for subgroup
- element :new_subgroup_button, /%input.*\.js-new-group-child/
+ element :new_project_or_subgroup_dropdown
+ element :new_project_or_subgroup_dropdown_toggle
+ element :new_project_option
+ element :new_subgroup_option
+ element :new_in_group_button
end
view 'app/assets/javascripts/groups/constants.js' do
@@ -24,7 +21,7 @@ module QA
end
def has_new_project_or_subgroup_dropdown?
- page.has_css?(element_selector_css(:new_project_or_subgroup_dropdown))
+ has_element?(:new_project_or_subgroup_dropdown)
end
def has_subgroup?(name)
@@ -36,31 +33,29 @@ module QA
end
def go_to_new_subgroup
- click_new('subgroup')
+ select_kind :new_subgroup_option
- find("input[data-action='new-subgroup']").click
+ click_element :new_in_group_button
end
def go_to_new_project
- click_new('project')
+ select_kind :new_project_option
- find("input[data-action='new-project']").click
+ click_element :new_in_group_button
end
private
- def click_new(kind)
- within '.new-project-subgroup' do
- css = "li[data-value='new-#{kind}']"
-
+ def select_kind(kind)
+ within_element(:new_project_or_subgroup_dropdown) do
# May need to click again because it is possible to click the button quicker than the JS is bound
wait(reload: false) do
- find('.dropdown-toggle').click
+ click_element :new_project_or_subgroup_dropdown_toggle
- page.has_css?(css)
+ has_element?(kind)
end
- find(css).click
+ click_element kind
end
end
end
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 89542b49d0e..9b3183ba328 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -108,6 +108,7 @@ module QA
end
def switch_to_register_tab
+ set_initial_password_if_present
click_element :register_tab
end
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index befb7c1809a..d9254d89541 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -19,7 +19,7 @@ module QA
element :no_fast_forward_message, 'Fast-forward merge is not possible'
end
- view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue' do
+ view 'app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue' do
element :squash_checkbox
end
diff --git a/qa/qa/page/project/activity.rb b/qa/qa/page/project/activity.rb
index 0196922c889..a0500b4d31a 100644
--- a/qa/qa/page/project/activity.rb
+++ b/qa/qa/page/project/activity.rb
@@ -3,7 +3,7 @@ module QA
module Project
class Activity < Page::Base
view 'app/views/shared/_event_filter.html.haml' do
- element :push_events, "event_filter_link EventFilter.push, _('Push events')"
+ element :push_events, "event_filter_link EventFilter::PUSH, _('Push events')"
end
def go_to_push_events
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index c82c85970dc..fd11cb31a2a 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -337,6 +337,22 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end
end
end
+
+ context 'when no trace is available' do
+ it 'has_trace is false' do
+ expect(response).to match_response_schema('job/job_details')
+ expect(json_response['has_trace']).to be false
+ end
+ end
+
+ context 'when job has trace' do
+ let(:job) { create(:ci_build, :running, :trace_live, pipeline: pipeline) }
+
+ it "has_trace is true" do
+ expect(response).to match_response_schema('job/job_details')
+ expect(json_response['has_trace']).to be true
+ end
+ end
end
context 'when requesting JSON job is triggered' do
diff --git a/spec/factories/events.rb b/spec/factories/events.rb
index 5798b81ecad..bf8411b1894 100644
--- a/spec/factories/events.rb
+++ b/spec/factories/events.rb
@@ -24,7 +24,7 @@ FactoryBot.define do
factory :push_event, class: PushEvent do
project factory: :project_empty_repo
- author factory: :user
+ author(factory: :user) { project.creator }
action Event::PUSHED
end
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index a6ab6a5696a..ed9c0ea9ac0 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -73,24 +73,72 @@ describe "Admin Runners" do
expect(page).to have_text 'No runners found'
end
+
+ it 'shows correct runner when status is selected and search term is entered' do
+ create(:ci_runner, description: 'runner-a-1', active: true)
+ create(:ci_runner, description: 'runner-a-2', active: false)
+ create(:ci_runner, description: 'runner-b-1', active: true)
+
+ visit admin_runners_path
+
+ input_filtered_search_keys('status:active')
+ expect(page).to have_content 'runner-a-1'
+ expect(page).to have_content 'runner-b-1'
+ expect(page).not_to have_content 'runner-a-2'
+
+ input_filtered_search_keys('status:active runner-a')
+ expect(page).to have_content 'runner-a-1'
+ expect(page).not_to have_content 'runner-b-1'
+ expect(page).not_to have_content 'runner-a-2'
+ end
end
- it 'shows correct runner when status is selected and search term is entered', :js do
- create(:ci_runner, description: 'runner-a-1', active: true)
- create(:ci_runner, description: 'runner-a-2', active: false)
- create(:ci_runner, description: 'runner-b-1', active: true)
+ describe 'filter by type', :js do
+ it 'shows correct runner when type matches' do
+ create :ci_runner, :project, description: 'runner-project'
+ create :ci_runner, :group, description: 'runner-group'
- visit admin_runners_path
+ visit admin_runners_path
+
+ expect(page).to have_content 'runner-project'
+ expect(page).to have_content 'runner-group'
- input_filtered_search_keys('status:active')
- expect(page).to have_content 'runner-a-1'
- expect(page).to have_content 'runner-b-1'
- expect(page).not_to have_content 'runner-a-2'
+ input_filtered_search_keys('type:project_type')
+ expect(page).to have_content 'runner-project'
+ expect(page).not_to have_content 'runner-group'
+ end
+
+ it 'shows no runner when type does not match' do
+ create :ci_runner, :project, description: 'runner-project'
+ create :ci_runner, :group, description: 'runner-group'
- input_filtered_search_keys('status:active runner-a')
- expect(page).to have_content 'runner-a-1'
- expect(page).not_to have_content 'runner-b-1'
- expect(page).not_to have_content 'runner-a-2'
+ visit admin_runners_path
+
+ input_filtered_search_keys('type:instance_type')
+
+ expect(page).not_to have_content 'runner-project'
+ expect(page).not_to have_content 'runner-group'
+
+ expect(page).to have_text 'No runners found'
+ end
+
+ it 'shows correct runner when type is selected and search term is entered' do
+ create :ci_runner, :project, description: 'runner-a-1'
+ create :ci_runner, :instance, description: 'runner-a-2'
+ create :ci_runner, :project, description: 'runner-b-1'
+
+ visit admin_runners_path
+
+ input_filtered_search_keys('type:project_type')
+ expect(page).to have_content 'runner-a-1'
+ expect(page).to have_content 'runner-b-1'
+ expect(page).not_to have_content 'runner-a-2'
+
+ input_filtered_search_keys('type:project_type runner-a')
+ expect(page).to have_content 'runner-a-1'
+ expect(page).not_to have_content 'runner-b-1'
+ expect(page).not_to have_content 'runner-a-2'
+ end
end
it 'sorts by last contact date', :js do
diff --git a/spec/features/projects/activity/user_sees_activity_spec.rb b/spec/features/projects/activity/user_sees_activity_spec.rb
index e0248911b5f..ebaa137772d 100644
--- a/spec/features/projects/activity/user_sees_activity_spec.rb
+++ b/spec/features/projects/activity/user_sees_activity_spec.rb
@@ -3,8 +3,10 @@ require 'spec_helper'
describe 'Projects > Activity > User sees activity' do
let(:project) { create(:project, :repository, :public) }
let(:user) { project.creator }
+ let(:issue) { create(:issue, project: project) }
before do
+ create(:event, :created, project: project, target: issue, author: user)
event = create(:push_event, project: project, author: user)
create(:push_event_payload,
event: event,
@@ -12,10 +14,18 @@ describe 'Projects > Activity > User sees activity' do
commit_to: '6d394385cf567f80a8fd85055db1ab4c5295806f',
ref: 'fix',
commit_count: 1)
- visit activity_project_path(project)
end
it 'shows the last push in the activity page', :js do
+ visit activity_project_path(project)
+
expect(page).to have_content "#{user.name} pushed new branch fix"
end
+
+ it 'allows to filter event with the "event_filter=issue" URL param', :js do
+ visit activity_project_path(project, event_filter: 'issue')
+
+ expect(page).not_to have_content "#{user.name} pushed new branch fix"
+ expect(page).to have_content "#{user.name} opened issue #{issue.to_reference}"
+ end
end
diff --git a/spec/finders/admin/runners_finder_spec.rb b/spec/finders/admin/runners_finder_spec.rb
index 1e9793a5e0a..0b2325cc7ca 100644
--- a/spec/finders/admin/runners_finder_spec.rb
+++ b/spec/finders/admin/runners_finder_spec.rb
@@ -29,6 +29,14 @@ describe Admin::RunnersFinder do
end
end
+ context 'filter by runner type' do
+ it 'calls the corresponding scope on Ci::Runner' do
+ expect(Ci::Runner).to receive(:project_type).and_call_original
+
+ described_class.new(params: { type_type: 'project_type' }).execute
+ end
+ end
+
context 'sort' do
context 'without sort param' do
it 'sorts by created_at' do
diff --git a/spec/fixtures/api/schemas/job/job_details.json b/spec/fixtures/api/schemas/job/job_details.json
index cd67d3e4160..70d59c6e621 100644
--- a/spec/fixtures/api/schemas/job/job_details.json
+++ b/spec/fixtures/api/schemas/job/job_details.json
@@ -3,12 +3,16 @@
{ "$ref": "job.json" }
],
"description": "An extension of job.json with more detailed information",
+ "required": [
+ "has_trace"
+ ],
"properties": {
"artifact": { "$ref": "artifact.json" },
"terminal_path": { "type": "string" },
"trigger": { "$ref": "trigger.json" },
"deployment_status": { "$ref": "deployment_status.json" },
"runner": { "$ref": "runner.json" },
- "runners": { "type": "runners.json" }
+ "runners": { "type": "runners.json" },
+ "has_trace": { "type": "boolean" }
}
}
diff --git a/spec/javascripts/jobs/components/empty_state_spec.js b/spec/javascripts/jobs/components/empty_state_spec.js
index dcc2b3d8a20..872cc1e3864 100644
--- a/spec/javascripts/jobs/components/empty_state_spec.js
+++ b/spec/javascripts/jobs/components/empty_state_spec.js
@@ -66,7 +66,7 @@ describe('Empty State', () => {
...props,
content,
action: {
- link: 'runner',
+ path: 'runner',
title: 'Check runner',
method: 'post',
},
diff --git a/spec/javascripts/jobs/components/erased_block_spec.js b/spec/javascripts/jobs/components/erased_block_spec.js
index a4ae0c7c81e..8e0433d3fb7 100644
--- a/spec/javascripts/jobs/components/erased_block_spec.js
+++ b/spec/javascripts/jobs/components/erased_block_spec.js
@@ -18,9 +18,10 @@ describe('Erased block', () => {
describe('with job erased by user', () => {
beforeEach(() => {
vm = mountComponent(Component, {
- erasedByUser: true,
- username: 'root',
- linkToUser: 'gitlab.com/root',
+ user: {
+ username: 'root',
+ web_url: 'gitlab.com/root',
+ },
erasedAt,
});
});
@@ -40,7 +41,6 @@ describe('Erased block', () => {
describe('with erased job', () => {
beforeEach(() => {
vm = mountComponent(Component, {
- erasedByUser: false,
erasedAt,
});
});
diff --git a/spec/javascripts/jobs/components/job_details_mediator_spec.js b/spec/javascripts/jobs/components/job_details_mediator_spec.js
deleted file mode 100644
index 3e2fb7bfbbb..00000000000
--- a/spec/javascripts/jobs/components/job_details_mediator_spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import JobMediator from '~/jobs/job_details_mediator';
-import job from '../mock_data';
-
-describe('JobMediator', () => {
- let mediator;
- let mock;
-
- beforeEach(() => {
- mediator = new JobMediator({ endpoint: 'jobs/40291672.json' });
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('should set defaults', () => {
- expect(mediator.store).toBeDefined();
- expect(mediator.service).toBeDefined();
- expect(mediator.options).toEqual({ endpoint: 'jobs/40291672.json' });
- expect(mediator.state.isLoading).toEqual(false);
- });
-
- describe('request and store data', () => {
- beforeEach(() => {
- mock.onGet().reply(200, job, {});
- });
-
- it('should store received data', (done) => {
- mediator.fetchJob();
- setTimeout(() => {
- expect(mediator.store.state.job).toEqual(job);
- done();
- }, 0);
- });
- });
-});
diff --git a/spec/javascripts/jobs/components/job_log_controllers_spec.js b/spec/javascripts/jobs/components/job_log_controllers_spec.js
index 416dfab8a48..099aca602c4 100644
--- a/spec/javascripts/jobs/components/job_log_controllers_spec.js
+++ b/spec/javascripts/jobs/components/job_log_controllers_spec.js
@@ -10,50 +10,51 @@ describe('Job log controllers', () => {
vm.$destroy();
});
- describe('Truncate information', () => {
+ const props = {
+ rawPath: '/raw',
+ erasePath: '/erase',
+ size: 511952,
+ isScrollTopDisabled: false,
+ isScrollBottomDisabled: false,
+ isScrollingDown: true,
+ isTraceSizeVisible: true,
+ };
- beforeEach(() => {
- vm = mountComponent(Component, {
- rawTracePath: '/raw',
- canEraseJob: true,
- size: 511952,
- canScrollToTop: true,
- canScrollToBottom: true,
+ describe('Truncate information', () => {
+ describe('with isTraceSizeVisible', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, props);
+ });
+ it('renders size information', () => {
+ expect(vm.$el.querySelector('.js-truncated-info').textContent).toContain('499.95 KiB');
});
- });
-
- it('renders size information', () => {
- expect(vm.$el.querySelector('.js-truncated-info').textContent).toContain('499.95 KiB');
- });
- it('renders link to raw trace', () => {
- expect(vm.$el.querySelector('.js-raw-link').getAttribute('href')).toEqual('/raw');
+ it('renders link to raw trace', () => {
+ expect(vm.$el.querySelector('.js-raw-link').getAttribute('href')).toEqual('/raw');
+ });
});
-
});
describe('links section', () => {
describe('with raw trace path', () => {
it('renders raw trace link', () => {
- vm = mountComponent(Component, {
- rawTracePath: '/raw',
- canEraseJob: true,
- size: 511952,
- canScrollToTop: true,
- canScrollToBottom: true,
- });
+ vm = mountComponent(Component, props);
- expect(vm.$el.querySelector('.js-raw-link-controller').getAttribute('href')).toEqual('/raw');
+ expect(vm.$el.querySelector('.js-raw-link-controller').getAttribute('href')).toEqual(
+ '/raw',
+ );
});
});
describe('without raw trace path', () => {
it('does not render raw trace link', () => {
vm = mountComponent(Component, {
- canEraseJob: true,
+ erasePath: '/erase',
size: 511952,
- canScrollToTop: true,
- canScrollToBottom: true,
+ isScrollTopDisabled: true,
+ isScrollBottomDisabled: true,
+ isScrollingDown: false,
+ isTraceSizeVisible: true,
});
expect(vm.$el.querySelector('.js-raw-link-controller')).toBeNull();
@@ -62,52 +63,23 @@ describe('Job log controllers', () => {
describe('when is erasable', () => {
beforeEach(() => {
- vm = mountComponent(Component, {
- rawTracePath: '/raw',
- canEraseJob: true,
- size: 511952,
- canScrollToTop: true,
- canScrollToBottom: true,
- });
+ vm = mountComponent(Component, props);
});
- it('renders erase job button', () => {
+ it('renders erase job link', () => {
expect(vm.$el.querySelector('.js-erase-link')).not.toBeNull();
});
-
- describe('on click', () => {
- describe('when user confirms action', () => {
- it('emits eraseJob event', () => {
- spyOn(window, 'confirm').and.returnValue(true);
- spyOn(vm, '$emit');
-
- vm.$el.querySelector('.js-erase-link').click();
-
- expect(vm.$emit).toHaveBeenCalledWith('eraseJob');
- });
- });
-
- describe('when user does not confirm action', () => {
- it('does not emit eraseJob event', () => {
- spyOn(window, 'confirm').and.returnValue(false);
- spyOn(vm, '$emit');
-
- vm.$el.querySelector('.js-erase-link').click();
-
- expect(vm.$emit).not.toHaveBeenCalledWith('eraseJob');
- });
- });
- });
});
describe('when it is not erasable', () => {
it('does not render erase button', () => {
vm = mountComponent(Component, {
- rawTracePath: '/raw',
- canEraseJob: false,
+ rawPath: '/raw',
size: 511952,
- canScrollToTop: true,
- canScrollToBottom: true,
+ isScrollTopDisabled: true,
+ isScrollBottomDisabled: true,
+ isScrollingDown: false,
+ isTraceSizeVisible: true,
});
expect(vm.$el.querySelector('.js-erase-link')).toBeNull();
@@ -119,13 +91,7 @@ describe('Job log controllers', () => {
describe('scroll top button', () => {
describe('when user can scroll top', () => {
beforeEach(() => {
- vm = mountComponent(Component, {
- rawTracePath: '/raw',
- canEraseJob: true,
- size: 511952,
- canScrollToTop: true,
- canScrollToBottom: true,
- });
+ vm = mountComponent(Component, props);
});
it('renders enabled scroll top button', () => {
@@ -143,16 +109,20 @@ describe('Job log controllers', () => {
describe('when user can not scroll top', () => {
beforeEach(() => {
vm = mountComponent(Component, {
- rawTracePath: '/raw',
- canEraseJob: true,
+ rawPath: '/raw',
+ erasePath: '/erase',
size: 511952,
- canScrollToTop: false,
- canScrollToBottom: true,
+ isScrollTopDisabled: true,
+ isScrollBottomDisabled: false,
+ isScrollingDown: false,
+ isTraceSizeVisible: true,
});
});
it('renders disabled scroll top button', () => {
- expect(vm.$el.querySelector('.js-scroll-top').getAttribute('disabled')).toEqual('disabled');
+ expect(vm.$el.querySelector('.js-scroll-top').getAttribute('disabled')).toEqual(
+ 'disabled',
+ );
});
it('does not emit scrollJobLogTop event on click', () => {
@@ -167,13 +137,7 @@ describe('Job log controllers', () => {
describe('scroll bottom button', () => {
describe('when user can scroll bottom', () => {
beforeEach(() => {
- vm = mountComponent(Component, {
- rawTracePath: '/raw',
- canEraseJob: true,
- size: 511952,
- canScrollToTop: true,
- canScrollToBottom: true,
- });
+ vm = mountComponent(Component, props);
});
it('renders enabled scroll bottom button', () => {
@@ -191,17 +155,20 @@ describe('Job log controllers', () => {
describe('when user can not scroll bottom', () => {
beforeEach(() => {
vm = mountComponent(Component, {
- rawTracePath: '/raw',
- canEraseJob: true,
+ rawPath: '/raw',
+ erasePath: '/erase',
size: 511952,
- canScrollToTop: true,
- canScrollToBottom: false,
+ isScrollTopDisabled: false,
+ isScrollBottomDisabled: true,
+ isScrollingDown: false,
+ isTraceSizeVisible: true,
});
});
it('renders disabled scroll bottom button', () => {
- expect(vm.$el.querySelector('.js-scroll-bottom').getAttribute('disabled')).toEqual('disabled');
-
+ expect(vm.$el.querySelector('.js-scroll-bottom').getAttribute('disabled')).toEqual(
+ 'disabled',
+ );
});
it('does not emit scrollJobLogBottom event on click', () => {
@@ -211,7 +178,29 @@ describe('Job log controllers', () => {
expect(vm.$emit).not.toHaveBeenCalledWith('scrollJobLogBottom');
});
});
+
+ describe('while isScrollingDown is true', () => {
+ it('renders animate class for the scroll down button', () => {
+ vm = mountComponent(Component, props);
+
+ expect(vm.$el.querySelector('.js-scroll-bottom').className).toContain('animate');
+ });
+ });
+
+ describe('while isScrollingDown is false', () => {
+ it('does not render animate class for the scroll down button', () => {
+ vm = mountComponent(Component, {
+ rawPath: '/raw',
+ erasePath: '/erase',
+ size: 511952,
+ isScrollTopDisabled: true,
+ isScrollBottomDisabled: false,
+ isScrollingDown: false,
+ isTraceSizeVisible: true,
+ });
+ expect(vm.$el.querySelector('.js-scroll-bottom').className).not.toContain('animate');
+ });
+ });
});
});
});
-
diff --git a/spec/javascripts/jobs/components/job_log_spec.js b/spec/javascripts/jobs/components/job_log_spec.js
index 6a5b375a26c..1011512360d 100644
--- a/spec/javascripts/jobs/components/job_log_spec.js
+++ b/spec/javascripts/jobs/components/job_log_spec.js
@@ -15,7 +15,7 @@ describe('Job Log', () => {
it('renders provided trace', () => {
vm = mountComponent(Component, {
trace,
- isReceivingBuildTrace: true,
+ isComplete: true,
});
expect(vm.$el.querySelector('code').textContent).toContain('Running with gitlab-runner 11.1.0 (081978aa)');
@@ -25,7 +25,7 @@ describe('Job Log', () => {
it('renders animation', () => {
vm = mountComponent(Component, {
trace,
- isReceivingBuildTrace: true,
+ isComplete: true,
});
expect(vm.$el.querySelector('.js-log-animation')).not.toBeNull();
@@ -36,7 +36,7 @@ describe('Job Log', () => {
it('does not render animation', () => {
vm = mountComponent(Component, {
trace,
- isReceivingBuildTrace: false,
+ isComplete: false,
});
expect(vm.$el.querySelector('.js-log-animation')).toBeNull();
diff --git a/spec/javascripts/jobs/components/job_store_spec.js b/spec/javascripts/jobs/components/job_store_spec.js
deleted file mode 100644
index 0dad5111b32..00000000000
--- a/spec/javascripts/jobs/components/job_store_spec.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import JobStore from '~/jobs/stores/job_store';
-import job from '../mock_data';
-
-describe('Job Store', () => {
- let store;
-
- beforeEach(() => {
- store = new JobStore();
- });
-
- it('should set defaults', () => {
- expect(store.state.job).toEqual({});
- });
-
- describe('storeJob', () => {
- it('should store empty object if none is provided', () => {
- store.storeJob();
- expect(store.state.job).toEqual({});
- });
-
- it('should store provided argument', () => {
- store.storeJob(job);
- expect(store.state.job).toEqual(job);
- });
- });
-});
diff --git a/spec/javascripts/jobs/store/mutations_spec.js b/spec/javascripts/jobs/store/mutations_spec.js
index 6900b2e5602..9ba543d32a8 100644
--- a/spec/javascripts/jobs/store/mutations_spec.js
+++ b/spec/javascripts/jobs/store/mutations_spec.js
@@ -12,6 +12,13 @@ describe('Jobs Store Mutations', () => {
stateCopy = state();
});
+ describe('SET_JOB_ENDPOINT', () => {
+ it('should set jobEndpoint', () => {
+ mutations[types.SET_JOB_ENDPOINT](stateCopy, 'job/21312321.json');
+ expect(stateCopy.jobEndpoint).toEqual('job/21312321.json');
+ });
+ });
+
describe('REQUEST_STATUS_FAVICON', () => {
it('should set fetchingStatusFavicon to true', () => {
mutations[types.REQUEST_STATUS_FAVICON](stateCopy);
diff --git a/spec/javascripts/monitoring/dashboard_spec.js b/spec/javascripts/monitoring/dashboard_spec.js
index 997163c7602..f0d53b2d8d7 100644
--- a/spec/javascripts/monitoring/dashboard_spec.js
+++ b/spec/javascripts/monitoring/dashboard_spec.js
@@ -25,7 +25,10 @@ describe('Dashboard', () => {
};
beforeEach(() => {
- setFixtures('<div class="prometheus-graphs"></div>');
+ setFixtures(`
+ <div class="prometheus-graphs"></div>
+ <div class="nav-sidebar"></div>
+ `);
DashboardComponent = Vue.extend(Dashboard);
});
@@ -127,4 +130,41 @@ describe('Dashboard', () => {
});
});
});
+
+ describe('when the window resizes', () => {
+ let mock;
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
+ jasmine.clock().install();
+ });
+
+ afterEach(() => {
+ mock.restore();
+ jasmine.clock().uninstall();
+ });
+
+ it('rerenders the dashboard when the sidebar is resized', done => {
+ const component = new DashboardComponent({
+ el: document.querySelector('.prometheus-graphs'),
+ propsData: { ...propsData, hasMetrics: true, showPanels: false },
+ });
+
+ expect(component.forceRedraw).toEqual(0);
+
+ const navSidebarEl = document.querySelector('.nav-sidebar');
+ navSidebarEl.classList.add('nav-sidebar-collapsed');
+
+ Vue.nextTick()
+ .then(() => {
+ jasmine.clock().tick(1000);
+ return Vue.nextTick();
+ })
+ .then(() => {
+ expect(component.forceRedraw).toEqual(component.elWidth);
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
});
diff --git a/spec/javascripts/monitoring/graph_spec.js b/spec/javascripts/monitoring/graph_spec.js
index 990619b4109..99180e4d303 100644
--- a/spec/javascripts/monitoring/graph_spec.js
+++ b/spec/javascripts/monitoring/graph_spec.js
@@ -1,7 +1,6 @@
import Vue from 'vue';
import Graph from '~/monitoring/components/graph.vue';
import MonitoringMixins from '~/monitoring/mixins/monitoring_mixins';
-import eventHub from '~/monitoring/event_hub';
import {
deploymentData,
convertDatesMultipleSeries,
@@ -69,23 +68,6 @@ describe('Graph', () => {
});
});
- it('sends an event to the eventhub when it has finished resizing', done => {
- const component = createComponent({
- graphData: convertedMetrics[1],
- updateAspectRatio: false,
- deploymentData,
- tagsPath,
- projectPath,
- });
- spyOn(eventHub, '$emit');
-
- component.updateAspectRatio = true;
- Vue.nextTick(() => {
- expect(eventHub.$emit).toHaveBeenCalled();
- done();
- });
- });
-
it('has a title for the y-axis and the chart legend that comes from the backend', () => {
const component = createComponent({
graphData: convertedMetrics[1],
diff --git a/spec/lib/event_filter_spec.rb b/spec/lib/event_filter_spec.rb
index 87ae6b6cf01..30016da6828 100644
--- a/spec/lib/event_filter_spec.rb
+++ b/spec/lib/event_filter_spec.rb
@@ -1,58 +1,119 @@
require 'spec_helper'
describe EventFilter do
+ describe 'FILTERS' do
+ it 'returns a definite list of filters' do
+ expect(described_class::FILTERS).to eq(%w[all push merged issue comments team])
+ end
+ end
+
+ describe '#filter' do
+ it 'returns "all" if given filter is nil' do
+ expect(described_class.new(nil).filter).to eq(described_class::ALL)
+ end
+
+ it 'returns "all" if given filter is ""' do
+ expect(described_class.new('').filter).to eq(described_class::ALL)
+ end
+
+ it 'returns "all" if given filter is "foo"' do
+ expect(described_class.new('foo').filter).to eq('all')
+ end
+ end
+
describe '#apply_filter' do
- let(:source_user) { create(:user) }
- let!(:public_project) { create(:project, :public) }
+ set(:public_project) { create(:project, :public) }
+
+ set(:push_event) { create(:push_event, project: public_project) }
+ set(:merged_event) { create(:event, :merged, project: public_project, target: public_project) }
+ set(:created_event) { create(:event, :created, project: public_project, target: public_project) }
+ set(:updated_event) { create(:event, :updated, project: public_project, target: public_project) }
+ set(:closed_event) { create(:event, :closed, project: public_project, target: public_project) }
+ set(:reopened_event) { create(:event, :reopened, project: public_project, target: public_project) }
+ set(:comments_event) { create(:event, :commented, project: public_project, target: public_project) }
+ set(:joined_event) { create(:event, :joined, project: public_project, target: public_project) }
+ set(:left_event) { create(:event, :left, project: public_project, target: public_project) }
- let!(:push_event) { create(:push_event, project: public_project, author: source_user) }
- let!(:merged_event) { create(:event, :merged, project: public_project, target: public_project, author: source_user) }
- let!(:created_event) { create(:event, :created, project: public_project, target: public_project, author: source_user) }
- let!(:updated_event) { create(:event, :updated, project: public_project, target: public_project, author: source_user) }
- let!(:closed_event) { create(:event, :closed, project: public_project, target: public_project, author: source_user) }
- let!(:reopened_event) { create(:event, :reopened, project: public_project, target: public_project, author: source_user) }
- let!(:comments_event) { create(:event, :commented, project: public_project, target: public_project, author: source_user) }
- let!(:joined_event) { create(:event, :joined, project: public_project, target: public_project, author: source_user) }
- let!(:left_event) { create(:event, :left, project: public_project, target: public_project, author: source_user) }
+ let(:filtered_events) { described_class.new(filter).apply_filter(Event.all) }
- it 'applies push filter' do
- events = described_class.new(described_class.push).apply_filter(Event.all)
- expect(events).to contain_exactly(push_event)
+ context 'with the "push" filter' do
+ let(:filter) { described_class::PUSH }
+
+ it 'filters push events only' do
+ expect(filtered_events).to contain_exactly(push_event)
+ end
end
- it 'applies merged filter' do
- events = described_class.new(described_class.merged).apply_filter(Event.all)
- expect(events).to contain_exactly(merged_event)
+ context 'with the "merged" filter' do
+ let(:filter) { described_class::MERGED }
+
+ it 'filters merged events only' do
+ expect(filtered_events).to contain_exactly(merged_event)
+ end
end
- it 'applies issue filter' do
- events = described_class.new(described_class.issue).apply_filter(Event.all)
- expect(events).to contain_exactly(created_event, updated_event, closed_event, reopened_event)
+ context 'with the "issue" filter' do
+ let(:filter) { described_class::ISSUE }
+
+ it 'filters issue events only' do
+ expect(filtered_events).to contain_exactly(created_event, updated_event, closed_event, reopened_event)
+ end
end
- it 'applies comments filter' do
- events = described_class.new(described_class.comments).apply_filter(Event.all)
- expect(events).to contain_exactly(comments_event)
+ context 'with the "comments" filter' do
+ let(:filter) { described_class::COMMENTS }
+
+ it 'filters comment events only' do
+ expect(filtered_events).to contain_exactly(comments_event)
+ end
end
- it 'applies team filter' do
- events = described_class.new(described_class.team).apply_filter(Event.all)
- expect(events).to contain_exactly(joined_event, left_event)
+ context 'with the "team" filter' do
+ let(:filter) { described_class::TEAM }
+
+ it 'filters team events only' do
+ expect(filtered_events).to contain_exactly(joined_event, left_event)
+ end
end
- it 'applies all filter' do
- events = described_class.new(described_class.all).apply_filter(Event.all)
- expect(events).to contain_exactly(push_event, merged_event, created_event, updated_event, closed_event, reopened_event, comments_event, joined_event, left_event)
+ context 'with the "all" filter' do
+ let(:filter) { described_class::ALL }
+
+ it 'returns all events' do
+ expect(filtered_events).to eq(Event.all)
+ end
+ end
+
+ context 'with an unknown filter' do
+ let(:filter) { 'foo' }
+
+ it 'returns all events' do
+ expect(filtered_events).to eq(Event.all)
+ end
+ end
+
+ context 'with a nil filter' do
+ let(:filter) { nil }
+
+ it 'returns all events' do
+ expect(filtered_events).to eq(Event.all)
+ end
+ end
+ end
+
+ describe '#active?' do
+ let(:event_filter) { described_class.new(described_class::TEAM) }
+
+ it 'returns false if filter does not include the given key' do
+ expect(event_filter.active?('foo')).to eq(false)
end
- it 'applies no filter' do
- events = described_class.new(nil).apply_filter(Event.all)
- expect(events).to contain_exactly(push_event, merged_event, created_event, updated_event, closed_event, reopened_event, comments_event, joined_event, left_event)
+ it 'returns false if the given key is nil' do
+ expect(event_filter.active?(nil)).to eq(false)
end
- it 'applies unknown filter' do
- events = described_class.new('').apply_filter(Event.all)
- expect(events).to contain_exactly(push_event, merged_event, created_event, updated_event, closed_event, reopened_event, comments_event, joined_event, left_event)
+ it 'returns true if filter does not include the given key' do
+ expect(event_filter.active?(described_class::TEAM)).to eq(true)
end
end
end
diff --git a/spec/lib/gitlab/ci/external/file/local_spec.rb b/spec/lib/gitlab/ci/external/file/local_spec.rb
index 3f32d81a827..73bb4ccf468 100644
--- a/spec/lib/gitlab/ci/external/file/local_spec.rb
+++ b/spec/lib/gitlab/ci/external/file/local_spec.rb
@@ -8,7 +8,7 @@ describe Gitlab::Ci::External::File::Local do
describe '#valid?' do
context 'when is a valid local path' do
- let(:location) { '/vendor/gitlab-ci-yml/existent-file.yml' }
+ let(:location) { '/lib/gitlab/ci/templates/existent-file.yml' }
before do
allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return("image: 'ruby2:2'")
@@ -20,7 +20,7 @@ describe Gitlab::Ci::External::File::Local do
end
context 'when is not a valid local path' do
- let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' }
+ let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
it 'should return false' do
expect(local_file.valid?).to be_falsy
@@ -48,7 +48,7 @@ describe Gitlab::Ci::External::File::Local do
- bundle install --jobs $(nproc) "${FLAGS[@]}"
HEREDOC
end
- let(:location) { '/vendor/gitlab-ci-yml/existent-file.yml' }
+ let(:location) { '/lib/gitlab/ci/templates/existent-file.yml' }
before do
allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return(local_file_content)
@@ -60,7 +60,7 @@ describe Gitlab::Ci::External::File::Local do
end
context 'with an invalid file' do
- let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' }
+ let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
it 'should be nil' do
expect(local_file.content).to be_nil
@@ -69,7 +69,7 @@ describe Gitlab::Ci::External::File::Local do
end
describe '#error_message' do
- let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' }
+ let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
it 'should return an error message' do
expect(local_file.error_message).to eq("Local file '#{location}' is not valid.")
diff --git a/spec/lib/gitlab/ci/external/mapper_spec.rb b/spec/lib/gitlab/ci/external/mapper_spec.rb
index 6270d27a36d..d925d6af73d 100644
--- a/spec/lib/gitlab/ci/external/mapper_spec.rb
+++ b/spec/lib/gitlab/ci/external/mapper_spec.rb
@@ -17,7 +17,7 @@ describe Gitlab::Ci::External::Mapper do
context 'when the string is a local file' do
let(:values) do
{
- include: '/vendor/gitlab-ci-yml/non-existent-file.yml',
+ include: '/lib/gitlab/ci/templates/non-existent-file.yml',
image: 'ruby:2.2'
}
end
@@ -61,7 +61,7 @@ describe Gitlab::Ci::External::Mapper do
include:
[
remote_url,
- '/vendor/gitlab-ci-yml/template.yml'
+ '/lib/gitlab/ci/templates/template.yml'
],
image: 'ruby:2.2'
}
diff --git a/spec/lib/gitlab/ci/external/processor_spec.rb b/spec/lib/gitlab/ci/external/processor_spec.rb
index 688c2b3c8aa..3c7394f53d2 100644
--- a/spec/lib/gitlab/ci/external/processor_spec.rb
+++ b/spec/lib/gitlab/ci/external/processor_spec.rb
@@ -16,12 +16,12 @@ describe Gitlab::Ci::External::Processor do
end
context 'when an invalid local file is defined' do
- let(:values) { { include: '/vendor/gitlab-ci-yml/non-existent-file.yml', image: 'ruby:2.2' } }
+ let(:values) { { include: '/lib/gitlab/ci/templates/non-existent-file.yml', image: 'ruby:2.2' } }
it 'should raise an error' do
expect { processor.perform }.to raise_error(
described_class::FileError,
- "Local file '/vendor/gitlab-ci-yml/non-existent-file.yml' is not valid."
+ "Local file '/lib/gitlab/ci/templates/non-existent-file.yml' is not valid."
)
end
end
@@ -79,7 +79,7 @@ describe Gitlab::Ci::External::Processor do
end
context 'with a valid local external file is defined' do
- let(:values) { { include: '/vendor/gitlab-ci-yml/template.yml', image: 'ruby:2.2' } }
+ let(:values) { { include: '/lib/gitlab/ci/templates/template.yml', image: 'ruby:2.2' } }
let(:local_file_content) do
<<-HEREDOC
before_script:
@@ -145,7 +145,7 @@ describe Gitlab::Ci::External::Processor do
end
context 'when external files are defined but not valid' do
- let(:values) { { include: '/vendor/gitlab-ci-yml/template.yml', image: 'ruby:2.2' } }
+ let(:values) { { include: '/lib/gitlab/ci/templates/template.yml', image: 'ruby:2.2' } }
let(:local_file_content) { 'invalid content file ////' }
diff --git a/spec/lib/gitlab/ci/templates/templates_spec.rb b/spec/lib/gitlab/ci/templates/templates_spec.rb
new file mode 100644
index 00000000000..0dd74399a47
--- /dev/null
+++ b/spec/lib/gitlab/ci/templates/templates_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe "CI YML Templates" do
+ Gitlab::Template::GitlabCiYmlTemplate.all.each do |template|
+ it "#{template.name} should be valid" do
+ expect { Gitlab::Ci::YamlProcessor.new(template.content) }.not_to raise_error
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index fcbdf71a4e9..a2d429fa859 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -1371,18 +1371,6 @@ module Gitlab
end
end
- describe "Validate configuration templates" do
- templates = Dir.glob("#{Rails.root.join('vendor/gitlab-ci-yml')}/**/*.gitlab-ci.yml")
-
- templates.each do |file|
- it "does not return errors for #{file}" do
- file = File.read(file)
-
- expect { Gitlab::Ci::YamlProcessor.new(file) }.not_to raise_error
- end
- end
- end
-
describe "#validation_message" do
subject { Gitlab::Ci::YamlProcessor.validation_message(content) }
diff --git a/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
index e2fa76522bc..fe46c67a920 100644
--- a/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
+++ b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
@@ -40,7 +40,7 @@ describe Gitlab::Template::GitlabCiYmlTemplate do
describe '#content' do
it 'loads the full file' do
- gitignore = subject.new(Rails.root.join('vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml'))
+ gitignore = subject.new(Rails.root.join('lib/gitlab/ci/templates/Ruby.gitlab-ci.yml'))
expect(gitignore.name).to eq 'Ruby'
expect(gitignore.content).to start_with('#')
diff --git a/spec/models/clusters/applications/jupyter_spec.rb b/spec/models/clusters/applications/jupyter_spec.rb
index 591a01d78a9..9c4396731eb 100644
--- a/spec/models/clusters/applications/jupyter_spec.rb
+++ b/spec/models/clusters/applications/jupyter_spec.rb
@@ -108,8 +108,15 @@ describe Clusters::Applications::Jupyter do
expect(values).to include('rbac')
expect(values).to include('proxy')
expect(values).to include('auth')
+ expect(values).to include('singleuser')
expect(values).to match(/clientId: '?#{application.oauth_application.uid}/)
expect(values).to match(/callbackUrl: '?#{application.callback_url}/)
end
+
+ context 'when cluster belongs to a project' do
+ it 'sets GitLab project id' do
+ expect(values).to match(/GITLAB_CLUSTER_ID: '?#{application.cluster.id}/)
+ end
+ end
end
end
diff --git a/spec/models/event_collection_spec.rb b/spec/models/event_collection_spec.rb
index e0a87c18cc7..6078f429bdc 100644
--- a/spec/models/event_collection_spec.rb
+++ b/spec/models/event_collection_spec.rb
@@ -41,7 +41,7 @@ describe EventCollection do
end
it 'allows filtering of events using an EventFilter' do
- filter = EventFilter.new(EventFilter.issue)
+ filter = EventFilter.new(EventFilter::ISSUE)
events = described_class.new(projects, filter: filter).to_a
expect(events.length).to eq(1)
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index d5b31610dad..f3fb88474a4 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -238,7 +238,7 @@ describe API::Commits do
describe 'create' do
let(:message) { 'Created file' }
- let!(:invalid_c_params) do
+ let(:invalid_c_params) do
{
branch: 'master',
commit_message: message,
@@ -251,7 +251,7 @@ describe API::Commits do
]
}
end
- let!(:valid_c_params) do
+ let(:valid_c_params) do
{
branch: 'master',
commit_message: message,
@@ -264,7 +264,7 @@ describe API::Commits do
]
}
end
- let!(:valid_utf8_c_params) do
+ let(:valid_utf8_c_params) do
{
branch: 'master',
commit_message: message,
@@ -315,7 +315,7 @@ describe API::Commits do
describe 'delete' do
let(:message) { 'Deleted file' }
- let!(:invalid_d_params) do
+ let(:invalid_d_params) do
{
branch: 'markdown',
commit_message: message,
@@ -327,7 +327,7 @@ describe API::Commits do
]
}
end
- let!(:valid_d_params) do
+ let(:valid_d_params) do
{
branch: 'markdown',
commit_message: message,
@@ -356,7 +356,7 @@ describe API::Commits do
describe 'move' do
let(:message) { 'Moved file' }
- let!(:invalid_m_params) do
+ let(:invalid_m_params) do
{
branch: 'feature',
commit_message: message,
@@ -370,7 +370,7 @@ describe API::Commits do
]
}
end
- let!(:valid_m_params) do
+ let(:valid_m_params) do
{
branch: 'feature',
commit_message: message,
@@ -401,7 +401,7 @@ describe API::Commits do
describe 'update' do
let(:message) { 'Updated file' }
- let!(:invalid_u_params) do
+ let(:invalid_u_params) do
{
branch: 'master',
commit_message: message,
@@ -414,7 +414,7 @@ describe API::Commits do
]
}
end
- let!(:valid_u_params) do
+ let(:valid_u_params) do
{
branch: 'master',
commit_message: message,
@@ -442,9 +442,57 @@ describe API::Commits do
end
end
+ describe 'chmod' do
+ let(:message) { 'Chmod +x file' }
+ let(:file_path) { 'files/ruby/popen.rb' }
+ let(:execute_filemode) { true }
+ let(:params) do
+ {
+ branch: 'master',
+ commit_message: message,
+ actions: [
+ {
+ action: 'chmod',
+ file_path: file_path,
+ execute_filemode: execute_filemode
+ }
+ ]
+ }
+ end
+
+ it 'responds with success' do
+ post api(url, user), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['title']).to eq(message)
+ end
+
+ context 'when execute_filemode is false' do
+ let(:execute_filemode) { false }
+
+ it 'responds with success' do
+ post api(url, user), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['title']).to eq(message)
+ end
+ end
+
+ context "when the file doesn't exists" do
+ let(:file_path) { 'foo/bar.baz' }
+
+ it "responds with 400" do
+ post api(url, user), params
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']).to eq("A file with this name doesn't exist")
+ end
+ end
+ end
+
describe 'multiple operations' do
let(:message) { 'Multiple actions' }
- let!(:invalid_mo_params) do
+ let(:invalid_mo_params) do
{
branch: 'master',
commit_message: message,
@@ -468,11 +516,16 @@ describe API::Commits do
action: 'update',
file_path: 'foo/bar.baz',
content: 'puts 8'
+ },
+ {
+ action: 'chmod',
+ file_path: 'files/ruby/popen.rb',
+ execute_filemode: true
}
]
}
end
- let!(:valid_mo_params) do
+ let(:valid_mo_params) do
{
branch: 'master',
commit_message: message,
@@ -496,6 +549,11 @@ describe API::Commits do
action: 'update',
file_path: 'files/ruby/popen.rb',
content: 'puts 8'
+ },
+ {
+ action: 'chmod',
+ file_path: 'files/ruby/popen.rb',
+ execute_filemode: true
}
]
}
diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb
index 3ebdb54f71f..49a79d2ccf9 100644
--- a/spec/requests/api/runners_spec.rb
+++ b/spec/requests/api/runners_spec.rb
@@ -25,36 +25,71 @@ describe API::Runners do
describe 'GET /runners' do
context 'authorized user' do
- it 'returns user available runners' do
+ it 'returns response status and headers' do
get api('/runners', user)
- shared = json_response.any? { |r| r['is_shared'] }
- descriptions = json_response.map { |runner| runner['description'] }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response[0]).to have_key('ip_address')
- expect(descriptions).to contain_exactly(
- 'Project runner', 'Two projects runner', 'Group runner'
- )
- expect(shared).to be_falsey
+ end
+
+ it 'returns user available runners' do
+ get api('/runners', user)
+
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Project runner'),
+ a_hash_including('description' => 'Two projects runner'),
+ a_hash_including('description' => 'Group runner')
+ ]
end
it 'filters runners by scope' do
- get api('/runners?scope=active', user)
+ create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project])
+
+ get api('/runners?scope=paused', user)
- shared = json_response.any? { |r| r['is_shared'] }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response[0]).to have_key('ip_address')
- expect(shared).to be_falsey
+
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Inactive project runner')
+ ]
end
it 'avoids filtering if scope is invalid' do
get api('/runners?scope=unknown', user)
expect(response).to have_gitlab_http_status(400)
end
+
+ it 'filters runners by type' do
+ get api('/runners?type=project_type', user)
+
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Project runner'),
+ a_hash_including('description' => 'Two projects runner')
+ ]
+ end
+
+ it 'does not filter by invalid type' do
+ get api('/runners?type=bogus', user)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'filters runners by status' do
+ create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project])
+
+ get api('/runners?status=paused', user)
+
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Inactive project runner')
+ ]
+ end
+
+ it 'does not filter by invalid status' do
+ get api('/runners?status=bogus', user)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
end
context 'unauthorized user' do
@@ -69,51 +104,91 @@ describe API::Runners do
describe 'GET /runners/all' do
context 'authorized user' do
context 'with admin privileges' do
+ it 'returns response status and headers' do
+ get api('/runners/all', admin)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ end
+
it 'returns all runners' do
get api('/runners/all', admin)
- shared = json_response.any? { |r| r['is_shared'] }
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Project runner'),
+ a_hash_including('description' => 'Two projects runner'),
+ a_hash_including('description' => 'Group runner'),
+ a_hash_including('description' => 'Shared runner')
+ ]
+ end
+
+ it 'filters runners by scope' do
+ get api('/runners/all?scope=shared', admin)
+
+ shared = json_response.all? { |r| r['is_shared'] }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response[0]).to have_key('ip_address')
expect(shared).to be_truthy
end
- end
- context 'without admin privileges' do
- it 'does not return runners list' do
- get api('/runners/all', user)
+ it 'filters runners by scope' do
+ get api('/runners/all?scope=specific', admin)
- expect(response).to have_gitlab_http_status(403)
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Project runner'),
+ a_hash_including('description' => 'Two projects runner'),
+ a_hash_including('description' => 'Group runner')
+ ]
end
- end
- it 'filters runners by scope' do
- get api('/runners/all?scope=shared', admin)
+ it 'avoids filtering if scope is invalid' do
+ get api('/runners/all?scope=unknown', admin)
+ expect(response).to have_gitlab_http_status(400)
+ end
- shared = json_response.all? { |r| r['is_shared'] }
- expect(response).to have_gitlab_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response[0]).to have_key('ip_address')
- expect(shared).to be_truthy
- end
+ it 'filters runners by type' do
+ get api('/runners/all?type=project_type', admin)
- it 'filters runners by scope' do
- get api('/runners/all?scope=specific', admin)
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Project runner'),
+ a_hash_including('description' => 'Two projects runner')
+ ]
+ end
- shared = json_response.any? { |r| r['is_shared'] }
- expect(response).to have_gitlab_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response[0]).to have_key('ip_address')
- expect(shared).to be_falsey
+ it 'does not filter by invalid type' do
+ get api('/runners/all?type=bogus', admin)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'filters runners by status' do
+ create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project])
+
+ get api('/runners/all?status=paused', admin)
+
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Inactive project runner')
+ ]
+ end
+
+ it 'does not filter by invalid status' do
+ get api('/runners/all?status=bogus', admin)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
end
- it 'avoids filtering if scope is invalid' do
- get api('/runners?scope=unknown', admin)
- expect(response).to have_gitlab_http_status(400)
+ context 'without admin privileges' do
+ it 'does not return runners list' do
+ get api('/runners/all', user)
+
+ expect(response).to have_gitlab_http_status(403)
+ end
end
end
@@ -577,15 +652,69 @@ describe API::Runners do
describe 'GET /projects/:id/runners' do
context 'authorized user with maintainer privileges' do
- it "returns project's runners" do
+ it 'returns response status and headers' do
+ get api('/runners/all', admin)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ end
+
+ it 'returns all runners' do
get api("/projects/#{project.id}/runners", user)
- shared = json_response.any? { |r| r['is_shared'] }
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Project runner'),
+ a_hash_including('description' => 'Two projects runner'),
+ a_hash_including('description' => 'Shared runner')
+ ]
+ end
+
+ it 'filters runners by scope' do
+ get api("/projects/#{project.id}/runners?scope=specific", user)
+
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response[0]).to have_key('ip_address')
- expect(shared).to be_truthy
+
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Project runner'),
+ a_hash_including('description' => 'Two projects runner')
+ ]
+ end
+
+ it 'avoids filtering if scope is invalid' do
+ get api("/projects/#{project.id}/runners?scope=unknown", user)
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'filters runners by type' do
+ get api("/projects/#{project.id}/runners?type=project_type", user)
+
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Project runner'),
+ a_hash_including('description' => 'Two projects runner')
+ ]
+ end
+
+ it 'does not filter by invalid type' do
+ get api("/projects/#{project.id}/runners?type=bogus", user)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'filters runners by status' do
+ create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project])
+
+ get api("/projects/#{project.id}/runners?status=paused", user)
+
+ expect(json_response).to match_array [
+ a_hash_including('description' => 'Inactive project runner')
+ ]
+ end
+
+ it 'does not filter by invalid status' do
+ get api("/projects/#{project.id}/runners?status=bogus", user)
+
+ expect(response).to have_gitlab_http_status(400)
end
end
diff --git a/spec/services/files/multi_service_spec.rb b/spec/services/files/multi_service_spec.rb
index 3bdedaf3770..5f3c8e82715 100644
--- a/spec/services/files/multi_service_spec.rb
+++ b/spec/services/files/multi_service_spec.rb
@@ -11,6 +11,7 @@ describe Files::MultiService do
let(:new_file_path) { 'files/ruby/popen.rb' }
let(:file_content) { 'New content' }
let(:action) { 'update' }
+ let(:commit_message) { 'Update File' }
let!(:original_commit_id) do
Gitlab::Git::Commit.last_for_path(project.repository, branch_name, original_file_path).sha
@@ -30,7 +31,7 @@ describe Files::MultiService do
let(:commit_params) do
{
- commit_message: "Update File",
+ commit_message: commit_message,
branch_name: branch_name,
start_branch: branch_name,
actions: actions
@@ -84,6 +85,39 @@ describe Files::MultiService do
end
end
+ describe 'changing execute_filemode of a file' do
+ let(:commit_message) { 'Chmod +x file' }
+ let(:file_path) { original_file_path }
+ let(:default_action) do
+ {
+ action: 'chmod',
+ file_path: file_path,
+ execute_filemode: true
+ }
+ end
+
+ it 'accepts the commit' do
+ results = subject.execute
+
+ expect(results[:status]).to eq(:success)
+ end
+
+ it 'updates the execute_filemode of the file' do
+ expect { subject.execute }.to change { repository.blob_at_branch(branch_name, file_path).mode }.from('100644').to('100755')
+ end
+
+ context "when the file doesn't exists" do
+ let(:file_path) { 'files/wrong_path.rb' }
+
+ it 'rejects the commit' do
+ results = subject.execute
+
+ expect(results[:status]).to eq(:error)
+ expect(results[:message]).to eq("A file with this name doesn't exist")
+ end
+ end
+ end
+
context 'when moving a file' do
let(:action) { 'move' }
let(:new_file_path) { 'files/ruby/new_popen.rb' }
diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index 06cad9c00d2..ac0ca1f33a5 100644
--- a/spec/services/quick_actions/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe QuickActions::InterpretService do
@@ -863,6 +865,13 @@ describe QuickActions::InterpretService do
let(:source_issuable) { create(:labeled_issue, project: project, labels: [inreview_label, todo_label]) }
let(:content) { "/copy_metadata #{source_issuable.to_reference}" }
+ let(:issuable) { build(:issue, project: project) }
+ end
+
+ it_behaves_like 'copy_metadata command' do
+ let(:source_issuable) { create(:labeled_issue, project: project, labels: [inreview_label, todo_label]) }
+
+ let(:content) { "/copy_metadata #{source_issuable.to_reference}" }
let(:issuable) { issue }
end
diff --git a/vendor/gitlab-ci-yml/.gitlab-ci.yml b/vendor/gitlab-ci-yml/.gitlab-ci.yml
deleted file mode 100644
index e2a55163682..00000000000
--- a/vendor/gitlab-ci-yml/.gitlab-ci.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-image: ruby:2.4-alpine
-
-test:
- script: ./verify_templates.rb
diff --git a/vendor/gitlab-ci-yml/CONTRIBUTING.md b/vendor/gitlab-ci-yml/CONTRIBUTING.md
deleted file mode 100644
index d33a1f06f26..00000000000
--- a/vendor/gitlab-ci-yml/CONTRIBUTING.md
+++ /dev/null
@@ -1,46 +0,0 @@
-## Developer Certificate of Origin + License
-
-By contributing to GitLab B.V., You accept and agree to the following terms and
-conditions for Your present and future Contributions submitted to GitLab B.V.
-Except for the license granted herein to GitLab B.V. and recipients of software
-distributed by GitLab B.V., You reserve all right, title, and interest in and to
-Your Contributions. All Contributions are subject to the following DCO + License
-terms.
-
-[DCO + License](https://gitlab.com/gitlab-org/dco/blob/master/README.md)
-
-_This notice should stay as the first item in the CONTRIBUTING.md file._
-
-## Code of conduct
-
-As contributors and maintainers of this project, we pledge to respect all people
-who contribute through reporting issues, posting feature requests, updating
-documentation, submitting pull requests or patches, and other activities.
-
-We are committed to making participation in this project a harassment-free
-experience for everyone, regardless of level of experience, gender, gender
-identity and expression, sexual orientation, disability, personal appearance,
-body size, race, ethnicity, age, or religion.
-
-Examples of unacceptable behavior by participants include the use of sexual
-language or imagery, derogatory comments or personal attacks, trolling, public
-or private harassment, insults, or other unprofessional conduct.
-
-Project maintainers have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions that are
-not aligned to this Code of Conduct. Project maintainers who do not follow the
-Code of Conduct may be removed from the project team.
-
-This code of conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community.
-
-Instances of abusive, harassing, or otherwise unacceptable behavior can be
-reported by emailing contact@gitlab.com.
-
-This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant], version 1.1.0,
-available at [http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/).
-
-[contributor-covenant]: http://contributor-covenant.org
-[individual-agreement]: https://docs.gitlab.com/ee/legal/individual_contributor_license_agreement.html
-[corporate-agreement]: https://docs.gitlab.com/ee/legal/corporate_contributor_license_agreement.html
-
diff --git a/vendor/gitlab-ci-yml/LICENSE b/vendor/gitlab-ci-yml/LICENSE
deleted file mode 100644
index 27a215686e7..00000000000
--- a/vendor/gitlab-ci-yml/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2011-2017 GitLab B.V.
-
-With regard to the GitLab Software:
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-For all third party components incorporated into the GitLab Software, those
-components are licensed under the original license provided by the owner of the
-applicable component.
diff --git a/yarn.lock b/yarn.lock
index 397fd4a2c13..33849642705 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -164,9 +164,9 @@
version "1.29.0"
resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.29.0.tgz#03b65b513f9099bbda6ecf94d673a2952f8c6c70"
-"@gitlab-org/gitlab-ui@^1.7.0":
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.7.0.tgz#cf37b7262f90af42664d4d1600917271a8f8fb28"
+"@gitlab-org/gitlab-ui@^1.7.1":
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.7.1.tgz#e9cce86cb7e34311405e705c1de674276b453f17"
dependencies:
"@gitlab-org/gitlab-svgs" "^1.23.0"
bootstrap-vue "^2.0.0-rc.11"
@@ -204,9 +204,9 @@
version "5.0.0"
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.0.tgz#9ae2106efc443d7c1e26570aa8247828c9c80f11"
-"@vue/component-compiler-utils@^1.2.1":
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-1.2.1.tgz#3d543baa75cfe5dab96e29415b78366450156ef6"
+"@vue/component-compiler-utils@^2.0.0":
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.2.0.tgz#bbbb7ed38a9a8a7c93abe7ef2e54a90a04b631b4"
dependencies:
consolidate "^0.15.1"
hash-sum "^1.0.2"
@@ -214,7 +214,7 @@
merge-source-map "^1.1.0"
postcss "^6.0.20"
postcss-selector-parser "^3.1.1"
- prettier "^1.11.1"
+ prettier "1.13.7"
source-map "^0.5.6"
vue-template-es2015-compiler "^1.6.0"
@@ -5552,10 +5552,14 @@ prepend-http@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
-prettier@1.12.1, prettier@^1.11.1:
+prettier@1.12.1:
version "1.12.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325"
+prettier@1.13.7:
+ version "1.13.7"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281"
+
prismjs@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.6.0.tgz#118d95fb7a66dba2272e343b345f5236659db365"
@@ -7005,11 +7009,11 @@ vue-hot-reload-api@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz#97976142405d13d8efae154749e88c4e358cf926"
-vue-loader@^15.2.4:
- version "15.2.4"
- resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.2.4.tgz#a7b923123d3cf87230a8ff54a1c16d31a6c5dbb4"
+vue-loader@^15.4.2:
+ version "15.4.2"
+ resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.4.2.tgz#812bb26e447dd3b84c485eb634190d914ce125e2"
dependencies:
- "@vue/component-compiler-utils" "^1.2.1"
+ "@vue/component-compiler-utils" "^2.0.0"
hash-sum "^1.0.2"
loader-utils "^1.1.0"
vue-hot-reload-api "^2.3.0"
@@ -7032,9 +7036,9 @@ vue-style-loader@^4.1.0:
hash-sum "^1.0.2"
loader-utils "^1.0.2"
-vue-template-compiler@^2.5.0, vue-template-compiler@^2.5.16:
- version "2.5.16"
- resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.16.tgz#93b48570e56c720cdf3f051cc15287c26fbd04cb"
+vue-template-compiler@^2.5.0, vue-template-compiler@^2.5.17:
+ version "2.5.17"
+ resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.17.tgz#52a4a078c327deb937482a509ae85c06f346c3cb"
dependencies:
de-indent "^1.0.2"
he "^1.1.0"
@@ -7047,9 +7051,9 @@ vue-virtual-scroll-list@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/vue-virtual-scroll-list/-/vue-virtual-scroll-list-1.2.5.tgz#bcbd010f7cdb035eba8958ebf807c6214d9a167a"
-vue@^2.5.16:
- version "2.5.16"
- resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085"
+vue@^2.5.16, vue@^2.5.17:
+ version "2.5.17"
+ resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.17.tgz#0f8789ad718be68ca1872629832ed533589c6ada"
vuex@^3.0.1:
version "3.0.1"